-
Notifications
You must be signed in to change notification settings - Fork 0
/
Voting.sol
143 lines (105 loc) · 5.26 KB
/
Voting.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import "../node_modules/@openzeppelin/contracts/access/Ownable.sol";
contract Voting is Ownable {
uint public winningProposalID;
struct Voter {
bool isRegistered;
bool hasVoted;
uint votedProposalId;
}
struct Proposal {
string description;
uint voteCount;
}
enum WorkflowStatus {
RegisteringVoters,
ProposalsRegistrationStarted,
ProposalsRegistrationEnded,
VotingSessionStarted,
VotingSessionEnded,
VotesTallied
}
WorkflowStatus public workflowStatus;
Proposal[] proposalsArray;
mapping (address => Voter) voters;
event VoterRegistered(address voterAddress);
event WorkflowStatusChange(WorkflowStatus previousStatus, WorkflowStatus newStatus);
event ProposalRegistered(uint proposalId);
event Voted (address voter, uint proposalId);
modifier onlyVoters() {
require(voters[msg.sender].isRegistered, "You're not a voter");
_;
}
// on peut faire un modifier pour les états
// ::::::::::::: GETTERS ::::::::::::: //
function getVoter(address _addr) external onlyVoters view returns (Voter memory) {
return voters[_addr];
}
function getOneProposal(uint _id) external onlyVoters view returns (Proposal memory) {
return proposalsArray[_id];
}
// ::::::::::::: REGISTRATION ::::::::::::: //
function addVoter(address _addr) external onlyOwner {
require(workflowStatus == WorkflowStatus.RegisteringVoters, 'Voters registration is not open yet');
require(voters[_addr].isRegistered != true, 'Already registered');
voters[_addr].isRegistered = true;
emit VoterRegistered(_addr);
}
// ::::::::::::: PROPOSAL ::::::::::::: //
function addProposal(string calldata _desc) external onlyVoters {
require(workflowStatus == WorkflowStatus.ProposalsRegistrationStarted, 'Proposals are not allowed yet');
require(keccak256(abi.encode(_desc)) != keccak256(abi.encode("")), 'Vous ne pouvez pas ne rien proposer'); // facultatif
// voir que desc est different des autres
Proposal memory proposal;
proposal.description = _desc;
proposalsArray.push(proposal);
emit ProposalRegistered(proposalsArray.length-1);
}
// ::::::::::::: VOTE ::::::::::::: //
function setVote( uint _id) external onlyVoters {
require(workflowStatus == WorkflowStatus.VotingSessionStarted, 'Voting session havent started yet');
require(voters[msg.sender].hasVoted != true, 'You have already voted');
require(_id < proposalsArray.length, 'Proposal not found'); // pas obligé, et pas besoin du >0 car uint
voters[msg.sender].votedProposalId = _id;
voters[msg.sender].hasVoted = true;
proposalsArray[_id].voteCount++;
emit Voted(msg.sender, _id);
}
// ::::::::::::: STATE ::::::::::::: //
function startProposalsRegistering() external onlyOwner {
require(workflowStatus == WorkflowStatus.RegisteringVoters, 'Registering proposals cant be started now');
workflowStatus = WorkflowStatus.ProposalsRegistrationStarted;
Proposal memory proposal;
proposal.description = "GENESIS";
proposalsArray.push(proposal);
emit WorkflowStatusChange(WorkflowStatus.RegisteringVoters, WorkflowStatus.ProposalsRegistrationStarted);
}
function endProposalsRegistering() external onlyOwner {
require(workflowStatus == WorkflowStatus.ProposalsRegistrationStarted, 'Registering proposals havent started yet');
workflowStatus = WorkflowStatus.ProposalsRegistrationEnded;
emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationStarted, WorkflowStatus.ProposalsRegistrationEnded);
}
function startVotingSession() external onlyOwner {
require(workflowStatus == WorkflowStatus.ProposalsRegistrationEnded, 'Registering proposals phase is not finished');
workflowStatus = WorkflowStatus.VotingSessionStarted;
emit WorkflowStatusChange(WorkflowStatus.ProposalsRegistrationEnded, WorkflowStatus.VotingSessionStarted);
}
function endVotingSession() external onlyOwner {
require(workflowStatus == WorkflowStatus.VotingSessionStarted, 'Voting session havent started yet');
workflowStatus = WorkflowStatus.VotingSessionEnded;
emit WorkflowStatusChange(WorkflowStatus.VotingSessionStarted, WorkflowStatus.VotingSessionEnded);
}
function tallyVotes() external onlyOwner {
require(workflowStatus == WorkflowStatus.VotingSessionEnded, "Current status is not voting session ended");
uint _winningProposalId;
for (uint256 p = 0; p < proposalsArray.length; p++) {
if (proposalsArray[p].voteCount > proposalsArray[_winningProposalId].voteCount) {
_winningProposalId = p;
}
}
winningProposalID = _winningProposalId;
workflowStatus = WorkflowStatus.VotesTallied;
emit WorkflowStatusChange(WorkflowStatus.VotingSessionEnded, WorkflowStatus.VotesTallied);
}
}