WorldIDRouter smart contract
to verify the ZK proofs of personhood.
Prerequisites
Before we start, make sure you have the following tools installed:- Git (usually pre-installed on most systems)
- Node.js
- pnpm (or equivalent like npm, yarn or bun)
- Foundry CLI
Clone template
First, clone the World ID template app repository from GitHub:Install dependencies
Next, install the dependencies for the World ID template app:Build the smart contracts
Next we are going to compile the smart contracts for the World ID template app:Understanding World ID
Before we deploy the World ID template app, let’s take a look at the smart contracts that are part of the app:- The Contractcontract is the main contract that will be deployed to World Chain Sepolia. It has a constructor that takes theIWorldIDinterface, the app ID and the action ID as parameters. TheIWorldIDinterface is the World ID router that will verify the proofs, the app ID is the ID of the app can be created by the developer using the World ID Developer Portal and that the action ID is the ID of the action that the user is performing which will be generated automatically by the IDKit SDK and derived fromactionstring defined in the Developer Portal.
- The nullifierHashesmapping is used to keep track of the nullifier hashes that have been used already. This is used to guarantee that an action is only performed once by a single person in order to achieve sybil resistance.
- The verifyAndExecutefunction is the main function that will be called by the user to verify their proof of personhood. It takes the user’s wallet address, the root of the Merkle tree, the nullifier hash, and the proof as parameters.
- The function first checks if the nullifier hash has been used already and reverts if it has.
- It then verifies the proof using the worldId.verifyProoffunction which is part of theIWorldIDinterface.
- If the proof is valid, the function records the nullifier hash and executes the logic of the app. In this case, it emits
the Verifiedevent.
RecurringGrantDrop.sol
contract which uses the World ID protocol to verify that the user is a unique human before they can claim a grant.
Deploy template app
First, you have to go to a node provider that supports World Chain Sepolia. You can use Alchemy or any of the other providers listed in the World Chain documentation. Once you have a node provider account, you need to get an RPC URL for the World Chain Sepolia network. For a simple deployment, the public RPC URL is sufficient. However, for doing a fork deployment, you will need to run a local fork of World Chain Sepolia using anvil which requires higher requirements on the RPC provider for forking the network. First, we will fork the World Chain Sepolia network using anvil:- WORLD_ID_ROUTER: The address of the World ID router contract that will verify the proofs (can be found in the World ID documentation)
- NEXT_PUBLIC_APP_ID: The app ID that was generated in the Developer Portal
- NEXT_PUBLIC_ACTION: The action ID as configured in the Developer Portal
Contract contract to the World Chain Sepolia network using the provided RPC URL and private key.
Local Web Setup
Set up your environment variables in the.env file. You will need to set the following variables:
- NEXT_PUBLIC_APP_ID: The app ID as configured in the Worldcoin Developer Portal.
- NEXT_PUBLIC_ACTION: The action ID as configured in the Worldcoin Developer Portal.
- NEXT_PUBLIC_WALLETCONNECT_ID: Your WalletConnect ID.
- NEXT_PUBLIC_CONTRACT_ADDRESS: The address of the contract deployed in the previous step.
src/abi/ContractAbi.json on each run of pnpm dev.
Iterating
After making changes to the contract, you should:- re-run the forge createcommand from above
- replace the NEXT_PUBLIC_CONTRACT_ADDRESSenvironment variable with the new contract address
- if your contract ABI has changed, restart the local web server
Testing
You’ll need to import the private keys on the local testnet into your wallet used for local development. The default development seed phrase istest test test test test test test test test test test junk.
This is only for local development. Do not use this seed phrase on mainnet or
any public testnet.