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

Tuples containing strings

One dynamic component makes the tuple dynamic.

LET’S PICTURE IT

A form becomes expandable when even one field contains an attachment.

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.

Inspect each component

The tuple (uint256,string) contains one static integer and one dynamic string. The containing tuple is dynamic, even when the supplied string happens to be short.

Follow the outer offset

As one top-level parameter, this tuple starts behind an outer offset. Inside its body, the integer appears directly and the string is represented by another offset.

Use the tuple-local pointer

The inner string pointer is 64 for this two-word tuple head. Add it to the tuple body base, not to argument byte zero, to find the string length word.

Distinguish nesting from flat parameters

Two top-level parameters uint256,string share their head at argument byte zero. A single tuple parameter adds an outer pointer layer because that parameter itself is dynamic.

Trace a local example

types: (uint256,string)
values: [["7","hi"]]
no function selector prefix

word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000000000000000020

word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000007

word 2 · argument offset 64 bytes
0x0000000000000000000000000000000000000000000000000000000000000040

word 3 · argument offset 96 bytes
0x0000000000000000000000000000000000000000000000000000000000000002

word 4 · argument offset 128 bytes
0x6869000000000000000000000000000000000000000000000000000000000000

An outer offset points to a tuple whose string has a local offset.

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

Does a short string make its containing tuple static?

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.