@0xflydev/labz 1.0.22 → 1.0.23
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/package.json +1 -1
- package/templates/buildable/projects/counter/test/Counter.test.ts.tmpl +47 -53
- package/templates/buildable/projects/prediction-market/test/PredictionMarket.test.ts.tmpl +10 -6
- package/templates/buildable/projects/voting/contracts/Voting.sol.tmpl +5 -5
- package/templates/buildable/projects/auction/deploy/deploy.ts.tmpl +0 -38
- package/templates/buildable/projects/token/deploy/deploy.ts.tmpl +0 -32
- package/templates/buildable/projects/voting/deploy/deploy.ts.tmpl +0 -28
package/package.json
CHANGED
|
@@ -1,71 +1,65 @@
|
|
|
1
1
|
import { expect } from "chai";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
2
|
+
import { ethers, fhevm } from "hardhat";
|
|
3
|
+
import { FhevmType } from "@fhevm/hardhat-plugin";
|
|
4
|
+
import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
|
|
4
5
|
|
|
5
6
|
describe("{{CONTRACT_NAME}}", function () {
|
|
6
7
|
let contract: any;
|
|
7
8
|
let contractAddress: string;
|
|
8
|
-
let
|
|
9
|
-
let signers: any[];
|
|
9
|
+
let signers: HardhatEthersSigner[];
|
|
10
10
|
|
|
11
11
|
before(async function () {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
signers = await ethers.getSigners();
|
|
13
|
+
});
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
const Factory = await
|
|
15
|
+
beforeEach(async function () {
|
|
16
|
+
const Factory = await ethers.getContractFactory("{{CONTRACT_NAME}}");
|
|
17
17
|
contract = await Factory.deploy();
|
|
18
18
|
await contract.waitForDeployment();
|
|
19
19
|
contractAddress = await contract.getAddress();
|
|
20
|
-
|
|
21
|
-
// Create FHEVM instance
|
|
22
|
-
fhevm = await createInstance({
|
|
23
|
-
networkUrl: hre.network.config.url || "http://localhost:8545",
|
|
24
|
-
gatewayUrl: "http://localhost:7077",
|
|
25
|
-
});
|
|
26
20
|
});
|
|
27
21
|
|
|
28
22
|
describe("Increment", function () {
|
|
29
23
|
it("should increment the counter with encrypted value", async function () {
|
|
30
24
|
const [signer] = signers;
|
|
31
|
-
|
|
32
|
-
// Encrypt the value to add
|
|
33
25
|
const valueToAdd = 5;
|
|
34
|
-
const encrypted = await fhevm.encrypt32(valueToAdd);
|
|
35
26
|
|
|
36
|
-
//
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
// Create encrypted input using hardhat plugin
|
|
28
|
+
const encryptedInput = await fhevm
|
|
29
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
30
|
+
.add32(valueToAdd)
|
|
31
|
+
.encrypt();
|
|
32
|
+
|
|
33
|
+
// Call increment with encrypted value and proof
|
|
34
|
+
const tx = await contract
|
|
35
|
+
.connect(signer)
|
|
36
|
+
.increment(encryptedInput.handles[0], encryptedInput.inputProof);
|
|
41
37
|
await tx.wait();
|
|
42
38
|
|
|
43
39
|
// Get the encrypted count
|
|
44
40
|
const encryptedCount = await contract.getCount();
|
|
45
|
-
|
|
46
|
-
// Request decryption (in real scenario, would use gateway)
|
|
47
|
-
expect(encryptedCount).to.not.equal(0n);
|
|
41
|
+
expect(encryptedCount).to.not.equal(ethers.ZeroHash);
|
|
48
42
|
});
|
|
49
43
|
|
|
50
44
|
it("should allow multiple increments", async function () {
|
|
51
45
|
const [signer] = signers;
|
|
52
46
|
|
|
53
47
|
// First increment
|
|
54
|
-
const encrypted1 = await fhevm
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
48
|
+
const encrypted1 = await fhevm
|
|
49
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
50
|
+
.add32(10)
|
|
51
|
+
.encrypt();
|
|
52
|
+
await contract.connect(signer).increment(encrypted1.handles[0], encrypted1.inputProof);
|
|
59
53
|
|
|
60
54
|
// Second increment
|
|
61
|
-
const encrypted2 = await fhevm
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
);
|
|
55
|
+
const encrypted2 = await fhevm
|
|
56
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
57
|
+
.add32(20)
|
|
58
|
+
.encrypt();
|
|
59
|
+
await contract.connect(signer).increment(encrypted2.handles[0], encrypted2.inputProof);
|
|
66
60
|
|
|
67
61
|
const encryptedCount = await contract.getCount();
|
|
68
|
-
expect(encryptedCount).to.not.equal(
|
|
62
|
+
expect(encryptedCount).to.not.equal(ethers.ZeroHash);
|
|
69
63
|
});
|
|
70
64
|
});
|
|
71
65
|
|
|
@@ -74,21 +68,21 @@ describe("{{CONTRACT_NAME}}", function () {
|
|
|
74
68
|
const [signer] = signers;
|
|
75
69
|
|
|
76
70
|
// First add some value
|
|
77
|
-
const addValue = await fhevm
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
);
|
|
71
|
+
const addValue = await fhevm
|
|
72
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
73
|
+
.add32(100)
|
|
74
|
+
.encrypt();
|
|
75
|
+
await contract.connect(signer).increment(addValue.handles[0], addValue.inputProof);
|
|
82
76
|
|
|
83
77
|
// Then decrement
|
|
84
|
-
const subValue = await fhevm
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
78
|
+
const subValue = await fhevm
|
|
79
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
80
|
+
.add32(30)
|
|
81
|
+
.encrypt();
|
|
82
|
+
await contract.connect(signer).decrement(subValue.handles[0], subValue.inputProof);
|
|
89
83
|
|
|
90
84
|
const encryptedCount = await contract.getCount();
|
|
91
|
-
expect(encryptedCount).to.not.equal(
|
|
85
|
+
expect(encryptedCount).to.not.equal(ethers.ZeroHash);
|
|
92
86
|
});
|
|
93
87
|
});
|
|
94
88
|
|
|
@@ -96,15 +90,15 @@ describe("{{CONTRACT_NAME}}", function () {
|
|
|
96
90
|
it("should grant access to caller after increment", async function () {
|
|
97
91
|
const [signer] = signers;
|
|
98
92
|
|
|
99
|
-
const encrypted = await fhevm
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
);
|
|
93
|
+
const encrypted = await fhevm
|
|
94
|
+
.createEncryptedInput(contractAddress, signer.address)
|
|
95
|
+
.add32(1)
|
|
96
|
+
.encrypt();
|
|
97
|
+
await contract.connect(signer).increment(encrypted.handles[0], encrypted.inputProof);
|
|
104
98
|
|
|
105
99
|
// Caller should be able to get the count
|
|
106
100
|
const count = await contract.connect(signer).getCount();
|
|
107
|
-
expect(count).to.not.equal(
|
|
101
|
+
expect(count).to.not.equal(ethers.ZeroHash);
|
|
108
102
|
});
|
|
109
103
|
});
|
|
110
104
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { expect } from "chai";
|
|
2
2
|
import { ethers } from "hardhat";
|
|
3
|
+
import { time } from "@nomicfoundation/hardhat-network-helpers";
|
|
3
4
|
import { {{CONTRACT_NAME}} } from "../typechain-types";
|
|
4
5
|
import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
|
|
5
6
|
|
|
@@ -72,13 +73,15 @@ describe("{{CONTRACT_NAME}}", function () {
|
|
|
72
73
|
let deadline: number;
|
|
73
74
|
|
|
74
75
|
beforeEach(async function () {
|
|
75
|
-
|
|
76
|
+
// Get current block timestamp and add 60 seconds
|
|
77
|
+
const block = await ethers.provider.getBlock("latest");
|
|
78
|
+
deadline = block!.timestamp + 60;
|
|
76
79
|
const tx = await market.createMarket("Test question?", deadline);
|
|
77
80
|
await tx.wait();
|
|
78
81
|
marketId = 0;
|
|
79
82
|
|
|
80
|
-
//
|
|
81
|
-
await
|
|
83
|
+
// Advance blockchain time past deadline
|
|
84
|
+
await time.increaseTo(deadline + 1);
|
|
82
85
|
});
|
|
83
86
|
|
|
84
87
|
it("Should allow oracle to resolve market", async function () {
|
|
@@ -140,11 +143,12 @@ describe("{{CONTRACT_NAME}}", function () {
|
|
|
140
143
|
it("Should handle complete market lifecycle", async function () {
|
|
141
144
|
// 1. Create market
|
|
142
145
|
const question = "Will BTC hit $100k?";
|
|
143
|
-
const
|
|
146
|
+
const block = await ethers.provider.getBlock("latest");
|
|
147
|
+
const deadline = block!.timestamp + 60;
|
|
144
148
|
await market.createMarket(question, deadline);
|
|
145
149
|
|
|
146
|
-
// 2.
|
|
147
|
-
await
|
|
150
|
+
// 2. Advance time past deadline
|
|
151
|
+
await time.increaseTo(deadline + 1);
|
|
148
152
|
|
|
149
153
|
// 3. Resolve market
|
|
150
154
|
await market.resolveMarket(0, true);
|
|
@@ -80,8 +80,8 @@ contract {{CONTRACT_NAME}} is {{INHERITS}} {
|
|
|
80
80
|
Proposal storage proposal = _proposals[proposalId];
|
|
81
81
|
proposal.description = description;
|
|
82
82
|
proposal.endTime = block.timestamp + durationSeconds;
|
|
83
|
-
proposal.yesVotes = FHE.
|
|
84
|
-
proposal.noVotes = FHE.
|
|
83
|
+
proposal.yesVotes = FHE.asEuint32(0);
|
|
84
|
+
proposal.noVotes = FHE.asEuint32(0);
|
|
85
85
|
proposal.exists = true;
|
|
86
86
|
|
|
87
87
|
// Set ACL for vote counts
|
|
@@ -118,13 +118,13 @@ contract {{CONTRACT_NAME}} is {{INHERITS}} {
|
|
|
118
118
|
[[VOTE_TYPE]] eVote = FHE.fromExternal(encryptedVote, inputProof);
|
|
119
119
|
|
|
120
120
|
// Encrypted vote: if vote > 0, it's a yes vote
|
|
121
|
-
ebool isYes = FHE.gt(eVote, FHE.
|
|
121
|
+
ebool isYes = FHE.gt(eVote, FHE.asEuint32(0));
|
|
122
122
|
|
|
123
123
|
// Homomorphic conditional addition
|
|
124
124
|
// yesVotes += isYes ? 1 : 0
|
|
125
125
|
// noVotes += isYes ? 0 : 1
|
|
126
|
-
[[VOTE_TYPE]] one = FHE.
|
|
127
|
-
[[VOTE_TYPE]] zero = FHE.
|
|
126
|
+
[[VOTE_TYPE]] one = FHE.asEuint32(1);
|
|
127
|
+
[[VOTE_TYPE]] zero = FHE.asEuint32(0);
|
|
128
128
|
|
|
129
129
|
proposal.yesVotes = FHE.add(proposal.yesVotes, FHE.select(isYes, one, zero));
|
|
130
130
|
proposal.noVotes = FHE.add(proposal.noVotes, FHE.select(isYes, zero, one));
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { ethers } from "hardhat";
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
const itemDescription = "Rare Digital Collectible";
|
|
5
|
-
const durationSeconds = 86400; // 1 day
|
|
6
|
-
|
|
7
|
-
console.log("Deploying {{CONTRACT_NAME}}...");
|
|
8
|
-
console.log(" Item:", itemDescription);
|
|
9
|
-
console.log(" Duration:", durationSeconds / 3600, "hours");
|
|
10
|
-
|
|
11
|
-
const AuctionFactory = await ethers.getContractFactory("{{CONTRACT_NAME}}");
|
|
12
|
-
const auction = await AuctionFactory.deploy(itemDescription, durationSeconds);
|
|
13
|
-
|
|
14
|
-
await auction.waitForDeployment();
|
|
15
|
-
|
|
16
|
-
const address = await auction.getAddress();
|
|
17
|
-
console.log("\n{{CONTRACT_NAME}} deployed to:", address);
|
|
18
|
-
|
|
19
|
-
console.log("\nAuction Lifecycle:");
|
|
20
|
-
console.log(" 1. Bid: bid(encryptedAmount, inputProof)");
|
|
21
|
-
console.log(" - Bids are encrypted and sealed");
|
|
22
|
-
console.log(" - No one can see competitors' bids");
|
|
23
|
-
console.log(" 2. Wait: Auction runs until endTime");
|
|
24
|
-
console.log(" 3. Request Reveal: requestWinnerReveal()");
|
|
25
|
-
console.log(" - Marks winner for decryption");
|
|
26
|
-
console.log(" 4. Finalize: finalizeWinner(winnerAddress, winningBid, proof)");
|
|
27
|
-
console.log(" - Verifies decryption proof");
|
|
28
|
-
console.log(" - Announces winner");
|
|
29
|
-
console.log("\nPrivacy Guarantees:");
|
|
30
|
-
console.log(" - Bids encrypted until reveal");
|
|
31
|
-
console.log(" - Losing bids never disclosed");
|
|
32
|
-
console.log(" - Fair competition guaranteed");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
main().catch((error) => {
|
|
36
|
-
console.error(error);
|
|
37
|
-
process.exitCode = 1;
|
|
38
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ethers } from "hardhat";
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
const tokenName = "Confidential Token";
|
|
5
|
-
const tokenSymbol = "CFHE";
|
|
6
|
-
|
|
7
|
-
console.log("Deploying {{CONTRACT_NAME}}...");
|
|
8
|
-
console.log(" Name:", tokenName);
|
|
9
|
-
console.log(" Symbol:", tokenSymbol);
|
|
10
|
-
|
|
11
|
-
const TokenFactory = await ethers.getContractFactory("{{CONTRACT_NAME}}");
|
|
12
|
-
const token = await TokenFactory.deploy(tokenName, tokenSymbol);
|
|
13
|
-
|
|
14
|
-
await token.waitForDeployment();
|
|
15
|
-
|
|
16
|
-
const address = await token.getAddress();
|
|
17
|
-
console.log("\n{{CONTRACT_NAME}} deployed to:", address);
|
|
18
|
-
|
|
19
|
-
console.log("\nToken Operations:");
|
|
20
|
-
console.log(" - mint(to, encryptedAmount): Mint tokens (owner only)");
|
|
21
|
-
console.log(" - transfer(to, encryptedAmount): Transfer tokens");
|
|
22
|
-
console.log(" - balanceOf(account): Get encrypted balance handle");
|
|
23
|
-
console.log("\nPrivacy Guarantees:");
|
|
24
|
-
console.log(" - Balances are encrypted");
|
|
25
|
-
console.log(" - Transfer amounts are private");
|
|
26
|
-
console.log(" - Only balance owner can decrypt");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
main().catch((error) => {
|
|
30
|
-
console.error(error);
|
|
31
|
-
process.exitCode = 1;
|
|
32
|
-
});
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ethers } from "hardhat";
|
|
2
|
-
|
|
3
|
-
async function main() {
|
|
4
|
-
console.log("Deploying {{CONTRACT_NAME}}...");
|
|
5
|
-
|
|
6
|
-
const VotingFactory = await ethers.getContractFactory("{{CONTRACT_NAME}}");
|
|
7
|
-
const voting = await VotingFactory.deploy();
|
|
8
|
-
|
|
9
|
-
await voting.waitForDeployment();
|
|
10
|
-
|
|
11
|
-
const address = await voting.getAddress();
|
|
12
|
-
console.log("\n{{CONTRACT_NAME}} deployed to:", address);
|
|
13
|
-
|
|
14
|
-
console.log("\nVoting Operations:");
|
|
15
|
-
console.log(" - createProposal(title, description, duration): Create proposal");
|
|
16
|
-
console.log(" - vote(proposalId, encryptedVote): Cast encrypted vote");
|
|
17
|
-
console.log(" - requestTally(proposalId): Request vote count reveal");
|
|
18
|
-
console.log(" - finalizeTally(proposalId, yesVotes, noVotes, proof): Finalize");
|
|
19
|
-
console.log("\nPrivacy Guarantees:");
|
|
20
|
-
console.log(" - Individual votes are encrypted");
|
|
21
|
-
console.log(" - Only final tally is revealed");
|
|
22
|
-
console.log(" - No one knows how you voted");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
main().catch((error) => {
|
|
26
|
-
console.error(error);
|
|
27
|
-
process.exitCode = 1;
|
|
28
|
-
});
|