Skip to content

Commit

Permalink
Feat(cast): Add --parse-bytes32-address (#4746)
Browse files Browse the repository at this point in the history
* Feat: Add --parse-bytes32-address

* Minor: removed out of context comment

* Changed error message

* Removed function to use inline code

* fix import

---------

Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
0xSileo and mattsse committed Jun 9, 2023
1 parent 98a1862 commit f2a61d8
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

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

21 changes: 20 additions & 1 deletion cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ impl SimpleCast {
pub fn parse_bytes32_string(s: &str) -> Result<String> {
let s = strip_0x(s);
if s.len() != 64 {
eyre::bail!("string not 32 bytes");
eyre::bail!("expected 64 byte hex-string, got {s}");
}

let bytes = hex::decode(s)?;
Expand All @@ -1293,6 +1293,25 @@ impl SimpleCast {
Ok(parse_bytes32_string(&buffer)?.to_owned())
}

/// Decodes checksummed address from bytes32 value
pub fn parse_bytes32_address(s: &str) -> Result<String> {
let s = strip_0x(s);
if s.len() != 64 {
eyre::bail!("expected 64 byte hex-string, got {s}");
}

let s = if let Some(stripped) = s.strip_prefix("000000000000000000000000") {
stripped
} else {
return Err(eyre::eyre!("Not convertible to address, there are non-zero bytes"))
};

let lowercase_address_string = format!("0x{s}");
let lowercase_address = Address::from_str(&lowercase_address_string)?;

Ok(ethers_core::utils::to_checksum(&lowercase_address, None))
}

/// Decodes abi-encoded hex input or output
///
/// # Example
Expand Down
4 changes: 4 additions & 0 deletions cli/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ async fn main() -> eyre::Result<()> {
let value = stdin::unwrap_line(bytes)?;
println!("{}", SimpleCast::parse_bytes32_string(&value)?);
}
Subcommands::ParseBytes32Address { bytes } => {
let value = stdin::unwrap_line(bytes)?;
println!("{}", SimpleCast::parse_bytes32_address(&value)?);
}

// ABI encoding & decoding
Subcommands::AbiDecode { sig, calldata, input } => {
Expand Down
6 changes: 6 additions & 0 deletions cli/src/opts/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,12 @@ pub enum Subcommands {
/// The string to parse.
bytes: Option<String>,
},
#[clap(name = "--parse-bytes32-address")]
#[clap(about = "Parses a checksummed address from bytes32 encoding.")]
ParseBytes32Address {
#[clap(value_name = "BYTES")]
bytes: Option<String>,
},
}

/// CLI arguments for `cast --to-base`.
Expand Down
10 changes: 10 additions & 0 deletions cli/tests/it/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,16 @@ casttest!(cast_receipt_revert_reason, |_: TestProject, mut cmd: TestCommand| {
assert!(output.contains("Transaction too old"));
});

// tests that `cast --parse-bytes32-address` command is working correctly.
casttest!(parse_bytes32_address, |_: TestProject, mut cmd: TestCommand| {
cmd.args([
"--parse-bytes32-address",
"0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045",
]);
let output = cmd.stdout_lossy();
assert_eq!(output.trim(), "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
});

casttest!(cast_access_list, |_: TestProject, mut cmd: TestCommand| {
let rpc = next_http_rpc_endpoint();
cmd.args([
Expand Down

0 comments on commit f2a61d8

Please sign in to comment.