EVM RPC Canister

Hello devs! I am pleased to announce that the EVM RPC Canister is now live. Thank you all for your feedback and comments while we developed this service.

The canister is still in beta, and while we put it through some real-world battle testing, it will remain managed by DFINITY. Once we are confident it can serve the needs of all of your dapps safely and performantly, we will publish a GA release and put it under NNS control.

You can find the latest beta release here on github: Release 2024-01-31 (Beta) · internet-computer-protocol/ic-eth-rpc · GitHub

Big thank you to @THLO @gregory-demay @Manu and most of all @rvanasa for all of the hard work in getting this out. I don’t think I can give enough credit to @rvanasa — he really put his heart and soul into this to give you all a fast and easy way to bridge your canisters to EVM smart contracts. Incredible work, Ryan!

As you begin your integrations, please let us know of any issues you come across. We will address feedback as quickly as possible, but will give priority to bugs and security issues.

Thank you all and hear from you soon!

10 Likes

Hey I have a major question, does the canister rely on making on request to one Ethereum provider? Or does it make multiple requests and compare them? I don’t see any way to control that so far in the Candid file.

@THLO @gregory-demay @Manu @rvanasa

If there is no capability to use multiple providers and have the responses compared, I would like to understand the reasoning and suggest that this be implemented so that applications can choose to increase the security of their Ethereum integration until we have a direct integration.

This is the case specifically for the candid RPC methods. The general RPC endpoint accepts a provider id as a param and will leave the normalization / canonicalization up to the developer.

Is there something that isn’t obvious when you run one of the candid RPC methods? Perhaps @rvanasa can help out

By default, the canister makes requests to 3 different JSON-RPC providers (Cloudflare Web3, Ankr, and Public Node). We also support Alchemy and BlockPI out of the box.

It’s possible to select any number or combination of these RPC providers. Here is an example dfx command for making an RPC request with all 5 built-in Ethereum providers:

dfx canister call evm_rpc eth_getTransactionCount '(
  variant {EthMainnet = opt vec {
    variant {Cloudflare};
    variant {Ankr};
    variant {PublicNode};
    variant {Alchemy};
    variant {BlockPi};
  }},
  null,
  record {
    address = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
    block = variant {Latest};
  }
)' --with-cycles 10000000000 --wallet=$(dfx identity get-wallet --network ic) --network ic

Note that using more RPC providers increases the chance of encountering HTTP outcall consensus errors, but this may be worth it for the added security depending on the situation.

We are in the process of rolling out documentation and examples for how to use the canister; hopefully this is useful as a reference point for the time being.

3 Likes

Okay I understand now, I didn’t see the vec for providing the providers.

I am trying to get a basic example working, and eth_getBlockByNumber so far no matter what provider I try is returning "missing field baseFeePerGas:

{"Consistent":{"Err":{"HttpOutcallError":{"InvalidHttpJsonRpcResponse":{"status":200,"body":"{\"jsonrpc\":\"2.0\",\"id\":13,\"result\":{\"difficulty\":\"0x400000000\",\"extraData\":\"0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa\",\"gasLimit\":\"0x1388\",\"gasUsed\":\"0x0\",\"hash\":\"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"nonce\":\"0x0000000000000042\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"size\":\"0x21c\",\"stateRoot\":\"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544\",\"timestamp\":\"0x0\",\"totalDifficulty\":\"0x400000000\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]}}\n","parsingError":["missing field `baseFeePerGas` at line 1 column 1473"]}}}}}

Is this in your local replica? I’m using the following dfx command to try and reproduce the issue:

dfx canister call evm_rpc eth_getBlockByNumber '(variant {EthMainnet}, null, variant {Latest})' --with-cycles 10000000000 --wallet=$(dfx identity get-wallet)

Does this command work for you? Feel free to send me a DM and we can try to narrow down what’s happening.

1 Like

Hello everyone,

Be sure to check out @dfx-json’s announcement blog post which gives some great background for the EVM RPC canister along with detailed installation instructions.

Documentation is now available for those interested in the full capabilities of the EVM RPC canister.

I also set up a full-stack starter project as an example of how to call RPC methods from a Motoko dapp. Here is a browser-based development environment so you can get started without downloading anything on your local machine.

Let us know if you run into any issues or have any questions; your feedback is highly important during this beta testing phase. Feel free to open an issue or even contribute a PR on the project’s GitHub repository.

Cheers!

6 Likes

Hello again! We just updated the EVM RPC canister to make it significantly easier to use custom EVM chains based directly on community feedback.

Here is an example command to get the latest block information on the Arbitrum L2 network:

dfx canister call evm_rpc eth_getBlockByNumber '(variant {Custom = record {chainId = 42161; services = vec {record {url = "https://1rpc.io/arb"}}}}, null, variant {Latest})' --with-cycles 10000000000 --wallet=$(dfx identity get-wallet)

Equivalent in Motoko:

let source = #Custom {
  chainId = 42161;
  services = [{ url = "https://1rpc.io/arb"; headers = null }];
};
Cycles.add(1000000000);
let result = await EvmRpc.eth_getBlockByNumber(source, null, #Latest);

A full list of chain ids and RPC services can be found on ChainList.org.

We appreciate your involvement during this beta testing phase and encourage you to reach out with any questions or requests here or on the GitHub repository.

4 Likes

Hello @rvanasa, are all the chains in the Chainlist website supported already?

I don’t think so, as it depends on which chains the RPC providers support.

1 Like

+1. It’s possible to use most networks listed on ChainList by specifying a custom provider (relevant documentation), although support varies depending on the specific chain and RPC method.

2 Likes

Exciting developments. When will it be fully rolled out in production?