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; }}