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

Fix how indexed event parameters of dynamically-sized types are handled #132

Open
dhruvio opened this issue Jul 2, 2022 · 1 comment
Open

Comments

@dhruvio
Copy link

dhruvio commented Jul 2, 2022

Description

When an event has an indexed parameter of type bytes, the abi and abiFrom template Haskell helpers produce Tagged n Bytes types inside an event's *Indexed and event types. Instead, they should produce Tagged n (BytesN 32) types for these indexed parameters instead given the documentation states that the keccak256 hash of dynamically-sized types is what is indexed, not the underlying bytes value.

For my use-case, I was trying to get logs from Ethereum for events with an indexed bytes parameter. However, I received a run-time error because decoding the event was failing due to a EventParseFailure "[\"Failed reading: getBytes: negative length requested\\nEmpty call stack\\n\"]" error. I manually dumped the splices for my contract's ABI .hs module into a separate module and imported that directly instead of the quasi-quoted version (after adding imports and pacifying the compiler). Then, I changed the indexed parameter in the file to use BytesN 32 instead of Bytes, and the event parse succeeded.

From the documentation:

Source: https://docs.soliditylang.org/en/v0.8.13/abi-spec.html#indexed-event-encoding

Indexed event parameters that are not value types, i.e. arrays and structs are not stored directly but instead a keccak256-hash of an encoding is stored. This encoding is defined as follows:

  • the encoding of a bytes and string value is just the string contents without any padding or length prefix.
  • the encoding of a struct is the concatenation of the encoding of its members, always padded to a multiple of 32 bytes (even bytes and string).
  • the encoding of an array (both dynamically- and statically-sized) is the concatenation of the encoding of its elements, always padded to a multiple of 32 bytes (even bytes and string) and without any length prefix

Requested Changes

Network.Ethereum.Contract.TH should be updated to fix the types generated for bytes and string indexed parameters for events. It may be worthwhile using a richer type, like Digest Keccak256, instead of BytesN 32.

Also, the above-linked documentation states that indexed array and struct event parameters are also hashed using keccak256. Those may need to be addressed as a part of this issue too.

@akru
Copy link
Member

akru commented Jul 29, 2022

Thank you for report! Feel free to create PR with fix if you wish.

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

2 participants