We present OVOTE: Offchain Voting with Onchain Trustless Execution

We present OVOTE (v0.5): Offchain Voting with Onchain Trustless Execution.

TL;DR: OVOTE is a L2 design for voting using validity-proofs (zkSNARK proofs), which is similar to zkRollups. The main idea is that the votes are aggregated offchain, and proved onchain through a zkSNARK proof, resulting in constant gas costs while scaling up to thousands of voters through a single Ethereum transaction.
We present the technical document together with the implementation of the zk circuits, smart contracts and backend node.

Context

This is a project that we started 4 months ago in the Aragon ZK Research guild, continuing the ideas that we’ve been discussing in Vocdoni for the past year, with the aim to be a contribution to the Aragon ecosystem.

OVOTE (v0.5) is a short-term project with a specific scope, with the aim to be a first practical step towards a future of high scalablility & privacy preserving voting systems for DAOs using zkSNARKs.
This forum post presents the high level idea, the full design can be found at the OVOTE technical document: https://research.aragon.org/docs/ovote

Introduction

The main idea is that the computation and verification of the votes (vote + signature + censusProof), is computed off-chain. Then, a zkSNARK proof (validity-proof) is sent to the Smart Contract which verifies that everything is correct, similar to a zkRollup (Validium), but instead of economic transactions updating the Rollup state, with votes aggregated into a Result.

With this design, we can have thousands of users voting offchain, triggering onchain execution in a trustless way. This is done with constant gas costs without needing Oracles or optimistic multisigs.

How it works

Votes are computed offchain, and a zkSNARK proof (validity-proof) is verified onchain which proves that votes aggregation result is correct and that includes votes issued by each user belonging to the census.

ovote-how-it-works-diagram

  • Census is created offchain, containing user’s public keys.
  • Once the census is closed, the CensusRoot is sent to the SmartContract, and the process is created.
  • Users send their votes + signatures + censusProof to the OVOTE-node
  • Once process is finished, the OVOTE-node aggregates all the received votes, computes the result (using user’s weights) and generates the zkSNARK proof.
  • Then, any user can get the generated proof and send it to the SmartContract, which will verify it and if it’s correct will trigger the configured actions (eg. moving funds).

Status of the project

We have implemented the zk circuits, the smart contracts, clientlib and the backend node (see next subsection with the links to the repos). We have almost an usable version of OVOTE which we hope to finish during next weeks, with the idea that can be used to build a product for the Aragon ecosystem.

In the following subsection we list the different components that we have implemented.

Components implemented

Properties

Properties covered for this initial version.

  • Properties covered:
    • Trustless: nobody (neither users nor the Node) is able to modify votes values, neither add fake votes (eg. votes which user is not in the census).
    • Offchain/gasless voting: users vote offchain, and the OVOTE-node aggregates the computation & verification of all the votes and census-proofs, in a small zkSNARK proof (Validity-proof), which is sent to the SmartContract.
    • Binding execution: because of its trustless characteristic, it can trigger onchain actions in a trustless way (eg. moving funds of a DAO), directly from the voting process result (without human intervention).
    • Chain agnostic census: the census is build off-chain, and the zkSNARK proof of correct results computation can be published into any EVM chain (furthermore, into any chain that supports Pairing computation). So an OVOTE census could be used in Ethereum mainnet, but also in Polygon or GnosisChain.
    • Scalability: in a similar fashion than zkRollups, OVOTE scales to thousands of users under a single ethereum tx (results + proof publication).
  • Properties not covered (that will be covered in future designs):
    • No voter privacy
      • While the relation between votes & publicKeys is not published in the blockchain, the OVOTE-node will know these relations and could make them public. So, unless users use a node managed by themselves, the votes info is assumed to be ‘public’.
      • Future designs by the Aragon ZK Research will focus on privacy preserving voting solutions.
    • No token-based voting
      • The scope of OVOTE is not about token-based voting, but it is planned in the mid-term future (check section: “Future use cases > OVOTE-DAO”)

Use cases

The aim of this project is to be a first step towards the usage of zkSNARKs technology for DAOs tooling. In the following sub-sections we describe some of the inmediate use cases that can be done with the current implementation, some other use cases that we plan to implement, and some further research that we will do.

Aragon DAOs integration

  • OVOTE is a modular component, which can be plugged into AragonApp.
    • Users could use OVOTE as a sub-option (component) in AragonApp, from the AragonApp’s UI
  • Potentially, users, could deploy their own standalone instance of OVOTE with a minimalistic UI
  • The OVOTE proof Verifier would be deployed in Ethereum, and any project could call it to verify their OVOTE proofs.
    • The Verifier contract contains part of the Trusted Setup which ceremony would be organized by Aragon

Tokenomics

Tokenomics are not in the scope of this project, but we identified some places where the usage of ANT would be useful:

  • To pay the prover-server costs: Aragon could have servers that DAOs can use to compute the zkSNARK proofs, these are powerful (and a expensive) machines. There could be a fee in ANT that needs to be paid to the prover-server when publishing the results + proof on the Smart Contract.
    • This could be achieved by putting the prover-server ethereum address as a public input of the circuit, so the Smart Contract needs to know it to verify the proof, thus the contract can require sending ANT to that address, in the results publishing (& verification) transaction call.

We aim to do more research about possible other uses of ANT tokens in the context of OVOTE.

Direct use cases (short term, available with the current implementation)

Use cases available with the current implementation:

  • Offchain multisig with onchain results: users make offchain signatures, when a certian threshold of support is reached, the node generates a proof (validity-proof) and the SmartContract verifies it, if correct, it triggers the configured transaction (eg. DAO funds movement).
  • Offchain referendum with onchain results: similarly to the OVOTE, but users cast a vote which can be ‘yes’ or ‘no’, meaning that when the results are presented, it is known how many votes are ‘yes’ and how many votes are ‘no’.
  • Onchain Anonymous voting: the same census can be reused to users generating zkProofs that they belong to the census, and sending them directly to the onchain SmartContract. This approach is costly for users, but allows for anonymous voting. This use case would be cheap in non-congestioned EVM chains like Polygon or GnosisChain.

Future mid-term use case - OVOTE-DAO (~zkDAO)

An interesting idea to build on top of OVOTE, is to set up a Smart Contract that builds a Census Tree, where users can deposit ETH or any ERC20 token, and when the deposit is done, the contract adds a new leaf in the Census Tree with a weight value corresponding to the amount of tokens deposited by the user. In this way, the contract maintains the Census Tree, based on the deposits of tokens of the users, and the users can vote on proposals to spend the deposited tokens by using the same approach than the OVOTE. This could be managed by a contract on top of the OVOTE contract.

In short words, this would be a kind of ‘offchain DAO with onchain validity-proofs’, where users make token deposits to the DAO contract, and then they vote offchain based on the weight of their deposited tokens, and the results with a zkSNARK proof is published to the DAO contract, which if correct, proves the correctness of the results and triggers a transaction execution (which, can be DAO funds movement).

In one line: a DAO where the census is built by the tokens deposited in the contract, where the members vote based on their deposited tokens through OVOTE, and the results are published onchain together with the OVOTE zkSNARK proofs, to triger the funds movement.

This is our next step once OVOTE is implemented, as for having an initial version of OVOTE-DAO we could reuse the same zk-circuit that we implemented for OVOTE, and most of the needed implementation would be for the contract that gathers the user’s deposits onchain and build the CensusTree.

Long term research

  • Proofs recursion: this would allow users generating a zkproof that they belong to the census, and the Node would generate a zkproof aggregating the verification of the user’s zkproofs. In this way, users still enjoy gasless voting, but with anonymicity.
  • Ring signatures inside zkSNARK circuit: this would allow users proving that they belong to the census without revealing who they are (Monero style), and later all the signatures verification would be proven inside a zkSNARK circuit by the node. This would bring anonymous voting while having the scalability that we have with OVOTE.
  • EthStorageProofs and EthSignatures: instead of using ‘snark-friendly’ cryptographic primitives (MerkleTree, Hash function, and elliptic curve) if we can have inside a zk circuit the Ethereum cryptographic primitives (such as Ethereum Patricia Trie (with RLP encoding), keccak256 hash function, and secp256k1 elliptic curve), we could use as census the already existing Ethereum state. This would allow to directly use Ethereum token-holdings as a census for voting.
  • Research on results aggregation: this would allow for different nodes sending different results that are aggregated.
  • Researching other proving schemas such as PLONK.

Regarding the project name

OVOTE (Offchain Voting with Onchain Trustless Execution) is the research project name. Aragon could build a product using OVOTE, and this product could have a more user-friendly name such as zkMultisig, zkGov, gaslessVoting, etc.

More details

Technical paper (draft): https://research.aragon.org/docs/ovote
ovote-cover-document

13 Likes

Hey Arnau, this is incredible work! The optionality that this technology can create is impressive in both a short, medium, and long-term trajectory for product creation for DAO tooling/decision making.

Very much looking forward to seeing the Aragon ecosystem produce functional products with this research and technology.

I like that you’ve thought through aspects including tokenomics and marketing. Looking forward to hearing more input from some tech ecosystem members as well!

3 Likes

A product built around this can really be a 0 to 1 for DAOs. Well done!

4 Likes

Great piece! Thanks for all the work. Look forward to seeing a team build this. :eyes:

2 Likes

That’s quite cool.

Onchain Anonymous voting: the same census can be reused to users generating zkProofs that they belong to the census, and sending them directly to the onchain SmartContract. This approach is costly for users, but allows for anonymous voting. This use case would be cheap in non-congestioned EVM chains like Polygon or GnosisChain.

Does it mean that we can replace the OVOTE-nodes by a smart contract in an already existing sidechain/L2? It would reduce the overhead and offer the user a familiar way to interact with the system.

I also appreciate the census tree to be agnostic to any implementation, so you can fill it with any kind of data. I wonder how easy would it be to generate one of those trees from an ERC20 snapshot, and if there is an automatic way to validate the tree is right.

I’m looking forward to see more work in this direction. I really think zero knowledge is the next steps in the evolution of blockchains.

3 Likes

Does it mean that we can replace the OVOTE-nodes by a smart contract in an already existing sidechain/L2?

If needed, it could be done, but the snark proof probably would still be needed to be generated in a server as it’s a bit heavy computation.
The Onchain Anonymous voting section refers to using the same census with a slightly different circuit, where instead of generating a proof in a node that aggregates all the votes and signatures, each user would generate a proof from their browser and send it directly to the smart contract, proving that they are in the census without revealing who they are. As this is expensive in terms of gas for each user tx, we mention that it might be a use case for other EVM chains like Polygon or GnosisChain.
Ideally in the future we will have both: privacy and scalability, so a node would aggregate those zkSNARK proofs offchain in another proof which is later sent onchain. This is a line of research for the mid-long term.

One thing to have in mind, is that OVOTE itself is a Layer2 (L2), which inherits from Ethereum mainnet the security guarantees. A line of research that we aim to do is related to the possibility of aggregating different results&proofs from different nodes (in which the repeated votes should not be counted more than once), this will help decentralizing more the ovote-nodes.

I also appreciate the census tree to be agnostic to any implementation, so you can fill it with any kind of data. I wonder how easy would it be to generate one of those trees from an ERC20 snapshot, and if there is an automatic way to validate the tree is right.

Right, we were aiming for flexibility in this design, so if a DAO needs to generate a census from a ERC20 snapshot it can be done (with the proper tooling so anybody can check that is well generated).
But on the same time the design allows other use cases as for example there could be another DAO which prefers to have for example 3 levels of contributors (eg: core, members and supporters), they could generate the census setting the weights based on these 3 levels of contributors.
So the same ovote product could be used by both use cases.

3 Likes

It’s totally fine if it is something that can be done by anyone, not just a trusted party.

I understand from your message that there would be not a trivial way to generate a zk-proof that the census contains all the token holders at a specific point in time, and it should be treated in an optimistic way. Is that true?

Regarding doing the votes aggregatin in an EVM sidechain: while I see need for decentralizing the nodes, I’m not so sure than going through anther EVM sidechain fits well. But we have on the table going through a specific blockchain where the nodes replicate the votes processing that currently the ovote-nodes do.

Thanks to the zkSNARK proof, no node is capable of modifying votes neither manipulating votes, neither adding fake votes. The only malicious thing that a node could do is not including votes (=censoring/banning). Regarding this, one thing to note, is that with the design of the current ovote version, users don’t need to depend just on one single ovote-node. It’s not the ideal solution, but users can send their vote to multiple ovote-nodes.

So for example, if there is a node banning or censoring votes, as soon as any of the other nodes gathers enough support for the voting proposal, will generate a SNARK proof and it can be sent to the smart contract to trigger the funds movement, no matter if there is a malicious node censoring votes. (and is just a matter of having some nodes running, and the frontend app sending the same vote to multiple nodes).

As mentioned, this is not ideal, but still better than a single centralized node. Is in the topics of research to find ways to continue with the approach of having multiple nodes, but with the capability of being able to aggregate results from different nodes into a single succint result (but on the same time, avoiding counting more than once the votes from each user that may be included into different nodes results).

I understand from your message that there would be not a trivial way to generate a zk-proof that the census contains all the token holders at a specific point in time, and it should be treated in an optimistic way.

Yes, there should be the proper tooling to make it easy to check that a census is well generated.
That’s why OVOTE does not focus on token-based voting, but on a flexible census design, which if needed can be used for token-based voting through an optimistic approach as you mention, and ideally in the future having a snarky-way to proof that the census is well generated based on the token-holders at a specific point in time.

Furthermore, if we could generate easily such snark proof proving that the census contains all the EVM token holders at a specific point of time, probably we could use the same zk-circuit to directly use the ethereum state tree as the direct census, without need to generate an intermediate census. That’s a line of research, in order to have trustless-token-based-voting. The current friction is that in order to prove token holders through EthStorageProofs, we need to prove inside the circuit the Ethereum Patricia Merkle Tree, and also the Keccak256 hash function and the secp256k1 ECDSA signatures, which all of them are not much ‘snark-friendly’ with the current zk stack (but things are evolving fast, we’re optimistic regarding the feasibility of this).

2 Likes

This looks very promising Arnau, I look forward to see how this line of research evolves!

2 Likes