Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(transactions): send_7702_tx #129

Merged
merged 5 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ significant_drop_in_scrutinee = "allow"
significant_drop_tightening = "allow"

[workspace.dependencies]
alloy = { version = "0.2.1", features = [
alloy = { version = "0.3.0", features = [
"full",
"node-bindings",
"rpc-types-debug",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ This repository contains the following examples:
- [x] [Send EIP-1559 transaction](./examples/transactions/examples/send_eip1559_transaction.rs)
- [x] [Send legacy transaction](./examples/transactions/examples/send_legacy_transaction.rs)
- [x] [Send EIP-4844 transaction](./examples/transactions/examples/send_eip4844_transaction.rs)
- [x] [Send EIP-7702 transaction](./examples/transactions/examples/send_eip7702_transaction.rs)
- [x] [Send private transaction using Flashbots Protect](./examples/transactions/examples/send_private_transaction.rs)
- [x] [Send transaction with access list](./examples/transactions/examples/with_access_list.rs)
- [x] Wallets
Expand Down
2 changes: 1 addition & 1 deletion examples/providers/examples/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async fn main() -> Result<()> {

let handle = tokio::spawn(async move {
while let Some(block) = stream.next().await {
println!("{}", block.header.number.expect("Failed to get block number"));
println!("{}", block.header.number);
}
});

Expand Down
5 changes: 1 addition & 4 deletions examples/providers/examples/ws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@ async fn main() -> Result<()> {
// Take the stream and print the block number upon receiving a new block.
let handle = tokio::spawn(async move {
while let Some(block) = stream.next().await {
println!(
"Latest block number: {}",
block.header.number.expect("Failed to get block number")
);
println!("Latest block number: {}", block.header.number);
}
});

Expand Down
10 changes: 2 additions & 8 deletions examples/providers/examples/ws_with_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,14 @@ async fn main() -> Result<()> {
// Take the basic stream and print the block number upon receiving a new block.
let basic_handle = tokio::spawn(async move {
while let Some(block) = stream_basic.next().await {
println!(
"Latest block number (basic): {}",
block.header.number.expect("Failed to get block number")
);
println!("Latest block number (basic): {}", block.header.number);
}
});

// Take the bearer stream and print the block number upon receiving a new block.
let bearer_handle = tokio::spawn(async move {
while let Some(block) = stream_bearer.next().await {
println!(
"Latest block number (bearer): {}",
block.header.number.expect("Failed to get block number")
);
println!("Latest block number (bearer): {}", block.header.number);
}
});

Expand Down
6 changes: 3 additions & 3 deletions examples/sol-macro/examples/decode_returns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use alloy::{
hex,
primitives::{I256, U256},
primitives::{Uint, I256, U256},
sol,
sol_types::SolCall,
};
Expand Down Expand Up @@ -31,11 +31,11 @@ fn main() -> Result<()> {
assert_eq!(
result,
Ok(getRoundDataReturn {
roundId: 110680464442257327894_u128,
roundId: Uint::<80, 2>::from(110680464442257327894_u128),
answer: I256::from_dec_str("352098000000")?,
startedAt: U256::from(1718182523),
updatedAt: U256::from(1718182523),
answeredInRound: 110680464442257327894_u128,
answeredInRound: Uint::<80, 2>::from(110680464442257327894_u128),
})
);

Expand Down
5 changes: 1 addition & 4 deletions examples/subscriptions/examples/subscribe_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ async fn main() -> Result<()> {
let mut stream = subscription.into_stream().take(2);

while let Some(block) = stream.next().await {
println!(
"Received block number: {}",
block.header.number.expect("Failed to get block number")
);
println!("Received block number: {}", block.header.number);
}

// Poll for block headers.
Expand Down
87 changes: 87 additions & 0 deletions examples/transactions/examples/send_eip7702_transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//! This example demonstrates how to send an EIP7702 transaction.
use alloy::{
consensus::{SignableTransaction, TxEip7702},
eips::eip7702::Authorization,
network::TxSignerSync,
node_bindings::Anvil,
primitives::{TxKind, 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: TxKind::Call(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(())
}
Loading