Created
February 10, 2023 00:30
-
-
Save pom421/4ebee88be7abbeb8d34a61d8dc531a4e to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.18+commit.87f61d96.js&optimize=false&runs=200&gist=
This file contains hidden or 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
// SPDX-License-Identifier: GPL-3.0 | |
pragma solidity 0.8.18; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
/** | |
* @title Voting | |
*/ | |
contract Voting is Ownable { | |
event VoterRegistered(address voter); | |
event WorkflowStatusChange( | |
WorkflowStatus previousStatus, | |
WorkflowStatus newStatus | |
); | |
event ProposalRegistered(uint256 proposalId); | |
event Voted(address voter, uint256 proposalId); | |
event WinnerAfterTally(uint256 proposalId); | |
struct Voter { | |
bool isRegistered; | |
bool hasVoted; | |
uint256 votedProposalId; | |
} | |
struct Proposal { | |
string description; | |
uint256 voteCount; | |
} | |
enum WorkflowStatus { | |
RegisteringVoters, | |
ProposalsRegistrationStarted, | |
ProposalsRegistrationEnded, | |
VotingSessionStarted, | |
VotingSessionEnded, | |
VotesTallied | |
} | |
uint256 public winningProposalId; | |
WorkflowStatus currentStatus; | |
mapping(address => Voter) public voters; | |
Proposal[] public proposals; | |
uint256 private proposalId; // To track the index of the last proposal. | |
modifier mustBeInWorkflowStatus(WorkflowStatus _status) { | |
require( | |
currentStatus == _status, | |
"Operation not allowed in the current workflow status." | |
); | |
_; | |
} | |
modifier isElector() { | |
require( | |
voters[msg.sender].isRegistered == true, | |
"The voter is already on the white list." | |
); | |
_; | |
} | |
modifier notPresentInWhitelist(address _address) { | |
require( | |
voters[_address].isRegistered == false, | |
"The voter is already on the white list." | |
); | |
_; | |
} | |
// emit WorkflowStatusChange RegisteringVoters | |
//constructor(); | |
function addVoter(address _address) | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.RegisteringVoters) | |
notPresentInWhitelist(_address) | |
{ | |
voters[_address] = Voter({ | |
isRegistered: true, | |
hasVoted: false, | |
votedProposalId: 0 | |
}); | |
emit VoterRegistered(_address); | |
} | |
function addProposal(string calldata _description) | |
external | |
mustBeInWorkflowStatus(WorkflowStatus.ProposalsRegistrationStarted) | |
isElector | |
{ | |
proposals.push(Proposal({description: _description, voteCount: 0})); | |
emit ProposalRegistered(proposalId++); // Increment proposal index. | |
} | |
function changeWorkflowStatus(WorkflowStatus _newStatus) private { | |
WorkflowStatus oldStatus = currentStatus; | |
currentStatus = _newStatus; | |
emit WorkflowStatusChange(oldStatus, currentStatus); | |
} | |
function startRegistrationProposalSession() | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.RegisteringVoters) | |
{ | |
changeWorkflowStatus(WorkflowStatus.ProposalsRegistrationStarted); | |
} | |
function endRegistrationProposalSession() | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.ProposalsRegistrationStarted) | |
{ | |
changeWorkflowStatus(WorkflowStatus.ProposalsRegistrationEnded); | |
} | |
function startVotingSession() | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.ProposalsRegistrationEnded) | |
{ | |
changeWorkflowStatus(WorkflowStatus.VotingSessionStarted); | |
} | |
function endVotingSession() | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.VotingSessionStarted) | |
{ | |
changeWorkflowStatus(WorkflowStatus.VotingSessionEnded); | |
} | |
function voteForProposal(uint256 _id) | |
external | |
mustBeInWorkflowStatus(WorkflowStatus.VotingSessionStarted) | |
isElector | |
{ | |
// Change count on proposals. | |
proposals[_id].voteCount++; | |
// Set voter as hasVoted. | |
voters[msg.sender].hasVoted = true; | |
voters[msg.sender].votedProposalId = _id; | |
// emit event | |
emit Voted(msg.sender, _id); | |
} | |
function tallyVotes() | |
external | |
onlyOwner | |
mustBeInWorkflowStatus(WorkflowStatus.VotingSessionEnded) | |
{ | |
uint256 winnerId = 0; | |
uint256 maxCount = 0; | |
for (uint256 i = 0; i < proposals.length; i++) { | |
if (proposals[i].voteCount > maxCount) { | |
winnerId = i; | |
maxCount = proposals[i].voteCount; | |
} | |
} | |
winningProposalId = winnerId; | |
emit WinnerAfterTally(winnerId); | |
changeWorkflowStatus(WorkflowStatus.VotesTallied); | |
} | |
function getWinner() | |
external | |
view | |
mustBeInWorkflowStatus(WorkflowStatus.VotesTallied) | |
returns (uint256) | |
{ | |
return winningProposalId; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment