From 49b9df349eee2d9b9da74a3259713eb3af9336bf Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 5 Jan 2022 03:20:38 -0500 Subject: [PATCH] add cast abi-encode (#374) --- cast/src/lib.rs | 21 +++++++++++++++++++++ cli/src/cast.rs | 3 +++ cli/src/opts/cast.rs | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/cast/src/lib.rs b/cast/src/lib.rs index e2bc30b3f81c..08e3359dd9e1 100644 --- a/cast/src/lib.rs +++ b/cast/src/lib.rs @@ -592,6 +592,27 @@ impl SimpleCast { foundry_utils::abi_decode(sig, calldata, input) } + /// Performs ABI encoding based off of the function signature. Does not include + /// the function selector in the result. + /// + /// ``` + /// # use cast::SimpleCast as Cast; + /// + /// # fn main() -> eyre::Result<()> { + /// assert_eq!( + /// "0x0000000000000000000000000000000000000000000000000000000000000001", + /// Cast::abi_encode("f(uint a)", &["1"]).unwrap().as_str() + /// ); + /// # Ok(()) + /// # } + /// ``` + pub fn abi_encode(sig: &str, args: &[impl AsRef]) -> Result { + let func = AbiParser::default().parse_function(sig.as_ref())?; + let calldata = encode_args(&func, args)?.to_hex::(); + let encoded = &calldata[8..]; + Ok(format!("0x{}", encoded)) + } + /// Converts decimal input to hex /// /// ``` diff --git a/cli/src/cast.rs b/cli/src/cast.rs index 19c89c75d7c8..4cc526304699 100644 --- a/cli/src/cast.rs +++ b/cli/src/cast.rs @@ -204,6 +204,9 @@ async fn main() -> eyre::Result<()> { let tokens = foundry_utils::format_tokens(&tokens); tokens.for_each(|t| println!("{}", t)); } + Subcommands::AbiEncode { sig, args } => { + println!("{}", SimpleCast::abi_encode(&sig, &args)?); + } Subcommands::FourByte { selector } => { let sigs = foundry_utils::fourbyte(&selector).await?; sigs.iter().for_each(|sig| println!("{}", sig.0)); diff --git a/cli/src/opts/cast.rs b/cli/src/opts/cast.rs index 58d94bc89cb2..bd17a77ce083 100644 --- a/cli/src/opts/cast.rs +++ b/cli/src/opts/cast.rs @@ -178,6 +178,16 @@ pub enum Subcommands { #[structopt(long, short, help = "the encoded output, in hex format")] input: bool, }, + #[structopt(name = "abi-encode")] + #[structopt( + help = "ABI encodes the given arguments with the function signature, excluidng the selector" + )] + AbiEncode { + #[structopt(help = "the function signature")] + sig: String, + #[structopt(help = "the list of function arguments")] + args: Vec, + }, #[structopt(name = "4byte")] #[structopt(about = "Fetches function signatures given the selector from 4byte.directory")] FourByte {