Example: send_eip7702_transaction
Example
To run this example:
- Clone the examples repository:
git clone git@github.com:alloy-rs/examples.git
- Run:
cargo run --example send_eip7702_transaction
//! This example demonstrates how to send an EIP7702 transaction.
use alloy::{
consensus::{SignableTransaction, TxEip7702},
eips::eip7702::Authorization,
network::TxSignerSync,
node_bindings::Anvil,
primitives::U256,
providers::{Provider, ProviderBuilder},
signers::{local::LocalSigner, SignerSync},
sol,
};
use eyre::Result;
// Codegen from embedded Solidity code and precompiled bytecode.
// solc v0.8.25 Log.sol --via-ir --optimize --bin
sol!(
#[allow(missing_docs)]
#[sol(rpc, bytecode = "6080806040523460135760c9908160188239f35b5f80fdfe6004361015600b575f80fd5b5f3560e01c80637b3ab2d014605f57639ee1a440146027575f80fd5b34605b575f366003190112605b577f2d67bb91f17bca05af6764ab411e86f4ddf757adb89fcec59a7d21c525d417125f80a1005b5f80fd5b34605b575f366003190112605b577fbcdfe0d5b27dd186282e187525415c57ea3077c34efb39148111e4d342e7ab0e5f80a100fea2646970667358221220f6b42b522bc9fb2b4c7d7e611c7c3e995d057ecab7fd7be4179712804c886b4f64736f6c63430008190033")]
contract Log {
#[derive(Debug)]
event Hello();
event World();
function emitHello() public {
emit Hello();
}
function emitWorld() public {
emit World();
}
}
);
#[tokio::main]
async fn main() -> Result<()> {
let anvil = Anvil::new().arg("--hardfork").arg("prague").try_spawn()?;
let authority = LocalSigner::from_signing_key(anvil.keys()[0].clone().into()); // 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
let sender = LocalSigner::from_signing_key(anvil.keys()[1].clone().into());
let provider = ProviderBuilder::new().on_http(anvil.endpoint_url());
let contract = Log::deploy(&provider).await?;
let auth_7702 = Authorization {
chain_id: U256::from(31337),
address: *contract.address(), /* Reference to the contract that will be set as code for
* the authority */
nonce: provider.get_transaction_count(authority.address()).await?,
};
// Sign the authorization
let sig = authority.sign_hash_sync(&auth_7702.signature_hash())?;
let auth = auth_7702.into_signed(sig);
// Collect the calldata required for the tx
let call = contract.emitHello();
let emit_hello_calldata = call.calldata().to_owned();
// Estimate the EIP1559 fees
let eip1559_est = provider.estimate_eip1559_fees(None).await?;
// Build the transaction
let mut tx = TxEip7702 {
to: authority.address(),
authorization_list: vec![auth],
input: emit_hello_calldata.to_owned(),
nonce: provider.get_transaction_count(sender.address()).await?,
chain_id: 31337,
gas_limit: 1000000,
max_fee_per_gas: eip1559_est.max_fee_per_gas,
max_priority_fee_per_gas: eip1559_est.max_priority_fee_per_gas,
..Default::default()
};
// Sign and Encode the transaction
let sig = sender.sign_transaction_sync(&mut tx)?;
let tx = tx.into_signed(sig);
let mut encoded = Vec::new();
tx.tx().encode_with_signature(tx.signature(), &mut encoded, false);
let receipt = provider.send_raw_transaction(&encoded).await?.get_receipt().await?;
assert!(receipt.status());
assert_eq!(receipt.inner.logs().len(), 1);
assert_eq!(receipt.inner.logs()[0].address(), authority.address());
Ok(())
}
Find the source code on Github here.