This repository has been archived by the owner on Mar 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathContract.sol
73 lines (60 loc) · 2.9 KB
/
Contract.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {ByteHasher} from "./helpers/ByteHasher.sol";
import {IWorldID} from "./interfaces/IWorldID.sol";
contract Contract {
using ByteHasher for bytes;
///////////////////////////////////////////////////////////////////////////////
/// ERRORS ///
//////////////////////////////////////////////////////////////////////////////
/// @notice Thrown when attempting to reuse a nullifier
error InvalidNullifier();
/// @dev The World ID instance that will be used for verifying proofs
IWorldID internal immutable worldId;
/// @dev The contract's external nullifier hash
uint256 internal immutable externalNullifier;
/// @dev The World ID group ID (always 1)
uint256 internal immutable groupId = 1;
/// @dev Whether a nullifier hash has been used already. Used to guarantee an action is only performed once by a single person
mapping(uint256 => bool) internal nullifierHashes;
/// @param _worldId The WorldID instance that will verify the proofs
/// @param _appId The World ID app ID
/// @param _actionId The World ID action ID
constructor(
IWorldID _worldId,
string memory _appId,
string memory _actionId
) {
worldId = _worldId;
externalNullifier = abi
.encodePacked(abi.encodePacked(_appId).hashToField(), _actionId)
.hashToField();
}
/// @param signal An arbitrary input from the user, usually the user's wallet address (check README for further details)
/// @param root The root of the Merkle tree (returned by the JS widget).
/// @param nullifierHash The nullifier hash for this proof, preventing double signaling (returned by the JS widget).
/// @param proof The zero-knowledge proof that demonstrates the claimer is registered with World ID (returned by the JS widget).
/// @dev Feel free to rename this method however you want! We've used `claim`, `verify` or `execute` in the past.
function verifyAndExecute(
address signal,
uint256 root,
uint256 nullifierHash,
uint256[8] calldata proof
) public {
// First, we make sure this person hasn't done this before
if (nullifierHashes[nullifierHash]) revert InvalidNullifier();
// We now verify the provided proof is valid and the user is verified by World ID
worldId.verifyProof(
root,
groupId,
abi.encodePacked(signal).hashToField(),
nullifierHash,
externalNullifier,
proof
);
// We now record the user has done this, so they can't do it again (proof of uniqueness)
nullifierHashes[nullifierHash] = true;
// Finally, execute your logic here, for example issue a token, NFT, etc...
// Make sure to emit some kind of event afterwards!
}
}