This repository contains example dApps built using fhEVM (Fully Homomorphic EVM). Each example demonstrates different aspects of building privacy-preserving smart contracts using FHE operations.
The Confidential Counter examples demonstrate progressively more complex uses of FHE operations through four samples:
- Basic Counter: Simple encrypted counter with basic increment operations
- Input Counter: Handles encrypted inputs with proofs and type conversions
- Decryptable Counter: Adds decryption capabilities and state management
- Multi-User Counter: Supports per-user encrypted counters with access control
Each sample builds on the previous one to showcase different FHE capabilities.
How the Game Works
-
Random Target Generation: Contract generates an encrypted random number within
MAX_VALUE
range using TFHE. -
Player Participation: Players submit encrypted guesses with ZK proofs. One guess per address per round.
-
Minimum Players: Game requires
MIN_PLAYERS
submissions before proceeding. -
Winner Determination: Uses FHE operations to privately find the closest guess to target while maintaining confidentiality.
-
Decryption & Results: Target, winning guess, and winner's address are securely decrypted via Zama Gateway. Results announced through
WinnerDeclared
event. -
Game Reset: Automatically clears state, generates new target, and prepares for next round.
The game showcases FHE capabilities for secure random number generation, private comparisons, and controlled decryption while maintaining player privacy throughout.
How the Game Works
-
Game Setup: A factory contract deploys unique game instances for each player using minimal proxies. Each game has:
- An encrypted target word (represented as encrypted letter indices 0-25)
- A player address who can submit guesses
- A relayer address who helps with FHE operations
-
Word Submission: The relayer submits the encrypted target word letters using
submitWord1
. The letters are stored as encrypted uint8 values. -
Player Guessing: Players submit guesses by calling
guessWord1
with:- A word encoded as a uint32 (each letter as index 0-25)
- A Merkle proof verifying the word is valid
- Limited to 5 guesses total
-
Guess Feedback: After each guess, players can request feedback via
getGuess
which returns:- An encrypted equality mask showing exact letter matches (green)
- An encrypted letter presence mask showing letters in wrong positions (yellow)
-
Winning: Players can claim victory using
claimWin
if they get all letters correct. The contract verifies this using FHE operations. -
Word Revelation: After game completion, the target word can be revealed using
revealWordAndStore
. -
Proof Verification: The relayer can verify game outcomes using Merkle proofs via
checkProof
.
The game leverages FHE operations to keep the target word encrypted while still allowing comparison with guesses. This prevents players from seeing the word until the game is complete.
How it works
-
Identity Management: The system consists of four main contracts:
IdMapping
: Maps user addresses to unique IDs for identity trackingPassportID
: Stores encrypted passport/identity data like name, birthdateDiploma
: Manages encrypted educational credentials and degreesEmployerClaim
: Generates verifiable claims about age and education
-
Identity Registration:
- Users first get a unique ID from
IdMapping
viagenerateId()
- Authorized registrars can register encrypted passport data using
PassportID.registerIdentity()
- Educational institutions can register encrypted diploma data via
Diploma.registerDiploma()
- Users first get a unique ID from
-
Encrypted Data Storage: All sensitive data is stored encrypted using FHE:
- Names, birthdates, and biometric data in
PassportID
- University, degree type, and grades in
Diploma
- Access controlled through TFHE permissions
- Names, birthdates, and biometric data in
-
Claim Generation:
- Users can generate verifiable claims about their identity/credentials
EmployerClaim
supports two types of claims:- Adult verification (18+ age check)
- Degree verification (specific degree requirements)
- Claims preserve privacy by using encrypted comparisons
-
Verification Process:
- Claims are generated as encrypted boolean results
- Employers can verify claims without seeing actual data
- Combined verification checks both age and education requirements
- Results stored as encrypted verification status
The system leverages FHE operations to enable privacy-preserving identity and credential verification without exposing sensitive personal data.
How it works
-
Confidential Token: A privacy-preserving ERC20 token using FHE with encrypted balances, transfers and approvals.
-
Key Features: Encrypted balances (euint64), standard ERC20 functions with FHE, and owner-restricted minting.
-
Privacy Protection: All operations are encrypted using TFHE, with balances visible only to transaction participants.
The contract implements confidential tokens with ERC20 compatibility using FHE for privacy.
You can either deploy the dApp on the real fhEVM coprocessor on the Ethereum Sepolia testnet, or on a local Hardhat node (i.e a mocked corpocessor).
- Deploy the contract:
cd hardhat/
cp .env.example .env # Or use custom mnemonic
npm install
npm run test # to check if everything works as it should
npm run deploy-sepolia
Note: Use your own private mnemonic in
.env
- Launch frontend:
cd frontend/
cp .env.example .env # Or use custom mnemonic
npm install
npm run dev
Access at http://localhost:4173/
- Setup local node:
cd hardhat/
cp .env.example .env # Or use custom mnemonic
npm install
npx hardhat node
- Launch frontend:
cd frontend/
cp .env.example .env # Or use custom mnemonic
npm install
npm run dev-mocked
Access at http://localhost:4173/
Invalid nonce errors: For invalid nonce errors after restarting Hardhat node:
- Open Metamask
- Select Hardhat network
- Go to
Settings
->Advanced
->Clear activity tab data