Lição 3

Implementing Vote Tallying and Result Announcement

In this lesson, we will implement the final parts of our decentralized voting system: tallying votes and announcing the result. This will involve expanding our Voter contract one last time and creating functions to calculate the winning proposal.

Expanding the Voter Contract

Let’s start by adding the winningProposal function to our contract. This function will iterate over all the proposals and return the one with the most votes. Additionally, we’ll create a function winnerName to return the name of the winning proposal. Here is the final version of our contract:

Solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Voter {
    struct Person {
        bool voted;  
        uint vote;   
    }

    struct Proposal {
        string name;   
        uint voteCount; 
    }

    Proposal[] public proposals;
    mapping(address => Person) public voters;

    function registerVoter() public {
        voters[msg.sender].voted = false;
    }

    function addProposal(string memory _name) public {
        proposals.push(Proposal(_name, 0));
    }

    function vote(uint _proposal) public { 
     require(_proposal < proposals.length, "Invalid proposal index."); // This is the added check 

     Person storage sender = voters[msg.sender]; 
     require(!sender.voted, "Already voted."); 
     sender.voted = true; 
     sender.vote = _proposal; 

     proposals[_proposal].voteCount += 1; 
    }

    function winningProposal() public view 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;
            }
        }
    }

    function winnerName() public view returns (string memory winnerName_) {
        winnerName_ = proposals[winningProposal()].name;
    }
}

Understanding the Code

Let’s explain the new additions:

  1. Winning Proposal Function: This function iterates over all the proposals and finds the one with the highest vote count. It returns the index of this proposal in the proposals array. It’s a view function, meaning it doesn’t modify the state of the contract and only reads the data.

  2. Winner Name Function: This function calls the winningProposal function to get the index of the winning proposal and then returns the name of this proposal.

Compiling and Testing

Compile your contract by clicking on the Solidity compiler icon on the left sidebar and then clicking on the “Compile” button.

Deploy your contract in the “Deploy & Run Transactions” tab and interact with it. Register some voters, add a few proposals, cast your votes, and finally, check the winner.

How to do it:

  1. Deployment: First, click on the “Deploy & Run Transactions” tab on the Remix IDE. It’s the one below the Solidity compiler icon. Make sure you’re in the “JavaScript VM” environment. Then, click the “Deploy” button.
  2. Registering Voters: Once the contract is deployed, you’ll see it under the “Deployed Contracts” section. Click on the arrow to expand it. You’ll find all the functions of our contract listed there.
  3. To register voters, find the registerVoter function. Since we have programmed our contract to register the account calling this function as a voter, you can switch accounts in the “Account” dropdown in the “Deploy & Run Transactions” tab. Once you’ve selected an account, click the registerVoter function. Repeat this step for each account you want to register as a voter.
  4. Adding Proposals: To add proposals, find the addProposal function. Enter the proposal name in the input box next to the function and click the function. Repeat this step for each proposal you want to add.
  5. Voting: To vote, switch to a voter account and find the vote function. Enter the index of the proposal (the order in which you added it, starting from 0) you want to vote for in the input box next to the function and click the function. Repeat this step for each voter.
  6. Checking the Winner: After all voters have cast their votes, you can check the winner. Find the winnerName function and click it. The name of the winning proposal will be displayed in the console at the bottom of the screen.
  7. Remember, all actions in the blockchain (including the test ones in Remix) are transactions. You can expand the transaction details in the console to see more information, like the transaction cost and the data. It’s a good practice to check this information to understand better how your contract is interacting with the blockchain.

In the next lesson, we’ll discuss contract interactions and event logging. We’ll learn how contracts can interact with each other and how to log and monitor activities on blockchain. Congratulations on building your first decentralized voting system on Ethereum!

Exclusão de responsabilidade
* O investimento em criptomoedas envolve riscos significativos. Prossiga com cuidado. O curso não pretende ser um conselho de investimento.
* O curso é criado pelo autor que se juntou ao Gate Learn. Qualquer opinião partilhada pelo autor não representa o Gate Learn.
Catálogo
Lição 3

Implementing Vote Tallying and Result Announcement

In this lesson, we will implement the final parts of our decentralized voting system: tallying votes and announcing the result. This will involve expanding our Voter contract one last time and creating functions to calculate the winning proposal.

Expanding the Voter Contract

Let’s start by adding the winningProposal function to our contract. This function will iterate over all the proposals and return the one with the most votes. Additionally, we’ll create a function winnerName to return the name of the winning proposal. Here is the final version of our contract:

Solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

contract Voter {
    struct Person {
        bool voted;  
        uint vote;   
    }

    struct Proposal {
        string name;   
        uint voteCount; 
    }

    Proposal[] public proposals;
    mapping(address => Person) public voters;

    function registerVoter() public {
        voters[msg.sender].voted = false;
    }

    function addProposal(string memory _name) public {
        proposals.push(Proposal(_name, 0));
    }

    function vote(uint _proposal) public { 
     require(_proposal < proposals.length, "Invalid proposal index."); // This is the added check 

     Person storage sender = voters[msg.sender]; 
     require(!sender.voted, "Already voted."); 
     sender.voted = true; 
     sender.vote = _proposal; 

     proposals[_proposal].voteCount += 1; 
    }

    function winningProposal() public view 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;
            }
        }
    }

    function winnerName() public view returns (string memory winnerName_) {
        winnerName_ = proposals[winningProposal()].name;
    }
}

Understanding the Code

Let’s explain the new additions:

  1. Winning Proposal Function: This function iterates over all the proposals and finds the one with the highest vote count. It returns the index of this proposal in the proposals array. It’s a view function, meaning it doesn’t modify the state of the contract and only reads the data.

  2. Winner Name Function: This function calls the winningProposal function to get the index of the winning proposal and then returns the name of this proposal.

Compiling and Testing

Compile your contract by clicking on the Solidity compiler icon on the left sidebar and then clicking on the “Compile” button.

Deploy your contract in the “Deploy & Run Transactions” tab and interact with it. Register some voters, add a few proposals, cast your votes, and finally, check the winner.

How to do it:

  1. Deployment: First, click on the “Deploy & Run Transactions” tab on the Remix IDE. It’s the one below the Solidity compiler icon. Make sure you’re in the “JavaScript VM” environment. Then, click the “Deploy” button.
  2. Registering Voters: Once the contract is deployed, you’ll see it under the “Deployed Contracts” section. Click on the arrow to expand it. You’ll find all the functions of our contract listed there.
  3. To register voters, find the registerVoter function. Since we have programmed our contract to register the account calling this function as a voter, you can switch accounts in the “Account” dropdown in the “Deploy & Run Transactions” tab. Once you’ve selected an account, click the registerVoter function. Repeat this step for each account you want to register as a voter.
  4. Adding Proposals: To add proposals, find the addProposal function. Enter the proposal name in the input box next to the function and click the function. Repeat this step for each proposal you want to add.
  5. Voting: To vote, switch to a voter account and find the vote function. Enter the index of the proposal (the order in which you added it, starting from 0) you want to vote for in the input box next to the function and click the function. Repeat this step for each voter.
  6. Checking the Winner: After all voters have cast their votes, you can check the winner. Find the winnerName function and click it. The name of the winning proposal will be displayed in the console at the bottom of the screen.
  7. Remember, all actions in the blockchain (including the test ones in Remix) are transactions. You can expand the transaction details in the console to see more information, like the transaction cost and the data. It’s a good practice to check this information to understand better how your contract is interacting with the blockchain.

In the next lesson, we’ll discuss contract interactions and event logging. We’ll learn how contracts can interact with each other and how to log and monitor activities on blockchain. Congratulations on building your first decentralized voting system on Ethereum!

Exclusão de responsabilidade
* O investimento em criptomoedas envolve riscos significativos. Prossiga com cuidado. O curso não pretende ser um conselho de investimento.
* O curso é criado pelo autor que se juntou ao Gate Learn. Qualquer opinião partilhada pelo autor não representa o Gate Learn.