|
2 | 2 |
|
3 | 3 | This is an example dApp made with React.js to let users do transfers of a `ConfidentialERC20` token on fhEVM. It contains also a button to request the decryption of an encrypted secret value. |
4 | 4 |
|
5 | | -## How to use this repo |
6 | 5 |
|
7 | | -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). |
| 6 | +## Examples featured |
8 | 7 |
|
9 | | -### How to deploy on Sepolia |
| 8 | +### Confidential Counter |
10 | 9 |
|
11 | | -First, before launching the React app, you must deploy the `ConfidentialERC20` smart contract and mint the first few tokens. |
12 | | -To do this, go to the `hardhat/` directory, and follow all the instructions from the [`README`](/hardhat/README.md) there to deploy and mint the first tokens with Alice's account, i.e until you are able to run the following command: |
| 10 | +The Confidential Counter examples demonstrate progressively more complex uses of FHE operations: |
13 | 11 |
|
14 | | -``` |
15 | | -npm run deploy-sepolia |
16 | | -``` |
| 12 | +1. **Basic Counter (Sample 1)** |
| 13 | + - Simple encrypted counter using `euint8` type |
| 14 | + - Basic increment operation using FHE addition |
| 15 | + - Demonstrates minimal FHE setup and operations |
17 | 16 |
|
18 | | -> **Note:** Be careful to use your own private mnemonic key in this case, in the `.env` file (do not reuse the public values from `.env.example`!). |
| 17 | +2. **Input Counter (Sample 2)** |
| 18 | + - Accepts encrypted input values to increment by |
| 19 | + - Shows how to handle encrypted inputs with proofs |
| 20 | + - Demonstrates converting between encrypted types |
19 | 21 |
|
20 | | -After you succesfully run the Sepolia deployment script, go to the `frontend/` directory, and just run those two commands: |
| 22 | +3. **Decryptable Counter (Sample 3)** |
| 23 | + - Adds decryption capability via Gateway integration |
| 24 | + - Shows how to request and handle decryption callbacks |
| 25 | + - Maintains both encrypted and decrypted state |
21 | 26 |
|
22 | | -``` |
23 | | -npm install |
24 | | -npm run dev |
25 | | -``` |
| 27 | +4. **Multi-User Counter (Sample 4)** |
| 28 | + - Individual encrypted counters per user address |
| 29 | + - Demonstrates access control with FHE |
| 30 | + - Shows re-encryption for specific users |
| 31 | + - Uses mapping for multiple encrypted values |
26 | 32 |
|
27 | | -This will launch the front-end of the dApp from a local Vite server, which will be available at the following URL: [`http://localhost:4173/`](http://localhost:4173/) . You can connect to the dApp with a Web3 wallet such as Metamask and start transferring tokens, reencrypt and read your balance, or request the decryption of the encrypted secret on Sepolia. |
| 33 | +Each sample builds on the previous one to showcase different FHE capabilities while maintaining security and privacy of the counter values. |
28 | 34 |
|
29 | | -### How to use in Mocked mode |
| 35 | +### GuessRandomNumberGame |
30 | 36 |
|
31 | | -First go to the `hardhat/` directory : define a new `.env` file - in mocked mode, simply doing a copy `cp .env.example .env` is doable, but you can also you your own private mnemonic - then install all packages with |
32 | | -`npm i`. Now you can launch the hardhat local node with: |
| 37 | +**How the Game Works** |
33 | 38 |
|
| 39 | +1. **Random Target Generation**: Contract generates an encrypted random number within `MAX_VALUE` range using TFHE. |
| 40 | + |
| 41 | +2. **Player Participation**: Players submit encrypted guesses with ZK proofs. One guess per address per round. |
| 42 | + |
| 43 | +3. **Minimum Players**: Game requires `MIN_PLAYERS` submissions before proceeding. |
| 44 | + |
| 45 | +4. **Winner Determination**: Uses FHE operations to privately find the closest guess to target while maintaining confidentiality. |
| 46 | + |
| 47 | +5. **Decryption & Results**: Target, winning guess, and winner's address are securely decrypted via Zama Gateway. Results announced through `WinnerDeclared` event. |
| 48 | + |
| 49 | +6. **Game Reset**: Automatically clears state, generates new target, and prepares for next round. |
| 50 | + |
| 51 | +The game showcases FHE capabilities for secure random number generation, private comparisons, and controlled decryption while maintaining player privacy throughout. |
| 52 | + |
| 53 | +### FHEWordle |
| 54 | + |
| 55 | +**How the Game Works** |
| 56 | + |
| 57 | +1. **Game Setup**: A factory contract deploys unique game instances for each player using minimal proxies. Each game has: |
| 58 | + - An encrypted target word (represented as encrypted letter indices 0-25) |
| 59 | + - A player address who can submit guesses |
| 60 | + - A relayer address who helps with FHE operations |
| 61 | + |
| 62 | +2. **Word Submission**: The relayer submits the encrypted target word letters using `submitWord1`. The letters are stored as encrypted uint8 values. |
| 63 | + |
| 64 | +3. **Player Guessing**: Players submit guesses by calling `guessWord1` with: |
| 65 | + - A word encoded as a uint32 (each letter as index 0-25) |
| 66 | + - A Merkle proof verifying the word is valid |
| 67 | + - Limited to 5 guesses total |
| 68 | + |
| 69 | +4. **Guess Feedback**: After each guess, players can request feedback via `getGuess` which returns: |
| 70 | + - An encrypted equality mask showing exact letter matches (green) |
| 71 | + - An encrypted letter presence mask showing letters in wrong positions (yellow) |
| 72 | + |
| 73 | +5. **Winning**: Players can claim victory using `claimWin` if they get all letters correct. The contract verifies this using FHE operations. |
| 74 | + |
| 75 | +6. **Word Revelation**: After game completion, the target word can be revealed using `revealWordAndStore`. |
| 76 | + |
| 77 | +7. **Proof Verification**: The relayer can verify game outcomes using Merkle proofs via `checkProof`. |
| 78 | + |
| 79 | +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. |
| 80 | + |
| 81 | + |
| 82 | +### Decentralized Identity |
| 83 | + |
| 84 | +**How it works** |
| 85 | + |
| 86 | +1. **Identity Management**: The system consists of four main contracts: |
| 87 | + - `IdMapping`: Maps user addresses to unique IDs for identity tracking |
| 88 | + - `PassportID`: Stores encrypted passport/identity data like name, birthdate |
| 89 | + - `Diploma`: Manages encrypted educational credentials and degrees |
| 90 | + - `EmployerClaim`: Generates verifiable claims about age and education |
| 91 | + |
| 92 | +2. **Identity Registration**: |
| 93 | + - Users first get a unique ID from `IdMapping` via `generateId()` |
| 94 | + - Authorized registrars can register encrypted passport data using `PassportID.registerIdentity()` |
| 95 | + - Educational institutions can register encrypted diploma data via `Diploma.registerDiploma()` |
| 96 | + |
| 97 | +3. **Encrypted Data Storage**: All sensitive data is stored encrypted using FHE: |
| 98 | + - Names, birthdates, and biometric data in `PassportID` |
| 99 | + - University, degree type, and grades in `Diploma` |
| 100 | + - Access controlled through TFHE permissions |
| 101 | + |
| 102 | +4. **Claim Generation**: |
| 103 | + - Users can generate verifiable claims about their identity/credentials |
| 104 | + - `EmployerClaim` supports two types of claims: |
| 105 | + - Adult verification (18+ age check) |
| 106 | + - Degree verification (specific degree requirements) |
| 107 | + - Claims preserve privacy by using encrypted comparisons |
| 108 | + |
| 109 | +5. **Verification Process**: |
| 110 | + - Claims are generated as encrypted boolean results |
| 111 | + - Employers can verify claims without seeing actual data |
| 112 | + - Combined verification checks both age and education requirements |
| 113 | + - Results stored as encrypted verification status |
| 114 | + |
| 115 | +The system leverages FHE operations to enable privacy-preserving identity and credential verification without exposing sensitive personal data. |
| 116 | + |
| 117 | +### MyConfidentialERC20.sol |
| 118 | + |
| 119 | +**How it works** |
| 120 | + |
| 121 | +1. **Confidential Token**: A privacy-preserving ERC20 token implementation using Fully Homomorphic Encryption (FHE): |
| 122 | + - Balances and allowances are stored as encrypted values |
| 123 | + - Transfers and approvals operate on encrypted data |
| 124 | + - Inherits from ConfidentialERC20Mintable for basic token functionality |
| 125 | + |
| 126 | +2. **Key Features**: |
| 127 | + - Encrypted balances using euint64 type |
| 128 | + - Standard ERC20 functions (transfer, approve, etc.) with FHE |
| 129 | + - Minting capability restricted to owner |
| 130 | + - Built-in decryption request/callback mechanism |
| 131 | + |
| 132 | +3. **Secret Value Demo**: |
| 133 | + - Contains an encrypted SECRET value (set to 42) |
| 134 | + - Demonstrates Gateway decryption flow: |
| 135 | + - requestSecret() initiates decryption request |
| 136 | + - callbackSecret() receives and stores decrypted value |
| 137 | + - Shows basic FHE operations and Gateway integration |
| 138 | + |
| 139 | +4. **Privacy Protection**: |
| 140 | + - All token balances and transfers are encrypted |
| 141 | + - Only transaction participants can view their own balances |
| 142 | + - Uses TFHE library for homomorphic operations |
| 143 | + - Integrates with Zama's FHE infrastructure |
| 144 | + |
| 145 | +The contract showcases how to implement confidential tokens while maintaining ERC20 compatibility and leveraging FHE for privacy preservation. |
| 146 | + |
| 147 | + |
| 148 | + |
| 149 | +## How to use this repo |
| 150 | + |
| 151 | +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). |
| 152 | + |
| 153 | +### Sepolia Testnet Deployment |
| 154 | +1. Deploy the contract: |
| 155 | +```bash |
| 156 | +cd hardhat/ |
| 157 | +cp .env.example .env # Or use custom mnemonic |
| 158 | +npm install |
| 159 | +npm run test # to check if everything works as it should |
| 160 | +npm run deploy-sepolia |
34 | 161 | ``` |
35 | | -npx hardhat node |
36 | | -``` |
| 162 | +> **Note:** Use your own private mnemonic in `.env` |
37 | 163 |
|
38 | | -This will also launch a mocked instance of the coprocessor. |
| 164 | +2. Launch frontend: |
| 165 | +```bash |
| 166 | +cd frontend/ |
| 167 | +cp .env.example .env # Or use custom mnemonic |
| 168 | +npm install |
| 169 | +npm run dev |
| 170 | +``` |
39 | 171 |
|
40 | | -You can then go to the `frontend/` directory, and just run those two commands: |
| 172 | +Access at [`http://localhost:4173/`](http://localhost:4173/) |
41 | 173 |
|
| 174 | +### Local Development (Mocked Mode) |
| 175 | +1. Setup local node: |
| 176 | +```bash |
| 177 | +cd hardhat/ |
| 178 | +cp .env.example .env # Or use custom mnemonic |
| 179 | +npm install |
| 180 | +npx hardhat node |
42 | 181 | ``` |
| 182 | + |
| 183 | +2. Launch frontend: |
| 184 | +```bash |
| 185 | +cd frontend/ |
| 186 | +cp .env.example .env # Or use custom mnemonic |
43 | 187 | npm install |
44 | 188 | npm run dev-mocked |
45 | 189 | ``` |
46 | 190 |
|
47 | | -The dApp will be available again at: [`http://localhost:4173/`](http://localhost:4173/) . You can connect to the dApp with a Web3 wallet such as Metamask and start transferring tokens, reencrypt and read your balance, or request the decryption of the encrypted. This time, the only difference is that it will ask you to connect to the Hardhat network instead of Sepolia, so make sure to have added the Hardhat network to your Metamask wallet in order to be able to use the dApp with the mocked coprocessor. You can find instructions to configure Metamask adequatly [here](https://support.chainstack.com/hc/en-us/articles/4408642503449-Using-MetaMask-with-a-Hardhat-node). |
| 191 | +Access at [`http://localhost:4173/`](http://localhost:4173/) |
48 | 192 |
|
49 | 193 | #### Troubleshooting |
50 | 194 |
|
51 | | -**_Invalid nonce errors:_** This is a common issue everytime you restart your local Hardhat node and you want to reuse the same accounts in Metamask. You should remember to reset the nonce of the accounts you used the last time with Hardhat. To reset the account's transaction history and the nonce, open Metamask and select the Hardhat network, click on your account followed by `Settings -> Advanced -> Clear activity tab data`. |
| 195 | +**_Invalid nonce errors:_** |
| 196 | +For invalid nonce errors after restarting Hardhat node: |
| 197 | +1. Open Metamask |
| 198 | +2. Select Hardhat network |
| 199 | +3. Go to `Settings` -> `Advanced` -> `Clear activity tab data` |
| 200 | + |
0 commit comments