#contract #ethereum #async #bindings-generator #smart-contracts #web3 #proc-macro

ethcontract

Runtime library and proc macro for interacting and generating type-safe bindings to Ethereum smart contracts

49 unstable releases

new 0.25.6 Apr 22, 2024
0.25.5 Feb 22, 2024
0.25.4 Nov 24, 2023
0.25.0 Jul 13, 2023
0.1.0 Nov 7, 2019

#77 in Magic Beans

Download history 103/week @ 2024-01-01 119/week @ 2024-01-08 70/week @ 2024-01-15 314/week @ 2024-01-22 180/week @ 2024-01-29 54/week @ 2024-02-05 73/week @ 2024-02-12 455/week @ 2024-02-19 306/week @ 2024-02-26 293/week @ 2024-03-04 297/week @ 2024-03-11 277/week @ 2024-03-18 190/week @ 2024-03-25 526/week @ 2024-04-01 356/week @ 2024-04-08 276/week @ 2024-04-15

1,356 downloads per month
Used in 7 crates

MIT/Apache

365KB
8K SLoC

Generate bindings for Ethereum smart contracts. Internally, the generated types use web3 crate to interact with the Ethereum network and uses a custom Instance runtime that can be used directly without code generation.

This crate is using std::future::Future for futures by wrapping web3 futures 0.1 with futures 0.3 compatibility layer. This means that this crate is ready for async/await!

Here is an example of interacing with a smart contract MyContract. The builder pattern is used for configuring transactions.

pragma solidity ^0.6.0;

contract MyContract {
  function my_view_function(uint64 some_val) public view returns (string) {
    // ...
  }

  function my_function(bool some_bool, string some_str) public returns (uint256) {
    // ...
  }

  function my_other_function() public {
    // ...
  }
}

Once this contract is built and deployed with truffle the following example demonstrates how to interact with it from Rust.

use ethcontract::transaction::Account;
use std::time::Duration;
use web3::api::Web3;
use web3::types::*;

// this proc macro generates a `MyContract` type with type-safe bindings to
// contract functions
ethcontract::contract!("path/to/MyContract.json");

// create a web3 instance as usual
let transport = ...;
let web3 = Web3::new(transport);

// now create an instance of an interface to the contract
let instance = MyContract::deployed(web3).await?;

let addr: Address = "0x000102030405060708090a0b0c0d0e0f10111213".parse()?;
let some_uint: U256 = U256::from_dec_str("1000000000000000000")?;
let some_bool = true;
let some_val = u64;

// call instance view functions with type-safe bindings! will only compile
// if contract function accepts a single `u64` value parameter and returns
// a concrete type based on the contract function's return type
let value = instance
    .my_view_function(some_val)
    .from(addr)
    .execute()
    .await?;

// contract functions also have type-safe bindings and return the tx hash
// of the submitted transaction; allows for multiple ways of signing txs
let tx = instance
    .my_function(some_bool, value)
    .from(Account::Locked(addr, "password".into(), None))
    .value(some_uint)
    .gas_price(1_000_000.into())
    .execute()
    .await?;

// wait for confirmations when needed
let receipt = instance
    .my_important_function()
    .poll_interval(Duration::from_secs(5))
    .confirmations(2)
    .execute_confirm()
    .await?;

See contract! proc macro documentation for more information on usage and parameters as well on how to use contract ABI directly from Etherscan. A prelude module for importing commonly used types when interacting with generated contracts. Type aliases to various runtime types that use an underlying DynTransport. These types are used extensively throughout the generated code.

Dependencies

~11–32MB
~461K SLoC