{"id":27021221,"url":"https://github.com/jonas089/zk-state-proofs","last_synced_at":"2026-04-28T20:02:23.244Z","repository":{"id":263817681,"uuid":"891478046","full_name":"jonas089/zk-state-proofs","owner":"jonas089","description":"Prove Blockchain State in Zero Knowledge","archived":false,"fork":false,"pushed_at":"2024-12-17T11:43:07.000Z","size":877,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-04T19:46:17.125Z","etag":null,"topics":["consensus","ethereum","light-client","risc0","sp1","zkvm"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonas089.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-20T12:07:10.000Z","updated_at":"2025-01-13T06:58:16.000Z","dependencies_parsed_at":"2024-12-14T02:01:48.524Z","dependency_job_id":null,"html_url":"https://github.com/jonas089/zk-state-proofs","commit_stats":null,"previous_names":["jonas089/sp1-eth-tx"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/jonas089/zk-state-proofs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fzk-state-proofs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fzk-state-proofs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fzk-state-proofs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fzk-state-proofs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonas089","download_url":"https://codeload.github.com/jonas089/zk-state-proofs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonas089%2Fzk-state-proofs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32396781,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["consensus","ethereum","light-client","risc0","sp1","zkvm"],"created_at":"2025-04-04T19:43:08.713Z","updated_at":"2026-04-28T20:02:23.221Z","avatar_url":"https://github.com/jonas089.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔐 Complete Library to prove EVM state in ZK, to cryptographically verify storage, transactions, receipts and accounts!\nThis library exposes functions and ZK circuits (SP1, Risc0) to obtain, verify and prove query infromation from `Ethereum` clients.\n\n# Overview of provided functions\n\n| account | storage | receipt | transaction |\n| --- | --- | --- | --- |\n| Verify that an account exists in the Ethereum Trie | Verify a value stored under an account or smart contract | Verify a receipt or the entire receipt trie of a block | Verify native Ethereum transactions |\n\n- `accounts`: any Ethereum address with a Balance \u003e 0\n- `receipts`: data related to events (for example ERC20 transfer information)\n\n# Obtain a Merkle Proof for a value in Ethereum State\nFor each of these values in storage a function is provided that helps obtain a `merkle proof` from the Ethereum client using `alloy rpc`:\n\n`trie-utils/src/proofs/*`\n- account.rs\n- receipt.rs\n- storage.rs\n- transaction.rs\n\nFor example `transaction.rs` returns a `merkle proof` for an individual native Ethereum transaction:\n\n```rust\npub async fn get_ethereum_transaction_proof_inputs(\n    target_index: u32,\n    block_hash: \u0026str,\n) -\u003e MerkleProofInput {\n    let key = load_infura_key_from_env();\n    println!(\"Key: {}\", key);\n    let rpc_url = \"https://mainnet.infura.io/v3/\".to_string() + \u0026key;\n    let provider = ProviderBuilder::new().on_http(Url::from_str(\u0026rpc_url).unwrap());\n    let block = provider\n        .get_block_by_hash(\n            B256::from_str(block_hash).unwrap(),\n            alloy::rpc::types::BlockTransactionsKind::Full,\n        )\n        .await\n        .expect(\"Failed to get Block!\")\n        .expect(\"Block not found!\");\n    let memdb = Arc::new(MemoryDB::new(true));\n    let mut trie = EthTrie::new(memdb.clone());\n\n    for (index, tx) in block.transactions.txns().enumerate() {\n        let path = alloy_rlp::encode(index);\n        let mut encoded_tx = vec![];\n        match \u0026tx.inner {\n            TxEnvelope::Legacy(tx) =\u003e tx.eip2718_encode(\u0026mut encoded_tx),\n            TxEnvelope::Eip2930(tx) =\u003e {\n                tx.eip2718_encode(\u0026mut encoded_tx);\n            }\n            TxEnvelope::Eip1559(tx) =\u003e {\n                tx.eip2718_encode(\u0026mut encoded_tx);\n            }\n            TxEnvelope::Eip4844(tx) =\u003e {\n                tx.eip2718_encode(\u0026mut encoded_tx);\n            }\n            TxEnvelope::Eip7702(tx) =\u003e {\n                tx.eip2718_encode(\u0026mut encoded_tx);\n            }\n            _ =\u003e panic!(\"Unsupported transaction type\"),\n        }\n        trie.insert(\u0026path, \u0026encoded_tx).expect(\"Failed to insert\");\n    }\n\n    trie.root_hash().unwrap();\n    let tx_key: Vec\u003cu8\u003e = alloy_rlp::encode(target_index);\n    let proof: Vec\u003cVec\u003cu8\u003e\u003e = trie.get_proof(\u0026tx_key).unwrap();\n    MerkleProofInput {\n        proof,\n        root_hash: block.header.transactions_root.to_vec(),\n        key: tx_key,\n    }\n}\n```\n\n# Verify a Merkle Proof against a trusted State Root\nThe `merkle proof` is then be verified using the `verify_merkle_proof` function found in `crypto-ops/lib.rs`:\n\n```rust\npub fn verify_merkle_proof(root_hash: B256, proof: Vec\u003cVec\u003cu8\u003e\u003e, key: \u0026[u8]) -\u003e Vec\u003cu8\u003e {\n    let proof_db = Arc::new(MemoryDB::new(true));\n    for node_encoded in proof.clone().into_iter() {\n        let hash: B256 = digest_keccak(\u0026node_encoded).into();\n        proof_db.insert(hash.as_slice(), node_encoded).unwrap();\n    }\n    let mut trie = EthTrie::from(proof_db, root_hash).expect(\"Invalid merkle proof\");\n    assert_eq!(root_hash, trie.root_hash().unwrap());\n    trie.verify_proof(root_hash, key, proof)\n        .expect(\"Failed to verify Merkle Proof\")\n        .expect(\"Key does not exist!\")\n}\n```\n\nThis function checks that the trie root matches the `trusted root` obtained from the [Light Client](https://github.com/jonas089/spectre-rad).\nAnd that the data we claim exists in the Trie is actually present at the specified path (=`key`). \n\n# Generate a ZK proof for the validity of a Merkle Proof\nIn order to prove our Merkle verification in ZK, we can use the circuit located in `circuits/merkle-proof/src/main.rs`:\n\n```rust\n#![no_main]\nsp1_zkvm::entrypoint!(main);\nuse crypto_ops::{types::MerkleProofInput, verify_merkle_proof};\npub fn main() {\n    let merkle_proof: MerkleProofInput =\n        serde_json::from_slice(\u0026sp1_zkvm::io::read::\u003cVec\u003cu8\u003e\u003e()).unwrap();\n\n    let output = verify_merkle_proof(\n        merkle_proof.root_hash.as_slice().try_into().unwrap(),\n        merkle_proof.proof.clone(),\n        \u0026merkle_proof.key,\n    );\n    sp1_zkvm::io::commit_slice(\u0026output);\n}\n```\n\nTo try this against a real Ethereum Transaction for testing purposes, run:\n\n`cargo test --bin prover test_generate_ethereum_transaction_zk_proof_sp1 -F sp1`\n\nconsider using `-F cuda` when cuda acceleration is available!\n\nor \n\n`cargo test --bin prover test_generate_optimism_transaction_zk_proof_risc0 -F metal`\n\n\u003e [!NOTE]\n\u003e The feature flag `sp1` tells the compiler to leverage the `keccak` precompile for hash acceleration in the ZK circuit.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonas089%2Fzk-state-proofs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonas089%2Fzk-state-proofs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonas089%2Fzk-state-proofs/lists"}