Skip to content

Instantly share code, notes, and snippets.

@pom421
Created February 10, 2023 00:30
Show Gist options
  • Save pom421/4ebee88be7abbeb8d34a61d8dc531a4e to your computer and use it in GitHub Desktop.
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=
// 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