-
-
Save Manasse228/477b1cbb4f2f44f84fabaf622342fb4d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.7; | |
contract CommitRevealElection { | |
// The two choices for your vote | |
string public choice1; | |
string public choice2; | |
// Information about the current status of the vote | |
uint public votesForChoice1; | |
uint public votesForChoice2; | |
uint public commitPhaseEndTime; | |
uint public numberOfVotesCast = 0; | |
// The actual votes and vote commits | |
bytes32[] public voteCommits; | |
mapping(bytes32 => string) voteStatuses; // Either `Committed` or `Revealed` | |
// Events used to log what's going on in the contract | |
event logString(string); | |
event newVoteCommit(string, bytes32); | |
event voteWinner(string, string); | |
// Constructor used to set parameters for the this specific vote | |
function CommitRevealElection(uint _commitPhaseLengthInSeconds, | |
string _choice1, | |
string _choice2) { | |
if (_commitPhaseLengthInSeconds < 20) { | |
throw; | |
} | |
commitPhaseEndTime = now + _commitPhaseLengthInSeconds * 1 seconds; | |
choice1 = _choice1; | |
choice2 = _choice2; | |
} | |
function commitVote(bytes32 _voteCommit) { | |
if (now > commitPhaseEndTime) throw; // Only allow commits during committing period | |
// Check if this commit has been used before | |
bytes memory bytesVoteCommit = bytes(voteStatuses[_voteCommit]); | |
if (bytesVoteCommit.length != 0) throw; | |
// We are still in the committing period & the commit is new so add it | |
voteCommits.push(_voteCommit); | |
voteStatuses[_voteCommit] = "Committed"; | |
numberOfVotesCast ++; | |
newVoteCommit("Vote committed with the following hash:", _voteCommit); | |
} | |
function revealVote(string _vote, bytes32 _voteCommit) { | |
if (now < commitPhaseEndTime) throw; // Only reveal votes after committing period is over | |
// FIRST: Verify the vote & commit is valid | |
bytes memory bytesVoteStatus = bytes(voteStatuses[_voteCommit]); | |
if (bytesVoteStatus.length == 0) { | |
logString('A vote with this voteCommit was not cast'); | |
} else if (bytesVoteStatus[0] != 'C') { | |
logString('This vote was already cast'); | |
return; | |
} | |
if (_voteCommit != keccak256(_vote)) { | |
logString('Vote hash does not match vote commit'); | |
return; | |
} | |
// NEXT: Count the vote! | |
bytes memory bytesVote = bytes(_vote); | |
if (bytesVote[0] == '1') { | |
votesForChoice1 = votesForChoice1 + 1; | |
logString('Vote for choice 1 counted.'); | |
} else if (bytesVote[0] == '2') { | |
votesForChoice2 = votesForChoice2 + 1; | |
logString('Vote for choice 2 counted.'); | |
} else { | |
logString('Vote could not be read! Votes must start with the ASCII character `1` or `2`'); | |
} | |
voteStatuses[_voteCommit] = "Revealed"; | |
} | |
function getWinner () constant returns(string) { | |
// Only get winner after all vote commits are in | |
if (now < commitPhaseEndTime) throw; | |
// Make sure all the votes have been counted | |
if (votesForChoice1 + votesForChoice2 != voteCommits.length) throw; | |
if (votesForChoice1 > votesForChoice2) { | |
voteWinner("And the winner of the vote is:", choice1); | |
return choice1; | |
} else if (votesForChoice2 > votesForChoice1) { | |
voteWinner("And the winner of the vote is:", choice2); | |
return choice2; | |
} else if (votesForChoice1 == votesForChoice2) { | |
voteWinner("The vote ended in a tie!", ""); | |
return "It was a tie!"; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment