---
sidebar_position: 3
---

# Contracts

Semaphore contracts are designed with minimal yet essential code, enabling developers to efficiently manage on-chain groups and verify or validate zero-knowledge proofs.
There are three contracts:

-   [`SemaphoreVerifier.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/base/SemaphoreVerifier.sol)
-   [`SemaphoreGroups.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/base/SemaphoreGroups.sol)
-   [`Semaphore.sol`](https://github.com/semaphore-protocol/semaphore/blob/main/packages/contracts/contracts/Semaphore.sol)

:::info
To use Semaphore contracts and interfaces in your project,
install the [`@semaphore-protocol/contracts`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/contracts) NPM package.
:::

## SemaphoreVerifier.sol

`SemaphoreVerifier.sol` is an extended version of the Groth16 verifier generated by default with [SnarkJS](https://github.com/iden3/snarkjs). It contains a function for verifying proofs and a list of verification keys parameters.

Since the Semaphore circuit is compiled with a `MAX_DEPTH` range from 1 to 32 during the [trusted setup](/glossary#trusted-setup), the verifier must contain the parameters of the verification keys of each instance.

## SemaphoreGroups.sol

`SemaphoreGroups.sol` is an abstract contract which contains the functions required to create on-chain groups, and add/remove/update members. Each group is assigned an admin, which can be an Ethereum account or another contract.

This contract uses the [`LeanIMT.sol`](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/imt.sol/contracts/internal/InternalLeanIMT.sol) ZK-Kit library, an optimized binary incremental Merkle tree with [Poseidon](https://www.poseidon-hash.info).

## Semaphore.sol

`Semaphore.sol` inherits `SemaphoreGroups.sol` and adds functions to verify (`verifyProof`) or validate (`validateProof`) a Semaphore proof. The only constructor parameter is the `SemaphoreVerifier.sol` address, which must be deployed separately.

The `verifyProof` function contains code for checking whether a Semaphore proof is true or false. It is a read-only view function that in addition to verifying the proof also includes a mechanism for keeping track of proofs generated with old Merkle roots, i.e. group instances that contained fewer or different members.

The `validateProof` function first checks whether a proof with the same nullifier has already been validated, and then verifies the proof with the `verifyProof` function and saves the nullifier. This function also creates a log with the group id and the proof, which can then additionally be verified off-chain.

:::info
Semaphore contracts are deployed on the main testnets and Arbitrum One. See the [deployed contracts](/deployed-contracts) to check the addresses.
::::
