2

Let's say we are doing an election and it's easy to note that we need commit/reveal scheme to hide votes.

So, we store hashes while users commit their votes. Now, let's say the election is over. How do we count the votes ?

Solution: all users call reveal and pass their actual votes with the corresponding hash which means we get the actual vote from each one of users and we count the votes directly in reveal function. like this:

function reveal(vote) {
   require(keccak256(vote) == data[msg.sender]);
   if(vote == true) {
     trueVotes+=1;
   }else{
     falseVotes+=1;
   }
}

The problem with this solution is that all the users have to call reveal and some might forget about it at all to call it, which means we lose votes.

Are there any other solutions or how does it happen at all ?

Nika Kurashvili
  • 1,175
  • 1
  • 10
  • 25
  • If something is as simple as true or false, the hash for this is not hidden because anyone can know it. This is not a good case. – smarteasy Feb 20 '21 at 15:19
  • This doesn't answer the question. Let's say they vote on presidential names. or anything in that matter. What I am interested is how the vote counting happens – Nika Kurashvili Feb 20 '21 at 15:36
  • Incentive design is needed so that users can actively act. – smarteasy Feb 20 '21 at 15:58

1 Answers1

1

Are there any other solutions

Can't say definitively that there isn't another solution but the core problem boils down to this. If it is possible for the contract to use any form of deduction whatsoever to deduce the result then the result is calculable by everyone which clearly defeats the secrecy goal. This is the generalized problem that commit/reveal solves.

In terms of "other" solutions to rising gas costs, off-chain but cryptographically verifiable processes could possibly help. That could be decentralized given a non-trivial approach that uses incentives. I can't give you a complete solution because it would be non-trivial.

If something is as simple as true or false, the hash for this is not hidden

I thought this comment deserves a remark. He is quite right. Two possibilities means it's not even brute-force to try both and one of them will work, so nothing is really hidden. That's easily solved by adding "salt" - a secret word known only to the voter. As a further buttress, make sure salt words are never used again.

Clients can easily generate a secret and retain it until reveal-time so it doesn't have to be a burden on the users. Something like:

function vote(bool vote, bytes32 salt) ...

Hope it helps.

Rob Hitchens
  • 55,151
  • 11
  • 89
  • 145
  • Hi Rob, Thanks for commenting. I understand why salt is necessary. Without it, it's like nothing is hidden at all. If we go back to my questions about other solutions, I don't think there's. Even if you use off-chain but cryptographically verifable processes, it still requires one thing - each user still has to call reveal function and we have the same problem as I described. What's your comment on this ? – Nika Kurashvili Feb 20 '21 at 20:03
  • Also, Rob. It would be great if you could take a look at my next question: https://ethereum.stackexchange.com/questions/93727/how-does-commit-reveal-solve-front-running (Thanks a lot in advance) – Nika Kurashvili Feb 20 '21 at 20:34
  • "it still requires one thing - each user still has to call reveal function" - yes. I'm hinting at how that process is not necessarily an on-chain, gas-burning step. They need to sign something and send it somewhere, but there is some hope to optimize the process if that's the concern. – Rob Hitchens Feb 20 '21 at 20:49
  • So with your solution , i guess users dont call reveal anymore on chain and just call something else off chain and this process (counting votes) happen off chain. Is this your idea ? If so, any example material i can take a look at ? – Nika Kurashvili Feb 20 '21 at 21:01
  • Nothing especially simple. If you decided that the on-chain reveal is unacceptable, then you would move to an Oracle pattern. An Oracle could easily verify signatures. Users would still "sign" but it would be a gas-free message. You would have to consider the degree of centralization you would be willing to accept to reduce costs and the degree of complexity you would accept to prevent centralization. It's a non-trivial problem but it's not a dead end. – Rob Hitchens Feb 20 '21 at 21:26
  • I don't get how oracles ease the situations. Oracles also contain on-chain contract(these are not the requesting contracts) and off-chain nodes. and off-chain nodes feed the on-chain contracts. So, there is still the same gas costs. The only difference is the actual contract where the election happened just calls the oracle and receives the final winner of the election and this difference doesn't ease anything. – Nika Kurashvili Feb 20 '21 at 21:43
  • Any comments on this, Rob ? – Nika Kurashvili Feb 21 '21 at 19:27
  • I think Rob means to say that if you want to avoid voters from having to reveal using a second transaction on chain, you can have them commit - that's one transaction, but then you also have them sign a message and send to so called Oracles (essentially just dec. set of computers, in most cases at first stage, just your own backend server) that simply take the signed message and trigger the smart contracts at the reveal stage in your behalf, paying the gas for you and freeing you from having to have the user go through another transaction. Oracle is a bit misleading usually called Relayers. – Ami Jul 15 '23 at 08:18