0xcalldata

4-byte function identifiers

Ethereum function selectors

In a standard ABI-encoded function call, the first four bytes are the function selector. Compiler-generated dispatch code uses it to choose a function and decode its arguments, but Ethereum itself does not enforce this convention and the selector is not globally unique.

From signature to selector

Take the Keccak-256 hash of the UTF-8 canonical signature, then keep its first four bytes. Ethereum uses Keccak-256 here—not the standardized SHA3-256 variant.

  1. 1Write the canonical signaturetransfer(address,uint256)
  2. 2Hash that exact text with Keccak-2560xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b
  3. 3Keep the first four bytes0xa9059cbb

The selector is placed before the encoded arguments. This example encodes 10¹⁸ base units for transfer(address,uint256). A token UI would display that as one token only if the target token uses 18 decimals; neither the target nor its decimals are contained in these bytes. Line breaks only show the three parts.

68-byte transfer(address,uint256) call
a9059cbb                                                        selector
0000000000000000000000002222222222222222222222222222222222222222  to
0000000000000000000000000000000000000000000000000de0b6b3a7640000  amount
Open this call in the decoder →

What belongs in the canonical signature?

Include the function name and the canonical input types, in order, with no spaces. Leave out the function keyword, parameter names, data-location specifiers such as memory, calldata, or storage, return types, visibility, and state mutability. Changing an input type or its position changes the selector.

Expand Solidity type aliases before hashing manually: uint becomes uint256, int becomes int256, and address payable becomes address. A tuple is written using its component types, such as (address,uint256)[], rather than the word tuple[].

Canonical signatureSelectorWhat changed
transfer(address,uint256)0xa9059cbbERC-20 transfer
approve(address,uint256)0x095ea7b3Different name
safeTransferFrom(address,address,uint256)0x42842e0eThree inputs
safeTransferFrom(address,address,uint256,bytes)0xb88d4fdeOverload adds bytes

The address supplies the context

Every contract that implements transfer(address,uint256) uses the same 0xa9059cbb selector. The destination address determines which contract receives the call; that contract’s deployed code determines whether the selector is implemented and what the function actually does.

This is why a transaction’s input data can suggest a function without identifying a token, protocol, or even the intended semantics. Those facts come from the target address, verified source code, and ABI—not from the four bytes alone.

Different signatures can collide

Four bytes allow only 2³² possible selectors. Keccak-256 still produces a 32-byte hash, but truncating it means unrelated signatures can share the same prefix. A known example is:

Two signatures, one selector
burn(uint256)                         → 0x42966c68
collate_propagate_storage(bytes16)    → 0x42966c68

A contract normally knows which schema applies because its dispatcher was compiled for the functions it implements. A general-purpose decoder does not have that context. It should therefore treat selector-database results as candidates, try the argument layouts, and preserve multiple valid interpretations instead of declaring the first text match authoritative.

Common selector questions

Do overloaded functions have different selectors?

Yes. Overloads share a name but have different input-type lists, so their canonical signatures—and therefore their selectors—are different.

Does every calldata payload start with a selector?

No. Standard ABI-encoded function calls do. Constructor arguments, plain ETH receive calls, and arbitrary fallback payloads do not have to follow this structure. Return data and event data use different conventions too.

Are event topics also function selectors?

No. A non-anonymous event normally places the full 32-byte Keccak-256 hash of its canonical event signature in topic zero. Custom errors do use a 4-byte selector, but it appears in revert data rather than call dispatch.

Can I trust a selector lookup result?

Treat it as a lead. Public databases map selectors to submitted signature text, and collisions are possible. A verified ABI for the target contract is stronger evidence; decoding and re-encoding the arguments can eliminate candidates that do not fit the bytes.