In this track: Write and read Solidity
advanced · 4 MIN READ

Strings and UTF-8

Byte length and visible character count can differ.

LET’S PICTURE IT

A word can contain a symbol that occupies several encoded bytes even though it looks like one character.

SEE IT FOR YOURSELF
Build a transfer call from typed fieldsStep 1 / 4
Build a transfer call from typed fieldstransfer(address,uint256)Recipient: 0x0000…0001Raw amount: 100Diagram labels abbreviate addresses; the lab shows full bytes4-byte selectora9059cbbEach box is one byte; this prefix is not a 32-byte wordWord 0 · recipient address12 zero bytes20 address bytes000…0001Left padding preserves the lower-order address valueSelector4 bytesa9059cbbAddress32 bytesword 0Amount32 bytesword 1 → 0x644 + 32 + 32 = 68 bytesThe integer does not contain token decimals or market price

The standard transfer interface takes an address and a raw integer amount. This diagram uses address one and amount one hundred.

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

A string is encoded data

Solidity string is used for text-like variable-length data. Applications commonly interpret its bytes as UTF-8. The language does not make every possible byte sequence a meaningful human word.

Length is a byte question in encoding

For example, the UTF-8 text é takes two bytes. An ABI dynamic string stores a byte length, then the encoded bytes and padding. A visible-character counter is not a reliable substitute.

Normalization can change bytes

Two visually similar strings may use different Unicode compositions and therefore hash differently. Contracts and signatures operate on exact encoded data, so applications need explicit text conventions where identity matters.

Try a non-ASCII message

Choose setMessage(string) in the ABI lab and encode a short message containing a multibyte character. Follow its offset, byte length and padded data rather than counting what the screen appears to show.

Read the example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract LearningExample {
    function byteLength(string calldata text)
        external pure returns (uint256)
    {
        return bytes(text).length;
    }
}

This returns byte length rather than a human-perceived character count.

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

Does one visible text character always occupy one UTF-8 byte?

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.