-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into provider_examples
- Loading branch information
Showing
23 changed files
with
1,844 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "examples-layers" | ||
|
||
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.workspace = true | ||
|
||
eyre.workspace = true | ||
reqwest.workspace = true | ||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//! Example of using the `ManagedNonceLayer` in the provider. | ||
use alloy::{ | ||
network::{EthereumSigner, TransactionBuilder}, | ||
node_bindings::Anvil, | ||
primitives::{address, U256}, | ||
providers::{layers::ManagedNonceLayer, Provider, ProviderBuilder}, | ||
rpc::{client::RpcClient, types::eth::request::TransactionRequest}, | ||
signers::wallet::LocalWallet, | ||
}; | ||
use eyre::Result; | ||
|
||
/// In Ethereum, the nonce of a transaction is a number that represents the number of transactions | ||
/// that have been sent from a particular account. The nonce is used to ensure that transactions are | ||
/// processed in the order they are intended, and to prevent the same transaction from being | ||
/// processed multiple times. | ||
/// | ||
/// The nonce manager in Alloy is a layer that helps you manage the nonce | ||
/// of transactions by keeping track of the current nonce for a given account and automatically | ||
/// incrementing it as needed. This can be useful if you want to ensure that transactions are sent | ||
/// in the correct order, or if you want to avoid having to manually manage the nonce yourself. | ||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
// Spin up a local Anvil node. | ||
// Ensure `anvil` is available in $PATH | ||
let anvil = Anvil::new().try_spawn()?; | ||
|
||
// Set up the wallets. | ||
let wallet: LocalWallet = anvil.keys()[0].clone().into(); | ||
let from = wallet.address(); | ||
|
||
// Create a provider with the signer. | ||
let http = anvil.endpoint().parse()?; | ||
let provider = ProviderBuilder::new() | ||
// Add the `ManagedNonceLayer` to the provider | ||
.layer(ManagedNonceLayer) | ||
.signer(EthereumSigner::from(wallet)) | ||
.on_client(RpcClient::new_http(http)); | ||
|
||
// Create an EIP-1559 type transaction. | ||
let tx = TransactionRequest::default() | ||
.with_from(from) | ||
.with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) | ||
.with_value(U256::from(100)) | ||
.with_gas_limit(U256::from(21000)) | ||
.with_max_fee_per_gas(U256::from(20e9)) | ||
.with_max_priority_fee_per_gas(U256::from(1e9)) | ||
.with_chain_id(anvil.chain_id()); | ||
|
||
// Send the transaction, the nonce (0) is automatically managed by the provider. | ||
let builder = provider.send_transaction(tx.clone()).await?; | ||
let node_hash = *builder.tx_hash(); | ||
let pending_transaction = provider.get_transaction_by_hash(node_hash).await?; | ||
assert_eq!(pending_transaction.nonce, 0); | ||
|
||
println!("Transaction sent with nonce: {}", pending_transaction.nonce); | ||
|
||
// Send the transaction, the nonce (1) is automatically managed by the provider. | ||
let builder = provider.send_transaction(tx).await?; | ||
let node_hash = *builder.tx_hash(); | ||
let pending_transaction = provider.get_transaction_by_hash(node_hash).await?; | ||
assert_eq!(pending_transaction.nonce, 1); | ||
|
||
println!("Transaction sent with nonce: {}", pending_transaction.nonce); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
//! Example of using the `SignerLayer` in the provider. | ||
use alloy::{ | ||
network::{EthereumSigner, TransactionBuilder}, | ||
node_bindings::Anvil, | ||
primitives::{address, b256, U256}, | ||
providers::{Provider, ProviderBuilder}, | ||
rpc::{client::RpcClient, types::eth::request::TransactionRequest}, | ||
signers::wallet::LocalWallet, | ||
}; | ||
use eyre::Result; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
// Spin up a local Anvil node. | ||
// Ensure `anvil` is available in $PATH | ||
let anvil = Anvil::new().try_spawn()?; | ||
|
||
// Set up the wallets. | ||
let wallet: LocalWallet = anvil.keys()[0].clone().into(); | ||
let from = wallet.address(); | ||
|
||
// Create a provider with the signer. | ||
let http = anvil.endpoint().parse()?; | ||
let provider = ProviderBuilder::new() | ||
// Add the `SignerLayer` to the provider | ||
.signer(EthereumSigner::from(wallet)) | ||
.on_client(RpcClient::new_http(http)); | ||
|
||
// Create a legacy type transaction. | ||
let tx = TransactionRequest::default() | ||
.with_nonce(0) | ||
.with_from(from) | ||
.with_to(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()) | ||
.with_value(U256::from(100)) | ||
.with_gas_price(U256::from(20e9)) | ||
.with_gas_limit(U256::from(21000)); | ||
|
||
let builder = provider.send_transaction(tx).await?; | ||
let node_hash = *builder.tx_hash(); | ||
|
||
println!( | ||
"Node hash matches expected hash: {}", | ||
node_hash == b256!("eb56033eab0279c6e9b685a5ec55ea0ff8d06056b62b7f36974898d4fbb57e64") | ||
); | ||
|
||
let pending = builder.register().await?; | ||
let pending_transaction_hash = *pending.tx_hash(); | ||
|
||
println!( | ||
"Pending transaction hash matches node hash: {}", | ||
pending_transaction_hash == node_hash | ||
); | ||
|
||
let transaction_hash = pending.await?; | ||
assert_eq!(transaction_hash, node_hash); | ||
|
||
println!("Transaction hash matches node hash: {}", transaction_hash == node_hash); | ||
|
||
let receipt = | ||
provider.get_transaction_receipt(transaction_hash).await.unwrap().expect("no receipt"); | ||
let receipt_hash = receipt.transaction_hash; | ||
assert_eq!(receipt_hash, node_hash); | ||
|
||
println!("Transaction receipt hash matches node hash: {}", receipt_hash == node_hash); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[package] | ||
name = "examples-queries" | ||
|
||
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.workspace = true | ||
# alloy-network.workspace = true | ||
# alloy-primitives.workspace = true | ||
# alloy-provider = { workspace = true, features = ["pubsub", "ws"] } | ||
# alloy-rpc-types.workspace = true | ||
# alloy-rpc-client.workspace = true | ||
# alloy-transport-http.workspace = true | ||
|
||
eyre.workspace = true | ||
futures-util = "0.3" | ||
reqwest.workspace = true | ||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//! Example of querying contract storage from the Ethereum network. | ||
use alloy::{ | ||
network::Ethereum, | ||
primitives::{address, U256}, | ||
providers::{Provider, RootProvider}, | ||
}; | ||
use eyre::Result; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
let url = "https://eth.merkle.io".parse().unwrap(); | ||
let provider = RootProvider::<Ethereum, _>::new_http(url); | ||
|
||
// Get slot0 from USDC-ETH Uniswap V3 pool | ||
let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"); | ||
|
||
let storage_slot = U256::from(0); | ||
|
||
let storage = provider.get_storage_at(pool_address, storage_slot, None).await?; | ||
|
||
println!("Slot 0: {:?}", storage); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//! Example of querying deployed bytecode of a contract on Ethereum network. | ||
use alloy::{ | ||
network::Ethereum, | ||
primitives::address, | ||
providers::{Provider, RootProvider}, | ||
rpc::types::eth::{BlockId, BlockNumberOrTag}, | ||
}; | ||
use eyre::Result; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
let url = "https://eth.merkle.io".parse().unwrap(); | ||
let provider = RootProvider::<Ethereum, _>::new_http(url); | ||
|
||
// Get bytecode of USDC-ETH Uniswap V3 pool | ||
let pool_address = address!("88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"); | ||
|
||
let bytecode = | ||
provider.get_code_at(pool_address, BlockId::Number(BlockNumberOrTag::Latest)).await?; | ||
|
||
println!("Bytecode: {:?}", bytecode); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use alloy::{ | ||
network::Ethereum, | ||
primitives::{address, fixed_bytes}, | ||
providers::{Provider, RootProvider}, | ||
rpc::types::eth::Filter, | ||
}; | ||
use eyre::Result; | ||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
let url = "https://eth.merkle.io".parse().unwrap(); | ||
let provider = RootProvider::<Ethereum, _>::new_http(url); | ||
|
||
// Get logs from the latest block | ||
let latest_block = provider.get_block_number().await?; | ||
|
||
// Get all logs from the latest block | ||
let filter = Filter::new().from_block(latest_block); | ||
|
||
let logs = provider.get_logs(&filter).await?; | ||
|
||
for log in logs { | ||
println!("{:?}", log); | ||
} | ||
|
||
let tranfer_event_signature = | ||
fixed_bytes!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"); | ||
|
||
// Get all logs from the latest block that match the transfer event signature/topic | ||
let filter = Filter::new().event_signature(tranfer_event_signature).from_block(latest_block); | ||
// You could also use the event name instead of the event signature like so: | ||
// .event("Transfer(address,address,uint256)") | ||
|
||
let logs = provider.get_logs(&filter).await?; | ||
|
||
for log in logs { | ||
println!("Transfer event: {:?}", log); | ||
} | ||
|
||
let uni_address = address!("1f9840a85d5aF5bf1D1762F925BDADdC4201F984"); | ||
|
||
// Get all from the latest block emitted by the UNI token address | ||
let filter = Filter::new().address(uni_address).from_block(latest_block); | ||
|
||
let logs = provider.get_logs(&filter).await?; | ||
|
||
for log in logs { | ||
println!("UNI token logs: {:?}", log); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "examples-transactions" | ||
|
||
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.workspace = true | ||
|
||
eyre.workspace = true | ||
reqwest.workspace = true | ||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } |
Oops, something went wrong.