Skip to content

Commit

Permalink
skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
m1guelpf committed May 12, 2023
1 parent 6f8d630 commit b1c69b8
Show file tree
Hide file tree
Showing 16 changed files with 1,012 additions and 167 deletions.
File renamed without changes.
3 changes: 3 additions & 0 deletions .gitmodules
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
2 changes: 1 addition & 1 deletion contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ src = "src"
out = "out"
libs = ["lib"]

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
# See more config options https://github.com/foundry-rs/foundry/tree/master/config
1 change: 1 addition & 0 deletions contracts/lib/forge-std
Submodule forge-std added at 73d44e
12 changes: 0 additions & 12 deletions contracts/script/Counter.s.sol

This file was deleted.

62 changes: 62 additions & 0 deletions contracts/src/Contract.sol
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!
}
}
14 changes: 0 additions & 14 deletions contracts/src/Counter.sol

This file was deleted.

12 changes: 12 additions & 0 deletions contracts/src/helpers/ByteHasher.sol
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;
}
}
21 changes: 21 additions & 0 deletions contracts/src/interfaces/IWorldID.sol
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;
}
24 changes: 0 additions & 24 deletions contracts/test/Counter.t.sol

This file was deleted.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"@types/node": "20.1.2",
"@types/react": "18.2.6",
"@types/react-dom": "18.2.4",
"@worldcoin/idkit": "^0.4.9",
"autoprefixer": "10.4.14",
"connectkit": "^1.2.4",
"eslint": "8.40.0",
Expand Down
Loading

1 comment on commit b1c69b8

@Yutmanah
Copy link

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

Please sign in to comment.