-
Notifications
You must be signed in to change notification settings - Fork 795
feat(abigen): add EthAbiCodec proc macro #704
Conversation
Fixed clippy lints on #705 |
Awesome. It works well on the struct I was testing with. I noticed something that seems a bit strange to me. In order to If I use the new decode method on that I do get and extra Tried to illustrate this below abigen!(
Example,
r#"[
struct Foo { uint256[] a; }
function readFoo(bytes b)
]"#,
event_derives(serde::Deserialize, serde::Serialize);
);
let a = vec![U256::from(255)];
let foo = Foo { a };
fn disp(b: &[u8]) {
hex::encode(b)
.chars()
.collect::<Vec<char>>()
.chunks(64)
.for_each(|x| println!("{}", x.iter().collect::<String>()));
println!("");
}
let encoded = foo.clone().encode();
disp(&encoded);
// 0000000000000000000000000000000000000000000000000000000000000020
// 0000000000000000000000000000000000000000000000000000000000000001
// 00000000000000000000000000000000000000000000000000000000000000ff
// same as encode above
let from_tokens = abi::encode(&Tokenize::into_tokens(foo.clone()));
disp(&from_tokens);
// 0000000000000000000000000000000000000000000000000000000000000020
// 0000000000000000000000000000000000000000000000000000000000000001
// 00000000000000000000000000000000000000000000000000000000000000ff
let encoded_wrapped = (foo.clone(),).encode();
disp(&encoded_wrapped);
// 0000000000000000000000000000000000000000000000000000000000000020 X
// 0000000000000000000000000000000000000000000000000000000000000020 X
// 0000000000000000000000000000000000000000000000000000000000000020
// 0000000000000000000000000000000000000000000000000000000000000001
// 00000000000000000000000000000000000000000000000000000000000000ff
// this works with abi.decode(b, (Foo)) in a contract
let from_tokens_wrapped = abi::encode(&Tokenize::into_tokens((foo.clone(),)));
disp(&from_tokens_wrapped);
// 0000000000000000000000000000000000000000000000000000000000000020 X
// 0000000000000000000000000000000000000000000000000000000000000020
// 0000000000000000000000000000000000000000000000000000000000000001
// 00000000000000000000000000000000000000000000000000000000000000ff |
nice catch! |
Yes. I'm getting matching outputs now for the tuple 🥳
|
let tuple = (val,); | ||
let encoded = tuple.clone().encode(); | ||
let decoded = <(SomeType,)>::decode(&encoded).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this tuple syntax seems like a footgun? can we get rid of the x,)
requirement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a bit weird but this ist the required rust syntax for single-element tuple, otherwise it would just be a parenthesized expression
https://doc.rust-lang.org/1.30.0/book/second-edition/appendix-02-operators.html
Motivation
Add AbiEncode + AbiDecode implementation for custom structs.
Currently, those get derived for EthCall only.
Solution
Add
EthAbiCodec
as a complementary proc macro toEthAbiType
that derives encode/decode.The reason why this needs to be separate and not included in
EthAbiType
is because in EthCall we have an additional leading 4byte selector, soEthCall
needs to implement the codec traits but requires all the tokenized support thatEthAbiType
provides.So we simply add an additional
EthAbiCodec
derive when we generate AbiEncoderV2 structs within abigen!PR Checklist