API Reference Rust¶
IN3 Rust API features:¶
- Cross-platform support tested with cross-rs.
- Unsafe code is isolated to a small subset of the API and should not be required for most use cases.
- The C sources are bundled with the crate and we leverage the rust-bindgen and cmake-rs projects to auto-generate bindings.
- Leak-free verified with Valgrind-memcheck.
- Well-documented API support for Ethereum, Bitcoin, and IPFS.
- Customizable storage, transport, and signing.
- All of IN3’s verification capabilities with examples and much more!
Quickstart¶
Add in3 to Cargo manifest¶
Add IN3 and futures_executor (or just any executor of your choice) to your cargo manifest. The in3-rs API is asynchronous and Rust doesn’t have any built-in executors so we need to choose one, and we decided futures_executor is a very good option as it is lightweight and practical to use.
[package]
name = "in3-tutorial"
version = "0.0.1"
authors = ["reader@medium.com"]
edition = "2018"
[dependencies]
in3 = "1.0.0"
futures-executor = "0.3.5"
Let’s begin with the ‘hello-world’ equivalent of the Ethereum JSON-RPC API - eth_blockNumber. This call returns the number of the most recent block in the blockchain. Here’s the complete program:
use in3::eth1;
use in3::prelude::*;
fn main() -> In3Result<()> {
let client = Client::new(chain::MAINNET);
let mut eth_api = eth1::Api::new(client);
let number = futures_executor::block_on(eth_api.block_number())?;
println!("Latest block number => {:?}", number);
Ok(())
}
Now, let’s go through this program line-by-line. We start by creating a JSON-RPC capable Incubed Client instance for the Ethereum mainnet chain.
let client = Client::new(chain::MAINNET);
This client is then used to instantiate an Ethereum Api instance which implements the Ethereum JSON-RPC API spec.
let mut eth_api = eth1::Api::new(client);
From here, getting the latest block number is as simple as calling the block_number() function on the Ethereum Api instance. As specified before, we need to use futures_executor::block_on to run the future returned by block_number() to completion on the current thread.
let number = futures_executor::block_on(eth_api.block_number())?;
A complete list of supported functions can be found on the in3-rs crate documentation page at docs.rs.
Get an Ethereum block by number¶
use async_std::task;
use in3::prelude::*;
fn main() {
// configure client and API
let mut eth_api = Api::new(Client::new(chain::MAINNET));
// get latest block
let block: Block = block_on(eth_api.get_block_by_number(BlockNumber::Latest, false))?;
println!("Block => {:?}", block);
}
An Ethereum contract call¶
In this case, we are reading the number of nodes that are registered in the IN3 network deployed on the Ethereum Mainnet at 0x2736D225f85740f42D17987100dc8d58e9e16252
use async_std::task;
use in3::prelude::*;
fn main() {
// configure client and API
let mut eth_api = Api::new(Client::new(chain::MAINNET));
// Setup Incubed contract address
let contract: Address =
serde_json::from_str(r#""0x2736D225f85740f42D17987100dc8d58e9e16252""#).unwrap(); // cannot fail
// Instantiate an abi encoder for the contract call
let mut abi = abi::In3EthAbi::new();
// Setup the signature to call in this case we are calling totalServers():uint256 from in3-nodes contract
let params = task::block_on(abi.encode("totalServers():uint256", serde_json::json!([])))
.expect("failed to ABI encode params");
// Setup the transaction with contract and signature data
let txn = CallTransaction {
to: Some(contract),
data: Some(params),
..Default::default()
};
// Execute asynchronous api call.
let output: Bytes =
task::block_on(eth_api.call(txn, BlockNumber::Latest)).expect("ETH call failed");
// Decode the Bytes output and get the result
let output =
task::block_on(abi.decode("uint256", output)).expect("failed to ABI decode output");
let total_servers: U256 = serde_json::from_value(output).unwrap(); // cannot fail if ABI decode succeeds
println!("{:?}", total_servers);
}
Store a string in IPFS¶
IPFS is a protocol and peer-to-peer network for storing and sharing data in a distributed file system.
fn main() {
let mut ipfs_api = Api::new(Client::new(chain::IPFS));
//`put` is an asynchrous request (due to the internal C library). Therefore to block execution
//we use async_std's block_on function
match task::block_on(ipfs_api.put("incubed meets rust".as_bytes().into())) {
Ok(res) => println!("The hash is {:?}", res),
Err(err) => println!("Failed with error: {}", err),
}
}
Ready-To-Run Example¶
Head over to our sample project on GitHub or simply run:
$ git clone https://github.com/hu55a1n1/in3-examples.rs
$ cd in3-examples.rs
$ cargo run
Crate¶
In3 crate can be found in crates.io/crates/in3
Api Documentation¶
Api reference information can be found in docs.rs/in3/0.0.2/in3