Writing to a contract
The sol!
macro also helps up building transactions and submit them to the chain seamless.
Once again, this is enabled via the rpc
attribute and the CallBuilder
type similar to how they aided in reading a contract
.
The CallBuilder
exposes various transaction setting methods such as .value(..)
to modify the transaction before sending it. The calldata encoding is handled under the hood.
We'll be forking mainnet using a local anvil node to avoid spending real ETH.
write_contract.rs
//! Demonstrates writing to a contract by depositing ETH to the WETH contract.
use alloy::{primitives::{address, utils::{format_ether, Unit}, U256},
providers::ProviderBuilder,
signers::local::PrivateKeySigner,
sol,
};
use std::error::Error;
// Generate bindings for the WETH9 contract.
// WETH9: <https://etherscan.io/token/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2>
sol! {
#[sol(rpc)]
contract WETH9 {
function deposit() public payable;
function balanceOf(address) public view returns (uint256);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Initialize a signer with a private key.
let signer: PrivateKeySigner =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80".parse()?;
// Instantiate a provider with the signer.
let provider = ProviderBuilder::new()
// Signs transactions before dispatching them.
.wallet(signer) // Signs the transactions
// Forking mainnet using anvil to avoid spending real ETH.
.on_anvil_with_config(|a| a.fork("https://reth-ethereum.ithaca.xyz/rpc")); [!]
// Setup WETH contract instance.
let weth = address!("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2");
let weth = WETH9::new(weth, provider);
// Prepare deposit transaction.
let amt = Unit::ETHER.wei().saturating_mul(U256::from(100));
let deposit = weth.deposit().value(amt);
// Send the transaction and wait for it to be included.
let deposit_tx = deposit.send().await?;
let receipt = deposit_tx.get_receipt().await?;
// Check balance by verifying the deposit.
let balance = weth.balanceOf(receipt.from).call().await?;
println!("Verified balance of {:.3} WETH for {}", format_ether(balance), receipt.from);
Ok(())
}