pragma solidity ^0.4.24; contract Votacion { modifier onlyOwner() { require(isOwner(msg.sender)); _; } uint public voteStartTime; uint public voteEndTime; uint16 private voterCount; string public votingTitle; address public owner; uint8 public candidateCount; uint16 public accountedVotes; uint16 public nulledVotes; uint16 public votesLeft; bool public isPostulationEnabled; event Voted (bytes24 _token); event newVoterId (uint _voterId); event voteAccounted (bytes32 _candidateName, uint _votesReceived, uint16 _totalVotesAccounted); event voteNulled (uint16 _voterId, uint16 _totalVotesAccounted); mapping (bytes32 => uint16) private votesReceived; mapping (bytes32 => bool) public votesCasted; mapping (uint8 => string) private candidateNames; bytes32[] private candidateList; bytes32[] private votingOptions; struct Counter { uint16 countStart; uint16 countEnd; uint16 countLimit; uint16 accountedVotes; uint16 nulledVotes; bytes32 candidate; } constructor (bytes32[] _votingOptions, string _votingTitle, uint _startTime, uint _endTime) public { candidateCount = 0; voterCount = 0; isPostulationEnabled = true; votingOptions = _votingOptions; voteStartTime = _startTime; voteEndTime = _endTime; votingTitle = _votingTitle; nulledVotes = 0; accountedVotes = 0; owner = msg.sender; } function allCandidates() external view returns (bytes32[]) { return candidateList; } function isOwner(address addr) view public returns(bool) { return addr == owner; } function addCandidate(string candidateName) external { require (isPostulationEnabled); candidateNames[candidateCount] = candidateName; candidateList.push(stringToBytes32(candidateNames[candidateCount])); candidateCount += 1; } function closePostulations() external onlyOwner { require (isPostulationEnabled); isPostulationEnabled = false; } function countVotes() external onlyOwner { require(votingEnded()); require(votesLeft > 0); Counter memory counter = Counter((nulledVotes + accountedVotes + 1), 0, 0, accountedVotes, nulledVotes, 0x0); if (votesLeft < 100){ counter.countLimit = votesLeft; }else{ counter.countLimit = 100; } counter.countEnd = counter.nulledVotes + counter.accountedVotes + counter.countLimit; for (uint16 i = counter.countStart; i <= counter.countEnd; i++){ counter.candidate = checkVote(i); if (counter.candidate.length == 0) { counter.nulledVotes += 1; emit voteNulled(i, counter.nulledVotes); } else { votesReceived[counter.candidate] += 1; counter.accountedVotes += 1; emit voteAccounted(counter.candidate, votesReceived[counter.candidate], counter.accountedVotes); } } votesLeft -= counter.countLimit; accountedVotes = counter.accountedVotes; nulledVotes = counter.nulledVotes; } function newVoter() external { voterCount = voterCount + 1; emit newVoterId(voterCount); } function queryVote(uint16 voterId) public view returns (string) { for (uint8 x = 0; x < candidateCount; x++){ if (votesCasted[keccak256(abi.encodePacked(voterId, candidateNames[x]))] == true){ return candidateNames[x]; } } } function checkVote(uint16 voterId) internal view returns (bytes32) { for (uint8 x = 0; x < candidateCount; x++){ if (votesCasted[keccak256(abi.encodePacked(voterId, candidateNames[x]))] == true){ return stringToBytes32(candidateNames[x]); } } } function readVoterCount() external view onlyOwner returns (uint){ return voterCount; } function stringToBytes32(string memory source) internal pure returns (bytes32 result) { bytes memory tempEmptyStringTest = bytes(source); if (tempEmptyStringTest.length == 0) { return 0x0; } assembly { result := mload(add(source, 32)) } } function totalVotesFor(string candidate) external view returns (uint16) { require(votingEnded()); return votesReceived[keccak256(abi.encodePacked(candidate))]; } function voteForOption(bytes32 hashedVote, bytes24 votedFlag) external { require(msg.sender == owner); require(now >= voteStartTime); require(now <= voteEndTime); require(isPostulationEnabled == false); votesCasted[hashedVote] = true; votesLeft += 1; emit Voted(votedFlag); } function votingStarted() external view returns (bool) { return now > voteStartTime; } function votingEnded() public view returns (bool) { return now > voteEndTime; } function votingStatus() external view returns (bool) { return (now > voteStartTime) != (now > voteEndTime); } }
0.4.24