Description
High Level Specs
Initialization
sequenceDiagram
participant Shutter Key Broadcast Contract
participant Shutter Keypers
Shutter Keypers->>Shutter Keypers: Keyper Set becomes active
Shutter Keypers->>Shutter Keypers: Generate new Eon key
Shutter Keypers->>Shutter Key Broadcast Contract: Broadcast Eon public key
During a dispute
sequenceDiagram
%% Participants
participant Voter as Juror
participant Bot as Reveal Bot<br>(anyone)
participant ShutterSDK as Shutter SDK
participant Shutter as Shutter Network
participant Contract as ShutterDisputeKit
%% --- Vote Commitment Phase ---
Note over Voter,Contract: Voting session opens
Voter->>Shutter: register_identity(decryptionTimestamp)
Shutter-->>Voter: {identity, eon_key}
Voter->>Voter: generate random salt
Voter->>ShutterSDK: encrypt(message: {choice, justification, salt}, identity, eon_key)
ShutterSDK-->>Voter: {encryptedVote}
Voter->>Voter: commitHash = keccak256(choice, justification, salt)
Voter->>Contract: castCommit(voteIDs, commitHash, identity, encryptedVote)
Contract-->>Contract: emits CommitCast(voter, voteIDs, commitHash, identity, encryptedVote)
%% --- Vote Reveal Phase (after delay) ---
Note over Voter,Contract: Voting session ends, Shutter Network releases decryption key
Bot->>Contract: query CommitCast event({voter})
Contract-->>Bot: CommitCast event(voter, voteIDs, commitHash, identity, encryptedVote)
Bot->>ShutterSDK: decrypt(encryptedVote, identity)
ShutterSDK->>Shutter: get_decryption_key(identity)
Shutter-->>ShutterSDK: decryption_key
ShutterSDK-->>Bot: {choice, justification, salt}
Bot->>Contract: castVote(voteIDs, choice, salt, justification)
Contract-->>Contract: verify vote hash against commitHash
Contract-->>Contract: emits VoteCast(voteIDs, voter, choice, justification, salt)
The disputeID and roundID are omitted for clarity.
Considerations
- Allow the encrypted vote and justification to be submitted along with the committment and emit the enrypted value as an Event so it can be picked up by the Keypers
- Add a function batchCastVote that is callable by anyone (i.e. no check against msg.sender) and thereby allows third parties to submit decrypted vote batches on behalf of the users.
- There could be a fee incentive for the third party to offset the transaction costs (deposited by jurors in castCommit, excess can be refunded).
- Possible solution for the not commited to justification:
Jurors EC-Recoverable sign the justification which allows verifivation of the sender.
Reference
Shutter JS library
Shutter JS example use by Snapshot
Default commit/reveal implementation