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

Build a dynamic encoding trace

Annotate byte positions before trying to memorize a long hex string.

LET’S PICTURE IT

A map becomes readable when each turn has an origin, distance and destination.

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.

Write the declaration and values

Use setMessage(string) with hello as a small reproducible request. Keep the declaration, canonical signature, typed argument and selector visible alongside the encoded output.

Divide framing and arguments

The first four bytes select the function. Label argument byte zero immediately afterward. The first argument word contains offset 32, so the string tail begins at calldata byte 36.

Annotate the tail

At that destination, the length word is five. The content begins at calldata byte 68 and contains hello followed by twenty-seven padding bytes.

Verify by changing one thing

Replace hello with an empty string or a thirty-three-byte ASCII string. Predict which lengths and total sizes change, then compare the locally generated bytes with your prediction.

Trace a local example

types: string
values: ["hello"]
no function selector prefix

word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000000000000000020

word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000005

word 2 · argument offset 64 bytes
0x68656c6c6f000000000000000000000000000000000000000000000000000000

Parameter encoding shown here excludes the selector; add four to convert its positions to calldata positions.

Complete function input

function setMessage(string message)
arguments: ["hello"]

selector: 0x368b8772
arguments begin at calldata byte 4

word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000000000000000020

word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000005

word 2 · argument offset 64 bytes
0x68656c6c6f000000000000000000000000000000000000000000000000000000

Here the selector is shown separately from the argument words.

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

Where does hello content begin in this function call?

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.