MacOSXでHyperleger fabricを動かす


Hyperleger fabricは現在活発に開発が行われていること、またインストール方法が直近で大きく変更されている（改善されている）ため、書籍やWEB上の多くの資料どおりではうまく動作せず、逆に混乱を招く自体となっています。

Hyperleger fabricを動作させる基本的な構成は次の通りです。
```
MacOSX - Virtualbox - Vagrant - docker - Hyperleger fabric
```

Virtualboxによる仮想化でハードやOSの違いを吸収し、均一な環境でHyperleger fabricの環境を構築することができます。
また、Vagrantやdockerを利用することで簡単に環境構築できることを目指しているようです。

##VirtualboxとVagrantの導入

下記を参考に、MacOSXにVirtualboxとVagrantを導入します。
また、簡単で良いのでその動作を確認しておいてください。

http://qiita.com/tetotetote/items/7701b1e6207313467b1d

##gitとGoの導入

下記よりそれぞれgitとGoをインストールします。

git
https://git-scm.com/download

Go
https://golang.org/dl/

MacOS版のGoは「/usr/local/go」にインストールされるため、GOROOTとPATHをそれぞれ設定します。
また、workディデクトリを作成し、GOPATHとします。

```
$ echo 'export PATH=/usr/local/go/bin:$PATH' >> $HOME/.profile
$ echo 'export GOROOT=/usr/local/go' >> $HOME/.profile
$ mkdir $HOME/work
$ echo 'export GOPATH=$HOME/work' >> $HOME/.profile
. $HOME/.profile
```

##Hyperledger fabricの開発環境の構築

```
$ cd $GOPATH
$ mkdir -p src/github.com/hyperledger
$ cd src/github.com/hyperledger
$ git clone https://github.com/hyperledger/fabric.git
$ cd fabric
```

「devenv」ディレクトリを確認するとVagrantfileがあり、開発環境の構築が行えます。

```
$ cd devenv
$ vagrant up
```

1GB近くあるBox「hyperledger/fabric-baseimage」をダウンロードして追加するので5分から10分程度の時間を要します。

```
$ vagrant ssh
```

「docker」コマンドが利用できるよう環境が整備されていますが、まだイメージはほとんどありません。

```
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
busybox             latest              7968321274dc        2 weeks ago         1.11 MB
```

Hyperledger fabricを利用するためには、ノードの機能を提供する「peer」、セキュリティ関連の機能を提供する「membersrvc」のそれぞれのdockerイメージが必要です。またクライアントとなる環境も必要です。

「examples/sdk/node/docker-compose.yml」を参照すると「hyperledger/fabric-membersrvc」「hyperledger/fabric-peer」「hyperledger/fabric-starter-kit」のそれぞれのイメージを利用して、初期テストを行えそうです。

```
$ cat examples/sdk/node/docker-compose.yml 
membersrvc:
  # try 'docker ps' to see the container status after starting this compose
  container_name: membersrvc
  image: hyperledger/fabric-membersrvc
  command: membersrvc

peer:
  container_name: peer
  image: hyperledger/fabric-peer
  environment:
    - CORE_PEER_ADDRESSAUTODETECT=true
    - CORE_VM_ENDPOINT=unix:///var/run/docker.sock
    - CORE_LOGGING_LEVEL=DEBUG
    - CORE_PEER_ID=vp0
    - CORE_SECURITY_ENABLED=true
    - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
    - CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=noops
  # this gives access to the docker host daemon to deploy chain code in network mode
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  # have the peer wait 10 sec for membersrvc to start
  #  the following is to run the peer in Developer mode - also set sample DEPLOY_MODE=dev
  command: sh -c "sleep 10; peer node start --peer-chaincodedev"
  #command: sh -c "sleep 10; peer node start"
  links:
    - membersrvc

starter:
  container_name: starter
  image: hyperledger/fabric-starter-kit
  volumes:
    # tweak this to map a local developmnt directory tree into the container
    - ~/mytest:/user/mytest
  environment:
    - MEMBERSRVC_ADDRESS=membersrvc:7054
    - PEER_ADDRESS=peer:7051
    - KEY_VALUE_STORE=/tmp/hl_sdk_node_key_value_store
    # set to following to 'dev' if peer running in Developer mode
    - DEPLOY_MODE=dev
    - CORE_CHAINCODE_ID_NAME=mycc
    - CORE_PEER_ADDRESS=peer:7051
  # the following command will start the chain code when this container starts and ready it for deployment by the app
  command: sh -c "sleep 20; /opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02/chaincode_example02"
  stdin_open: true
  tty: true
  links:
    - membersrvc
    - peer
```

「docker-compose」コマンドを実行し、「docker images」「docker ps」で状況を確認してみます。

```
$ docker-compose -f examples/sdk/node/docker-compose.yml up -d
$ docker images
REPOSITORY                       TAG                 IMAGE ID            CREATED             SIZE
busybox                          latest              7968321274dc        2 weeks ago         1.11 MB
hyperledger/fabric-starter-kit   latest              1dd3be105e8d        3 months ago        1.71 GB
hyperledger/fabric-membersrvc    latest              b3654d32e4f9        3 months ago        1.42 GB
hyperledger/fabric-peer          latest              21cb00fb27f4        3 months ago        1.42 GB
$ docker ps    
CONTAINER ID        IMAGE                            COMMAND                  CREATED             STATUS              PORTS               NAMES
5f70ba2188cb        hyperledger/fabric-starter-kit   "sh -c 'sleep 20; ..."   12 seconds ago      Up 12 seconds                           starter
75787d0ec3b9        hyperledger/fabric-peer          "sh -c 'sleep 10; ..."   13 seconds ago      Up 12 seconds                           peer
581bee8299b8        hyperledger/fabric-membersrvc    "membersrvc"             18 seconds ago      Up 13 seconds                           membersrvc
```

starterのContainer IDを確認します（上記の例では「5f70ba2188cb」）。

まず設定されている環境変数を確認してみます。

```
$ docker exec -it 5f70ba2188cb env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/go/bin:/opt/gopath/bin
HOSTNAME=e33e7f4dceb3
TERM=xterm
MEMBERSRVC_NAME=/starter/membersrvc
MEMBERSRVC_ENV_HOSTNAME=e33e7f4dceb3
MEMBERSRVC_ENV_PWD=/
MEMBERSRVC_ENV_SHLVL=1
MEMBERSRVC_ENV_GOROOT=/opt/go
MEMBERSRVC_ENV_GOPATH=/opt/gopath
MEMBERSRVC_ENV__=/usr/bin/printenv
PEER_NAME=/starter/peer
PEER_ENV_CORE_PEER_ID=vp0
PEER_ENV_CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
PEER_ENV_CORE_PEER_ADDRESSAUTODETECT=true
PEER_ENV_CORE_LOGGING_LEVEL=DEBUG
PEER_ENV_CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=noops
PEER_ENV_CORE_SECURITY_ENABLED=true
PEER_ENV_CORE_VM_ENDPOINT=unix:///var/run/docker.sock
PEER_ENV_CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
PEER_ENV_CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
PEER_ENV_HOSTNAME=e33e7f4dceb3
PEER_ENV_PWD=/
PEER_ENV_SHLVL=1
PEER_ENV_GOROOT=/opt/go
PEER_ENV_GOPATH=/opt/gopath
PEER_ENV__=/usr/bin/printenv
CORE_CHAINCODE_ID_NAME=mycc
KEY_VALUE_STORE=/tmp/hl_sdk_node_key_value_store
DEPLOY_MODE=dev
MEMBERSRVC_ADDRESS=membersrvc:7054
CORE_PEER_ADDRESS=peer:7051
PEER_ADDRESS=peer:7051
PWD=/
SHLVL=1
HOME=/root
GOROOT=/opt/go
GOPATH=/opt/gopath
_=/usr/bin/printenv
```

また「examples/sdk/node/docker-compose.yml」の「command」に記載の通り、すでにサンプルのチェーンコードプロセス「/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02/chaincode_example02」が実行されています。このチェーンコードは送金処理を実装したものです。

下記のコマンドを実行して、starterコンテナに接続します。

```
$ docker exec -it 5f70ba2188cb bash
# exit
```

またmenbersrvcコンテナに接続するには、同様にContainer IDを確認して接続します（上記の例では「581bee8299b8」）。

```
$ docker exec -it 581bee8299b8 bash
# exit
```

接続を解除（ログアウト）するには「exit」コマンドを実行します。

##トランザクションの実行

すでにチェーンコードプロセスが実行されているので、次の順にサンプルコマンドを実行してトランザクションを実行します。

1. 登録されているユーザでネットワークにログイン
2. Deplioyトランザクションの実行
3. Invokeトランザクションの実行
4. Queryトランザクションの実行

###ネットワークにログイン

menbersrvcコンテナに接続し、登録されているユーザを確認します。今回はユーザ「jim」、パスワード「6avZQLwcUe9b」を利用します。

```
$ docker exec -it 581bee8299b8 bash
# cat /opt/gopath/src/github.com/hyperledger/fabric/membersrvc/membersrvc.yaml
...
        users:
				...
        		jim: 1 6avZQLwcUe9b bank_a
...
# exit
```

starterコンテナに接続し、先ほど確認したユーザでネットワークにログインします。

```
$ docker exec -it 5f70ba2188cb bash
# peer network login jim -p 6avZQLwcUe9b
```

場合により、ここでディレクトリが無いというエラーが出るので作成し、再度、同じコマンドを実行します。

```
# mkdir -p /var/hyperledger/production/client/
# peer network login jim -p 6avZQLwcUe9b
```


チェーンコードをデプロイします（Taroに100、Hanakoに200の初期値を設定）。

```
# CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -l golang -n mycc -c '{"Function":"init", "Args":["Taro","100","Hanako","200"]}' -u jim --logging-level DEBUG
```

次にInvokeトランザクションを実行します。（TaroからHanakoに10を送金）

```
# CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode invoke -l golang -n mycc -c '{"Function":"invoke", "Args":["Taro","Hanako","10"]}' -u jim --logging-level DEBUG
```

最後に、Queryトランザクションを実行します。（Taroの所持金を表示）

```
$ CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode query -l golang -n mycc -c '{"Function": "query", "Args":["Taro"]}' -u jim --logging-level DEBUG
```

本来ならここで結果（90）が表示されるのですが、以下のように文字化け？して結果がよく分からなくなりました。

```
Query Result: "?D?Z??Ug?ސ??qR?\&We?P???
```

starterコンテナのログを確認します。

```
# exit
$ docker logs 5f70ba2188cb
```

そうするとログ中に以下のような表示がありきちんと処理されていることが分かります。

```
Query Response:{"Name":"Taro","Amount":"90"}」
```

今回のチェーンコードは「/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02」にあるので、参考にしながら開発等行えそうです。

##終了

コンテナを終了させるには下記コマンドを実行します。

```
$ docker-compose -f examples/sdk/node/docker-compose.yml down
```

またVirtualbox仮想環境からログアウトし、仮想環境を終了します。

```
$ exit
$ vagrant halt
```