Easiest Blockchain~超簡単 大学生に向けたブロックチェーン技術の勉強ブログ~

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

ビザンチン将軍問題~ブロックチェーン理解への道~

この記事を読んでくださっているということはブロックチェーンに興味があるということですよね。
そんな皆さんには基礎知識であるビザンチン将軍問題(Byzantine Fault Tolerance)について改めて整理していきます。

ブロックチェーンには合意形成アルゴリズムが必要不可欠であり、それらがブロックチェン技術の中核を担っています。
ブロックチェーンの生みの親ともいわれるSatoshi NakamotoもPoWのもつビザンチン将軍問題解決の可能性に関して触れていました。

それでは本題に入ります。

1.二人の将軍問題
ビザンチン将軍問題に入る前にこの議論のもととなる話「The Two Generals Problem」を取り上げます。
次の条件を想定してください

  • 二人の将軍がいます
  • 一人はリーダー、もう一人はそれに従うフォロワー
  • 二人はとある敵陣へ攻め込もうとします
  • 敵を倒すには二人が同じ時間に同時に攻撃を仕掛けなければなりません
  • 二人は遠く離れた地にいるため伝令をお互いに送って「攻撃する時間」を示しあわなければなりません
  • お互いに伝令を送るためには間に位置する敵陣を超えていかなければなりません

以上のことを踏まえてシミュレーションを行います。

  1. 将軍A(リーダー)は朝の9時に攻撃すると決定し、その旨を 将軍B(フォロワー)に伝えるため伝令兵を送ります
  2. 伝令を受け取った将軍Bは「了解した」という旨を伝えるべく伝令兵を将軍Aに送ります
  3. 伝令を受け取った将軍Aは合意が形成されたと考え、9時に攻撃を仕掛けることにしました

さてここで問題です。将軍A,Bは敵を倒すことができたでしょうか?
答えは「どちらともあり得る」です。
なんとも腑に落ちない答えですね。

実はこの答えがまさに合意形成の難しさなのです。

細かく見てみましょう。
「将軍Aが伝令を送り将軍Bが受け取った、将軍Bがさらに伝令を送って将軍Aが受け取った」
一見合意形成がなされたように見えます、しかし実は穴があります。
皆さん次の条件を覚えていますか?

  • お互いに伝令を送るためには間に位置する敵陣を超えていかなければなりません

ここで不確実性が生まれてきます。

この不確実性により将軍Bは自分が出した伝令が将軍Aに届いたか「わからないのです」
これが無限にループしていきます。

だいぶ簡単に書きましたがこれが二人の将軍問題と呼ばれるものです。
ここから派生しビザンチン将軍問題というものが生まれてきます。

2.ビザンチン将軍問題
さて本題のビザンチン将軍問題に入ります。

次の条件を想定してください

  • 1人の将軍A、3人の中将a、b、cがいます
  • 敵軍に攻め込みたいが、全軍で攻撃を仕掛けないと倒すことができない(一人でも撤退した場合は負ける)
  • 4人は遠く離れた地にいるため伝令をお互いに送って「攻撃する」か「撤退する」かを示しあわなければなりません
  • 将軍は中将にどちらの選択をするか伝令をおくります
  • 合意の確認を取るため将軍からの伝令を受け取った中将はほかの中将にさらに伝令を送ります

全員が信頼があり、絶対的に裏切らないといえるならばこの作戦は成功するかもしれません。
しかしここで誰かひとり(ここでは中将a)が「裏切り」を行うと仮定します。
これを踏まえてシミュレーションすると

  1. 将軍Aは「攻撃する」と中将、a、b、c全員に伝令を送りました。
  2. 伝令を受け取った将軍たちは合意を確認するため他の中将へ伝令を送ります
  3. 中将aは中将bに「攻撃する」という旨を送ります
  4. 中将cがここで「裏切り」を行い、bに「撤退する」という旨を送ります

さてこのままいくとどうなるでしょうか。
正解は
aだけが全員が攻撃を行うと思っており、攻撃した。しかし実はほかの二人は撤退していた。
ということが起こります。

このように悪意を持ったノード(ここでは中将)によって合意形成がうまくされませんでした。
少々省いた部分もありますが概要はこのようなことです。

ビザンチン将軍問題は失敗モデルとして最も難しい問題の部類に入ります。
ブロックチェーンは悪意のあるノードが存在することを仮定して設計され、これを解決する策が講じられています。
というかここがブロックチェーンのキモですね。

Bitcoinのブロックチェーンでは最も長いチェーンが採用されるという形で合意形成がされます。
PoWは合意形成というよりスパムを排除する機能といったほうが正しいです。

しかしブロックチェーンではこの問題が完全に排除されたかといわれると疑問視する声が多々あります。
ブロックチェーンの問題はたくさんありますね。


今回はビザンチン将軍問題を扱いました。
今後もブロックチェーンへの理解を深めるためにこのような記事を投稿していきます!!

最後までご覧いただきありがとうございました!

超簡易 ブロックチェーン(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をつかった実際のブロックチェーンに載せる記事も書きたいと思います。
最後までご覧いただきありがとうございました!!

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

前回までにEthereumを利用した匿名投票プログラムをコーディング、ブロックチェーンへデプロイをしてきました。
今回は前回のデプロイ編の続きになります。
↓前回の記事
www.miyatech-univ.com

投票プログラムをブロックチェーンにのせる行程に関しては前回で完了しました。せっかくプログラムを作ったので使ってみたいですよね!
というか動作確認を行っていませんのでそこも併せて確認していきましょう。
今までの記事通りにやったがエラーが出てきた。という方は共有したいのでコメントしていただけると助かります。
それではNodejsのコンソール内でコントラクトを動かしてみましょう!

5:コントラクト実行
※1、前回同様cdコマンドでvoting_appフォルダに移動してから、さらに別ウィンドウのシェルでganache-cliを起動してから行ってください。
※2、前回の記事と続いています、Part2で書いたコードPart3でコンパイルしてからPart4でデプロイした後にこの記事を読んでください。

>contractInstance.totalVotesFor.call("Taro")
BigNumber { s: 1, e: 0, c: [ 0 ] }

前回指定したcontractInstanceからコントラクト内のtotalVotesForを呼び出して。Taroの数値を確認します。
c[0]となっているのが確認できます。
まだ誰からも投票を受けてないので総数が0となっています。
では投票してみましょう。

> contractInstance.voteForCandidate("Taro", {from: web3.eth.accounts[0]})
'0xb6aa941a9958f0b50407caa6f62ada684d74f09d0b7a38f06983a7b38bcf1a91'

ganacheで生成されたテストアカウントのインデックス番号0のアカウントからTaroに投票を行いました。
その下にすぐにhashが表示されます。
これがこのトランザクション(コントラクト実行)のhash値(トランザクションid)になります。
Ethereumではトランザクションが実行されるごとにこのハッシュ値が生成されます。
この値が各トランザクションの証拠となります。この値はイミュータブル(変更不可)です。
ここで一度ganache-cliのウィンドウを見てみましょう。

eth_accounts
eth_sendTransaction

  Transaction: 0xb6aa941a9958f0b50407caa6f62ada684d74f09d0b7a38f06983a7b38bcf1a91
  Gas usage: 43411
  Block Number: 2
  Block Time: Wed May 30 2018 20:48:44 GMT+0900 (東京 (標準時))

どうでしょう、トランザクションidが一致していますよね。
そして使用されたgas、取り込まれたブロックの番号、時間が表示されます。

一番最初のトランザクションなのにBlock Numberが2になっていますね。
これは前回のデプロイした際

deployedContract = VotingContract.new(["Taro","Kenji","Naoko"],{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})

ここでブロックチェーンにデプロイし、コントラクトがブロック1に取り込まれたためです。

では続いて投票してみましょう

> contractInstance.voteForCandidate("Taro", {from: web3.eth.accounts[0]})
'0x1cf83e75f545bbea6904148ffffb28da66bf3dc52225dbf65e280fc6bef2de45'
> contractInstance.voteForCandidate("Naoko", {from: web3.eth.accounts[0]})
'0x2a5160dca86a79564d2db06b8c1fd1ead3b8b438449b23050ce1ac4377ef1027'

最後に投票されたか得票数を確認してみましょう。

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

総数が投票した数だけ変わりましたね。

以上がコントラクトを実際に動かして、投票を行う流れです。
一通り試してみてEthereumの理解が深まったと思います。
※シェル上でコントラクトを動かすのは実用的ではないため次回は参考元サイトのソースをお借りして、html上で投票を行う方法を紹介したいと思います。

今後はSolidityの使い方や、その他ブロックチェーン記事を引き続き書いていきます!
最後までお付き合いいただきありがとうございます!
今後も引き続きよろしくお願いします!

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

今回はついにコントラクトをブロックチェーンにデプロイしていきます!
これまでの記事は下準備+コーディング+コンパイルでした。
区切りをつけて理解していくと簡単に感じますよね。
今後もこのようなスタイルで行こうかと思います。
では早速本題に入っていきましょう!

※1、cdコマンドでvoting_appフォルダに移動してから、さらに別ウィンドウのシェルでganache-cliを起動してから行ってください。
※2、前回の記事と続いています、Part2で書いたコードPart3でコンパイルしてから今回のデプロイを行ってください。

4:デプロイ
デプロイといっても難しいことはありません。ただ変数に重要な個所をストアしていき、ブロックチェーンに組み込む際に必要なデータを指定してあげるだけです、

>abiDefinition = JSON.parse(compiledCode.contracts[":Voting"].interface)
>VotingContract = web3.eth.contract(abiDefinition)
>byteCode = compiledCode.contracts[":Voting"].bytecode
>deployedContract = VotingContract.new(["Taro","Kenji","Naoko"],{data: bytecode, from: web3.eth.accounts[0], gas: 4700000})
>deployedContract.address
>contractInstance = VotingContract.at(deployedContract.address)

①abiDefinition:JSON.perseオブジェクトを使用し、。JSONとして前回のコンパイルしたコードをストアします。
②VotingContract:コントラクトオブジェクトを作成します。これはブロックチェーンにデプロイする際、初期化する際に使用します。
③byteCode:ここに前回重要だといったbytecodeをストアしていきます。
④deployedContract:ここのVotingContract.new部分でブロックチェーン上にデプロイします。最初の["Taro","Kenji","Naoko"]は選挙での立候補者をそのまま記述します。その次に来る引数がブロックチェーンにデプロイする際に重要になります。
1.data:コンパイルされてできたバイトコードです。以前から数回出てきていますが、この部分がブロックチェーン上にデプロイされてハッシュ内に入ります。
2、from:ブロックチェーンでは誰がコントラクトをデプロイしたかをトラックし続けます。ここではganacheが生成したテストアカウントの一つ目(インデックス番号0番目)を指定しています。
※実際のブロックチェーン上でアカウントを利用する場合はアカウントのロックを解除できませんので注意してください、今回のテストアカウントは既にアンロック済みなので気にしなくで大丈夫です。
3、gas:Ethereumを知っている方、勉強している方はわかると思いますが。Ethereumではブロックチェーン上でコントラクトを実行する際にEtherを消費します。ここで指定したgasはマイニングを行うマイナーに報酬として支払われます。ここではその報酬金をgasで指定します。
※1.gasが低すぎるとマイナーへの報酬が少なくなり、マイナーは進んでマイニングしません。よってgasを高く指定すると比較的迅速にマイニングされます。またこの限度額はfor、whileの無限ループを利用したgasの異常消費を制限します。
※2.実際にはgasPrice(ETH) x Total Gas Usage = 支払われたETHとなりますので、厳密にはここでのガスはマイナーへ支払われるETHではありません。
⑤deployedContract.address:④でブロックチェーンにデプロイはできました。しかしブロックチェーン上にはたくさんのコントラクトが実行されています。その中から特定のコントラクトを探す際にここで指定するdeployedContract.addressで識別します。つまりアドレスを利用します。
⑥contractInstance:⑤でコントラクトのアドレスを取得したので、それをインスタンスとしてストアします。

次回は実際にデプロイしたコントラクトをを使って投票していきますが、今回出てきたAddressとabiDefinitionが大切な値なので覚えておいてください。

以上でデプロイ編は終了です。
どうでしょうか、思ったより簡単ですよね!
次回はブロックチェーン上に流したコントラクトにメゾッドを利用して、実際に投票を行ってみましょう。
今回も最後までお付き合いいただきありがとうございました。

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

今回も前回に引き続きブロックチェーンアプリケーション匿名投票Dappsプログラムの解説をしていきます。

その前にモナコインのブロックチェーンへの攻撃が行われました。
簡単に言うと、事前にブロックチェーンをある程度生成しておいて、本丸のブロックチェーンに載せる、そこでコンセンサスにより長いチェーンが採用されるため悪意のあるブロックチェーンのほうが採用されてしまう。これによって取引が改ざんされてしまいました。
このようなことは今後も少なからず起きてしまうと思います。
しかしネガティブな側面をとらえることはとても大事なことですので、今後も注目していきたいと思います。

では本題の投票プログラムの続きに入りましょう。
前回Solidityを使用したコーディングを行いました、今回はコンパイル編です。
3:コンパイル
※事前にcdコマンドでvoting_appフォルダに移動しておきましょう、また別ウインドウでganache-cliを起動しておきましょう。

まず初めにSolidityのコードをコンパイルするためにnpmモジュールのsolcをインストールしましょう。

npm install solc

次にnodeを起動します。node内でweb3、solcライブラリを使用します。
ここではweb3、solcオブジェクトを初期化します。

node
>Web3 = require("web3")
>web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

今回はlocalhostポート8545を使用します。
※他のサイトや教材でほとんどが8545ポートを利用しています。

次にweb3の初期化+ブロックチェーンとの関連付けの確認のためにethereumアカウントを確認しておきましょう。

>web3.eth.accounts
[ '0x4dcd2e673fe1c920c45de581b9347614640575f0',
  '0x5a209645aac68435603257c74146d5d90fd6169d',
  '0xd34db156bf746766de85066ce658ccdddf489c4f',
  '0x40cb7f6830d049981a0e74c3595b6eb3b12a0969',
  '0x5260f537c3cca4f502f70473b3414f91f3f38c00',
  '0x425f7db511183848b99143b20d02aecf1358a976',
  '0x43567eb9c530e7c2c2b50889dc0d4b69ba3b01f3',
  '0xa47b2f3a661e741e9e0674ca28661a367ba837cf',
  '0x5136fadac75c2aba4d5d2688aed7ae494ff138ab',
  '0x6eb4e6ce52de4605d869edbf258f63c16349184e' ]

手順が間違っていなければ上記のようにethのテストアカウントが表示されます。
※テストアカウントはそれぞれ異なります。
最後にコードをString型で読み取ってコンパイルしていきましょう。

>code = fs.readFileSync("Voting.sol").toString()
>solc = require("solc")
>compiledCode = solc.compile(code)

code変数にはnode.jsのfsを利用しVoting.solをString型で読み取ります。
compiledCodeにコンパイルされたデータをストアします。
これでコンパイルができました。
無事にコンパイルが成功するとダーッとコードが表示されます。
コード内のcontractオブジェクト内に2つ大切な個所があります
1.[bytecode]
Voting.solをコンパイルしたときにできるソースコードです。
のちにブロックチェーンにデプロイされるのはこのbytecodeです。
2.[interface]
ユーザーになんのメゾッドが利用可能であるかを知らせるテンプレートです。abiとも呼ばれます。コントラクトと関わる際に今後このabi定義が重要となってきます。

ひとまずこれでコンパイルができました。
ブロックチェーンへのデプロイはこのプログラムのメインともいえるので、ブロックチェーンへのデプロイは次回の記事で解説します!

今回も最後までおつきありいただきありがとうございました!

p.s.この記事を書いている際にブラウザがクラッシュして、ほぼ完成した記事が消滅しました。皆さんも気を付けてください。下書き保存やなどをはこまめに!

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

前回導入編では、環境準備としてnpm、web3、ganacheをインストールしました。
この記事を読む前にPart1を読むことをお勧めします。↓
miyatech.hatenablog.com

今回はプログラム作成編です!
実際にプログラミング言語Solidityを利用して、コードを記述しコントラクトを作成していきます。
SolidityはJavascriptに構文が似ており、非常に勉強しやすい言語でもあります。
Solidityの構文や、解説は別記事で取り上げる予定です!

それでは早速コーディングを行っていきます。
※コードの塊ごとに必要な個所は解説を入れていきます
2:コントラクト作成
※事前にコードエディタで新規作成をしVoting.solとでも名前を付けてvoting_app下に保存をしてください、そこにコードを記述していきます。私はSublime textを使用しています、

まずはSolidityのバージョンをpragmaで指定していきます。

pragma solidity ^0.4.18;

次にメインのコントラクトを追加します。
内容についてはのちに説明していきます。

contract Voting{
      //①
	mapping(bytes32 => uint8) public votesReceived;
	bytes32[] public candidateList;
	
      //②
	constructor(bytes32[] candidateNames) public {
		candidateList = candidateNames;
	}
  
      //③
	function totalVotesFor(bytes32 candidate) view public returns (uint8){
		require(validCandidate(candidate));
		return votesReceived[candidate];
	}
      //④
	function voteForCandidate(bytes32 candidate) public {
		require(validCandidate(candidate));
		votesReceived[candidate] += 1;
	}

      //⑤
	function validCandidate(bytes32 candidate) view public returns (bool) {
		for(uint i = 0; i < candidateList.length; i++){
			if(candidateList[i] == candidate){
				return true;
			}
		}
		return false;
	}
}

何となくパット見ただけでも内容がわかると思います。
それではそれぞれ見ていきましょう。

mapping(bytes32 => uint8) public votesReceived;
bytes32[] public candidateList;

①.mappingを使用して。キーと値に割り振る型を指定します。
mappingは簡単に言うとPythonでいう辞書みたいなものです。
今回はキーを候補者byte32型、値を投票数uint8型として指定しています。
また立候補者リストをbyte32のArrayで指定します。

constructor(bytes32[] candidateNames) public {
	candidateList = candidateNames;
}

②.立候補者リストに投票者をストアしていきます。このコントラクターはブロックチェーンにデプロイするときに一度だけ呼ばれます。
元サイトではfunction Votingとなっていますが、そのままコンパイルするとエラーになります。
現在ではコントラクトと同じ名前を使う場合はconstructorと指定します。
他の書籍や、サイトを見ているとfunction ”コントラクトと同名”となっていることが多くありますが、エラーが出た場合は確認してみてください。

function totalVotesFor(bytes32 candidate) view public returns (uint8){
	require(validCandidate(candidate));
	return votesReceived[candidate];
}

③.この関数では、候補者がその時点で受け取った投票総数を戻します。

function voteForCandidate(bytes32 candidate) public {
	require(validCandidate(candidate));
	votesReceived[candidate] += 1;
}

④.ここでは投票数をインクリメントします。
インクリメントとは”足す”、 ”+=1”のことです。

function validCandidate(bytes32 candidate) view public returns (bool) {
	for(uint i = 0; i < candidateList.length; i++){
		if(candidateList[i] == candidate){
			return true;
		}
	}
	return false;
}

⑤.最後に候補者が存在しているか確認してtrue、falseを返します。
candidateList.lengthを使ってArrayのインデックスをインクリメントして確認していきます。


これでコントラクトのコードは完了です。簡単ですよね!
次回はsolcをつかってコンパイルして、ついにブロックチェーン上にデプロイしていきます!最後までお付き合いいただきありがとうございました!
ご質問がありましたら、コメントにお願いします!

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

今回からは手始めにブロックチェーンアプリケーションの初級編として
匿名投票をブロックチェーン上に載せるプログラムを作っていきます。
今回はPart1ということで導入編です。

参考にしたのはこちらのサイトです↓
medium.com


今回はnpmとnodeを使用し、またweb3.jsを利用して動かしていきます!
仮想ブロックチェーンとして使うものは(ブロックチェーンシミュレーター)ganache-cliです。
※勉強中の学生が勉強中の方に向けて書いている記事ですので、指摘箇所があればコメントしていただけると幸いです。また解釈として簡単な言葉を選ぶようにしています。使用OSはWindows10です。

まずは準備をしていきましょう。

1:環境準備
事前にnpmとnodeをインストールします。
Node.js
にアクセスし、ダウンロードインストールをしてください。
インストールが終わるとnodeそしてnpmもインストールされているはずです。

それでは事前準備ができましたので。
作業に入っていきます。

まずはディレクトリを作成しましょう。

mkdir voting_app
cd voting_app 

今回はわかりやすいようにvoting_appとしましたが。ご自由に指定してもらって構いません。
mkdir はディレクトリを作成するコマンドです。
cd は指定した場所(フォルダ)へ移動するコマンドです。

次にモジュールをインストールするフォルダを作成します

mkdir node_modules

次にganache-cli、web3.jsをインストールします

npm install ganache-cli web3@0.20.2

インストールが完了したら起動してみましょう

ganache-cli

すると以下のようにずらっと出てきます。

Ganache CLI v6.1.0 (ganache-core: 2.1.0)

Available Accounts
==================
(0) 0xc867001038388828bede9ed24a50cba7d87d0152
(1) 0x207154aabb5616846e9f9e6b9adce2f8dd4f453a
(2) 0x5ce62cf9fb11f8ebb7649e3e7ba0ccbdbda62cc1
(3) 0xe604ad444eb1daa0b2fd8d414fdb9a4841c7d3c3
(4) 0x7e0ae96bce372879dcee28882f469300822f4d5d
(5) 0xb91e3e1a564296308124dbbe2a7ca72294b75569
(6) 0x373823574a2bbe1ddd1ae3666a3620391dc6f5e4
(7) 0x935e71ab4e268103556a721579ba2de5852050ed
(8) 0x9971dea65beefdcebc4e063027e36ea7c798926d
(9) 0xab1aedcb0d9e024cbfdbc4159b0e9bd3ba280e59

Private Keys
==================
(0) 0a357266958266835871bd7f111b48e667713f34aec2f172d7ed0aee9f1a6ce4
(1) e251db6254ace222a517cbd040ae71a6538866b4b554c539a268bd6afc78b0e4
(2) 51652d38f1473b3af148bb942f7e5b69000b1f9340644e86c638bbba7b884553
(3) 4354e235331698961d33e3e836fe5b8a7a13f03e555cea688a4f1d53de5d96d5
(4) e3b08a5b0efaafebd0900de9867837d1c7df763d10ceb58368bcf1fb07417a01
(5) c5dded37ea4dbbe28bc062ad5332ef846f37acfa385dbc7ba00053dcdd0ddcc7
(6) 24dc8b017e5e59f8afd300fc3fed32b3fab660b62efb4bfbbbd47ec670ea8359
(7) 385df4314c653262a005311db36c9bc2d4c00def0f2e000f321bdfccc7108ebf
(8) c67c45100cef9f89bd95ab5e49fbc53748c7b2575f792459ed50230f5a66f565
(9) 6faee674d7844420fa87ab3fbe13cbe479a07a062b5e33094f46f60161332856

HD Wallet
==================
Mnemonic:      umbrella cute combine latin donkey pitch peasant luxury reveal another gallery tissueBase HD Path:  m/44'/60'/0'/0/{account_index}

Listening on localhost:8545

ganache-cliは親切にテスト用アカウントを10個自動生成してくれます。
※起動時毎にアカウントが作成されるため、アドレスは上記とは異なります

無事にインストールできたでしょうか?
次回Part2では実際にコードを記述し、コントラクトを作成していきます!