visit
Subscribe here for all the cool zk-tech and web3 stuff!
AgeCheck.sol
takes proof inputs from the frontend app and maintains the mapping of addresses if they are verified or not.Verifier.sol
has one purpose i.e. to verify the proof.
git clone //github.com/heypran/zk-block.git
Note: Following along with code requires familiarity with react, ethers, and solidity.
cd zk-block
cd backend
yarn install
yarn compile:circuits
This will use the circuit present in the backend/circuits
folder and compile it using the script in scripts/compile-circuits.ts
If you know about zero-knowledge proofs, you will know that Groth16 protocol requires performing a trusted setup. This is done in two phases. Phase 1 is independent of the circuit and phase 2 is circuit dependent. You can read about them .
Caution: Please note that you need to perform MPC to generate trusted setup, do not use the setup in compile-circuits.ts
as-is for production.
When you compile the circuit, it will create the necessary files in the build/snarks
folder which can be used in the repo to generate proofs. The above compilation also generates the Verifier.sol
in the contracts
folder. The Verifier.sol
is used to verify the proof on-chain.
Execute the following command inside the background
folder to compile the contracts
yarn compile
This will compile the contracts in backend/contracts
folder, which contains AgeCheck.sol
and Verifier.sol
( which is generated in the above step). The compilation is done using hardhat configuration and the selected network in the hardhat.config.ts
, the compiled code is generated in the backend/build
folder.
(Optional) Deploy contracts to the network of your own choice
Note: This step is not required, if you don’t want to deploy, you can simply use the existing testnet contract address, which is already configured inside ui/src/config/constants.ts
and also mentioned in the github .
In order to deploy the compiled contract, you will have to create a backend/private.json
with your private key inside it ( refer private.example.json
) and change the selected network in hardhat.config.ts
to a network of your choice ( refer chain.ts
to view the networks).
yarn deploy:agecheck --network testnet
The deployed contract address will be displayed on the terminal, configure it inside ui/src/config/constants.ts
cd ..
cd frontend
yarn install
yarn dev
The above will run the zk-block frontend locally, visit //localhost:3000/dapp
to see the age verification in action. You may connect to network, Polygon, or Harmony ( or where you deployed the smart contract), using Metamask.
Behind the scenes, when the user inputs the age, it will generate the witness using public and private inputs ( refer to the below snippet from ui/src/utils/zk/zk-witness.ts
).
// read the wasm generated by compiling the circuit in STEP 1
const buffer = await getBinaryPromise(circuitWasm);
// generate witness using calculator file generated from circom
// and then passing the public and private input
const witnessCalculator = await generateWitnessJs(buffer);
const buff = await witnessCalculator.calculateWTNSBin(params, 0);
const provingKey = await fetch(zkey);
const provingKeyBuffer = await provingKey.arrayBuffer();
// Generate groth proof
const { proof, publicSignals } = await snarkjs.groth16.prove(
new Uint8Array(provingKeyBuffer),
buff,
null,
);
// required to generate solidity call params
const editedPublicSignals = unstringifyBigInts(publicSignals);
const editedProof = unstringifyBigInts(proof);
// Generate solidity compatible params for Verifier.sol
const callData = await snarkjs.groth16.exportSolidityCallData(
editedProof,
editedPublicSignals,
);
The calldata
are proof parameters generated to be able to verify the proof ( i.e. the age is indeed above a limit, in this case 18) defined using our Verifier.sol
deployed on-chain.
for all the cool zk-tech and web3 stuff!