A minimal implementation of generating zero-knowledge proofs of EVM block execution using Reth. Supports both Ethereum and OP Stack.
Caution
This repository is still an active work-in-progress and is not audited or meant for production usage.
Required
- Rust
- zkMIPS toolchain
- Register on Alchemy or Chainstack to get
rpc url
andws url
. But Chainstack does not support archival/historicaleth_getProof
calls.
Reth processor fetches block and state data from a JSON-RPC node. You must use an archive node which preserves historical intermediate trie nodes needed for fetching storage proofs.
In Geth, the archive mode can be enabled with the --gcmode=archive
option. You can also use an RPC provider that offers archive data access.
Important
Some RPC providers have issues with eth_getProof
on older blocks. For instance QuickNode returns invalid data that lead to state mismatch errors.
For the supported chains (Ethereum Mainnet and Sepolia, OP Stack Mainnet, and Linea Mainnet), the host CLI automatically identifies the underlying chain type using the RPC (with the eth_chainId
call). Simply supply a block number and an RPC URL:
cargo run -r --bin host -- --block-number <block-number> --rpc-url <RPC> --chain-id <chain-id>
# eg.
cargo run -r --bin host -- --block-number 18884864 --rpc-url <RPC> --chain-id 1
The host CLI executes the block while fetching additional data necessary for offline execution. The same execution and verification logic is then run inside the zkVM. No actual proof is generated from this command, but it will print out a detailed execution report and statistics on the # of cycles to a CSV file (can be specified by the --report-path
argument).
Additional information about precompiles can be added to the CSV file when specifying the --precompile-tracking
argument, and about opcodes with the --opcode-tracking
argument.
The client input (witness) generated by executing against RPC can be cached to speed up iteration of the client program by supplying the --cache-dir
option:
cargo run -r --bin host -- --block-number <block-number> --chain-id <chain-id> --cache-dir /path/to/cache
# eg.
cargo run -r --bin host -- --block-number 18884864 --chain-id 1 --cache-dir ./bin/host
Note that even when utilizing a cached input, the host still needs access to the chain ID to identify the network type, either through --rpc-url
or --chain-id
. To run the host completely offline, use --chain-id
for this.
If you want to actually generate proofs, you can run the CLI using the --prove
argument, like this:
cargo run -r --bin host -- --block-number <block-number> --rpc-url <RPC> --chain-id <chain-id> --prove
# eg.
cargo run -r --bin host -- --block-number 18884864 --rpc-url <RPC> --chain-id 1 --prove
This will generate proofs locally on your machine. Given how large these programs are, it might take a while for the proof to generate.
If you want to run proofs using prover network, follow the sign-up instructions, and run the command with the following environment variables prefixed:
export ZKM_PROVER="network"
export ZKM_PRIVATE_KEY=<your_private_key> # Private key corresponding to your registered public key
export SSL_CERT_PATH=<path_to_ssl_certificate> # Path to the ssl client certificate
export SSL_KEY_PATH=<path_to_ssl_key> # Path to the ssl client key
To run benchmarking with ETH proofs, you'll need to:
-
Set the following environment variables:
export ETH_PROOFS_ENDPOINT="https://staging--ethproofs.netlify.app/api/v0" export ETH_PROOFS_API_TOKEN=<your_api_token> export HTTP_RPC_URL=<your_eth_mainnet_http_rpc> export WS_RPC_URL=<your_eth_mainnet_ws_rpc>
-
Run the benchmarking recipe:
cargo run -r --bin eth-proofs -- --eth-proofs-cluster-id 1 --block-interval 100
This will continuously:
- Fetch the latest block number
- Round it down to the nearest 100
- Generate a proof and submit its proving time
- Sleep for the specified duration before the next iteration
A good small block to test on for Ethereum mainnet is: 20526624
.
This issue can be caused using an RPC provider that returns incorrect results from the eth_getProof
endpoint. We have empirically observed such issues with many RPC providers. We recommend using Alchemy.