0

我正在尝试在松露框架上使用区块链制作投票应用程序。来自网络的数据不会呈现在网页上。仅显示加载,但未显示实际内容,即使我已通过区块链帐户从 Ganache 连接到我的元掩码扩展。这是我的代码:

选举.sol

pragma solidity ^0.5.0;

contract Election {
    // Model a Candidate for first past the post system
    struct Candidatepost {
        uint id;
        string name;
        uint voteCount;
    }

    // Model as candidate for proportional party system
    struct Candidateparty {
        uint id;
        string name;
        uint voteCount;
    }

    // Store accounts that have voted
    mapping(address => bool) public voters;
    // Store Candidates
    // Fetch Candidate
    mapping(uint => Candidatepost) public cand_post;

    mapping(uint => Candidateparty) public cand_party;

    // Store Candidates Count
    uint public partyCount;
    uint public postCount;
    uint[] public candidatesCount = [postCount,partyCount];

    constructor () public {
        addpostCandidate("Candidate 1");
        addpostCandidate("Candidate 2");
        addpartyCandidate("Candidate 1");
        addpartyCandidate("Candidate 2");
        candidatesCount = [postCount,partyCount];
    }

    function addpostCandidate (string memory _name) private {
        postCount ++;
        cand_post[postCount] = Candidatepost(postCount, _name, 0);
    }


    function addpartyCandidate (string memory _name) private {
        partyCount ++;
        cand_party[partyCount] = Candidateparty(partyCount, _name, 0);
    }
    // voted event
    event votedEvent (
        uint indexed _candidateId1,
        uint indexed _candidateId2
    );


    function vote (uint _candidateId1, uint _candidateId2) public {
        // require that they haven't voted before
        require(!voters[msg.sender]);

        // require a valid candidate
        require(_candidateId1 > 0 && _candidateId1 <= postCount && _candidateId2 > 0 && _candidateId2 <= partyCount);

        // record that voter has voted
        voters[msg.sender] = true;

        // update candidate vote Count
        cand_post[_candidateId1].voteCount ++;
        cand_party[_candidateId2].voteCount ++;   
        // trigger voted event
        emit votedEvent(_candidateId1, _candidateId2);
    }
}

应用程序.js

App = {
  web3Provider: null,
  contracts: {},
  account: '0x0',
  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(1) {


      var postcandidatesResults = $("#postcandidatesResults");
      postcandidatesResults.empty();
      var partycandidatesResults = $("#partycandidatesResults");
      partycandidatesResults.empty();

      var postcandidatesSelect = $('#postcandidatesSelect');
      postcandidatesSelect.empty();
      var partycandidatesSelect = $('#partycandidatesSelect');
      partycandidatesSelect.empty();

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

        electionInstance.cand_post(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>";
          postcandidatesResults.append(candidateTemplate);

          // Render candidate ballot option
          var candidateOption = "<option value='" + id + "' >" + name + "</ option>";
          postcandidatesSelect.append(candidateOption);
        });
      }
      for (var j = 1; j <= 2; j++) {
        electionInstance.cand_party(i).then(function(candidate) {
          var id2 = candidate[0];
          var name2 = candidate[1];
          var voteCount2 = candidate[2];

          // Render candidate Result
          var candidateTemplate2 = "<tr><th>" + id2 + "</th><td>" + name2 + "</td><td>" + voteCount2 + "</td></tr>";
          partycandidatesResults.append(candidateTemplate2);

          // Render candidate ballot option
          var candidateOption2 = "<option value='" + id2 + "' >" + name2 + "</ option>";
          partycandidatesSelect.append(candidateOption2);
        });
      }

      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 candidateId1 = $('#postcandidatesSelect').val();
    var candidateId2 = $('#partycandidatesSelect').val();
    App.contracts.Election.deployed().then(function(instance) {
      return instance.vote(candidateId1, candidateId2, { 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();
  });
});

索引.html

<!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">
            <div class="row d-flex justify-content-center" style="border:none;background:white;">
      <div class="col-md-1 col-3">
        <img class="mx-auto d-block  img-fluid" src="images/logo.png" style=""   alt="">
      </div>
    </div></h1>
          <hr/>
          <br/>

          <h1 class="text-center">National Election-2075</h1>
          <h1 class="text-center">Election Updates</h1>
          <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="postcandidatesResults">
              </tbody>
            </table>
            <hr/>
            <table class="table">
              <thead>
                <tr>
                  <th scope="col">#</th>
                  <th scope="col">Name</th>
                  <th scope="col">Votes</th>
                </tr>
              </thead>
              <tbody id="partycandidatesResults">
              </tbody>
            </table>
            <hr/>
            <form onSubmit="App.castVote(); return false;">
              <div class="form-group">
                <label for="postcandidatesSelect">Select Candidate</label>
                <select class="form-control" id="postcandidatesSelect">
                </select>
              </div>
              <div class="form-group">
                <label for="partycandidatesSelect">Select Candidate</label>
                <select class="form-control" id="partycandidatesSelect">
                </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>
4

1 回答 1

0

对区块链的任何调用都是异步的(返回一个承诺)。您需要使用 .then() 处理承诺,也可以使用异步等待。基本上在选举实例之后链接的任何东西都是异步的。例如:

 electionInstance.candidatesCount();
 electionInstance.cand_party
 electionInstance.voters
于 2019-02-14T00:54:41.600 回答