Skip to content

This Clarity smart contract implements a cryptographically secure, privacy-preserving voting system on the Stacks blockchain. It enables organizations, communities, and DAOs to conduct transparent polls while maintaining voter privacy during the voting process through a commitment-reveal cryptographic scheme.

Notifications You must be signed in to change notification settings

pascalineaugustine/Privacy-Preserving-Voting

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

Privacy-Preserving Voting Smart Contract

A Clarity smart contract implementing anonymous voting through a commitment-reveal scheme on the Stacks blockchain.

Overview

This contract enables privacy-preserving polls where voters commit to their choices cryptographically before revealing them, preventing vote manipulation and maintaining anonymity during the voting process.

Key Features

🔒 Privacy Protection

  • Commit-Reveal Scheme: Two-phase voting prevents vote observation during commit phase
  • Cryptographic Commitments: SHA-256 hashing with salt prevents vote tampering
  • Anonymous Voting: Vote choices hidden until reveal phase begins

🗳️ Three-Phase Voting Process

  1. Registration Phase: Voters register for specific polls
  2. Commit Phase: Voters submit hashed votes (commitment)
  3. Reveal Phase: Voters prove their votes with salt verification

🛡️ Security Features

  • Input validation for all user data
  • Double-voting prevention
  • Time-locked phases using block heights
  • Registered voters only
  • Emergency shutdown capability

Contract Functions

Public Functions

create-poll

Creates a new poll with multiple options.

(create-poll 
  (title (string-ascii 100))
  (description (string-ascii 500))
  (options (list 10 (string-ascii 200)))
  (commit-duration uint)
  (reveal-duration uint))

Parameters:

  • title: Poll title (1-100 characters)
  • description: Poll description (1-500 characters)
  • options: List of 2-10 voting options (each 1-200 characters)
  • commit-duration: Number of blocks for commit phase
  • reveal-duration: Number of blocks for reveal phase

Returns: Poll ID


register-voter

Register to participate in a poll.

(register-voter (poll-id uint))

Requirements:

  • Poll must be active
  • Must register before commit phase ends
  • Cannot register twice

commit-vote

Submit a cryptographic commitment of your vote.

(commit-vote (poll-id uint) (commitment-hash (buff 32)))

Commitment Hash Calculation:

hash = SHA256(option-id + salt + voter-principal)

Requirements:

  • Must be registered voter
  • Only during commit phase
  • Cannot commit twice
  • Hash must be exactly 32 bytes

reveal-vote

Reveal your vote with proof.

(reveal-vote 
  (poll-id uint) 
  (option-id uint) 
  (salt (buff 32)))

Requirements:

  • Must have committed in commit phase
  • Only during reveal phase
  • Hash must match commitment
  • Cannot reveal twice

close-poll

Close the poll after reveal phase ends (creator only).

(close-poll (poll-id uint))

emergency-close-poll

Emergency shutdown (contract owner only).

(emergency-close-poll (poll-id uint))

Read-Only Functions

  • get-poll (poll-id uint): Get poll details
  • get-poll-option (poll-id uint) (option-id uint): Get option details and vote count
  • get-commitment (poll-id uint) (voter principal): Get voter's commitment
  • is-registered (poll-id uint) (voter principal): Check registration status
  • get-vote-reveal (poll-id uint) (voter principal): Get revealed vote
  • get-poll-counter: Get total number of polls
  • is-commit-phase (poll-id uint): Check if in commit phase
  • is-reveal-phase (poll-id uint): Check if in reveal phase

Usage Example

1. Create a Poll

(contract-call? .voting-contract create-poll
  "Best Programming Language"
  "Vote for your favorite programming language"
  (list "Clarity" "Solidity" "Rust" "JavaScript")
  u144  ;; ~1 day commit phase
  u144) ;; ~1 day reveal phase

2. Register as Voter

(contract-call? .voting-contract register-voter u1)

3. Generate Commitment

Off-chain calculation:

const optionId = 2; // Voting for option 2
const salt = generateRandom32Bytes();
const voter = "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM";
const commitment = sha256(optionId + salt + voter);

4. Commit Vote

(contract-call? .voting-contract commit-vote 
  u1 
  0x<commitment-hash>)

5. Reveal Vote

(contract-call? .voting-contract reveal-vote 
  u1 
  u2 
  0x<original-salt>)

6. Check Results

(contract-call? .voting-contract get-poll-option u1 u2)
;; Returns: {description: "Solidity", vote-count: u5}

Error Codes

Code Error Description
u100 err-owner-only Only contract owner can perform action
u101 err-not-authorized Caller not authorized
u102 err-poll-not-found Poll does not exist
u103 err-poll-closed Poll is not active
u104 err-already-voted Already committed/revealed
u105 err-invalid-option Invalid option ID
u106 err-reveal-phase-not-started Still in commit phase
u107 err-commitment-not-found No commitment found
u108 err-invalid-reveal Hash verification failed
u109 err-poll-active Poll still active
u110 err-already-registered Already registered
u111 err-invalid-options-count Invalid options list
u112 err-invalid-duration Invalid duration value
u113 err-invalid-input Input validation failed

Security Considerations

✅ Protections Implemented

  • Input Validation: All user inputs validated before processing
  • Cryptographic Verification: SHA-256 ensures vote integrity
  • Time-Locking: Block-height-based phases prevent timing attacks
  • Access Control: Registration and authorization checks
  • State Management: Prevents double voting and unauthorized actions

⚠️ Important Notes

  • Salt Security: Keep salt secret until reveal phase
  • Gas Costs: Revealing votes requires transaction fees
  • Block Timing: Phase durations are in blocks (~10 min per block on Stacks)
  • Commitment Storage: Store commitment details off-chain for reveal

Deployment

  1. Deploy contract to Stacks blockchain
  2. Contract deployer becomes owner
  3. Create polls with appropriate durations
  4. Share poll ID with voters

Testing Recommendations

  • Test all three phases sequentially
  • Verify commitment hash calculations
  • Test error conditions (double voting, wrong phase, etc.)
  • Validate time-lock enforcement
  • Test emergency shutdown functionality

About

This Clarity smart contract implements a cryptographically secure, privacy-preserving voting system on the Stacks blockchain. It enables organizations, communities, and DAOs to conduct transparent polls while maintaining voter privacy during the voting process through a commitment-reveal cryptographic scheme.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published