verifyProof
method of the World ID contract, and then execute the rest of its logic as usual.
The smart contract starter kit and the frontend & on-chain monorepo template are great resources to help you get started with World ID.
Using one of these repositories is strongly recommended to get started with World ID on-chain.
The following examples demonstrate the most common use case: verifying proofs from only Orb-verified users, for a single action, with a user’s wallet address as the signal, while also enabling sybil-resistance.
This setup is recommended for most users, as it is the most gas-efficient. For more information on use cases that require more complex setups (such as multiple actions or other types of signals), see the Advanced On-Chain Verification page.
hashToField
Helper Functionuint256
that is guaranteed to be in the field of the elliptic curve we use. This is necessary to ensure that the uint256
returned by the hash function can be used in our zero-knowledge proofs.
ByteHasher
library and call hashToField
on your bytestring.
externalNullifier
is the unique identifier of the action performed in Semaphore, and its keccak256 hash (named externalNullifierHash
) is what is passed to the World ID Router contract. It is a combination of the app ID and the action.
You should typically set it in the constructor to save gas (as is done in this example), as it will not change if all users are performing the same action.
We additionally set the groupId
to 1
, which limits this example to Orb-verified users only. World ID Device is currently not supported on-chain.
verifyProof
method reverts if the proof is invalid, meaning you can just call it as part of your smart contract’s logic and execute the rest of your logic after as usual.
verifyProof
function by itself does not provide
sybil-resistance, or prevent proof reuse — it just verifies that the proof is
valid. However, this example does implement sybil-resistance by checking
that the nullifierHash
has not been verified before.verifyProof
method takes the arguments below.
root
- The World ID root to verify against. This is obtained from the IDKit widget, and should be passed as-is.groupId
- This must be 1
for Orb-verified users. World ID Device is currently not supported on-chain.signalHash
- The keccak256 hash of the signal to verify.nullifierHash
- Anonymous user ID for this action. This is obtained from the IDKit widget, and should just be passed as-is.externalNullifierHash
- The externalNullifierHash, which identifies which app and action the user is verifying for.proof
- The proof to verify. This is obtained from the IDKit widget.uint256
, with the exception of proof
, which is of type uint256[8]
. Depending on how you’re calling your smart contract, you might be required to unpack it into a uint256[8]
before passing it to the verifyProof method. To unpack it, use the following code: