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(cast): Move non tx methods to alloy #7129

Merged
merged 19 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/cast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ alloy-rlp.workspace = true
alloy-providers.workspace = true
alloy-rpc-types.workspace = true
alloy-signer.workspace = true
alloy-contract.workspace = true
alloy-consensus.workspace = true

ethers-core.workspace = true
ethers-providers.workspace = true
Expand Down
26 changes: 15 additions & 11 deletions crates/cast/bin/cmd/access_list.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use alloy_primitives::Address;
use alloy_providers::provider::TempProvider;
use alloy_rpc_types::BlockId;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers_core::types::{BlockId, NameOrAddress};
use ethers_providers::Middleware;
use eyre::{Result, WrapErr};
use foundry_cli::{
opts::{EthereumOpts, TransactionOpts},
utils,
};
use foundry_common::types::ToEthers;
use foundry_common::ens::NameOrAddress;
use foundry_config::{Chain, Config};
use std::str::FromStr;

Expand Down Expand Up @@ -65,10 +66,18 @@ impl AccessListArgs {
let chain = utils::get_chain(config.chain, &provider).await?;
let sender = eth.wallet.sender().await;

let to = match to {
Some(NameOrAddress::Name(name)) => {
Some(NameOrAddress::Name(name).resolve(&alloy_provider).await?)
}
Some(NameOrAddress::Address(addr)) => Some(addr),
None => None,
};

access_list(
&provider,
alloy_provider,
sender.to_ethers(),
sender,
to,
sig,
args,
Expand All @@ -84,16 +93,11 @@ impl AccessListArgs {
}

#[allow(clippy::too_many_arguments)]
async fn access_list<
M: Middleware,
P: TempProvider,
F: Into<NameOrAddress>,
T: Into<NameOrAddress>,
>(
async fn access_list<M: Middleware, P: TempProvider>(
provider: M,
alloy_provider: P,
from: F,
to: Option<T>,
from: Address,
to: Option<Address>,
sig: Option<String>,
args: Vec<String>,
data: Option<String>,
Expand Down
19 changes: 12 additions & 7 deletions crates/cast/bin/cmd/call.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use alloy_primitives::U256;
use alloy_rpc_types::BlockId;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers_core::types::{BlockId, NameOrAddress};
use eyre::{Result, WrapErr};
use foundry_cli::{
opts::{EthereumOpts, TransactionOpts},
utils::{self, handle_traces, parse_ether_value, TraceResult},
};
use foundry_common::{
runtime_client::RuntimeClient,
types::{ToAlloy, ToEthers},
};
use foundry_common::{ens::NameOrAddress, runtime_client::RuntimeClient, types::ToAlloy};
use foundry_compilers::EvmVersion;
use foundry_config::{find_project_root_path, Config};
use foundry_evm::{executors::TracingExecutor, opts::EvmOpts};
Expand Down Expand Up @@ -120,8 +117,16 @@ impl CallArgs {
let chain = utils::get_chain(config.chain, &provider).await?;
let sender = eth.wallet.sender().await;

let to = match to {
Some(NameOrAddress::Name(name)) => {
Some(NameOrAddress::Name(name).resolve(&alloy_provider).await?)
}
Some(NameOrAddress::Address(addr)) => Some(addr),
None => None,
};

let mut builder: TxBuilder<'_, Provider> =
TxBuilder::new(&provider, sender.to_ethers(), to, chain, tx.legacy).await?;
TxBuilder::new(&provider, sender, to, chain, tx.legacy).await?;

builder
.gas(tx.gas_limit)
Expand Down Expand Up @@ -196,7 +201,7 @@ impl CallArgs {
}
};

let builder_output = builder.build();
let builder_output = builder.build_alloy();
println!("{}", Cast::new(provider, alloy_provider).call(builder_output, block).await?);

Ok(())
Expand Down
11 changes: 10 additions & 1 deletion crates/cast/bin/cmd/estimate.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use alloy_primitives::U256;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers_core::types::NameOrAddress;
use eyre::Result;
use foundry_cli::{
opts::{EtherscanOpts, RpcOpts},
utils::{self, parse_ether_value},
};
use foundry_common::ens::NameOrAddress;
use foundry_config::{figment::Figment, Config};
use std::str::FromStr;

Expand Down Expand Up @@ -87,6 +87,15 @@ impl EstimateArgs {
let chain = utils::get_chain(config.chain, &provider).await?;
let api_key = config.get_etherscan_api_key(Some(chain));

let from = from.resolve(&alloy_provider).await?;
let to = match to {
Some(NameOrAddress::Name(name)) => {
Some(NameOrAddress::Name(name).resolve(&alloy_provider).await?)
}
Some(NameOrAddress::Address(addr)) => Some(addr),
None => None,
};

let mut builder = TxBuilder::new(&provider, from, to, chain, false).await?;
builder.etherscan_api_key(api_key);

Expand Down
6 changes: 3 additions & 3 deletions crates/cast/bin/cmd/logs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloy_rpc_types::BlockHashOrNumber;
use alloy_rpc_types::BlockId;
use cast::Cast;
use clap::Parser;
use ethers_core::{
Expand All @@ -23,13 +23,13 @@ pub struct LogsArgs {
///
/// Can also be the tags earliest, finalized, safe, latest, or pending.
#[clap(long)]
from_block: Option<BlockHashOrNumber>,
from_block: Option<BlockId>,

/// The block height to stop query at.
///
/// Can also be the tags earliest, finalized, safe, latest, or pending.
#[clap(long)]
to_block: Option<BlockHashOrNumber>,
to_block: Option<BlockId>,

/// The contract address to filter on.
#[clap(
Expand Down
21 changes: 15 additions & 6 deletions crates/cast/bin/cmd/send.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloy_primitives::Address;
use alloy_providers::provider::TempProvider;
use cast::{Cast, TxBuilder};
use clap::Parser;
use ethers_core::types::NameOrAddress;
use ethers_middleware::MiddlewareBuilder;
use ethers_providers::Middleware;
use ethers_signers::Signer;
Expand All @@ -12,6 +12,7 @@ use foundry_cli::{
};
use foundry_common::{
cli_warn,
ens::NameOrAddress,
types::{ToAlloy, ToEthers},
};
use foundry_config::{Chain, Config};
Expand Down Expand Up @@ -119,6 +120,14 @@ impl SendTxArgs {
let chain = utils::get_chain(config.chain, &provider).await?;
let api_key = config.get_etherscan_api_key(Some(chain));

let to = match to {
Some(NameOrAddress::Name(name)) => {
Some(NameOrAddress::Name(name).resolve(&alloy_provider).await?)
}
Some(NameOrAddress::Address(addr)) => Some(addr),
None => None,
};

// Case 1:
// Default to sending via eth_sendTransaction if the --unlocked flag is passed.
// This should be the only way this RPC method is used as it requires a local node
Expand Down Expand Up @@ -155,7 +164,7 @@ impl SendTxArgs {
cast_send(
provider,
alloy_provider,
config.sender.to_ethers(),
config.sender,
to,
code,
(sig, args),
Expand Down Expand Up @@ -199,7 +208,7 @@ corresponds to the sender, or let foundry automatically detect it by not specify
cast_send(
provider,
alloy_provider,
from,
from.to_alloy(),
to,
code,
(sig, args),
Expand All @@ -216,11 +225,11 @@ corresponds to the sender, or let foundry automatically detect it by not specify
}

#[allow(clippy::too_many_arguments)]
async fn cast_send<M: Middleware, P: TempProvider, F: Into<NameOrAddress>, T: Into<NameOrAddress>>(
async fn cast_send<M: Middleware, P: TempProvider>(
provider: M,
alloy_provider: P,
Evalir marked this conversation as resolved.
Show resolved Hide resolved
from: F,
to: Option<T>,
from: Address,
to: Option<Address>,
code: Option<String>,
args: (String, Vec<String>),
tx: TransactionOpts,
Expand Down
51 changes: 22 additions & 29 deletions crates/cast/bin/cmd/storage.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::opts::parse_slot;
use alloy_primitives::{B256, U256};
use alloy_primitives::{Address, B256, U256};
use alloy_providers::provider::TempProvider;
use alloy_rpc_types::BlockId;
use cast::Cast;
use clap::Parser;
use comfy_table::{presets::ASCII_MARKDOWN, Table};
use ethers_core::types::{BlockId, NameOrAddress};
use ethers_providers::Middleware;
use eyre::Result;
use foundry_block_explorers::Client;
use foundry_cli::{
Expand All @@ -14,8 +14,7 @@ use foundry_cli::{
use foundry_common::{
abi::find_source,
compile::{etherscan_project, ProjectCompiler},
provider::ethers::RetryProvider,
types::{ToAlloy, ToEthers},
ens::NameOrAddress,
};
use foundry_compilers::{
artifacts::StorageLayout, Artifact, ConfigurableContractArtifact, Project, Solc,
Expand Down Expand Up @@ -80,20 +79,20 @@ impl StorageArgs {
let config = Config::from(&self);

let Self { address, slot, block, build, .. } = self;

let provider = utils::get_provider(&config)?;
let alloy_provider = utils::get_alloy_provider(&config)?;
let provider = utils::get_alloy_provider(&config)?;
let ethers_provider = utils::get_provider(&config)?;
let address = address.resolve(&provider).await?;

// Slot was provided, perform a simple RPC call
if let Some(slot) = slot {
let cast = Cast::new(provider, alloy_provider);
println!("{}", cast.storage(address, slot.to_ethers(), block).await?);
let cast = Cast::new(ethers_provider, provider);
println!("{}", cast.storage(address, slot, block).await?);
return Ok(());
}

// No slot was provided
// Get deployed bytecode at given address
let address_code = provider.get_code(address.clone(), block).await?.to_alloy();
let address_code = provider.get_code_at(address, block).await?;
if address_code.is_empty() {
eyre::bail!("Provided address has no deployed code and thus no storage");
}
Expand All @@ -108,8 +107,7 @@ impl StorageArgs {
artifact.get_deployed_bytecode_bytes().is_some_and(|b| *b == address_code)
});
if let Some((_, artifact)) = artifact {
return fetch_and_print_storage(provider, address.clone(), block, artifact, true)
.await;
return fetch_and_print_storage(provider, address, block, artifact, true).await;
}
}

Expand All @@ -121,14 +119,10 @@ impl StorageArgs {
eyre::bail!("You must provide an Etherscan API key if you're fetching a remote contract's storage.");
}

let chain = utils::get_chain(config.chain, &provider).await?;
let chain = utils::get_chain(config.chain, &ethers_provider).await?;
let api_key = config.get_etherscan_api_key(Some(chain)).unwrap_or_default();
let client = Client::new(chain, api_key)?;
let addr = address
.as_address()
.ok_or_else(|| eyre::eyre!("Could not resolve address"))?
.to_alloy();
let source = find_source(client, addr).await?;
let source = find_source(client, address).await?;
let metadata = source.items.first().unwrap();
if metadata.is_vyper() {
eyre::bail!("Contract at provided address is not a valid Solidity contract")
Expand Down Expand Up @@ -210,9 +204,9 @@ impl StorageValue {
}
}

async fn fetch_and_print_storage(
provider: RetryProvider,
address: NameOrAddress,
async fn fetch_and_print_storage<P: TempProvider>(
provider: P,
address: Address,
block: Option<BlockId>,
artifact: &ConfigurableContractArtifact,
pretty: bool,
Expand All @@ -227,18 +221,17 @@ async fn fetch_and_print_storage(
}
}

async fn fetch_storage_slots(
provider: RetryProvider,
address: NameOrAddress,
async fn fetch_storage_slots<P: TempProvider>(
provider: P,
address: Address,
block: Option<BlockId>,
layout: &StorageLayout,
) -> Result<Vec<StorageValue>> {
let requests = layout.storage.iter().map(|storage_slot| async {
let slot = B256::from(U256::from_str(&storage_slot.slot)?);
let raw_slot_value =
provider.get_storage_at(address.clone(), slot.to_ethers(), block).await?.to_alloy();
let raw_slot_value = provider.get_storage_at(address, slot.into(), block).await?;

let value = StorageValue { slot, raw_slot_value };
let value = StorageValue { slot, raw_slot_value: raw_slot_value.into() };

Ok(value)
});
Expand Down Expand Up @@ -267,7 +260,7 @@ fn print_storage(layout: StorageLayout, values: Vec<StorageValue>, pretty: bool)
storage_type.map_or("?", |t| &t.label),
&slot.slot,
&slot.offset.to_string(),
&storage_type.map_or("?", |t| &t.number_of_bytes),
(storage_type.map_or("?", |t| &t.number_of_bytes)),
&converted_value.to_string(),
&value.to_string(),
&slot.contract,
Expand Down
Loading
Loading