Hyperledger Fabric 1.4の環境構築からサンプル実行まで

##必要なもの

* Docker(18.06.2~), Docker-compose(1.14.0~)
* Node.js(8.9.x), npm
* Go(1.11.x)
* Python(2.7系)


##バージョン確認

```:Docker,Docker-compose
~$ docker --version
Docker version 18.09.2, build 6247962
~$ docker-compose  --version
docker-compose version 1.23.2, build 1110ad01
~$
```

nodeが無かったのでnodebrewでインストールしました。

```:Node.js,npm
#インストール
~$ curl -L git.io/nodebrew | perl - setup
~$ export PATH=$HOME/.nodebrew/current/bin:$PATH >> ~/.bash_profile
~$ nodebrew install-binary v8.9.4

#バージョン確認
~$ nodebrew use v8.9.4
use v8.9.4
~$ npm -version
5.6.0
```

```:go
~$ go version
go version go1.12.5 darwin/amd64
```

```:Python
~$ python -V
Python 2.7.10
```

##環境構築
インストール用のディレクトリを用意する。
そこに公式サイトに従ってインストール用のスクリプトをダウンロード・実行する。
今回は最新版をインストールしました。

```:スクリプトのインストール・実行
#最新の製品リリースが必要な場合
curl -sSL http://bit.ly/2ysbOFE | bash -s

#バージョンを指定する場合
curl -sSL http://bit.ly/2ysbOFE | bash -s -- <fabric_version> <fabric-ca_version> <thirdparty_version>
curl -sSL http://bit.ly/2ysbOFE | bash -s -- 1.4.1 1.4.1 0.4.15
```
Hyperledgerのコマンド群にパスを通す(bin下にあります)

```:パスを通す
#コマンド群
~/HyperledgerFabric-v1.4/fabric-samples/bin$ ls
configtxgen		cryptogen		fabric-ca-client	orderer
configtxlator		discover		idemixgen		peer

#パスを通す
echo 'export PATH=$PATH:$HOME/HyperledgerFabric-v1.4/fabric-sample/bin' >> ~/.bash_profile
```

スクリプトはDocker HubからHyperledger Fabric DockerイメージをローカルのDockerレジストリにダウンロードし、それらを「latest」としてタグ付けします。

```:imangeの確認
~/HyperledgerFabric-v1.4/fabric-samples$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
hyperledger/fabric-ca          1.4.1               3a1799cda5d7        4 weeks ago         252MB
hyperledger/fabric-ca          latest              3a1799cda5d7        4 weeks ago         252MB
hyperledger/fabric-tools       1.4.1               432c24764fbb        4 weeks ago         1.55GB
hyperledger/fabric-tools       latest              432c24764fbb        4 weeks ago         1.55GB
hyperledger/fabric-ccenv       1.4.1               d7433c4b2a1c        4 weeks ago         1.43GB
hyperledger/fabric-ccenv       latest              d7433c4b2a1c        4 weeks ago         1.43GB
hyperledger/fabric-orderer     1.4.1               ec4ca236d3d4        4 weeks ago         173MB
hyperledger/fabric-orderer     latest              ec4ca236d3d4        4 weeks ago         173MB
hyperledger/fabric-peer        1.4.1               a1e3874f338b        4 weeks ago         178MB
hyperledger/fabric-peer        latest              a1e3874f338b        4 weeks ago         178MB
hyperledger/fabric-javaenv     1.4.1               b8c9d7ff6243        4 weeks ago         1.74GB
hyperledger/fabric-javaenv     latest              b8c9d7ff6243        4 weeks ago         1.74GB
hyperledger/fabric-zookeeper   0.4.15              20c6045930c8        7 weeks ago         1.43GB
hyperledger/fabric-zookeeper   latest              20c6045930c8        7 weeks ago         1.43GB
hyperledger/fabric-kafka       0.4.15              b4ab82bbaf2f        7 weeks ago         1.44GB
hyperledger/fabric-kafka       latest              b4ab82bbaf2f        7 weeks ago         1.44GB
hyperledger/fabric-couchdb     0.4.15              8de128a55539        7 weeks ago         1.5GB
hyperledger/fabric-couchdb     latest              8de128a55539        7 weeks ago         1.5GB
```

##サンプル(Commercial Paper)
Hyperledger Fabricを使用してビジネス上の問題を解決するためのクライアントアプリケーションとスマートコントラクトについてサンプルで学んでいく。
複数の組織が関わる現実世界のコマーシャルペーパーから、必要なすべての概念とタスクについて学ぶ。

###Commarcial Paper
企業が短期資金の調達のために、オープン市場（1年未満の資金取引を行う短期金融市場）で割引形式で発行する無担保の約束手形(現状では手元にお金はないが、将来確実にお金が入る予定があるという時などに使用される信用証券)のことです。

###PaperNet network
PaperNetは、承認された参加者がコマーシャルペーパーを発行・交換・償還・評価することを可能にするコマーシャルペーパーネットワークのことです。


![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/develop.diagram.1.png)











##```基本ネットワーク構築``` ~ ```チェーンコードのインスタンス化```

特定のウインドウからのコマンド実行時を明確にしておきます。

* Takaのウインドウからlsコマンドを実行するときの例

```:特定のウインドウからのコマンド実行時の表記
(Taka)$ ls
```

###ネットワークの作成
Hyperledger Fabricの基本的なネットワークは、

* ピア, ピアが保持している台帳
* Orderer
* CA(認証局)

で構成されています。
これらはDocekrコンテナで実行されます。
サンプルではシェルスクリプトを実行することでネットワークを起動できます。

```:~/HyperledgerFabric-v1.4/fabric-samples/basic-network
$ ./start.sh
  (略)
2019-05-12 09:46:30.751 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2019-05-12 09:46:31.338 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
```

docker psコマンドで基本ネットワークを構成しているコンテナを確認できます。

```:~/HyperledgerFabric-v1.4/fabric-samples/basic-network
$ docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                                            NAMES
7eb1845ee78f        hyperledger/fabric-peer      "peer node start"        5 minutes ago       Up 5 minutes        0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp   peer0.org1.example.com
d07e13e6fc5e        hyperledger/fabric-orderer   "orderer"                5 minutes ago       Up 5 minutes        0.0.0.0:7050->7050/tcp                           orderer.example.com
8542b9ad369f        hyperledger/fabric-ca        "sh -c 'fabric-ca-se…"   5 minutes ago       Up 5 minutes        0.0.0.0:7054->7054/tcp                           ca.example.com
2302b1c2c77f        hyperledger/fabric-couchdb   "tini -- /docker-ent…"   5 minutes ago       Up 5 minutes        4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp       couchdb
```
これらのコンテナは全てnet_basicと呼ばれるネットワークを形成します。
docker networkで確認してみましょう。

```:~/HyperledgerFabric-v1.4/fabric-samples/basic-network
$ docker network inspect net_basic
[
    {
        "Name": "net_basic",
        "Id": "2057b68c06f58c51440a242789b6dfba3fd6d79e04fbf0f12a5b9f65d753e149",
        "Created": "2019-05-12T09:46:13.8953851Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2302b1c2c77f507746a5cd5b67b5abbdaf63e4f70387fd7e845dad04a74e9e33": {
                "Name": "couchdb",
                "EndpointID": "8673bf36ab916f977d041696a3fd727134cd7bcd2e89eef0bce44e8f55429b83",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "7eb1845ee78f53ea6f73b74739631d18518f1e89b78d10f500b1540376232379": {
                "Name": "peer0.org1.example.com",
                "EndpointID": "1b337e40cda49120841ddb9e92d30f8d8a86f56102d92dc2759a909c8dffcc1e",
                "MacAddress": "02:42:ac:12:00:05",
                "IPv4Address": "172.18.0.5/16",
                "IPv6Address": ""
            },
            "8542b9ad369f35cb4d10b731ff6a744f4a9a2a230b997d45958d34c8805ac4c5": {
                "Name": "ca.example.com",
                "EndpointID": "507dca5e691a0846278269c4c9bc670297f5817c6f3e8f837417d1e868bc6248",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            },
            "d07e13e6fc5ea14819ba35266b8e1c3dd8118b784ac085612397e0ca180e6fe7": {
                "Name": "orderer.example.com",
                "EndpointID": "61ebdb0f615bf6736027daa35064802a7c2a82f749373280500a0248f2d68c30",
                "MacAddress": "02:42:ac:12:00:04",
                "IPv4Address": "172.18.0.4/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
```

単一のdockerネットワークでありながら、4つのコンテナが異なるIPアドレスを使用しているのが確認できます。
ローカルマシン上で基本ネットワークが起動している状態です。

###MagnetoCorpを動かす
PaperNetのMagnetoCorpコンポーネントを監視するために、管理者はlogspoutツールを使用して、logspoutコンテナから集約された出力を表示できます。様々な出力をまとめて、1つのウィンドウから何が起こっているか確認できます。スマートコントラクトのインストール時・スマートコントラクトを呼び出すときに便利です。

PaperNetをMagetoCorp管理者として監視してみます。新しいウインドウを開き、monitordocker.shスクリプトを見つけ出し、net_basicに関連づけられているPaperNet dockerコンテナのlogspoutツールを起動します。


```:
(magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
(magnetocorp admin)$ ./monitordocker.sh net_basic
(略)
latest: Pulling from gliderlabs/logspout
4fe2ade4980c: Pull complete
decca452f519: Pull complete
(略)
Starting monitoring on all containers on the network net_basic
b7f3586e5d0233de5a454df369b8eadab0613886fc9877529587345fc01a3582
```
このウインドウにdockerコンテナからの出力が表示されるため、対話するにはもう一つ別のウィンドウを開く必要があります。
MagnetoCorp管理者はdockerコンテナを介してネットワークとやり取りします。

![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/commercial_paper.diagram.4.png)

PaperNetとの対話には、peerコマンドを使用する必要がありますが、これはhyperledger/fabric-toolsというDockerイメージにあらかじめ用意されています。

docker-composeコマンドを使用して、管理者MagnetoCorp固有のdockerコンテナを起動します。

```:
(magnetocorp admin)$ cd commercial-paper/organization/magnetocorp/configuration/cli/
(magnetocorp admin)$ docker-compose -f docker-compose.yml up -d cliMagnetoCorp

Pulling cliMagnetoCorp (hyperledger/fabric-tools:)...
latest: Pulling from hyperledger/fabric-tools
3b37166ec614: Already exists
　　(略)
afff1a4f3772: Pull complete
91abd3b624d2: Pull complete
53c55265651f: Pull complete
Creating cliMagnetoCorp ... done
```
これで、このコマンドラインでMagnetoCorp管理者としてPaperNetと対話することができます。

###スマートコントラクト
PaperNetの中心となるのは、issue(発行)・buy(購入)・redeem(償還)の3つの機能です。これらは、commercial-paper/organization/magnetocorp/contract下にあるpapercontract.jsに含まれています。

###チェーンコードのインストール
papercontractを適切なピアノードにインストールすることで、アプリケーションから呼び出すことができるようになります。
サンプルでは、MagnetoCorp・DigiBankの管理者は、それぞれ権限を持っているのでpapercontractをインストールできます。

![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/commercial_paper.diagram.6.png)

スマートコントラクトはアプリケーション開発の重要なポイントであり、一つのチェーンコード内に複数のスマートコントラクトを定義できます。
チェーンコードはPaperNetで共有されるので、他の組織でも利用できます。

MagnetoCorp管理者は、 peer chaincode installコマンドを使用して、 papercontractをローカルマシンからターゲットとなるピアのdockerコンテナ内のファイルシステムにコピーすることができます。
スマートコントラクトがピアにインストールされ、チャネル上でインスタンス化されると、papercontractがアプリケーションによって呼びされます。これにより、ledger-api\statelist.jsに含まれているaddState()やgetState()などを介して、台帳データベースと対話できます。

実際に、MagnetoCorpの管理者としてpapercontractをインストールしていきます。MagnetoCorpの管理者のウィンドウでdocker execコマンドを使用して、cliMagnetoCorp上でpeer chaincode installコマンドを実行します。

```:
$ docker exec cliMagnetoCorp peer chaincode install -n papercontract -v 0 -p /opt/gopath/src/github.com/contract -l node
2019-05-13 03:42:31.208 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2019-05-13 03:42:31.208 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2019-05-13 03:42:31.358 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
```
*```補足```*

* パラメータ
    * n : チェーンコード名
    * v : チェーンコードのバージョン　
    * p : コンテナのファイルシステムに対するチェーンコードのパス　
    * l : チェーンコードの言語の指定(-lがないとGo言語になる)

* pのパスについて
    * ```/opt/gopath/src/github.com/contract```は、 magnetocorp/configuration/cli/docker-compose.ymlファイルでローカルファイルシステムのパス```.../organization/magnetocorp/contract```にマッピングされています。

* docker-compose.yml内のvolumesを確認

```:
   volumes:
        - (略)
        - ./../../../../organization/magnetocorp:/opt/gopath/src/github.com/
        - (略)
```
* volumesで```organization/magnetocorp```を```/opt/gopath/src/github.com/```にマッピングし、MagnetoCorpのpapercontractのコピーが保存されているローカルファイルシステムにこのコンテナがアクセスします。



* cliMagnetoCorpコンテナは、コマンドをpeer0.org1.exampleをターゲットにするようになっています。

###チェーンコードのインスタンス化
インストールが完了したら、MagnetoCorp管理者はスマートコントラクトを含むpapercontractチェーンコードをインスタンス化する必要があります。このとき、papercontractを実行するための新しくdocker chaincodeコンテナが作成されます。
![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/commercial_paper.diagram.7.png)

実際に、peer chaincode instantiateコマンドを使用して、mychannelのpapercontractをインスタンス化します。

```:
(magnetocorp admin)$ docker exec cliMagnetoCorp peer chaincode instantiate -n papercontract -v 0 -l node -c '{"Args":["org.papernet.commercialpaper:instantiate"]}' -C mychannel -P "AND ('Org1MSP.member')"
2019-05-13 05:11:13.219 UTC [chaincodeCmd] InitCmdFactory -> INFO 001 Retrieved channel (mychannel) orderer endpoint: orderer.example.com:7050
2019-05-13 05:11:13.244 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default escc
2019-05-13 05:11:13.245 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default vscc
```

* パラメータ
    * n : チェーンコード名
    * v : チェーンコードのバージョン
    * l : チェーンコードの言語の指定（デフォルトはGo言語）
    * c : チェーンコードのコンストラクタへのメッセージ(デフォルトは"{}")
    * <b>P</b> : チェーンコードに関連付けられているエンドースメントポリシー

Pはpapercontractのためのエンドースメントポリシーを指定しています。そのトランザクションが有効であると決定される前に、承認(実行と署名)が必要とされる組織のセットを記述します。

他のピアが自身のチェーンコードコンテナでチェーンコードを実行できるようにするために、インスタンス化トランザクションをブロックに含みordererに渡します。
ordererは同じチャネル(今回はmychannel)に参加しているすべてのピアにブロックをブロードキャストするため、papaercontractに対して一回のインスタンス化で、同じチャネル内にいる複数のピアにチェーンコードをインストールすることができます。

以上で、基本ネットワークの起動・チェーンコードのインストール/インスタンス化が終わりました。
続いて、commercial paperを発行するMagnetoCorpアプリケーションについて見ていきましょう。

##アプリケーション

###アプリケーションに必要なステップ

アプリケーションでは、トランザクションを送信するために以下の6つのステップが必要です。

* 6つのステップ
    * Walletから身元を選択する
    * ゲートウェイに接続する
    * 目的のネットワークにアクセスする
    * スマートコントラクトのためのトランザクションリクエストを作成する
    * ネットワークにトランザクションを送信する
    * 応答を処理する

###アプリケーションの構造
papercontract内のissue,buy,redeemなどのスマートコントラクトは、MagnetoCorpのisseu.jsによって呼び出されます。
issue.jsはcommercial-paper/organization/magnetocorp/application下にあります。

Isabellaがcommercial paperを発行する台帳に取引を送信するためにアプリケーションを利用する例は以下のようになっています。
![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/commercial_paper.diagram.8.png)
*ゲートウェイによって、アプリケーションはトランザクションの作成・送信や応答の処理だけで良くなります。異なるネットワーク構成要素間の取引提案や順序付け、通知処理を調整することができます。*

###アプリケーションの依存関係
アプリケーションは、開発の品質やスピードを向上させるために、多くの外部ノードのパッケージ上に構築されています。それらのパッケージををnpm installコマンドでインストールします。 Isabellaのウィンドウで実行してください。

```:
(magnetocorp user:Isabella)$ npm install

> pkcs11js@1.0.17 install $HOME/HyperledgerFabric-v1.4/fabric-samples/commercial-paper/organization/magnetocorp/application/node_modules/pkcs11js
> node-gyp rebuild

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance

Traceback (most recent call last):
  (略)
AttributeError: 'NoneType' object has no attribute 'groups'
gyp ERR! configure error 
gyp ERR! stack Error: `gyp` failed with exit code: 1
gyp ERR! stack     at ChildProcess.onCpExit (usr/.nodebrew/node/v8.9.4/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:336:16)
gyp ERR! stack     at emitTwo (events.js:126:13)
gyp ERR! stack     at ChildProcess.emit (events.js:214:7)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:198:12)
gyp ERR! System Darwin 17.7.0
gyp ERR! command "/usr/.nodebrew/node/v8.9.4/bin/node" "/usr/.nodebrew/node/v8.9.4/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /usr/HyperledgerFabric-v1.4/fabric-samples/commercial-paper/organization/magnetocorp/application/node_modules/pkcs11js
gyp ERR! node -v v8.9.4
gyp ERR! node-gyp -v v3.6.2
gyp ERR! not ok 
npm WARN nodejs@1.0.0 No description
npm WARN nodejs@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! pkcs11js@1.0.17 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the pkcs11js@1.0.17 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /usr/.npm/_logs/2019-05-13T08_54_42_802Z-debug.log
```

エラーが発生しました。

* Xcodeをインストールする
* ```sudo xcode-select -s /Applications/Xcode.app/Contents/Developer```を実行してactiveなdeveloper directoryを変更する

以上の二点で解決しました。


```:
(magnetocorp user:Isabella)$ npm install
(magnetocorp user:Isabella)$ $ ls
addToWallet.js		issue.js		node_modules		package-lock.json	package.json
```
*<b>※package-lock.jsonが作成されていることを確認してください</b>*

###Wallet
Walletから彼女の身元を特定するという作業を行えば、issue.jsを実行しcommercial paperを発行する準備が整います。
Isabellaのウィンドウから、addToWalle.jsを実行して自分のWalletに識別情報を追加します。

```:
(isabella)$ node addToWallet.js
done
```

 複数のIdを自分のWalletに格納できるが。この例では、Useri@org.exaample.comの一つのみを使用。
addToWalletの結果、PaperNetへのトランザクションの送信に使用されるWalletの内容がどのようになったのか確認します。

```:
(isabella)$ ls ../identity/user/isabella/wallet/
User1@org1.example.com
```
このUser1@org1.example.comにIsabellanの識別情報があるので確認します。

```:
$ ls ../identity/user/isabella/wallet/User1\@org1.example.com/
User1@org1.example.com
c75...-priv
c75...-pub
```
* 秘密鍵 : Isabellaの代わりトランザクションの署名に使用(?)
* 公開鍵 : Isabellaの証明書に含まれているもの
* User1@org1.example.com : これは証明書でネットワークに配信される

###issueアプリケーション
証明書の発行を終えると、Isabellaはissue.jsを使用して、MagnetoCorpcommercial paperを発行できます。
発行してみましょう。

```:
(Isabella) $ node issue.js
Connect to Fabric gateway.
Use network channel: mychannel.
Use org.papernet.commercialpaper smart contract.
Submit commercial paper issue transaction.
Process issue transaction response.
MagnetoCorp commercial paper : 00001 successfully issued for value 5000000
Transaction complete.
Disconnect from Fabric gateway.
Issue program complete.
```

Paper00001が5MUSDで発行されたのが確認できます。
papercontract.js内のCommercialPapercontractクラスで定義されているissueトランザクションを呼び出しています。

###DigiBankがPaper00001を購入する
Paper00001をDigiBankの従業員として購入するためにDigiBank管理者のウィンドウに切り替えます。
![](https://hyperledger-fabric.readthedocs.io/en/release-1.4/_images/commercial_paper.diagram.5.png)
*DigiBank管理者としてPaperNetとやり取りする*


別の端末を開き、cliDigiBankコンテナを立ち上げて、DigiBankとしてPaperNetと対話できるようにします。

```:
(digibank admin)$ cd commercial-paper/organization/digibank/configuration/cli/
(digibank admin)$ docker-compose -f docker-compose.yml up -d cliDigiBank

(略)
Creating cliDigiBank ... done
```

立ち上がっているか確認します。

```:
$ docker ps
CONTAINER ID        IMAGE                                                                                                         COMMAND                  CREATED             STATUS              PORTS                                            NAMES
097df5a492f7        hyperledger/fabric-tools                                                                                      "/bin/bash"              42 seconds ago      Up 40 seconds                                                        cliDigiBank
57abca7ae7b5        gliderlabs/logspout                                                                                           "/bin/logspout"          4 days ago          Up 4 days           127.0.0.1:8000->80/tcp                           logspout
40447e5be544        dev-peer0.org1.example.com-papercontract-0-d96abb966a1ed760663cf0a061700a902284832716c55b4cb05eca53054fe011   "/bin/sh -c 'cd /usr…"   4 days ago          Up 4 days                                                            dev-peer0.org1.example.com-papercontract-0
7171a1f248a0        hyperledger/fabric-tools                                                                                      "/bin/bash"              5 days ago          Up 5 days                                                            cliMagnetoCorp
965b85d3719c        hyperledger/fabric-peer                                                                                       "peer node start"        5 days ago          Up 5 days           0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp   peer0.org1.example.com
5f97f6d1c215        hyperledger/fabric-couchdb                                                                                    "tini -- /docker-ent…"   5 days ago          Up 5 days           4369/tcp, 9100/tcp, 0.0.0.0:5984->5984/tcp       couchdb
5998ee5aa689        hyperledger/fabric-orderer                                                                                    "orderer"                5 days ago          Up 5 days           0.0.0.0:7050->7050/tcp                           orderer.example.com
7f73318d0e4a        hyperledger/fabric-ca                                                                                         "sh -c 'fabric-ca-se…"   5 days ago          Up 5 days           0.0.0.0:7054->7054/tcp                           ca.example.com
```
*実際はDigiBankユーザはアクセスできるピア・オーダー・CAしか見ることができません。*

###DigiBankアプリケーション
BalajiはDigiBankのbuyアプリケーションを使用して台帳にトランザクションを送信し、それがコマーシャルペーパー00001所有権をMagnetoCorpからDigiBankに変更します。
CommercialPaperContractクラスは、MagnetoCorpのアプリケーションで使用されているものと同じですが、今回のトランザクションissueではなくbuyです。

###DigiBankとして実行する
MagnetoCorpと同じような手順を踏む必要があります。
依存関係をインストールし、BalajiのWalletをセットアップします。

```:
(digibank admin)$ cd commercial-paper/organization/digibank/application/
(digibank admin)$ npm install

(略)
added 738 packages in 46.701s
```

Balajiの端末からaddToWallet.jsを実行して、自分のWalletに識別情報を追加します。

```:
(balaji)$ node addToWallet.js
done
```

これにより、balajiのID情報をWalletに追加することができました。buy,redeemのトランザクションに使用されます。
Isabellaと同様に、Admin@org.example.comという1つのIDのみ使用しています。

```:
(balaji) $ pushd  ../identity/user/balaji/wallet/Admin\@org1.example.com/
(balaji) $ ls
Admin@org1.example.com
cd96...-priv
cd96...-pub
```

###実際に購入する
Walletに識別情報を追加したことで、トランザクションを発行できるようになりました。
MagnetoCorpコマーシャルペーパー00001の所有権をDigiBankに譲渡するトランザクションを送信します。
Balajiのウィンドウでbuy.jsを実行します。

```:
(balaji)$ node buy.js

Connect to Fabric gateway.
Use network channel: mychannel.
Use org.papernet.commercialpaper smart contract.
Submit commercial paper buy transaction.
Process buy transaction response.
MagnetoCorp commercial paper : 00001 successfully purchased by DigiBank
Transaction complete.
Disconnect from Fabric gateway.
Buy program complete.
```

buy.jsではCommercialPaperContractクラスのbuyトランザクションを呼び出しています。

###償還する
commercial paperのライフサイクルの最後の取引は、DigiBankがMagnetoCOrpと交換を行うことです。
Balajiはredeem.jsを使ってトランザクションを送信し、償還の処理を行います。

```:
$ node redeem.js

Connect to Fabric gateway.
Use network channel: mychannel.
Use org.papernet.commercialpaper smart contract.
Submit commercial paper redeem transaction.
Process redeem transaction response.
MagnetoCorp commercial paper : 00001 successfully redeemed with MagnetoCorp
Transaction complete.
Disconnect from Fabric gateway.
Redeem program complete.
```

redeem.jsでは、所有権がその発行者であるMagnetoCorpに戻ったことを反映して、ワールドステートのPaper00001更新しています。