From bf29dff1642d41c19c02454fca8c548705933422 Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Fri, 26 Jan 2024 15:50:31 -0600 Subject: [PATCH 1/7] EVM RPC canister docs --- .../integrations/ethereum/evm-rpc.md | 365 ++++++++++++++++++ .../integrations/ethereum/overview.md | 23 ++ 2 files changed, 388 insertions(+) create mode 100644 docs/developer-docs/integrations/ethereum/evm-rpc.md create mode 100644 docs/developer-docs/integrations/ethereum/overview.md diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md new file mode 100644 index 0000000000..3ed89aeca7 --- /dev/null +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -0,0 +1,365 @@ +# EVM RPC canister + +To use the EVM RPC canister, you can import it into your project's `dfx.json` file: + +```json +{ + "canisters": { + "evm_rpc": { + "type": "custom", + "candid": "https://github.com/internet-computer-protocol/ic-eth-rpc/releases/latest/download/evm_rpc.did", + "wasm": "https://github.com/internet-computer-protocol/ic-eth-rpc/releases/latest/download/evm_rpc_dev.wasm.gz", + "remote": { + "id": { + "ic": "a6d44-nyaaa-aaaap-abp7q-cai" + } + } + } + } +} +``` + +## Supported RPC methods + +- `eth_gasPrice`: Queries the current ETH gas price. +- `eth_getLogs`: Queries the logs of a specified block or transaction. +- `eth_getBlockByNumber`: Queries information about a given block. +- `eth_getTransactionReceipt`: Queries details about a submitted transaction. +- `eth_feeHistory`: Queries the historical fee data to estimate gas prices for transactions. +- `eth_sendRawTransaction`: Submits a signed transaction to the Ethereum network. +- `eth_getTransactionCount`: Queries the number of transactions for a specified address. +- `eth_call`: Calls a smart contract function without changing the blockchain's state. +- `eth_getStorageAt`: Queries the value of a storage position at a given address. +- `eth_estimateGas`: Provides an estimate for the gas consumption of a transaction before it is mined. +- `eth_blockNumber`: Queries the number of the most recent block. +- `eth_getCode`: Queries the bytecode of a specified contract. + + +## Supported RPC providers + +- Alchemy: `https://eth-mainnet.g.alchemy.com/v2/` +- Ankr: `https://rpc.ankr.com/eth/` +- BlockPI: `https://ethereum.blockpi.network/v1/rpc/` +- Cloudflare Web3: `https://cloudflare-eth.com/v1/mainnet/` +- Public Node: `https://ethereum.publicnode.com` + +View the [full list of RPC providers for each EVM network.](https://chainlist.org/) + +### Specifying an RPC provider + +To specify the RPC provider you'd like to use, change the `Url` value: + +``` +dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 600000000 request '(variant {Url="https://ethereum.publicnode.com"},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' +``` + +### Registering your own provider + +To register your own RPC provider, you can use the following command: + +``` +dfx canister call evm_rpc register_provider '(record { chain_id=1; base_url="https://cloudflare-eth.com"; credential_path="/v1/mainnet"; cycles_per_call=10; cycles_per_message_byte=1; })' +``` + +In this command, the following configuration parameters are set: + +- `chain_id`: The ID of the blockchain network. +- `base_url`: The JSON-RPC base URL. +- `credential_path`: The path to the RPC authentication. +- `cycles_per_call`: The amount of cycles charged per RPC call. +- `cycles_per_message_byte`: The amount of cycles charged per message byte. + + +Then, to authorize with this provider in your local environment, run the commands: + +``` +PRINCIPAL=$(dfx identity get-principal) +dfx canister call evm_rpc authorize "(principal \"$PRINCIPAL\", variant { RegisterProvider })" +dfx canister call evm_rpc get_authorized '(variant { RegisterProvider })' +``` + +To deauthorize the provider locally, run the command: + +``` +dfx canister call evm_rpc deauthorize "(principal \"$PRINCIPAL\", variant { RegisterProvider })" +``` + + +### Using a specific EVM chain + +To use a specific EVM chain, specify the chain's ID in the `Chain` parameter: + +``` +dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 600000000 request '(variant {Chain=0x1},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' +``` + + +## Using the EVM RPC canister + +To use the canister locally, start the local replica and deploy the canister locally with `13` subnets to simulate deployment on the mainnet: + +``` +dfx start --background +dfx deploy evm_rpc --argument '(record { nodesInSubnet = 13 })' +``` + +To use the canister on the mainnet, deploy it with the `--network ic` flag: + +``` +dfx deploy evm_rpc --network ic +``` + +## eth_gasPrice + +To query the current ETH gas price, make a call to the `eth_gasPrice` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Additional parameters; none are specified in this example. +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getLogs + +To query the logs of a specific transaction, make a call to the `eth_getLogs` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\",\"params\":[{\"topics\":[\"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b\"]}],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies a 'topic' value. A topic is an array of 32 bytes of data. Additional parameters can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getlogs) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getBlockByNumber + +To query information about a block, make a call to the `eth_getBlockByNumber` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x1b4\", true],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies a block number, or the string "earliest", "latest," or "pending". Specifies a boolean of "true" or "false," where true returns the full transaction objects and false only returns the hashes of the transactions. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getblockbynumber) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getTransactionReceipt + +To query a transaction receipt, make a call to the `eth_getTransactionReceipt` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the hash of a transaction. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getblockbynumber) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_feeHistory + +To return a collection of historical gas information, make a call to the `eth_feeHistory` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_feeHistory\",\"params\":[\"4\",\"4\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the number of blocks in the request range and the highest block of that requested range. Additional information can be found in the [JSON RPC documentation.](https://docs.alchemy.com/reference/eth-feehistory) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + + +### eth_sendRawTransaction + +To submit a raw transaction, make a call to the `eth_sendRawTransaction` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendRawTransaction\",\"params\":[\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the signed transaction data. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_sendrawtransaction) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getTransactionCount + +To return the amount of transactions sent from an address, make a call to the `eth_getTransactionCount` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"0x407d73d8a49eeb85d32cf465507dd71d507100c1\",\"latest\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the address to query and the "latest", "earliest", or "pending" filter for transactions. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_gettransactioncount) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_call + +To execute a new message without creating a transaction (often used for read-only functions), make a call to the `eth_call` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_call) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getStorageAt + +To return the value of a storage position, make a call to the `eth_getStorageAt` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getStorageAt\",\"params\":["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the contract address, integer of the position in the storage, and integer block number or string "latest", "earliest", or "pending" status. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getstorageat) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + + +### eth_estimateGas + +To estimate the gas fee, make a call to the `eth_estimateGas` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_estimateGas\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: All parameters are optional. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_estimategas) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + + +### eth_blockNumber + +To return the most recent block number, make a call to the `eth_blockNumber` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: No parameters. +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). + +### eth_getCode + +To return the code for an address, make a call to the `eth_getCode` JSON-RPC method: + +``` +dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getCode\",\"params\":[\"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\", \"0x2\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +``` + +In this request, the following configuration is passed: + +- `Url`: The URL of the RPC service. +- `jsonrpc`: The version of JSON-RPC used. +- `method`: The RPC method being called. +- `params`: Specifies the address and the integer block number of string "latest", "earliest", or "pending". Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getcode) +- `id`: id of the request. + +Additionally, the flags used are: + +- `wallet`: The cycles wallet associated with the current dfx identity. +- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). diff --git a/docs/developer-docs/integrations/ethereum/overview.md b/docs/developer-docs/integrations/ethereum/overview.md new file mode 100644 index 0000000000..fe3ae1c692 --- /dev/null +++ b/docs/developer-docs/integrations/ethereum/overview.md @@ -0,0 +1,23 @@ +# Overview + +Canisters deployed on ICP are able to communicate with the Ethereum blockchain and other EVM-compatible networks using the EVM RPC canister. The EVM RPC canister implements an on-chain API that facilitates API requests to JSON-RPC services like Alchemy, Ankr, and Cloudflare WEb3. It also supports BlockPI requests using the ICP feature HTTPS outcalls. + +This integration enables canisters to use Ethereum similar to dapps deployed directly on Ethereum. ICP canisters can query info such as Ethereum smart contract states and submit raw transactions to the Ethereum network. + +The EVM-RPC canister supports [other EVM chains](https://chainlist.org/?testnets=true) such as Polygon and Avalanche. + +This integration allows for the implementation of ckETH, a chain-key twin of the ETH token. + +You can [learn how to use the EVM RPC canister](evm-rpc.md) + +## Costs + +An approximate cost breakdown in USD can be found below. These costs are estimated using the Cloudflare RPC with a 13-node subnet: + +- JSON-RPC API request: $0.0001 USD +- HTTPS outcalls: $0.001 USD (This assumes 1KiB request and 1KiB response) +- Base cost: $0.0008 USD +- JSON Request: $0.00008 USD per KiB +- JSON Response: $0.00008 USD per KiB + +These costs are paid by sending cycles with each RPC call using the `--with-cycles` flag. Learn more about [cycles](/docs/current/developer-docs/gas-cost). \ No newline at end of file From c17bbdf4ea0ab33457b0cf9978c125f62714151d Mon Sep 17 00:00:00 2001 From: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> Date: Mon, 29 Jan 2024 09:08:32 -0600 Subject: [PATCH 2/7] Update docs/developer-docs/integrations/ethereum/evm-rpc.md Co-authored-by: Ryan Vandersmith --- docs/developer-docs/integrations/ethereum/evm-rpc.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md index 3ed89aeca7..6eef8458e3 100644 --- a/docs/developer-docs/integrations/ethereum/evm-rpc.md +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -21,18 +21,14 @@ To use the EVM RPC canister, you can import it into your project's `dfx.json` fi ## Supported RPC methods -- `eth_gasPrice`: Queries the current ETH gas price. +- `eth_feeHistory`: Queries the historical fee data to estimate gas prices for transactions. - `eth_getLogs`: Queries the logs of a specified block or transaction. - `eth_getBlockByNumber`: Queries information about a given block. +- `eth_getTransactionCount`: Queries the number of transactions for a specified address. - `eth_getTransactionReceipt`: Queries details about a submitted transaction. -- `eth_feeHistory`: Queries the historical fee data to estimate gas prices for transactions. - `eth_sendRawTransaction`: Submits a signed transaction to the Ethereum network. -- `eth_getTransactionCount`: Queries the number of transactions for a specified address. -- `eth_call`: Calls a smart contract function without changing the blockchain's state. -- `eth_getStorageAt`: Queries the value of a storage position at a given address. -- `eth_estimateGas`: Provides an estimate for the gas consumption of a transaction before it is mined. -- `eth_blockNumber`: Queries the number of the most recent block. -- `eth_getCode`: Queries the bytecode of a specified contract. + +Other JSON-RPC methods (including those specific to non-Ethereum networks) may be accessed using the canister's `request` method. ## Supported RPC providers From 01b1b4603a00d27edf50e355ea8fed32b811632b Mon Sep 17 00:00:00 2001 From: Jessie Mongeon Date: Mon, 29 Jan 2024 10:00:18 -0600 Subject: [PATCH 3/7] Add sidebars and Candid example --- .../integrations/ethereum/evm-rpc.md | 19 +++++++++++++++++++ sidebars.js | 8 ++++++++ 2 files changed, 27 insertions(+) diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md index 6eef8458e3..5899ece47d 100644 --- a/docs/developer-docs/integrations/ethereum/evm-rpc.md +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -49,6 +49,25 @@ To specify the RPC provider you'd like to use, change the `Url` value: dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 600000000 request '(variant {Url="https://ethereum.publicnode.com"},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' ``` +You can also specify an RPC provider within your Candid file: + +``` +type JsonRpcSource = variant { + Chain : nat64; + Service : record { hostname : text; chainId : opt nat64, headers: opt vec (text, text) }; + Provider : nat64; + Custom : record { url : text; headers : vec (text, text) }; +}; + +request : ( + source : JsonRpcSource, + jsonRequest : text, + maxResponseBytes : nat64 +) -> ( + Result +); +``` + ### Registering your own provider To register your own RPC provider, you can use the following command: diff --git a/sidebars.js b/sidebars.js index 16835106e7..67de7ef121 100644 --- a/sidebars.js +++ b/sidebars.js @@ -471,6 +471,14 @@ const sidebars = { "developer-docs/integrations/bitcoin/local-development", ], }, + { + type: "category", + label: "Ethereum", + items: [ + "developer-docs/integrations/ethereum/overview", + "developer-docs/integrations/ethereum/evm-rpc", + ], + }, { type: "category", label: "Bootcamps", From 66a822eeb1316411344b20c0a4057ac5ab6350f2 Mon Sep 17 00:00:00 2001 From: Ryan Vandersmith Date: Tue, 30 Jan 2024 09:42:18 -0700 Subject: [PATCH 4/7] Additions to EVM RPC canister documentation (#2413) * Adjust 'Specifying an RPC provider' section * Adjust 'Supported RPC providers' * Adjust 'Using the EVM RPC canister' * Lots of changes * Phrasing * Mention supported networks for each built-in provider * Clarify HTTP outcall retry logic and document 'responseSizeEstimate' config * Update evm-rpc.md * Update overview.md * Remove redundant 'Overview' subheading (given 'Overview' page) --------- Co-authored-by: Jessie Mongeon <133128541+jessiemongeon1@users.noreply.github.com> --- .../integrations/ethereum/evm-rpc.md | 415 ++++++------------ .../integrations/ethereum/overview.md | 10 +- 2 files changed, 135 insertions(+), 290 deletions(-) diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md index 5899ece47d..75d77ff65a 100644 --- a/docs/developer-docs/integrations/ethereum/evm-rpc.md +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -1,26 +1,13 @@ # EVM RPC canister -To use the EVM RPC canister, you can import it into your project's `dfx.json` file: +**EVM RPC** is an Internet Computer canister smart contract for communicating with [Ethereum](https://ethereum.org/en/) and other [EVM blockchains](https://chainlist.org/?testnets=true) using an on-chain API. -```json -{ - "canisters": { - "evm_rpc": { - "type": "custom", - "candid": "https://github.com/internet-computer-protocol/ic-eth-rpc/releases/latest/download/evm_rpc.did", - "wasm": "https://github.com/internet-computer-protocol/ic-eth-rpc/releases/latest/download/evm_rpc_dev.wasm.gz", - "remote": { - "id": { - "ic": "a6d44-nyaaa-aaaap-abp7q-cai" - } - } - } - } -} -``` +The source code for this project is available on GitHub ([dfinity/evm-rpc-canister](https://github.com/dfinity/evm-rpc-canister) ⭐️) under the Apache 2.0 license. ## Supported RPC methods +The following JSON-RPC methods are available as part of the canister's [Candid interface](https://github.com/dfinity/candid#readme): + - `eth_feeHistory`: Queries the historical fee data to estimate gas prices for transactions. - `eth_getLogs`: Queries the logs of a specified block or transaction. - `eth_getBlockByNumber`: Queries information about a given block. @@ -28,353 +15,211 @@ To use the EVM RPC canister, you can import it into your project's `dfx.json` fi - `eth_getTransactionReceipt`: Queries details about a submitted transaction. - `eth_sendRawTransaction`: Submits a signed transaction to the Ethereum network. -Other JSON-RPC methods (including those specific to non-Ethereum networks) may be accessed using the canister's `request` method. - +Other RPC methods (including those specific to non-Ethereum networks) may be accessed using the canister's `request` method. ## Supported RPC providers -- Alchemy: `https://eth-mainnet.g.alchemy.com/v2/` -- Ankr: `https://rpc.ankr.com/eth/` -- BlockPI: `https://ethereum.blockpi.network/v1/rpc/` -- Cloudflare Web3: `https://cloudflare-eth.com/v1/mainnet/` -- Public Node: `https://ethereum.publicnode.com` - -View the [full list of RPC providers for each EVM network.](https://chainlist.org/) +The EVM RPC canister has built-in support for the following [Ethereum JSON-RPC providers](https://ethereum.org/developers/docs/apis/json-rpc): -### Specifying an RPC provider +- [Alchemy](https://docs.alchemy.com/docs/how-to-read-data-with-json-rpc): Ethereum mainnet, Sepolia testnet. +- [Ankr](https://www.ankr.com/infrastructure/build-on-ethereum/): Ethereum mainnet, Sepolia testnet. +- [BlockPI](https://blockpi.io/): Ethereum mainnet, Sepolia testnet. +- [Cloudflare Web3](https://www.cloudflare.com/application-services/products/web3/): Ethereum mainnet. +- [Public Node](https://www.publicnode.com/): Ethereum mainnet, Sepolia testnet. -To specify the RPC provider you'd like to use, change the `Url` value: - -``` -dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 600000000 request '(variant {Url="https://ethereum.publicnode.com"},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' -``` - -You can also specify an RPC provider within your Candid file: - -``` -type JsonRpcSource = variant { - Chain : nat64; - Service : record { hostname : text; chainId : opt nat64, headers: opt vec (text, text) }; - Provider : nat64; - Custom : record { url : text; headers : vec (text, text) }; -}; +Many of the providers on [ChainList.org](https://chainlist.org/) can be called using the canister's `request` method. -request : ( - source : JsonRpcSource, - jsonRequest : text, - maxResponseBytes : nat64 -) -> ( - Result -); -``` -### Registering your own provider +## Importing or deploying the EVM RPC canister -To register your own RPC provider, you can use the following command: +To include the EVM RPC canister in a [dfx](https://internetcomputer.org/docs/current/references/cli-reference/dfx-parent) project, add the following to your `dfx.json` file: +```json +{ + "canisters": { + "evm_rpc": { + "type": "custom", + "candid": "https://github.com/dfinity/evm-rpc-canister/releases/latest/download/evm_rpc.did", + "wasm": "https://github.com/dfinity/evm-rpc-canister/releases/latest/download/evm_rpc_dev.wasm.gz", + "remote": { + "id": { + "ic": "a6d44-nyaaa-aaaap-abp7q-cai" + } + } + } + } +} ``` -dfx canister call evm_rpc register_provider '(record { chain_id=1; base_url="https://cloudflare-eth.com"; credential_path="/v1/mainnet"; cycles_per_call=10; cycles_per_message_byte=1; })' -``` - -In this command, the following configuration parameters are set: - -- `chain_id`: The ID of the blockchain network. -- `base_url`: The JSON-RPC base URL. -- `credential_path`: The path to the RPC authentication. -- `cycles_per_call`: The amount of cycles charged per RPC call. -- `cycles_per_message_byte`: The amount of cycles charged per message byte. - - -Then, to authorize with this provider in your local environment, run the commands: - -``` -PRINCIPAL=$(dfx identity get-principal) -dfx canister call evm_rpc authorize "(principal \"$PRINCIPAL\", variant { RegisterProvider })" -dfx canister call evm_rpc get_authorized '(variant { RegisterProvider })' -``` - -To deauthorize the provider locally, run the command: - -``` -dfx canister call evm_rpc deauthorize "(principal \"$PRINCIPAL\", variant { RegisterProvider })" -``` - - -### Using a specific EVM chain - -To use a specific EVM chain, specify the chain's ID in the `Chain` parameter: - -``` -dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 600000000 request '(variant {Chain=0x1},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' -``` - - -## Using the EVM RPC canister -To use the canister locally, start the local replica and deploy the canister locally with `13` subnets to simulate deployment on the mainnet: +Next, start the local replica and deploy the canister locally with a specified number of nodes (`13` for a standard ICP subnet): ``` dfx start --background dfx deploy evm_rpc --argument '(record { nodesInSubnet = 13 })' ``` -To use the canister on the mainnet, deploy it with the `--network ic` flag: +Another option is to create a fork of the EVM RPC canister: ``` -dfx deploy evm_rpc --network ic +git clone https://github.com/dfinity/evm-rpc-canister ``` -## eth_gasPrice - -To query the current ETH gas price, make a call to the `eth_gasPrice` JSON-RPC method: +To deploy your own canister on the mainnet, run the `dfx deploy` command with the `--network ic` flag: ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +dfx deploy evm_rpc --network ic --argument '(record { nodesInSubnet = 13 })' ``` -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Additional parameters; none are specified in this example. -- `id`: id of the request. - -Additionally, the flags used are: +Note that when deploying your own canister, you may encounter API rate limits. Refer to the [Replacing API keys](#replacing-api-keys) section to learn how to configure API credentials. -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +## Example usage -### eth_getLogs - -To query the logs of a specific transaction, make a call to the `eth_getLogs` JSON-RPC method: - -``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\",\"params\":[{\"topics\":[\"0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b\"]}],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` +```bash +# Configuration +NETWORK=local +IDENTITY=default +CYCLES=1000000000 +WALLET=$(dfx identity get-wallet) +RPC_SOURCE=EthMainnet +JSON_RPC_SOURCE=Chain=1 +RPC_CONFIG=null -In this request, the following configuration is passed: +# Get event logs for smart contract `0xdAC1...1ec7` +dfx canister call evm_rpc eth_getLogs "(variant {$CANDID_SOURCE}, $RPC_CONFIG, record {addresses = vec {\"0xdAC17F958D2ee523a2206206994597C13D831ec7\"}})" --with-cycles=$CYCLES --wallet=$WALLET -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies a 'topic' value. A topic is an array of 32 bytes of data. Additional parameters can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getlogs) -- `id`: id of the request. +# Get the latest Ethereum block info +dfx canister call evm_rpc eth_getBlockByNumber "(variant {$CANDID_SOURCE}, $RPC_CONFIG, variant {Latest})" --with-cycles=$CYCLES --wallet=$WALLET -Additionally, the flags used are: +# Get receipt for transaction `0xdd5d...4746f` +dfx canister call evm_rpc eth_getTransactionReceipt "(variant {$CANDID_SOURCE}, $RPC_CONFIG, \"0xdd5d4b18923d7aae953c7996d791118102e889bea37b48a651157a4890e4746f\")" --with-cycles=$CYCLES --wallet=$WALLET -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +# Get number of transactions for contract `0xdAC1...1ec7` +dfx canister call evm_rpc eth_getTransactionCount "(variant {$CANDID_SOURCE}, $RPC_CONFIG, record {address = \"0xdAC17F958D2ee523a2206206994597C13D831ec7\"; block = variant {Latest}})" --with-cycles=$CYCLES --wallet=$WALLET -### eth_getBlockByNumber +# Get the fee history for the last 3 Ethereum blocks +dfx canister call evm_rpc eth_feeHistory "(variant {$CANDID_SOURCE}, $RPC_CONFIG, record {blockCount = 3; newestBlock = variant {Latest}})" --with-cycles=$CYCLES --wallet=$WALLET -To query information about a block, make a call to the `eth_getBlockByNumber` JSON-RPC method: +# Send a raw transaction +dfx canister call evm_rpc eth_sendRawTransaction "(variant {$SOURCE}, $RPC_CONFIG, \"0xf86c098504a817c800825208943535353535353535353535353535353535353535880de0b6b3a76400008025a028ef61340bd939bc2195fe537567866003e1a15d3c71ff63e1590620aa636276a067cbe9d8997f761aecb703304b3800ccf555c9f3dc64214b297fb1966a3b6d83\")" --with-cycles=$CYCLES --wallet=$WALLET +# Send a raw JSON-RPC request +dfx canister call evm_rpc request "(variant {$JSON_RPC_SOURCE}, "'"{ \"jsonrpc\": \"2.0\", \"method\": \"eth_gasPrice\", \"params\": [], \"id\": 1 }"'", 1000)" --with-cycles=$CYCLES --wallet=$WALLET ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getBlockByNumber\",\"params\":[\"0x1b4\", true],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies a block number, or the string "earliest", "latest," or "pending". Specifies a boolean of "true" or "false," where true returns the full transaction objects and false only returns the hashes of the transactions. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getblockbynumber) -- `id`: id of the request. -Additionally, the flags used are: -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +## Custom JSON-RPC requests -### eth_getTransactionReceipt +Send a raw JSON-RPC request to a custom URL with the `request` method: -To query a transaction receipt, make a call to the `eth_getTransactionReceipt` JSON-RPC method: - -``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionReceipt\",\"params\":[\"0x85d995eba9763907fdf35cd2034144dd9d53ce32cbec21349d4b12823c6860c5\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +```bash +dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 100000000 request '(variant {Custom={url = "https://ethereum.publicnode.com"}},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' ``` -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the hash of a transaction. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getblockbynumber) -- `id`: id of the request. +## Specifying an EVM chain -Additionally, the flags used are: - -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). - -### eth_feeHistory - -To return a collection of historical gas information, make a call to the `eth_feeHistory` JSON-RPC method: +To use a specific EVM chain, specify the chain's ID in the `Chain` variant: ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_feeHistory\",\"params\":[\"4\",\"4\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +dfx canister call evm_rpc --wallet $(dfx identity get-wallet) --with-cycles 100000000 request '(variant {Chain=0x1},"{\"jsonrpc\":\"2.0\",\"method\":\"eth_gasPrice\",\"params\":[],\"id\":1}",1000)' ``` -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the number of blocks in the request range and the highest block of that requested range. Additional information can be found in the [JSON RPC documentation.](https://docs.alchemy.com/reference/eth-feehistory) -- `id`: id of the request. - -Additionally, the flags used are: - -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). - +## Specifying an RPC provider -### eth_sendRawTransaction +You can also specify an RPC provider: -To submit a raw transaction, make a call to the `eth_sendRawTransaction` JSON-RPC method: +```candid +type JsonRpcSource = variant { + Chain : nat64; + Provider : nat64; + Custom : record { url : text; headers : vec (text, text) }; +}; +request : ( + source : JsonRpcSource, + jsonRequest : text, + maxResponseBytes : nat64 +) -> ( + Result +); ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_sendRawTransaction\",\"params\":[\"0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the signed transaction data. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_sendrawtransaction) -- `id`: id of the request. +## Registering your own provider -Additionally, the flags used are: +To register your own RPC provider in your local replica, you can use the following commands: -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). - -### eth_getTransactionCount - -To return the amount of transactions sent from an address, make a call to the `eth_getTransactionCount` JSON-RPC method: +```bash +# Authorize your dfx identity to add an RPC provider +OWNER_PRINCIPAL=$(dfx identity get-principal) +dfx canister call evm_rpc authorize "(principal \"$OWNER_PRINCIPAL\", variant { RegisterProvider })" +# Register a provider +dfx canister call evm_rpc registerProvider '(record { chainId=1; hostname="cloudflare-eth.com"; credentialPath="/v1/mainnet"; cyclesPerCall=1000; cyclesPerMessageByte=100; })' ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"0x407d73d8a49eeb85d32cf465507dd71d507100c1\",\"latest\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the address to query and the "latest", "earliest", or "pending" filter for transactions. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_gettransactioncount) -- `id`: id of the request. +The `registerProvider` command has the following input parameters: -Additionally, the flags used are: +- `chainId`: The ID of the blockchain network. +- `hostname`: The JSON-RPC API hostname. +- `credentialPath`: The path to the RPC authentication. +- `cyclesPerCall`: The amount of cycles charged per RPC call. +- `cyclesPerMessageByte`: The amount of cycles charged per message byte. -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +## Replacing API keys -### eth_call +If you want to add or change the API key in your local replica or a deployed fork of the canister, the first step is to determine the relevant `providerId` for the API. -To execute a new message without creating a transaction (often used for read-only functions), make a call to the `eth_call` JSON-RPC method: +Run the following command to view all registered providers: +```bash +dfx canister call evm_rpc getProviders ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_call\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_call) -- `id`: id of the request. -Additionally, the flags used are: - -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). - -### eth_getStorageAt - -To return the value of a storage position, make a call to the `eth_getStorageAt` JSON-RPC method: +You should see a list of values. Look for the `providerId`, which in this case is `0`: ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getStorageAt\",\"params\":["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +( + vec { + record { + cyclesPerCall = 0 : nat64; + owner = principal "k3uua-wskan-xmpt3-e5bpx-ibj67-azbop-s26l5-kaakn-64bvk-y4jlc-oqe"; + hostname = "cloudflare-eth.com"; + primary = false; + chainId = 1 : nat64; + cyclesPerMessageByte = 0 : nat64; + providerId = 0 : nat64; + }; + } +) ``` -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the contract address, integer of the position in the storage, and integer block number or string "latest", "earliest", or "pending" status. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getstorageat) -- `id`: id of the request. - -Additionally, the flags used are: - -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). - - -### eth_estimateGas - -To estimate the gas fee, make a call to the `eth_estimateGas` JSON-RPC method: +Update the configuration for an existing provider using the `updateProvider` method: +```bash +dfx canister call evm_rpc updateProvider '(record { providerId = 0; credentialPath = opt "/path/to/YOUR-API-KEY" })' ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_estimateGas\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: All parameters are optional. Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_estimategas) -- `id`: id of the request. - -Additionally, the flags used are: - -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +Note that `credentialPath` should include everything after the hostname. For example, an RPC provider with hostname `rpc.example.org` and credential path `/path/to/secret` will resolve to `https://rpc.example.org/path/to/secret`. -### eth_blockNumber +Some RPC services expect the API key in a request header instead of a URI path. In this case, use a command such as the following: -To return the most recent block number, make a call to the `eth_blockNumber` JSON-RPC method: - -``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 +```bash +dfx canister call evm_rpc updateProvider '(record { providerId = 0; credentialHeaders = opt vec { record { name = "HEADER_NAME"; value = "HEADER_VALUE" } } })' ``` -In this request, the following configuration is passed: +## Important notes -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: No parameters. -- `id`: id of the request. +### HTTP outcall consensus -Additionally, the flags used are: +Be sure to verify that RPC requests work as expected on the ICP mainnet. HTTP outcalls performed in the `request` method only reach consensus if the JSON-RPC response is the same each call. -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +If you encounter an issue with consensus, [please let us know](https://github.com/dfinity/evm-rpc-canister) and we will look into whether it's possible to add official support for your use case. -### eth_getCode +### Response size estimates -To return the code for an address, make a call to the `eth_getCode` JSON-RPC method: +In some cases, it's necessary to perform multiple HTTP outcalls with increasing maximum response sizes to complete a request. This is relatively common for the `eth_getLogs` method and may increase the time and cost of performing an RPC call. One solution is to specify an initial response size estimate (in bytes): +```bash +dfx canister call evm_rpc eth_getLogs "(variant {EthMainnet}, record {responseSizeEstimate = 5000}, record {addresses = vec {\"0xdAC17F958D2ee523a2206206994597C13D831ec7\"}})" --with-cycles=1000000000 --wallet=$(dfx identity get-wallet) ``` -dfx canister call evm_rpc --network ic request '(variant {Url="https://cloudflare-eth.com/v1/mainnet"}, "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getCode\",\"params\":[\"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b\", \"0x2\"],\"id\":1}", 1000)' --wallet $(dfx identity get-wallet) --with-cycles 600000000 -``` - -In this request, the following configuration is passed: - -- `Url`: The URL of the RPC service. -- `jsonrpc`: The version of JSON-RPC used. -- `method`: The RPC method being called. -- `params`: Specifies the address and the integer block number of string "latest", "earliest", or "pending". Additional information can be found in the [JSON RPC documentation.](https://ethereum.org/en/developers/docs/apis/json-rpc#eth_getcode) -- `id`: id of the request. - -Additionally, the flags used are: -- `wallet`: The cycles wallet associated with the current dfx identity. -- `with-cycles`: The amount of cycles to send with the call. Sending cycles with the call is necessary to pay for the RPC call. Learn more about [RPC costs](overview.md). +If the response is larger than the estimate, the canister will double the max response size and retry until either receiving a response or running out of cycles given by the `--with-cycles` flag. diff --git a/docs/developer-docs/integrations/ethereum/overview.md b/docs/developer-docs/integrations/ethereum/overview.md index fe3ae1c692..ed1516eb4d 100644 --- a/docs/developer-docs/integrations/ethereum/overview.md +++ b/docs/developer-docs/integrations/ethereum/overview.md @@ -1,14 +1,14 @@ # Overview -Canisters deployed on ICP are able to communicate with the Ethereum blockchain and other EVM-compatible networks using the EVM RPC canister. The EVM RPC canister implements an on-chain API that facilitates API requests to JSON-RPC services like Alchemy, Ankr, and Cloudflare WEb3. It also supports BlockPI requests using the ICP feature HTTPS outcalls. +Canisters deployed on ICP are able to communicate with the Ethereum blockchain and other EVM-compatible networks using the EVM RPC canister. This canister facilitates API requests to JSON-RPC services such as [CloudFlare](https://www.cloudflare.com/en-gb/web3/), [Alchemy](https://www.alchemy.com/), [Ankr](https://www.ankr.com/), [BlockPI](https://blockpi.io/), or [Public Node](https://www.publicnode.com/) using [HTTPS outcalls](https://internetcomputer.org/https-outcalls). -This integration enables canisters to use Ethereum similar to dapps deployed directly on Ethereum. ICP canisters can query info such as Ethereum smart contract states and submit raw transactions to the Ethereum network. +This enables functionality similar to traditional Ethereum dapps, including querying Ethereum smart contract states and submitting raw transactions. -The EVM-RPC canister supports [other EVM chains](https://chainlist.org/?testnets=true) such as Polygon and Avalanche. +Beyond the Ethereum blockchain, this canister also has partial support for Polygon, Avalanche, and other popular EVM networks. Check out [ChainList.org](https://chainlist.org/?testnets=true) for an extensive list of compatible networks and RPC providers. This integration allows for the implementation of ckETH, a chain-key twin of the ETH token. -You can [learn how to use the EVM RPC canister](evm-rpc.md) +You can [learn how to use the EVM RPC canister](evm-rpc.md). ## Costs @@ -20,4 +20,4 @@ An approximate cost breakdown in USD can be found below. These costs are estimat - JSON Request: $0.00008 USD per KiB - JSON Response: $0.00008 USD per KiB -These costs are paid by sending cycles with each RPC call using the `--with-cycles` flag. Learn more about [cycles](/docs/current/developer-docs/gas-cost). \ No newline at end of file +These costs are paid by sending cycles with each RPC call using the `--with-cycles` flag. Learn more about [cycles](/docs/current/developer-docs/gas-cost). From 28ca323b5c05abbe65fb58c7ccda93828f8d926f Mon Sep 17 00:00:00 2001 From: Ryan Vandersmith Date: Wed, 31 Jan 2024 09:18:31 -0700 Subject: [PATCH 5/7] Update docs/developer-docs/integrations/ethereum/evm-rpc.md --- docs/developer-docs/integrations/ethereum/evm-rpc.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md index 75d77ff65a..ff2df61592 100644 --- a/docs/developer-docs/integrations/ethereum/evm-rpc.md +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -208,6 +208,16 @@ dfx canister call evm_rpc updateProvider '(record { providerId = 0; credentialHe ## Important notes +### RPC result consistency + +When calling RPC methods directly through the Candid interface (rather than via the `request` method), the canister will compare results from several JSON-RPC APIs and return a `Consistent` or `Inconsistent` variant based on whether the APIs agree on the result. + +By default, the canister uses three different RPC providers, which may change depending on availability. It's possible to specify which providers to use for this consistency check. For example: + +```bash +dfx canister call evm_rpc eth_getTransactionCount '(variant {EthMainnet = opt vec {Cloudflare; PublicNode}}, record {address = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; block = variant {Tag = variant {Latest}}})' --with-cycles 100000000000 --wallet=$(dfx identity get-wallet) +``` + ### HTTP outcall consensus Be sure to verify that RPC requests work as expected on the ICP mainnet. HTTP outcalls performed in the `request` method only reach consensus if the JSON-RPC response is the same each call. From c6b4db62c6e2f2f72bbae90b77f0a2cdcec422ac Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 31 Jan 2024 17:00:15 -0700 Subject: [PATCH 6/7] Update mainnet canister ID --- docs/developer-docs/integrations/ethereum/evm-rpc.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/developer-docs/integrations/ethereum/evm-rpc.md b/docs/developer-docs/integrations/ethereum/evm-rpc.md index 75d77ff65a..22c3805dea 100644 --- a/docs/developer-docs/integrations/ethereum/evm-rpc.md +++ b/docs/developer-docs/integrations/ethereum/evm-rpc.md @@ -43,7 +43,7 @@ To include the EVM RPC canister in a [dfx](https://internetcomputer.org/docs/cur "wasm": "https://github.com/dfinity/evm-rpc-canister/releases/latest/download/evm_rpc_dev.wasm.gz", "remote": { "id": { - "ic": "a6d44-nyaaa-aaaap-abp7q-cai" + "ic": "7hfb6-caaaa-aaaar-qadga-cai" } } } @@ -208,6 +208,16 @@ dfx canister call evm_rpc updateProvider '(record { providerId = 0; credentialHe ## Important notes +### RPC result consistency + +When calling RPC methods directly through the Candid interface (rather than via the `request` method), the canister will compare results from several JSON-RPC APIs and return a `Consistent` or `Inconsistent` variant based on whether the APIs agree on the result. + +By default, the canister uses three different RPC providers, which may change depending on availability. It's possible to specify which providers to use for this consistency check. For example: + +```bash +dfx canister call evm_rpc eth_getTransactionCount '(variant {EthMainnet = opt vec {Cloudflare; PublicNode}}, record {address = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; block = variant {Tag = variant {Latest}}})' --with-cycles 100000000000 --wallet=$(dfx identity get-wallet) +``` + ### HTTP outcall consensus Be sure to verify that RPC requests work as expected on the ICP mainnet. HTTP outcalls performed in the `request` method only reach consensus if the JSON-RPC response is the same each call. From 1cb12277d65c54719c5edc264c51e6671bdb52f5 Mon Sep 17 00:00:00 2001 From: rvanasa Date: Wed, 31 Jan 2024 17:19:33 -0700 Subject: [PATCH 7/7] Update 'Costs' section --- docs/developer-docs/integrations/ethereum/overview.md | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/docs/developer-docs/integrations/ethereum/overview.md b/docs/developer-docs/integrations/ethereum/overview.md index ed1516eb4d..cae26bc9cc 100644 --- a/docs/developer-docs/integrations/ethereum/overview.md +++ b/docs/developer-docs/integrations/ethereum/overview.md @@ -12,12 +12,6 @@ You can [learn how to use the EVM RPC canister](evm-rpc.md). ## Costs -An approximate cost breakdown in USD can be found below. These costs are estimated using the Cloudflare RPC with a 13-node subnet: +JSON-RPC requests typically cost between 10^8 and 10^9 cycles, which is equivalent to approximately $0.0001 - $0.001 USD. -- JSON-RPC API request: $0.0001 USD -- HTTPS outcalls: $0.001 USD (This assumes 1KiB request and 1KiB response) -- Base cost: $0.0008 USD -- JSON Request: $0.00008 USD per KiB -- JSON Response: $0.00008 USD per KiB - -These costs are paid by sending cycles with each RPC call using the `--with-cycles` flag. Learn more about [cycles](/docs/current/developer-docs/gas-cost). +These costs are paid by sending cycles with each RPC call, such as by using the `--with-cycles` flag when calling a canister with [dfx](https://internetcomputer.org/docs/current/references/cli-reference/dfx-canister#dfx-canister-call). Learn more about [cycles](/docs/current/developer-docs/gas-cost).