Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encodePacked appears to have different behavior from solidity for complex types #149

Open
charles-cooper opened this issue Aug 1, 2021 · 2 comments

Comments

@charles-cooper
Copy link
Contributor

charles-cooper commented Aug 1, 2021

For arrays, encodePacked appears to fall back to standard encoding.

encoded_elements = self.encode_elements(value)

->

eth-abi/eth_abi/encoding.py

Lines 615 to 631 in decaadc

def encode_elements(self, value):
self.validate_value(value)
item_encoder = self.item_encoder
tail_chunks = tuple(item_encoder(i) for i in value)
items_are_dynamic = getattr(item_encoder, 'is_dynamic', False)
if not items_are_dynamic:
return b''.join(tail_chunks)
head_length = 32 * len(value)
tail_offsets = (0,) + tuple(accumulate(map(len, tail_chunks[:-1])))
head_chunks = tuple(
encode_uint_256(head_length + offset)
for offset in tail_offsets
)
return b''.join(head_chunks + tail_chunks)

However, solidity skips the length and pads dynamic array elements with zeros:
https://docs.soliditylang.org/en/v0.8.6/abi-spec.html#non-standard-packed-mode

The encoding of an array is the concatenation of the encoding of its elements with padding.

cf. ethereum/solidity#8441 for an example of the current padding scheme.

Additionally, and please correct me if I'm wrong here, eth-abi appears to encode bytestrings in tuples without padding as in the tests here

decode_hex(
'646176696420617474656e626f726f756768' # encoding of b'david attenborough'
'00' # encoding for `False`
'626f617479206d63626f617466616365' # encoding of b'boaty mcboatface'
'01' # encoding for `True`
),

However my cursory reading of solc output says that they are in fact padded. (solidity disallows structs in abi.encodePacked, but it uses the packed encoding code path to calculate event indexes).
event.ir.txt
event.sol.txt

@kclowes
Copy link
Contributor

kclowes commented Aug 12, 2021

Thanks for the report @charles-cooper. On first glance, this does look like a bug. It will probably be a few weeks before I can get to really digging in though. If you want to open a PR, that will be the fastest way to get it fixed, otherwise I can take a deeper look in a few weeks.

@charles-cooper
Copy link
Contributor Author

I'm wondering if it's worth fixing. ethereum/solidity#11593 says encodePacked is going to be removed, it's unclear to me what the effect will be on event indexes though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants