Una prova de projecte

contract.sol 5.2KB

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

Powered by TurnKey Linux.