ethereum(以太坊)(十二)--應用(二)__投票(基礎總和)
pragma solidity ^0.4.11; /// @title Voting with delegation. contract Ballot { // This declares(宣告) a new complex type which will // be used for variables later. // It will represent(代表) a single(單一的) voter. // (宣告一個新的class 將會成為一個變數, 會代表其中的一個投票者) struct Voter { uint weight; // weight is accumulated(積累) by delegation(委託)bool voted; // if true, that person already voted address delegate; // person delegated to (你所委託的人) uint vote; // index of the voted proposal (投票索引號) } // This is a type for a single proposal. (單個提案型別) struct Proposal { bytes32 name; // short name (up to 32 bytes)uint voteCount; // number of accumulated votes(累計票數) } address public chairperson;//主席 // This declares a state variable that // stores a `Voter` struct for each possible address. //(這裡建立裡一個投票者的變數, 用於儲存每個投票者的地址) mapping(address => Voter) public voters; // A dynamically-sized array of `Proposal` structs.(一個動態分配的票據結構)Proposal[] public proposals; /// Create a new ballot to choose one of `proposalNames`. (建立一個新的票據來選擇一個提案名稱) function Ballot(bytes32[] proposalNames) { chairperson = msg.sender; voters[chairperson].weight = 1; // For each of the provided proposal names, (每一個選舉人的名字建立單個的選舉物件, 並且新增到陣列的尾部) // create a new proposal object and add it // to the end of the array. for (uint i = 0; i < proposalNames.length; i++) { // `Proposal({...})` creates a temporary // Proposal object and `proposals.push(...)` // appends it to the end of `proposals`. (意向人物件`proposal`, 使用proposal.push(), 把意向人壓入) proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 })); } } // Give `voter` the right to vote on this ballot. (給與投票者投票權益) // May only be called by `chairperson`. (只可能是被支援人所呼叫) function giveRightToVote(address voter) { // If the argument of `require` evaluates to `false`, (如何請求的值是 false , 這個將會被終結, 並且回滾所有的改變) // it terminates and reverts all changes to // the state and to Ether balances. It is often (如果函式被非法呼叫, 這將會是個很好的辦法) // a good idea to use this if functions are // called incorrectly. But watch out, this (但是需要注意的是, 這將會消耗當前所有的 gas(在未來可能有所改善)) // will currently also consume all provided gas // (this is planned to change in the future). require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0)); voters[voter].weight = 1; } /// Delegate your vote to the voter `to`. (委託你的票到其他的可信投票者) function delegate(address to) { // assigns reference Voter storage sender = voters[msg.sender]; require(!sender.voted); //(這裡保證是沒有投過票的) // Self-delegation is not allowed. (不允許自己投給自己) require(to != msg.sender); // Forward the delegation as long as // `to` also delegated. // In general, such loops are very dangerous, // because if they run too long, they might // need more gas than is available in a block. // In this case, the delegation will not be executed, // but in other situations, such loops might // cause a contract to get "stuck" completely. //(這裡避免一個迴圈委託的可能性 , 如果A委託給B, B委託給其他人,最終到了A ) while (voters[to].delegate != address(0)) { to = voters[to].delegate; // We found a loop in the delegation, not allowed. require(to != msg.sender); } // Since `sender` is a reference, this // modifies `voters[msg.sender].voted` sender.voted = true; sender.delegate = to; Voter storage delegate = voters[to]; if (delegate.voted) { // If the delegate already voted, (如果委託投票已經投過, 直接修改票數) // directly add to the number of votes proposals[delegate.vote].voteCount += sender.weight; //(投票權重) } else { // If the delegate did not vote yet, // add to her weight. delegate.weight += sender.weight; } } /// Give your vote (including votes delegated to you) (投出你的票票) /// to proposal `proposals[proposal].name`. function vote(uint proposal) { Voter storage sender = voters[msg.sender]; require(!sender.voted); //(require 是新版的語法) sender.voted = true; sender.vote = proposal; // If `proposal` is out of the range of the array,(如果提案超出了索引範圍, 直接回滾所有資料) // this will throw automatically and revert all // changes. proposals[proposal].voteCount += sender.weight; } /// @dev Computes the winning proposal taking all (根據記票找到最終 的勝出者) /// previous votes into account. function winningProposal() constant returns (uint winningProposal) { uint winningVoteCount = 0; for (uint p = 0; p < proposals.length; p++) { if (proposals[p].voteCount > winningVoteCount) { winningVoteCount = proposals[p].voteCount; winningProposal = p; } } } // Calls winningProposal() function to get the index // of the winner contained in the proposals array and then // returns the name of the winner function winnerName() constant returns (bytes32 winnerName) { winnerName = proposals[winningProposal()].name; } }
pragma solidity ^0.4.11;
/// @title Voting with delegation.contract Ballot { // This declares(宣告) a new complex type which will // be used for variables later. // It will represent(代表) a single(單一的) voter. // (宣告一個新的class 將會成為一個變數, 會代表其中的一個投票者)
struct Voter { uint weight; // weight is accumulated(積累) by delegation(委託) bool voted; // if true, that person already voted address delegate; // person delegated to (你所委託的人) uint vote; // index of the voted proposal (投票索引號) }
// This is a type for a single proposal. (單個提案型別) struct Proposal { bytes32 name; // short name (up to 32 bytes) uint voteCount; // number of accumulated votes(累計票數) }
address public chairperson;//主席
// This declares a state variable that // stores a `Voter` struct for each possible address. //(這裡建立裡一個投票者的變數, 用於儲存每個投票者的地址) mapping(address => Voter) public voters;
// A dynamically-sized array of `Proposal` structs.(一個動態分配的票據結構) Proposal[] public proposals;
/// Create a new ballot to choose one of `proposalNames`. (建立一個新的票據來選擇一個提案名稱) function Ballot(bytes32[] proposalNames) { chairperson = msg.sender; voters[chairperson].weight = 1;
// For each of the provided proposal names, (每一個選舉人的名字建立單個的選舉物件, 並且新增到陣列的尾部) // create a new proposal object and add it // to the end of the array. for (uint i = 0; i < proposalNames.length; i++) { // `Proposal({...})` creates a temporary // Proposal object and `proposals.push(...)` // appends it to the end of `proposals`. (意向人物件`proposal`, 使用proposal.push(), 把意向人壓入) proposals.push(Proposal({ name: proposalNames[i], voteCount: 0 })); } }
// Give `voter` the right to vote on this ballot. (給與投票者投票權益) // May only be called by `chairperson`. (只可能是被支援人所呼叫) function giveRightToVote(address voter) { // If the argument of `require` evaluates to `false`, (如何請求的值是 false , 這個將會被終結, 並且回滾所有的改變) // it terminates and reverts all changes to // the state and to Ether balances. It is often (如果函式被非法呼叫, 這將會是個很好的辦法) // a good idea to use this if functions are // called incorrectly. But watch out, this (但是需要注意的是, 這將會消耗當前所有的 gas(在未來可能有所改善)) // will currently also consume all provided gas // (this is planned to change in the future). require((msg.sender == chairperson) && !voters[voter].voted && (voters[voter].weight == 0)); voters[voter].weight = 1; }
/// Delegate your vote to the voter `to`. (委託你的票到其他的可信投票者) function delegate(address to) { // assigns reference Voter storage sender = voters[msg.sender]; require(!sender.voted); //(這裡保證是沒有投過票的)
// Self-delegation is not allowed. (不允許自己投給自己) require(to != msg.sender);
// Forward the delegation as long as // `to` also delegated. // In general, such loops are very dangerous, // because if they run too long, they might // need more gas than is available in a block. // In this case, the delegation will not be executed, // but in other situations, such loops might // cause a contract to get "stuck" completely. //(這裡避免一個迴圈委託的可能性 , 如果A委託給B, B委託給其他人,最終到了A )
while (voters[to].delegate != address(0)) { to = voters[to].delegate;
// We found a loop in the delegation, not allowed. require(to != msg.sender); }
// Since `sender` is a reference, this // modifies `voters[msg.sender].voted` sender.voted = true; sender.delegate = to; Voter storage delegate = voters[to]; if (delegate.voted) { // If the delegate already voted, (如果委託投票已經投過, 直接修改票數) // directly add to the number of votes proposals[delegate.vote].voteCount += sender.weight; //(投票權重) } else { // If the delegate did not vote yet, // add to her weight. delegate.weight += sender.weight; } }
/// Give your vote (including votes delegated to you) (投出你的票票) /// to proposal `proposals[proposal].name`.
function vote(uint proposal) { Voter storage sender = voters[msg.sender]; require(!sender.voted); //(require 是新版的語法) sender.voted = true; sender.vote = proposal;
// If `proposal` is out of the range of the array,(如果提案超出了索引範圍, 直接回滾所有資料) // this will throw automatically and revert all // changes. proposals[proposal].voteCount += sender.weight; }
/// @dev Computes the winning proposal taking all (根據記票找到最終 的勝出者) /// previous votes into account. function winningProposal() constant returns (uint winningProposal) { uint winningVoteCount = 0; for (uint p = 0; p < proposals.length; p++) { if (proposals[p].voteCount > winningVoteCount) { winningVoteCount = proposals[p].voteCount; winningProposal = p; } } }
// Calls winningProposal() function to get the index // of the winner contained in the proposals array and then // returns the name of the winner function winnerName() constant returns (bytes32 winnerName) { winnerName = proposals[winningProposal()].name; }}