Index

Ethereum

  1. Election
  2. Accounts
  3. Test
  4. Frontend
  5. Voting
  6. Validation
  7. Events

Voting

pragma solidity >=0.4.22 <0.7.0;


contract Election {

    // Model a candidate
    struct Candidate {
        uint id;
        string name;
        uint voteCount;
    }
    // Storing accounts that have voted
    mapping(address => bool) public voters;

    // Store candidate
    // Fetch Candidate
    mapping(uint => Candidate) public candidates;

     // Store candidate count
    uint public candidatesCount;

    constructor () public {
       addCandidate("Candidate 1");
       addCandidate("Candidate 2");
    }

    function addCandidate(string memory _name) private {
        candidatesCount ++;
        candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
    }
    function vote(uint _candidateId) public {
        // record that voter has voted
        voters[msg.sender] = true;

        // update candidate vote Count
        candidates[_candidateId].voteCount ++;
    }
}



function vote(uint _candidateId) public {
        // record that voter has voted
        voters[msg.sender] = true;

        // update candidate vote Count
        candidates[_candidateId].voteCount ++;
    }


Keeping track that account has voted. When we call a function, solidity allows to pass in metadata to the function, allows us to pass more arguments that you have defined.
Solidity will give the account as
msg.sender


This mapping will take an account (address) and give a bool value.
// Storing accounts that have voted
    mapping(address => bool) public voters;

Setting the value is done here.
// record that voter has voted
        voters[msg.sender] = true;




truffle migrate --reset


truffle console

Election.deployed().then(function(i) { app = i} )


var accounts;

web3.eth.getAccounts(function(err, res) { accounts = res;});

accounts[0];


images/529-1.png

Voting
from is the metadata, this will denote the account, that we are sending to the function.

app.vote(1, {from: accounts[0]})

form data translates into msg.sender

The remind the function is:
function vote(uint _candidateId) public {
        // record that voter has voted
        voters[msg.sender] = true;

        // update candidate vote Count
        candidates[_candidateId].voteCount ++;
    }




This is a transaction receipt.
images/529-2.png


Test:


election.js
it("allows a voter to cast a vote"function(){
        return Election.deployed().then(function(instance) {
            electionInstance = instance;
            candidateId = 1;
            return electionInstance.vote(candidateId, { from: accounts[0]});
            // Return value is a transaction receipt that you show in the console
            // We will not do anything with the receipt
        }).then(function(receipt) {
            // Read the voters mapping
            // mapping(address => bool) public voters;
            return electionInstance.voters(accounts[0]);
            // Returns a boolean
        }).then(function(voted){
            assert(voted, "the voter was marked as voted");
            // Read the candidates mapping
            // mapping(uint => Candidate) public candidates;
            return electionInstance.candidates(candidateId);
            // It takes the candidateId(uint) and returns a candidate of the id stored in struct Candidate
        }).then(function(candidate){
            //Receive the a candidate
            //candidate[0] is id (unit)
            //candidate[1] is name of candidate (Candidate 1)
            //candidate[2] is voteCount
            var voteCount = candidate[2];
            assert.equal(voteCount, 1"increments the candidate's vote count");
        })
    });