0

Consider the voting contract as described here. The flow of the contract is like this:

  1. Create a new contract with three candidates for whom votes are cast.
  2. Votes are cast by users.
  3. Number of votes won by a candidate can be seen at any point in time.

My requirement is as follows:

  1. Create a new contract with n candidates for whom votes are cast.
  2. Votes are cast by a pre-determined user community.
  3. Voting is allowed up to a pre-determined date.
  4. At the end date, the number of votes for each candidate is counted and the winner announced.

Clearly, until the voting is over, the number of votes won by a candidate shouldn't be revealed. However, since the contract state is always available on the blockchain, how can one hide the "intermediate state", i.e. the number of votes won by a candidate, until the "final state", i.e. the position of candidates?

The voting contract code, as available in the link above, is shown here:

pragma solidity ^0.4.11;
// We have to specify what version of compiler this code will compile with

contract Voting {
  /* mapping field below is equivalent to an associative array or hash.
  The key of the mapping is candidate name stored as type bytes32 and value is
  an unsigned integer to store the vote count
  */

  mapping (bytes32 => uint8) public votesReceived;

  /* Solidity doesn't let you pass in an array of strings in the constructor (yet).
  We will use an array of bytes32 instead to store the list of candidates
  */

  bytes32[] public candidateList;

  /* This is the constructor which will be called once when you
  deploy the contract to the blockchain. When we deploy the contract,
  we will pass an array of candidates who will be contesting in the election
  */
  function Voting(bytes32[] candidateNames) {
    candidateList = candidateNames;
  }

  // This function returns the total votes a candidate has received so far
  function totalVotesFor(bytes32 candidate) returns (uint8) {
    if (validCandidate(candidate) == false) throw;
    return votesReceived[candidate];
  }

  // This function increments the vote count for the specified candidate. This
  // is equivalent to casting a vote
  function voteForCandidate(bytes32 candidate) {
    if (validCandidate(candidate) == false) throw;
    votesReceived[candidate] += 1;
  }

  function validCandidate(bytes32 candidate) returns (bool) {
    for(uint i = 0; i < candidateList.length; i++) {
      if (candidateList[i] == candidate) {
        return true;
      }
    }
    return false;
  }
}
1

It would have to be a two step process where before the end date of the vote people would submit encrypted votes (which either could or could not be changed depending on your needs).

Then, after the end of the voting period, those same people (i.e. those same Ethereum addresses) would submit another transaction that would reveal their previous vote.

The reveal would need to be accompanied with some sort of decryption mechanism that would allow anyone who wanted to to verify that the vote cast (in its encrypted state) was the same as the vote revealed.

If you wanted to protect the addresses of the voters even after the reveal you would have to resort to something like a zk-snark, but I can't even begin to tell you how that would work.

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.