Skip to content

ZK Proof of Humanity (zkPoH) allows humans, registered in Proof of Humanity, to prove their humanity without doxing.

License

Notifications You must be signed in to change notification settings

elmol/zk-proof-of-humanity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐ŸŽญ ZK Proof of Humanity

Github license GitHub Workflow test Coveralls Linter eslint Code style prettier Repository top language

๐Ÿ“ฆ zkpoh-widget npm version

Project Overview

ZK Proof of Humanity allows humans, registered in Proof of Humanity, to prove their humanity without doxing.

The issue being addressed is that when a humans conducts transactions on or off-chain using an account registered in Proof of Humanity, their personal information (biometric data, voice, and video) is exposed (doxed).

ZK Proof of Humanity (zkPoH) uses Semaphore integrated with Proof of Humanity (PoH) to solve this issue.

It consists of a smart contract that allows subscribing as a member to a Semaphore group only if the subscriber is registered in PoH. In this way, any member of this group can emit signals (votes, approvals, etc.) without revealing their identity and ensuring that they are registered in PoH as a human.

process

When a human subscribes to zkPoH, they must send the identity commitment with the account that is registered in Proof of Humanity. The protocol only allows subscribing to valid accounts in PoH that are not already registered in zkPoH. Once the human is registered in zkPoH, they can generate proofs and emit signals, like the Semaphore protocol, without exposing their identity. To generate the identity, the deterministic method is used which signs a message with the account registered in Proof of Humanity

๐Ÿš€ Repository

Clone the repository:

git clone https://github.com/elmol/zk-proof-of-humanity.git

๐Ÿ›  Installation

Install the dependencies:

yarn

๐Ÿ“œ General Scripts

  • yarn dev starts the dapp locally: run local network, deploy contracts and start the webapp.
  • yarn dev:web-app starts the web application for your Dapp locally.
  • yarn dev:contracts runs the project on a local network, This script starts the local node and then compiles the contract and deploys it on the local network.
  • yarn prettier runs prettier.
  • yarn prettier:write fixes any formatting issues in the code.

๐Ÿ“‘ Table of Contents

๐Ÿ’ผ Smart Contracts

Select contract directory apps/contracts

cd apps/contracts

๐Ÿ›  Configuration

Copy the .env.example file as .env and add your environment variables:

cp .env.example .env

Note
You should at least set a valid Ethereum URL (e.g. Infura) and a private key with some ethers.

Deploy the contract:

yarn deploy --semaphore <semaphore-address> --group <group-id> --network goerli

Verify the contract

yarn verify <zk-proof-of-humanity-address> <semaphore-address> <proof-of-humanity-address> <group-id> --network goerli

Note
You should download the snark artifacts before run tests

yarn download:snark-artifacts

๐Ÿ“œ Scripts

This project uses several scripts to help with the development and deployment of the contract.

  • dev: This script runs the project on a local network, This script starts the local node and then compiles the contract and deploys it on the local network.

  • compile: This script compiles the contract using the command hardhat compile

  • download:snark-artifacts: This script downloads SNARK artifacts

  • deploy: This script deploys the contract to the network

  • verify: verify the contract

  • test: This script runs the tests

  • test:report-gas: Runs automated tests for a smart contract project with gas usage reporting enabled.

  • test:coverage: Generates a code coverage report for a smart contract project.

  • docgen: Generates documentation for the contract

  • prettier: Runs prettier

๐Ÿ‘จโ€๐Ÿ’ป Tasks

The following hardhat tasks were developed to help testing the protocol in goerli network.

It uses hardhat configured accounts

Registration Task

Register a human account in ZKProofOfHumanity

$ yarn hardhat register --help
Usage: hardhat [GLOBAL OPTIONS] register [--human <STRING>] [--logs <BOOLEAN>] [--zkpoh <STRING>]

OPTIONS:

  --human       Human account (default accounts[1])
  --logs        Print the logs (default: true)
  --zkpoh       ZKProofOfHumanity contract address (default env ZK_POH_ADDRESS)

register: Register a human account in ZKProofOfHumanity

Localhost example

$ yarn hardhat node

Localhost deployment and human account registration in a PoH mock

$ yarn hardhat deploy-mock --network localhost
yarn run v1.22.19
ZKProofOfHumanity contract has been deployed to: 0x0165878A594ca255338adfa4d48449f69242Eb8F
Human Account PoH Registered: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8
Done in 4.42s.

ZKPoH account registration

$ yarn hardhat register --zkpoh 0x0165878A594ca255338adfa4d48449f69242Eb8F --network localhost
๐Ÿ‘ค Human registration successfully DONE! โœ…
> zkPoHAdress: [ 0x0165878A594ca255338adfa4d48449f69242Eb8F ]
> Account: [ 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 ]
> ๐Ÿ”’ Identity: [ ["3ff729abbf2207ea0af1f0aa2fa2cfff28f00341e3fb6230f5d6085459cc17","968b860bb3e241572f8565155613100965e21bd353410ecffb18cd96a4951"] ]
Done in 3.42s.

Verification Task

Verify proof of humanity and save nullifier to avoid double-signaling

Usage: hardhat [GLOBAL OPTIONS] verify-proof [--anon <STRING>] [--externalnullifier <STRING>] [--human <STRING>] [--logs <BOOLEAN>] [--signal <STRING>] [--zkpoh <STRING>]

OPTIONS:

  --anon                Anonymous account to verify the proof on-chain (default accounts[2])
  --externalnullifier   ExternalNullifier - (default groupId)
  --human               Human account to get the identity (default accounts[1])
  --logs                Print the logs (default: true)
  --signal              Signal to broadcast (default: "Hello World")
  --zkpoh               ZKProofOfHumanity contract address (default env ZK_POH_ADDRESS)

verify-proof: Verify proof of humanity and save nullifier to avoid double-signaling

Localhost example

$ yarn run hardhat verify-proof --zkpoh "0x0165878A594ca255338adfa4d48449f69242Eb8F" --signal "Hi ZKPoH" --network localhost

๐Ÿ‘ค Human verification DONE! โœ…
> zkPoHAdress: [ 0x0165878A594ca255338adfa4d48449f69242Eb8F ]
> ๐Ÿ”’ Identity: [ ["3ff729abbf2207ea0af1f0aa2fa2cfff28f00341e3fb6230f5d6085459cc17","968b860bb3e241572f8565155613100965e21bd353410ecffb18cd96a4951"] ]
> ExternalNullifier: [ 42 ]
> Signal: [ Hi ZKPoH ]
Done in 14.48s

๐Ÿ“ฆ Goerli Deployment

Proof of Humanity

Goerli Proof of Humanity Contract: 0x29988D3e5E716fdFf6a7Bfb34fe05B5A4F3C9b52 Goerli Proof of Humanity test webapp: https://proof-of-humanity-web-elmol.vercel.app/

Deployment

$ yarn deploy --poh 0x29988D3e5E716fdFf6a7Bfb34fe05B5A4F3C9b52 --semaphore 0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131 --network goerli
ZKProofOfHumanity contract has been deployed to: 0x3575E04983C401f26fA02FC09f6EE97e44dF296B
ZKProofOfHumanity groupId: 64529223205059941630256627722838976601664149149671692208634810640620297856220
ZKProofOfHumanity depth: 20
ZKProofOfHumanity deployed with account: 0xaDa5168fA388d4bB6F6A1bd762a9B9a3d3033e0C
Done in 17.88s.

Verification

yarn hardhat verify --network goerli <zkpoh-address> <semaphore-address> <poh-address> <groupId>
$ yarn hardhat verify --network goerli 0x3575E04983C401f26fA02FC09f6EE97e44dF296B 0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131 0x29988D3e5E716fdFf6a7Bfb34fe05B5A4F3C9b52 64529223205059941630256627722838976601664149149671692208634810640620297856220 20
Successfully submitted source code for contract
contracts/ZKProofOfHumanity.sol:ZKProofOfHumanity at 0x3575E04983C401f26fA02FC09f6EE97e44dF296B
for verification on the block explorer. Waiting for verification result...

Successfully verified contract ZKProofOfHumanity on Etherscan.
https://goerli.etherscan.io/address/0x3575E04983C401f26fA02FC09f6EE97e44dF296B#code
Done in 139.57s.

Tasks usage example in Goerli

Registration

Registration of the human https://proof-of-humanity-web-elmol.vercel.app/profile/0x45756fed107d0aea575a2dc0d49a1c5156b0b796

$ yarn run hardhat register --zkpoh "0x3575E04983C401f26fA02FC09f6EE97e44dF296B" --human "0x45756fED107d0aEA575a2dc0d49a1c5156b0b796" --network goerli

๐Ÿ‘ค Human registration successfully DONE! โœ… 
> zkPoHAdress: [ 0x3575E04983C401f26fA02FC09f6EE97e44dF296B ]
> Account: [ 0x45756fED107d0aEA575a2dc0d49a1c5156b0b796 ]
> ๐Ÿ”’ Identity: [ <<secret>> ]
Done in 16.09s.

https://goerli.etherscan.io/tx/0xd0ae3d930b2cdcd59218607a8e2c7ec4b2c9a68deb94e089bc0fa599185a41c2

Verification and signal broadcasting

$ yarn run hardhat verify-proof --zkpoh "0x3575E04983C401f26fA02FC09f6EE97e44dF296B" --signal "Hi ZKPoH" --externalnullifier "1" --human "0x45756fED107d0aEA575a2dc0d49a1c5156b0b796" ----anon "0xaDa5168fA388d4bB6F6A1bd762a9B9a3d3033e0C" --network goerli

๐Ÿ‘ค Human verification DONE! โœ… 
> zkPoHAdress: [ 0x3575E04983C401f26fA02FC09f6EE97e44dF296B ]
> ๐Ÿ”’ Identity: [ <<secret>> ]
> ExternalNullifier: [ 1 ]
> Signal: [ Hi ZKPoH ]
Done in 53.85s.

https://goerli.etherscan.io/tx/0x7939fc4ac22578eae1946ba09f7ae42b3dff89f7b074bb516ebd063a6dd46ed4

๐Ÿ’ฐ Cost Analysis

ยท-------------------------------------------------|---------------------------|-----------------|-----------------------------ยท
|               Solc version: 0.8.4               ยท  Optimizer enabled: true  ยท  Runs: 1000000  ยท  Block limit: 30000000 gas  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Contract             ยท  Method                 ยท  Min        ยท  Max        ยท  Avg            ยท  # calls      ยท  usd (avg)  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  Methods                                        ยท                 33 gwei/gas                 ยท       1651.85 usd/eth       โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ZKProofOfHumanity    ยท  register               ยท     974390  ยท    1751356  ยท        1523169  ยท           17  ยท      83.03  โ”‚
ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท|ยทยทยทยทยทยทยทยทยทยทยทยทยทยท
|  ZKProofOfHumanity    ยท  verifyProof            ยท     350468  ยท     350504  ยท         350487  ยท           10  ยท      19.11  โ”‚
ยท-------------------------------------------------|-------------|-------------|-----------------|---------------|-------------ยท

๐Ÿ“– Contract Documentation

ZK Proof of Humanity Documentation

๐Ÿ–ฅ๏ธ Web Application

This is the web app that serves as the frontend user interface for ZK Proof of Humanity.

The main objective of this dapp is to provide a user-friendly experience for both registered and non-registered ZK Proof of Humanity users to easily and securely verify their humanity, while maintaining anonymity.

It's a Next.js based project and features a customizable <Button\> react component that guides users through the entire process, from registration to human verification. This process can be visualized in the accompanying flow graph.

Note: The human verification is conducted using a random externalNullifier and the signal I'm human

button-flow

Goerli versel deployment: https://zk-proof-of-humanity.vercel.app/

Demo

demo-github-v1.mp4

๐Ÿ›  Contract address configuration

Select contract directory apps/web-app

cd apps/web-app
  • In wagmi.config.ts update the contract addresses for each supported network.
  • Run yarn generate to update the configuration.

๐Ÿ“œ Usage

Start the app

yarn start

Dev mode

yarn dev

Open http://localhost:3000 with your browser.

๐Ÿงฐ ZK Proof of Humanity Widget

React library that enables easy integration with ZK Proof of Humanity for your projects.

More information in Widget readme

You can find the npm package in ๐Ÿ“ฆ zkpoh-widget

Contract address configuration

  • In wagmi.config.ts update the contract addresses for each supported network.
  • Run yarn wagmi generate to update the configuration.

Building a Private Voting App with zkPoH: A Step-by-Step Guide

In this step-by-step guide, we'll show you how to get started with zkPoH and use the zkpoh-widget React library to build anonymous voting systems that require proof of humanity.

Link to the step by step guide

You can find the complete application in https://github.com/elmol/zk-proof-of-humanity-vote github repository

About

ZK Proof of Humanity (zkPoH) allows humans, registered in Proof of Humanity, to prove their humanity without doxing.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published