Advertisement
Guest User

Untitled

a guest
Aug 25th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. pragma solidity >=0.4.22 <0.7.0;
  2.  
  3. /// @title Voting with delegation.
  4. contract Ballot {
  5. // This declares a new complex type which will
  6. // be used for variables later.
  7. // It will represent a single voter.
  8. struct Voter {
  9. uint weight; // weight is accumulated by delegation
  10. bool voted; // if true, that person already voted
  11. address delegate; // person delegated to
  12. uint vote; // index of the voted proposal
  13. }
  14.  
  15. // This is a type for a single proposal.
  16. struct Proposal {
  17. bytes32 name; // short name (up to 32 bytes)
  18. uint voteCount; // number of accumulated votes
  19. }
  20.  
  21. address public chairperson;
  22.  
  23. // This declares a state variable that
  24. // stores a `Voter` struct for each possible address.
  25. mapping(address => Voter) public voters;
  26.  
  27. // A dynamically-sized array of `Proposal` structs.
  28. Proposal[] public proposals;
  29.  
  30. /// Create a new ballot to choose one of `proposalNames`.
  31. constructor(bytes32[] memory proposalNames) public {
  32. chairperson = msg.sender;
  33. voters[chairperson].weight = 1;
  34.  
  35. // For each of the provided proposal names,
  36. // create a new proposal object and add it
  37. // to the end of the array.
  38. for (uint i = 0; i < proposalNames.length; i++) {
  39. // `Proposal({...})` creates a temporary
  40. // Proposal object and `proposals.push(...)`
  41. // appends it to the end of `proposals`.
  42. proposals.push(Proposal({
  43. name: proposalNames[i],
  44. voteCount: 0
  45. }));
  46. }
  47. }
  48.  
  49. // Give `voter` the right to vote on this ballot.
  50. // May only be called by `chairperson`.
  51. function giveRightToVote(address voter) public {
  52. // If the first argument of `require` evaluates
  53. // to `false`, execution terminates and all
  54. // changes to the state and to Ether balances
  55. // are reverted.
  56. // This used to consume all gas in old EVM versions, but
  57. // not anymore.
  58. // It is often a good idea to use `require` to check if
  59. // functions are called correctly.
  60. // As a second argument, you can also provide an
  61. // explanation about what went wrong.
  62. require(
  63. msg.sender == chairperson,
  64. "Only chairperson can give right to vote."
  65. );
  66. require(
  67. !voters[voter].voted,
  68. "The voter already voted."
  69. );
  70. require(voters[voter].weight == 0, "Voter needs to have weight");
  71. voters[voter].weight = 1;
  72. }
  73.  
  74. /// Delegate your vote to the voter `to`.
  75. function delegate(address to) public view{
  76. // assigns reference
  77. Voter storage sender = voters[msg.sender];
  78. require(!sender.voted, "You already voted.");
  79.  
  80. require(to != msg.sender, "Self-delegation is disallowed.");
  81.  
  82. // Forward the delegation as long as
  83. // `to` also delegated.
  84. // In general, such loops are very dangerous,
  85. // because if they run too long, they might
  86. // need more gas than is available in a block.
  87. // In this case, the delegation will not be executed,
  88. // but in other situations, such loops might
  89. // cause a contract to get "stuck" completely.
  90. while (voters[to].delegate != address(0)) {
  91. to = voters[to].delegate;
  92.  
  93. // We found a loop in the delegation, not allowed.
  94. require(to != msg.sender, "Found loop in delegation.");
  95. }
  96.  
  97. // Since `sender` is a reference, this
  98. // modifies `voters[msg.sender].voted`
  99. sender.voted = true;
  100. sender.delegate = to;
  101. Voter storage delegate_ = voters[to];
  102. if (delegate_.voted) {
  103. // If the delegate already voted,
  104. // directly add to the number of votes
  105. proposals[delegate_.vote].voteCount += sender.weight;
  106. } else {
  107. // If the delegate did not vote yet,
  108. // add to her weight.
  109. delegate_.weight += sender.weight;
  110. }
  111. }
  112.  
  113. /// Give your vote (including votes delegated to you)
  114. /// to proposal `proposals[proposal].name`.
  115. function vote(uint proposal) public {
  116. Voter storage sender = voters[msg.sender];
  117. require(sender.weight != 0, "Has no right to vote");
  118. require(!sender.voted, "Already voted.");
  119. sender.voted = true;
  120. sender.vote = proposal;
  121.  
  122. // If `proposal` is out of the range of the array,
  123. // this will throw automatically and revert all
  124. // changes.
  125. proposals[proposal].voteCount += sender.weight;
  126. }
  127.  
  128. /// @dev Computes the winning proposal taking all
  129. /// previous votes into account.
  130. function winningProposal() public view
  131. returns (uint winningProposal_)
  132. {
  133. uint winningVoteCount = 0;
  134. for (uint p = 0; p < proposals.length; p++) {
  135. if (proposals[p].voteCount > winningVoteCount) {
  136. winningVoteCount = proposals[p].voteCount;
  137. winningProposal_ = p;
  138. }
  139. }
  140. }
  141.  
  142. // Calls winningProposal() function to get the index
  143. // of the winner contained in the proposals array and then
  144. // returns the name of the winner
  145. function winnerName() public view
  146. returns (bytes32 winnerName_)
  147. {
  148. winnerName_ = proposals[winningProposal()].name;
  149. }
  150. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement