๐ฆ zkpoh-widget |
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.
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
Clone the repository:
git clone https://github.com/elmol/zk-proof-of-humanity.git
Install the dependencies:
yarn
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.
Select contract directory apps/contracts
cd apps/contracts
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
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
The following hardhat tasks were developed to help testing the protocol in goerli network.
It uses hardhat configured accounts
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.
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 Proof of Humanity Contract: 0x29988D3e5E716fdFf6a7Bfb34fe05B5A4F3C9b52
Goerli Proof of Humanity test webapp: https://proof-of-humanity-web-elmol.vercel.app/
$ 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.
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.
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
ยท-------------------------------------------------|---------------------------|-----------------|-----------------------------ยท
| 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 โ
ยท-------------------------------------------------|-------------|-------------|-----------------|---------------|-------------ยท
ZK Proof of Humanity Documentation
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 signalI'm human
Goerli versel deployment: https://zk-proof-of-humanity.vercel.app/
demo-github-v1.mp4
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.
yarn start
yarn dev
Open http://localhost:3000 with your browser.
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
- In
wagmi.config.ts
update the contract addresses for each supported network. - Run
yarn wagmi generate
to update the configuration.
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