Learn Solidity - Build Decentralized Application in Ethereum

Learn Solidity: Complete Example: Voting Ballot Smart Contract

In this post, we will go through the complete example of a Voting Ballot smart contract. This is a fully working smart contract for voting. [pastacode lang=”javascript” manual=”pragma%20solidity%20%5E0.4.9%3B%0A%0A%2F%2F%2F%20%40title%20Voting%20with%20delegation.%0Acontract%20Ballot%20%7B%0A%20%20%20%20%2F%2F%20This%20declares%20a%20new%20complex%20type%20which%20will%0A%20%20%20%20%2F%2F%20be%20used%20for%20variables%20later.%0A%20%20%20%20%2F%2F%20It%20will%20represent%20a%20single%20voter.%0A%20%20%20%20struct%20Voter%20%7B%0A%20%20%20%20%20%20%20%20uint%20weight%3B%20%2F%2F%20weight%20is%20accumulated%20by%20delegation%0A%20%20%20%20%20%20%20%20bool%20voted%3B%20%20%2F%2F%20if%20true%2C%20that%20person%20already%20voted%0A%20%20%20%20%20%20%20%20address%20delegate%3B%20%2F%2F%20person%20delegated%20to%0A%20%20%20%20%20%20%20%20uint%20vote%3B%20%20%20%2F%2F%20index%20of%20the%20voted%20proposal%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20This%20is%20a%20type%20for%20a%20single%20proposal.%0A%20%20%20%20struct%20Proposal%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20bytes32%20name%3B%20%20%20%2F%2F%20short%20name%20(up%20to%2032%20bytes)%0A%20%20%20%20%20%20%20%20uint%20voteCount%3B%20%2F%2F%20number%20of%20accumulated%20votes%0A%20%20%20%20%7D%0A%0A%20%20%20%20address%20public%20chairperson%3B%0A%0A%20%20%20%20%2F%2F%20This%20declares%20a%20state%20variable%20that%0A%20%20%20%20%2F%2F%20stores%20a%20%60Voter%60%20struct%20for%20each%20possible%20address.%0A%20%20%20%20mapping(address%20%3D%3E%20Voter)%20public%20voters%3B%0A%0A%20%20%20%20%2F%2F%20A%20dynamically-sized%20array%20of%20%60Proposal%60%20structs.%0A%20%20%20%20Proposal%5B%5D%20public%20proposals%3B%0A%0A%20%20%20%20%2F%2F%2F%20Create%20a%20new%20ballot%20to%20choose%20one%20of%20%60proposalNames%60.%0A%20%20%20%20function%20Ballot(bytes32%5B%5D%20proposalNames)%20%7B%0A%20%20%20%20%20%20%20%20chairperson%20%3D%20msg.sender%3B%0A%20%20%20%20%20%20%20%20voters%5Bchairperson%5D.weight%20%3D%201%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20For%20each%20of%20the%20provided%20proposal%20names%2C%0A%20%20%20%20%20%20%20%20%2F%2F%20create%20a%20new%20proposal%20object%20and%20add%20it%0A%20%20%20%20%20%20%20%20%2F%2F%20to%20the%20end%20of%20the%20array.%0A%20%20%20%20%20%20%20%20for%20(uint%20i%20%3D%200%3B%20i%20%3C%20proposalNames.length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%60Proposal(%7B…%7D)%60%20creates%20a%20temporary%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Proposal%20object%20and%20%60proposals.push(…)%60%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20appends%20it%20to%20the%20end%20of%20%60proposals%60.%0A%20%20%20%20%20%20%20%20%20%20%20%20proposals.push(Proposal(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3A%20proposalNames%5Bi%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20voteCount%3A%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D))%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Give%20%60voter%60%20the%20right%20to%20vote%20on%20this%20ballot.%0A%20%20%20%20%2F%2F%20May%20only%20be%20called%20by%20%60chairperson%60.%0A%20%20%20%20function%20giveRightToVote(address%20voter)%20%7B%0A%20%20%20%20%20%20%20%20if%20(msg.sender%20!%3D%20chairperson%20%7C%7C%20voters%5Bvoter%5D.voted)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%60throw%60%20terminates%20and%20reverts%20all%20changes%20to%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20the%20state%20and%20to%20Ether%20balances.%20It%20is%20often%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20a%20good%20idea%20to%20use%20this%20if%20functions%20are%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20called%20incorrectly.%20But%20watch%20out%2C%20this%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20will%20also%20consume%20all%20provided%20gas.%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20voters%5Bvoter%5D.weight%20%3D%201%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%2F%20Delegate%20your%20vote%20to%20the%20voter%20%60to%60.%0A%20%20%20%20function%20delegate(address%20to)%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20assigns%20reference%0A%20%20%20%20%20%20%20%20Voter%20sender%20%3D%20voters%5Bmsg.sender%5D%3B%0A%20%20%20%20%20%20%20%20if%20(sender.voted)%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Forward%20the%20delegation%20as%20long%20as%0A%20%20%20%20%20%20%20%20%2F%2F%20%60to%60%20also%20delegated.%0A%20%20%20%20%20%20%20%20%2F%2F%20In%20general%2C%20such%20loops%20are%20very%20dangerous%2C%0A%20%20%20%20%20%20%20%20%2F%2F%20because%20if%20they%20run%20too%20long%2C%20they%20might%0A%20%20%20%20%20%20%20%20%2F%2F%20need%20more%20gas%20than%20is%20available%20in%20a%20block.%0A%20%20%20%20%20%20%20%20%2F%2F%20In%20this%20case%2C%20the%20delegation%20will%20not%20be%20executed%2C%0A%20%20%20%20%20%20%20%20%2F%2F%20but%20in%20other%20situations%2C%20such%20loops%20might%0A%20%20%20%20%20%20%20%20%2F%2F%20cause%20a%20contract%20to%20get%20%22stuck%22%20completely.%0A%20%20%20%20%20%20%20%20while%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20voters%5Bto%5D.delegate%20!%3D%20address(0)%20%26%26%0A%20%20%20%20%20%20%20%20%20%20%20%20voters%5Bto%5D.delegate%20!%3D%20msg.sender%0A%20%20%20%20%20%20%20%20)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20to%20%3D%20voters%5Bto%5D.delegate%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20We%20found%20a%20loop%20in%20the%20delegation%2C%20not%20allowed.%0A%20%20%20%20%20%20%20%20if%20(to%20%3D%3D%20msg.sender)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20Since%20%60sender%60%20is%20a%20reference%2C%20this%0A%20%20%20%20%20%20%20%20%2F%2F%20modifies%20%60voters%5Bmsg.sender%5D.voted%60%0A%20%20%20%20%20%20%20%20sender.voted%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20sender.delegate%20%3D%20to%3B%0A%20%20%20%20%20%20%20%20Voter%20delegate%20%3D%20voters%5Bto%5D%3B%0A%20%20%20%20%20%20%20%20if%20(delegate.voted)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20the%20delegate%20already%20voted%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20directly%20add%20to%20the%20number%20of%20votes%0A%20%20%20%20%20%20%20%20%20%20%20%20proposals%5Bdelegate.vote%5D.voteCount%20%2B%3D%20sender.weight%3B%0A%20%20%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20If%20the%20delegate%20did%20not%20vote%20yet%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20add%20to%20her%20weight.%0A%20%20%20%20%20%20%20%20%20%20%20%20delegate.weight%20%2B%3D%20sender.weight%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%2F%20Give%20your%20vote%20(including%20votes%20delegated%20to%20you)%0A%20%20%20%20%2F%2F%2F%20to%20proposal%20%60proposals%5Bproposal%5D.name%60.%0A%20%20%20%20function%20vote(uint%20proposal)%20%7B%0A%20%20%20%20%20%20%20%20Voter%20sender%20%3D%20voters%5Bmsg.sender%5D%3B%0A%20%20%20%20%20%20%20%20if%20(sender.voted)%0A%20%20%20%20%20%20%20%20%20%20%20%20throw%3B%0A%20%20%20%20%20%20%20%20sender.voted%20%3D%20true%3B%0A%20%20%20%20%20%20%20%20sender.vote%20%3D%20proposal%3B%0A%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20%60proposal%60%20is%20out%20of%20the%20range%20of%20the%20array%2C%0A%20%20%20%20%20%20%20%20%2F%2F%20this%20will%20throw%20automatically%20and%20revert%20all%0A%20%20%20%20%20%20%20%20%2F%2F%20changes.%0A%20%20%20%20%20%20%20%20proposals%5Bproposal%5D.voteCount%20%2B%3D%20sender.weight%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%2F%20%40dev%20Computes%20the%20winning%20proposal%20taking%20all%0A%20%20%20%20%2F%2F%2F%20previous%20votes%20into%20account.%0A%20%20%20%20function%20winningProposal()%20constant%0A%20%20%20%20%20%20%20%20%20%20%20%20returns%20(uint%20winningProposal)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20uint%20winningVoteCount%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for%20(uint%20p%20%3D%200%3B%20p%20%3C%20proposals.length%3B%20p%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20(proposals%5Bp%5D.voteCount%20%3E%20winningVoteCount)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20winningVoteCount%20%3D%20proposals%5Bp%5D.voteCount%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20winningProposal%20%3D%20p%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20%2F%2F%20Calls%20winningProposal()%20function%20to%20get%20the%20index%0A%20%20%20%20%2F%2F%20of%20the%20winner%20contained%20in%20the%20proposals%20array%20and%20then%0A%20%20%20%20%2F%2F%20returns%20the%20name%20of%20the%20winner%0A%20%20%20%20function%20winnerName()%20constant%0A%20%20%20%20%20%20%20%20%20%20%20%20returns%20(bytes32%20winnerName)%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20winnerName%20%3D%20proposals%5BwinningProposal()%5D.name%3B%0A%20%20%20%20%7D%0A%7D” message=”” highlight=”” provider=”manual”/]…
Read More