Nuthatch is a log indexer: it turns a contract’s events into SQL tables. This page explains the mapping.
ABIs
At init, nuthatch resolves the contract’s ABI - Sourcify first, then an Etherscan-class API - and
vendors it into abis/. From then on the ABI is a local file; nuthatch never re-fetches it at
runtime. A DecodeRegistry is built from the vendored ABIs at startup: topic0 → event decoder,
filtered by contract address.
If a contract is a proxy, edit the abi path in nuthatch.toml to point at the implementation’s ABI.
One table per event
Every declared event becomes a table named {alias}__{event_snake_case}. For a contract aliased usdc
with a Transfer(address from, address to, uint256 value) event, you get a table usdc__transfer with
columns from, to, value.
Implicit columns
Every table also carries the same implicit columns, before the event’s own fields:
| Column | Meaning |
|---|---|
block_number | The block the log was in. |
block_hash | The canonical block hash (a reorg checkpoint). |
block_timestamp | The block header timestamp. |
tx_hash | The transaction hash. |
log_index | The log’s index within the block. |
address | The emitting contract (distinguishes children sharing a table - see factories). |
_seq | A single monotonic per-row ordering key, derived deterministically from (block, log_index). |
Column types
Decoded fields keep their Solidity types. Wide integers (uint256, and anything over 64 bits) are
stored as an exact decimal string, with a derived {col}_dec DECIMAL column for numeric use. A value
over 38 digits exceeds DECIMAL(38,0) - cast to DOUBLE or HUGEINT in SQL when you need arithmetic.
See The SQL surface.
Regenerating
schema.json (the machine-readable list of tables + columns) and the AI surface (llms.txt, semantic
footguns) are derived from nuthatch.toml + the ABIs. After editing config, regenerate them:
nuthatch schema
Next
- Authored SQL views - derive answers over these tables
- Factories - index children that share a table
- The SQL surface - querying, and the big-int columns