Skip to content

Commit 7135fd2

Browse files
grandizzyrplusq
authored andcommitted
feat(cast): decode-event with local and openchain API (foundry-rs#9431)
1 parent ef0c672 commit 7135fd2

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

crates/cast/bin/args.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,8 +533,9 @@ pub enum CastSubcommand {
533533
/// Decode event data.
534534
#[command(visible_aliases = &["event-decode", "--event-decode", "ed"])]
535535
DecodeEvent {
536-
/// The event signature.
537-
sig: String,
536+
/// The event signature. If none provided then tries to decode from local cache or `https://api.openchain.xyz`.
537+
#[arg(long, visible_alias = "event-sig")]
538+
sig: Option<String>,
538539
/// The event data to decode.
539540
data: String,
540541
},

crates/cast/bin/main.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,29 @@ async fn main_args(args: CastArgs) -> Result<()> {
213213
print_tokens(&tokens);
214214
}
215215
CastSubcommand::DecodeEvent { sig, data } => {
216-
let event = get_event(sig.as_str())?;
217-
let decoded_event = event.decode_log_parts(None, &hex::decode(data)?, false)?;
216+
let decoded_event = if let Some(event_sig) = sig {
217+
get_event(event_sig.as_str())?.decode_log_parts(None, &hex::decode(data)?, false)?
218+
} else {
219+
let data = data.strip_prefix("0x").unwrap_or(data.as_str());
220+
let selector = data.get(..64).unwrap_or_default();
221+
let identified_event =
222+
SignaturesIdentifier::new(Config::foundry_cache_dir(), false)?
223+
.write()
224+
.await
225+
.identify_event(&hex::decode(selector)?)
226+
.await;
227+
if let Some(event) = identified_event {
228+
let _ = sh_println!("{}", event.signature());
229+
let data = data.get(64..).unwrap_or_default();
230+
get_event(event.signature().as_str())?.decode_log_parts(
231+
None,
232+
&hex::decode(data)?,
233+
false,
234+
)?
235+
} else {
236+
eyre::bail!("No matching event signature found for selector `{selector}`")
237+
}
238+
};
218239
print_tokens(&decoded_event.body);
219240
}
220241
CastSubcommand::DecodeError { sig, data } => {

crates/cast/tests/cli/main.rs

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,15 +1539,35 @@ casttest!(string_decode, |_prj, cmd| {
15391539
"#]]);
15401540
});
15411541

1542-
casttest!(event_decode, |_prj, cmd| {
1543-
cmd.args(["decode-event", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
1542+
// tests cast can decode event with provided signature
1543+
casttest!(event_decode_with_sig, |_prj, cmd| {
1544+
cmd.args(["decode-event", "--sig", "MyEvent(uint256,address)", "0x000000000000000000000000000000000000000000000000000000000000004e0000000000000000000000000000000000000000000000000000000000d0004f"]).assert_success().stdout_eq(str![[r#"
15441545
78
15451546
0x0000000000000000000000000000000000D0004F
15461547
1548+
"#]]);
1549+
1550+
cmd.args(["--json"]).assert_success().stdout_eq(str![[r#"
1551+
[
1552+
"78",
1553+
"0x0000000000000000000000000000000000D0004F"
1554+
]
1555+
15471556
"#]]);
15481557
});
15491558

1550-
// tests cast can decode traces with provided signature
1559+
// tests cast can decode event with Openchain API
1560+
casttest!(event_decode_with_openchain, |prj, cmd| {
1561+
prj.clear_cache();
1562+
cmd.args(["decode-event", "0xe27c4c1372396a3d15a9922f74f9dfc7c72b1ad6d63868470787249c356454c1000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"]).assert_success().stdout_eq(str![[r#"
1563+
BaseCurrencySet(address,uint256)
1564+
0x000000000000000000000000000000000000004e
1565+
15187004358734 [1.518e13]
1566+
1567+
"#]]);
1568+
});
1569+
1570+
// tests cast can decode error with provided signature
15511571
casttest!(error_decode_with_sig, |_prj, cmd| {
15521572
cmd.args(["decode-error", "--sig", "AnotherValueTooHigh(uint256,address)", "0x7191bc6200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000D0004F"]).assert_success().stdout_eq(str![[r#"
15531573
101
@@ -1564,8 +1584,9 @@ casttest!(error_decode_with_sig, |_prj, cmd| {
15641584
"#]]);
15651585
});
15661586

1567-
// tests cast can decode traces with Openchain API
1568-
casttest!(error_decode_with_openchain, |_prj, cmd| {
1587+
// tests cast can decode error with Openchain API
1588+
casttest!(error_decode_with_openchain, |prj, cmd| {
1589+
prj.clear_cache();
15691590
cmd.args(["decode-error", "0x7a0e198500000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000000000000000000064"]).assert_success().stdout_eq(str![[r#"
15701591
ValueTooHigh(uint256,uint256)
15711592
101
@@ -1574,14 +1595,16 @@ ValueTooHigh(uint256,uint256)
15741595
"#]]);
15751596
});
15761597

1577-
// tests cast can decode traces when using local sig identifiers cache
1578-
forgetest!(error_decode_with_cache, |prj, cmd| {
1598+
// tests cast can decode error and event when using local sig identifiers cache
1599+
forgetest!(error_event_decode_with_cache, |prj, cmd| {
1600+
prj.clear_cache();
15791601
foundry_test_utils::util::initialize(prj.root());
15801602
prj.add_source(
15811603
"LocalProjectContract",
15821604
r#"
15831605
contract ContractWithCustomError {
15841606
error AnotherValueTooHigh(uint256, address);
1607+
event MyUniqueEventWithinLocalProject(uint256 a, address b);
15851608
}
15861609
"#,
15871610
)
@@ -1598,6 +1621,16 @@ AnotherValueTooHigh(uint256,address)
15981621
101
15991622
0x0000000000000000000000000000000000D0004F
16001623
1624+
"#]]);
1625+
// Assert cast can decode event with local cache.
1626+
cmd.cast_fuse()
1627+
.args(["decode-event", "0xbd3699995dcc867b64dbb607be2c33be38df9134bef1178df13bfb9446e73104000000000000000000000000000000000000000000000000000000000000004e00000000000000000000000000000000000000000000000000000dd00000004e"])
1628+
.assert_success()
1629+
.stdout_eq(str![[r#"
1630+
MyUniqueEventWithinLocalProject(uint256,address)
1631+
78
1632+
0x00000000000000000000000000000DD00000004e
1633+
16011634
"#]]);
16021635
});
16031636

0 commit comments

Comments
 (0)