Fixed bytes are right-padded, unlike unsigned integers.
LET’S PICTURE IT
A label occupying the front of a fixed-width field leaves blank space after it.
SEE IT FOR YOURSELF
Build a transfer call from typed fieldsStep 1 / 4
The standard transfer interface takes an address and a raw integer amount. This diagram uses address one and amount one hundred.
The standard transfer interface takes an address and a raw integer amount. This diagram uses address one and amount one hundred.Keccak-256 of the canonical signature supplies the first four bytes. The transfer selector is a9059cbb.An address is twenty bytes. Standard ABI encoding adds twelve zero bytes on the left to fill one thirty-two-byte word.The integer one hundred is hex 64, left-padded in word one. Selector plus two words produces sixty-eight bytes of standard calldata.
Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.
Use the declared fixed size
bytes4 contains exactly four bytes; bytes32 contains exactly thirty-two. A value of the wrong declared length needs validation rather than an assumption about how the author meant to pad it.
Pad the standard word on the right
bytes4 0x12345678 begins the ABI word with those four bytes, then twenty-eight zero bytes follow. A uint32 with the same bits would appear at the other end of its word.
Do not confuse dynamic bytes
The dynamic bytes type uses an offset-and-tail layout when placed in an argument tuple. It is not simply bytes32 with a variable amount of trimming.
Inspect selectors carefully
A selector can be described as bytes4 in application logic, but the selector prefix of function calldata is only four actual bytes. It is not automatically a full encoded bytes4 argument word.
Follow the bytes
types: bytes4
values: ["0x12345678"]
no function selector prefix
word 0 · argument offset 0 bytes
0x1234567800000000000000000000000000000000000000000000000000000000
Compare this alignment with a uint32 encoding of the same numeric bits.