3.5 프론트엔드 구현하고 마무리

혹시 index.html 이 열리지 않는다면?
Web3.js 의 변경사항 때문에 index.html 이 열리지 않을 수 있습니다. 이 경우 브라우저 콘솔 에러메시지가 Access to XMLHttpRequest at 'http://localhost:8545/' from origin 'null' has been blocked by CORS policy 와 같이 뜰텐데요. 이 이슈를 해결하려면 아래 순서대로 진행하세요.

1. 아래의 index.js 소스코드를 참고하여 js 파일 내용을 업데이트 하시길 바랍니다. 소스코드 내용을 보면, 계정을 fetch 하기 위해 web3.eth.accounts 함수를 쓰는 것을 볼 수 있습니다.
2. 아래의 명령어대로 웹 서버를 설치하고, 해당 서버 내에서 어플리케이션이 구동되도록 하세요.

npm install -g http-server
http-server
Starting up http-server, serving ./
Available on:
http://127.0.0.1:8080

index.html

<!DOCTYPE html>
<html>
<head>
 <title>Hello World DApp</title>
 <link href='https://fonts.googleapis.com/css?family=Open Sans:400,700' rel='stylesheet' type='text/css'>
 <link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>
</head>
<body class="container">
 <h1>A Simple Hello World Voting Application</h1>
 <div class="table-responsive">
  <table class="table table-bordered">
   <thead>
    <tr>
     <th>Candidate</th>
     <th>Votes</th>
    </tr>
   </thead>
   <tbody>
    <tr>
     <td>Rama</td>
     <td id="candidate-1"></td>
    </tr>
    <tr>
     <td>Nick</td>
     <td id="candidate-2"></td>
    </tr>
    <tr>
     <td>Jose</td>
     <td id="candidate-3"></td>
    </tr>
   </tbody>
  </table>
 </div>
 <input type="text" id="candidate" />
 <a href="#" onclick="voteForCandidate()" class="btn btn-primary">Vote</a>
</body>
<script src="https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="./index.js"></script>
</html>

index.js

web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"))
var account;

abi = JSON.parse('[{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')
VotingContract = web3.eth.contract(abi);

contractInstance = VotingContract.at('0x1b98efd29743f589646dbd0b064a9e4cfc4005f8');

candidates = {"Rama": "candidate-1", "Nick": "candidate-2", "Jose": "candidate-3"}

function voteForCandidate(candidate) {
 candidateName = $("#candidate").val();

 contractInstance.voteForCandidate(candidateName, {from: account, gas: 4700000}, function() {
  let div_id = candidates[candidateName];
  $("#" + div_id).html(contractInstance.totalVotesFor.call(candidateName).toString());
 });
}

$(document).ready(function() {

   web3.eth.getAccounts(function (err, accs) {
   if (err != null) {
    alert('There was an error fetching your accounts.')
    return
   }

   if (accs.length === 0) {
    alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly.")
    return
   }

   account = accs[0]

  })

 candidateNames = Object.keys(candidates);

 for(var i=0; i
  let name = candidateNames[i];
  let val = contractInstance.totalVotesFor.call(name).toNumber();
  $("#" + candidates[name]).html(val);
 }
});