Hyperledger Fabric 1.0 (Node.jsでトランザクション処理)

#はじめに
[前回](https://qiita.com/tworks55/items/12d879c2b896a61edb48)、[Hyperledger Fabric](http://hyperledger-fabric.readthedocs.io/en/release/index.html)の環境を作るところまで実施してみました。今回は実際にトランザクションを発生させてみます。[GO言語のチェーンコード](http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html)、[Java SDK](https://github.com/hyperledger/fabric-sdk-java)、[Node.jsのチェーンコード](http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html)を試してみたのですが、GO言語とJava SDKはエラーが解決できず、ひとまず[Node.jsのチェーンコード](http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html)でトランザクションを発生させることができました。(GO言語はJava SDKは機会があれば試してみようと思います。)

※環境構築は[こちら](https://qiita.com/tworks55/items/12d879c2b896a61edb48)を参照。

#1. 前提
以下の環境で動作した内容を記述しています。

Windows 10 Home (64bit)
Vagrant 2.0.2
VirtualBox 5.2
bento/ubuntu-16.04
Hyperledger Fabric 1.1.0-rc1
Node.js v8.10.0 (on ubuntu)
npm 5.6.0 (on ubuntu)


#2. Node.jsの環境を構築
Node.jsのサンプルプログラムを試すためにUbuntu上に環境を構築します。
[Node.jsは8.9以上が必要かつVer.9はサポートしていない](http://hyperledger-fabric.readthedocs.io/en/latest/prereqs.html)ため、標準のパッケージから取得したものは使用できません。

V8.9以上のインストール方法は、[https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions)に記載されています。

```
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
```

以下、結果です。

```
vagrant@vagrant:~$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -

## Installing the NodeSource Node.js v8.x LTS Carbon repo...


## Populating apt-get cache...

+ apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease
Hit:2 http://security.ubuntu.com/ubuntu xenial-security InRelease
Hit:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu xenial-backports InRelease
Reading package lists... Done

## Confirming "xenial" is supported...

+ curl -sLf -o /dev/null 'https://deb.nodesource.com/node_8.x/dists/xenial/Release'

## Adding the NodeSource signing key to your keyring...

+ curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -
OK

## Creating apt sources list file for the NodeSource Node.js v8.x LTS Carbon repo...

+ echo 'deb https://deb.nodesource.com/node_8.x xenial main' > /etc/apt/sources.list.d/nodesource.list
+ echo 'deb-src https://deb.nodesource.com/node_8.x xenial main' >> /etc/apt/sources.list.d/nodesource.list

## Running `apt-get update` for you...

+ apt-get update
Get:1 https://deb.nodesource.com/node_8.x xenial InRelease [4,646 B]
Get:2 https://deb.nodesource.com/node_8.x xenial/main Sources [761 B]
Hit:3 http://security.ubuntu.com/ubuntu xenial-security InRelease
<中略>
Hit:8 http://archive.ubuntu.com/ubuntu xenial-backports InRelease
Fetched 7,415 B in 1s (6,290 B/s)
Reading package lists... Done

## Run `apt-get install nodejs` (as root) to install Node.js v8.x LTS Carbon and npm

vagrant@vagrant:~$ sudo apt-get install -y nodejs
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  nodejs
0 upgraded, 1 newly installed, 0 to remove and 68 not upgraded.
Need to get 12.7 MB of archives.
After this operation, 61.3 MB of additional disk space will be used.
Get:1 https://deb.nodesource.com/node_8.x xenial/main amd64 nodejs amd64 8.10.0-1nodesource1 [12.7 MB]
<中略>
Setting up nodejs (8.10.0-1nodesource1) ...
vagrant@vagrant:~$ node -v
v8.10.0
vagrant@vagrant:~$ npm -v
5.6.0
```

#3. CouchDB Docker image ダウンロード
[http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html](http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html)に記載されているfabcarフォルダのサンプルを試しますが、ネットワークはbasic-networkフォルダにあるものを利用しているようです。
(ソースコードは[前回](https://qiita.com/tworks55/items/12d879c2b896a61edb48)ダウンロード済です。)

この中でCouchDBを使用しているのですが、先日構築したDocker環境には含まれていないため、個別にダウンロードする必要があります。ダウンロードするバージョンは、[https://hub.docker.com/r/hyperledger/fabric-couchdb/tags/](https://hub.docker.com/r/hyperledger/fabric-couchdb/tags/)にて最新版を確認しますが、環境に合うものを選択する必要があります。
今回はx86_64-1.0.0-rc1を選択しています。

以下、ダウンロード結果です。

```
vagrant@vagrant:~$ docker pull hyperledger/fabric-couchdb:x86_64-1.0.0-rc1
x86_64-1.0.0-rc1: Pulling from hyperledger/fabric-couchdb
aafe6b5e13de: Pull complete
<中略>
dd7e392626a1: Pull complete
Digest: sha256:80923528e5d570a77dc930cce2dc3e77ff72a8a437316844cbcd4808e7c99311
Status: Downloaded newer image for hyperledger/fabric-couchdb:x86_64-1.0.0-rc1
```

後に出てくるスクリプトでCouchDBのlatestタグを参照するため、事前にCouchDBイメージへタグ付けを実施します。

```
vagrant@vagrant:~$ docker imagees
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-ca        latest              8a6c8c2e2ebf        8 days ago          283 MB
hyperledger/fabric-ca        x86_64-1.1.0-rc1    8a6c8c2e2ebf        8 days ago          283 MB
<中略>
hyperledger/fabric-ccenv     x86_64-1.1.0-rc1    65c951b9681f        8 days ago          1.39 GB
hyperledger/fabric-couchdb   x86_64-1.0.0-rc1    b37a08f8a0cb        8 months ago        1.48 GB
vagrant@vagrant:~$ docker tag b37a08f8a0cb hyperledger/fabric-couchdb:latest
vagrant@vagrant:~$ docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-ca        latest              8a6c8c2e2ebf        8 days ago          283 MB
hyperledger/fabric-ca        x86_64-1.1.0-rc1    8a6c8c2e2ebf        8 days ago          283 MB
<中略>
hyperledger/fabric-couchdb   latest              b37a08f8a0cb        8 months ago        1.48 GB
hyperledger/fabric-couchdb   x86_64-1.0.0-rc1    b37a08f8a0cb        8 months ago        1.48 GB
```

#4. npm install
[Writing Your First Application](http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html)に記載がある通り、fabric-samples/fabcarに移動します。

```
vagrant@vagrant:~$ cd fabric-samples/fabcar
vagrant@vagrant:~/fabric-samples/fabcar$ ls -l
total 28
-rw-rw-r-- 1 vagrant vagrant 2809 Mar 10 09:42 enrollAdmin.js
-rw-rw-r-- 1 vagrant vagrant 6354 Mar 10 09:42 invoke.js
-rw-rw-r-- 1 vagrant vagrant  533 Mar 10 09:42 package.json
-rw-rw-r-- 1 vagrant vagrant 2606 Mar 10 09:42 query.js
-rw-rw-r-- 1 vagrant vagrant 3132 Mar 10 09:42 registerUser.js
-rwxrwxr-x 1 vagrant vagrant 1829 Mar 10 09:42 startFabric.sh
```

##4.1 g++ インストール

npm installする際に、g++が必要になるため、ここでインストールしておきます。以下、結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ sudo apt-get install g++
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  cpp-5 g++-5 gcc-5 gcc-5-base libasan2 libatomic1 libcc1-0 libcilkrts5 libgcc-5-dev libgomp1 libitm1 liblsan0 libmpx0
  libquadmath0 libstdc++-5-dev libstdc++6 libtsan0 libubsan0
Suggested packages:
  gcc-5-locales g++-multilib g++-5-multilib gcc-5-doc libstdc++6-5-dbg gcc-5-multilib libgcc1-dbg libgomp1-dbg
  libitm1-dbg libatomic1-dbg libasan2-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg libcilkrts5-dbg libmpx0-dbg
  libquadmath0-dbg libstdc++-5-doc
The following NEW packages will be installed:
  g++ g++-5 libstdc++-5-dev
The following packages will be upgraded:
  cpp-5 gcc-5 gcc-5-base libasan2 libatomic1 libcc1-0 libcilkrts5 libgcc-5-dev libgomp1 libitm1 liblsan0 libmpx0
  libquadmath0 libstdc++6 libtsan0 libubsan0
16 upgraded, 3 newly installed, 0 to remove and 52 not upgraded.
Need to get 29.8 MB of archives.
After this operation, 39.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 libitm1 amd64 5.4.0-6ubuntu1~16.04.9 [27.4 kB]
<中略>
Setting up g++ (4:5.3.1-1ubuntu1) ...
update-alternatives: using /usr/bin/g++ to provide /usr/bin/c++ (c++) in auto mode
Processing triggers for libc-bin (2.23-0ubuntu10) ...
```

##4.2 npm install 実行
npm installを実行し、必要なnode.jsパッケージをダウンロードします。以下結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ npm install
npm WARN deprecated crypto@0.0.3: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.

> pkcs11js@1.0.13 install /home/vagrant/fabric-samples/fabcar/node_modules/pkcs11js
> node-gyp rebuild

make: Entering directory '/home/vagrant/fabric-samples/fabcar/node_modules/pkcs11js/build'
  CXX(target) Release/obj.target/pkcs11/src/main.o
  CXX(target) Release/obj.target/pkcs11/src/dl.o
  CXX(target) Release/obj.target/pkcs11/src/const.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/error.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/v8_convert.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/template.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/mech.o
../src/pkcs11/mech.cpp: In member function ‘void Mechanism::Free()’:
../src/pkcs11/mech.cpp:121:15: warning: deleting ‘void*’ is undefined [-Wdelete-incomplete]
   delete(param);
               ^
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/param.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/param_aes.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/param_rsa.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/param_ecdh.o
  CXX(target) Release/obj.target/pkcs11/src/pkcs11/pkcs11.o
  CXX(target) Release/obj.target/pkcs11/src/async.o
../src/async.cpp: In member function ‘virtual void AsyncGenerateKey::HandleOKCallback()’:
../src/async.cpp:31:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
../src/async.cpp: In member function ‘virtual void AsyncGenerateKeyPair::HandleOKCallback()’:
../src/async.cpp:55:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
../src/async.cpp: In member function ‘virtual void AsyncCrypto::HandleOKCallback()’:
../src/async.cpp:100:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
../src/async.cpp: In member function ‘virtual void AsyncWrapKey::HandleOKCallback()’:
../src/async.cpp:124:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
../src/async.cpp: In member function ‘virtual void AsyncUnwrapKey::HandleOKCallback()’:
../src/async.cpp:148:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
../src/async.cpp: In member function ‘virtual void AsyncDeriveKey::HandleOKCallback()’:
../src/async.cpp:172:24: warning: ‘v8::Local<v8::Value> Nan::Callback::Call(int, v8::Local<v8::Value>*) const’ is deprecated [-Wdeprecated-declarations]
  callback->Call(2, argv);
                        ^
In file included from ../src/./pkcs11/v8_convert.h:12:0,
                 from ../src/./pkcs11/template.h:6,
                 from ../src/./pkcs11/pkcs11.h:6,
                 from ../src/./async.h:4,
                 from ../src/async.cpp:1:
../../nan/nan.h:1568:3: note: declared here
   Call(int argc, v8::Local<v8::Value> argv[]) const {
   ^
  CXX(target) Release/obj.target/pkcs11/src/node.o
  SOLINK_MODULE(target) Release/obj.target/pkcs11.node
  COPY Release/pkcs11.node
make: Leaving directory '/home/vagrant/fabric-samples/fabcar/node_modules/pkcs11js/build'

> grpc@1.9.1 install /home/vagrant/fabric-samples/fabcar/node_modules/grpc
> node-pre-gyp install --fallback-to-build --library=static_library

[grpc] Success: "/home/vagrant/fabric-samples/fabcar/node_modules/grpc/src/node/extension_binary/node-v57-linux-x64-glibc/grpc_node.node" is installed via remote
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN fabcar@1.0.0 No repository field.

added 261 packages in 61.005s
```

※最初にnpm installした際に、g++が無く途中でエラーが発生したため、g++をインストールした後もnpm installでエラーが発生し、npm rebuildの実施が必要となりました。以下、参考までに。

```
vagrant@vagrant:~/fabric-samples/fabcar$ npm rebuild

> grpc@1.9.1 install /home/vagrant/fabric-samples/fabcar/node_modules/grpc
> node-pre-gyp install --fallback-to-build --library=static_library

[grpc] Success: "/home/vagrant/fabric-samples/fabcar/node_modules/grpc/src/node/extension_binary/node-v57-linux-x64-glibc/grpc_node.node" is installed via remote

> pkcs11js@1.0.13 install /home/vagrant/fabric-samples/fabcar/node_modules/pkcs11js
> node-gyp rebuild

make: Entering directory '/home/vagrant/fabric-samples/fabcar/node_modules/pkcs11js/build'
  CXX(target) Release/obj.target/pkcs11/src/main.o
  CXX(target) Release/obj.target/pkcs11/src/dl.o
  CXX(target) Release/obj.target/pkcs11/src/const.o
<中略>
jsbn@0.1.1 /home/vagrant/fabric-samples/fabcar/node_modules/jsbn
vagrant@vagrant:~/fabric-samples/fabcar$
```

#5. Fabric networkの起動
startFabric.shを実行します。以下実行結果です。

```
vagrant@vagrant:~$ cd fabric-samples/fabcar
vagrant@vagrant:~/fabric-samples/fabcar$ ls
enrollAdmin.js  invoke.js  package.json  query.js  registerUser.js  startFabric.sh
vagrant@vagrant:~/fabric-samples/fabcar$ ./startFabric.sh

# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1

docker-compose -f docker-compose.yml down
Removing network net_basic
WARNING: Network net_basic not found.

docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb
Creating network "net_basic" with the default driver
Creating orderer.example.com
Creating couchdb
Creating ca.example.com
Creating peer0.org1.example.com

# wait for Hyperledger Fabric to start
# incase of errors when running later commands, issue export FABRIC_START_TIMEOUT=<larger number>
export FABRIC_START_TIMEOUT=10
#echo ${FABRIC_START_TIMEOUT}
sleep ${FABRIC_START_TIMEOUT}

# Create the channel
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel create -o orderer.example.com:7050 -c mychannel -f /etc/hyperledger/configtx/channel.tx
2018-03-10 07:04:44.815 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2018-03-10 07:04:44.870 UTC [main] main -> INFO 002 Exiting.....
# Join peer0.org1.example.com to the channel.
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/users/Admin@org1.example.com/msp" peer0.org1.example.com peer channel join -b mychannel.block
2018-03-10 07:04:44.965 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2018-03-10 07:04:45.083 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
2018-03-10 07:04:45.083 UTC [main] main -> INFO 003 Exiting.....
Creating cli
2018-03-10 07:04:46.274 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-03-10 07:04:46.276 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-03-10 07:04:46.277 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-03-10 07:04:46.277 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-03-10 07:04:46.277 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-03-10 07:04:46.541 UTC [golang-platform] getCodeFromFS -> DEBU 006 getCodeFromFS github.com/fabcar
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 007 Discarding GOROOT package bytes
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 008 Discarding GOROOT package encoding/json
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 009 Discarding GOROOT package fmt
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 00a Discarding provided package github.com/hyperledger/fabric/core/chaincode/shim
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 00b Discarding provided package github.com/hyperledger/fabric/protos/peer
2018-03-10 07:04:47.106 UTC [golang-platform] func1 -> DEBU 00c Discarding GOROOT package strconv
2018-03-10 07:04:47.107 UTC [golang-platform] GetDeploymentPayload -> DEBU 00d done
2018-03-10 07:04:47.107 UTC [container] WriteFileToPackage -> DEBU 00e Writing file to tarball: src/github.com/fabcar/fabcar.go
2018-03-10 07:04:47.111 UTC [msp/identity] Sign -> DEBU 00f Sign: plaintext: 0A9B070A5B08031A0B088F878ED50510...2F7EFE1B0000FFFF576EC16E00200000
2018-03-10 07:04:47.112 UTC [msp/identity] Sign -> DEBU 010 Sign: digest: FCFA127B702D984E0EA3996BF2DF69DBBB1029118BCBCCDEB70BFBD20F1903DF
2018-03-10 07:04:47.142 UTC [chaincodeCmd] install -> DEBU 011 Installed remotely response:<status:200 payload:"OK" >
2018-03-10 07:04:47.142 UTC [main] main -> INFO 012 Exiting.....
2018-03-10 07:04:47.256 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-03-10 07:04:47.256 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-03-10 07:04:47.259 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-03-10 07:04:47.259 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-03-10 07:04:47.259 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-03-10 07:04:47.260 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AA6070A6608031A0B088F878ED50510...324D53500A04657363630A0476736363
2018-03-10 07:04:47.260 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: 4101D36B6EA4FA2CD44BB6A4375C975E6B2D04DCA6D8E884DD3E895095DC336B
2018-03-10 07:05:15.650 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: 0AA6070A6608031A0B088F878ED50510...D8D6DD4E5ABADAACE8DCCA2FA4C51060
2018-03-10 07:05:15.650 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: 332A0F6CC162F649CC36AC0390E34C8095D1994875BF2199B23DDA778181D189
2018-03-10 07:05:15.657 UTC [main] main -> INFO 00a Exiting.....
2018-03-10 07:05:25.769 UTC [msp] GetLocalMSP -> DEBU 001 Returning existing local MSP
2018-03-10 07:05:25.769 UTC [msp] GetDefaultSigningIdentity -> DEBU 002 Obtaining default signing identity
2018-03-10 07:05:25.772 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2018-03-10 07:05:25.772 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2018-03-10 07:05:25.772 UTC [chaincodeCmd] getChaincodeSpec -> DEBU 005 java chaincode disabled
2018-03-10 07:05:25.773 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AA9070A6908031A0C08B5878ED50510...1A0E0A0A696E69744C65646765720A00
2018-03-10 07:05:25.773 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: 88211694F5524AADC53BCEBC6DAD17775CDF43757CB0430FBE3F1EA883ACCD9A
2018-03-10 07:05:25.784 UTC [msp/identity] Sign -> DEBU 008 Sign: plaintext: 0AA9070A6908031A0C08B5878ED50510...DEA5EA13C3FBF729B2FEFD3099BAC50C
2018-03-10 07:05:25.784 UTC [msp/identity] Sign -> DEBU 009 Sign: digest: 9878B4F3AE2444B5218EED62A297FBCDCE758153CF8A98ECDE374A88FDB1AD58
2018-03-10 07:05:25.787 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> DEBU 00a ESCC invoke result: version:1 response:<status:200 message:"OK" > payload:"\n \210\341\005b\344\277k>\324\202\310t@4n\203\337-?\203\210\037\033\247\016=%@\313\243\210\340\022\267\006\n\240\006\022\205\006\n\006fabcar\022\372\005\032J\n\004CAR0\032B{\"make\":\"Toyota\",\"model\":\"Prius\",\"colour\":\"blue\",\"owner\":\"Tomoko\"}\032G\n\004CAR1\032?{\"make\":\"Ford\",\"model\":\"Mustang\",\"colour\":\"red\",\"owner\":\"Brad\"}\032N\n\004CAR2\032F{\"make\":\"Hyundai\",\"model\":\"Tucson\",\"colour\":\"green\",\"owner\":\"Jin Soo\"}\032N\n\004CAR3\032F{\"make\":\"Volkswagen\",\"model\":\"Passat\",\"colour\":\"yellow\",\"owner\":\"Max\"}\032G\n\004CAR4\032?{\"make\":\"Tesla\",\"model\":\"S\",\"colour\":\"black\",\"owner\":\"Adriana\"}\032K\n\004CAR5\032C{\"make\":\"Peugeot\",\"model\":\"205\",\"colour\":\"purple\",\"owner\":\"Michel\"}\032H\n\004CAR6\032@{\"make\":\"Chery\",\"model\":\"S22L\",\"colour\":\"white\",\"owner\":\"Aarav\"}\032H\n\004CAR7\032@{\"make\":\"Fiat\",\"model\":\"Punto\",\"colour\":\"violet\",\"owner\":\"Pari\"}\032J\n\004CAR8\032B{\"make\":\"Tata\",\"model\":\"Nano\",\"colour\":\"indigo\",\"owner\":\"Valeria\"}\032M\n\004CAR9\032E{\"make\":\"Holden\",\"model\":\"Barina\",\"colour\":\"brown\",\"owner\":\"Shotaro\"}\022\026\n\004lscc\022\016\n\014\n\006fabcar\022\002\010\001\032\003\010\310\001\"\r\022\006fabcar\032\0031.0" endorsement:<endorser:"\n\007Org1MSP\022\226\006-----BEGIN CERTIFICATE-----\nMIICGjCCAcCgAwIBAgIRAPlwF/rUZUP9mqN4wSml4iswCgYIKoZIzj0EAwIwczEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG\ncmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMTcwODMxMDkxNDMyWhcNMjcwODI5MDkxNDMy\nWjBbMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMN\nU2FuIEZyYW5jaXNjbzEfMB0GA1UEAxMWcGVlcjAub3JnMS5leGFtcGxlLmNvbTBZ\nMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHihxW6ks3B2+5XdbAVq3CBgxRRRZ22x\nzzpqnD86nKkz7fBElBuhlXl2K6rTxyY2OBOB0ts8keqZ93xueRGymrajTTBLMA4G\nA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1UdIwQkMCKAIEI5qg3Ndtru\nuLoM2nAYUdFFBNMarRst3dusalc2Xkl8MAoGCCqGSM49BAMCA0gAMEUCIQD4j0Rn\ne1rrd0FSCzsR6u+IuuPK5dI/kR/bh7+VLf0TNgIgCfUtkJvfvzVEwZLFoFyjoHtr\ntvwzNUS1U0hEqIaDeo4=\n-----END CERTIFICATE-----\n" signature:"0E\002!\000\300\r5\352\312\355\277^\255\302wk\234\376S\302e\3731\270\355/M\250\343'<\215.\206\260\327\002 e%\016\255\220\315\362\243\023\366\360\211M1\264\242\336\245\352\023\303\373\367)\262\376\3750\231\272\305\014" >
2018-03-10 07:05:25.787 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 00b Chaincode invoke successful. result: status:200
2018-03-10 07:05:25.787 UTC [main] main -> INFO 00c Exiting.....

Total setup execution time : 56 secs ...


Start by installing required packages run 'npm install'
Then run 'node enrollAdmin.js', then 'node registerUser'

The 'node invoke.js' will fail until it has been updated with valid arguments
The 'node query.js' may be run at anytime once the user has been registered
```

#6. Log参照
もう１つコンソールを開き、docker logs -f ca.example.comを実行しておきます。

```
vagrant@vagrant:~$ docker logs -f ca.example.com
2018/03/10 07:10:43 [INFO] Created default configuration file at /etc/hyperledger/fabric-ca-server/fabric-ca-server-config.yaml
<中略>
2018/03/10 07:10:43 [DEBUG] CA initialization successful
2018/03/10 07:10:43 [INFO] Home directory for default CA: /etc/hyperledger/fabric-ca-server
2018/03/10 07:10:43 [DEBUG] 1 CA instance(s) running on server
2018/03/10 07:10:43 [INFO] Listening on http://0.0.0.0:7054
```


#7. Enrolling the Admin User
CA serverにadminユーザーを登録します。

node enrollAdmin.jsを実行すると以下のようになります。

```
vagrant@vagrant:~/fabric-samples/fabcar$ node enrollAdmin.js
 Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully enrolled admin user "admin"
Assigned the admin user to the fabric client ::{"name":"admin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"325c0dc0759c5ddfecf1ec01f2d58a0fc20a572e93ede6e2d598c6c8d7556158","identity":{"certificate":"-----BEGIN CERTIFICATE-----\nMIICATCCAaigAwIBAgIUFbsokHFeEwjsrneS3+oQ80kOci4wCgYIKoZIzj0EAwIw\nczELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMT\nE2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMTgwMzEwMDcyMTAwWhcNMTkwMzEwMDcy\nNjAwWjAhMQ8wDQYDVQQLEwZjbGllbnQxDjAMBgNVBAMTBWFkbWluMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAEAmm8eTEEfMKwgOAMahNpQem03bgAfcLnMqix9QAd\nkkIlhqJD1VrlaeSBr7sYBk0FKiMKjsPTuvRe2/ozPtn086NsMGowDgYDVR0PAQH/\nBAQDAgeAMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAAaGfNJrsjIGPMBCsZuVffi\niM3OMCsGA1UdIwQkMCKAIEI5qg3NdtruuLoM2nAYUdFFBNMarRst3dusalc2Xkl8\nMAoGCCqGSM49BAMCA0cAMEQCIFIWCo/MaVDrCWvmtgzjmcgd8SUW5Vczh6Cb07PN\n1hhRAiAsw/AIxHsUk/sicsjAKvbJ/Ni6VjpZCu1sFlQUpjEy+w==\n-----END CERTIFICATE-----\n"}}}
```

ログの方は以下のように出力されます。

```
2018/03/10 07:26:16 [DEBUG] Received request for /api/v1/enroll
2018/03/10 07:26:17 [DEBUG] ca.Config: &{Version:1.1.0-rc1 Cfg:{Identities:{AllowRemove:false} Affiliations:{AllowRemove:false}} CA:{Name:ca.example.com Keyfile:/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk Certfile:/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem Chainfile:/etc/hyperledger/fabric-ca-server/ca-chain.pem} Signing:0xc4202d13b0 CSR:{CN:ca.org1.example.com Names:[{C:US ST:North Carolina L: O:Hyperledger OU:Fabric SerialNumber:}] Hosts:[e15b7033da02 localhost] KeyRequest:<nil> CA:0xc4202a33c0 SerialNumber:} Registry:{MaxEnrollments:-1 Identities:[{ Name:**** Pass:**** Type:client Affiliation: MaxEnrollments:0 Attrs:map[hf.Registrar.Attributes:* hf.AffiliationMgr:1 hf.Registrar.Roles:peer,orderer,client,user hf.Registrar.DelegateRoles:peer,orderer,client,user hf.Revoker:1 hf.IntermediateCA:1 hf.GenCRL:1]  }]} Affiliations:map[org1:[department1 department2] org2:[department1]] LDAP:{ Enabled:false URL:ldap://****:****@<host>:<port>/<base> UserFilter:(uid=%s) GroupFilter:(memberUid=%s) Attribute:{[uid member] [{ }] map[groups:[{ }]]} TLS:{false [] { }}  } DB:{ Type:sqlite3 Datasource:/etc/hyperledger/fabric-ca-server/fabric-ca-server.db TLS:{false [] { }}  } CSP:0xc4202a39a0 Client:<nil> Intermediate:{ParentServer:{ URL: CAName:  } TLS:{Enabled:false CertFiles:[] Client:{KeyFile: CertFile:}} Enrollment:{ Name: Secret:**** Profile: Label: CSR:<nil> CAName: AttrReqs:[]  }} CRL:{Expiry:24h0m0s}}
2018/03/10 07:26:17 [DEBUG] DB: Getting identity admin
2018/03/10 07:26:17 [DEBUG] DB: Login user admin with max enrollments of -1 and state of 0
2018/03/10 07:26:17 [DEBUG] DB: identity admin successfully logged in
2018/03/10 07:26:17 [DEBUG] Processing sign request: id=admin, CommonName=admin, Subject=<nil>
2018/03/10 07:26:17 [DEBUG] Request is not for a CA signing certificate
2018/03/10 07:26:17 [DEBUG] Checking CSR fields to make sure that they do not exceed maximum character limits
2018/03/10 07:26:17 [DEBUG] DB: Getting identity admin
2018/03/10 07:26:17 [DEBUG] Finished processing sign request
2018/03/10 07:26:17 [DEBUG] DB: Getting identity admin
2018/03/10 07:26:17 [INFO] signed certificate with serial number 124062579182215189062622721445152431948547650094
2018/03/10 07:26:17 [DEBUG] DB: Insert Certificate
2018/03/10 07:26:17 [DEBUG] Saved serial number as hex 15bb2890715e1308ecae7792dfea10f3490e722e
2018/03/10 07:26:17 [DEBUG] saved certificate with serial number 124062579182215189062622721445152431948547650094
2018/03/10 07:26:17 [DEBUG] Successfully incremented state for identity admin to 1
2018/03/10 07:26:17 [INFO] 172.18.0.1:37228 POST /api/v1/enroll 201 0 "OK"
```

#8. Register and Enroll user1
上記で発行されたadmin eCertを使用し、user1を登録します。(別コンソールのログは省略します。)

```
vagrant@vagrant:~/fabric-samples/fabcar$ node registerUser.js
 Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully loaded admin from persistence
Successfully registered user1 - secret:JAgvHLWEfklm
Successfully enrolled member user "user1"
User1 was successfully registered and enrolled and is ready to intreact with the fabric network
```

#9. Querying the Ledger
query.jsを使いLedgerに登録された車情報を取得します。

#9.1 車情報一覧を取得
初期状態のquery.jsは、先ほど登録したuser1を使い、Ledgerに登録された車情報の一覧を取得しています。
以下実行結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ node query.js
Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully loaded user1 from persistence
Query has completed, checking results
Response is  [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
```

#9.2 特定の車情報を取得
query.jsnの以下の部分を修正します。fcnを'queryCar'にし、argsを'CAR4'にします。

```変更前.js
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
        //targets : --- letting this default to the peers assigned to the channel
      chaincodeId: 'fabcar',
      fcn: 'queryAllCars',
      args: ['']
};
```
```変更後.js
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
        //targets : --- letting this default to the peers assigned to the channel
        chaincodeId: 'fabcar',
        fcn: 'queryCar',
        args: ['CAR4']
};
```

再度、query.jsを実行します。以下実行結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ node query.js
Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully loaded user1 from persistence
Query has completed, checking results
```

#10. Updating the Ledger
invoke.jsを使い、情報を更新します。
初期状態では何も更新できないので、更新情報をファイルにセットします。

```変更前.js
// createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
// must send the proposal to endorsing peers
var request = {
        //targets: let default to the peer assigned to the client
        chaincodeId: 'fabcar',
        fcn: '',
        args: [''],
        chainId: 'mychannel',
        txId: tx_id
};
```
```変更後.js
// createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
// must send the proposal to endorsing peers
var request = {
        //targets: let default to the peer assigned to the client
        chaincodeId: 'fabcar',
        fcn: 'createCar',
        args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
        chainId: 'mychannel',
        txId: tx_id
};
```
invoke.jsを実行します。以下実行結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ node invoke.js
Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully loaded user1 from persistence
Assigning transaction_id:  033222bdaa6fbeaf5d6f6e3467440194605333a4d3e90ff43a65359a589cece8
Transaction proposal was good
Successfully sent Proposal and received ProposalResponse: Status - 200, message - "OK"
info: [EventHub.js]: _connect - options {"grpc.max_receive_message_length":-1,"grpc.max_send_message_length":-1}
The transaction has been committed on peer localhost:7053
Send transaction promise and event listener promise have completed
Successfully sent transaction to the orderer.
Successfully committed the change to the ledger by the peer
```
query.jsの'CAR4'を'CAR10'に変更し、実行します。以下実行結果です。

```
vagrant@vagrant:~/fabric-samples/fabcar$ node query.js
Store path:/home/vagrant/fabric-samples/fabcar/hfc-key-store
Successfully loaded user1 from persistence
Query has completed, checking results
Response is  {"colour":"Red","make":"Chevy","model":"Volt","owner":"Nick"}
```

#11. 終わりに
これでようやく、Hyperledger fabricを使ったデータの参照と追加を試すことができました。
環境ができたので、サンプルプログラムを解析することで自由にトランザクションを発生させることができそうです。


#参考URL
http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html
http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html
https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions
https://fabric-sdk-node.github.io/tutorial-app-dev-env-setup.html