create-fhevm-example 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/contracts/advanced/BlindAuction.sol +22 -57
- package/contracts/advanced/EncryptedEscrow.sol +7 -31
- package/contracts/advanced/HiddenVoting.sol +19 -54
- package/contracts/advanced/PrivateKYC.sol +9 -33
- package/contracts/advanced/PrivatePayroll.sol +9 -35
- package/contracts/basic/decryption/PublicDecryptMultipleValues.sol +19 -21
- package/contracts/basic/decryption/PublicDecryptSingleValue.sol +19 -20
- package/contracts/basic/decryption/UserDecryptMultipleValues.sol +11 -21
- package/contracts/basic/decryption/UserDecryptSingleValue.sol +15 -30
- package/contracts/basic/encryption/EncryptMultipleValues.sol +16 -22
- package/contracts/basic/encryption/EncryptSingleValue.sol +15 -17
- package/contracts/basic/encryption/FHECounter.sol +19 -17
- package/contracts/basic/fhe-operations/FHEAdd.sol +14 -16
- package/contracts/basic/fhe-operations/FHEArithmetic.sol +19 -31
- package/contracts/basic/fhe-operations/FHEComparison.sol +12 -29
- package/contracts/basic/fhe-operations/FHEIfThenElse.sol +9 -10
- package/contracts/concepts/FHEAccessControl.sol +28 -28
- package/contracts/concepts/FHEAntiPatterns.sol +8 -37
- package/contracts/concepts/FHEHandles.sol +14 -29
- package/contracts/concepts/FHEInputProof.sol +13 -33
- package/contracts/gaming/EncryptedLottery.sol +11 -38
- package/contracts/gaming/EncryptedPoker.sol +8 -34
- package/contracts/gaming/RockPaperScissors.sol +43 -64
- package/contracts/openzeppelin/ERC7984.sol +6 -1
- package/contracts/openzeppelin/ERC7984ERC20Wrapper.sol +5 -1
- package/contracts/openzeppelin/SwapERC7984ToERC20.sol +5 -1
- package/contracts/openzeppelin/SwapERC7984ToERC7984.sol +5 -1
- package/contracts/openzeppelin/VestingWallet.sol +13 -17
- package/dist/scripts/commands/generate-config.js +18 -3
- package/dist/scripts/shared/config.d.ts.map +1 -1
- package/dist/scripts/shared/config.js +81 -75
- package/package.json +1 -1
|
@@ -12,19 +12,22 @@ import {
|
|
|
12
12
|
} from "@openzeppelin/confidential-contracts/interfaces/IERC7984.sol";
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* @notice
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* @notice Time-locked vesting wallet with fully encrypted token amounts.
|
|
16
|
+
* Implements linear vesting for ERC7984 confidential tokens. Vesting
|
|
17
|
+
* schedule, amounts, and release calculations all happen on encrypted
|
|
18
|
+
* values using FHE operations. Beneficiary can release vested tokens
|
|
19
|
+
* over time without revealing the total allocation or vesting progress
|
|
20
|
+
* to observers.
|
|
21
|
+
|
|
22
|
+
* @dev Timeline: |--START--|---VESTING---|--END--| (0% → linear → 100%)
|
|
23
|
+
* All vesting calculations performed on encrypted values using FHE.
|
|
24
|
+
* ⚡ Gas: FHE.div/mul operations are expensive (~200k gas each)
|
|
21
25
|
*/
|
|
22
26
|
contract VestingWalletExample is
|
|
23
27
|
Ownable,
|
|
24
28
|
ReentrancyGuardTransient,
|
|
25
29
|
ZamaEthereumConfig
|
|
26
30
|
{
|
|
27
|
-
// 🔐 Track released amounts per token (encrypted)
|
|
28
31
|
mapping(address token => euint128) private _tokenReleased;
|
|
29
32
|
uint64 private _start;
|
|
30
33
|
uint64 private _duration;
|
|
@@ -50,8 +53,6 @@ contract VestingWalletExample is
|
|
|
50
53
|
_duration = durationSeconds;
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
// ==================== VIEW FUNCTIONS ====================
|
|
54
|
-
|
|
55
56
|
function start() public view virtual returns (uint64) {
|
|
56
57
|
return _start;
|
|
57
58
|
}
|
|
@@ -77,9 +78,7 @@ contract VestingWalletExample is
|
|
|
77
78
|
euint128 vestedAmount_ = vestedAmount(token, uint48(block.timestamp));
|
|
78
79
|
euint128 releasedAmount = released(token);
|
|
79
80
|
|
|
80
|
-
//
|
|
81
|
-
// If vested >= released: return (vested - released)
|
|
82
|
-
// Else: return 0
|
|
81
|
+
// Encrypted comparison: if vested >= released → return difference, else 0
|
|
83
82
|
ebool canRelease = FHE.ge(vestedAmount_, releasedAmount);
|
|
84
83
|
return
|
|
85
84
|
FHE.select(
|
|
@@ -89,11 +88,10 @@ contract VestingWalletExample is
|
|
|
89
88
|
);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
/// @notice Release vested tokens to beneficiary
|
|
93
91
|
function release(address token) public virtual nonReentrant {
|
|
94
92
|
euint64 amount = releasable(token);
|
|
95
93
|
|
|
96
|
-
// Transfer encrypted amount
|
|
94
|
+
// Transfer encrypted amount using allowTransient (cheaper!)
|
|
97
95
|
FHE.allowTransient(amount, token);
|
|
98
96
|
euint64 amountSent = IERC7984(token).confidentialTransfer(
|
|
99
97
|
owner(),
|
|
@@ -122,8 +120,6 @@ contract VestingWalletExample is
|
|
|
122
120
|
return _vestingSchedule(totalAllocation, timestamp);
|
|
123
121
|
}
|
|
124
122
|
|
|
125
|
-
// ==================== INTERNAL ====================
|
|
126
|
-
|
|
127
123
|
/// @dev Linear vesting: (total * elapsed) / duration
|
|
128
124
|
function _vestingSchedule(
|
|
129
125
|
euint128 totalAllocation,
|
|
@@ -136,7 +132,7 @@ contract VestingWalletExample is
|
|
|
136
132
|
// After end: 100% vested
|
|
137
133
|
return totalAllocation;
|
|
138
134
|
} else {
|
|
139
|
-
//
|
|
135
|
+
// ⚡ Gas warning: FHE.mul + FHE.div cost ~400k gas combined!
|
|
140
136
|
return
|
|
141
137
|
FHE.div(
|
|
142
138
|
FHE.mul(totalAllocation, (timestamp - start())),
|
|
@@ -56,9 +56,24 @@ const OUTPUT_FILE = path.join(ROOT_DIR, "scripts/shared/config.ts");
|
|
|
56
56
|
// =============================================================================
|
|
57
57
|
function extractNotice(contractPath) {
|
|
58
58
|
const content = fs.readFileSync(contractPath, "utf-8");
|
|
59
|
-
|
|
59
|
+
// Match @notice and capture everything until @dev or end of comment block
|
|
60
|
+
const noticeRegex = /\/\*\*[\s\S]*?@notice\s+([\s\S]*?)(?:@dev|@param|\*\/)/;
|
|
60
61
|
const match = content.match(noticeRegex);
|
|
61
|
-
|
|
62
|
+
if (!match || !match[1]) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
// Clean up the extracted text:
|
|
66
|
+
// 1. Remove leading asterisks and whitespace from each line
|
|
67
|
+
// 2. Join lines with space
|
|
68
|
+
// 3. Collapse multiple spaces
|
|
69
|
+
const cleaned = match[1]
|
|
70
|
+
.split("\n")
|
|
71
|
+
.map((line) => line.replace(/^\s*\*\s?/, "").trim())
|
|
72
|
+
.filter((line) => line.length > 0)
|
|
73
|
+
.join(" ")
|
|
74
|
+
.replace(/\s+/g, " ")
|
|
75
|
+
.trim();
|
|
76
|
+
return cleaned || null;
|
|
62
77
|
}
|
|
63
78
|
function readExistingConfig() {
|
|
64
79
|
try {
|
|
@@ -160,7 +175,7 @@ function generateExamplesConfig(contracts) {
|
|
|
160
175
|
contract: "${c.contractPath}",
|
|
161
176
|
test: "${c.testPath}",${npmDepsField}${depsField}
|
|
162
177
|
description:
|
|
163
|
-
"${c.description}",
|
|
178
|
+
"${c.description.replace(/"/g, '\\"')}",
|
|
164
179
|
category: "${c.category}",
|
|
165
180
|
docsOutput: "${c.docsOutput}",
|
|
166
181
|
title: "${c.title}"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../scripts/shared/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAMD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../scripts/shared/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAMD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA6RlD,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAoJrD,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
|
@@ -19,253 +19,259 @@ exports.EXAMPLES = {
|
|
|
19
19
|
"blind-auction": {
|
|
20
20
|
contract: "contracts/advanced/BlindAuction.sol",
|
|
21
21
|
test: "test/advanced/BlindAuction.ts",
|
|
22
|
-
description: "Blind
|
|
22
|
+
description: "Blind auction where bids remain encrypted until the end. Bidders submit encrypted amounts. The contract finds the highest bid using FHE.gt and FHE.select without ever decrypting losing bids. Only the winning bid amount is revealed after the auction closes. Losing bids remain private forever, ensuring true bid confidentiality.",
|
|
23
23
|
category: "Advanced",
|
|
24
24
|
docsOutput: "docs/advanced/blind-auction.md",
|
|
25
|
-
title: "Blind Auction"
|
|
25
|
+
title: "Blind Auction"
|
|
26
26
|
},
|
|
27
27
|
"encrypted-escrow": {
|
|
28
28
|
contract: "contracts/advanced/EncryptedEscrow.sol",
|
|
29
29
|
test: "test/advanced/EncryptedEscrow.ts",
|
|
30
|
-
description: "
|
|
30
|
+
description: "Confidential escrow service with hidden transaction amounts. Buyer and seller agree on encrypted escrow amount. Funds are held securely until conditions are met. Amount remains hidden from public view until release or refund. Includes arbiter for dispute resolution. Perfect for high-value transactions requiring privacy.",
|
|
31
31
|
category: "Advanced",
|
|
32
32
|
docsOutput: "docs/advanced/encrypted-escrow.md",
|
|
33
|
-
title: "Encrypted Escrow"
|
|
33
|
+
title: "Encrypted Escrow"
|
|
34
34
|
},
|
|
35
35
|
"hidden-voting": {
|
|
36
36
|
contract: "contracts/advanced/HiddenVoting.sol",
|
|
37
37
|
test: "test/advanced/HiddenVoting.ts",
|
|
38
|
-
description: "
|
|
38
|
+
description: "Private voting system with homomorphic vote tallying. Voters submit encrypted ballots (Yes/No). Votes are tallied using homomorphic addition WITHOUT decrypting individual ballots. Only the final tally is revealed - individual votes remain private forever. Perfect for DAO governance, elections, or any scenario requiring ballot secrecy.",
|
|
39
39
|
category: "Advanced",
|
|
40
40
|
docsOutput: "docs/advanced/hidden-voting.md",
|
|
41
|
-
title: "Hidden Voting"
|
|
41
|
+
title: "Hidden Voting"
|
|
42
42
|
},
|
|
43
43
|
"private-kyc": {
|
|
44
44
|
contract: "contracts/advanced/PrivateKYC.sol",
|
|
45
45
|
test: "test/advanced/PrivateKYC.ts",
|
|
46
|
-
description: "
|
|
46
|
+
description: "Privacy-preserving identity verification using predicate proofs. Users submit encrypted personal data (age, country, credit score). Contract can verify predicates like \"Is user 18+?\" or \"Good credit?\" without learning the actual values. Returns encrypted booleans that prove compliance without revealing sensitive information. Revolutionary for KYC/AML compliance while preserving user privacy.",
|
|
47
47
|
category: "Advanced",
|
|
48
48
|
docsOutput: "docs/advanced/private-kyc.md",
|
|
49
|
-
title: "Private KYC"
|
|
49
|
+
title: "Private KYC"
|
|
50
50
|
},
|
|
51
51
|
"private-payroll": {
|
|
52
52
|
contract: "contracts/advanced/PrivatePayroll.sol",
|
|
53
53
|
test: "test/advanced/PrivatePayroll.ts",
|
|
54
|
-
description: "
|
|
54
|
+
description: "Confidential payroll system with encrypted salaries. Employers can add employees with encrypted salary amounts. Each employee can decrypt only their own salary - other salaries remain hidden. Demonstrates selective decryption permissions where different users see different encrypted values. Perfect for privacy-preserving HR systems.",
|
|
55
55
|
category: "Advanced",
|
|
56
56
|
docsOutput: "docs/advanced/private-payroll.md",
|
|
57
|
-
title: "Private Payroll"
|
|
57
|
+
title: "Private Payroll"
|
|
58
58
|
},
|
|
59
59
|
"public-decrypt-multiple-values": {
|
|
60
60
|
contract: "contracts/basic/decryption/PublicDecryptMultipleValues.sol",
|
|
61
61
|
test: "test/basic/decryption/PublicDecryptMultipleValues.ts",
|
|
62
|
-
description: "
|
|
62
|
+
description: "Highest die roll game with public decryption of multiple values. Two players roll encrypted 8-sided dice, results are made publicly decryptable. Demonstrates handling multiple encrypted values in checkSignatures() where ORDER MATTERS - the cts[] array must match the order of values in the ABI-encoded result.",
|
|
63
63
|
category: "Basic - Decryption",
|
|
64
64
|
docsOutput: "docs/basic/decryption/public-decrypt-multiple-values.md",
|
|
65
|
-
title: "Public Decrypt Multiple Values"
|
|
65
|
+
title: "Public Decrypt Multiple Values"
|
|
66
66
|
},
|
|
67
67
|
"public-decrypt-single-value": {
|
|
68
68
|
contract: "contracts/basic/decryption/PublicDecryptSingleValue.sol",
|
|
69
69
|
test: "test/basic/decryption/PublicDecryptSingleValue.ts",
|
|
70
|
-
description: "
|
|
70
|
+
description: "Heads or Tails game with public, permissionless decryption. Demonstrates makePubliclyDecryptable() which allows ANYONE to decrypt the result (not just allowed users). Perfect for public game results, lottery winners, or voting tallies. Uses FHE.randEbool() for fair randomness and KMS-verified decryption proofs.",
|
|
71
71
|
category: "Basic - Decryption",
|
|
72
72
|
docsOutput: "docs/basic/decryption/public-decrypt-single-value.md",
|
|
73
|
-
title: "Public Decrypt Single Value"
|
|
73
|
+
title: "Public Decrypt Single Value"
|
|
74
74
|
},
|
|
75
75
|
"user-decrypt-multiple-values": {
|
|
76
76
|
contract: "contracts/basic/decryption/UserDecryptMultipleValues.sol",
|
|
77
77
|
test: "test/basic/decryption/UserDecryptMultipleValues.ts",
|
|
78
|
-
description: "
|
|
78
|
+
description: "Decrypting multiple encrypted values of different types for a user. Shows how to handle ebool, euint32, and euint64 in one contract. Each value requires individual permission grants - there's no batching for permissions (unlike input proofs). Demonstrates the pattern of granting allowThis() for each value separately.",
|
|
79
79
|
category: "Basic - Decryption",
|
|
80
80
|
docsOutput: "docs/basic/decryption/user-decrypt-multiple-values.md",
|
|
81
|
-
title: "User Decrypt Multiple Values"
|
|
81
|
+
title: "User Decrypt Multiple Values"
|
|
82
82
|
},
|
|
83
83
|
"user-decrypt-single-value": {
|
|
84
84
|
contract: "contracts/basic/decryption/UserDecryptSingleValue.sol",
|
|
85
85
|
test: "test/basic/decryption/UserDecryptSingleValue.ts",
|
|
86
|
-
description: "Demonstrates the
|
|
86
|
+
description: "User-controlled decryption with proper permission management. Demonstrates the critical two-step permission pattern: allowThis() grants the contract permission to store/compute, while allow() grants the user permission to decrypt. Missing either step causes decryption to fail. Includes examples of both correct and incorrect patterns.",
|
|
87
87
|
category: "Basic - Decryption",
|
|
88
88
|
docsOutput: "docs/basic/decryption/user-decrypt-single-value.md",
|
|
89
|
-
title: "User Decrypt Single Value"
|
|
89
|
+
title: "User Decrypt Single Value"
|
|
90
90
|
},
|
|
91
91
|
"encrypt-multiple-values": {
|
|
92
92
|
contract: "contracts/basic/encryption/EncryptMultipleValues.sol",
|
|
93
93
|
test: "test/basic/encryption/EncryptMultipleValues.ts",
|
|
94
|
-
description: "
|
|
94
|
+
description: "Efficient handling of multiple encrypted values in one transaction. Demonstrates batched input validation where a single proof covers multiple encrypted values (ebool, euint32, eaddress), saving ~50k gas per additional value compared to separate proofs.",
|
|
95
95
|
category: "Basic - Encryption",
|
|
96
96
|
docsOutput: "docs/basic/encryption/encrypt-multiple-values.md",
|
|
97
|
-
title: "Encrypt Multiple Values"
|
|
97
|
+
title: "Encrypt Multiple Values"
|
|
98
98
|
},
|
|
99
99
|
"encrypt-single-value": {
|
|
100
100
|
contract: "contracts/basic/encryption/EncryptSingleValue.sol",
|
|
101
101
|
test: "test/basic/encryption/EncryptSingleValue.ts",
|
|
102
|
-
description: "
|
|
102
|
+
description: "Single value encryption with proof validation. Shows how to receive encrypted data from users, validate proofs, and grant proper permissions. Includes examples of common mistakes and the correct permission pattern (allowThis + allow).",
|
|
103
103
|
category: "Basic - Encryption",
|
|
104
104
|
docsOutput: "docs/basic/encryption/encrypt-single-value.md",
|
|
105
|
-
title: "Encrypt Single Value"
|
|
105
|
+
title: "Encrypt Single Value"
|
|
106
106
|
},
|
|
107
107
|
"fhe-counter": {
|
|
108
108
|
contract: "contracts/basic/encryption/FHECounter.sol",
|
|
109
109
|
test: "test/basic/encryption/FHECounter.ts",
|
|
110
|
-
description: "Confidential counter
|
|
110
|
+
description: "Confidential counter with encrypted increment/decrement operations. Demonstrates the complete FHE workflow: encryption, computation, and permission management. The counter value remains private, only accessible through decryption by authorized users.",
|
|
111
111
|
category: "Basic - Encryption",
|
|
112
112
|
docsOutput: "docs/basic/encryption/fhe-counter.md",
|
|
113
|
-
title: "FHE Counter"
|
|
113
|
+
title: "FHE Counter"
|
|
114
114
|
},
|
|
115
115
|
"fhe-add": {
|
|
116
116
|
contract: "contracts/basic/fhe-operations/FHEAdd.sol",
|
|
117
117
|
test: "test/basic/fhe-operations/FHEAdd.ts",
|
|
118
|
-
description: "
|
|
118
|
+
description: "Introduction to homomorphic addition on encrypted values. Demonstrates the most fundamental FHE operation: adding two encrypted numbers without decrypting them. Shows the complete flow from receiving encrypted inputs, performing the addition, and granting permissions for both contract storage and user decryption.",
|
|
119
119
|
category: "Basic - FHE Operations",
|
|
120
120
|
docsOutput: "docs/basic/fhe-operations/fhe-add.md",
|
|
121
|
-
title: "FHE Add"
|
|
121
|
+
title: "FHE Add"
|
|
122
122
|
},
|
|
123
123
|
"fhe-arithmetic": {
|
|
124
124
|
contract: "contracts/basic/fhe-operations/FHEArithmetic.sol",
|
|
125
125
|
test: "test/basic/fhe-operations/FHEArithmetic.ts",
|
|
126
|
-
description: "
|
|
126
|
+
description: "Complete suite of FHE arithmetic operations on encrypted values. Covers all basic math: addition, subtraction, multiplication, division, remainder (modulo), minimum, and maximum. Includes gas cost comparisons and important limitations (e.g., division/remainder only work with plaintext divisors, not encrypted divisors).",
|
|
127
127
|
category: "Basic - FHE Operations",
|
|
128
128
|
docsOutput: "docs/basic/fhe-operations/fhe-arithmetic.md",
|
|
129
|
-
title: "FHE Arithmetic"
|
|
129
|
+
title: "FHE Arithmetic"
|
|
130
130
|
},
|
|
131
131
|
"fhe-comparison": {
|
|
132
132
|
contract: "contracts/basic/fhe-operations/FHEComparison.sol",
|
|
133
133
|
test: "test/basic/fhe-operations/FHEComparison.ts",
|
|
134
|
-
description: "
|
|
134
|
+
description: "Complete guide to encrypted comparisons and conditional selection. Covers all comparison operators (eq, ne, gt, lt, ge, le) that return encrypted booleans (ebool), and demonstrates FHE.select for branching without information leakage. Critical for implementing logic like \"find maximum\" or \"check threshold\" without revealing values.",
|
|
135
135
|
category: "Basic - FHE Operations",
|
|
136
136
|
docsOutput: "docs/basic/fhe-operations/fhe-comparison.md",
|
|
137
|
-
title: "FHE Comparison"
|
|
137
|
+
title: "FHE Comparison"
|
|
138
138
|
},
|
|
139
139
|
"fhe-if-then-else": {
|
|
140
140
|
contract: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
|
|
141
141
|
test: "test/basic/fhe-operations/FHEIfThenElse.ts",
|
|
142
|
-
description: "Demonstrates
|
|
142
|
+
description: "Conditional logic without information leakage using FHE.select. Demonstrates how to implement if-then-else logic on encrypted values (computing max of two numbers). Using regular if/else would decrypt and leak which branch was taken. FHE.select evaluates BOTH branches and picks one based on the encrypted condition, preserving privacy.",
|
|
143
143
|
category: "Basic - FHE Operations",
|
|
144
144
|
docsOutput: "docs/basic/fhe-operations/fhe-if-then-else.md",
|
|
145
|
-
title: "FHE If Then Else"
|
|
145
|
+
title: "FHE If Then Else"
|
|
146
146
|
},
|
|
147
147
|
"fhe-access-control": {
|
|
148
148
|
contract: "contracts/concepts/FHEAccessControl.sol",
|
|
149
149
|
test: "test/concepts/FHEAccessControl.ts",
|
|
150
|
-
description: "
|
|
150
|
+
description: "Master class for FHE permission patterns and access control. Explains the three permission types: allow() for permanent access, allowThis() for contract operations, and allowTransient() for temporary cross-contract calls. Includes correct and incorrect usage examples to prevent common decryption failures.",
|
|
151
151
|
category: "Concepts",
|
|
152
152
|
docsOutput: "docs/concepts/fhe-access-control.md",
|
|
153
|
-
title: "FHE Access Control"
|
|
153
|
+
title: "FHE Access Control"
|
|
154
154
|
},
|
|
155
155
|
"fhe-anti-patterns": {
|
|
156
156
|
contract: "contracts/concepts/FHEAntiPatterns.sol",
|
|
157
157
|
test: "test/concepts/FHEAntiPatterns.ts",
|
|
158
|
-
description: "
|
|
158
|
+
description: "Comprehensive guide to FHE anti-patterns and their solutions. Covers 9 critical mistakes: using if/else on encrypted values, incorrect permission patterns, require() statements that leak info, unbounded loops, noise accumulation, and deprecated APIs. Each pattern shows both ❌ WRONG and ✅ CORRECT implementations.",
|
|
159
159
|
category: "Concepts",
|
|
160
160
|
docsOutput: "docs/concepts/fhe-anti-patterns.md",
|
|
161
|
-
title: "FHE Anti Patterns"
|
|
161
|
+
title: "FHE Anti Patterns"
|
|
162
162
|
},
|
|
163
163
|
"fhe-handles": {
|
|
164
164
|
contract: "contracts/concepts/FHEHandles.sol",
|
|
165
165
|
test: "test/concepts/FHEHandles.ts",
|
|
166
|
-
description: "
|
|
166
|
+
description: "Deep dive into FHE handles: what they are and how they work. Explains that handles are uint256 pointers to encrypted data, demonstrates three creation methods (fromExternal, asEuint, operations), and emphasizes immutability - every operation creates a NEW handle. Includes gas cost comparisons for different operations.",
|
|
167
167
|
category: "Concepts",
|
|
168
168
|
docsOutput: "docs/concepts/fhe-handles.md",
|
|
169
|
-
title: "FHE Handles"
|
|
169
|
+
title: "FHE Handles"
|
|
170
170
|
},
|
|
171
171
|
"fhe-input-proof": {
|
|
172
172
|
contract: "contracts/concepts/FHEInputProof.sol",
|
|
173
173
|
test: "test/concepts/FHEInputProof.ts",
|
|
174
|
-
description: "
|
|
174
|
+
description: "Input proof validation and batching strategies in FHEVM. Explains why proofs are essential (prevent garbage data, wrong types, and replay attacks) and demonstrates the gas-efficient batching pattern where one proof validates multiple encrypted inputs, saving ~50k gas per additional value.",
|
|
175
175
|
category: "Concepts",
|
|
176
176
|
docsOutput: "docs/concepts/fhe-input-proof.md",
|
|
177
|
-
title: "FHE Input Proof"
|
|
177
|
+
title: "FHE Input Proof"
|
|
178
178
|
},
|
|
179
179
|
"encrypted-lottery": {
|
|
180
180
|
contract: "contracts/gaming/EncryptedLottery.sol",
|
|
181
181
|
test: "test/gaming/EncryptedLottery.ts",
|
|
182
|
-
description: "
|
|
182
|
+
description: "Provably fair lottery with encrypted ticket numbers. Players buy tickets with encrypted numbers. Winning number is generated using FHE randomness. Winner is determined by comparing encrypted values without revealing losing tickets. Ensures fairness and privacy - no one can see ticket numbers before the draw.",
|
|
183
183
|
category: "Gaming",
|
|
184
184
|
docsOutput: "docs/gaming/encrypted-lottery.md",
|
|
185
|
-
title: "Encrypted Lottery"
|
|
185
|
+
title: "Encrypted Lottery"
|
|
186
186
|
},
|
|
187
187
|
"encrypted-poker": {
|
|
188
188
|
contract: "contracts/gaming/EncryptedPoker.sol",
|
|
189
189
|
test: "test/gaming/EncryptedPoker.ts",
|
|
190
|
-
description: "
|
|
190
|
+
description: "On-chain Texas Hold'em poker with encrypted hole cards. Two players receive encrypted hole cards that remain hidden throughout the game. Hand strength is computed using FHE operations. Winner is determined by comparing encrypted hand strengths. Demonstrates complex game logic with multiple encrypted states and conditional operations.",
|
|
191
191
|
category: "Gaming",
|
|
192
192
|
docsOutput: "docs/gaming/encrypted-poker.md",
|
|
193
|
-
title: "Encrypted Poker"
|
|
193
|
+
title: "Encrypted Poker"
|
|
194
194
|
},
|
|
195
195
|
"rock-paper-scissors": {
|
|
196
196
|
contract: "contracts/gaming/RockPaperScissors.sol",
|
|
197
197
|
test: "test/gaming/RockPaperScissors.ts",
|
|
198
|
-
description: "Rock-Paper-Scissors game with encrypted moves -
|
|
198
|
+
description: "Fair Rock-Paper-Scissors game with encrypted moves. Players submit encrypted moves (0=Rock, 1=Paper, 2=Scissors) ensuring neither player can see the other's choice before committing. Winner is determined using FHE operations and revealed publicly. No trusted third party needed - cryptography guarantees fairness.",
|
|
199
199
|
category: "Gaming",
|
|
200
200
|
docsOutput: "docs/gaming/rock-paper-scissors.md",
|
|
201
|
-
title: "Rock Paper Scissors"
|
|
201
|
+
title: "Rock Paper Scissors"
|
|
202
202
|
},
|
|
203
|
-
erc7984: {
|
|
203
|
+
"erc7984": {
|
|
204
204
|
contract: "contracts/openzeppelin/ERC7984.sol",
|
|
205
205
|
test: "test/openzeppelin/ERC7984.ts",
|
|
206
206
|
npmDependencies: {
|
|
207
207
|
"@openzeppelin/contracts": "^5.4.0",
|
|
208
|
-
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
208
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
209
209
|
},
|
|
210
|
-
description: "Confidential token using OpenZeppelin's ERC7984 standard",
|
|
210
|
+
description: "Confidential ERC20-compatible token using OpenZeppelin's ERC7984 standard. Implements a fully private token where balances and transfer amounts are encrypted. Compatible with standard ERC20 interfaces but with FHE under the hood. Supports both visible minting (owner knows amount) and confidential minting (fully private). Foundation for building private DeFi applications.",
|
|
211
211
|
category: "Openzeppelin",
|
|
212
212
|
docsOutput: "docs/openzeppelin/erc7984.md",
|
|
213
|
-
title: "ERC7984"
|
|
213
|
+
title: "ERC7984"
|
|
214
214
|
},
|
|
215
215
|
"erc7984-erc20-wrapper": {
|
|
216
216
|
contract: "contracts/openzeppelin/ERC7984ERC20Wrapper.sol",
|
|
217
217
|
test: "test/openzeppelin/ERC7984ERC20Wrapper.ts",
|
|
218
218
|
npmDependencies: {
|
|
219
219
|
"@openzeppelin/contracts": "^5.4.0",
|
|
220
|
-
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
220
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
221
221
|
},
|
|
222
|
-
dependencies: [
|
|
223
|
-
|
|
222
|
+
dependencies: [
|
|
223
|
+
"contracts/openzeppelin/mocks/ERC20Mock.sol"
|
|
224
|
+
],
|
|
225
|
+
description: "Bridge between public ERC20 and confidential ERC7984 tokens. Allows users to wrap regular ERC20 tokens into privacy-preserving ERC7984 tokens (public → private) and unwrap them back (private → public). Wrapping is instant, unwrapping requires decryption proof from KMS. Essential for bringing existing tokens into the confidential ecosystem.",
|
|
224
226
|
category: "Openzeppelin",
|
|
225
227
|
docsOutput: "docs/openzeppelin/erc7984-erc20-wrapper.md",
|
|
226
|
-
title: "ERC7984 ERC20 Wrapper"
|
|
228
|
+
title: "ERC7984 ERC20 Wrapper"
|
|
227
229
|
},
|
|
228
230
|
"swap-erc7984-to-erc20": {
|
|
229
231
|
contract: "contracts/openzeppelin/SwapERC7984ToERC20.sol",
|
|
230
232
|
test: "test/openzeppelin/SwapERC7984ToERC20.ts",
|
|
231
233
|
npmDependencies: {
|
|
232
234
|
"@openzeppelin/contracts": "^5.4.0",
|
|
233
|
-
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
235
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
234
236
|
},
|
|
235
237
|
dependencies: [
|
|
236
238
|
"contracts/openzeppelin/mocks/ERC20Mock.sol",
|
|
237
|
-
"contracts/openzeppelin/ERC7984.sol"
|
|
239
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
238
240
|
],
|
|
239
|
-
description: "
|
|
241
|
+
description: "Atomic swap from confidential ERC7984 to public ERC20 tokens. Two-step process: (1) Initiate swap with encrypted amount, request decryption from KMS. (2) Finalize swap with decryption proof, receive ERC20 tokens. Demonstrates the FHEVM v0.9 public decryption flow with makePubliclyDecryptable() and checkSignatures() for trustless swaps.",
|
|
240
242
|
category: "Openzeppelin",
|
|
241
243
|
docsOutput: "docs/openzeppelin/swap-erc7984-to-erc20.md",
|
|
242
|
-
title: "Swap ERC7984 To ERC20"
|
|
244
|
+
title: "Swap ERC7984 To ERC20"
|
|
243
245
|
},
|
|
244
246
|
"swap-erc7984-to-erc7984": {
|
|
245
247
|
contract: "contracts/openzeppelin/SwapERC7984ToERC7984.sol",
|
|
246
248
|
test: "test/openzeppelin/SwapERC7984ToERC7984.ts",
|
|
247
249
|
npmDependencies: {
|
|
248
|
-
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
250
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
249
251
|
},
|
|
250
|
-
dependencies: [
|
|
251
|
-
|
|
252
|
+
dependencies: [
|
|
253
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
254
|
+
],
|
|
255
|
+
description: "Fully private atomic swap between two confidential ERC7984 tokens. Both input and output amounts remain encrypted throughout the entire swap process. No decryption needed - amounts stay private from start to finish. Perfect for confidential DEX operations where trade sizes must remain hidden. The ultimate privacy-preserving token exchange.",
|
|
252
256
|
category: "Openzeppelin",
|
|
253
257
|
docsOutput: "docs/openzeppelin/swap-erc7984-to-erc7984.md",
|
|
254
|
-
title: "Swap ERC7984 To ERC7984"
|
|
258
|
+
title: "Swap ERC7984 To ERC7984"
|
|
255
259
|
},
|
|
256
260
|
"vesting-wallet": {
|
|
257
261
|
contract: "contracts/openzeppelin/VestingWallet.sol",
|
|
258
262
|
test: "test/openzeppelin/VestingWallet.ts",
|
|
259
263
|
npmDependencies: {
|
|
260
264
|
"@openzeppelin/contracts": "^5.4.0",
|
|
261
|
-
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
265
|
+
"@openzeppelin/confidential-contracts": "^0.3.0"
|
|
262
266
|
},
|
|
263
|
-
dependencies: [
|
|
264
|
-
|
|
267
|
+
dependencies: [
|
|
268
|
+
"contracts/openzeppelin/ERC7984.sol"
|
|
269
|
+
],
|
|
270
|
+
description: "Time-locked vesting wallet with fully encrypted token amounts. Implements linear vesting for ERC7984 confidential tokens. Vesting schedule, amounts, and release calculations all happen on encrypted values using FHE operations. Beneficiary can release vested tokens over time without revealing the total allocation or vesting progress to observers.",
|
|
265
271
|
category: "Openzeppelin",
|
|
266
272
|
docsOutput: "docs/openzeppelin/vesting-wallet.md",
|
|
267
|
-
title: "Vesting Wallet"
|
|
268
|
-
}
|
|
273
|
+
title: "Vesting Wallet"
|
|
274
|
+
}
|
|
269
275
|
};
|
|
270
276
|
// =============================================================================
|
|
271
277
|
// Category Configurations
|
|
@@ -293,7 +299,7 @@ exports.CATEGORIES = {
|
|
|
293
299
|
{
|
|
294
300
|
sol: "contracts/advanced/PrivatePayroll.sol",
|
|
295
301
|
test: "test/advanced/PrivatePayroll.ts",
|
|
296
|
-
}
|
|
302
|
+
}
|
|
297
303
|
],
|
|
298
304
|
},
|
|
299
305
|
basicdecryption: {
|
|
@@ -314,7 +320,7 @@ exports.CATEGORIES = {
|
|
|
314
320
|
{
|
|
315
321
|
sol: "contracts/basic/decryption/UserDecryptSingleValue.sol",
|
|
316
322
|
test: "test/basic/decryption/UserDecryptSingleValue.ts",
|
|
317
|
-
}
|
|
323
|
+
}
|
|
318
324
|
],
|
|
319
325
|
},
|
|
320
326
|
basicencryption: {
|
|
@@ -331,7 +337,7 @@ exports.CATEGORIES = {
|
|
|
331
337
|
{
|
|
332
338
|
sol: "contracts/basic/encryption/FHECounter.sol",
|
|
333
339
|
test: "test/basic/encryption/FHECounter.ts",
|
|
334
|
-
}
|
|
340
|
+
}
|
|
335
341
|
],
|
|
336
342
|
},
|
|
337
343
|
basicfheoperations: {
|
|
@@ -352,7 +358,7 @@ exports.CATEGORIES = {
|
|
|
352
358
|
{
|
|
353
359
|
sol: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
|
|
354
360
|
test: "test/basic/fhe-operations/FHEIfThenElse.ts",
|
|
355
|
-
}
|
|
361
|
+
}
|
|
356
362
|
],
|
|
357
363
|
},
|
|
358
364
|
concepts: {
|
|
@@ -373,7 +379,7 @@ exports.CATEGORIES = {
|
|
|
373
379
|
{
|
|
374
380
|
sol: "contracts/concepts/FHEInputProof.sol",
|
|
375
381
|
test: "test/concepts/FHEInputProof.ts",
|
|
376
|
-
}
|
|
382
|
+
}
|
|
377
383
|
],
|
|
378
384
|
},
|
|
379
385
|
gaming: {
|
|
@@ -390,7 +396,7 @@ exports.CATEGORIES = {
|
|
|
390
396
|
{
|
|
391
397
|
sol: "contracts/gaming/RockPaperScissors.sol",
|
|
392
398
|
test: "test/gaming/RockPaperScissors.ts",
|
|
393
|
-
}
|
|
399
|
+
}
|
|
394
400
|
],
|
|
395
401
|
},
|
|
396
402
|
openzeppelin: {
|
|
@@ -415,9 +421,9 @@ exports.CATEGORIES = {
|
|
|
415
421
|
{
|
|
416
422
|
sol: "contracts/openzeppelin/VestingWallet.sol",
|
|
417
423
|
test: "test/openzeppelin/VestingWallet.ts",
|
|
418
|
-
}
|
|
424
|
+
}
|
|
419
425
|
],
|
|
420
|
-
}
|
|
426
|
+
}
|
|
421
427
|
};
|
|
422
428
|
// =============================================================================
|
|
423
429
|
// Helper Functions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-fhevm-example",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "Create FHEVM example projects with a single command - A comprehensive toolkit for building privacy-preserving smart contracts",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-fhevm-example": "./dist/scripts/index.js"
|