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.
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.
Description
When an event has an indexed parameter of type
bytes
, theabi
andabiFrom
template Haskell helpers produceTagged n Bytes
types inside an event's*Indexed
and event types. Instead, they should produceTagged 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 underlyingbytes
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 aEventParseFailure "[\"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 useBytesN 32
instead ofBytes
, 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:
Requested Changes
Network.Ethereum.Contract.TH
should be updated to fix the types generated forbytes
andstring
indexed parameters for events. It may be worthwhile using a richer type, likeDigest Keccak256
, instead ofBytesN 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.