Macro ethcontract::contract[][src]

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

Proc macro to generate type-safe bindings to a contract.

This macro accepts a path to an artifact JSON file. Note that this path is rooted in the crate’s root CARGO_MANIFEST_DIR:

contract!("build/contracts/WETH9.json");

Alternatively, other sources may be used, for full details consult the [ethcontract_generate::source] documentation. Some basic examples:

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

// Etherscan source
contract!("etherscan:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2");

// NPM package source
contract!("npm:@openzeppelin/contracts@4.2.0/build/contracts/IERC20.json")

Note that Etherscan rate-limits requests to their API, to avoid this an ETHERSCAN_API_KEY environment variable can be set. If it is, it will use that API key when retrieving the contract ABI.

Currently, the proc macro accepts additional parameters to configure some aspects of the code generation. Specifically it accepts the following.

  • format: format of the artifact.

    Available values are:

    Note that hardhat artifacts export multiple contracts. You’ll have to use contract parameter to specify which contract to generate bindings to.

  • contract: name of the contract we’re generating bindings to.

    If an artifact exports a single unnamed artifact, this parameter can be used to set its name. For example:

    contract!(
        "etherscan:0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
        contract = WETH9
    );

    Otherwise, it can be used to specify which contract we’re generating bindings to. Additionally, you can rename contract class by specifying a new name after the as keyword. For example:

    contract!(
        "build/contracts.json",
        format = hardhat_multi,
        contract = WETH9 as WrappedEthereum
    );
  • mod: name of the contract module to place generated code in.

    This defaults to the contract name converted into snake case.

    Note that the root contract type gets re-exported in the context where the macro was invoked.

    Example:

    contract!(
        "build/contracts/WETH9.json",
        contract = WETH9 as WrappedEthereum,
        mod = weth,
    );
  • deployments: a list of additional addresses of deployed contract for specified network IDs.

    This mapping allows generated contract’s deployed function to work with networks that are not included in the artifact’s deployment information.

    Note that deployments defined this way take precedence over the ones defined in the artifact.

    This parameter is intended to be used to manually specify contract addresses for test environments, be it testnet addresses that may defer from the originally published artifact or deterministic contract addresses on local development nodes.

    Example:

    contract!(
        "build/contracts/WETH9.json",
        deployments {
            4 => "0x000102030405060708090a0b0c0d0e0f10111213",
            5777 => "0x0123456789012345678901234567890123456789",
        },
    );
  • methods: a list of mappings from method signatures to method names allowing methods names to be explicitly set for contract methods.

    This also provides a workaround for generating code for contracts with multiple methods with the same name.

    Example:

    contract!(
        "build/contracts/WETH9.json",
        methods {
            approve(Address, U256) as set_allowance
        },
    );
  • event_derives: a list of additional derives that should be added to contract event structs and enums.

    Example:

    contract!(
        "build/contracts/WETH9.json",
        event_derives (serde::Deserialize, serde::Serialize),
    );
  • crate: the name of the ethcontract crate. This is useful if the crate was renamed in the Cargo.toml for whatever reason.

Additionally, the ABI source can be preceded by a visibility modifier such as pub or pub(crate). This visibility modifier is applied to both the generated module and contract re-export. If no visibility modifier is provided, then none is used for the generated code as well, making the module and contract private to the scope where the macro was invoked.

Full example:

contract!(
    pub(crate) "build/contracts.json",
    format = hardhat_multi,
    contract = WETH9 as WrappedEthereum,
    mod = weth,
    deployments {
        4 => "0x000102030405060708090a0b0c0d0e0f10111213",
        5777 => "0x0123456789012345678901234567890123456789",
    },
    methods {
        myMethod(uint256,bool) as my_renamed_method;
    },
    event_derives (serde::Deserialize, serde::Serialize),
    crate = ethcontract_renamed,
);

See ethcontract module level documentation for additional information.