AWS Blockchain TempleteでHyperledger fabricのチェーンコード動かしてみる

# tl;dr.

- [AWS Blockchain Templete](https://aws.amazon.com/jp/blockchain/templates/) でHyperledger fabricチェーンコードのインストール・実行までをやる。

# はじめに

## AWS Blockchain Templeteを触るに至った経緯

Hyperledger fabricを勉強しよう！
↓
やっぱりコンソーシアムはフルマネージドだよね！
↓
[Amazon Managed Blockchain](https://aws.amazon.com/jp/managed-blockchain/) で触ろう！
↓
高い！EC2みたいに停止して課金を停止することもできない！
↓
つらい！
↓
AWS Blockchain Templeteっていうのがある！
↓
EC2単独ノードにコンテナテンプレート作ってくれるらしい。
これなら課金を止められるかも！
↓
チャレンジ！

といった流れになります。

しかしながら、テンプレート作成のチュートリアルはあるものの実際の使い方に関するところは情報が少なかったので、Hyperledger fabric勉強しつつチェーンコードの実行までの流れ、詰まったところを整理していきます。

AWSも初心者なので、両方初心者だとなお厳しい感じですね。

実はAzureなどでもテンプレートサービスはあって、同じようにテンプレート展開までしか情報がないので、おそらく似たようなアプローチでそちらも触れるようになるのではと思います！

まぁ個人でHyperledger fabricのチュートリアルやれば同様のことができますが、環境構築が面倒なので、構築自体はテンプレート使った方が簡単にできると思います。

ではいってみましょう！

# 概要

1. テンプレートを作る
-  バグ？の修正
-  cliコンテナにアクセス
-  チェーンコード操作



## テンプレートを作る

[AWS Blockchain Templete](https://aws.amazon.com/jp/blockchain/templates/) の環境をまず構築します。
ここに関しては[公式のチュートリアル](https://docs.aws.amazon.com/ja_jp/blockchain-templates/latest/developerguide/what-are-blockchain-templates.html)があるので、それ通りにやれば問題ありません。

作成後、EC2にsshで入ってください。

## バグ？の修正

早速チェーンコードを、、、と行きたいですが、docker-composeファイルに問題があり、チェーンコードを操作するコマンドが実行できません。
なので、立ち上がってるネットワークを一旦削除し、設定ファイルを修正してネットワークを再起動します。

```sh
cd HyperLedger-BasicNetwork/artifacts/
pwd # -> /home/ec2-user/HyperLedger-BasicNetwork/artifacts コマンドここにいないと動きません
./network-management-scripts/network.sh down
vi docker-compose/docker-compose-cli.yaml
# (vi内で)
CORE_PEER_MSPCONFIGPATH=/opt /gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
# ここで何故かoptとgopathの間に入ってる半角スペースを削除してください
# (vi抜けて)
./network-management-scripts/network.sh up-silent
docker container ls -a
```

これで適切に環境設定されたコンテナが上がるはずです。

※ここで触ってるnetwork.shですが、Hyperledger fabric公式のbyfc.shとほぼ同じものなようです。そもそも当たり前ですが、大本からコピってテンプレートを作成しているみたい。
- https://github.com/hyperledger/fabric-samples/blob/release-1.4/first-network/byfn.sh

なので、以降の操作も https://hyperledger-fabric.readthedocs.io/en/release-1.4/chaincode4ade.html#install-hyperledger-fabric-samples に挙げられているようなfabricのコマンドとかが効くはずです。

## cliコンテナにアクセス

基本的にはいくつか上がったdockerコンテナの内、「cli」という名前のコンテナでpeerへの操作等を行います。
このままdockerコマンド経由でホストコンテナで操作できるはずですが、上記コンテナ内に入って操作することにします。

```sh
docker exec -it cli bash
```

## チェーンコード操作

ではチェーンコードをインストールしましょう。
インストールするのは公式サンプルの[chaincode_example02](https://github.com/hyperledger/fabric-samples/blob/release-1.4/chaincode/chaincode_example02/go/chaincode_example02.go) を使います。
A,B二者間で保有するアセット数を取得・授受できるようなサンプルコードです。

### チェーンコードのインストール

```sh
peer chaincode install -n mycc -v 0 -p github.com/chaincode/chaincode_example02/go

# -n チェーンコードの名前（任意）
# -v バージョンラベル（任意）
# -p チェーンコードへのパス。GOPATHからの相対位置なので注意。
```

### インストールされたチェーンコードの確認

```sh
peer chaincode list --installed
```

チェーンコードをインストールしたら、実行前にインスタンス化という処理が必要になります。

```sh
peer chaincode instantiate \
-n mycc \
-v 0 \
-c '{"Args":["init","a","100","b","200"]}' \
-C mychannel --tls -o orderer.example.com:7050 \
--cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

# -n チェーンコードの名前（任意）※インストール時に指定したもの
# -v バージョンラベル（任意）※インストール時に指定したもの
# -c チェーンコードに渡す引数。チェーンコードに実装に合わせる。
#    ここでは引数として一つ目に実行する関数名（コンストラクター）、2~5引数でAB両者の処理アセット数を初期化します。
# -C 対象のチャンネル名（テンプレート作成時に設定）
# --tls TLS通信使うよフラグ
# -o Ordererのエンドポイント。byfn.shの初期設定の同じ「orderer.example.com:7050」でいいです。もちろん必要に応じて変える必要があります。その時はdockerコマンドなりで確認してください。
# --cafile OrdererへのTLS通信用秘密鍵へのパス。初期位置だと↑のところにあります。
```

### インスタンス化されたチェーンコードの確認

```sh
peer chaincode list --instantiated -C mychannel
```

### チェーンコードの実行

それではチェーンコードを実行していきます。

#### A（またはB）の残高の確認

```sh
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","b"]}'

# -c でquery関数を実行します
```

#### AからBに10移転

```sh
peer chaincode invoke -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}' -o orderer.example.com:7050 --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --tls

# -c でinvoke（StateDBへの書き込み処理）を実行します。
#    StateDBへの書き込み時にはOredrerとのやり取りが必要なので、Oredrerへのオプションを追加します。
```

再度残高確認コマンドを実行すると、アセット数が移転されていることが確認できます。









# 詰まったところ


## チェーンコードインストール時

下記エラーに遭遇

```
Error: Error getting chaincode code chaincode: path to chaincode does not exist:
```

今回使用したチェーンコードはGo言語で書かれているため、GOPATHからの相対パスでソースを探しに行きます。
フルパス指定とかをするとNotFoundになるので気を付けてください。

## チェーンコードのインスタンス化時

下記エラー

```
Error: could not send: rpc error: code = Unavailable desc = transport is closing
```

どうもTLSで通信しないとgrpcがエラー吐くようです。
はじめはOredrerのオプションとかTLSのオプション付けていなかったので発生していました。
まぁ探し出すのが大変でしたが、、、、
同じくinvoke時にも設定が適切でないと同様のエラーになるようです。


## 鍵見つからない系

```
Error: Error getting broadcast client: failed to load config for OrdererClient: unable to load orderer.tls.rootcert.file: 
```

Oredrerの秘密鍵指定が間違っている場合出る。
相対パスでやるとfabricのconfigディレクトリをルートにするっぽくて認識されなかったので、
フルパスで書きましょう。
というかこの辺の設定は環境変数に入れといた方が後々楽だと思います。




# 感想

テンプレートを使ったHyperledger fabricの試行でした。
Hyperledger fabricを単純に触ってみたいだけなら環境構築済みでくれるので楽、なはず。
次はSDK勉強したいですね。

やっぱりコマンド操作が多いといろいろ面倒なので、フルマネージドでGUIベースで操作できる方が楽でいいですね。
ただawsのHyperledger fabricフルマネージドサービスの場合、GUIで完結とはいかないようです。
他のは見てない。
AzureのQuorumフルマネージドはコンソールもついてるし、ほぼGUIだけで行けるっぽいし楽そうだなーと思ってます。
どちらにするか、ビジネスニーズと技術特性で選ぶのが吉ですが、
自身Ethereumの方が理解できていて楽ちんだなーという印象です。

# 参考

- https://qiita.com/ksukenobe/items/fde330ccdf6ef7031050#%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B
- https://stackoverflow.com/questions/54455891/error-getting-chaincode-code-mycc-path-to-chaincode-does-not-exist
- https://hyperledger-fabric.readthedocs.io/en/release-1.4/chaincode4ade.html#install-hyperledger-fabric-samples
- https://stackoverflow.com/questions/46811019/hyperledger-fabric-peer-chaincode-instantiate-error
- https://stackoverflow.com/questions/49379059/at-the-time-of-chaincode-instansiate-getting-error-error-could-not-send-rpc-er
- https://stackoverflow.com/questions/50600107/bring-the-network-up-fails-in-hyperledger-fabric
- https://github.com/hyperledger/fabric-samples/blob/release-1.4/first-network/byfn.sh