SHARE
TWEET

Untitled

a guest Jun 25th, 2019 47 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top