From 43b229114079892c423c591ab95cc5e7a9744688 Mon Sep 17 00:00:00 2001 From: Maxim Andreev Date: Sat, 20 Jan 2024 10:13:20 +0300 Subject: [PATCH] feat(cast/selectors): add optional selectors resolving --- crates/cast/bin/main.rs | 31 +++++++++++++++++++++++++------ crates/cast/bin/opts.rs | 9 ++++++++- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/crates/cast/bin/main.rs b/crates/cast/bin/main.rs index eacae735465d..24d7b62904a4 100644 --- a/crates/cast/bin/main.rs +++ b/crates/cast/bin/main.rs @@ -14,8 +14,9 @@ use foundry_common::{ fmt::format_tokens, fs, selectors::{ - decode_calldata, decode_event_topic, decode_function_selector, import_selectors, - parse_signatures, pretty_calldata, ParsedSignatures, SelectorImportData, + decode_calldata, decode_event_topic, decode_function_selector, decode_selectors, + import_selectors, parse_signatures, pretty_calldata, ParsedSignatures, SelectorImportData, + SelectorType, }, types::{ToAlloy, ToEthers}, }; @@ -269,10 +270,28 @@ async fn main() -> Result<()> { Subcommands::Disassemble { bytecode } => { println!("{}", SimpleCast::disassemble(&bytecode)?); } - Subcommands::Selectors { bytecode } => { - let s = SimpleCast::extract_selectors(&bytecode)?; - let v: Vec<_> = s.into_iter().map(|r| format!("{}\t{}", r.0, r.1)).collect(); - println!("{}", v.join("\n")); + Subcommands::Selectors { bytecode, resolve } => { + let selectors_and_args = SimpleCast::extract_selectors(&bytecode)?; + if resolve { + let selectors_it = selectors_and_args.iter().map(|r| &r.0); + let resolve_results = + decode_selectors(SelectorType::Function, selectors_it).await?; + + let max_args_len = selectors_and_args.iter().map(|r| r.1.len()).max().unwrap_or(0); + for ((selector, arguments), func_names) in + selectors_and_args.into_iter().zip(resolve_results.into_iter()) + { + let resolved = match func_names { + Some(v) => v.join("|"), + None => "".to_string(), + }; + println!("{selector}\t{arguments:max_args_len$}\t{resolved}"); + } + } else { + for (selector, arguments) in selectors_and_args { + println!("{selector}\t{arguments}"); + } + } } Subcommands::FindBlock(cmd) => cmd.run().await?, Subcommands::GasPrice { rpc } => { diff --git a/crates/cast/bin/opts.rs b/crates/cast/bin/opts.rs index c4a2fd0ba341..141861a9e380 100644 --- a/crates/cast/bin/opts.rs +++ b/crates/cast/bin/opts.rs @@ -862,7 +862,14 @@ pub enum Subcommands { /// Extracts function selectors and arguments from bytecode #[clap(visible_alias = "sel")] - Selectors { bytecode: String }, + Selectors { + /// The hex encoded bytecode. + bytecode: String, + + /// Resolve the function signatures for the extracted selectors using https://openchain.xyz + #[clap(long, short)] + resolve: bool, + }, } /// CLI arguments for `cast --to-base`.