update ballot contract

pull/5066/head
aniket-engg 1 month ago committed by yann300
parent 7e44c51564
commit 44c4c463e6
  1. 55
      apps/remix-ide/contracts/ballot.sol

@ -7,7 +7,9 @@ pragma solidity >=0.7.0 <0.9.0;
* @dev Implements voting process along with vote delegation * @dev Implements voting process along with vote delegation
*/ */
contract Ballot { contract Ballot {
// This declares a new complex type which will
// be used for variables later.
// It will represent a single voter.
struct Voter { struct Voter {
uint weight; // weight is accumulated by delegation uint weight; // weight is accumulated by delegation
bool voted; // if true, that person already voted bool voted; // if true, that person already voted
@ -15,6 +17,7 @@ contract Ballot {
uint vote; // index of the voted proposal uint vote; // index of the voted proposal
} }
// This is a type for a single proposal.
struct Proposal { struct Proposal {
// If you can limit the length to a certain number of bytes, // If you can limit the length to a certain number of bytes,
// always use one of bytes1 to bytes32 because they are much cheaper // always use one of bytes1 to bytes32 because they are much cheaper
@ -24,8 +27,11 @@ contract Ballot {
address public chairperson; address public chairperson;
// This declares a state variable that
// stores a 'Voter' struct for each possible address.
mapping(address => Voter) public voters; mapping(address => Voter) public voters;
// A dynamically-sized array of 'Proposal' structs.
Proposal[] public proposals; Proposal[] public proposals;
/** /**
@ -36,6 +42,9 @@ contract Ballot {
chairperson = msg.sender; chairperson = msg.sender;
voters[chairperson].weight = 1; 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++) { for (uint i = 0; i < proposalNames.length; i++) {
// 'Proposal({...})' creates a temporary // 'Proposal({...})' creates a temporary
// Proposal object and 'proposals.push(...)' // Proposal object and 'proposals.push(...)'
@ -47,11 +56,21 @@ contract Ballot {
} }
} }
/** /**
* @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'. * @dev Give 'voter' the right to vote on this ballot. May only be called by 'chairperson'.
* @param voter address of voter * @param voter address of voter
*/ */
function giveRightToVote(address voter) public { function giveRightToVote(address voter) external {
// If the first argument of `require` evaluates
// to 'false', execution terminates and all
// changes to the state and to Ether balances
// are reverted.
// This used to consume all gas in old EVM versions, but
// not anymore.
// It is often a good idea to use 'require' to check if
// functions are called correctly.
// As a second argument, you can also provide an
// explanation about what went wrong.
require( require(
msg.sender == chairperson, msg.sender == chairperson,
"Only chairperson can give right to vote." "Only chairperson can give right to vote."
@ -68,20 +87,39 @@ contract Ballot {
* @dev Delegate your vote to the voter 'to'. * @dev Delegate your vote to the voter 'to'.
* @param to address to which vote is delegated * @param to address to which vote is delegated
*/ */
function delegate(address to) public { function delegate(address to) external {
// assigns reference
Voter storage sender = voters[msg.sender]; Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "You have no right to vote");
require(!sender.voted, "You already voted."); require(!sender.voted, "You already voted.");
require(to != msg.sender, "Self-delegation is disallowed."); require(to != msg.sender, "Self-delegation is disallowed.");
// 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.
while (voters[to].delegate != address(0)) { while (voters[to].delegate != address(0)) {
to = voters[to].delegate; to = voters[to].delegate;
// We found a loop in the delegation, not allowed. // We found a loop in the delegation, not allowed.
require(to != msg.sender, "Found loop in delegation."); require(to != msg.sender, "Found loop in delegation.");
} }
Voter storage delegate_ = voters[to];
// Voters cannot delegate to accounts that cannot vote.
require(delegate_.weight >= 1);
// Since 'sender' is a reference, this
// modifies 'voters[msg.sender]'.
sender.voted = true; sender.voted = true;
sender.delegate = to; sender.delegate = to;
Voter storage delegate_ = voters[to];
if (delegate_.voted) { if (delegate_.voted) {
// If the delegate already voted, // If the delegate already voted,
// directly add to the number of votes // directly add to the number of votes
@ -97,11 +135,10 @@ contract Ballot {
* @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'. * @dev Give your vote (including votes delegated to you) to proposal 'proposals[proposal].name'.
* @param proposal index of proposal in the proposals array * @param proposal index of proposal in the proposals array
*/ */
function vote(uint proposal) public { function vote(uint proposal) external {
Voter storage sender = voters[msg.sender]; Voter storage sender = voters[msg.sender];
require(sender.weight != 0, "Has no right to vote"); require(sender.weight != 0, "Has no right to vote");
require(!sender.voted, "Already voted."); require(!sender.voted, "Already voted.");
require(proposal < proposals.length, "Invalid proposal index.");
sender.voted = true; sender.voted = true;
sender.vote = proposal; sender.vote = proposal;
@ -131,9 +168,9 @@ contract Ballot {
* @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then * @dev Calls winningProposal() function to get the index of the winner contained in the proposals array and then
* @return winnerName_ the name of the winner * @return winnerName_ the name of the winner
*/ */
function winnerName() public view function winnerName() external view
returns (bytes32 winnerName_) returns (bytes32 winnerName_)
{ {
winnerName_ = proposals[winningProposal()].name; winnerName_ = proposals[winningProposal()].name;
} }
} }
Loading…
Cancel
Save