This tutorial uses the Uniswap V2 USDC–ETH pool at 0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc on Ethereum mainnet. Its contract holds USDC and WETH.
chain.event.eth → Filter the pool’s Sync events → Read end-of-block reserves → Reserve state table
Sign in to the Chaintable console and open your Space. This tutorial uses demo; replace it with your Space ID.
1. Create the reserve state table
In Tables, create a table named pool_reserves, select Block State, and choose Ethereum. Its table ID is demo.pool_reserves.eth.
In the table’s Schema, change id to ADDRESS to store the pool address, then add the fields below. Keep the built-in block fields and other default settings:
2. Run the Pipeline
In Notebooks, create backfill_pool_reserves and enter the code below. Set SPACE to your Space ID:
The code follows this flow:
Trigger filters the pool’s Sync events.
SOURCE_ROW passes each matching event to the function.
read_reserves calls getReserves() at the event’s block_id to read USDC and WETH reserves.
- The Pipeline writes the returned record to the reserve table specified by
target_table.
The function is defined directly in the Notebook. You can also set func to an existing Function ID.
getReserves() reads reserves after the block has finished executing. Multiple Sync events in one block therefore return the same end-of-block state.
Run the backfill
Save and click Run, then check Output for progress and results.
backfill() processes the specified 10 blocks, including both boundary heights, and exits when finished.
3. Inspect current and historical state
Return to pool_reserves.eth and check processed blocks in Overview. This backfill covers a limited range; earlier history is still incomplete.
Open latest under Subtables to view current reserves. Records use the pool address as their ID, so the two state updates leave one current record.
Open archive to inspect historical state by block. original_id is the pool address; id identifies the historical record.
The result contains one state record at each of blocks 25939928 and 25939930. Reserve fields retain raw integers:
- Divide the USDC value by
10^6 to get USDC units.
- Divide the WETH value by
10^18 to get WETH units.
Optional: keep the table updated
Create a Notebook named update_pool_reserves, copy the code above, and replace the final pipeline.backfill(...) line with the call below. Save and run it:
By default, update() fills history from the earliest unfinished block, then continues processing new blocks after catching up.
For large historical ranges, you can run backfill() in another Notebook at the same time to speed up the backfill.
Choose Switch to Background to keep the instance running in the background. Cancel it under the account’s Instances page to stop it. Data already written remains in the table.