ZeroPoll - Voting/Polls

This topic is to discuss the proposal submitted by @anarkrypto
Please see below for the details of the proposal and discussion.

5th October , 2024
Current status: Funded
Starting Date: 7th October , 2024

30th September, 2024
Current status: Under Consideration.
Opened for community discussion on : 30th September, 2024.

3 Likes

ZeroPoll: Anonymous, Secure, and Verifiable Voting System

Project Background

ZeroPoll is an innovative, privacy-preserving voting system that leverages zero-knowledge proofs (zk-SNARKs) to ensure that votes remain anonymous while being verifiable. Built on the Mina ecosystem, ZeroPoll provides a secure voting solution for organizations, businesses, and social events, covering numerous applications such as voting on proposals, business management, surveys, elections and much more. Initially bootstrapped using ProtoKit’s starter kit, ZeroPoll features a user-friendly interface powered by Next.js, React, Zustand, and ShadcnUI.

The system allows participants to vote anonymously while verifying their eligibility through a commitment system. This ensures both privacy and result verifiability.

Proposal Overview

Problem

Traditional voting methods often struggle to balance user experience, privacy and security. Ensuring that votes are anonymous and verifiable without compromising the integrity of the voting process can be complex and inefficient. Many existing systems fail to scale effectively on conventional blockchains.

Solution

ZeroPoll addresses these challenges by using zk-SNARKs to provide anonymous and verifiable voting. Poll options are hashed with salts and stored on-chain, allowing poll privacy. A Merkle tree-based commitment system ensures only eligible voters can participate, while nullifiers prevent double-voting. Through o1js and ProtoKit, ZeroPoll leverages zk-rollups and Mina L1 for scalable implementation. The poll proofs can be verified on the client side. Yet, ZeroPoll is designed to be user-friendly and accessible, requiring no technical expertise. Our modern and intuitive interface, combined with the seamless integration of Auro Wallet, handles all the complexities, ensuring a secure, smooth and enjoyable user experience.

Impact

ZeroPoll enhances the Mina ecosystem by showcasing the real-world application of zk-SNARKs for secure voting. It promotes adoption among entities seeking privacy-focused solutions and stimulates developer interest through new SDKs and APIs. By facilitating anonymous polling, ZeroPoll extends Mina’s utility to various sectors, including business and community voting.

Audience

Target audiences include organizations, businesses, and communities where secure, private voting is crucial. Developers interested in zk-SNARKs and blockchain applications will also benefit from the proposed SDKs and APIs.

Architecture & Design

ZeroPoll consists of 3 parts:

  • The Chain (Runtime Modules): Developed with ProtoKit and O1JS. The Poll Module is the core of the project, it’s designed to implement a secure and private voting system using Zero-Knowledge Proofs, Poseidon hashing, and Merkle trees. It ensures voter anonymity, verifies vote validity without revealing identities, and prevents double voting through nullifier checks. The system revolves around creating polls, handling votes, and verifying them using cryptographic techniques. It’s currently designed to work only with private polls, which requires the poll creator to restrict which public keys can vote through a commitment hash.
  • The Web App: Built with Next.js, React, Zustand, and ShadcnUI, it provides an intuitive interface for interacting with the blockchain. It consumes poll data from the chain and from the persistence repository and verifies voting through zero-knowledge proofs.
  • The Persistence Repository: Currently uses PostgreSQL with Prisma ORM for storing less sensitive data (poll metadata). It ensures that only authorized signed wallets can read the poll metadata (we authenticate users with Auro Wallet Sign Message. Future enhancements will include encrypted storage on IPFS for a more decentralized approach.

Poll creation diagram:

  1. Poll creator creates the poll, storing the offchain metadata, including the poll name, description, poll options, and public keys eligible for voting.
  2. Poll creator creates a commitment hash from the merkle map of the voter public keys hashed with Poseidon.
  3. Poll creator creates the hashes of each poll option with Poseidon + Salt.
  4. Poll creator calls the createPoll method, passing the commitment and optionsHashes as arguments. A new poll is created and can be shared with voters.

Vote cast diagram

  1. An eligible voter retrieves the poll’s offchain metadata and computes the hashes (commitment and optionsHashes).
  2. The eligible voter queries the chain to retrieve the poll’s commitment and optionsHashes to compare with the hashes of the offchain data, ensuring that the poll options are not tampered with and to verify which public keys are eligible to vote.
  3. The eligible voter generates a ZkProgram.Proof with a nullifier and casts his vote via the vote method. His poll state is updated, adding +1 to the hash of the voted option.
  4. The client-side vote count is recalculated.

Poll Module Detailed

The complete code for the poll module can be found here

Components

VoteOption:

  • A struct representing each voting option. Each option has a hash (to identify the option) and a votesCount (tracking the number of votes it has received).
  • Used to count votes for each option while ensuring privacy.

OptionHash:

  • Extends the Field class and provides a mechanism to hash text inputs (poll options) into unique Poseidon-based hashes at client-side.
  • Uses a combination of text and a salt to generate unique hashes, ensuring the integrity and uniqueness of poll options.

OptionsHashes:

  • Struct that represents a group of 10 hashed poll options. It either allow client-side to converts text options into hashes (fromTexts) or directly accepts predefined hashes (fromHashes).
  • Ensures that all polls always contain exactly 10 options, even if some are placeholders, using Poseidon hashes to make each option verifiable and unique.

VoteOptions:

  • A struct that holds the set of VoteOption instances for a given poll.
  • Responsible for casting votes using the cast method, which updates the vote count for the selected option while maintaining immutability.
  • Initialized from OptionsHashes, it creates a mapping between hashed options and their corresponding vote counts.

PollPublicOutput:

  • This struct holds the public output of the poll after a vote is cast, including the Merkle tree root and the nullifier (which prevents double voting).
  • Used to verify that a vote has been correctly processed and recorded.

Key Functionalities

createPoll:

  • This function creates a new poll with a unique poll ID and a commitment (representing the hash of the poll options).
  • The commitment and poll options (in the form of OptionsHashes) are stored on-chain, and the poll ID is incremented.
  • Maintains state using StateMap for commitments, poll options, and vote tallies.

vote:

  • A voter can cast a vote by providing a pollId, the hash of their selected option, and a PollProof (ZKP).
  • The method verifies the validity of the provided proof, checks that the poll exists and that the nullifier (used to prevent double voting) has not been used before.
  • It then updates the poll’s vote counts based on the selected option and marks the nullifier as used.

Proof Verification:

  • ZKPs are used to prove voter eligibility without revealing the voter’s identity. The canVote method calculates the root and verifies that the voter can vote based on their public key and the poll ID.
    This allows trustless verification, ensuring a user can only vote once while keeping their identity private.

Zero-Knowledge Poll Program:

  • The pollProgram is a ZK program that defines how the ZKP is generated and verified. It includes methods like canVote to ensure the integrity of the vote casting process.
  • Ensures secure interactions between the voting module and the cryptographic constructs of the system.

State Management

  • commitments: Maps poll IDs to their respective commitments (root of the Merkle tree containing the hashed participants public keys allowed to vote in the private poll).
  • nullifiers: Maps nullifiers (used for preventing double voting) to booleans indicating whether the nullifier has already been used.
  • votes: Stores the VoteOptions for each poll, keeping track of the votes for each option.
  • lastPollId: Tracks the ID of the most recently created poll.

Reference / Inspirational Works

Private Airdrop - Module: Allow private and anonymous token airdrop. Explores the same concept of set a MerkleMap commitment to anonymously register eligible participants and use nullifier to prevent double-claim. Made with Protokit by maht0rz.
Katz - Ballot Vote: Vote for a candidate with greater anonymity. By leveraging recursive proofs with o1js on Mina, the vote is kept private from the rest of the public while the overall election results can be known by anyone.

Vision

Long-term goals for ZeroPoll include:

  • Study extra voter invitation and authentication solutions based on identity systems such as zkid and/or social networks
  • Becoming one of the main use cases of zkApps with Mina, o1JS and Protokit; contributing to the adoption of these technologies by the community.
  • Becoming a collaborative project and well audited by community devs, thus providing a basis for other similar use cases.
  • Offer public and private management solutions for different organizations. Examples: managing proposal votes, elections and surveys.
  • Contribute to the creation of a culture of anonymous and verifiable voting systems based on zk-knowledge. This can affect the demand for such solutions in their most diverse use cases, such as public and private management, DAO proposals, surveys and even presidential elections…
  • After covering general use cases related to polling/voting, study the main market demands for the project and, if necessary, update the project’s positioning, user experience and functionalities.

Existing Work

The project is functional as an alpha release.

Production Timeline

ZeroPoll is expected to deliver all features and improvements contained in this proposal within 3 months, with regular updates and feature additions separated by scopes 1, 2 and 3.

Budget & Milestones

Deliverables

  • Development and release of @zeropoll/sdk, @zeropoll/chain, and @zeropoll/ui.
  • User account features for managing and bookmarking polls.
  • Enhanced UI/UX, including a new landing page and improved poll creation and voting experience.
  • Downloadable proof files in JSON format for offline verification.
  • Public anonymous polls without requiring voter public keys.
  • Integration with Mina L1 via ProtoKit zk-rollup.

Mid-Point Milestones

- Scope 1:

  • Complete development of the landing page and UI/UX improvements.
  • Refactor code for better maintainability and performance.
  • Enhance unit tests for both runtime modules and the web app.
  • Update and improve the README and technical documentation.

- Scope 2:

  • Release the @zeropoll/sdk, @zeropoll/chain, and @zeropoll/ui packages.
  • Implement functionality for downloadable proofs in JSON format.
  • Create and finalize technical documentation and user guides.
  • Transition poll metadata storage to a decentralized storage solution like IPFS.

- Scope 3:

  • Complete integration with Mina L1.
  • Launch public anonymous polls which does not requires the poll creator to insert the voters public keys, but simply share a link that anyone with a wallet could vote - currently the polls are private and the poll creator is required to restrict who can vote or read the poll options. To achieve this, the current Merkle Map system can be - adapted or replaced, while preserving the Nullifier and other components necessary for the zk circuit. Note that the idea is to allow the poll creator to choose the restrictions, like choose between PRIVATE or PUBLIC during the creation of the poll.
  • Release the stable version of ZeroPoll.

- Final:

  • Conduct zk-SNARK proof validation.
  • Execute bug bounties and security audits to ensure robustness and security.

Project Timeline

  • Month 1: (Scope 1) Develop landing page, refactor code, and improve UI/UX (poll management, creation, and voting), enhanced unit tests for runtime modules and web app, improve README of the repo.
  • Month 2: (Scope 2) Release @zeropoll/sdk, @zeropoll/chain, and @zeropoll/ui, implement downloadable proofs, creation of technical documentation and transition to decentralized data storage.
  • Month 3: (Scope 3) Launch public anonymous polls, integrate with Mina L1, and release stable version.

Budget Requested

Total: 33,000 MINA

  • Scope 1: 11,000 MINA
  • Scope 2: 11,000 MINA
  • Scope 3: 11,000 MINA

Wallet:

B62qisCaNyznz9VtEVStHKhzUsCCp9JaD1eTb8zUWKGdxfdhauoj8MU

Commitment to Long-Term Development

ZeroPoll will continue evolving beyond the initial funding period. Future plans include integrating ProtoKit’s full potential, creating public anonymous polls, enhancing user features, and developing SDKs and APIs. We will stay aligned with ProtoKit’s development to integrate our chain layer on Mina L1 as soon as possible. The project aims to explore further possibilities such as token-based incentives and decentralized governance features.

Team Info

Proposer GitHub

github.com/anarkrypto

Team Members

  • Kaique Nunes (anarkrypto)

Proposer Experience and Achievements

I am a full-stack developer with 8 years of experience in TypeScript, React, blockchain, smart contracts, web3, and decentralized systems. My previous projects include:

  • Bioca.eco - Decentralized Supply Chain System: EVM smart contracts for traceability via NFTs.
  • NFT Minting Backend: Using EVM, IPFS, and RabbitMQ.
  • NanoPay.me: Open source payment gateway for Nano cryptocurrency.
  • NanoDrop.io: Popular nanocurrency faucet recommended by the Nano Foundation.
  • Construbook.app: A social network for the construction industry.

Achievements include:

  • Winner of NanoJam hackathon with P2PoW.
  • Construbook’s integration with Hub da Construção Sinduscon-BA.
  • Awarded for contributions to Fluence marketplace.

Risks & Mitigations

Risks

  • Dependency on ProtoKit’s development for Mina L1 integration.
  • Ensuring app and chain security against privacy breaches or vote manipulation.

Mitigations

  • Monitor ProtoKit’s development and explore alternative zk-rollup solutions if needed.
2 Likes

Remember seeing your project at ETHGlobal live demo and the mentors were fascinated by it! Glad you’re here man, and hopefully we build something worthwhile for the ecosystem! :muscle:

Just a quick one, does the app report any details to the L1 or it runs totally on the application chain?

2 Likes

Thank you, JO-OLADEJI :muscle:

ZeroPoll chain uses Protokit, which has L1 integration under development, but apparently will be released very soon.

1 Like

Progress Update - October 31, 2024

The first few weeks were focused on

  1. Small fixes and improvements to the web app UI (responsiveness, landing page improvements, error messages, loading status, styling…)
  2. A long refactoring of the project’s core - Here I go into detail

The ZeroPoll web app, like the chain, was developed on top of StarterKit - a boilerplate provided by the Protokit team. Although this provided an excellent basis for starting development, it soon becamse inefficient in providing scale, testability and decoupling to the core of the project - which is not limited to the chain modules, but also to all modules that mediate the user UI interface to the polls, such as wallet, authentication, storage, APIs, etc.

This is not a Protokit issue, just a limitation of the StarterKit boilerplate. So, in our alpha version, the logic of these modules was coupled in the form of “stores” with the Zustand library to allow for easy integration with the React app, with simplicity and efficient state management as its strong points. However, continuing to develop these modules in the Zustand “stores” made the application complex to understand and, above all, extremely coupled. As if it were “Zustand-Oriented Programming”.

If we want to make ZeroPoll a scalable, testable and composable software, allowing it delivering the best of itself and be the basis for other projects, we need to decouple its core from the rest of the application.

The beginning of this process was to create a directory called “core” and move our code there in the form of “controllers” and “providers”, with classes and interfaces that isolate the business logic of each module, while managing the state in an agnostic way and allowing implementations with different services/adapters/providers, such as different wallets, different forms of storage and different frameworks. And also the creation of unit tests isolated from the rest of the application.

This current work can be found in the following branch: GitHub - anarkrypto/zeropoll at decouple-core-logic

With this refactoring complete and merged, in the next few weeks we will be able to start creating an SDK-like package, which will be imported in our React Web App, but can also be implemented by different use cases, with different TypeScript-based stacks. It will also be time to explore new storage mechanisms, such as IPFS.

Feel free to ask questions or make suggestions.

2 Likes

Progress Update - November 16, 2024

After a long refactoring of the codebase (see PR), the core of our project is finally fully separated from the application framework (React).

The first scope is complete, including:

  • UI/UX improvements.
  • Refactor code for maintainability and performance.
  • Enhance unit tests.
  • Update and improve the README.

With this change, we can move on to the next scope, including deliverables such as releasing @zeropoll/sdk, @zeropoll/chain, @zeropoll/ui packages and the poll metadata storage transition to a decentralized storage solution like IPFS.

Note that changes to the UI/UX and README will continue to be made along with upcoming features to improve the experience of users and developers, encouraging the use and building of new use cases on top of ZeroPoll.

1 Like

Progress Update - December 3, 2024

In the first part of the second scope, the focus was on implementing IPFS in ZeroPoll, eliminating centralized storage.

To achieve this, I am developing a lite IPFS node using libp2p with typescript. This node should be much leaner than the IPFS Kubo node. However, it brings 2 compatible APIs for PUT and GET.

/api/v0/block/put
/api/v0/block/get

Checkout the PR here

To complete this process, we need to ensure that the content is found by any node on the network.

After that, I will be working on the ZeroPoll npm packages.

Progress Update - December 16, 2024

I’m happy to announce great progress for ZeroPoll as part of the second scope.

Deliverables:

  • IPFS is now our storage mechanism for Poll metadata, in a similar way to what is done in NFTs and thus eliminating central servers.
  • The metadata is now encrypted with AES-256 before being stored on the public IPFS network. Only Poll participants have access to the key via the link.
  • The project core is now part of a separate package: @zeropoll/core. The context provider and react hooks are now part of the @zeropoll/react library. Together with @zeropoll/chain these should be published in the npm store soon.

Blockers:

  • Still need to further study the structure and feasibility of the deliverable “Implement functionality for downloadable proofs in JSON format”.
  • There is still no announcement of the Protokit being compatible with L1, which raises a major concern about the delivery of the 3⁰ scope.

Other:

  • Protokit has released a new version with “Indexer for historical data indexing”, “Processor for processing historical data” and “Runtime events”. Upgrade Protokit can be very beneficial to the project.

Progress Update - January 2, 2025

All packages are now available through npm:

Also, all our repo is fully documented through the README.md of each package.

2nd scope is finished, except for the downloadable proofs in JSON format, which has been a challenge, specifically how/where to store the zk vote program proofs, which has a virtually unlimited number of votes with the open poll feature. Protokit does not seem to store or to make it available through the chain or indexer graphql.

3rd scope
We now allow Open Polls, which allows anyone to vote anonymously. Different from the “Invite-only poll”, it does not require the poll creator to configure the poll with the voters’ wallets.

Blockers:

  • Still need to make the vote proofs available to finish the deliverable “Implement functionality for downloadable proofs in JSON format”.
  • Protokit now has a scheduled release date for the L1 integration, which is Q1 of 2024. Until then, we are still blocked from integrating with Mina L1. A decision will be needed immediately.

Update - January 15, 2025

  • End-Point presentation completed, check the presentation here

  • Improvements to the UI, especially buttons, creating more identity in the application.

  • As mentioned in the presentation, there is no documentation or examples for performing L1 settlement with Protokit yet. We need to monitor Protokit’s next steps to perform such an update when more information becomes available.

  • Removal of deliverable “Download Proofs in JSON format”
    After talking to experienced developers in the Mina community, it became clear that allowing JSON Proofs to be downloaded is not technically feasible and may not even make sense. This is because proofs are not stored onchain, but only used to change the state of contracts. Furthermore, solutions for storing these proofs offchain do not prove that they were used onchain.
    In fact, my idea for this little feature was a mistake. For the reasons mentioned and also because it would not change any important aspect of ZeroPoll, we have excluded it from the deliverables.

The last 3 months have been marked by a lot of work, challenges and learning. I would like to thank the Mina Foundation for the grant and also thank the Mina community on Discord for their countless technical assistance.

I hope that ZeroPoll will somehow contribute positively to the Mina ecosystem.

ZeroPoll will continue to be active, with improvements in the coming months.
If you want to know more or contribute check our repo GitHub - anarkrypto/zeropoll: A private voting system powered by zero-knowledge proofs (developing)
Or you can find me on Mina’s Discord, my nick @anarkrypto

1 Like