abigen!() { /* proc-macro */ }
Expand description

Generates type-safe bindings to an Ethereum smart contract from its ABI.

All the accepted ABI sources are listed in the examples below and in Source.

Note:

  • relative paths are rooted in the crate’s root (CARGO_MANIFEST_DIR).
  • Environment variable interpolation is supported via $ prefix, like "$CARGO_MANIFEST_DIR/contracts/c.json"
  • Etherscan rate-limits requests to their API. To avoid this, set the ETHERSCAN_API_KEY environment variable.

Additionally, this macro accepts additional parameters to configure some aspects of the code generation:

  • methods: A list of mappings from method signatures to method names allowing methods names to be explicitely set for contract methods. This also provides a workaround for generating code for contracts with multiple methods with the same name.
  • derives: A list of additional derive macros that are added to all the generated structs and enums, after the default ones which are (when applicable):

§Examples

All the possible ABI sources:

// ABI Path
abigen!(MyContract, "./MyContractABI.json");

// HTTP(S) source
abigen!(MyContract, "https://my.domain.local/path/to/contract.json");

// Etherscan.io
abigen!(MyContract, "etherscan:0x0001020304050607080910111213141516171819");
abigen!(MyContract, "https://etherscan.io/address/0x0001020304050607080910111213141516171819");

// npmjs
abigen!(MyContract, "npm:@org/package@1.0.0/path/to/contract.json");

// Human readable ABI
abigen!(MyContract, r"[
    function setValue(string)
    function getValue() external view returns (string)
    event ValueChanged(address indexed author, string oldValue, string newValue)
]");

Specify additional parameters:

abigen!(
    MyContract,
    "path/to/MyContract.json",
    methods {
        myMethod(uint256,bool) as my_renamed_method;
    },
    derives(serde::Deserialize, serde::Serialize),
);

Aliases for overloaded functions with no aliases provided in the method section are derived automatically.

abigen! supports multiple abigen definitions separated by a semicolon ; This is useful if the contracts use ABIEncoderV2 structs. In which case abigen! bundles all type duplicates so that all rust contracts also use the same rust types.

abigen!(
    MyContract,
    "path/to/MyContract.json",
    methods {
        myMethod(uint256,bool) as my_renamed_method;
    },
    derives(serde::Deserialize, serde::Serialize);

    MyOtherContract,
    "path/to/MyOtherContract.json",
    derives(serde::Deserialize, serde::Serialize);
);