0

I'm trying to develop a voting Dapp, I have already created the Smart Contract and the js and html files. I have successfully migrated the contract into the Blockchain (I'm using Ganache), but when I run the Dapp, the candidates don't appear, meaning that I can't vote. Here is the code:

Smart Contract:

pragma solidity ^0.5.0;

contract Election {

    // Model a Candidate

    struct Candidate {

        uint id;

        bytes32 name;

        uint voteCount;

    }



    // Store accounts that have voted

    mapping(address => bool) public voters; 

    // Store Candidates

    // Fetch Candidate

    mapping(uint => Candidate) public candidates;

    // Store Candidates Count

    uint public candidatesCount;



    // voted event

    event votedEvent (

        uint indexed _candidateId

    );


    function addCandidate (bytes32 _name) private {

        candidatesCount ++;

        candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);

    }


    function election () public {

        addCandidate("Candidate 1");

        addCandidate("Candidate 2");

    }


    function vote (uint _candidateId) public {

        // require that they haven't voted before

        require(!voters[msg.sender]);



        // require a valid candidate

        require(_candidateId > 0 && _candidateId <= candidatesCount);



        // record that voter has voted

        voters[msg.sender] = true;



        // update candidate vote Count

        candidates[_candidateId].voteCount ++;



        // trigger voted event

        emit votedEvent(_candidateId);

    }

}

This is the js file:

App = {

  web3Provider: null,

  contracts: {},

  account: '0x0', 

  hasVoted: false,  



  init: function() {

    return App.initWeb3();  

  }, 



  initWeb3: function() {

    // TODO: refactor conditional

    if (typeof web3 !== 'undefined') {

      // If a web3 instance is already provided by Meta Mask.

      App.web3Provider = web3.currentProvider;

      web3 = new Web3(web3.currentProvider);

    } else {

      // Specify default instance if no web3 instance provided

      App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');

      web3 = new Web3(App.web3Provider);

    }

    return App.initContract();

  },



  initContract: function() {

    $.getJSON("Election.json", function(election) {

      // Instantiate a new truffle contract from the artifact

      App.contracts.Election = TruffleContract(election);

      // Connect provider to interact with contract

      App.contracts.Election.setProvider(App.web3Provider);



      App.listenForEvents();



      return App.render();

    });

  },



  // Listen for events emitted from the contract

  listenForEvents: function() {

    App.contracts.Election.deployed().then(function(instance) {

      // Restart Chrome if you are unable to receive this event

      // This is a known issue with Metamask

      // https://github.com/MetaMask/metamask-extension/issues/2393

      instance.votedEvent({}, {

        fromBlock: 0,

        toBlock: 'latest'

      }).watch(function(error, event) {

        console.log("event triggered", event)

        // Reload when a new vote is recorded

        App.render();

      });

    });

  },



  render: function() {

    var electionInstance;

    var loader = $("#loader");

    var content = $("#content");



    loader.show();

    content.hide();



    // Load account data

    web3.eth.getCoinbase(function(err, account) {

      if (err === null) {

        App.account = account;

        $("#accountAddress").html("Your Account: " + account);

      }

    });



    // Load contract data

    App.contracts.Election.deployed().then(function(instance) {

      electionInstance = instance;

      return electionInstance.candidatesCount();

    }).then(function(candidatesCount) {

      var candidatesResults = $("#candidatesResults");

      candidatesResults.empty();



      var candidatesSelect = $('#candidatesSelect');

      candidatesSelect.empty();



      for (var i = 1; i <= candidatesCount; i++) {

        electionInstance.candidates(i).then(function(candidate) {

          var id = candidate[0];

          var name = candidate[1];

          var voteCount = candidate[2];



          // Render candidate Result

          var candidateTemplate = "<tr><th>" + id + "</th><td>" + name + "</td><td>" + voteCount + "</td></tr>"

          candidatesResults.append(candidateTemplate);



          // Render candidate ballot option

          var candidateOption = "<option value='" + id + "' >" + name + "</ option>"

          candidatesSelect.append(candidateOption);

        });

      }

      return electionInstance.voters(App.account);

    }).then(function(hasVoted) {

      // Do not allow a user to vote

      if(hasVoted) {

        $('form').hide();

      }

      loader.hide();

      content.show();

    }).catch(function(error) {

      console.warn(error);

    });

  },



  castVote: function() {

    var candidateId = $('#candidatesSelect').val();

    App.contracts.Election.deployed().then(function(instance) {

      return instance.vote(candidateId, { from: App.account });

    }).then(function(result) {

      // Wait for votes to update

      $("#content").hide();

      $("#loader").show();

    }).catch(function(err) {

      console.error(err);

    });

  }

};



$(function() {

  $(window).load(function() {

    App.init();

  });

});

And the html code:

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->

    <title>Election Results</title>



    <!-- Bootstrap -->

    <link href="css/bootstrap.min.css" rel="stylesheet">



    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->

    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->

    <!--[if lt IE 9]>

      <script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>

      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>

    <![endif]-->

  </head>

  <body>

    <div class="container" style="width: 650px;">

      <div class="row">

        <div class="col-lg-12">

          <h1 class="text-center">Election Results</h1>

          <hr/>

          <br/>

          <div id="loader">

            <p class="text-center">Loading...</p>

          </div>

          <div id="content" style="display: none;">

            <table class="table">

              <thead>

                <tr>

                  <th scope="col">#</th>

                  <th scope="col">Name</th>

                  <th scope="col">Votes</th>

                </tr>

              </thead>

              <tbody id="candidatesResults">

              </tbody>

            </table>

            <hr/>

            <form onSubmit="App.castVote(); return false;">

              <div class="form-group">

                <label for="candidatesSelect">Select Candidate</label>

                <select class="form-control" id="candidatesSelect">

                </select>

              </div>

              <button type="submit" class="btn btn-primary">Vote</button>

              <hr />

            </form>

            <p id="accountAddress" class="text-center"></p>

          </div>

        </div>

      </div>

    </div>



    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

    <!-- Include all compiled plugins (below), or include individual files as needed -->

    <script src="js/bootstrap.min.js"></script>

    <script src="js/web3.min.js"></script>

    <script src="js/truffle-contract.js"></script>

    <script src="js/app.js"></script>

  </body>

</html>

Could anyone take a look and try to solve the problem?

Thanks!!

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.