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

fix(cast storage): respect --json for layout #9332

Merged
merged 15 commits into from
Nov 18, 2024
Merged
Changes from 3 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
30 changes: 25 additions & 5 deletions crates/cast/bin/cmd/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use foundry_config::{
impl_figment_convert_cast, Config,
};
use semver::Version;
use std::path::PathBuf;
use std::str::FromStr;

/// The minimum Solc version for outputting storage layouts.
Expand All @@ -45,7 +46,7 @@ pub struct StorageArgs {
#[arg(value_parser = NameOrAddress::from_str)]
address: NameOrAddress,

/// The storage slot number.
/// The storage slot number. If not provided, it gets the full storage layout.
#[arg(value_parser = parse_slot)]
slot: Option<B256>,

Expand All @@ -63,6 +64,12 @@ pub struct StorageArgs {

#[command(flatten)]
build: CoreBuildArgs,

/// The path of the file in which the storage layout is saved. Only works if a slot
/// is not provided. The formatted (pretty) storage layout is shown even if this value
/// is provided.
#[arg(long, default_value = "", value_name = "output_json")]
pub output_json: String,
MaxMustermann2 marked this conversation as resolved.
Show resolved Hide resolved
}

impl_figment_convert_cast!(StorageArgs);
Expand All @@ -85,7 +92,7 @@ impl StorageArgs {
pub async fn run(self) -> Result<()> {
let config = Config::from(&self);

let Self { address, slot, block, build, .. } = self;
let Self { address, slot, block, build, output_json, .. } = self;
let provider = utils::get_provider(&config)?;
let address = address.resolve(&provider).await?;

Expand Down Expand Up @@ -114,7 +121,15 @@ 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, block, artifact, true).await;
return fetch_and_print_storage(
provider,
address,
block,
artifact,
true,
output_json,
)
.await;
}
}

Expand Down Expand Up @@ -180,7 +195,7 @@ impl StorageArgs {
// Clear temp directory
root.close()?;

fetch_and_print_storage(provider, address, block, artifact, true).await
fetch_and_print_storage(provider, address, block, artifact, true, output_json).await
}
}

Expand Down Expand Up @@ -221,13 +236,18 @@ async fn fetch_and_print_storage<P: Provider<T, AnyNetwork>, T: Transport + Clon
block: Option<BlockId>,
artifact: &ConfigurableContractArtifact,
pretty: bool,
output_json: String,
) -> Result<()> {
if is_storage_layout_empty(&artifact.storage_layout) {
sh_warn!("Storage layout is empty.")?;
Ok(())
} else {
let layout = artifact.storage_layout.as_ref().unwrap().clone();
let values = fetch_storage_slots(provider, address, block, &layout).await?;
let output_path = PathBuf::from(output_json);
if !output_path.as_os_str().is_empty() {
foundry_common::fs::write_json_file(&output_path, &layout)?;
}
print_storage(layout, values, pretty)
}
}
Expand Down Expand Up @@ -256,7 +276,7 @@ async fn fetch_storage_slots<P: Provider<T, AnyNetwork>, T: Transport + Clone>(
fn print_storage(layout: StorageLayout, values: Vec<StorageValue>, pretty: bool) -> Result<()> {
if !pretty {
sh_println!("{}", serde_json::to_string_pretty(&serde_json::to_value(layout)?)?)?;
return Ok(())
return Ok(());
MaxMustermann2 marked this conversation as resolved.
Show resolved Hide resolved
}

let mut table = Table::new();
Expand Down