Skip to content

Commit

Permalink
Added voting.sol to contracts (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
mac-lawson committed Nov 13, 2023
1 parent 67d3be2 commit 5fff46a
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions contracts/voting.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
pragma solidity >=0.7.0 <0.9.0;

contract Ballot {
struct Voter {
uint weight;
bool voted;
address delegate;
uint vote;
}

struct Proposal {
bytes32 name;
uint voteCount;
}

address public chairperson;
mapping(address => Voter) public voters;
Proposal[] public proposals;

constructor(bytes32[] memory proposalNames) {
chairperson = msg.sender;
voters[chairperson].weight = 1;

for (uint i = 0; i < proposalNames.length; i++) {
proposals.push(Proposal({
name: proposalNames[i],
voteCount: 0
}));
}
}

function giveRightToVote(address voter) external {
require(msg.sender == chairperson, "Only chairperson can give right to vote.");
require(!voters[voter].voted, "The voter already voted.");
require(voters[voter].weight == 0);
voters[voter].weight = 1;
}

function delegate(address to) external {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "You have no right to vote");
require(!sender.voted, "You already voted.");
require(to != msg.sender, "Self-delegation is disallowed.");

while (voters[to].delegate != address(0)) {
to = voters[to].delegate;
require(to != msg.sender, "Found loop in delegation.");
}

Voter storage delegate_ = voters[to];
require(delegate_.weight >= 1);

sender.voted = true;
sender.delegate = to;

if (delegate_.voted) {
proposals[delegate_.vote].voteCount += sender.weight;
} else {
delegate_.weight += sender.weight;
}
}

function vote(uint proposal) external {
Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted.");
sender.voted = true;
sender.vote = proposal;

proposals[proposal].voteCount += sender.weight;
}

function winningProposal() public view returns (uint winningProposal_) {
uint winningVoteCount = 0;
for (uint p = 0; p < proposals.length; p++) {
if (proposals[p].voteCount > winningVoteCount) {
winningVoteCount = proposals[p].voteCount;
winningProposal_ = p;
}
}
}

function winnerName() external view returns (bytes32 winnerName_) {
winnerName_ = proposals[winningProposal()].name;
}
}

0 comments on commit 5fff46a

Please sign in to comment.