Skip to content

Commit

Permalink
feat(cast): decode-event with local and openchain API (#9431)
Browse files Browse the repository at this point in the history
  • Loading branch information
grandizzy authored Nov 29, 2024
1 parent 0d76df5 commit 0f7268f
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 11 deletions.
5 changes: 3 additions & 2 deletions crates/cast/bin/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,8 +533,9 @@ pub enum CastSubcommand {
/// Decode event data.
#[command(visible_aliases = &["event-decode", "--event-decode", "ed"])]
DecodeEvent {
/// The event signature.
sig: String,
/// The event signature. If none provided then tries to decode from local cache or `https://api.openchain.xyz`.
#[arg(long, visible_alias = "event-sig")]
sig: Option<String>,
/// The event data to decode.
data: String,
},
Expand Down
25 changes: 23 additions & 2 deletions crates/cast/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,29 @@ async fn main_args(args: CastArgs) -> Result<()> {
print_tokens(&tokens);
}
CastSubcommand::DecodeEvent { sig, data } => {
let event = get_event(sig.as_str())?;
let decoded_event = event.decode_log_parts(None, &hex::decode(data)?, false)?;
let decoded_event = if let Some(event_sig) = sig {
get_event(event_sig.as_str())?.decode_log_parts(None, &hex::decode(data)?, false)?
} else {
let data = data.strip_prefix("0x").unwrap_or(data.as_str());
let selector = data.get(..64).unwrap_or_default();
let identified_event =
SignaturesIdentifier::new(Config::foundry_cache_dir(), false)?
.write()
.await
.identify_event(&hex::decode(selector)?)
.await;
if let Some(event) = identified_event {
let _ = sh_println!("{}", event.signature());
let data = data.get(64..).unwrap_or_default();
get_event(event.signature().as_str())?.decode_log_parts(
None,
&hex::decode(data)?,
false,
)?
} else {
eyre::bail!("No matching event signature found for selector `{selector}`")
}
};
print_tokens(&decoded_event.body);
}
CastSubcommand::DecodeError { sig, data } => {
Expand Down
47 changes: 40 additions & 7 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,15 +1474,35 @@ casttest!(string_decode, |_prj, cmd| {
"#]]);
});

casttest!(event_decode, |_prj, cmd| {
cmd.args(["decode-event", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
// tests cast can decode event with provided signature
casttest!(event_decode_with_sig, |_prj, cmd| {
cmd.args(["decode-event", "--sig", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
78
0x0000000000000000000000000000000000D0004F
"#]]);

cmd.args(["--json"]).assert_success().stdout_eq(str![[r#"
[
"78",
"0x0000000000000000000000000000000000D0004F"
]
"#]]);
});

// tests cast can decode traces with provided signature
// tests cast can decode event with Openchain API
casttest!(event_decode_with_openchain, |prj, cmd| {
prj.clear_cache();
cmd.args(["decode-event", "0xe27c4c1372396a3d15a9922f74f9dfc7c72b1ad6d63868470787249c356454c1000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"]).assert_success().stdout_eq(str![[r#"
BaseCurrencySet(address,uint256)
0x000000000000000000000000000000000000004e
15187004358734 [1.518e13]
"#]]);
});

// tests cast can decode error with provided signature
casttest!(error_decode_with_sig, |_prj, cmd| {
cmd.args(["decode-error", "--sig", "AnotherValueTooHigh(uint256,address)", "0x7191bc6200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000D0004F"]).assert_success().stdout_eq(str![[r#"
101
Expand All @@ -1499,8 +1519,9 @@ casttest!(error_decode_with_sig, |_prj, cmd| {
"#]]);
});

// tests cast can decode traces with Openchain API
casttest!(error_decode_with_openchain, |_prj, cmd| {
// tests cast can decode error with Openchain API
casttest!(error_decode_with_openchain, |prj, cmd| {
prj.clear_cache();
cmd.args(["decode-error", "0x7a0e198500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000064"]).assert_success().stdout_eq(str![[r#"
ValueTooHigh(uint256,uint256)
101
Expand All @@ -1509,14 +1530,16 @@ ValueTooHigh(uint256,uint256)
"#]]);
});

// tests cast can decode traces when using local sig identifiers cache
forgetest!(error_decode_with_cache, |prj, cmd| {
// tests cast can decode error and event when using local sig identifiers cache
forgetest!(error_event_decode_with_cache, |prj, cmd| {
prj.clear_cache();
foundry_test_utils::util::initialize(prj.root());
prj.add_source(
"LocalProjectContract",
r#"
contract ContractWithCustomError {
error AnotherValueTooHigh(uint256, address);
event MyUniqueEventWithinLocalProject(uint256 a, address b);
}
"#,
)
Expand All @@ -1533,6 +1556,16 @@ AnotherValueTooHigh(uint256,address)
101
0x0000000000000000000000000000000000D0004F
"#]]);
// Assert cast can decode event with local cache.
cmd.cast_fuse()
.args(["decode-event", "0xbd3699995dcc867b64dbb607be2c33be38df9134bef1178df13bfb9446e73104000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"])
.assert_success()
.stdout_eq(str![[r#"
MyUniqueEventWithinLocalProject(uint256,address)
78
0x00000000000000000000000000000DD00000004e
"#]]);
});

Expand Down

0 comments on commit 0f7268f

Please sign in to comment.