Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
Try it Live
Run ABI examples in the interactive playground
Overview
Selectors identify functions, events, and errors in Ethereum. They are derived from canonical signatures using keccak256.
Quick Start
import { Abi } from '@tevm/voltaire/Abi';
const transfer = {
type: 'function',
name: 'transfer',
inputs: [
{ type: 'address', name: 'to' },
{ type: 'uint256', name: 'amount' }
],
outputs: [{ type: 'bool' }]
} as const;
const selector = Abi.Function.getSelector(transfer);
// 0xa9059cbb
import { Abi } from '@tevm/voltaire/Abi';
const Transfer = {
type: 'event',
name: 'Transfer',
inputs: [
{ type: 'address', name: 'from', indexed: true },
{ type: 'address', name: 'to', indexed: true },
{ type: 'uint256', name: 'value' }
]
} as const;
const topic0 = Abi.Event.getSelector(Transfer);
// 0xddf252ad...
import { Abi } from '@tevm/voltaire/Abi';
const InsufficientBalance = {
type: 'error',
name: 'InsufficientBalance',
inputs: [
{ type: 'uint256', name: 'balance' },
{ type: 'uint256', name: 'required' }
]
} as const;
const selector = Abi.Error.getSelector(InsufficientBalance);
// first 4 bytes of keccak256(signature)
Canonical Signatures
Signatures are generated from the canonical type list:
- No whitespace
- Use full size types (
uint256, int256)
- Tuples use parentheses:
foo((uint256,address))
- Arrays include brackets:
foo(address[])
const sig = Abi.Function.getSignature(transfer);
// "transfer(address,uint256)"
Event Topic0 and Anonymous Events
Non-anonymous events include topic0 = keccak256(signature). Anonymous events omit topic0 entirely, so all topics are indexed parameters only.
const anonymous = {
type: 'event',
name: 'Log',
anonymous: true,
inputs: [{ type: 'uint256', name: 'id', indexed: true }]
} as const;
Selector Collisions
Function selectors are 4 bytes, so collisions are possible. You can scan an ABI for collisions:
import { Abi } from '@tevm/voltaire/Abi';
const hasCollisions = Abi.hasSelectorCollisions(erc20Abi);
const collisions = Abi.findSelectorCollisions(erc20Abi);
Event selectors are 32 bytes and effectively collision-free.
Common Selectors
ERC-20 functions:
0xa9059cbb - transfer(address,uint256)
0x23b872dd - transferFrom(address,address,uint256)
0x095ea7b3 - approve(address,uint256)
0x70a08231 - balanceOf(address)
ERC-20 events:
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef - Transfer(address,address,uint256)
0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925 - Approval(address,address,uint256)
Custom Hash Functions
Use selector factories when you need a custom keccak256 implementation:
import { Function } from '@tevm/voltaire/Abi';
const getSelector = Function.GetSelector({
keccak256String: (value) => myKeccak256(value)
});
const selector = getSelector(transfer);
See Also