-
Notifications
You must be signed in to change notification settings - Fork 0
/
Voting.sol
168 lines (124 loc) · 5.27 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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// SPDX-License-Identifier: GPL-3.0
pragma experimental ABIEncoderV2;
pragma solidity >=0.7.0 <0.9.0;
// 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
/**
* @title Ballot
* @dev Implements voting process along with vote delegation
*/
contract Ballot {
struct Voter {
uint token;
bool voted; // if true, that person already voted
uint vote; // index of the voted proposal
address voterAddress;
}
struct Proposal {
bytes32 name; // short name (up to 32 bytes)
uint voteCount; // number of accumulated votes
}
address private government;
mapping(address => Voter) public voters;
Proposal[] public proposals;
uint private winningVoteCount = 0;
uint private tmpWinnerCount = 0;
uint public totalVote;
uint public voterCount;
uint private voteFinishTime;
uint private statViewFinishTime;
modifier alreadyVoted() {
require(!voters[msg.sender].voted, "Already voted.");
_;
}
modifier multipleWinner() {
_;
require(winningVoteCount != 0, "No vote submitted.");
require(tmpWinnerCount < 2, "Two or more candidate has been voted equally");
}
modifier onlyVoters() {
require(msg.sender != government, "Government cannot check vote.");
_;
}
modifier onlyValidVoters() {
require(voters[msg.sender].voted == false && voters[msg.sender].token != 0, "Only valid voters can cast a vote!");
_;
}
/**
* @dev Create a new ballot to choose one of 'proposalNames'.
* @param proposalNames names of proposals
*/
constructor(bytes32[] memory proposalNames, address[] memory voterArr, uint voteFinishTime_, uint statViewFinishTime_) {
government = msg.sender;
for (uint i = 0; i < proposalNames.length; i++) {
// 'Proposal({...})' creates a temporary
// Proposal object and 'proposals.push(...)'
// appends it to the end of 'proposals'.
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
totalVote = 0;
voterCount = voterArr.length;
voteFinishTime = voteFinishTime_;
statViewFinishTime = statViewFinishTime_;
for (uint i = 0; i < voterArr.length; i++) {
voters[voterArr[i]].token = 1;
}
}
/**
Adaylar:
["0x63616e6469646174653100000000000000000000000000000000000000000000","0x6332000000000000000000000000000000000000000000000000000000000000","0x6333000000000000000000000000000000000000000000000000000000000000"]
Seçmenler:
["0xdD870fA1b7C4700F2BD7f44238821C26f7392148", "0x583031D1113aD414F02576BD6afaBfb302140225", "0x4B0897b0513fdC7C541B6d9D7E929C4e5364D2dB"]
*/
function vote(uint proposal) public alreadyVoted() onlyValidVoters() {
Voter storage sender = voters[msg.sender];
require(sender.token != 0, "Has no right to vote");
require(block.timestamp < voteFinishTime, "Election has been finished! You cannot vote.");
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount += sender.token;
totalVote += sender.token;
sender.token -= 1;
}
function winningProposal() private multipleWinner()
returns (uint winningProposal_) {
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
tmpWinnerCount = 1;
}
if (proposals[p].voteCount == winningVoteCount) {
tmpWinnerCount += 1;
}
}
}
/**
* @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then
* @return winnerName_ the name of the winner
*/
function winnerName() public
returns (bytes32 winnerName_)
{
require(block.timestamp > voteFinishTime, "Election has not been finished yet.");
winnerName_ = proposals[winningProposal()].name;
}
function checkMyVote() public view onlyVoters() returns (bytes32 proposalName) {
require(voters[msg.sender].voted, "You have not voted yet!");
uint vote_index = voters[msg.sender].vote;
return proposals[vote_index].name;
}
function getElectionResult() external view returns (bytes32[] memory names, uint[] memory voteCounts) {
require( block.timestamp > statViewFinishTime, "Election has not been finished! You cannot view the results.");
bytes32[] memory namesArr = new bytes32[](proposals.length);
uint[] memory voteCountsArr = new uint[](proposals.length);
for (uint i = 0; i < proposals.length; i++) {
Proposal storage proposal = proposals[i];
namesArr[i] = proposal.name;
voteCountsArr[i] = proposal.voteCount;
}
return (namesArr, voteCountsArr);
}
}