Logo
Back to Hub

FHE Voting System

Confidential voting with encrypted yes/no ballots and time-based access control

Basics
Documentation

FHE Voting

A confidential voting system where votes and results remain encrypted until the voting session ends, demonstrating advanced FHEVM patterns for boolean operations and vote tallying.

What You'll Learn

This example teaches intermediate to advanced FHEVM patterns:

  • Boolean to Integer Conversion: Convert encrypted booleans (0/1) for arithmetic operations
  • Encrypted Vote Counting: Tally votes without ever decrypting individual ballots
  • Struct with Encrypted Fields: Organize multiple encrypted values in a struct
  • Time-Based Access Control: Use deadlines to control voting periods
  • Permission Management: Grant decryption rights only after voting ends
  • Multiple Encrypted Counters: Maintain separate tallies for different vote types

Contract Overview

The FHEVoting contract enables confidential voting where individual votes remain private and only the final tally can be decrypted by the owner after voting ends.

Key Features

Loading...
  • createVotingSession(duration) - Start a new voting session (owner only)
  • vote(encryptedVote, inputProof) - Cast an encrypted ballot (0 = no, 1 = yes)
  • endVoting() - Close voting and grant owner decryption permission
  • getYesVotes(), getNoVotes(), getTotalVotes() - Query encrypted results

Quick Start

Prerequisites

  • Node.js >= 20
  • npm >= 7.0.0

Installation

Loading...

Compile

Loading...

Test

Loading...

Usage Example

Loading...

Key Patterns Demonstrated

1. Boolean to Integer Conversion Trick

The core pattern for encrypted vote counting:

Loading...

How it works:

  • If voteValue = 1 (yes): yesIncrement = 1, noIncrement = 1 - 1 = 0
  • If voteValue = 0 (no): yesIncrement = 0, noIncrement = 1 - 0 = 1

This allows us to increment exactly one counter based on the encrypted vote, without ever decrypting!

2. Struct with Multiple Encrypted Fields

Loading...

Combining encrypted and plaintext fields in a struct for organized state management.

3. Time-Based Access Control

Loading...

Use plaintext timestamps to control when operations are allowed.

4. Delayed Permission Granting

Loading...

Permissions are granted only after voting ends, ensuring results can't be seen during the voting period.

5. Double-Voting Prevention

Loading...

Simple plaintext mapping prevents users from voting multiple times.

Important Patterns

Why Use 0 and 1 Instead of ebool?

You might wonder why we use euint32 with values 0/1 instead of ebool:

Loading...

The boolean→integer conversion allows us to use encrypted votes directly in arithmetic operations.

Confidentiality Guarantees

  • During voting: No one can see individual votes or tallies (all encrypted)
  • After voting ends: Only the owner can decrypt the final results
  • Vote privacy: Individual ballots remain encrypted forever - only aggregates are revealed

Alternative Patterns

For more complex voting systems, you could:

  1. Multiple choices: Use separate counters for each option
Loading...
  1. Weighted voting: Multiply vote by encrypted token balance
Loading...
  1. Threshold checks: Use FHE.select() to implement quorum requirements
Loading...

Testing

The test suite demonstrates:

  • Creating voting sessions with deadlines
  • Casting encrypted yes/no votes
  • Preventing double voting
  • Correctly tallying mixed votes
  • Time-based access control
  • Permission management for result decryption
  • Event emission

Run tests:

Loading...

Key Test Cases

  1. Vote Tallying: Verifies the boolean→integer conversion correctly counts votes
  2. Double Voting Prevention: Ensures users can only vote once
  3. Time Controls: Confirms voting can't happen before/after session period
  4. Mixed Votes: Tests correct tallying when users vote differently
  5. Permission System: Validates only owner can decrypt after voting ends

Production Considerations

1. Voter Authentication

Add voter registration to control who can vote:

Loading...

2. Multiple Voting Sessions

Reset hasVoted when starting a new session:

Loading...

3. Gateway Decryption for Real-Time Results

For live result updates, use gateway decryption:

Loading...

4. Result Verification

Emit encrypted vote counts in events for transparency:

Loading...

5. Minimum Participation

Add quorum requirements:

Loading...

6. Vote Delegation

Allow users to delegate voting power:

Loading...

Common Pitfalls

1. Forgetting to Set Permissions

Loading...

2. Trying to Use ebool for Counting

Loading...

3. Not Validating Vote Values

In production, validate that votes are actually 0 or 1:

Loading...

Next Steps

After mastering this example, explore:

  • Quadratic Voting - Weighted voting with encrypted balances
  • DAO Governance - Proposal creation and multi-option voting
  • Ranked Choice Voting - Multiple preference ordering
  • Sealed Auction - Similar confidentiality patterns for bidding

Resources

License

BSD-3-Clause-Clear


Part of ZCraft FHEVM Examples | Built with Zama FHEVM

Loading...