Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.28 KB | None | 0 0
  1. pragma solidity ^0.4.22;
  2.  
  3. /// @title การลงคะแนนเสียงแบบโอนสิทธิให้ตัวแทนได้
  4. /// @notice เป็นการสรา้งระบบลงคะแนนเสียง โดยผู้สรา้งการลงคะแนนสามารถกำหนดผู้ลงคะแนนได้ ขณะเดียวกันก็สามารถโอนสิทธิไปให้ผู้อื่นลงคะแนนได้
  5. /// @dev เริ่มต้นจะต้องระบุข้อเสนอทั้งหมดในการลงคะแนนก่อน(โครงสร้างตาม Proposal)
  6. contract Ballot {
  7.  
  8. // โครงสรา้ง(struct)ของผู้มีสิทธิโหวด
  9. struct Voter {
  10. uint weight; // นำ้หนักในาการให้คะแนนรวมถึงการได้รับการโอนสิทธิจากเจ้าของแล้ว
  11. bool voted; // สถานะการโหวดถ้าเป็น true หมายถึงว่ามีการโหวดแล้ว
  12. address delegate; // ตำแหน่งของผู้ลงคะแนนที่ให้มอบสิทธิให้
  13. uint vote; // index ที่ชั้ไปยังข้อเสนอที่เลือกไว้
  14. }
  15.  
  16. // โครงสร้างของข้อเสนอ (Poporsal) ที่ใช้ในการโหวด
  17. struct Proposal {
  18. bytes32 name; // หัวข้อของข้อเสนอ (ขนาดสูงสุด 32 bytes)
  19. uint voteCount; // คะแนนสะสมของผู้โหวดข้อเสนอนี้
  20. }
  21.  
  22. //กำหนดตำแหน่ง(adderess) ประธานการลงคะแนนเสียง
  23. address public chairperson;
  24.  
  25. //กำหนดเก็บผู้ลงคะแนนทั้งหมด(voters) โดยโครงสร้างข้อมูล จะเป็นตาม Voter และทำตารางเทียบกับ address ของผู้ได้รับสิทธิ
  26. mapping(address => Voter) public voters;
  27.  
  28. // ตัวแปรในการเก็บกลุ่มของข้อเสนอ
  29. Proposal[] public proposals;
  30.  
  31. ///@dev contructor ของ smart contract นี้โดยส่งอาร์เรย์ของข้อเสนอทั้งหมด
  32. constructor(bytes32[] proposalNames) public {
  33. //เก็บตำแหน่ง(address) ของผู้สรา้ง(ประธาน)การลงคะแนนเสียงนี้
  34. chairperson = msg.sender;
  35.  
  36. //กำหนดประธานให้สามารถเป็นผู้ลงคะแนนได้ และให้กำหนดน้ำหนักเป็น 1
  37. voters[chairperson].weight = 1;
  38.  
  39. //แต่ละครั้งที่ีมีการระบุข้อเสนอเข้าไป จะเป็นการเพิ่มข้อเสนอต่อท้ายอาร์์เรย์ของข้อเสนอที่มีอยู่
  40. for (uint i = 0; i < proposalNames.length; i++) {
  41. // สร้าง temporay object ของ Proposal และต่อทั้ง (push) ต่อไปยังอาร์เรย์ของข้อเสนอ proposals
  42. proposals.push(Proposal({
  43. name: proposalNames[i],
  44. voteCount: 0
  45. }));
  46. }
  47. }
  48.  
  49. ///@noitce กำหนดผู้ที่มีสิทธิในกระลงคะแนน(ผู้ที่ใช้ได้ต้องเป็นประธานการลงคะแนนเท่านั้น)
  50. function giveRightToVote(address voter) public {
  51. //ตรวจสอบว่าผู้เรียกใช้งานเป็นผู้สรา้ง(ประธาน) การลงคะแนนหรือไม่
  52. require(
  53. msg.sender == chairperson,
  54. "Only chairperson can give right to vote."
  55. );
  56. //ตรวจสอบว่าผู้ถูกกำหนดให้ลงคะแนนเคยลงคะแนนไปแล้วรึยัง
  57. require(
  58. !voters[voter].voted,
  59. "The voter already voted."
  60. );
  61.  
  62. require(voters[voter].weight == 0);
  63. voters[voter].weight = 1;
  64. }
  65.  
  66. ///@notice ให้สิทธิในการลงคะแนนไปที่ผู้อื่น
  67. ///@param to ตำแหน่ง(address) ของผู้ที่ให้สิทธิในการลงคะแนน
  68. function delegate(address to) public {
  69. // เรียกหาผู้ลงคะแนนโดยอ้างอิงจากจากตำแหน่งของผู้เรียก smart contract
  70. Voter storage sender = voters[msg.sender];
  71.  
  72. //ตรวจสอบว่าผู้ให้สิทธิเคยลงคะแนนไปแล้วหรือยัง
  73. require(!sender.voted, "You already voted.");
  74.  
  75. //ตรวจสอบว่าผู้ให้สิทธิให้สิทธิตัวเองหรือไม่
  76. require(to != msg.sender, "Self-delegation is disallowed.");
  77.  
  78. // Forward the delegation as long as
  79. // `to` also delegated.
  80. // In general, such loops are very dangerous,
  81. // because if they run too long, they might
  82. // need more gas than is available in a block.
  83. // In this case, the delegation will not be executed,
  84. // but in other situations, such loops might
  85. // cause a contract to get "stuck" completely.
  86.  
  87. while (voters[to].delegate != address(0)) {
  88. to = voters[to].delegate;
  89.  
  90. // We found a loop in the delegation, not allowed.
  91. require(to != msg.sender, "Found loop in delegation.");
  92. }
  93.  
  94. //กำหนดสถานะผู้ให้สิทธิลงคะแนน เป็นลงคะแนนแล้ว และกำหนดผู้ที่รับสิทธิ
  95. sender.voted = true;
  96. sender.delegate = to;
  97. //เลือกผู้ลงคะแนนโดยอ้างจากผู้ได้รับสิทธิ
  98. Voter storage delegate_ = voters[to];
  99. //ตรวจสอบว่าผู้ได้รับสิทธิ ได้ทำการลงคะแนนรึยัง
  100. if (delegate_.voted) {
  101. // ถ้าเคยลงคะแนนแล้วให้เพิ่มน้ำหนักไปยังข้อเสนอที่ผู้ได้รับสิทธิเลือกไว้แล้ว
  102. // directly add to the number of votes
  103. proposals[delegate_.vote].voteCount += sender.weight;
  104. } else {
  105. // ถ้ายังไม่เคยลงคะแนนให้เพิ่มน้ำหนักการลงคะแนน
  106. delegate_.weight += sender.weight;
  107. }
  108. }
  109.  
  110. /// @notice ลงคะแนน Give your vote (including votes delegated to you)
  111. /// @param proposal index ของข้อเสนอที่ต้องการเลือก
  112. function vote(uint proposal) public {
  113. //กำหนดผู้ลงคะแนนโดยอ้างจากตำแหน่งผู้เรียก smart contract
  114. Voter storage sender = voters[msg.sender];
  115.  
  116. //ตรวจสอบว่าผู้ลงคะแนนทำการลงคะแนนไปแล้วรึยัง
  117. require(!sender.voted, "Already voted.");
  118.  
  119. //กำหนด index ของข้อเสนอพร้อมกับกำหนดว่าเป็นผู้ลงคะแนนแล้ว
  120. sender.voted = true;
  121. sender.vote = proposal;
  122.  
  123. //เพิ่มคะแนนสะสมให้กับข้อเสนอนั้นตามน้ำหนักที่ผู้ลงคะแนนได้รับ
  124. proposals[proposal].voteCount += sender.weight;
  125. //ในกรณีที่ index ของข้อเสนอที่ป้อนเข้ามาอยู่นอกอาร์เรย์ มันจะออกจาก smart contract นี้โดยอัตโนมัติ พร้อมกับยกเลิกการเปลี่ยนแปลงทั้งหมด
  126. }
  127.  
  128. /// @notice ข้อเสนอที่ชนะการลงคะแนน
  129. /// @return index ที่ชี้ไปยังข้อเสนอที่มีผู้ลงคะแนนเลือกมากสุด
  130. /// @dev Computes the winning proposal taking all previous votes into account.
  131. function winningProposal() public view
  132. returns (uint winningProposal_)
  133. {
  134. uint winningVoteCount = 0;
  135. //วนลูปไปทุกข้อเสนอ และหาข้อเสนอที่มีคะแนนสะสมสูงสุด
  136. for (uint p = 0; p < proposals.length; p++) {
  137. if (proposals[p].voteCount > winningVoteCount) {
  138. winningVoteCount = proposals[p].voteCount;
  139. winningProposal_ = p;
  140. }
  141. }
  142. }
  143.  
  144. ///@notice แสดงข้อเสนอที่ชนะการลงคะแนน
  145. ///@return ชื่อของข้อเสนอที่ชนะการลงคะแนน
  146. function winnerName() public view
  147. returns (bytes32 winnerName_)
  148. {
  149. //เรียกใช้ฟังก์ชัน winningProposal() ในการเรียก index ของข้อเสนอที่มีผู้ลงคะแนนมากสุดจากเรียกชื่อจาก index ในอาร์เรย์
  150. winnerName_ = proposals[winningProposal()].name;
  151. }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement