Goerli Testnet

Contract

0x3889927F0B5Eb1a02C6E2C20b39a1Bd4EAd76131
Source Code
Transaction Hash
Method
Block
From
To
Value
Add Members97405392023-09-22 17:00:244 days 21 hrs ago1695402024IN
0x388992...EAd76131
0 ETH0.001103581.5
Add Member97018342023-09-15 23:10:0011 days 15 hrs ago1694819400IN
0x388992...EAd76131
0 ETH0.001086111.50000001
Add Members96687572023-09-10 6:15:4817 days 8 hrs ago1694326548IN
0x388992...EAd76131
0 ETH0.002641181.5
Add Members96687062023-09-10 6:04:1217 days 8 hrs ago1694325852IN
0x388992...EAd76131
0 ETH0.001091011.5
Create Group96687032023-09-10 6:03:3617 days 8 hrs ago1694325816IN
0x388992...EAd76131
0 ETH0.001449751.5
Add Members96653192023-09-09 16:18:2417 days 22 hrs ago1694276304IN
0x388992...EAd76131
0 ETH0.002647141.5
Add Members96643252023-09-09 12:16:0018 days 2 hrs ago1694261760IN
0x388992...EAd76131
0 ETH0.001878111.50000001
Create Group96641542023-09-09 11:32:3618 days 3 hrs ago1694259156IN
0x388992...EAd76131
0 ETH0.00255771.50000001
Add Members96637572023-09-09 9:53:3618 days 4 hrs ago1694253216IN
0x388992...EAd76131
0 ETH0.004211551.50000001
Add Member96627572023-09-09 5:48:1218 days 8 hrs ago1694238492IN
0x388992...EAd76131
0 ETH0.001086041.5
Add Member96627552023-09-09 5:47:2418 days 8 hrs ago1694238444IN
0x388992...EAd76131
0 ETH0.002003861.5
Create Group96622932023-09-09 3:56:3618 days 10 hrs ago1694231796IN
0x388992...EAd76131
0 ETH0.001449881.5
Add Member96597162023-09-08 17:22:2418 days 21 hrs ago1694193744IN
0x388992...EAd76131
0 ETH0.00200391.5
Create Group96597082023-09-08 17:20:3618 days 21 hrs ago1694193636IN
0x388992...EAd76131
0 ETH0.001451.5
Add Member96596952023-09-08 17:17:2418 days 21 hrs ago1694193444IN
0x388992...EAd76131
0 ETH0.002003921.5
Create Group96554022023-09-07 23:31:1219 days 15 hrs ago1694129472IN
0x388992...EAd76131
0 ETH0.001449861.5
Add Member96553872023-09-07 23:27:2419 days 15 hrs ago1694129244IN
0x388992...EAd76131
0 ETH0.001090161.5
Add Member96545602023-09-07 20:01:4819 days 18 hrs ago1694116908IN
0x388992...EAd76131
0 ETH0.001090541.50000001
Add Member96499892023-09-07 1:13:3620 days 13 hrs ago1694049216IN
0x388992...EAd76131
0 ETH0.001085951.5
Add Member96491382023-09-06 21:48:4820 days 16 hrs ago1694036928IN
0x388992...EAd76131
0 ETH0.003643251.50000001
Create Group96491352023-09-06 21:47:4820 days 16 hrs ago1694036868IN
0x388992...EAd76131
0 ETH0.00255771.50000001
Add Member96085922023-08-30 19:51:1227 days 18 hrs ago1693425072IN
0x388992...EAd76131
0 ETH0.002003591.50000001
Create Group96085882023-08-30 19:50:2427 days 18 hrs ago1693425024IN
0x388992...EAd76131
0 ETH0.00144971.50000001
Add Member96060882023-08-30 9:17:2428 days 5 hrs ago1693387044IN
0x388992...EAd76131
0 ETH0.001328191.50000553
Create Group96013802023-08-29 13:30:0029 days 1 hr ago1693315800IN
0x388992...EAd76131
0 ETH0.001449751.50000001
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Txn Hash Block From To Value
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
97685122023-09-27 13:14:121 hr 21 mins ago1695820452
0x388992...EAd76131
0 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Semaphore

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 9 : Semaphore.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "./interfaces/ISemaphore.sol";
import "./interfaces/ISemaphoreVerifier.sol";
import "./base/SemaphoreGroups.sol";

/// @title Semaphore
/// @dev This contract uses the Semaphore base contracts to provide a complete service
/// to allow admins to create and manage groups and their members to generate Semaphore proofs
/// and verify them. Group admins can add, update or remove group members, and can be
/// an Ethereum account or a smart contract. This contract also assigns each new Merkle tree
/// generated with a new root a duration (or an expiry) within which the proofs generated with that root
/// can be validated.
contract Semaphore is ISemaphore, SemaphoreGroups {
    ISemaphoreVerifier public verifier;

    /// @dev Gets a group id and returns the group parameters.
    mapping(uint256 => Group) public groups;

    /// @dev Checks if the group admin is the transaction sender.
    /// @param groupId: Id of the group.
    modifier onlyGroupAdmin(uint256 groupId) {
        if (groups[groupId].admin != _msgSender()) {
            revert Semaphore__CallerIsNotTheGroupAdmin();
        }
        _;
    }

    /// @dev Checks if there is a verifier for the given tree depth.
    /// @param merkleTreeDepth: Depth of the tree.
    modifier onlySupportedMerkleTreeDepth(uint256 merkleTreeDepth) {
        if (merkleTreeDepth < 16 || merkleTreeDepth > 32) {
            revert Semaphore__MerkleTreeDepthIsNotSupported();
        }
        _;
    }

    /// @dev Initializes the Semaphore verifier used to verify the user's ZK proofs.
    /// @param _verifier: Semaphore verifier address.
    constructor(ISemaphoreVerifier _verifier) {
        verifier = _verifier;
    }

    /// @dev See {ISemaphore-createGroup}.
    function createGroup(
        uint256 groupId,
        uint256 merkleTreeDepth,
        address admin
    ) external override onlySupportedMerkleTreeDepth(merkleTreeDepth) {
        _createGroup(groupId, merkleTreeDepth);

        groups[groupId].admin = admin;
        groups[groupId].merkleTreeDuration = 1 hours;

        emit GroupAdminUpdated(groupId, address(0), admin);
    }

    /// @dev See {ISemaphore-createGroup}.
    function createGroup(
        uint256 groupId,
        uint256 merkleTreeDepth,
        address admin,
        uint256 merkleTreeDuration
    ) external override onlySupportedMerkleTreeDepth(merkleTreeDepth) {
        _createGroup(groupId, merkleTreeDepth);

        groups[groupId].admin = admin;
        groups[groupId].merkleTreeDuration = merkleTreeDuration;

        emit GroupAdminUpdated(groupId, address(0), admin);
    }

    /// @dev See {ISemaphore-updateGroupAdmin}.
    function updateGroupAdmin(uint256 groupId, address newAdmin) external override onlyGroupAdmin(groupId) {
        groups[groupId].admin = newAdmin;

        emit GroupAdminUpdated(groupId, _msgSender(), newAdmin);
    }

    /// @dev See {ISemaphore-updateGroupMerkleTreeDuration}.
    function updateGroupMerkleTreeDuration(
        uint256 groupId,
        uint256 newMerkleTreeDuration
    ) external override onlyGroupAdmin(groupId) {
        uint256 oldMerkleTreeDuration = groups[groupId].merkleTreeDuration;

        groups[groupId].merkleTreeDuration = newMerkleTreeDuration;

        emit GroupMerkleTreeDurationUpdated(groupId, oldMerkleTreeDuration, newMerkleTreeDuration);
    }

    /// @dev See {ISemaphore-addMember}.
    function addMember(uint256 groupId, uint256 identityCommitment) external override onlyGroupAdmin(groupId) {
        _addMember(groupId, identityCommitment);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);

        groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
    }

    /// @dev See {ISemaphore-addMembers}.
    function addMembers(
        uint256 groupId,
        uint256[] calldata identityCommitments
    ) external override onlyGroupAdmin(groupId) {
        for (uint256 i = 0; i < identityCommitments.length; ) {
            _addMember(groupId, identityCommitments[i]);

            unchecked {
                ++i;
            }
        }

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);

        groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
    }

    /// @dev See {ISemaphore-updateMember}.
    function updateMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256 newIdentityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) external override onlyGroupAdmin(groupId) {
        _updateMember(groupId, identityCommitment, newIdentityCommitment, proofSiblings, proofPathIndices);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);

        groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
    }

    /// @dev See {ISemaphore-removeMember}.
    function removeMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) external override onlyGroupAdmin(groupId) {
        _removeMember(groupId, identityCommitment, proofSiblings, proofPathIndices);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);

        groups[groupId].merkleRootCreationDates[merkleTreeRoot] = block.timestamp;
    }

    /// @dev See {ISemaphore-verifyProof}.
    function verifyProof(
        uint256 groupId,
        uint256 merkleTreeRoot,
        uint256 signal,
        uint256 nullifierHash,
        uint256 externalNullifier,
        uint256[8] calldata proof
    ) external override {
        uint256 merkleTreeDepth = getMerkleTreeDepth(groupId);

        if (merkleTreeDepth == 0) {
            revert Semaphore__GroupDoesNotExist();
        }

        uint256 currentMerkleTreeRoot = getMerkleTreeRoot(groupId);

        // A proof could have used an old Merkle tree root.
        // https://github.com/semaphore-protocol/semaphore/issues/98
        if (merkleTreeRoot != currentMerkleTreeRoot) {
            uint256 merkleRootCreationDate = groups[groupId].merkleRootCreationDates[merkleTreeRoot];
            uint256 merkleTreeDuration = groups[groupId].merkleTreeDuration;

            if (merkleRootCreationDate == 0) {
                revert Semaphore__MerkleTreeRootIsNotPartOfTheGroup();
            }

            if (block.timestamp > merkleRootCreationDate + merkleTreeDuration) {
                revert Semaphore__MerkleTreeRootIsExpired();
            }
        }

        if (groups[groupId].nullifierHashes[nullifierHash]) {
            revert Semaphore__YouAreUsingTheSameNillifierTwice();
        }

        verifier.verifyProof(merkleTreeRoot, nullifierHash, signal, externalNullifier, proof, merkleTreeDepth);

        groups[groupId].nullifierHashes[nullifierHash] = true;

        emit ProofVerified(groupId, merkleTreeRoot, nullifierHash, externalNullifier, signal);
    }
}

File 2 of 9 : ISemaphore.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

/// @title Semaphore contract interface.
interface ISemaphore {
    error Semaphore__CallerIsNotTheGroupAdmin();
    error Semaphore__MerkleTreeDepthIsNotSupported();
    error Semaphore__MerkleTreeRootIsExpired();
    error Semaphore__MerkleTreeRootIsNotPartOfTheGroup();
    error Semaphore__YouAreUsingTheSameNillifierTwice();

    /// It defines all the group parameters, in addition to those in the Merkle tree.
    struct Group {
        address admin;
        uint256 merkleTreeDuration;
        mapping(uint256 => uint256) merkleRootCreationDates;
        mapping(uint256 => bool) nullifierHashes;
    }

    /// @dev Emitted when an admin is assigned to a group.
    /// @param groupId: Id of the group.
    /// @param oldAdmin: Old admin of the group.
    /// @param newAdmin: New admin of the group.
    event GroupAdminUpdated(uint256 indexed groupId, address indexed oldAdmin, address indexed newAdmin);

    /// @dev Emitted when the Merkle tree duration of a group is updated.
    /// @param groupId: Id of the group.
    /// @param oldMerkleTreeDuration: Old Merkle tree duration of the group.
    /// @param newMerkleTreeDuration: New Merkle tree duration of the group.
    event GroupMerkleTreeDurationUpdated(
        uint256 indexed groupId,
        uint256 oldMerkleTreeDuration,
        uint256 newMerkleTreeDuration
    );

    /// @dev Emitted when a Semaphore proof is verified.
    /// @param groupId: Id of the group.
    /// @param merkleTreeRoot: Root of the Merkle tree.
    /// @param nullifierHash: Nullifier hash.
    /// @param externalNullifier: External nullifier.
    /// @param signal: Semaphore signal.
    event ProofVerified(
        uint256 indexed groupId,
        uint256 indexed merkleTreeRoot,
        uint256 nullifierHash,
        uint256 indexed externalNullifier,
        uint256 signal
    );

    /// @dev Saves the nullifier hash to avoid double signaling and emits an event
    /// if the zero-knowledge proof is valid.
    /// @param groupId: Id of the group.
    /// @param merkleTreeRoot: Root of the Merkle tree.
    /// @param signal: Semaphore signal.
    /// @param nullifierHash: Nullifier hash.
    /// @param externalNullifier: External nullifier.
    /// @param proof: Zero-knowledge proof.
    function verifyProof(
        uint256 groupId,
        uint256 merkleTreeRoot,
        uint256 signal,
        uint256 nullifierHash,
        uint256 externalNullifier,
        uint256[8] calldata proof
    ) external;

    /// @dev Creates a new group. Only the admin will be able to add or remove members.
    /// @param groupId: Id of the group.
    /// @param depth: Depth of the tree.
    /// @param admin: Admin of the group.
    function createGroup(uint256 groupId, uint256 depth, address admin) external;

    /// @dev Creates a new group. Only the admin will be able to add or remove members.
    /// @param groupId: Id of the group.
    /// @param depth: Depth of the tree.
    /// @param admin: Admin of the group.
    /// @param merkleTreeRootDuration: Time before the validity of a root expires.
    function createGroup(uint256 groupId, uint256 depth, address admin, uint256 merkleTreeRootDuration) external;

    /// @dev Updates the group admin.
    /// @param groupId: Id of the group.
    /// @param newAdmin: New admin of the group.
    function updateGroupAdmin(uint256 groupId, address newAdmin) external;

    /// @dev Updates the group Merkle tree duration.
    /// @param groupId: Id of the group.
    /// @param newMerkleTreeDuration: New Merkle tree duration.
    function updateGroupMerkleTreeDuration(uint256 groupId, uint256 newMerkleTreeDuration) external;

    /// @dev Adds a new member to an existing group.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: New identity commitment.
    function addMember(uint256 groupId, uint256 identityCommitment) external;

    /// @dev Adds new members to an existing group.
    /// @param groupId: Id of the group.
    /// @param identityCommitments: New identity commitments.
    function addMembers(uint256 groupId, uint256[] calldata identityCommitments) external;

    /// @dev Updates an identity commitment of an existing group. A proof of membership is
    /// needed to check if the node to be updated is part of the tree.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: Existing identity commitment to be updated.
    /// @param newIdentityCommitment: New identity commitment.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function updateMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256 newIdentityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) external;

    /// @dev Removes a member from an existing group. A proof of membership is
    /// needed to check if the node to be removed is part of the tree.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: Identity commitment to be removed.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function removeMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) external;
}

File 3 of 9 : ISemaphoreVerifier.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "../base/Pairing.sol";

/// @title SemaphoreVerifier contract interface.
interface ISemaphoreVerifier {
    struct VerificationKey {
        Pairing.G1Point alfa1;
        Pairing.G2Point beta2;
        Pairing.G2Point gamma2;
        Pairing.G2Point delta2;
        Pairing.G1Point[] IC;
    }

    struct Proof {
        Pairing.G1Point A;
        Pairing.G2Point B;
        Pairing.G1Point C;
    }

    /// @dev Verifies whether a Semaphore proof is valid.
    /// @param merkleTreeRoot: Root of the Merkle tree.
    /// @param nullifierHash: Nullifier hash.
    /// @param signal: Semaphore signal.
    /// @param externalNullifier: External nullifier.
    /// @param proof: Zero-knowledge proof.
    /// @param merkleTreeDepth: Depth of the tree.
    function verifyProof(
        uint256 merkleTreeRoot,
        uint256 nullifierHash,
        uint256 signal,
        uint256 externalNullifier,
        uint256[8] calldata proof,
        uint256 merkleTreeDepth
    ) external view;
}

File 4 of 9 : SemaphoreGroups.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

import "../interfaces/ISemaphoreGroups.sol";
import "@zk-kit/incremental-merkle-tree.sol/IncrementalBinaryTree.sol";
import "@openzeppelin/contracts/utils/Context.sol";

/// @title Semaphore groups contract.
/// @dev This contract allows you to create groups, add, remove and update members.
/// You can use getters to obtain informations about groups (root, depth, number of leaves).
abstract contract SemaphoreGroups is Context, ISemaphoreGroups {
    using IncrementalBinaryTree for IncrementalTreeData;

    /// @dev Gets a group id and returns the tree data.
    mapping(uint256 => IncrementalTreeData) internal merkleTrees;

    /// @dev Creates a new group by initializing the associated tree.
    /// @param groupId: Id of the group.
    /// @param merkleTreeDepth: Depth of the tree.
    function _createGroup(uint256 groupId, uint256 merkleTreeDepth) internal virtual {
        if (getMerkleTreeDepth(groupId) != 0) {
            revert Semaphore__GroupAlreadyExists();
        }

        // The zeroValue is an implicit member of the group, or an implicit leaf of the Merkle tree.
        // Although there is a remote possibility that the preimage of
        // the hash may be calculated, using this value we aim to minimize the risk.
        uint256 zeroValue = uint256(keccak256(abi.encodePacked(groupId))) >> 8;

        merkleTrees[groupId].init(merkleTreeDepth, zeroValue);

        emit GroupCreated(groupId, merkleTreeDepth, zeroValue);
    }

    /// @dev Adds an identity commitment to an existing group.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: New identity commitment.
    function _addMember(uint256 groupId, uint256 identityCommitment) internal virtual {
        if (getMerkleTreeDepth(groupId) == 0) {
            revert Semaphore__GroupDoesNotExist();
        }

        merkleTrees[groupId].insert(identityCommitment);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
        uint256 index = getNumberOfMerkleTreeLeaves(groupId) - 1;

        emit MemberAdded(groupId, index, identityCommitment, merkleTreeRoot);
    }

    /// @dev Updates an identity commitment of an existing group. A proof of membership is
    /// needed to check if the node to be updated is part of the tree.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: Existing identity commitment to be updated.
    /// @param newIdentityCommitment: New identity commitment.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function _updateMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256 newIdentityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) internal virtual {
        if (getMerkleTreeDepth(groupId) == 0) {
            revert Semaphore__GroupDoesNotExist();
        }

        merkleTrees[groupId].update(identityCommitment, newIdentityCommitment, proofSiblings, proofPathIndices);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
        uint256 index = proofPathIndicesToMemberIndex(proofPathIndices);

        emit MemberUpdated(groupId, index, identityCommitment, newIdentityCommitment, merkleTreeRoot);
    }

    /// @dev Removes an identity commitment from an existing group. A proof of membership is
    /// needed to check if the node to be deleted is part of the tree.
    /// @param groupId: Id of the group.
    /// @param identityCommitment: Existing identity commitment to be removed.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function _removeMember(
        uint256 groupId,
        uint256 identityCommitment,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) internal virtual {
        if (getMerkleTreeDepth(groupId) == 0) {
            revert Semaphore__GroupDoesNotExist();
        }

        merkleTrees[groupId].remove(identityCommitment, proofSiblings, proofPathIndices);

        uint256 merkleTreeRoot = getMerkleTreeRoot(groupId);
        uint256 index = proofPathIndicesToMemberIndex(proofPathIndices);

        emit MemberRemoved(groupId, index, identityCommitment, merkleTreeRoot);
    }

    /// @dev See {ISemaphoreGroups-getMerkleTreeRoot}.
    function getMerkleTreeRoot(uint256 groupId) public view virtual override returns (uint256) {
        return merkleTrees[groupId].root;
    }

    /// @dev See {ISemaphoreGroups-getMerkleTreeDepth}.
    function getMerkleTreeDepth(uint256 groupId) public view virtual override returns (uint256) {
        return merkleTrees[groupId].depth;
    }

    /// @dev See {ISemaphoreGroups-getNumberOfMerkleTreeLeaves}.
    function getNumberOfMerkleTreeLeaves(uint256 groupId) public view virtual override returns (uint256) {
        return merkleTrees[groupId].numberOfLeaves;
    }

    /// @dev Converts the path indices of a Merkle proof to the identity commitment index in the tree.
    /// @param proofPathIndices: Path of the proof of membership.
    /// @return Index of a group member.
    function proofPathIndicesToMemberIndex(uint8[] calldata proofPathIndices) private pure returns (uint256) {
        uint256 memberIndex = 0;

        for (uint8 i = uint8(proofPathIndices.length); i > 0; ) {
            if (memberIndex > 0 || proofPathIndices[i - 1] != 0) {
                memberIndex *= 2;

                if (proofPathIndices[i - 1] == 1) {
                    memberIndex += 1;
                }
            }

            unchecked {
                --i;
            }
        }

        return memberIndex;
    }
}

File 5 of 9 : Pairing.sol
// Copyright 2017 Christian Reitwiessner
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// The following Pairing library is a modified version adapted to Semaphore.
//
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library Pairing {
    error InvalidProof();

    // The prime q in the base field F_q for G1
    uint256 constant BASE_MODULUS = 21888242871839275222246405745257275088696311157297823662689037894645226208583;

    // The prime modulus of the scalar field of G1.
    uint256 constant SCALAR_MODULUS = 21888242871839275222246405745257275088548364400416034343698204186575808495617;

    struct G1Point {
        uint256 X;
        uint256 Y;
    }

    // Encoding of field elements is: X[0] * z + X[1]
    struct G2Point {
        uint256[2] X;
        uint256[2] Y;
    }

    /// @return the generator of G1
    function P1() public pure returns (G1Point memory) {
        return G1Point(1, 2);
    }

    /// @return the generator of G2
    function P2() public pure returns (G2Point memory) {
        return
            G2Point(
                [
                    11559732032986387107991004021392285783925812861821192530917403151452391805634,
                    10857046999023057135944570762232829481370756359578518086990519993285655852781
                ],
                [
                    4082367875863433681332203403145435568316851327593401208105741076214120093531,
                    8495653923123431417604973247489272438418190587263600148770280649306958101930
                ]
            );
    }

    /// @return r the negation of p, i.e. p.addition(p.negate()) should be zero.
    function negate(G1Point memory p) public pure returns (G1Point memory r) {
        if (p.X == 0 && p.Y == 0) {
            return G1Point(0, 0);
        }

        // Validate input or revert
        if (p.X >= BASE_MODULUS || p.Y >= BASE_MODULUS) {
            revert InvalidProof();
        }

        // We know p.Y > 0 and p.Y < BASE_MODULUS.
        return G1Point(p.X, BASE_MODULUS - p.Y);
    }

    /// @return r the sum of two points of G1
    function addition(G1Point memory p1, G1Point memory p2) public view returns (G1Point memory r) {
        // By EIP-196 all input is validated to be less than the BASE_MODULUS and form points
        // on the curve.
        uint256[4] memory input;

        input[0] = p1.X;
        input[1] = p1.Y;
        input[2] = p2.X;
        input[3] = p2.Y;

        bool success;

        // solium-disable-next-line security/no-inline-assembly
        assembly {
            success := staticcall(sub(gas(), 2000), 6, input, 0xc0, r, 0x60)
        }

        if (!success) {
            revert InvalidProof();
        }
    }

    /// @return r the product of a point on G1 and a scalar, i.e.
    /// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
    function scalar_mul(G1Point memory p, uint256 s) public view returns (G1Point memory r) {
        // By EIP-196 the values p.X and p.Y are verified to be less than the BASE_MODULUS and
        // form a valid point on the curve. But the scalar is not verified, so we do that explicitly.
        if (s >= SCALAR_MODULUS) {
            revert InvalidProof();
        }

        uint256[3] memory input;

        input[0] = p.X;
        input[1] = p.Y;
        input[2] = s;

        bool success;

        // solium-disable-next-line security/no-inline-assembly
        assembly {
            success := staticcall(sub(gas(), 2000), 7, input, 0x80, r, 0x60)
        }

        if (!success) {
            revert InvalidProof();
        }
    }

    /// Asserts the pairing check
    /// e(p1[0], p2[0]) *  .... * e(p1[n], p2[n]) == 1
    /// For example pairing([P1(), P1().negate()], [P2(), P2()]) should succeed
    function pairingCheck(G1Point[] memory p1, G2Point[] memory p2) public view {
        // By EIP-197 all input is verified to be less than the BASE_MODULUS and form elements in their
        // respective groups of the right order.
        if (p1.length != p2.length) {
            revert InvalidProof();
        }

        uint256 elements = p1.length;
        uint256 inputSize = elements * 6;
        uint256[] memory input = new uint256[](inputSize);

        for (uint256 i = 0; i < elements; i++) {
            input[i * 6 + 0] = p1[i].X;
            input[i * 6 + 1] = p1[i].Y;
            input[i * 6 + 2] = p2[i].X[0];
            input[i * 6 + 3] = p2[i].X[1];
            input[i * 6 + 4] = p2[i].Y[0];
            input[i * 6 + 5] = p2[i].Y[1];
        }

        uint256[1] memory out;
        bool success;

        // solium-disable-next-line security/no-inline-assembly
        assembly {
            success := staticcall(sub(gas(), 2000), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
        }

        if (!success || out[0] != 1) {
            revert InvalidProof();
        }
    }
}

File 6 of 9 : ISemaphoreGroups.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

/// @title SemaphoreGroups contract interface.
interface ISemaphoreGroups {
    error Semaphore__GroupDoesNotExist();
    error Semaphore__GroupAlreadyExists();

    /// @dev Emitted when a new group is created.
    /// @param groupId: Id of the group.
    /// @param merkleTreeDepth: Depth of the tree.
    /// @param zeroValue: Zero value of the tree.
    event GroupCreated(uint256 indexed groupId, uint256 merkleTreeDepth, uint256 zeroValue);

    /// @dev Emitted when a new identity commitment is added.
    /// @param groupId: Group id of the group.
    /// @param index: Identity commitment index.
    /// @param identityCommitment: New identity commitment.
    /// @param merkleTreeRoot: New root hash of the tree.
    event MemberAdded(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);

    /// @dev Emitted when an identity commitment is updated.
    /// @param groupId: Group id of the group.
    /// @param index: Identity commitment index.
    /// @param identityCommitment: Existing identity commitment to be updated.
    /// @param newIdentityCommitment: New identity commitment.
    /// @param merkleTreeRoot: New root hash of the tree.
    event MemberUpdated(
        uint256 indexed groupId,
        uint256 index,
        uint256 identityCommitment,
        uint256 newIdentityCommitment,
        uint256 merkleTreeRoot
    );

    /// @dev Emitted when a new identity commitment is removed.
    /// @param groupId: Group id of the group.
    /// @param index: Identity commitment index.
    /// @param identityCommitment: Existing identity commitment to be removed.
    /// @param merkleTreeRoot: New root hash of the tree.
    event MemberRemoved(uint256 indexed groupId, uint256 index, uint256 identityCommitment, uint256 merkleTreeRoot);

    /// @dev Returns the last root hash of a group.
    /// @param groupId: Id of the group.
    /// @return Root hash of the group.
    function getMerkleTreeRoot(uint256 groupId) external view returns (uint256);

    /// @dev Returns the depth of the tree of a group.
    /// @param groupId: Id of the group.
    /// @return Depth of the group tree.
    function getMerkleTreeDepth(uint256 groupId) external view returns (uint256);

    /// @dev Returns the number of tree leaves of a group.
    /// @param groupId: Id of the group.
    /// @return Number of tree leaves.
    function getNumberOfMerkleTreeLeaves(uint256 groupId) external view returns (uint256);
}

File 7 of 9 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 8 of 9 : IncrementalBinaryTree.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import {PoseidonT3} from "./Hashes.sol";

// Each incremental tree has certain properties and data that will
// be used to add new leaves.
struct IncrementalTreeData {
    uint256 depth; // Depth of the tree (levels - 1).
    uint256 root; // Root hash of the tree.
    uint256 numberOfLeaves; // Number of leaves of the tree.
    mapping(uint256 => uint256) zeroes; // Zero hashes used for empty nodes (level -> zero hash).
    // The nodes of the subtrees used in the last addition of a leaf (level -> [left node, right node]).
    mapping(uint256 => uint256[2]) lastSubtrees; // Caching these values is essential to efficient appends.
}

/// @title Incremental binary Merkle tree.
/// @dev The incremental tree allows to calculate the root hash each time a leaf is added, ensuring
/// the integrity of the tree.
library IncrementalBinaryTree {
    uint8 internal constant MAX_DEPTH = 32;
    uint256 internal constant SNARK_SCALAR_FIELD =
        21888242871839275222246405745257275088548364400416034343698204186575808495617;

    /// @dev Initializes a tree.
    /// @param self: Tree data.
    /// @param depth: Depth of the tree.
    /// @param zero: Zero value to be used.
    function init(
        IncrementalTreeData storage self,
        uint256 depth,
        uint256 zero
    ) public {
        require(zero < SNARK_SCALAR_FIELD, "IncrementalBinaryTree: leaf must be < SNARK_SCALAR_FIELD");
        require(depth > 0 && depth <= MAX_DEPTH, "IncrementalBinaryTree: tree depth must be between 1 and 32");

        self.depth = depth;

        for (uint8 i = 0; i < depth; ) {
            self.zeroes[i] = zero;
            zero = PoseidonT3.poseidon([zero, zero]);

            unchecked {
                ++i;
            }
        }

        self.root = zero;
    }

    /// @dev Inserts a leaf in the tree.
    /// @param self: Tree data.
    /// @param leaf: Leaf to be inserted.
    function insert(IncrementalTreeData storage self, uint256 leaf) public {
        uint256 depth = self.depth;

        require(leaf < SNARK_SCALAR_FIELD, "IncrementalBinaryTree: leaf must be < SNARK_SCALAR_FIELD");
        require(self.numberOfLeaves < 2**depth, "IncrementalBinaryTree: tree is full");

        uint256 index = self.numberOfLeaves;
        uint256 hash = leaf;

        for (uint8 i = 0; i < depth; ) {
            if (index & 1 == 0) {
                self.lastSubtrees[i] = [hash, self.zeroes[i]];
            } else {
                self.lastSubtrees[i][1] = hash;
            }

            hash = PoseidonT3.poseidon(self.lastSubtrees[i]);
            index >>= 1;

            unchecked {
                ++i;
            }
        }

        self.root = hash;
        self.numberOfLeaves += 1;
    }

    /// @dev Updates a leaf in the tree.
    /// @param self: Tree data.
    /// @param leaf: Leaf to be updated.
    /// @param newLeaf: New leaf.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function update(
        IncrementalTreeData storage self,
        uint256 leaf,
        uint256 newLeaf,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) public {
        require(newLeaf != leaf, "IncrementalBinaryTree: new leaf cannot be the same as the old one");
        require(newLeaf < SNARK_SCALAR_FIELD, "IncrementalBinaryTree: new leaf must be < SNARK_SCALAR_FIELD");
        require(
            verify(self, leaf, proofSiblings, proofPathIndices),
            "IncrementalBinaryTree: leaf is not part of the tree"
        );

        uint256 depth = self.depth;
        uint256 hash = newLeaf;
        uint256 updateIndex;

        for (uint8 i = 0; i < depth; ) {
            updateIndex |= uint256(proofPathIndices[i]) << uint256(i);

            if (proofPathIndices[i] == 0) {
                if (proofSiblings[i] == self.lastSubtrees[i][1]) {
                    self.lastSubtrees[i][0] = hash;
                }

                hash = PoseidonT3.poseidon([hash, proofSiblings[i]]);
            } else {
                if (proofSiblings[i] == self.lastSubtrees[i][0]) {
                    self.lastSubtrees[i][1] = hash;
                }

                hash = PoseidonT3.poseidon([proofSiblings[i], hash]);
            }

            unchecked {
                ++i;
            }
        }
        require(updateIndex < self.numberOfLeaves, "IncrementalBinaryTree: leaf index out of range");

        self.root = hash;
    }

    /// @dev Removes a leaf from the tree.
    /// @param self: Tree data.
    /// @param leaf: Leaf to be removed.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    function remove(
        IncrementalTreeData storage self,
        uint256 leaf,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) public {
        update(self, leaf, self.zeroes[0], proofSiblings, proofPathIndices);
    }

    /// @dev Verify if the path is correct and the leaf is part of the tree.
    /// @param self: Tree data.
    /// @param leaf: Leaf to be removed.
    /// @param proofSiblings: Array of the sibling nodes of the proof of membership.
    /// @param proofPathIndices: Path of the proof of membership.
    /// @return True or false.
    function verify(
        IncrementalTreeData storage self,
        uint256 leaf,
        uint256[] calldata proofSiblings,
        uint8[] calldata proofPathIndices
    ) private view returns (bool) {
        require(leaf < SNARK_SCALAR_FIELD, "IncrementalBinaryTree: leaf must be < SNARK_SCALAR_FIELD");
        uint256 depth = self.depth;
        require(
            proofPathIndices.length == depth && proofSiblings.length == depth,
            "IncrementalBinaryTree: length of path is not correct"
        );

        uint256 hash = leaf;

        for (uint8 i = 0; i < depth; ) {
            require(
                proofSiblings[i] < SNARK_SCALAR_FIELD,
                "IncrementalBinaryTree: sibling node must be < SNARK_SCALAR_FIELD"
            );

            require(
                proofPathIndices[i] == 1 || proofPathIndices[i] == 0,
                "IncrementalBinaryTree: path index is neither 0 nor 1"
            );

            if (proofPathIndices[i] == 0) {
                hash = PoseidonT3.poseidon([hash, proofSiblings[i]]);
            } else {
                hash = PoseidonT3.poseidon([proofSiblings[i], hash]);
            }

            unchecked {
                ++i;
            }
        }

        return hash == self.root;
    }
}

File 9 of 9 : Hashes.sol
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

library PoseidonT3 {
    function poseidon(uint256[2] memory) public pure returns (uint256) {}
}

library PoseidonT6 {
    function poseidon(uint256[5] memory) public pure returns (uint256) {}
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {
    "@zk-kit/incremental-merkle-tree.sol/IncrementalBinaryTree.sol": {
      "IncrementalBinaryTree": "0x4621ee309eac747425f0fed51931ddc241a27f49"
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"contract ISemaphoreVerifier","name":"_verifier","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Semaphore__CallerIsNotTheGroupAdmin","type":"error"},{"inputs":[],"name":"Semaphore__GroupAlreadyExists","type":"error"},{"inputs":[],"name":"Semaphore__GroupDoesNotExist","type":"error"},{"inputs":[],"name":"Semaphore__MerkleTreeDepthIsNotSupported","type":"error"},{"inputs":[],"name":"Semaphore__MerkleTreeRootIsExpired","type":"error"},{"inputs":[],"name":"Semaphore__MerkleTreeRootIsNotPartOfTheGroup","type":"error"},{"inputs":[],"name":"Semaphore__YouAreUsingTheSameNillifierTwice","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":true,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"GroupAdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"merkleTreeDepth","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"zeroValue","type":"uint256"}],"name":"GroupCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldMerkleTreeDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMerkleTreeDuration","type":"uint256"}],"name":"GroupMerkleTreeDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"identityCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"merkleTreeRoot","type":"uint256"}],"name":"MemberAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"identityCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"merkleTreeRoot","type":"uint256"}],"name":"MemberRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"identityCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newIdentityCommitment","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"merkleTreeRoot","type":"uint256"}],"name":"MemberUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"groupId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"merkleTreeRoot","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"externalNullifier","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"signal","type":"uint256"}],"name":"ProofVerified","type":"event"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"identityCommitment","type":"uint256"}],"name":"addMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256[]","name":"identityCommitments","type":"uint256[]"}],"name":"addMembers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"merkleTreeDepth","type":"uint256"},{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint256","name":"merkleTreeDuration","type":"uint256"}],"name":"createGroup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"merkleTreeDepth","type":"uint256"},{"internalType":"address","name":"admin","type":"address"}],"name":"createGroup","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"}],"name":"getMerkleTreeDepth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"}],"name":"getMerkleTreeRoot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"}],"name":"getNumberOfMerkleTreeLeaves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"groups","outputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"uint256","name":"merkleTreeDuration","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"identityCommitment","type":"uint256"},{"internalType":"uint256[]","name":"proofSiblings","type":"uint256[]"},{"internalType":"uint8[]","name":"proofPathIndices","type":"uint8[]"}],"name":"removeMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"address","name":"newAdmin","type":"address"}],"name":"updateGroupAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"newMerkleTreeDuration","type":"uint256"}],"name":"updateGroupMerkleTreeDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"identityCommitment","type":"uint256"},{"internalType":"uint256","name":"newIdentityCommitment","type":"uint256"},{"internalType":"uint256[]","name":"proofSiblings","type":"uint256[]"},{"internalType":"uint8[]","name":"proofPathIndices","type":"uint8[]"}],"name":"updateMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract ISemaphoreVerifier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"groupId","type":"uint256"},{"internalType":"uint256","name":"merkleTreeRoot","type":"uint256"},{"internalType":"uint256","name":"signal","type":"uint256"},{"internalType":"uint256","name":"nullifierHash","type":"uint256"},{"internalType":"uint256","name":"externalNullifier","type":"uint256"},{"internalType":"uint256[8]","name":"proof","type":"uint256[8]"}],"name":"verifyProof","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200214a3803806200214a833981810160405281019062000037919062000096565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000124565b60008151905062000090816200010a565b92915050565b600060208284031215620000a957600080fd5b6000620000b9848285016200007f565b91505092915050565b6000620000cf82620000ea565b9050919050565b6000620000e382620000c2565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200011581620000d6565b81146200012157600080fd5b50565b61201680620001346000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636389e1071161008c5780639c112141116100665780639c11214114610246578063dabc4d5114610262578063ec45622a14610292578063fcf0b6ec146102ae576100ea565b80636389e107146101c957806365e54f83146101f957806396324bd414610215576100ea565b80633bc778e3116100c85780633bc778e31461014557806343989f8514610161578063568ee8261461017d578063638480be14610199576100ea565b806304245371146100ef5780631783efc31461010b5780632b7ac3f314610127575b600080fd5b61010960048036038101906101049190611655565b6102ca565b005b610125600480360381019061012091906116ad565b610410565b005b61012f6104fc565b60405161013c9190611b24565b60405180910390f35b61015f600480360381019061015a91906118e6565b610522565b005b61017b6004803603810190610176919061179b565b6107cf565b005b61019760048036038101906101929190611619565b6108c3565b005b6101b360048036038101906101ae91906115f0565b610a22565b6040516101c09190611c5b565b60405180910390f35b6101e360048036038101906101de91906115f0565b610a41565b6040516101f09190611c5b565b60405180910390f35b610213600480360381019061020e9190611738565b610a60565b005b61022f600480360381019061022a91906115f0565b610b84565b60405161023d929190611afb565b60405180910390f35b610260600480360381019061025b91906116e9565b610bc8565b005b61027c600480360381019061027791906115f0565b610ced565b6040516102899190611c5b565b60405180910390f35b6102ac60048036038101906102a79190611836565b610d0c565b005b6102c860048036038101906102c391906116ad565b610e02565b005b826102d3610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461036d576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838390508110156103cf576103c4858585848181106103b8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135610f23565b806001019050610370565b5060006103db85610ced565b905042600260008781526020019081526020016000206002016000838152602001908152602001600020819055505050505050565b81610419610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146104b3576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104bd8383610f23565b60006104c884610ced565b9050426002600086815260200190815260200160002060020160008381526020019081526020016000208190555050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061052d87610a41565b9050600081141561056a576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061057588610ced565b9050808714610648576000600260008a815260200190815260200160002060020160008981526020019081526020016000205490506000600260008b81526020019081526020016000206001015490506000821415610600576040517f4d32958600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808261060c9190611dce565b421115610645576040517f9581a99000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505b60026000898152602001908152602001600020600301600086815260200190815260200160002060009054906101000a900460ff16156106b4576040517f948d067400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639aca8f2a8887898888886040518763ffffffff1660e01b815260040161071996959493929190611d1b565b60006040518083038186803b15801561073157600080fd5b505afa158015610745573d6000803e3d6000fd5b505050506001600260008a8152602001908152602001600020600301600087815260200190815260200160002060006101000a81548160ff0219169083151502179055508387897f48950129900df26c2140187532df49c8af343c3daf74f1e99e562e1b2be07adc888a6040516107bd929190611c76565b60405180910390a45050505050505050565b856107d8610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610872576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088087878787878761104a565b600061088b88610ced565b905042600260008a81526020019081526020016000206002016000838152602001908152602001600020819055505050505050505050565b816108cc610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610966576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816002600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff166109da610f1b565b73ffffffffffffffffffffffffffffffffffffffff16847f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a4505050565b6000806000838152602001908152602001600020600201549050919050565b6000806000838152602001908152602001600020600001549050919050565b826010811080610a705750602081115b15610aa7576040517fecf64f1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab18585611172565b826002600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000878152602001908152602001600020600101819055508273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16867f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a45050505050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b816010811080610bd85750602081115b15610c0f576040517fecf64f1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c198484611172565b816002600086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610e1060026000868152602001908152602001600020600101819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16857f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a450505050565b6000806000838152602001908152602001600020600101549050919050565b86610d15610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610daf576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dbe888888888888886112a3565b6000610dc989610ced565b905042600260008b8152602001908152602001600020600201600083815260200190815260200160002081905550505050505050505050565b81610e0b610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea5576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060026000858152602001908152602001600020600101549050826002600086815260200190815260200160002060010181905550837f264b2a8f6763c084235fe832ba903482b2ef1a521336881fc75b987c2dfd29c58285604051610f0d929190611c76565b60405180910390a250505050565b600033905090565b6000610f2e83610a41565b1415610f66576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080838152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f4963168703fa9091836040518363ffffffff1660e01b8152600401610fb2929190611b3f565b60006040518083038186803b158015610fca57600080fd5b505af4158015610fde573d6000803e3d6000fd5b505050506000610fed83610ced565b905060006001610ffc85610a22565b6110069190611e7e565b9050837f19239b3f93cd10558aaf11423af70c77763bf54f52bcc75bfa74d4d13548cde982858560405161103c93929190611c9f565b60405180910390a250505050565b600061105587610a41565b141561108d576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080878152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f49630629596f909187878787876040518763ffffffff1660e01b81526004016110e196959493929190611b68565b60006040518083038186803b1580156110f957600080fd5b505af415801561110d573d6000803e3d6000fd5b50505050600061111c87610ced565b9050600061112a84846113d0565b9050877f3108849c053c77b8073a11256dffb5ffd5b55e93e105a355e1c9061db890d87182898560405161116093929190611c9f565b60405180910390a25050505050505050565b600061117d83610a41565b146111b4576040517f8121725b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006008836040516020016111c99190611ae0565b6040516020818303038152906040528051906020012060001c901c9050600080848152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f49631095fbb4909184846040518463ffffffff1660e01b815260040161123493929190611bbf565b60006040518083038186803b15801561124c57600080fd5b505af4158015611260573d6000803e3d6000fd5b50505050827f0d000126c26c1bbe400fd2332187f75d58b69306f9ec47b408686189d3a008338383604051611296929190611c76565b60405180910390a2505050565b60006112ae88610a41565b14156112e6576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080888152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f4963a547882790918888888888886040518863ffffffff1660e01b815260040161133c9796959493929190611bf6565b60006040518083038186803b15801561135457600080fd5b505af4158015611368573d6000803e3d6000fd5b50505050600061137788610ced565b9050600061138584846113d0565b9050887fea3588e4a2a0c93d6a0e69dfeaf7496f43ccccf02ad9ce0a5b7627cbca4b61b1828a8a866040516113bd9493929190611cd6565b60405180910390a2505050505050505050565b6000806000905060008484905090505b60008160ff1611156114f457600082118061145b5750600085856001846114079190611eb2565b60ff16818110611440577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906114559190611970565b60ff1614155b156114e85760028261146d9190611e24565b9150600185856001846114809190611eb2565b60ff168181106114b9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906114ce9190611970565b60ff1614156114e7576001826114e49190611dce565b91505b5b806001900390506113e0565b508091505092915050565b60008135905061150e81611f9b565b92915050565b60008190508260206008028201111561152c57600080fd5b92915050565b60008083601f84011261154457600080fd5b8235905067ffffffffffffffff81111561155d57600080fd5b60208301915083602082028301111561157557600080fd5b9250929050565b60008083601f84011261158e57600080fd5b8235905067ffffffffffffffff8111156115a757600080fd5b6020830191508360208202830111156115bf57600080fd5b9250929050565b6000813590506115d581611fb2565b92915050565b6000813590506115ea81611fc9565b92915050565b60006020828403121561160257600080fd5b6000611610848285016115c6565b91505092915050565b6000806040838503121561162c57600080fd5b600061163a858286016115c6565b925050602061164b858286016114ff565b9150509250929050565b60008060006040848603121561166a57600080fd5b6000611678868287016115c6565b935050602084013567ffffffffffffffff81111561169557600080fd5b6116a186828701611532565b92509250509250925092565b600080604083850312156116c057600080fd5b60006116ce858286016115c6565b92505060206116df858286016115c6565b9150509250929050565b6000806000606084860312156116fe57600080fd5b600061170c868287016115c6565b935050602061171d868287016115c6565b925050604061172e868287016114ff565b9150509250925092565b6000806000806080858703121561174e57600080fd5b600061175c878288016115c6565b945050602061176d878288016115c6565b935050604061177e878288016114ff565b925050606061178f878288016115c6565b91505092959194509250565b600080600080600080608087890312156117b457600080fd5b60006117c289828a016115c6565b96505060206117d389828a016115c6565b955050604087013567ffffffffffffffff8111156117f057600080fd5b6117fc89828a01611532565b9450945050606087013567ffffffffffffffff81111561181b57600080fd5b61182789828a0161157c565b92509250509295509295509295565b600080600080600080600060a0888a03121561185157600080fd5b600061185f8a828b016115c6565b97505060206118708a828b016115c6565b96505060406118818a828b016115c6565b955050606088013567ffffffffffffffff81111561189e57600080fd5b6118aa8a828b01611532565b9450945050608088013567ffffffffffffffff8111156118c957600080fd5b6118d58a828b0161157c565b925092505092959891949750929550565b6000806000806000806101a0878903121561190057600080fd5b600061190e89828a016115c6565b965050602061191f89828a016115c6565b955050604061193089828a016115c6565b945050606061194189828a016115c6565b935050608061195289828a016115c6565b92505060a061196389828a01611514565b9150509295509295509295565b60006020828403121561198257600080fd5b6000611990848285016115db565b91505092915050565b60006119a58383611ad1565b60208301905092915050565b6119ba81611ee6565b82525050565b6119cd6101008383611f53565b5050565b60006119dd8385611d95565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611a0c57600080fd5b602083029250611a1d838584611f53565b82840190509392505050565b6000611a358385611da6565b9350611a4082611d7e565b8060005b85811015611a7957611a568284611db7565b611a608882611999565b9750611a6b83611d88565b925050600181019050611a44565b5085925050509392505050565b611a8f81611f2f565b82525050565b8082525050565b611aa581611f18565b82525050565b611ab481611f18565b82525050565b611acb611ac682611f18565b611f62565b82525050565b611ada81611f22565b82525050565b6000611aec8284611aba565b60208201915081905092915050565b6000604082019050611b1060008301856119b1565b611b1d6020830184611a9c565b9392505050565b6000602082019050611b396000830184611a86565b92915050565b6000604082019050611b546000830185611a95565b611b616020830184611aab565b9392505050565b6000608082019050611b7d6000830189611a95565b611b8a6020830188611aab565b8181036040830152611b9d8186886119d1565b90508181036060830152611bb2818486611a29565b9050979650505050505050565b6000606082019050611bd46000830186611a95565b611be16020830185611aab565b611bee6040830184611aab565b949350505050565b600060a082019050611c0b600083018a611a95565b611c186020830189611aab565b611c256040830188611aab565b8181036060830152611c388186886119d1565b90508181036080830152611c4d818486611a29565b905098975050505050505050565b6000602082019050611c706000830184611a9c565b92915050565b6000604082019050611c8b6000830185611a9c565b611c986020830184611a9c565b9392505050565b6000606082019050611cb46000830186611a9c565b611cc16020830185611a9c565b611cce6040830184611a9c565b949350505050565b6000608082019050611ceb6000830187611a9c565b611cf86020830186611a9c565b611d056040830185611a9c565b611d126060830184611a9c565b95945050505050565b60006101a082019050611d316000830189611a9c565b611d3e6020830188611a9c565b611d4b6040830187611a9c565b611d586060830186611a9c565b611d6560808301856119c0565b611d73610180830184611a9c565b979650505050505050565b6000819050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611dc660208401846115db565b905092915050565b6000611dd982611f18565b9150611de483611f18565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611e1957611e18611f6c565b5b828201905092915050565b6000611e2f82611f18565b9150611e3a83611f18565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611e7357611e72611f6c565b5b828202905092915050565b6000611e8982611f18565b9150611e9483611f18565b925082821015611ea757611ea6611f6c565b5b828203905092915050565b6000611ebd82611f22565b9150611ec883611f22565b925082821015611edb57611eda611f6c565b5b828203905092915050565b6000611ef182611ef8565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000611f3a82611f41565b9050919050565b6000611f4c82611ef8565b9050919050565b82818337600083830152505050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b611fa481611ee6565b8114611faf57600080fd5b50565b611fbb81611f18565b8114611fc657600080fd5b50565b611fd281611f22565b8114611fdd57600080fd5b5056fea2646970667358221220a6777edc645a16d8f81beacbb5ec133f19452c578127e38e7f40d5540508d08464736f6c63430008040033000000000000000000000000b908bcb798e5353fb90155c692bdde3b4937217c

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636389e1071161008c5780639c112141116100665780639c11214114610246578063dabc4d5114610262578063ec45622a14610292578063fcf0b6ec146102ae576100ea565b80636389e107146101c957806365e54f83146101f957806396324bd414610215576100ea565b80633bc778e3116100c85780633bc778e31461014557806343989f8514610161578063568ee8261461017d578063638480be14610199576100ea565b806304245371146100ef5780631783efc31461010b5780632b7ac3f314610127575b600080fd5b61010960048036038101906101049190611655565b6102ca565b005b610125600480360381019061012091906116ad565b610410565b005b61012f6104fc565b60405161013c9190611b24565b60405180910390f35b61015f600480360381019061015a91906118e6565b610522565b005b61017b6004803603810190610176919061179b565b6107cf565b005b61019760048036038101906101929190611619565b6108c3565b005b6101b360048036038101906101ae91906115f0565b610a22565b6040516101c09190611c5b565b60405180910390f35b6101e360048036038101906101de91906115f0565b610a41565b6040516101f09190611c5b565b60405180910390f35b610213600480360381019061020e9190611738565b610a60565b005b61022f600480360381019061022a91906115f0565b610b84565b60405161023d929190611afb565b60405180910390f35b610260600480360381019061025b91906116e9565b610bc8565b005b61027c600480360381019061027791906115f0565b610ced565b6040516102899190611c5b565b60405180910390f35b6102ac60048036038101906102a79190611836565b610d0c565b005b6102c860048036038101906102c391906116ad565b610e02565b005b826102d3610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461036d576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b838390508110156103cf576103c4858585848181106103b8577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135610f23565b806001019050610370565b5060006103db85610ced565b905042600260008781526020019081526020016000206002016000838152602001908152602001600020819055505050505050565b81610419610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146104b3576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104bd8383610f23565b60006104c884610ced565b9050426002600086815260200190815260200160002060020160008381526020019081526020016000208190555050505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061052d87610a41565b9050600081141561056a576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061057588610ced565b9050808714610648576000600260008a815260200190815260200160002060020160008981526020019081526020016000205490506000600260008b81526020019081526020016000206001015490506000821415610600576040517f4d32958600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808261060c9190611dce565b421115610645576040517f9581a99000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505b60026000898152602001908152602001600020600301600086815260200190815260200160002060009054906101000a900460ff16156106b4576040517f948d067400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639aca8f2a8887898888886040518763ffffffff1660e01b815260040161071996959493929190611d1b565b60006040518083038186803b15801561073157600080fd5b505afa158015610745573d6000803e3d6000fd5b505050506001600260008a8152602001908152602001600020600301600087815260200190815260200160002060006101000a81548160ff0219169083151502179055508387897f48950129900df26c2140187532df49c8af343c3daf74f1e99e562e1b2be07adc888a6040516107bd929190611c76565b60405180910390a45050505050505050565b856107d8610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610872576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61088087878787878761104a565b600061088b88610ced565b905042600260008a81526020019081526020016000206002016000838152602001908152602001600020819055505050505050505050565b816108cc610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610966576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816002600085815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff166109da610f1b565b73ffffffffffffffffffffffffffffffffffffffff16847f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a4505050565b6000806000838152602001908152602001600020600201549050919050565b6000806000838152602001908152602001600020600001549050919050565b826010811080610a705750602081115b15610aa7576040517fecf64f1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab18585611172565b826002600087815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508160026000878152602001908152602001600020600101819055508273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16867f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a45050505050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010154905082565b816010811080610bd85750602081115b15610c0f576040517fecf64f1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c198484611172565b816002600086815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610e1060026000868152602001908152602001600020600101819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff16857f0ba83579a0e79193ef649b9f5a8759d35af086ba62a3e207b52e4a8ae30d49e360405160405180910390a450505050565b6000806000838152602001908152602001600020600101549050919050565b86610d15610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610daf576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610dbe888888888888886112a3565b6000610dc989610ced565b905042600260008b8152602001908152602001600020600201600083815260200190815260200160002081905550505050505050505050565b81610e0b610f1b565b73ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610ea5576040517fbb9bf27800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060026000858152602001908152602001600020600101549050826002600086815260200190815260200160002060010181905550837f264b2a8f6763c084235fe832ba903482b2ef1a521336881fc75b987c2dfd29c58285604051610f0d929190611c76565b60405180910390a250505050565b600033905090565b6000610f2e83610a41565b1415610f66576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080838152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f4963168703fa9091836040518363ffffffff1660e01b8152600401610fb2929190611b3f565b60006040518083038186803b158015610fca57600080fd5b505af4158015610fde573d6000803e3d6000fd5b505050506000610fed83610ced565b905060006001610ffc85610a22565b6110069190611e7e565b9050837f19239b3f93cd10558aaf11423af70c77763bf54f52bcc75bfa74d4d13548cde982858560405161103c93929190611c9f565b60405180910390a250505050565b600061105587610a41565b141561108d576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080878152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f49630629596f909187878787876040518763ffffffff1660e01b81526004016110e196959493929190611b68565b60006040518083038186803b1580156110f957600080fd5b505af415801561110d573d6000803e3d6000fd5b50505050600061111c87610ced565b9050600061112a84846113d0565b9050877f3108849c053c77b8073a11256dffb5ffd5b55e93e105a355e1c9061db890d87182898560405161116093929190611c9f565b60405180910390a25050505050505050565b600061117d83610a41565b146111b4576040517f8121725b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006008836040516020016111c99190611ae0565b6040516020818303038152906040528051906020012060001c901c9050600080848152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f49631095fbb4909184846040518463ffffffff1660e01b815260040161123493929190611bbf565b60006040518083038186803b15801561124c57600080fd5b505af4158015611260573d6000803e3d6000fd5b50505050827f0d000126c26c1bbe400fd2332187f75d58b69306f9ec47b408686189d3a008338383604051611296929190611c76565b60405180910390a2505050565b60006112ae88610a41565b14156112e6576040517f029f057900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080888152602001908152602001600020734621ee309eac747425f0fed51931ddc241a27f4963a547882790918888888888886040518863ffffffff1660e01b815260040161133c9796959493929190611bf6565b60006040518083038186803b15801561135457600080fd5b505af4158015611368573d6000803e3d6000fd5b50505050600061137788610ced565b9050600061138584846113d0565b9050887fea3588e4a2a0c93d6a0e69dfeaf7496f43ccccf02ad9ce0a5b7627cbca4b61b1828a8a866040516113bd9493929190611cd6565b60405180910390a2505050505050505050565b6000806000905060008484905090505b60008160ff1611156114f457600082118061145b5750600085856001846114079190611eb2565b60ff16818110611440577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906114559190611970565b60ff1614155b156114e85760028261146d9190611e24565b9150600185856001846114809190611eb2565b60ff168181106114b9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020160208101906114ce9190611970565b60ff1614156114e7576001826114e49190611dce565b91505b5b806001900390506113e0565b508091505092915050565b60008135905061150e81611f9b565b92915050565b60008190508260206008028201111561152c57600080fd5b92915050565b60008083601f84011261154457600080fd5b8235905067ffffffffffffffff81111561155d57600080fd5b60208301915083602082028301111561157557600080fd5b9250929050565b60008083601f84011261158e57600080fd5b8235905067ffffffffffffffff8111156115a757600080fd5b6020830191508360208202830111156115bf57600080fd5b9250929050565b6000813590506115d581611fb2565b92915050565b6000813590506115ea81611fc9565b92915050565b60006020828403121561160257600080fd5b6000611610848285016115c6565b91505092915050565b6000806040838503121561162c57600080fd5b600061163a858286016115c6565b925050602061164b858286016114ff565b9150509250929050565b60008060006040848603121561166a57600080fd5b6000611678868287016115c6565b935050602084013567ffffffffffffffff81111561169557600080fd5b6116a186828701611532565b92509250509250925092565b600080604083850312156116c057600080fd5b60006116ce858286016115c6565b92505060206116df858286016115c6565b9150509250929050565b6000806000606084860312156116fe57600080fd5b600061170c868287016115c6565b935050602061171d868287016115c6565b925050604061172e868287016114ff565b9150509250925092565b6000806000806080858703121561174e57600080fd5b600061175c878288016115c6565b945050602061176d878288016115c6565b935050604061177e878288016114ff565b925050606061178f878288016115c6565b91505092959194509250565b600080600080600080608087890312156117b457600080fd5b60006117c289828a016115c6565b96505060206117d389828a016115c6565b955050604087013567ffffffffffffffff8111156117f057600080fd5b6117fc89828a01611532565b9450945050606087013567ffffffffffffffff81111561181b57600080fd5b61182789828a0161157c565b92509250509295509295509295565b600080600080600080600060a0888a03121561185157600080fd5b600061185f8a828b016115c6565b97505060206118708a828b016115c6565b96505060406118818a828b016115c6565b955050606088013567ffffffffffffffff81111561189e57600080fd5b6118aa8a828b01611532565b9450945050608088013567ffffffffffffffff8111156118c957600080fd5b6118d58a828b0161157c565b925092505092959891949750929550565b6000806000806000806101a0878903121561190057600080fd5b600061190e89828a016115c6565b965050602061191f89828a016115c6565b955050604061193089828a016115c6565b945050606061194189828a016115c6565b935050608061195289828a016115c6565b92505060a061196389828a01611514565b9150509295509295509295565b60006020828403121561198257600080fd5b6000611990848285016115db565b91505092915050565b60006119a58383611ad1565b60208301905092915050565b6119ba81611ee6565b82525050565b6119cd6101008383611f53565b5050565b60006119dd8385611d95565b93507f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115611a0c57600080fd5b602083029250611a1d838584611f53565b82840190509392505050565b6000611a358385611da6565b9350611a4082611d7e565b8060005b85811015611a7957611a568284611db7565b611a608882611999565b9750611a6b83611d88565b925050600181019050611a44565b5085925050509392505050565b611a8f81611f2f565b82525050565b8082525050565b611aa581611f18565b82525050565b611ab481611f18565b82525050565b611acb611ac682611f18565b611f62565b82525050565b611ada81611f22565b82525050565b6000611aec8284611aba565b60208201915081905092915050565b6000604082019050611b1060008301856119b1565b611b1d6020830184611a9c565b9392505050565b6000602082019050611b396000830184611a86565b92915050565b6000604082019050611b546000830185611a95565b611b616020830184611aab565b9392505050565b6000608082019050611b7d6000830189611a95565b611b8a6020830188611aab565b8181036040830152611b9d8186886119d1565b90508181036060830152611bb2818486611a29565b9050979650505050505050565b6000606082019050611bd46000830186611a95565b611be16020830185611aab565b611bee6040830184611aab565b949350505050565b600060a082019050611c0b600083018a611a95565b611c186020830189611aab565b611c256040830188611aab565b8181036060830152611c388186886119d1565b90508181036080830152611c4d818486611a29565b905098975050505050505050565b6000602082019050611c706000830184611a9c565b92915050565b6000604082019050611c8b6000830185611a9c565b611c986020830184611a9c565b9392505050565b6000606082019050611cb46000830186611a9c565b611cc16020830185611a9c565b611cce6040830184611a9c565b949350505050565b6000608082019050611ceb6000830187611a9c565b611cf86020830186611a9c565b611d056040830185611a9c565b611d126060830184611a9c565b95945050505050565b60006101a082019050611d316000830189611a9c565b611d3e6020830188611a9c565b611d4b6040830187611a9c565b611d586060830186611a9c565b611d6560808301856119c0565b611d73610180830184611a9c565b979650505050505050565b6000819050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000611dc660208401846115db565b905092915050565b6000611dd982611f18565b9150611de483611f18565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115611e1957611e18611f6c565b5b828201905092915050565b6000611e2f82611f18565b9150611e3a83611f18565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611e7357611e72611f6c565b5b828202905092915050565b6000611e8982611f18565b9150611e9483611f18565b925082821015611ea757611ea6611f6c565b5b828203905092915050565b6000611ebd82611f22565b9150611ec883611f22565b925082821015611edb57611eda611f6c565b5b828203905092915050565b6000611ef182611ef8565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b6000611f3a82611f41565b9050919050565b6000611f4c82611ef8565b9050919050565b82818337600083830152505050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b611fa481611ee6565b8114611faf57600080fd5b50565b611fbb81611f18565b8114611fc657600080fd5b50565b611fd281611f22565b8114611fdd57600080fd5b5056fea2646970667358221220a6777edc645a16d8f81beacbb5ec133f19452c578127e38e7f40d5540508d08464736f6c63430008040033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000b908bcb798e5353fb90155c692bdde3b4937217c

-----Decoded View---------------
Arg [0] : _verifier (address): 0xb908Bcb798e5353fB90155C692BddE3b4937217C

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000b908bcb798e5353fb90155c692bdde3b4937217c


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.