From bb7c74a122e40980ad416c4e7c0cb201a2861e18 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Fri, 15 Mar 2024 09:05:37 +0000 Subject: [PATCH 1/9] add contract examples --- README.md | 14 +- examples/contracts/Cargo.toml | 25 ++ examples/contracts/examples/abi/Counter.json | 35 +++ examples/contracts/examples/abi/IERC20.json | 279 ++++++++++++++++++ .../contracts/examples/artifacts/Counter.json | 134 +++++++++ .../examples/deploy_from_artifact.rs | 70 +++++ .../examples/deploy_from_contract.rs | 80 +++++ examples/contracts/examples/generate.rs | 38 +++ 8 files changed, 665 insertions(+), 10 deletions(-) create mode 100644 examples/contracts/Cargo.toml create mode 100644 examples/contracts/examples/abi/Counter.json create mode 100644 examples/contracts/examples/abi/IERC20.json create mode 100644 examples/contracts/examples/artifacts/Counter.json create mode 100644 examples/contracts/examples/deploy_from_artifact.rs create mode 100644 examples/contracts/examples/deploy_from_contract.rs create mode 100644 examples/contracts/examples/generate.rs diff --git a/README.md b/README.md index 3d3de244..3ec5625d 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,10 @@ cargo run --example mnemonic_signer - [ ] Creating Instances - [ ] Math operations - [ ] Utilities -- [ ] Contracts - - [ ] Abigen - - [ ] Compile - - [ ] Creating Instances - - [ ] Deploy Anvil - - [ ] Deploy from ABI and bytecode - - [ ] Deploy Moonbeam - - [ ] Events - - [ ] Events with meta - - [ ] Methods +- [x] Contracts + - [x] [Deploy from artifact](./examples/contracts/examples/deploy_from_artifact.rs) + - [x] [Deploy from contract](./examples/contracts/examples/deploy_from_contract.rs) + - [x] [Generate](./examples/contracts/examples/generate.rs) - [ ] Events - [ ] Logs and filtering - [ ] Solidity topics diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml new file mode 100644 index 00000000..cb195418 --- /dev/null +++ b/examples/contracts/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "examples-contracts" + +publish.workspace = true +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dev-dependencies] +alloy-contract.workspace = true +alloy-network.workspace = true +alloy-node-bindings.workspace = true +alloy-primitives.workspace = true +alloy-provider.workspace = true +alloy-rpc-client.workspace = true +alloy-signer.workspace = true +alloy-sol-types = { workspace = true, features = ["json"] } +alloy-transport-http.workspace = true + +reqwest.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/examples/contracts/examples/abi/Counter.json b/examples/contracts/examples/abi/Counter.json new file mode 100644 index 00000000..b6c39c5f --- /dev/null +++ b/examples/contracts/examples/abi/Counter.json @@ -0,0 +1,35 @@ +[ + { + "type": "function", + "name": "increment", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "number", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setNumber", + "inputs": [ + { + "name": "newNumber", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + } +] \ No newline at end of file diff --git a/examples/contracts/examples/abi/IERC20.json b/examples/contracts/examples/abi/IERC20.json new file mode 100644 index 00000000..37f31f97 --- /dev/null +++ b/examples/contracts/examples/abi/IERC20.json @@ -0,0 +1,279 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "guy", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "src", + "type": "address" + }, + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "wad", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "dst", + "type": "address" + }, + { + "name": "wad", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "deposit", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + }, + { + "name": "", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": true, + "name": "guy", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": true, + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "dst", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "src", + "type": "address" + }, + { + "indexed": false, + "name": "wad", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + } +] \ No newline at end of file diff --git a/examples/contracts/examples/artifacts/Counter.json b/examples/contracts/examples/artifacts/Counter.json new file mode 100644 index 00000000..3c90354e --- /dev/null +++ b/examples/contracts/examples/artifacts/Counter.json @@ -0,0 +1,134 @@ +{ + "abi": [ + { + "type": "function", + "name": "increment", + "inputs": [], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "number", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "setNumber", + "inputs": [ + { + "name": "newNumber", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + } + ], + "bytecode": { + "object": "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220f90c910068fe53f64c8ae6b87a01287f43bbafbff9a3bceded7c441b71ceb3c364736f6c63430008180033", + "sourceMap": "65:192:22:-:0;;;;;;;;;;;;;;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220f90c910068fe53f64c8ae6b87a01287f43bbafbff9a3bceded7c441b71ceb3c364736f6c63430008180033", + "sourceMap": "65:192:22:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116:80;;;;;;:::i;:::-;171:6;:18;116:80;;;88:21;;;;;;;;;345:25:24;;;333:2;318:18;88:21:22;;;;;;;202:53;;240:6;:8;;;:6;:8;;;:::i;:::-;;;;;;202:53::o;14:180:24:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;-1:-1:-1;165:23:24;;14:180;-1:-1:-1;14:180:24:o;381:232::-;420:3;441:17;;;438:140;;500:10;495:3;491:20;488:1;481:31;535:4;532:1;525:15;563:4;560:1;553:15;438:140;-1:-1:-1;605:1:24;594:13;;381:232::o", + "linkReferences": {} + }, + "methodIdentifiers": { + "increment()": "d09de08a", + "number()": "8381f58a", + "setNumber(uint256)": "3fb5c1cb" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.24+commit.e11b9ed9\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"increment\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"number\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newNumber\",\"type\":\"uint256\"}],\"name\":\"setNumber\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/Counter.sol\":\"Counter\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":forge-std/=lib/forge-std/src/\"]},\"sources\":{\"src/Counter.sol\":{\"keccak256\":\"0x09277f949d59a9521708c870dc39c2c434ad8f86a5472efda6a732ef728c0053\",\"license\":\"UNLICENSED\",\"urls\":[\"bzz-raw://94cd5258357da018bf911aeda60ed9f5b130dce27445669ee200313cd3389200\",\"dweb:/ipfs/QmNbEfWAqXCtfQpk6u7TpGa8sTHXFLpUz7uebz2FVbchSC\"]}},\"version\":1}", + "metadata": { + "compiler": { + "version": "0.8.24+commit.e11b9ed9" + }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "function", + "name": "increment" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "number", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ] + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newNumber", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setNumber" + } + ], + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + } + }, + "settings": { + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/" + ], + "optimizer": { + "enabled": true, + "runs": 200 + }, + "metadata": { + "bytecodeHash": "ipfs" + }, + "compilationTarget": { + "src/Counter.sol": "Counter" + }, + "evmVersion": "paris", + "libraries": {} + }, + "sources": { + "src/Counter.sol": { + "keccak256": "0x09277f949d59a9521708c870dc39c2c434ad8f86a5472efda6a732ef728c0053", + "urls": [ + "bzz-raw://94cd5258357da018bf911aeda60ed9f5b130dce27445669ee200313cd3389200", + "dweb:/ipfs/QmNbEfWAqXCtfQpk6u7TpGa8sTHXFLpUz7uebz2FVbchSC" + ], + "license": "UNLICENSED" + } + }, + "version": 1 + }, + "id": 22 +} \ No newline at end of file diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs new file mode 100644 index 00000000..581d8c2e --- /dev/null +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -0,0 +1,70 @@ +//! Example of deploying a contract from an artifact to Anvil and interacting with it. + +use alloy_network::EthereumSigner; +use alloy_node_bindings::Anvil; +use alloy_primitives::{U256, U64}; +use alloy_provider::{Provider, ProviderBuilder, RootProvider}; +use alloy_rpc_client::RpcClient; +use alloy_signer::LocalWallet; +use alloy_sol_types::sol; +use alloy_transport_http::Http; +use reqwest::Client; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Codegen from artifact. + sol!( + #[sol(rpc)] + Counter, + "examples/artifacts/Counter.json" + ); + + // Spin up a local Anvil node. + // Ensure `anvil` is available in $PATH + let anvil = Anvil::new().spawn(); + + // Set up wallet + let wallet: LocalWallet = anvil.keys()[0].clone().into(); + + // Create a provider with a signer and the network. + let http = Http::::new(anvil.endpoint().parse()?); + let provider = ProviderBuilder::new() + .signer(EthereumSigner::from(wallet)) + .provider(RootProvider::new(RpcClient::new(http, true))); + + println!("Anvil running at `{}`", anvil.endpoint()); + + // Get the base fee for the block. + let base_fee = provider.get_gas_price().await?; + + // Deploy the contract. + let contract_builder = Counter::deploy_builder(&provider); + let estimate = contract_builder.estimate_gas().await?; + let contract_address = + contract_builder.gas(estimate).gas_price(base_fee).nonce(U64::from(0)).deploy().await?; + + println!("Deployed contract at address: {:?}", contract_address); + + let contract = Counter::new(contract_address, &provider); + + let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?; + let builder = + contract.setNumber(U256::from(42)).nonce(U64::from(1)).gas(estimate).gas_price(base_fee); + let receipt = builder.send().await?.get_receipt().await?; + + println!("Set number to 42: {:?}", receipt.transaction_hash.unwrap()); + + // Increment the number to 43. + let estimate = contract.increment().estimate_gas().await?; + let builder = contract.increment().nonce(U64::from(2)).gas(estimate).gas_price(base_fee); + let receipt = builder.send().await?.get_receipt().await?; + + println!("Incremented number: {:?}", receipt.transaction_hash.unwrap()); + + // Retrieve the number, which should be 43. + let Counter::numberReturn { _0 } = contract.number().call().await?; + + println!("Retrieved number: {:?}", _0.to_string()); + + Ok(()) +} diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs new file mode 100644 index 00000000..54c14e8d --- /dev/null +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -0,0 +1,80 @@ +//! Example of deploying a contract from Solidity code to Anvil and interacting with it. + +use alloy_network::EthereumSigner; +use alloy_node_bindings::Anvil; +use alloy_primitives::{U256, U64}; +use alloy_provider::{Provider, ProviderBuilder, RootProvider}; +use alloy_rpc_client::RpcClient; +use alloy_signer::LocalWallet; +use alloy_sol_types::sol; +use alloy_transport_http::Http; +use reqwest::Client; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Codegen from embedded Solidity code and precompiled bytecode. + sol! { + // solc v0.8.24; solc a.sol --via-ir --optimize --bin + #[sol(rpc, bytecode="608080604052346100155760d2908161001a8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c9081633fb5c1cb1460865781638381f58a14606f575063d09de08a146039575f80fd5b34606b575f366003190112606b575f545f1981146057576001015f55005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b34606b575f366003190112606b576020905f548152f35b34606b576020366003190112606b576004355f5500fea2646970667358221220bdecd3c1dd631eb40587cafcd6e8297479db76db6a328e18ad1ea5b340852e3864736f6c63430008180033")] + contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } + } + } + + // Spin up a local Anvil node. + // Ensure `anvil` is available in $PATH + let anvil = Anvil::new().spawn(); + + // Set up wallet + let wallet: LocalWallet = anvil.keys()[0].clone().into(); + + // Create a provider with a signer and the network. + let http = Http::::new(anvil.endpoint().parse()?); + let provider = ProviderBuilder::new() + .signer(EthereumSigner::from(wallet)) + .provider(RootProvider::new(RpcClient::new(http, true))); + + println!("Anvil running at `{}`", anvil.endpoint()); + + // Get the base fee for the block. + let base_fee = provider.get_gas_price().await?; + + // Deploy the contract. + let contract_builder = Counter::deploy_builder(&provider); + let estimate = contract_builder.estimate_gas().await?; + let contract_address = + contract_builder.gas(estimate).gas_price(base_fee).nonce(U64::from(0)).deploy().await?; + + println!("Deployed contract at address: {:?}", contract_address); + + let contract = Counter::new(contract_address, &provider); + + let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?; + let builder = + contract.setNumber(U256::from(42)).nonce(U64::from(1)).gas(estimate).gas_price(base_fee); + let receipt = builder.send().await?.get_receipt().await?; + + println!("Set number to 42: {:?}", receipt.transaction_hash.unwrap()); + + // Increment the number to 43. + let estimate = contract.increment().estimate_gas().await?; + let builder = contract.increment().nonce(U64::from(2)).gas(estimate).gas_price(base_fee); + let receipt = builder.send().await?.get_receipt().await?; + + println!("Incremented number: {:?}", receipt.transaction_hash.unwrap()); + + // Retrieve the number, which should be 43. + let Counter::numberReturn { _0 } = contract.number().call().await?; + + println!("Retrieved number: {:?}", _0.to_string()); + + Ok(()) +} diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs new file mode 100644 index 00000000..0f02b479 --- /dev/null +++ b/examples/contracts/examples/generate.rs @@ -0,0 +1,38 @@ +//! Example of generating code from ABI file to interact with the contract. + +use alloy_network::Ethereum; +use alloy_node_bindings::Anvil; +use alloy_provider::{ProviderBuilder, RootProvider}; +use alloy_rpc_client::RpcClient; +use alloy_sol_types::sol; +use alloy_transport_http::Http; +use reqwest::Client; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Codegen from ABI file to interact with the contract. + sol!( + #[sol(rpc)] + IERC20, + "examples/abi/IERC20.json" + ); + + // Spin up a forked Anvil node. + // Ensure `anvil` is available in $PATH + let anvil = Anvil::new().fork("https://eth.llamarpc.com").spawn(); + + // Create a provider. + let http = Http::::new(anvil.endpoint().parse()?); + let provider = ProviderBuilder::<_, Ethereum>::new() + .provider(RootProvider::new(RpcClient::new(http, true))); + + // Create a contract instance. + let contract = IERC20::new("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?, provider); + + // Call the contract, retrieve the total supply. + let IERC20::totalSupplyReturn { _0 } = contract.totalSupply().call().await?; + + println!("WETH total supply is {_0}"); + + Ok(()) +} From e0f36372c3b079215f669b1e1e05a084b688691a Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Fri, 15 Mar 2024 09:41:43 +0000 Subject: [PATCH 2/9] upgrade to e7dfb4f --- examples/contracts/Cargo.toml | 2 +- examples/contracts/examples/deploy_from_artifact.rs | 2 +- examples/contracts/examples/deploy_from_contract.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml index cb195418..8cfa704a 100644 --- a/examples/contracts/Cargo.toml +++ b/examples/contracts/Cargo.toml @@ -17,7 +17,7 @@ alloy-node-bindings.workspace = true alloy-primitives.workspace = true alloy-provider.workspace = true alloy-rpc-client.workspace = true -alloy-signer.workspace = true +alloy-signer-wallet.workspace = true alloy-sol-types = { workspace = true, features = ["json"] } alloy-transport-http.workspace = true diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index 581d8c2e..eb2013ba 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -5,7 +5,7 @@ use alloy_node_bindings::Anvil; use alloy_primitives::{U256, U64}; use alloy_provider::{Provider, ProviderBuilder, RootProvider}; use alloy_rpc_client::RpcClient; -use alloy_signer::LocalWallet; +use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; use alloy_transport_http::Http; use reqwest::Client; diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 54c14e8d..07cf8b8d 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -5,7 +5,7 @@ use alloy_node_bindings::Anvil; use alloy_primitives::{U256, U64}; use alloy_provider::{Provider, ProviderBuilder, RootProvider}; use alloy_rpc_client::RpcClient; -use alloy_signer::LocalWallet; +use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; use alloy_transport_http::Http; use reqwest::Client; From 4eecaaa8824c1c20d10062bc2fb12ccca49e298f Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Fri, 15 Mar 2024 10:07:50 +0000 Subject: [PATCH 3/9] add eyre and update examples --- examples/contracts/Cargo.toml | 1 + examples/contracts/examples/deploy_from_artifact.rs | 3 ++- examples/contracts/examples/deploy_from_contract.rs | 3 ++- examples/contracts/examples/generate.rs | 3 ++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml index 8cfa704a..038d9c04 100644 --- a/examples/contracts/Cargo.toml +++ b/examples/contracts/Cargo.toml @@ -21,5 +21,6 @@ alloy-signer-wallet.workspace = true alloy-sol-types = { workspace = true, features = ["json"] } alloy-transport-http.workspace = true +eyre.workspace = true reqwest.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index eb2013ba..029297bf 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -8,10 +8,11 @@ use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; use alloy_transport_http::Http; +use eyre::Result; use reqwest::Client; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { // Codegen from artifact. sol!( #[sol(rpc)] diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 07cf8b8d..7a1e5048 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -8,10 +8,11 @@ use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; use alloy_transport_http::Http; +use eyre::Result; use reqwest::Client; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { // Codegen from embedded Solidity code and precompiled bytecode. sol! { // solc v0.8.24; solc a.sol --via-ir --optimize --bin diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index 0f02b479..7912b1fc 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -6,10 +6,11 @@ use alloy_provider::{ProviderBuilder, RootProvider}; use alloy_rpc_client::RpcClient; use alloy_sol_types::sol; use alloy_transport_http::Http; +use eyre::Result; use reqwest::Client; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { // Codegen from ABI file to interact with the contract. sol!( #[sol(rpc)] From d130362e4bbe288416f2d61be2489744d10e7023 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Mon, 18 Mar 2024 09:05:37 +0000 Subject: [PATCH 4/9] move out macros of main --- .../examples/deploy_from_artifact.rs | 14 ++++---- .../examples/deploy_from_contract.rs | 32 +++++++++---------- examples/contracts/examples/generate.rs | 14 ++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index 029297bf..a5862712 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -11,15 +11,15 @@ use alloy_transport_http::Http; use eyre::Result; use reqwest::Client; +// Codegen from artifact. +sol!( + #[sol(rpc)] + Counter, + "examples/artifacts/Counter.json" +); + #[tokio::main] async fn main() -> Result<()> { - // Codegen from artifact. - sol!( - #[sol(rpc)] - Counter, - "examples/artifacts/Counter.json" - ); - // Spin up a local Anvil node. // Ensure `anvil` is available in $PATH let anvil = Anvil::new().spawn(); diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 7a1e5048..268e9a3f 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -11,25 +11,25 @@ use alloy_transport_http::Http; use eyre::Result; use reqwest::Client; -#[tokio::main] -async fn main() -> Result<()> { - // Codegen from embedded Solidity code and precompiled bytecode. - sol! { - // solc v0.8.24; solc a.sol --via-ir --optimize --bin - #[sol(rpc, bytecode="608080604052346100155760d2908161001a8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c9081633fb5c1cb1460865781638381f58a14606f575063d09de08a146039575f80fd5b34606b575f366003190112606b575f545f1981146057576001015f55005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b34606b575f366003190112606b576020905f548152f35b34606b576020366003190112606b576004355f5500fea2646970667358221220bdecd3c1dd631eb40587cafcd6e8297479db76db6a328e18ad1ea5b340852e3864736f6c63430008180033")] - contract Counter { - uint256 public number; - - function setNumber(uint256 newNumber) public { - number = newNumber; - } - - function increment() public { - number++; - } +// Codegen from embedded Solidity code and precompiled bytecode. +sol! { + // solc v0.8.24; solc a.sol --via-ir --optimize --bin + #[sol(rpc, bytecode="608080604052346100155760d2908161001a8239f35b5f80fdfe60808060405260043610156011575f80fd5b5f3560e01c9081633fb5c1cb1460865781638381f58a14606f575063d09de08a146039575f80fd5b34606b575f366003190112606b575f545f1981146057576001015f55005b634e487b7160e01b5f52601160045260245ffd5b5f80fd5b34606b575f366003190112606b576020905f548152f35b34606b576020366003190112606b576004355f5500fea2646970667358221220bdecd3c1dd631eb40587cafcd6e8297479db76db6a328e18ad1ea5b340852e3864736f6c63430008180033")] + contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; } } +} +#[tokio::main] +async fn main() -> Result<()> { // Spin up a local Anvil node. // Ensure `anvil` is available in $PATH let anvil = Anvil::new().spawn(); diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index 7912b1fc..450e5bfa 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -9,15 +9,15 @@ use alloy_transport_http::Http; use eyre::Result; use reqwest::Client; +// Codegen from ABI file to interact with the contract. +sol!( + #[sol(rpc)] + IERC20, + "examples/abi/IERC20.json" +); + #[tokio::main] async fn main() -> Result<()> { - // Codegen from ABI file to interact with the contract. - sol!( - #[sol(rpc)] - IERC20, - "examples/abi/IERC20.json" - ); - // Spin up a forked Anvil node. // Ensure `anvil` is available in $PATH let anvil = Anvil::new().fork("https://eth.llamarpc.com").spawn(); From 8ac4bf8664dfc962e445ec6d8c67ff9fb00f0921 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Mon, 18 Mar 2024 10:03:52 +0000 Subject: [PATCH 5/9] spawn -> try_spawn --- examples/contracts/examples/deploy_from_artifact.rs | 2 +- examples/contracts/examples/deploy_from_contract.rs | 2 +- examples/contracts/examples/generate.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index a5862712..e0868991 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -22,7 +22,7 @@ sol!( async fn main() -> Result<()> { // Spin up a local Anvil node. // Ensure `anvil` is available in $PATH - let anvil = Anvil::new().spawn(); + let anvil = Anvil::new().try_spawn()?; // Set up wallet let wallet: LocalWallet = anvil.keys()[0].clone().into(); diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 268e9a3f..3cc648ae 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -32,7 +32,7 @@ sol! { async fn main() -> Result<()> { // Spin up a local Anvil node. // Ensure `anvil` is available in $PATH - let anvil = Anvil::new().spawn(); + let anvil = Anvil::new().try_spawn()?; // Set up wallet let wallet: LocalWallet = anvil.keys()[0].clone().into(); diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index 450e5bfa..751b0c5a 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -20,7 +20,7 @@ sol!( async fn main() -> Result<()> { // Spin up a forked Anvil node. // Ensure `anvil` is available in $PATH - let anvil = Anvil::new().fork("https://eth.llamarpc.com").spawn(); + let anvil = Anvil::new().fork("https://eth.llamarpc.com").try_spawn()?; // Create a provider. let http = Http::::new(anvil.endpoint().parse()?); From 21d8c0181c5ee76370754e3bee6373a48c50205e Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Tue, 19 Mar 2024 15:37:04 +0000 Subject: [PATCH 6/9] update to 218ece4 --- examples/contracts/examples/deploy_from_artifact.rs | 13 ++++++------- examples/contracts/examples/deploy_from_contract.rs | 11 +++++------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index e0868991..b301bdc3 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -2,7 +2,7 @@ use alloy_network::EthereumSigner; use alloy_node_bindings::Anvil; -use alloy_primitives::{U256, U64}; +use alloy_primitives::U256; use alloy_provider::{Provider, ProviderBuilder, RootProvider}; use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; @@ -42,25 +42,24 @@ async fn main() -> Result<()> { let contract_builder = Counter::deploy_builder(&provider); let estimate = contract_builder.estimate_gas().await?; let contract_address = - contract_builder.gas(estimate).gas_price(base_fee).nonce(U64::from(0)).deploy().await?; + contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; println!("Deployed contract at address: {:?}", contract_address); let contract = Counter::new(contract_address, &provider); let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?; - let builder = - contract.setNumber(U256::from(42)).nonce(U64::from(1)).gas(estimate).gas_price(base_fee); + let builder = contract.setNumber(U256::from(42)).nonce(1).gas(estimate).gas_price(base_fee); let receipt = builder.send().await?.get_receipt().await?; - println!("Set number to 42: {:?}", receipt.transaction_hash.unwrap()); + println!("Set number to 42: {:?}", receipt.transaction_hash); // Increment the number to 43. let estimate = contract.increment().estimate_gas().await?; - let builder = contract.increment().nonce(U64::from(2)).gas(estimate).gas_price(base_fee); + let builder = contract.increment().nonce(2).gas(estimate).gas_price(base_fee); let receipt = builder.send().await?.get_receipt().await?; - println!("Incremented number: {:?}", receipt.transaction_hash.unwrap()); + println!("Incremented number: {:?}", receipt.transaction_hash); // Retrieve the number, which should be 43. let Counter::numberReturn { _0 } = contract.number().call().await?; diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 3cc648ae..e57377f6 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -52,25 +52,24 @@ async fn main() -> Result<()> { let contract_builder = Counter::deploy_builder(&provider); let estimate = contract_builder.estimate_gas().await?; let contract_address = - contract_builder.gas(estimate).gas_price(base_fee).nonce(U64::from(0)).deploy().await?; + contract_builder.gas(estimate).gas_price(base_fee).nonce(0).deploy().await?; println!("Deployed contract at address: {:?}", contract_address); let contract = Counter::new(contract_address, &provider); let estimate = contract.setNumber(U256::from(42)).estimate_gas().await?; - let builder = - contract.setNumber(U256::from(42)).nonce(U64::from(1)).gas(estimate).gas_price(base_fee); + let builder = contract.setNumber(U256::from(42)).nonce(1).gas(estimate).gas_price(base_fee); let receipt = builder.send().await?.get_receipt().await?; - println!("Set number to 42: {:?}", receipt.transaction_hash.unwrap()); + println!("Set number to 42: {:?}", receipt.transaction_hash); // Increment the number to 43. let estimate = contract.increment().estimate_gas().await?; - let builder = contract.increment().nonce(U64::from(2)).gas(estimate).gas_price(base_fee); + let builder = contract.increment().nonce(2).gas(estimate).gas_price(base_fee); let receipt = builder.send().await?.get_receipt().await?; - println!("Incremented number: {:?}", receipt.transaction_hash.unwrap()); + println!("Incremented number: {:?}", receipt.transaction_hash); // Retrieve the number, which should be 43. let Counter::numberReturn { _0 } = contract.number().call().await?; From 0b8eb56a6cd413a2c770d39d485addaedc4e02e7 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Tue, 19 Mar 2024 15:46:03 +0000 Subject: [PATCH 7/9] fix clippy --- examples/contracts/examples/deploy_from_contract.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index e57377f6..40adb5a6 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -2,7 +2,7 @@ use alloy_network::EthereumSigner; use alloy_node_bindings::Anvil; -use alloy_primitives::{U256, U64}; +use alloy_primitives::U256; use alloy_provider::{Provider, ProviderBuilder, RootProvider}; use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; From e8b004acd18543542b3f8a083df6a98cb5f626c5 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Tue, 19 Mar 2024 16:10:17 +0000 Subject: [PATCH 8/9] avoid using RootProvider directly, use on_client and new_http --- examples/contracts/examples/deploy_from_artifact.rs | 10 ++++------ examples/contracts/examples/deploy_from_contract.rs | 10 ++++------ examples/contracts/examples/generate.rs | 7 ++----- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index b301bdc3..60266bbf 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -3,13 +3,11 @@ use alloy_network::EthereumSigner; use alloy_node_bindings::Anvil; use alloy_primitives::U256; -use alloy_provider::{Provider, ProviderBuilder, RootProvider}; +use alloy_provider::{Provider, ProviderBuilder}; use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; -use alloy_transport_http::Http; use eyre::Result; -use reqwest::Client; // Codegen from artifact. sol!( @@ -27,11 +25,11 @@ async fn main() -> Result<()> { // Set up wallet let wallet: LocalWallet = anvil.keys()[0].clone().into(); - // Create a provider with a signer and the network. - let http = Http::::new(anvil.endpoint().parse()?); + // Create a provider with a signer. + let http = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() .signer(EthereumSigner::from(wallet)) - .provider(RootProvider::new(RpcClient::new(http, true))); + .on_client(RpcClient::new_http(http)); println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 40adb5a6..00217792 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -3,13 +3,11 @@ use alloy_network::EthereumSigner; use alloy_node_bindings::Anvil; use alloy_primitives::U256; -use alloy_provider::{Provider, ProviderBuilder, RootProvider}; +use alloy_provider::{Provider, ProviderBuilder}; use alloy_rpc_client::RpcClient; use alloy_signer_wallet::LocalWallet; use alloy_sol_types::sol; -use alloy_transport_http::Http; use eyre::Result; -use reqwest::Client; // Codegen from embedded Solidity code and precompiled bytecode. sol! { @@ -37,11 +35,11 @@ async fn main() -> Result<()> { // Set up wallet let wallet: LocalWallet = anvil.keys()[0].clone().into(); - // Create a provider with a signer and the network. - let http = Http::::new(anvil.endpoint().parse()?); + // Create a provider with a signer. + let http = anvil.endpoint().parse()?; let provider = ProviderBuilder::new() .signer(EthereumSigner::from(wallet)) - .provider(RootProvider::new(RpcClient::new(http, true))); + .on_client(RpcClient::new_http(http)); println!("Anvil running at `{}`", anvil.endpoint()); diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index 751b0c5a..e5d17b7c 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -2,12 +2,10 @@ use alloy_network::Ethereum; use alloy_node_bindings::Anvil; -use alloy_provider::{ProviderBuilder, RootProvider}; +use alloy_provider::ProviderBuilder; use alloy_rpc_client::RpcClient; use alloy_sol_types::sol; -use alloy_transport_http::Http; use eyre::Result; -use reqwest::Client; // Codegen from ABI file to interact with the contract. sol!( @@ -23,9 +21,8 @@ async fn main() -> Result<()> { let anvil = Anvil::new().fork("https://eth.llamarpc.com").try_spawn()?; // Create a provider. - let http = Http::::new(anvil.endpoint().parse()?); let provider = ProviderBuilder::<_, Ethereum>::new() - .provider(RootProvider::new(RpcClient::new(http, true))); + .on_client(RpcClient::new_http(anvil.endpoint().parse()?)); // Create a contract instance. let contract = IERC20::new("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?, provider); From 52f8edd7dc8225aca5f806933b508bea6200ca18 Mon Sep 17 00:00:00 2001 From: zerosnacks Date: Thu, 21 Mar 2024 16:04:57 +0000 Subject: [PATCH 9/9] use alloy namespace, no need to use explicit Ethereum network identifier anymore but `<_>` is required --- examples/contracts/Cargo.toml | 10 +--------- .../contracts/examples/deploy_from_artifact.rs | 16 +++++++++------- .../contracts/examples/deploy_from_contract.rs | 16 +++++++++------- examples/contracts/examples/generate.rs | 10 +++------- 4 files changed, 22 insertions(+), 30 deletions(-) diff --git a/examples/contracts/Cargo.toml b/examples/contracts/Cargo.toml index 038d9c04..4dbe196e 100644 --- a/examples/contracts/Cargo.toml +++ b/examples/contracts/Cargo.toml @@ -11,15 +11,7 @@ homepage.workspace = true repository.workspace = true [dev-dependencies] -alloy-contract.workspace = true -alloy-network.workspace = true -alloy-node-bindings.workspace = true -alloy-primitives.workspace = true -alloy-provider.workspace = true -alloy-rpc-client.workspace = true -alloy-signer-wallet.workspace = true -alloy-sol-types = { workspace = true, features = ["json"] } -alloy-transport-http.workspace = true +alloy.workspace = true eyre.workspace = true reqwest.workspace = true diff --git a/examples/contracts/examples/deploy_from_artifact.rs b/examples/contracts/examples/deploy_from_artifact.rs index 60266bbf..8bf1ad80 100644 --- a/examples/contracts/examples/deploy_from_artifact.rs +++ b/examples/contracts/examples/deploy_from_artifact.rs @@ -1,12 +1,14 @@ //! Example of deploying a contract from an artifact to Anvil and interacting with it. -use alloy_network::EthereumSigner; -use alloy_node_bindings::Anvil; -use alloy_primitives::U256; -use alloy_provider::{Provider, ProviderBuilder}; -use alloy_rpc_client::RpcClient; -use alloy_signer_wallet::LocalWallet; -use alloy_sol_types::sol; +use alloy::{ + network::EthereumSigner, + node_bindings::Anvil, + primitives::U256, + providers::{Provider, ProviderBuilder}, + rpc::client::RpcClient, + signers::wallet::LocalWallet, + sol, +}; use eyre::Result; // Codegen from artifact. diff --git a/examples/contracts/examples/deploy_from_contract.rs b/examples/contracts/examples/deploy_from_contract.rs index 00217792..6853aded 100644 --- a/examples/contracts/examples/deploy_from_contract.rs +++ b/examples/contracts/examples/deploy_from_contract.rs @@ -1,12 +1,14 @@ //! Example of deploying a contract from Solidity code to Anvil and interacting with it. -use alloy_network::EthereumSigner; -use alloy_node_bindings::Anvil; -use alloy_primitives::U256; -use alloy_provider::{Provider, ProviderBuilder}; -use alloy_rpc_client::RpcClient; -use alloy_signer_wallet::LocalWallet; -use alloy_sol_types::sol; +use alloy::{ + network::EthereumSigner, + node_bindings::Anvil, + primitives::U256, + providers::{Provider, ProviderBuilder}, + rpc::client::RpcClient, + signers::wallet::LocalWallet, + sol, +}; use eyre::Result; // Codegen from embedded Solidity code and precompiled bytecode. diff --git a/examples/contracts/examples/generate.rs b/examples/contracts/examples/generate.rs index e5d17b7c..b5ef21fc 100644 --- a/examples/contracts/examples/generate.rs +++ b/examples/contracts/examples/generate.rs @@ -1,10 +1,6 @@ //! Example of generating code from ABI file to interact with the contract. -use alloy_network::Ethereum; -use alloy_node_bindings::Anvil; -use alloy_provider::ProviderBuilder; -use alloy_rpc_client::RpcClient; -use alloy_sol_types::sol; +use alloy::{node_bindings::Anvil, providers::ProviderBuilder, rpc::client::RpcClient, sol}; use eyre::Result; // Codegen from ABI file to interact with the contract. @@ -21,8 +17,8 @@ async fn main() -> Result<()> { let anvil = Anvil::new().fork("https://eth.llamarpc.com").try_spawn()?; // Create a provider. - let provider = ProviderBuilder::<_, Ethereum>::new() - .on_client(RpcClient::new_http(anvil.endpoint().parse()?)); + let provider = + ProviderBuilder::<_>::new().on_client(RpcClient::new_http(anvil.endpoint().parse()?)); // Create a contract instance. let contract = IERC20::new("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".parse()?, provider);