1
1
import { createPublicClient , createWalletClient , http , Hex , getContract } from "viem" ;
2
- import { privateKeyToAccount } from "viem/accounts" ;
2
+ import { mnemonicToAccount } from "viem/accounts" ;
3
3
import { hardhat } from "viem/chains" ;
4
4
import { encrypt , decrypt , DECRYPTION_DELAY } from "./shutter" ;
5
5
import { abi as DisputeKitShutterPoCAbi } from "../deployments/localhost/DisputeKitShutterPoC.json" ;
@@ -9,35 +9,35 @@ import crypto from "crypto";
9
9
const SEPARATOR = "␟" ; // U+241F
10
10
11
11
// Store encrypted votes for later decryption
12
- interface EncryptedVote {
12
+ type EncryptedVote = {
13
13
encryptedCommitment : string ;
14
14
identity : Hex ;
15
15
timestamp : number ;
16
- voteId : bigint ;
16
+ voteIDs : bigint [ ] ;
17
17
salt : Hex ;
18
- }
18
+ } ;
19
19
20
20
const encryptedVotes : EncryptedVote [ ] = [ ] ;
21
21
22
- const PRIVATE_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 " as const ;
22
+ const disputeKitAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3 " as const ;
23
23
24
- const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" as const ;
24
+ const MNEMONIC = "test test test test test test test test test test test junk" ;
25
+ const account = mnemonicToAccount ( MNEMONIC ) ;
25
26
26
27
const transport = http ( ) ;
27
28
const publicClient = createPublicClient ( {
28
29
chain : hardhat ,
29
30
transport,
30
31
} ) ;
31
32
32
- const account = privateKeyToAccount ( PRIVATE_KEY ) ;
33
33
const walletClient = createWalletClient ( {
34
34
account,
35
35
chain : hardhat ,
36
36
transport,
37
37
} ) ;
38
38
39
39
const disputeKit = getContract ( {
40
- address : CONTRACT_ADDRESS ,
40
+ address : disputeKitAddress ,
41
41
abi : DisputeKitShutterPoCAbi ,
42
42
client : { public : publicClient , wallet : walletClient } ,
43
43
} ) ;
@@ -49,6 +49,41 @@ function generateSalt(): Hex {
49
49
return ( "0x" + crypto . randomBytes ( 32 ) . toString ( "hex" ) ) as Hex ;
50
50
}
51
51
52
+ /**
53
+ * Encodes vote parameters into a message string with separators
54
+ */
55
+ function encode ( {
56
+ coreDisputeID,
57
+ voteIDs,
58
+ choice,
59
+ justification,
60
+ salt,
61
+ } : {
62
+ coreDisputeID : bigint ;
63
+ voteIDs : bigint [ ] ;
64
+ choice : bigint ;
65
+ justification : string ;
66
+ salt : Hex ;
67
+ } ) : string {
68
+ return `${ coreDisputeID } ${ SEPARATOR } ${ voteIDs . join ( "," ) } ${ SEPARATOR } ${ choice } ${ SEPARATOR } ${ justification } ${ SEPARATOR } ${ salt } ` ;
69
+ }
70
+
71
+ /**
72
+ * Decodes a message string into its component parts
73
+ * @param message The message to decode
74
+ * @returns Object containing the decoded components
75
+ */
76
+ function decode ( message : string ) {
77
+ const [ coreDisputeID , voteIDsStr , choice , justification , salt ] = message . split ( SEPARATOR ) ;
78
+ return {
79
+ coreDisputeID,
80
+ voteIDs : voteIDsStr . split ( "," ) . map ( ( id ) => BigInt ( id ) ) ,
81
+ choice,
82
+ justification,
83
+ salt,
84
+ } ;
85
+ }
86
+
52
87
/**
53
88
* Cast a commit on-chain
54
89
*/
@@ -64,15 +99,23 @@ async function castCommit({
64
99
justification : string ;
65
100
} ) {
66
101
try {
67
- // Create message with U+241F separator
68
- const message = `${ coreDisputeID } ${ SEPARATOR } ${ voteIDs [ 0 ] } ${ SEPARATOR } ${ choice } ${ SEPARATOR } ${ justification } ` ;
102
+ // Generate salt first
103
+ const salt = generateSalt ( ) ;
104
+
105
+ // Encode the vote parameters into a message
106
+ const message = encode ( {
107
+ coreDisputeID,
108
+ voteIDs,
109
+ choice,
110
+ justification,
111
+ salt,
112
+ } ) ;
69
113
70
114
// Encrypt the message using shutter.ts
71
115
const { encryptedCommitment, identity } = await encrypt ( message ) ;
72
116
73
- // Generate salt and compute hash
74
- const salt = generateSalt ( ) ;
75
- const commitHash = await disputeKit . read . hashVote ( [ coreDisputeID , voteIDs [ 0 ] , choice , justification , salt ] ) ;
117
+ // Compute hash using all vote IDs
118
+ const commitHash = await disputeKit . read . hashVote ( [ coreDisputeID , voteIDs , choice , justification , salt ] ) ;
76
119
77
120
// Cast the commit on-chain
78
121
const txHash = await disputeKit . write . castCommit ( [ coreDisputeID , voteIDs , commitHash , identity as Hex ] ) ;
@@ -89,7 +132,7 @@ async function castCommit({
89
132
encryptedCommitment,
90
133
identity : identity as Hex ,
91
134
timestamp : Math . floor ( Date . now ( ) / 1000 ) ,
92
- voteId : voteIDs [ 0 ] ,
135
+ voteIDs,
93
136
salt,
94
137
} ) ;
95
138
@@ -116,16 +159,16 @@ export async function autoVote() {
116
159
// Attempt to decrypt the vote
117
160
const decryptedMessage = await decrypt ( vote . encryptedCommitment , vote . identity ) ;
118
161
119
- // Parse the decrypted message
120
- const [ coreDisputeID , , choice , justification ] = decryptedMessage . split ( SEPARATOR ) ;
162
+ // Decode the decrypted message
163
+ const { coreDisputeID, voteIDs , choice, justification, salt } = decode ( decryptedMessage ) ;
121
164
122
165
// Cast the vote on-chain
123
166
const txHash = await disputeKit . write . castVote ( [
124
167
BigInt ( coreDisputeID ) ,
125
- [ vote . voteId ] ,
168
+ voteIDs ,
126
169
BigInt ( choice ) ,
127
170
justification ,
128
- vote . salt ,
171
+ salt ,
129
172
] ) ;
130
173
131
174
// Wait for transaction to be mined
@@ -139,7 +182,7 @@ export async function autoVote() {
139
182
const index = encryptedVotes . indexOf ( vote ) ;
140
183
if ( index > - 1 ) encryptedVotes . splice ( index , 1 ) ;
141
184
} catch ( error ) {
142
- console . error ( `Error processing vote ${ vote . voteId } :` , error ) ;
185
+ console . error ( `Error processing vote ${ vote . voteIDs . join ( "," ) } :` , error ) ;
143
186
}
144
187
}
145
188
@@ -158,9 +201,9 @@ async function main() {
158
201
try {
159
202
// Cast an encrypted commit
160
203
await castCommit ( {
161
- coreDisputeID : BigInt ( 0 ) ,
162
- voteIDs : [ BigInt ( 0 ) ] ,
163
- choice : BigInt ( 2 ) ,
204
+ coreDisputeID : 0n ,
205
+ voteIDs : [ 0n , 1n , 2n ] ,
206
+ choice : 2n ,
164
207
justification : "This is my vote justification" ,
165
208
} ) ;
166
209
0 commit comments