Our team at Voto has created an innovative on-chain, censorship-resistant voting solution utilizing decentralized identities. We address the trust and identity challenges in traditional voting systems by leveraging a community-based identity system, Zupass, and the MACI protocol for anonymous, bribery-resistant voting.

Team's submissions

Voto Social Tech Social Impact

The problem Voto solves

Voto is an on-chain censorship-resistant anonymous voting solution built on decentralised identities.

Voting has always relied on two pillars: trust and identity. These two pillars have been broken by misuse and subversion of power, as represented by historically low election participation, not only in emerging countries, as well as in traditional democracies. Lack of trust - electorates have been continuously expressing a vote of no confidence in their elected governors who have been manipulating the electorate system to continuously stay in a carousel of power. Outdated ideas of identity - the idea of identity has evolved since the time when a government-issued passport was the one and only identity.

Voto allows communities to easily set-up a poll and participate in a voting process which could not be subverted or manipulated. We use a censorship-resistant, anonymous, bribery-resistant voting protocol - MACI - based on community-issued identities. We believe that the idea of identity currently is in a process of constant evolution, and we can’t pigeon-hole participants into using a fixed type of identity, so we rely on a community-based identity - Zupass.

Challenges you ran into

We ran in several issues while building our project:

The idea of identity - voting is based and shaped by the identity of the voter, so we took a lot of care in choosing the right ID solution. We iterated through several versions of identity solutions (i.e. Fractal ID, Civic Pass etc.) until we understood that no-one version of identity should be imposed by us as the creators of the project. Instead of governments being the sole purveyors of identities - we can have many identities which show our uniqueness as a human being. Communities (such as a school, church, community of builders), events (hackathons, concerts), protests and movements should also have right to issue identities - and we as a community should find appropriate ways to use each of these multiple identities as we see fit - this is the reason we ended up choosing Zupass as our solution for identity.

Technical difficulty of underlying technologies and their implementations - integrating the MACI protocol, as well as solutions which expand on it’s functionality (maci-wrapper by yashgo0018) was quite challenging, and our team spent a big part of our time on making the base solutions work, as well as troubleshooting, bug-fixing, expanding the functionality and documenting the maci-wrapper. We believe that we have significantly increased the deployability and usability of MACI through this work.

Limitations of Account Abstraction (ERC-4337): With our intention to make the registration as easy as possible we started experimenting with tools such as Biconomy or Candide. We very quickly encountered various limitations such as the requirement for additional tools such as etc. to allow social login and pairing with a newly created wallet. In this case however the user has to make a trust assumption and depend on a third-party for the access to their wallet. This was not acceptable to us. Candide had an interesting approach to utilise Passkeys to create a Key Pair used to create and interact with a Smart Wallet. This was implemented until we encountered issues utilising the smart wallet to prepare and execute complex transactions (our initial tests can be found within ./packages/nextjs/registration.

Technology used


  • Zupass: For zkp-based identification
  • MACI: voting infrastructure to ensure minimal anti-collusion with zk-proof to ensure correctness of result.
  • Next.js + typescript: User-friendly front-end
  • Hardhat + solidity: Smart contract development and deployment.
  • Next.js backend:

Voter Registration: We use Zupass to verify the identity of any user. The participation at any event or association in any group can be chosen by the coordinator (who will also be the deployer of the vote contracts) as the requirement to participate in MACI polls. This is enforced by the ZupassGatekeeper.sol contract.

Voting Process: Initiating a new vote

Vote counting:

  • Using the MACI cli to merge signups, messages, and tally votes.
  • The final tally file can be posted in the app for the voters to see.
  • The vote tally can also be published on-chain in a future implementation.