book icon indicating copy to clipboard operation
book copied to clipboard

docs(`cast`): document `abi-encode` / `abi-decode` with nested structs that contain arrays

Open zerosnacks opened this issue 5 months ago • 10 comments

Sections

cast abi-encode cast abi-decode

Describe the bug

Document how to correctly pass arguments to cast abi-encode when it has multiple parameters in a nested struct with one of them being an array.

Context: https://gist.github.com/pcaversaccio/0ef8fb8034594e012a4903dfa992369e

From: https://github.com/foundry-rs/book/issues/1286#issuecomment-2347083110

They're 2 different encodings, cast abi-encode encodes for function arguments, not a single struct.

Essentially you're comparing the encoding of (cast abi-encode):

function f( (address,uint256,bytes)[] arg1, address arg2, bytes32 arg3 )

to (expected):

function g( ((address,uint256,bytes)[],address,bytes32) arg1 )

(which is equivalent to the abi.encode(arg1))

You're looking for the second one, so the correct command is achieved by wrapping the struct fields in another pair of parentheses:

cast abi-encode "f(((address,uint256,bytes)[],address,bytes32))" "([(0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB,0,0x79ba5097),(0xD7f9f54194C633F36CCD5F3da84ad4a1c38cB2cB,0,0x79ba5097)],0x8f7a9912416e8AdC4D9c21FAe1415D3318A11897,0x646563656e7472616c697a6174696f6e206973206e6f74206f7074696f6e616c)"

The examples in OP:

$ cast abi-encode "UpgradeProposal((uint256)[],uint256)" "[(1)]" "123"
0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001

$ cast abi-encode "UpgradeProposal(((uint256)[],uint256))" "([(1)],123)"
0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001

Note the extra 0x00..20 at the start

zerosnacks avatar Sep 12 '24 11:09 zerosnacks