Locate a dynamic bytes argument inside Ethereum calldata

A decoder that measures offsets from the start of a transaction input lands four bytes early. For a top-level ABI argument tuple, the offset base begins after the function selector.

Walk through one short payload

For write(bytes) carrying the three bytes aabbcc, first skip the four-byte selector. The first argument word contains 32. Move forward 32 bytes from the start of the arguments to read the length word, which contains 3.

word 0 = 0x20
word 1 = 0x03
word 2 = aabbcc followed by 29 zero bytes

Read exactly three bytes after the length word. Ignore the right padding to the next ABI word. The entire encoded argument tuple occupies 96 bytes, even though the payload contains only three.

Validate offsets before slicing

Reject truncated data, lengths outside the buffer and integer overflow during bounds checks. Offsets inside nested dynamic structures are relative to their own containing encoding. Applying the top-level offset base to every nested value misreads valid calldata. docs.soliditylang.org Solidity ABI