2

Can we build a smart contract where it is not possible to see the actual vote until the voting period ends? One idea is to use hashing. Voters can send a hashed version of a vote. The problem with voting is that there is only two options, but we can add something like salt together to circumvent this. And then after the end of the voting period, the voters have to reveal their votes. They send their values unencrypted and contract checks that the hash value is the same as the one provided during the voting period.

The problem is that there is one extra step for voters, and thus it is not usable.

Any ideas?

1

Cool idea. Yes, a commit-reveal scheme is a primitive from cryptography that is easy to implement on Ethereum using, e.g. the built-in keccak hash function.

The salt you mention is also known as a "blinding factor" in cryptography, a randomly chosen value that hides what you noticed is an otherwise deterministic hash value of YES or NO. Your one extra step (of revealing the vote afterwards) can be solved with zero-knowledge proofs as described in the two schemes below, which eliminate the need for a reveal, and count the votes while they are still encrypted. (Operating on encrypted data without revealing it is sometimes called "homomorphic")

There is a private voting scheme. There are many extra steps involved rather than just submitting and hashing a vote, but these steps can all be done with client software during the voting period, and don't require an extra step from all voters in order to count.

A second scheme, which is more efficient in gas costs, uses the AZTEC protocol (https://www.aztecprotocol.com/) which is already deployed and working on mainnet. In brief, the scheme works like

  1. The election commissioner, for each ballot item, creates a "security" or ERC1724 token and issues a "yes" vote (of value 1) to each registered voter.

  2. Each voter (or their client software) creates two new votes, another "yes" vote of value 1 and a "no" vote of value 0 (a decoy note), and converts their allotted vote into two votes, with blinding factors, that both look random to the public.

  3. Each voter pays their new yes vote to an Ethereum address / contract representing the ballot outcome they want, and their new no vote to another Ethereum address / contract representing the other outcoome. (Could be multiple, e.g. a presidential election could have 3 candidates). This is done using the ERC1724 method confidentialTransfer using what's known as a join-split proof, the sum of the input votes equals the sum of the output votes.

  4. After the voting period is over, each outcome contract is programmed to compare their balance (the number of yes votes they received) to each other using privateRange or publicRange proofs, depending on whether the election wants each candidate to reveal the number of votes they received rather than just comparing who has more.

  5. The winner is recorded on-chain by another, vote-counting contract, and perhaps can be appealed by a panel of supreme court judges via Aragon Court or a similar adjudication protocol.

| improve this answer | |
0

The simplest (and best IMO) is to do what you said and hash with a random salt and do a commit/reveal pattern. Since everything in the EVM is public and readable by nature, there isn't a way to time lock the secrecy of committed data without external intervention without trusting some third party (e.g. everyone gives their unhashed votes to you and you reveal them at the end, making the user only have to do one action, but requiring you to not leak/act on the votes)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.