Typed values should produce the same standard bytes in different implementations.
LET’S PICTURE IT
Two printers should produce matching forms when they receive the same template and field values.
SEE IT FOR YOURSELF
Follow a dynamic string from head to tailStep 1 / 4
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.
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.At argument byte 32, the string tail begins with length five. This counts the UTF-8 payload bytes and excludes all padding.At argument byte 64, read 68 65 6c 6c 6f for hello. Twenty-seven following zero bytes fill the final content word.The encoding uses ninety-six argument bytes: one offset word, one length word and one padded content word. A normal function call adds a four-byte selector before these bytes.
Animated local teaching model. No wallet, RPC or live blockchain data. Some labels and hashes are abbreviated for readability.
Match the precise schema
Compare the same canonical types and nesting in both implementations. Encoding string text and encoding dynamic bytes containing similar text are not identical schema choices.
Preserve large integers
JavaScript numbers cannot exactly represent every uint256. Supply large values through a lossless representation, and confirm the other language receives the same integer.
Compare complete byte sequences
Normalize harmless hex letter casing for display comparison, then compare the actual bytes. A round trip in one library can miss an error shared by its own encoder and decoder.
Include boundary fixtures
Useful fixtures include empty values, multi-byte text, maximum allowed integers and nested arrays. Record library versions so an observed difference can be reproduced.
Trace a local example
types: uint256,string
values: ["9007199254740993","é"]
no function selector prefix
word 0 · argument offset 0 bytes
0x0000000000000000000000000000000000000000000000000020000000000001
word 1 · argument offset 32 bytes
0x0000000000000000000000000000000000000000000000000000000000000040
word 2 · argument offset 64 bytes
0x0000000000000000000000000000000000000000000000000000000000000002
word 3 · argument offset 96 bytes
0xc3a9000000000000000000000000000000000000000000000000000000000000
The large integer is preserved exactly and the string length is two bytes.