[Hyperledger Fabric]Fabcar( 公式サンプル)とNGO-blockchain（AWSサンプル）を使ってローカル環境でブロックチェーンとAPIサーバを立てる

#### Hyperledger FabricにAPIサーバでアクセスしたい！

Hyperledger Fabricと通信するAPIサーバをローカルで立ててみます。

今回は公式サンプルのFabcarとAWSが出しているNGO-blockchainのサンプルを使ってやってみました。

Amazon Managed Blockchainは停止出来ない（止めるには削除するしかない）のでローカルで環境があると大変捗ります！


####今回の目標
Fabcarのサンプルでローカル環境にHyperledger Fabricネットワークを構築。
そこにNGO BlockchainサンプルのAPIサーバでアクセス出来るようにする。

では始めましょう！


####必要なもの

[Fabcarサンプル](https://github.com/hyperledger/fabric-samples)

[NGO Blcokchainサンプル](https://github.com/aws-samples/non-profit-blockchain)

今回はHyperledger Fabric v1.2を使用しています！

####始めます
Fabcarのサンプルネットワークの立ち上げに関してはこの記事がわかりやすいです。

[Fabcarサンプルで学ぶHyperledger Fabric Node.js SDK (v1.2.1対応版)](https://qiita.com/yoshihiro-nnnn/items/a9db142f59f606977b11)

####Fabcarネットワークに変更を加える

ネットワークが立ち上がるとDockerコンテナがいくつか起動します。
今回はその中のCliコンテナ内でAPIサーバを立てます。

fabric-samples/basic-network/docker-compose.ymlを見ると
cliコンテナの設定が書いてあります。
ローカル環境にあるngo-blockchainとfabcarフォルダをコンテナ内で扱いたいのでマウントできるように書き換えます。
working_dirを変えたのと、
2,4つ目のボリュームの部分と、portsの部分を付け加えました。


```docker-compose.yml
 cli:
   #省略
   working_dir: /opt/gopath/src/github.com/
   volumes:
        - /var/run/:/host/var/run/
        - ~/non-profit-blockchain:/opt/gopath/src/github.com/hyperledger/fabric/peer
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ~/fabric-samples/fabcar:/opt/gopath/src/github.com/fabcar
   ports:
        - 3000:3000
```

これで一度Fabcarを起動しますがその前に、
今回はFabcarのチェーンコードではなくngoのチェーンコードをデプロイしたいので
fabcar/startFabric.shの中身を少し変えます。
変更するのは
１５行目あたりのifの中身と
三ヶ所あるdockerコマンドの-nオプションの部分です

```startFacric.sh
CC_SRC_PATH=/opt/gopath/src/github.com/ngo-chaincode/src

-n ngo
```

そして起動

```
./startFabric node
```

ここで管理者とユーザーのアイデンティティを登録します
fabric-samples/fabcar/です

```
node enrollAdmin.js
node registerUser.js
```



ここまででブロックチェーン側でやることはほぼ終わりです。

####APIサーバの設定

APIサーバの設定を色々決めているのファイルは主に３つあります。
connection-profile.yaml
client-org1.yaml
config.json
です

まずはディレクトリ構成をつくります
non-profit-blockchainディレクトリ内でこのような構成をつくり

```
tmp/
　└ connection-profile/
　  ├ org1
　  │ 　└ client-org1.yaml
　  └ ngo-connection-profile.yaml
```

以下のようにyamlファイルを書いてください。
(ngo-rest-api/connection-profileにあるgen-connection-profile-local.shを使用するとこの構成が作成できます。
その際はスクリプトファイル内のREPODIRの値に気をつけてください)


各サーバのurlの部分はこのコマンド

```
docker network inspect net_basic
```
で確認できるそれぞれのコンテナのIPアドレスにしてください。
名前などの情報は一貫性があればなんでも大丈夫です。

```ngo-connection-profile.yaml


name: "ngo"
x-type: "hlfv1"
description: "NGO Network"
version: "1.0"

channels:
  mychannel:
    orderers:
      - orderer.com
    peers:
      peer1:
        endorsingPeer: true
        chaincodeQuery: true
        ledgerQuery: true
        eventSource: true

organizations:
  Org1:
    mspid: Org1MSP
    peers:
      - peer1
    certificateAuthorities:
      - ca-org1

orderers:
  orderer.com:
    url: grpc://<ordererコンテナのIPアドレス>:7050
    grpcOptions:
      ssl-target-name-override: orderer.example.com
    tlsCACerts:
      path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem

peers:
  peer1:
    url: grpc://<ピアコンテナのIPアドレス>:7051
    eventUrl: grpc://<ピアコンテナのIPアドレス>:7053
    grpcOptions:
      ssl-target-name-override: peer0.org1.example.com
    tlsCACerts:
      path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem

certificateAuthorities:
  ca-org1:
    url: http://<caコンテナのIPアドレス>:7054
    httpOptions:
      verify: false
    tlsCACerts:
      path: /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem
    registrar:
      - enrollId: admin
        enrollSecret: adminpw
    caName: ca.example.com
```

次はclient-org1.yamlです
pathではfabcar/hfc-key-storeまでのパスを指定します
これでfabcarネットワーク内のアイデンティティをAPIサーバが参照できるようになります。

```client-org1.yaml

name: "NGO-org1"
x-type: "hlfv1"
description: "NGO for Org1"
version: "1.0"
client:
  organization: Org1
  credentialStore:
    path: "/opt/gopath/src/github.com/fabcar/hfc-key-store"
    cryptoStore:
      path: "/opt/gopath/src/github.com/fabcar/hfc-key-store"
```


次はconfig.jsonです

```config.json
{
    "host":"localhost",
    "port":"3000",
    "channelName":"mychannel",
    "chaincodeName":"ngo",
    "eventWaitTime":"30000",
    "peers":[
        "peer1"
    ],
    "admins":[
       {
          "username":"admin",
          "secret":"adminpw"
       }
    ]
 }

```

最後に一つ！

ngo-rest-api/app.jsで以下のように変えます

```javascript:app.js
var host= "cliコンテナのIPアドレス"

```

####サーバ起動！！！

設定完了です！

ではcliコンテナに入ってサーバ起動しましょう！

```
docker exec -it cli bash


# cd ngo-rest-api
# npm install
# cd src
# node app.js &

```

これでdocker内でAPIサーバが起動しています！
curlコマンドを打ったりしてみる

```
curl -s -X GET http://localhost:3000/health 
```

<img width="610" alt="スクリーンショット 2019-07-02 22.34.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344683/7673eb4b-6051-78f0-5701-879d573f1ab6.png">

できてます！

あとはapp.js内のコードに合わせてcurlコマンドを叩いてみたり、チェーンコードとAPIを書き換えて遊んでみたりしてみてください！！
チェーンコードのInvokeやQueryをする際にはネットワークに登録されているどのアイデンティティを使用しているのかをリクエストボディに含める必要があるので、その場合は以下のようなコマンドになります。

```
curl -s -X GET http://localhost:3000/donor -H "content-type: application/json" -d '{"userName":"admin", "orgName":"Org1"}'　
```

###まとめ

これでHyperledger Fabricと通信できるAPIサーバが立てられました！
VisualStudioCodeでDockerの拡張を入れるとログがすぐに見られるので開発捗ります！
Managed Blockchainを使用してチェーンコードの開発とかしようと思うとピア側のログがみられない（？）のでかなり大変だと思います

余談ですが
Amazon Managed Blockchainで立てることのできるピアは現状LevelDBにしか対応しておらず、
CouchDBは使用できないです。

fabcarサンプルではCouchDBを使用しているので、もし同じようにLevelDBを使う環境にしたい場合は
上記のdocker-compose.ymlのpeer0.org1.example.comの部分でCOUCHDBを含む環境変数を消してあげるとLevelDBが使えるようになります。

また、LevelDB用のクエリを行いたい場合は
チェーンコードのngo.jsの
queryByString関数内で

- コメントアウトしているLevelDB用のクエリをコメントインさせる
- CouchDB用のクエリはコメントアウトさせる

ことが必要になります！

ご参考までに！