80 lines
2.5 KiB
Solidity
80 lines
2.5 KiB
Solidity
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
pragma solidity ^0.8.13;
|
|
|
|
contract BallotDraft {
|
|
struct ballotVoter {
|
|
uint delegateWeight;
|
|
bool voteSpent;
|
|
address delegateTo;
|
|
uint voteIndex;
|
|
}
|
|
|
|
struct Proposal {
|
|
bytes32 proposalName;
|
|
uint voteCount;
|
|
}
|
|
|
|
address public chairman;
|
|
mapping(address => ballotVoter) public ballotVoters;
|
|
Proposal[] public proposalsOption;
|
|
|
|
function Ballot(bytes32[] proposalNames) external {
|
|
chairman = msg.sender;
|
|
ballotVoters[chairman].delegateWeight = 1;
|
|
for (uint i = 0; i < proposalNames.length; i++) {
|
|
proposalsOption.push(Proposal({
|
|
proposalName: proposalNames[i] ,
|
|
voteCount: 0
|
|
}));
|
|
}
|
|
}
|
|
|
|
function giveVotingRights(address ballotVoter) external {
|
|
require((msg.sender == chairman) && !ballotVoters[ballotvoter].voteSpent && (ballotVoters[ballotvoter].delegateWeight == 0));
|
|
ballotVoters[ballotvoter].delegateWeight = 1;
|
|
}
|
|
|
|
function delegateTo(address to) external {
|
|
ballotVoter storage sender = ballotVoters[msg.sender];
|
|
require(!sender.voteSpent);
|
|
require(to != msg.sender);
|
|
while (ballotVoters[to].delegateTo != address(0)) {
|
|
to = ballotVoters[to].delegateTo;
|
|
require(to != msg.sender);
|
|
}
|
|
|
|
sender.voteSpent = true;
|
|
sender.delegateTo = to;
|
|
ballotVoter storage delegateTo = ballotVoters[to];
|
|
if (delegateTo.voteSpent) {
|
|
proposalsOption[delegateTo.voteIndex].voteCount += sender.delegateWeight;
|
|
} else {
|
|
delegateTo.delegateWeight += sender.delegateWeight;
|
|
}
|
|
}
|
|
|
|
function voteIndex(uint proposal) external {
|
|
ballotVoter storage sender = ballotVoters[msg.sender];
|
|
require(!sender.voteSpent);
|
|
sender.voteSpent = true;
|
|
sender.voteIndex = proposal;
|
|
proposalsOption[proposal].voteCount += sender.delegateWeight;
|
|
}
|
|
|
|
function winnerProposal() external returns (uint winnerProposal) {
|
|
uint winnerVoteCount = 0;
|
|
for (uint p = 0; p < proposalsOption.length; p++) {
|
|
if (proposalsOption[p].voteCount > winnerVoteCount) {
|
|
winnerVoteCount = proposalsOption[p].voteCount;
|
|
winnerProposal = p;
|
|
}
|
|
}
|
|
}
|
|
|
|
function winner() external
|
|
returns (bytes32 winner)
|
|
{
|
|
winner = proposalsOption[winnerProposal()].proposalName;
|
|
}
|
|
}
|