Hyperledger Composer 使ってみた#2

Hyperledger Fabric V1.0がついに[リリースされました。](https://www.hyperledger.org/blog/2017/07/11/hyperledger-fabric-1-0-is-released)

Hyperledger Composerもかなりのスピードでリリースが繰り返されています。
機能追加も激しいです。
https://github.com/hyperledger/composer/releases/tag/v0.9.0

## Hyperledger Composerの環境構築

今回は環境の構築からサンプルの開発、デプロイ、稼動確認までやってみます。
英語Docにインストールガイドがあるので最新情報はこちらをどうぞ
https://hyperledger.github.io/composer/installing/development-tools.html
**特に冒頭、対応OS含め、前提についてはFabricと異っていますのでご注意ください**

まずは環境構築なのですが、その前にComposerで提供されているツールをまとめます。


**CLI**

- composer-cli : デプロイ、アップデート、管理、テストなど
- generator-fabric-composer　：CLIクライアント/Angularクライアント/Composerテンプレート生成

**フロントRESTサーバー**

- composer-rest-server : 専用フロントRESTサーバー (StrongLoop) 通常Fabric上のアプリケーションはgRPCでのコールになりますが、RESTでの呼び出しができるようになります。（一部制約あり）

**Nodeモジュール**

- composer-client : AssetのcrudやTransactionの実行など
- composer-admin : bnaのデプロイやアップデートなど

**Web GUI**

 - composer-playground : GUIエディター (publicもあり)、デプロイ、アップデート、テストなど


前回も記載しましたが、ブロックチェーン・アプリケーションの開発テストからデプロイ等管理までのサイクルはPlaygroundというWeb GUIツールか、任意のEditor + CLI(composer-cli)のどちらかでできます。

Playgroundやcomposer-cliでcomposerアプリ(bna)をデプロイするとComposerアプリとしてComposerクライアントから呼び出しできるようになります。

一方のクライアントですが、ブロックチェーン・アプリケーションを呼び出すクライアント・アプリケーション用のライブラリとしてNode.js用のモジュールが提供されています。

図にすると↓のようなイメージです。
![comp3.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/9812433b-046b-ee9c-c9dc-ed54f92e6c7c.png)

登場コンポーネントとしてはHyperledger Fabricが前提になってしまうので、Fabricって何と言う方、[こちら](http://qiita.com/kyrieleison/items/ec5223bbe6140822df4a)や[こちら](https://www.ibm.com/developerworks/jp/cloud/library/j_cl-blockchain-basics-bluemix/index.html)、[こちら](http://qiita.com/tyasu/items/92c2033cf3199a80cb67)の記事など如何でしょうか。

環境構築といってもComposerのレベルでは利用したいツールだけ導入すればOKです。
Editor + CLIで運用したいのであればcomposer-cliだけいれればいいですし、オンライン公開されているplaygroundだけ使うのであればComposerとしては何も準備しなくてもＯＫなのです。
（ただしオンラインplaygroundはバージョン選択できませんし、強制更新されますのでご注意ください。）

rest-serverやgeneratorの導入も必須ではないです。RESTでの呼び出しを使いたい場合やテスト用の画面をジェネりたい時に導入すれば問題ありません。

ちなみにここではFabric自体の導入には触れていません。
簡単にFabric側も整えるには以下インストールガイド冒頭の前提導入(prereqs-ubuntu.sh)をお試しください。
https://hyperledger.github.io/composer/installing/development-tools.html

### CLI(composer cli)の導入
CLIベースでcomposerアプリの運用管理を行う場合はcomposer-cliを導入します。

```
npm install -g composer-cli
```
ただし、composerはバージョンアップが頻繁で、かつクライアントとサーバーでバージョンが揃ってないとトラブルが起こる可能性があります。必要に応じてバージョン指定を行ってください

```
npm install -g composer-cli@0.8.1
```

※Vagrantなどの仮想環境で導入する場合、事前に以下を実施しないとパーミッション系の書き込みエラーが発生する場合があります。

```
npm config set unsafe-perm true

```

### Playgroundの導入
最新バージョンの（もしくはバージョン指定して）Playgroundをローカルに導入したい場合は以下です。やはり必要に応じて@バージョン指定してください。

```
npm install -g composer-playground
```

必須のツールとしてはcomposer-cliかplayground、どちらかがあればOKです。


## Hyperledger Composerアプリケーションの開発
では早速開発に入ります。[前回#1](http://qiita.com/khit9/items/8e08f27400b11f31cfa9#hyperledger-composer%E3%81%A7%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA)で解説したように、Composerアプリはモデル定義とJSロジックで構成します。

Playgorundを用いる場合は予め編集元のテンプレートが提供されているので、それぞれのファイルを編集するだけです。任意のJavaScriptエディターを利用する場合はまずはyoでアプリケーションのスケルトンを生成すると楽だと思います。
https://hyperledger.github.io/composer/business-network/bnd-create.html

**モデル** 専用記法でモデリング byビジネスアナリスト

- Asset:ブロックチェーンでの管理対象資産。
- Participant:アプリケーションのアクター(※Fabricのenrollment IDにマッピングされます)
- Transaction:アプリケーションのビジネスロジックの処理引数

**ビジネスロジック** JavaScriptで記述 byデベロッパー

- Processer:ビジネスロジックの処理実装

**アクセス制御** JSON/JavaScriptで記述 byデベロッパー

ACL:アクターのアクセスコントロール設定


モデル定義は.ctoファイルに独自記法を用いて定義します。
といっても非常にシンプルです。
https://hyperledger.github.io/composer/reference/cto_language.html

```
namespace org.acme.sample

asset SampleAsset identified by assetId {
  o String assetId
  --> SampleParticipant owner
  o String value
}

participant SampleParticipant identified by participantId {
  o String participantId
  o String firstName
  o String lastName
}

transaction SampleTransaction {
  --> SampleAsset asset
  o String newValue
}

event SampleEvent {
  --> SampleAsset asset
  o String oldValue
  o String newValue
}
```

- Asset, Participant, Transaction (もしくはEvent)いずれかの接頭辞でクラスを定義します。
- 必ずidentified byでidプロパティを指定します。
- クラスにはプロパティ名と型を定義します。
- 使える型はプリミティブと任意クラスおよびそれらの配列
- メンバーとして別クラスを持ちたい場合、-->で参照先のクラス型をもったプロパティを定義します。
- 必須プロパティで無い場合はoptionalを付与します。

Playgroundで定義する場合、リアルタイムチェックが走りますので、記述ミスがあるとすぐ指摘してくれます。

Fabric上で動くビジネスロジック(チェーンコード)はJavaScriptで関数として定義します。
ビジネスロジックでは、モデルで定義したParticipantが、Assetに対して何らかの処理をおこないます。

モデルのうち、transactionは関数単位で引数の構造を定義しています。ここではSampleTransactionという関数の引数が定義されています。
対応する関数は以下のように同名のJavaScript関数として定義します。引数txにはモデルで定義したプロパティを渡すことができます。(関数なので先頭小文字で)


```
function sampleTransaction(tx) {

    // Save the old value of the asset.
    var oldValue = tx.asset.value;

    // Update the asset with the new value.
    tx.asset.value = tx.newValue;

    // Get the asset registry for the asset.
    return getAssetRegistry('org.acme.sample.SampleAsset')
        .then(function (assetRegistry) {

            // Update the asset in the asset registry.
            return assetRegistry.update(tx.asset);

        })
        .then(function () {

            // Emit an event for the modified asset.
            var event = getFactory().newEvent('org.acme.sample', 'SampleEvent');
            event.asset = tx.asset;
            event.oldValue = oldValue;
            event.newValue = tx.newValue;
            emit(event);

        });

}

```
このサンプルではモデル定義したSampleAssetのAssetRegistryを取得し、引数で取得したnew valueをセットしたSampleAssetで更新をかけています。結果はイベントで通知しています。

- Transactionでは[composer-runtimeのAPI](https://hyperledger.github.io/composer/jsdoc/module-composer-runtime.html)を利用できます。(composer-clientとcomposer-adminはクライアントサイドのAPI）

- Transactionはチェーンコードのinvokeにあたる処理に相当します。
    - invokeはAsset等の更新処理を行います。更新処理によりブロックチェーン(台帳)へのブロック追加が発生します。
    - 参照だけするquery処理ではないため、同期的にAssetの値などをクライアントに返却することはできません。返却したい場合、イベントとして通知する必要があります。(最後のemit部分)

- 主たるロジックであるAssetの処理は以下のAPIを用いて実装します。
 - [AssetRegistry](https://hyperledger.github.io/composer/jsdoc/module-composer-runtime.AssetRegistry.html)による特定AssetのCRUD処理 
 - [Factory](https://hyperledger.github.io/composer/jsdoc/module-composer-runtime.Factory.html)による新規Asset,Participant,Eventインスタンスの生成

- optionalがついていない引数が無い場合は呼び出し前にエラーが返りますが、それ以外は同期的にエラーを返却することはできませんので同様にイベント通知を利用します。

Playgroundで開発する場合、モデル同様にリアルタイムチェックが走るので便利です。

クライアント側からAssetの書き込みや更新、Transactionの実行をリクエストすると、
Fabricにinvokeがコールされ、ブロックチェーンのブロック追加がトリガーされます。


最後がACL定義です。ACL定義はJSONで行います。
https://hyperledger.github.io/composer/reference/acl_language.html

```
rule EverybodyCanReadEverything {
    description: "Allow all participants read access to all resources"
    participant: "org.acme.sample.SampleParticipant"
    operation: READ
    resource: "org.acme.sample.*"
    action: ALLOW
}

rule EverybodyCanSubmitTransactions {
    description: "Allow all participants to submit transactions"
    participant: "org.acme.sample.SampleParticipant"
    operation: CREATE
    resource: "org.acme.sample.SampleTransaction"
    action: ALLOW
}

rule OwnerHasFullAccessToTheirAssets {
    description: "Allow all participants full access to their assets"
    participant(p): "org.acme.sample.SampleParticipant"
    operation: ALL
    resource(r): "org.acme.sample.SampleAsset"
    condition: (r.owner.getIdentifier() === p.getIdentifier())
    action: ALLOW
}
```

ACL定義は
- どのParticipantが : participant(p)
- どのAssetに対し : resource(r)
- どんな条件のときに : condition
- 何ができるのか : operation
を定義します。


以上、モデル定義、JSビジネスロジック、ACL定義の３つでアプリケーションを構成します。
ここまでできたらパッケージングしてみましょう。

Playgroundを利用している場合は、Editor画面のExportボタンでパッケージングされたbnaファイル(実体はzip)をローカルダウンロードできます。（また、ImportでbnaファイルをPlayground上に展開できます。）

![comp4.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/14b0d077-0c11-0820-a3cb-8bb25b0be970.png)

任意エディターを使っている場合、cliでパッケージングできます。
https://hyperledger.github.io/composer/reference/composer.archive.create.html

アプリケーションのルートディレクトリにてcomposer archiveします。

```
composer archive create -d .
```


##Composerアプリケーションのテスト at Playground

Playgroundの場合、このあと説明するデプロイを本物のFabric環境に行うまえにWeb上でシミュレート実行することができます。

まずは最新状態のComposerアプリをWeb上のシミュレート環境にデプロイします。Playground左下のDeployボタンを押してみましょう。Deploy Successfulのポップアップが出れば完了です。
![comp5.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/07a04382-cb3c-7acd-a33b-472ca5b0f9ef.png)

※PublicのPlaygroundではできませんが、ローカル導入のPlaygroundで後述するconnection profileの設定を行っていると対象のFabric環境にデプロイされます。設定していなければデフォルトはWeb環境へのデプロイです。

続いてTestタブを選択してください。
左側にモデルとして定義したParticipant, Asset, Transactionが表示されていると思います。
![comp6.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/39d1f4f9-a4e3-9974-c299-748fcadccc91.png)

任意のモデルのCreate New **を選択すると、JSONフォーマットでプロパティ設定してAssetを追加できるダイアログが表示され、Createすることができます。
AssetやParticipantのCRUD処理はここから実行することができます。
![comp7.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/b91d6d28-edd0-8291-4723-34430345dedb.png)

Transactionの前提となるAssetやParticipantの準備ができたらTransactionの実行に移ります。
Submit Transactionのボタンを押すとモデル定義したTransaction引数を設定できるダイアログが現れます。
![comp8.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/0a1c2ec5-239b-27dd-6382-fb2e62521b29.png)
引数を入力し、Submitすると・・
![comp9.PNG](https://qiita-image-store.s3.amazonaws.com/0/106176/94b7718e-da5d-f812-7f4e-9af263ab259d.png)
Transactionロジックが実行され、結果がポップアップで現れます。
ロジック中にエラーがあれば確認し、修正することができます。

Transactionの結果、ロジックでAssetの更新や生成をしているのであれば対象のAssetの項目から確認することができます。

このように、Playgroundがあれば実際のFabric環境を準備しなくても開発したComposerアプリをテスト実行することができます。JavaScriptだけに実行精度もかなり高い印象です。


##Composerアプリケーションのデプロイ

テスト確認とパッケージングができたら対象のFabric環境にComposerアプリケーションをデプロイしてみます。
ちなみにローカル導入したPlaygroundの場合はパッケージングは気にせずそのままDeployボタンで任意の接続環境にデプロイすることができます。

composer-cliの場合、以下のcomposer deployコマンドでbnaファイルをFabric環境にデプロイできます。
https://hyperledger.github.io/composer/reference/composer.network.deploy.html

```
composer network deploy -a digitalPropertyNetwork.bna -p myProfile -i <enrollment Id> -s <secret>
```

-iで指定するのが対象Fabric環境のmembership service(もしくはca)に登録されているenrollment id、-sがそのidのパスワード(secret)です。

また、このとき対象の環境ごとにConnection Profileという接続構成ファイルを準備する必要があります。
https://hyperledger.github.io/composer/reference/connectionprofile.html

cliコマンドの-pで指定している部分なんですが、ConnectionProfileは$HOME/.composer-connection-profiles以下に任意のフォルダ名で配置することができます。-pで指定するのはフォルダ名です。
で、フォルダ直下にconnection.jsonというファイル名で設定をJSON記述します。

対象環境がV0.6の場合のフォーマット

```
{
    "type": <hlf|web>,
    "keyValStore":"/home/<your-username>/.composer-credentials",
    "membershipServicesURL": <your-membership-services-url>,
    "peerURL": <your-peer-url>,
    "eventHubURL": <your-event-hub-url>
}
```

- type : 基本hlf(fabric)。playgroundを利用する場合のみFabricなしでシミュレート可能なwebを選択可
- keyValStore : membership-Serviceのcertを格納するフォルダパス。enrollment idでの初回アクセス時に認証され、certがここに保管されます。
    - **membership-serviceの特性上、ある環境で一度コマンド発行してcertを保管してしまうと、他の環境ではcertをコピペしない限り同じenrollmentidは使えないのでご注意を**

- membershipServicesURL : Fabric環境のmembership serviceの接続先 http(s)://domain:port
- peerURL: Fabric環境のpeerの接続先 http(s)://domain:port
- eventHubURL: Fabric環境のeventHubの接続先 http(s)://domain:port

publicのPlaygroundではいまのところconnection profileの設定はできずweb環境へのデプロイのみですが、ローカル導入した場合は画面からConnection Profileの設定が可能です。

###接続テスト

最後にCLIを用いてデプロイしたアプリへの接続テストをしてみましょう。
接続テストにはcomposer network pingコマンドが利用できます。
https://hyperledger.github.io/composer/reference/composer.network.ping.html

```
composer network ping -n digitalproperty-network -i WebAppAdmin -s DJY27pEnl16d
The connection to the network was successfully tested:
  version = 0.4.1
  participant = <no participant found>
Command completed successfully.
```


ここまでComposerアプリケーションの開発、テスト、デプロイまで基本的なところを確認することができました。
次回はこのComposerアプリケーションを利用するクライアントを開発してみたいと思います。

##関連URL
[Hyperledger Composer](https://hyperledger.github.io/composer/introduction/introduction.html)
[composer-cliのコマンドラインリファレンス](https://hyperledger.github.io/composer/reference/commands.html)
[composer APIリファレンス](https://hyperledger.github.io/composer/jsdoc/index.html)