Hyperledger composerで投票システムを作ってみた【作成編】

最近はやりのブロックチェーンを触ってみよう！
ということで、手っ取り早く試せると定評のある「Hyperledger composer」で投票システムを作ってみました。
> なぜ投票システムかというツッコミは無しで

★★
スクリーンショットを取りながら書くとかなり長くなりそうだったので、
作成編とテスト編の2部構成に分けています。

テスト編はこちら　→　https://qiita.com/sh003/items/d15afc786417d86b64a6

なお、Hyperledger composer自体の解説は別の方が書かれているのでここでは割愛します

# このサンプルの概要
## やりたかったこと
* 候補者A,B,Cの誰かに投票できるシステム
  * 投票者は任意に追加できる
  * 追加された投票者には投票権(1票)が付与される
  * 投票を行うと、投票された票の所有者がA,B,Cいずれかの有権者に変わる

## 利用したもの
* Hyperledger composer Playground v0.14.0
  * Playground？：Hyperledger composerをWEB UIベースのお試し環境で触ってみれるもの(と認識しています)

## 作成したもの
* model file(.cto)
  * 参加者(participant)、資産(Asset)、トランザクションなどを定義するファイル
* script file(.js)
  * トランザクション処理の内容を記載するファイル。チェーンコードに相当。

以下、作成手順
--- 

# Hyperledger composer Playgroundの準備
## Hyperledger composerにアクセス
https://hyperledger.github.io/composer/

<img width="1440" alt="スクリーンショット 2017-10-17 9.05.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/8879a246-3894-4f73-8421-cee6c39b9214.png">

ローカル環境でHyperledger composerを利用する場合、`Install〜`を選択しますが、今回はサクッとテストしたいので`Try it Online`からテスト環境を起動します。

## Let's Blockchain!

<img width="1440" alt="スクリーンショット 2017-10-17 9.05.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/81c04700-c1c7-d578-8bc1-1fb8f6049aaf.png">

Hyperledger Composer Playgroundへようこそ！

## Business Network選択画面

<img width="1440" alt="スクリーンショット 2017-10-17 9.05.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/f49650c8-68e7-cf8b-1ce7-ec976656a622.png">

この時点でbasic-sample-networkがすでにできています。が、今回は利用しません。
隣の`Deploy a new business network`を選択します。

## 新規Business Networkの作成

<img width="1440" alt="スクリーンショット 2017-10-17 9.06.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/3af93dcb-bceb-59e2-f48a-e6d86ebf10a4.png">

早速サンプルを作ってみます。
1. 最上段に任意の名前を入力します
2. デフォルトでは`basic-sample-network`が選択されていますが、今回は`empty-business-network`を選択
3. 画面右下の`Deploy`を選択

>  ここで選択した`empty-business-network`は最低限の権限設定(permissions.acl)のみが用意されたbusiness networkです。
もっと手っ取り早く色々作りたい方は、サンプルがいくつか用意されているので、そちらを利用されると良いかと思います。
(自分はこれから勉強・・・)

## 新しいBusiness Networkに接続

<img width="1440" alt="スクリーンショット 2017-10-17 9.06.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/63e212eb-990a-9aec-d615-0fc5b399f6a8.png">

先ほどDeployしたNWが作成されています。
パネル下段の`Connect now →`から設定を始めます

## サンプルシステムのダッシュボード
<img width="1440" alt="スクリーンショット 2017-10-17 9.06.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/a1262e49-0d23-4b8d-a386-6557b09954a1.png">

`empty-business-network`で作成したため、ほぼ空っぽです。
ここから左側の`+ Add a file...`を選択して各ファイルを記載していきます。

# 各ファイルの作成
## model fileの作成
<img width="1440" alt="スクリーンショット 2017-10-17 9.06.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/af57bf20-c367-8093-7b2d-05697b1985be.png">

最上段`Model File`を選択。

<img width="1440" alt="スクリーンショット 2017-10-17 9.06.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/b4b63bd5-ee63-edab-0e06-2a1674966919.png">

ブラウザ上でコーディングできます。
文法間違いは随時確認してくれているので、ミスがあると教えてくれます。
(エディタ部分下部の`Everything looks good!`の部分が変わります)

> 中身の説明はまた別の機会に...

## script fileの作成

<img width="1440" alt="スクリーンショット 2017-10-17 9.18.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/34c4a0e7-b659-0135-9554-ef91ff9d65bc.png">

同様にscript fileも作成。
script fileはJavascriptなので、お好きなエディタでコーディングしましょう

サンプルのソースコードは以下の通りです。

``` script.js
/**
 * add new user and new vote.
 * @param {org.acme.sample.AddUser} user name
 * @transaction
 */
function addUser(tx) {
  var name = tx.name;
  var factory = getFactory();
  
  // create new Resource(User and Vote)
  var user = factory.newResource('org.acme.sample','User',name);
  user.type = 'voter';
  var vote = factory.newResource('org.acme.sample','Vote',name);
  vote.owner = user;
  
  // add new asset(Vote)
  getAssetRegistry('org.acme.sample.Vote')
    .then(function (assetRegistry) {
      return assetRegistry.add(vote);
  });
  
  // add new participant(User)
  getParticipantRegistry('org.acme.sample.User')
    .then(function (participantRegistry) {
      return participantRegistry.add(user);
  });
  
  return 0;
}

/**
 * voting 
 * @param {org.acme.sample.Voting} candidate 
 * @transaction
 */
function voting(tx) {
  tx.vote.owner = tx.candidate;
  return getAssetRegistry('org.acme.sample.Vote')
    .then(function (assetRegistry) {
      return assetRegistry.update(tx.vote);
  });
}
```

> 調べながらなんとなく書いたので、
> ちゃんとした書き方をご存知の方がいらっしゃればご指摘ください。。。


## Business networkを更新
<img width="1440" alt="スクリーンショット 2017-10-17 9.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/192468/4f341cb2-c0a2-84c0-77c7-cfade8dc0338.png">

サイドバー上の`Update`からBusiness networkを更新します。
いずれかのファイルにエラーがあると`Update`ボタンが押せない仕様になっているので、文法的には正しい状態でUpdateできるようになっています。

---

ここまででファイルの作成は完了です。
ここからはテスト編に続きます。

テスト編 → https://qiita.com/sh003/items/d15afc786417d86b64a6