0xa9059cbb
transfer(address,uint256)
Paste a Solidity signature, selector, custom error, or calldata blob and get the ABI routing bytes without digging through documentation.
0xa9059cbb
transfer(address,uint256)
0xa9059cbb2ab09eb2...
a9059cbb
address recipient, uint256 amount
| Signature | Type | Selector |
|---|
Results come from a local database of common signatures. For comprehensive lookups, check 4byte.directory or Openchain.
0xa9059cbb
64 bytes
No known matches found for this selector in our local database.
Try looking up this selector on 4byte.directory or Openchain.
How the EVM reads function calls
a9059cbb
0000...recipient
0000...amount
Example: transfer(address,uint256) call to send 100 tokens to an address.
Placed at the start of calldata so the dispatcher knows which function to run.
Stored as topic[0], using the full hash for log filtering.
Custom revert data starts with the error selector, just like calldata.
When you call a function on an Ethereum smart contract, the EVM doesn't use the function name directly. Instead, each function is identified by its selector, a compact 4-byte identifier derived from the function's signature. This selector is the first 4 bytes of the keccak256 hash of the function's canonical signature.
For example, calling transfer(address,uint256) on an ERC-20 token doesn't send the string "transfer" on-chain. It sends 0xa9059cbb followed by ABI-encoded arguments. The contract's dispatcher matches this 4-byte prefix to the correct function's code.
The computation follows three steps:
transfer(address,uint256)
bytes4(keccak256("transfer(address,uint256)")), which equals 0xa9059cbb.
Functions use a 4-byte selector placed at the beginning of transaction calldata. The EVM's dispatcher uses this to route the call.
Events use the full 32-byte keccak256 hash as topic[0] in the transaction log. The full hash is needed because logs are indexed for efficient filtering, and 4 bytes would cause too many collisions across all contracts.
Custom Errors (introduced in Solidity 0.8.4) use a 4-byte selector just like functions. When a contract reverts with a custom error, the revert data starts with the error's 4-byte selector instead of the generic Error(string) selector.
If you see a value like 0xef28f901 in revert data, calldata, a trace, or an explorer, treat it as a selector first. Paste it into the decode tab to check local known matches, then compare against 4byte.directory or Openchain when the selector is not in the local database.
For a custom error, compute the selector from the canonical error signature, such as NotOwner(address). For collision-sensitive systems, review the selector against proxy, router, diamond, and fallback dispatch code so a selector collision cannot route a call to the wrong logic.
Since selectors are only 4 bytes, collisions are mathematically inevitable. Different function signatures can produce identical selectors.
In transparent proxy patterns, if a proxy function's selector collides with an implementation function's selector, the proxy intercepts the call. Attackers have exploited this to bypass access controls and call unintended logic.
Selector clashing is also used in calldata-based phishing, where malicious contracts disguise function calls to deceive users and wallets.
Learn About Call AttacksMost frequently used selectors in Ethereum smart contracts
| Selector | Function | Standard | Action |
|---|---|---|---|
0xa9059cbb |
transfer(address,uint256) | ERC-20 | |
0x095ea7b3 |
approve(address,uint256) | ERC-20 | |
0x23b872dd |
transferFrom(address,address,uint256) | ERC-20 | |
0x70a08231 |
balanceOf(address) | ERC-20 | |
0xdd62ed3e |
allowance(address,address) | ERC-20 | |
0x18160ddd |
totalSupply() | ERC-20 | |
0x6352211e |
ownerOf(uint256) | ERC-721 | |
0x42842e0e |
safeTransferFrom(address,address,uint256) | ERC-721 | |
0xc87b56dd |
tokenURI(uint256) | ERC-721 |
A function selector is the first 4 bytes of the keccak256 hash of a function's canonical signature. For example, transfer(address,uint256) has the selector 0xa9059cbb. The EVM uses this 4-byte identifier to determine which function to execute when a smart contract receives a call. Every external and public function in a Solidity contract has a unique selector within that contract.
Write the function name followed by its parameter types in parentheses with no spaces or parameter names (e.g., transfer(address,uint256)). Hash this string using keccak256 to get a 32-byte digest. The function selector is the first 4 bytes (8 hex characters) prefixed with 0x. In Solidity, you can compute it as bytes4(keccak256("transfer(address,uint256)")).
Both are derived from the keccak256 hash of the signature, but they differ in length and usage. A function selector is only 4 bytes and is placed at the beginning of calldata to route function calls. An event topic uses the full 32-byte keccak256 hash and is stored in the log's topic[0] field. Events use the full hash because logs are indexed for efficient filtering across all contracts, and 4 bytes would cause excessive collisions.
Yes. Since selectors are only 4 bytes (about 4.3 billion possibilities), different function signatures can produce the same selector. The Solidity compiler prevents collisions within a single contract at compile time, but collisions across different contracts are common. In proxy patterns, a proxy function's selector can collide with an implementation function's selector, creating a security vulnerability known as selector clashing. EIP-1967 and the transparent proxy pattern were designed to mitigate this risk.
Extract the first 4 bytes from the calldata. That's the function selector. Look it up in a signature database like 4byte.directory or Openchain. If a match is found, you know the function name and parameter types, and can ABI-decode the remaining calldata bytes to extract the argument values. Note that multiple signatures may match the same selector.
Learn how selector collisions, calldata manipulation, and low-level call vulnerabilities lead to real-world exploits. Our comprehensive course teaches you to identify and prevent these attacks.