Warning, /frameworks/syntax-highlighting/autotests/folding/test.sol.fold is written in an unsupported language. File is not indexed.

0001 // Solidity Sample File
0002 // https://solidity.readthedocs.io/en/latest/solidity-by-example.html#voting
0003 
0004 pragma solidity >=0.4.22 <0.7.0;
0005 
0006 /// @title Voting with delegation.
0007 contract Ballot <beginfold id='1'>{</beginfold id='1'>
0008     // This declares a new complex type which will
0009     // be used for variables later.
0010     // It will represent a single voter.
0011     struct Voter <beginfold id='1'>{</beginfold id='1'>
0012         uint weight; // weight is accumulated by delegation
0013         bool voted;  // if true, that person already voted
0014         address delegate; // person delegated to
0015         uint vote;   // index of the voted proposal
0016     <endfold id='1'>}</endfold id='1'>
0017 
0018     // This is a type for a single proposal.
0019     struct Proposal <beginfold id='1'>{</beginfold id='1'>
0020         bytes32 name;   // short name (up to 32 bytes)
0021         uint voteCount; // number of accumulated votes
0022     <endfold id='1'>}</endfold id='1'>
0023 
0024     address public chairperson;
0025 
0026     // This declares a state variable that
0027     // stores a `Voter` struct for each possible address.
0028     mapping(address => Voter) public voters;
0029 
0030     // A dynamically-sized array of `Proposal` structs.
0031     Proposal[] public proposals;
0032 
0033     /// Create a new ballot to choose one of `proposalNames`.
0034     constructor(bytes32[] memory proposalNames) public <beginfold id='1'>{</beginfold id='1'>
0035         chairperson = msg.sender;
0036         voters[chairperson].weight = 1;
0037 
0038         // For each of the provided proposal names,
0039         // create a new proposal object and add it
0040         // to the end of the array.
0041         for (uint i = 0; i < proposalNames.length; i++) <beginfold id='1'>{</beginfold id='1'>
0042             // `Proposal({...})` creates a temporary
0043             // Proposal object and `proposals.push(...)`
0044             // appends it to the end of `proposals`.
0045             proposals.push(Proposal(<beginfold id='1'>{</beginfold id='1'>
0046                 name: proposalNames[i],
0047                 voteCount: 0
0048             <endfold id='1'>}</endfold id='1'>));
0049         <endfold id='1'>}</endfold id='1'>
0050     <endfold id='1'>}</endfold id='1'>
0051 
0052     // Give `voter` the right to vote on this ballot.
0053     // May only be called by `chairperson`.
0054     function giveRightToVote(address voter) public <beginfold id='1'>{</beginfold id='1'>
0055         // If the first argument of `require` evaluates
0056         // to `false`, execution terminates and all
0057         // changes to the state and to Ether balances
0058         // are reverted.
0059         // This used to consume all gas in old EVM versions, but
0060         // not anymore.
0061         // It is often a good idea to use `require` to check if
0062         // functions are called correctly.
0063         // As a second argument, you can also provide an
0064         // explanation about what went wrong.
0065         require(
0066             msg.sender == chairperson,
0067             "Only chairperson can give right to vote."
0068         );
0069         require(
0070             !voters[voter].voted,
0071             "The voter already voted."
0072         );
0073         require(voters[voter].weight == 0);
0074         voters[voter].weight = 1;
0075     <endfold id='1'>}</endfold id='1'>
0076 
0077     /// Delegate your vote to the voter `to`.
0078     function delegate(address to) public <beginfold id='1'>{</beginfold id='1'>
0079         // assigns reference
0080         Voter storage sender = voters[msg.sender];
0081         require(!sender.voted, "You already voted.");
0082 
0083         require(to != msg.sender, "Self-delegation is disallowed.");
0084 
0085         // Forward the delegation as long as
0086         // `to` also delegated.
0087         // In general, such loops are very dangerous,
0088         // because if they run too long, they might
0089         // need more gas than is available in a block.
0090         // In this case, the delegation will not be executed,
0091         // but in other situations, such loops might
0092         // cause a contract to get "stuck" completely.
0093         while (voters[to].delegate != address(0)) <beginfold id='1'>{</beginfold id='1'>
0094             to = voters[to].delegate;
0095 
0096             // We found a loop in the delegation, not allowed.
0097             require(to != msg.sender, "Found loop in delegation.");
0098         <endfold id='1'>}</endfold id='1'>
0099 
0100         // Since `sender` is a reference, this
0101         // modifies `voters[msg.sender].voted`
0102         sender.voted = true;
0103         sender.delegate = to;
0104         Voter storage delegate_ = voters[to];
0105         if (delegate_.voted) <beginfold id='1'>{</beginfold id='1'>
0106             // If the delegate already voted,
0107             // directly add to the number of votes
0108             proposals[delegate_.vote].voteCount += sender.weight;
0109         <endfold id='1'>}</endfold id='1'> else <beginfold id='1'>{</beginfold id='1'>
0110             // If the delegate did not vote yet,
0111             // add to her weight.
0112             delegate_.weight += sender.weight;
0113         <endfold id='1'>}</endfold id='1'>
0114     <endfold id='1'>}</endfold id='1'>
0115 
0116     /// Give your vote (including votes delegated to you)
0117     /// to proposal `proposals[proposal].name`.
0118     function vote(uint proposal) public <beginfold id='1'>{</beginfold id='1'>
0119         Voter storage sender = voters[msg.sender];
0120         require(sender.weight != 0, "Has no right to vote");
0121         require(!sender.voted, "Already voted.");
0122         sender.voted = true;
0123         sender.vote = proposal;
0124 
0125         // If `proposal` is out of the range of the array,
0126         // this will throw automatically and revert all
0127         // changes.
0128         proposals[proposal].voteCount += sender.weight;
0129     <endfold id='1'>}</endfold id='1'>
0130 
0131     /// @dev Computes the winning proposal taking all
0132     /// previous votes into account.
0133     function winningProposal() public view
0134             returns (uint winningProposal_)
0135     <beginfold id='1'>{</beginfold id='1'>
0136         uint winningVoteCount = 0;
0137         for (uint p = 0; p < proposals.length; p++) <beginfold id='1'>{</beginfold id='1'>
0138             if (proposals[p].voteCount > winningVoteCount) <beginfold id='1'>{</beginfold id='1'>
0139                 winningVoteCount = proposals[p].voteCount;
0140                 winningProposal_ = p;
0141             <endfold id='1'>}</endfold id='1'>
0142         <endfold id='1'>}</endfold id='1'>
0143     <endfold id='1'>}</endfold id='1'>
0144 
0145     // Calls winningProposal() function to get the index
0146     // of the winner contained in the proposals array and then
0147     // returns the name of the winner
0148     function winnerName() public view
0149             returns (bytes32 winnerName_)
0150     <beginfold id='1'>{</beginfold id='1'>
0151         winnerName_ = proposals[winningProposal()].name;
0152     <endfold id='1'>}</endfold id='1'>
0153 <endfold id='1'>}</endfold id='1'>