The Deriver: Rebuilding L2 State from L1 Alone
STEP 1 OF 3
NEXT WALKTHROUGH: How the address is derived →
L1 EVENT LOG · WATCHED, NOT TRUSTED
event BatchPosted(bytes32 sharedPublicInput, uint64[] rollupIds);
address
0xA9c1…04Fe (EEZ)
topics[0]
keccak256("BatchPosted(bytes32,uint64[])")
data
sharedPublicInput = 0x3e7a…91c4 · rollupIds =
[7]
— kept only if it contains our rollup id
tx blobs
EIP-4844 blobs carry the batch payload (batch.callData is empty) — this is what the deriver decodes
DERIVER SCANNING L1 — NO NODE OPERATOR CONSULTED
PROTOCOL RESEARCHERS
How the deriver rebuilds L2 from L1
The deriver watches L1 for BatchPosted events instead of trusting any node’s live output — the log is the trigger, the posting transaction’s blobs are the data.
Replaying those batches forward, after re-checking that the ones it already indexed are still canonical, reconstructs the chain from L1 alone.
WHAT YOU'LL LEARN
- 01 · WATCH L1The deriver watches L1 for BatchPosted events naming its rollup, instead of trusting any node’s live output. The log carries no payload.
- 02 · DECODE THE BLOBSThe posting transaction’s blobs are fetched and checked against their KZG hashes; on_batch_posted decodes that payload and replays the blocks through execute_block.
- 03 · REVALIDATE, THEN SCAN FORWARDcatch_up() drops indexed batches whose L1 block is no longer canonical, then scans forward from that anchor — or from deploy_block on a cold start with no persisted seed.
Verified against eez-rollupX Git commit 2c19e36; interfaces may move.