In this track: Dynamic ABI and nested layouts
advanced · 5 MIN READ

Encode two dynamic arguments

Later tails begin after the full earlier tail.

LET’S PICTURE IT

Two index entries point to separate attachments whose sizes determine the second starting position.

SEE IT FOR YOURSELF
Follow a dynamic string from head to tailStep 1 / 4
Follow a dynamic string from head to tailArgument headbyte 0 · offset 32hex word ends in 20String tailstarts at byte 32length + contentPositions are measured from argument byte zero, excluding any selectorOffset destinationargument byte 32read a length wordLength = 5hello is five UTF-8 bytescontent starts at byte 64A length word and an offset word have different jobsContent word · argument byte 6468 65 6c 6c 6f5 payload bytes27 padding bytesBlocks are schematic; their drawn widths do not represent the exact byte ratioHeadoffset: 32argument byte 0Tail lengthlength: 5argument byte 32Tail contenthello + paddingargument byte 6432 + 32 + 32 = 96 bytesWith a four-byte selector, total calldata length is 100 bytes

This example encodes one string parameter with value hello. A dynamic argument uses an offset in its head, even when it is the only argument.

Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.

Reserve both head entries

For string and bytes, each dynamic member contributes one offset word. Their shared head is sixty-four bytes, so the first tail starts at byte 64.

Build the first complete tail

The string a uses one length word and one padded content word. Its complete tail takes sixty-four bytes, even though the original text is only one byte.

Place the second pointer

The second tail starts at byte 128: sixty-four head bytes plus sixty-four bytes for the first tail. Both top-level pointers use the same tuple base.

Check a size change

Growing the first payload past thirty-two bytes adds another content word and moves the second tail. The head size stays fixed because the parameter types have not changed.

Trace a local example

types: string,bytes
values: ["a","0x1234"]
no function selector prefix

word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000000000000000040

word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000080

word 2 · argument offset 64 bytes
0x0000000000000000000000000000000000000000000000000000000000000001

word 3 · argument offset 96 bytes
0x6100000000000000000000000000000000000000000000000000000000000000

word 4 · argument offset 128 bytes
0x0000000000000000000000000000000000000000000000000000000000000002

word 5 · argument offset 160 bytes
0x1234000000000000000000000000000000000000000000000000000000000000

The head words are offsets 64 and 128.

TURN UNDERSTANDING INTO PRACTICEOpen the ABI encoder →
QUICK CHECK · NO PRESSURE

Where does the second tail begin in this example?

Your progress stays in this browser.
Keep exploring the original referenceSolidity documentation ↗

Original explanations by EtherTools. Examples are educational and source-linked; this site is independent of the Ethereum Foundation. Our approach.