Guest User

Untitled

a guest
Jan 13th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.86 KB | None | 0 0
  1. pragma solidity ^0.4.16;
  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. function Ballot(bytes32[] 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 argument of `require` evaluates to `false`,
  53. // it terminates and reverts all changes to
  54. // the state and to Ether balances. It is often
  55. // a good idea to use this if functions are
  56. // called incorrectly. But watch out, this
  57. // will currently also consume all provided gas
  58. // (this is planned to change in the future).
  59. require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0));
  60. voters[voter].weight = 1;
  61. }
  62.  
  63. /// Delegate your vote to the voter `to`.
  64. function delegate(address to) public {
  65. // assigns reference
  66. Voter storage sender = voters[msg.sender];
  67. require(!sender.voted);
  68.  
  69. // Self-delegation is not allowed.
  70. require(to != msg.sender);
  71.  
  72. // Forward the delegation as long as
  73. // `to` also delegated.
  74. // In general, such loops are very dangerous,
  75. // because if they run too long, they might
  76. // need more gas than is available in a block.
  77. // In this case, the delegation will not be executed,
  78. // but in other situations, such loops might
  79. // cause a contract to get "stuck" completely.
  80. while (voters[to].delegate != address(0)) {
  81. to = voters[to].delegate;
  82.  
  83. // We found a loop in the delegation, not allowed.
  84. require(to != msg.sender);
  85. }
  86.  
  87. // Since `sender` is a reference, this
  88. // modifies `voters[msg.sender].voted`
  89. sender.voted = true;
  90. sender.delegate = to;
  91. Voter storage delegate = voters[to];
  92. if (delegate.voted) {
  93. // If the delegate already voted,
  94. // directly add to the number of votes
  95. proposals[delegate.vote].voteCount += sender.weight;
  96. } else {
  97. // If the delegate did not vote yet,
  98. // add to her weight.
  99. delegate.weight += sender.weight;
  100. }
  101. }
  102.  
  103. /// Give your vote (including votes delegated to you)
  104. /// to proposal `proposals[proposal].name`.
  105. function vote(uint proposal) public {
  106. Voter storage sender = voters[msg.sender];
  107. require(!sender.voted);
  108. sender.voted = true;
  109. sender.vote = proposal;
  110.  
  111. // If `proposal` is out of the range of the array,
  112. // this will throw automatically and revert all
  113. // changes.
  114. proposals[proposal].voteCount += sender.weight;
  115. }
  116.  
  117. /// @dev Computes the winning proposal taking all
  118. /// previous votes into account.
  119. function winningProposal() public view
  120. returns (uint winningProposal)
  121. {
  122. uint winningVoteCount = 0;
  123. for (uint p = 0; p < proposals.length; p++) {
  124. if (proposals[p].voteCount > winningVoteCount) {
  125. winningVoteCount = proposals[p].voteCount;
  126. winningProposal = p;
  127. }
  128. }
  129. }
  130.  
  131. // Calls winningProposal() function to get the index
  132. // of the winner contained in the proposals array and then
  133. // returns the name of the winner
  134. function winnerName() public view
  135. returns (bytes32 winnerName)
  136. {
  137. winnerName = proposals[winningProposal()].name;
  138. }
  139. }
Add Comment
Please, Sign In to add comment