This repository provides a simple example of a decentralized application (DApp) that leverages zkVerify for off-chain proof verification, via zkVerifyJS. The DApp demonstrates how to integrate a zk-SNARK circuit, deploy Solidity smart contracts that interact with zkVerify's attestation contract, and build a user interface to interact with the system.
The repository is organized into three main directories:
app: Contains the frontend of the DApp, built with Node.js. This is the user-facing part of the application.circuit: Contains the zk-SNARK circuit written in Circom. This is where the logic for the zero-knowledge proof is defined.contracts: Contains the Solidity smart contracts, managed with Foundry. These contracts are deployed to an Ethereum-compatible blockchain and interact with the zkVerify attestation contract.
Before you begin, ensure you have the following installed:
-
Clone the repository:
git clone https://github.com/zkVerify/zkverify-evm-dapp-example.git cd zkverify-evm-dapp-example -
Install Node.js dependencies:
cd app npm install cd ..
-
Set up environment variables:
In the
appandcontractsdirectories, you will find.env.templateand.env.secrets.templatefiles. Copy these to.envand.env.secretsrespectively:cp app/.env.template app/.env cp contracts/.env.template contracts/.env
Fill in the required values, such as your private key and RPC URL.
The circuit directory contains the Circom code for the zk-SNARK. The Makefile in this directory automates the process of compiling the circuit and generating the necessary keys.
-
Compile the circuit and generate keys:
cd circuit makeThis command will:
- Compile the
circuit.circomfile. - Perform a local trusted setup (for demonstration purposes, do not use in production).
- Generate the proving key (
circuit_final.zkey), verification key (verification_key.json), and a WebAssembly version of the circuit (circuit.wasm). - Place the generated files in the
setupdirectory.
- Compile the
The contracts directory contains the Solidity smart contracts, managed with Foundry.
-
Build the contracts:
cd contracts forge build -
Deploy the contracts:
The deployment scripts are located in the
scriptdirectory. To deploy the contracts, first copy the .env.template file to .env:cd contracts forge script script/ZkFactorization.s.sol:ZkFactorizationContractScript --rpc-url <your_rpc_url> --private-key <your_private_key>
The app directory contains the Node.js application that serves as the frontend for the DApp. zkVerifyJS is used to interact with the zkVerify Blockchain.
-
Run the DApp:
cd app node index.js
-
Generate a Proof: The user interacts with the DApp's frontend. The DApp uses the compiled circuit (
circuit.wasm) and the proving key (circuit_final.zkey) to generate a proof based on the user's input. -
Submit Proof to zkVerify: The DApp sends the generated proof and public inputs to the zkVerify service for verification.
-
Receive Proof ID: zkVerify verifies the proof and, if valid, returns a unique
proofId. -
Interact with the Smart Contract: The DApp calls a function on the deployed smart contract, passing the
proofIdas an argument. -
On-Chain Attestation: The smart contract communicates with the zkVerify attestation contract, providing the
proofId. The attestation contract checks if a proof with that ID has been successfully verified by zkVerify. -
Execute Logic: If the proof is valid, the smart contract proceeds with its logic (e.g., minting an NFT, transferring tokens, etc.).
Check out zkVerify documentation for additional info and tutorials: