Easiest Blockchain~簡単 ブロックチェーン・Cloudの勉強ブログ~

ブロックチェーン技術の勉強のために学んだことをシェアしていきます。ブロックチェーン技術の基礎から応用まで幅広く勉強していきます。

超簡易 ブロックチェーン(Ethereum)上での匿名投票プログラム解説 ”Easiest voting app with blockchain”Part6 番外編

今回はものすごく短い記事です。
前回までの記事でEthereumを利用した投票Dappsプログラムを開設しました。

前回はCUI上で投票を実現したのですが、あまり実践的ではありません。
そこで私が参考にした元サイトではhtmlが公開され、GUI操作によって投票ができます。

今回は解説というよりあくまで紹介記事です。
参考にした元記事↓
medium.com

今回は元記事で公開している、htmlとjsのコードを紹介します。
前回までの解説記事用に少々コードをいじってあります。
下に紹介するhtmlとjavascript(index.js)のコードをPart1で作成したvoting_appフォルダに保存してください
※当ブログの解説記事Part1からPart5までを実行してから利用ください。コンパイルをして、ganacheブロックチェーン上にローカルホストでデプロイして接続していないと以下のコードは利用できません。インストールからデプロイまでは前記事をご覧ください。
www.miyatech-univ.com

vote.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>Easiest voting app with blockchain</h1>
  <div class="table-responsive">
    <table class="table table-bordered">
      <thead>
        <tr>
          <th>Candidate</th>
          <th>Votes</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Taro</td>
          <td id="candidate-1"></td>
        </tr>
        <tr>
          <td>Kenji</td>
          <td id="candidate-2"></td>
        </tr>
        <tr>
          <td>Naoko</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"));
abi = JSON.parse('[{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"totalVotesFor","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"validCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"votesReceived","outputs":[{"name":"","type":"uint8"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"x","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidateList","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"candidate","type":"bytes32"}],"name":"voteForCandidate","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"contractOwner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"inputs":[{"name":"candidateNames","type":"bytes32[]"}],"payable":false,"type":"constructor"}]')
VotingContract = web3.eth.contract(abi);
//Part4の記事でnodeコンソール内で指定したcontractInstanceを実行し、アドレスを確認してください。そのアドレス(ブロックチェーンにデプロイした際に発行されたトランザクションid)を以下にcontractinstance = VotingContract.at("ここのアドレスを変更") 変更してください。
contractInstance = VotingContract.at('0x2a9c1d265d06d47e8f7b00ffa987c9185aecf672');
candidates = {"Taro": "candidate-1", "Kenji": "candidate-2", "Naoko": "candidate-3"}

function voteForCandidate() {
  candidateName = $("#candidate").val();
  contractInstance.voteForCandidate(candidateName, {from: web3.eth.accounts[0]}, function() {
    let div_id = candidates[candidateName];
    $("#" + div_id).html(contractInstance.totalVotesFor.call(candidateName).toString());
  });
}

$(document).ready(function() {
  candidateNames = Object.keys(candidates);
  for (var i = 0; i < candidateNames.length; i++) {
    let name = candidateNames[i];
    let val = contractInstance.totalVotesFor.call(name).toString()
    $("#" + candidates[name]).html(val);
  }
});

さてそれではhtmlファイルを開いてみましょう。
※ブラウザはGoogle Chromeをお勧めします。
以下には実際のhtml画像を載せています。
1.まずはhtmlを開きます。
※すでにTaroに投票が1入っていますが、スクリーンショットを取る前にテストで投票してみました、htmlを開いた状態では全員の投票数は0になっています。
f:id:miya_blockchain:20180603204206p:plain
2.ではTaroに投票してみましょう
f:id:miya_blockchain:20180603204211p:plain
f:id:miya_blockchain:20180603204223p:plain
Taroの票が1増えたのが確認できると思います。
次にKenji,Naokoにも同様に投票を行います。
f:id:miya_blockchain:20180603204228p:plain
f:id:miya_blockchain:20180603204232p:plain
f:id:miya_blockchain:20180603204237p:plain
最終的な得票数は
Taro:2
Kenji:1
Naoko:3
となりました。
本当に投票できているかをnodeコンソールから確認してみましょう。
nodeコンソールでの確認については前記事を参照してください。
www.miyatech-univ.com

> contractInstance.totalVotesFor.call("Taro").toString()
'2'
> contractInstance.totalVotesFor.call("Kenji").toString()
'1'
> contractInstance.totalVotesFor.call("Naoko").toString()
'3'

しっかり投票できていますね。
このようにhtmlを利用してブラウザによる投票も可能になります。


今回使ったのはganache-cli(テストブロックチェーン)ですので、実際のブロックチェーンではありません。
機会があったらgethをつかった実際のブロックチェーンに載せる記事も書きたいと思います。
最後までご覧いただきありがとうございました!!