-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,012 additions
and
167 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "contracts/lib/forge-std"] | ||
path = contracts/lib/forge-std | ||
url = https://github.com/foundry-rs/forge-std |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// 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! | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.10; | ||
|
||
library ByteHasher { | ||
/// @dev Creates a keccak256 hash of a bytestring. | ||
/// @param value The bytestring to hash | ||
/// @return The hash of the specified value | ||
/// @dev `>> 8` makes sure that the result is included in our field | ||
function hashToField(bytes memory value) internal pure returns (uint256) { | ||
return uint256(keccak256(abi.encodePacked(value))) >> 8; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.10; | ||
|
||
interface IWorldID { | ||
/// @notice Reverts if the zero-knowledge proof is invalid. | ||
/// @param root The of the Merkle tree | ||
/// @param groupId The id of the Semaphore group | ||
/// @param signalHash A keccak256 hash of the Semaphore signal | ||
/// @param nullifierHash The nullifier hash | ||
/// @param externalNullifierHash A keccak256 hash of the external nullifier | ||
/// @param proof The zero-knowledge proof | ||
/// @dev Note that a double-signaling check is not included here, and should be carried by the caller. | ||
function verifyProof( | ||
uint256 root, | ||
uint256 groupId, | ||
uint256 signalHash, | ||
uint256 nullifierHash, | ||
uint256 externalNullifierHash, | ||
uint256[8] calldata proof | ||
) external view; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
b1c69b8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help me verify my world ID