All posts

Willow's State, Verified on Ethereum

A mainnet contract verified Willow's consensus and checked a record from the network's state against it, so Ethereum contracts can now act on anything Willow indexes or stores, with no oracle in between.

Willow is the first on-chain verifiable blockchain indexer, and it runs as its own chain. It indexes blocks from other chains, like Ethereum and Base, and proves that the data it serves is correct, and most importantly, complete. No missing events. Every dataset it indexes, every record an app writes to it directly, and the registry of who indexes what all live in one state tree, and Willow's validators sign the root hash of that tree into every block. The entire state of the network is a single hash.

Last week we verified that hash on Ethereum. A contract we deployed to mainnet checked a proof that Willow's validators had signed a given block, and stored the state root from it. That stored root is the anchor. Then the contract checked a second proof, of a query against that state, and confirmed the result, one record we had stored on Willow. The anchor transaction, the state read, and the contract are all public. The two verifications cost about $0.16 and $0.21.

What one root covers: indexed history from other chains, records apps write to Willow directly, and the registry of who indexes what all sit in one state tree whose root Willow's validators sign into every block, and one anchor on Ethereum lets a contract verify any value under it

One root

Until now, every Willow proof verified on Ethereum was about one dataset, posted to a contract built for that one shape: an Ethereum window, Lido's validator set, a Merkl campaign, a Base window. Now any value in Willow's state verifies against the anchor the same way, whether it was indexed from another chain or written to Willow directly. Basically, a contract on Ethereum can act on anything Willow holds, with no oracle in the middle. The contract trusts Willow's validators, as a light client would, and nobody else.

That matters because a contract can't read the chain's past events. Anything that depends on the past (a rewards distribution, an airdrop, an accounting report) goes through an indexer, and the contract that pays has to take the indexer's word for it. If that read misses one event, someone gets paid less than they earned. Willow already proves complete views over that history. Now those views have a path back onto Ethereum that a contract can check, and so do records that were never on Ethereum at all, like holder lists, orders, or an AI agent's memory stored on Willow with proofs.

Now, onto how it works.

The anchor

Willow runs CometBFT (formerly Tendermint), so every block is finalized by its validators signing the header, and the header carries the state root. Proving "this is Willow's state" comes down to proving "Willow's validators signed a header with this root in it."

This half isn't new. Succinct ships a Tendermint light client as an example for SP1, its zkVM, and several Cosmos-to-Ethereum bridges run ZK light clients of their own. Ours wraps tendermint-rs's verifier, the same code IBC runs, in an SP1 program. It checks that more than two thirds of the voting power signed the header, that it follows from the last header we trusted, and that it's within the five-day trusting period. The contract verifies the proof and stores the root under the header's height. It was given one trusted header at deploy, and from then on it only accepts headers proven to follow from the one it holds. Anyone can post an anchor.

The state

Willow's state lives in GroveDB, the provable database our founder worked on at Dash Core Group. It's a Merkle database, so any query result comes with a proof against the root, and that root is exactly the hash the validators sign. We run GroveDB's real verifier inside SP1. The program recomputes the root from the query proof and commits the query and the exact result set. The contract checks that root against the one it stored and emits a hash of the query and a hash of the results. Whoever acts on the result fetches it from Willow and checks it against those hashes.

One rule decides which stored root: CometBFT puts the state after block H into the header at H+1, so a query at height H is checked against header H+1. That's the read we did. We stored a record under the key greeting (its message reads "Willow state, proven on Ethereum"), pulled its proof at Willow height 295,289, and proved it. The contract matched the proof's root to the root it had stored for header 295,290 and reported exactly one result.

The two halves. On the left, Willow's validators sign a header carrying the state root, and the anchor proof lets the Ethereum contract store that root. On the right, a query result and its GroveDB proof go through GroveDB's verifier inside SP1, which commits the root it recomputed. The contract requires the two roots to match

The two proofs never touch. The anchor proof never runs the database's hashing, and the state proof never checks a signature, so a bug in one can't move the other. The contract has no owner and no upgrade path, and anyone can post an anchor or check a state proof.

Cost

Deploying the contract cost 962,419 gas, about $0.13. The anchor proofs took about three and about eight minutes on a single rented GPU (almost entirely SP1's Groth16 wrap, since the light client itself is under 300,000 cycles), and the state proof a little over a minute. Verifying cost 312,356 gas for the anchor and 301,690 for the state read, about $0.16 and $0.21 (basically instant).

What's next

The next thing we're building is a contract that pays from a whole dataset in Willow rather than one stored record. It's the state proof over a range query instead of a key. And since every CometBFT chain puts its state root in the header, any of them could be read on Ethereum this way, with its own database verifier in place of GroveDB's.

If there's a payout, a report, or an app record you'd like a contract to read straight out of Willow's state, we're at [email protected].

Put proven data under your app.

Partners

Request a call