HyperledgerFabricv1.4でネットワーク構築

#構築するネットワークと確認
2つのピアノードを保持する2つの組織からなるHyperledgerFabricネットワークを構築していきます。

[こちら]:https://qiita.com/komiya_5467/private/b999844cf948c815e6f7

*[こちら]の環境構築が完了している前提で話を進めていきます*

以下の手順を行う前に、fabric-samples/first-network下のdocker-compose-cli.yamlのFABRIC_LOGGING_SPECをDEBUGにします。

```yaml:
cli:
  container_name: cli
  image: hyperledger/fabric-tools:$IMAGE_TAG
  tty: true
  stdin_open: true
  environment:
    - GOPATH=/opt/gopath
    - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
    - FABRIC_LOGGING_SPEC=DEBUG
    #- FABRIC_LOGGING_SPEC=INFO
```

#MSP
>MSP は証明書の発行と検証、ユーザ認証の背後にある暗号化メカニズムとプロトコルを抽象化するコンポーネントです。 MSP が複雑な部分を抽象化してくれるおかげで、そういった複雑なものを意識することなく、ネットワーク内で証明書の発行や検証、ユーザ認証を行うことができます。Hyperledger Fabric のネットワークは 1つ以上の MSP によって管理されます。ネットワークに参加する Peer、Orderer は MSP を所持している必要があります。 これによりブロックチェーンネットワーク内でクライアントの検証やそれぞれの署名 (Endorsing Peer の署名や Orderer の署名) の検証を行うことができます。

MSPのインスタンスを作成するためにcryptogenツールがあります。
作成したMSPインスタンスは一意なMSPIDに紐付けられ、OrdererやPeerの各ノードに対応するMSPIDを指定します。

HyperledgerFabricネットワークを立ち上げる際に、これらのMSPの情報がGenesisブロックに組み込まれます。

ブロックチェーンネットワークに参加する全ての組織の MSP を定義することで、どの組織がブロックチェーンネットワークへの参加や、チャネルの作成ができるか等の認証を行っています。

![](https://www.ibm.com/developerworks/jp/cloud/library/cl-hyperledger-fabric-basic-4/fig1.png)

##cryptogenツール
それぞれの身元を証明するための証明書と署名鍵を生成するためにcryptogenツールを使います。

###どのように機能するか
cryotogenはネットワークトポロジー(ネットワークの接続形態のこと)を含む```crypto-config.yaml```を使い、組織と組織に属するコンポーネント(ピア・オーダラー)の両方のために証明書とキーのセットを生成します。
各組織には、特定のコンポーネント（ピアとオーダー）をその組織にバインドする一意のルート証明書（ ca-cert ）が用意されています。
各組織に固有のCA証明書を割り当てることで、参加メンバーが独自の認証局を使用するようなネットワークとなります。
Hyperledger Fabric内のトランザクションと通信は、エンティティのプライベートキーによって署名され、次にパブリックキーによって検証されます。

##configtxgenツール
設定ファイルを作成するためのツールです。
configtxgenツールを使用して4つの構成要素を作成します。

* orderer genesis block
* channel configuration transaction
* anchor peer transactions × 2 (組織内の各ピア?)

###どのように機能するか
サンプルネットワークの定義を含むファイルconfigtx.yamlを使います。
1つのOrderer（ OrdererOrg ）と2つのPeer（ Org1 ＆ Org2 ）の3つのメンバーがあり、それぞれ2つのピアノードを管理および維持します。


##ツールを実行する
最初にcryptogenツールを実行します。
バイナリはbinディレクトリにあります。

```:
fabric-samples/first-network$ ls
README.md				docker-compose-couch.yaml
base					docker-compose-e2e-template.yaml
byfn.sh					docker-compose-etcdraft2.yaml
channel-artifacts			docker-compose-kafka.yaml
configtx.yaml				docker-compose-org3.yaml
crypto-config.yaml  <- これを使う		eyfn.sh
docker-compose-cli.yaml			org3-artifacts
docker-compose-couch-org3.yaml		scripts

#実行
$ ../bin/cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
```

MSPの情報(証明書と鍵)はfirst-network下のcrypto-configにあります。

```:
$ tree crypto-config -L 3
crypto-config
├── ordererOrganizations
│   └── example.com
│       ├── ca
│       ├── msp
│       ├── orderers
│       ├── tlsca
│       └── users
└── peerOrganizations
    ├── org1.example.com
    │   ├── ca
    │   ├── msp
    │   ├── peers
    │   ├── tlsca
    │   └── users
    └── org2.example.com
        ├── ca
        ├── msp
        ├── peers
        ├── tlsca
        └── users

```

次にconfigtxgenツールが使用するconfigtx.yamlがある場所を指定し、ツールを呼び出して、orderergenesisブロックを生成します。

```:
$ export FABRIC_CFG_PATH=$PWD

$ ../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block 

2019-05-18 17:10:33.078 JST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2019-05-18 17:10:33.205 JST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2019-05-18 17:10:33.205 JST [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: $HOME/HyperledgerFabric-v1.4/fabric-samples/first-network/configtx.yaml
2019-05-18 17:10:33.318 JST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 004 orderer type: solo
2019-05-18 17:10:33.318 JST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 005 Loaded configuration: $HOME/HyperledgerFabric-v1.4/fabric-samples/first-network/configtx.yaml
2019-05-18 17:10:33.378 JST [common.tools.configtxgen] doOutputBlock -> INFO 006 Generating genesis block
2019-05-18 17:10:33.379 JST [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
```
*orderer genesisブロックとそれに続くこれから作成するchannel-artifactsは、このプロジェクトのルートにあるchannel-artifactsディレクトリに出力されます。 上記のコマンドのchannelIDはシステムチャネルの名前です。*


*以下公式の出力(何か違う)*

```:
2017 - 10 - 26 19 : 21 : 56.301 EDT [ common / tools / configtxgen ] main -> INFO 001 Loading configuration
2017 - 10 - 26 19 : 21 : 56.309 EDT [ common / tools / configtxgen ] doOutputBlock -> INFO 002 Generating genesis block
2017 - 10 - 26 19 : 21 : 56.309 EDT [ common / tools / configtxgen ] doOutputBlock -> INFO 003 Writing genesis block
```

##Channel Configuration Transactionを作成する
###channel transaction artifact
channel transaction artifact(チャネル設定用のファイル)を作成する必要があります。
CHANNEL_NAMEを以下の手順で使えるように環境変数として設定してから、実行します。

```:
 $ export CHANNEL_NAME=mychannel  && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

2019-05-18 17:20:48.888 JST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2019-05-18 17:20:49.006 JST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: $HOME/HyperledgerFabric-v1.4/fabric-samples/first-network/configtx.yaml
2019-05-18 17:20:49.122 JST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 orderer type: solo
2019-05-18 17:20:49.122 JST [common.tools.configtxgen.localconfig] LoadTopLevel -> INFO 004 Loaded configuration: $HOME/HyperledgerFabric-v1.4/fabric-samples/first-network/configtx.yaml
2019-05-18 17:20:49.122 JST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 005 Generating new channel configtx
2019-05-18 17:20:49.127 JST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 006 Writing new channel tx
```
*以下公式の出力(何か違う)*

```:
2017 - 10 - 26 19 : 24 : 05.324 EDT [ common / tools / configtxgen ] main -> INFO 001 Loading configuration
2017 - 10 - 26 19 : 24 : 05.329 EDT [ common / tools / configtxgen ] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
2017 - 10 - 26 19 : 24 : 05.329 EDT [ common / tools / configtxgen ] doOutputChannelCreateTx -> INFO 003 Writing new channel tx
```

###anchor peer
次に、構築しているチャネル上でOrg1のアンカーピアを定義します。

```:
$ ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
```

同じチャネルでOrg2のアンカーピアを定義します。

```:
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
```

>    Anchor Peer
    Anchor Peer はブロックチェーンネットワーク上の他の組織の Peer との通信の窓口となる Peer のことを言います。 各組織の Anchor Peer のアドレスはブロックチェーンネットワークの起動時に受け取ることができるので、Anchor Peer を通じて各組織の持つ Peer の情報を知ることができます。

>Leader Peer
Leader Peer は Orderer と通信する Peer です。LeaderPeer は 1 つの組織内で 1 ノード選出され、Leader Peer が Orderer から新しいブロックを受け取ると、同じ組織内の他の Peer に新しいブロックを伝播します。 Leader Peer により、全ての Peer が Orderer から直接ブロックを受け取る必要がなくなるため、Peer と Orderer 間の通信の負荷を軽減することができます。


#ネットワークを起動する
ネットワークを構築していきます。まずは、docker-compose.yamlで定義されているcliコンテナを立ち上げます。

```:
$ docker-compose -f docker-compose-cli.yaml up  -d
```

-dをつけるとログ表示を消すことができます。-dを指定しない場合、もう一つの端末を開く必要があります。

##チャネルを作成して参加する
docker execコマンドを使用してCLIコンテナに入ります。

```:
$ docker exec -it cli bash
```

これ以降のCLIコマンドを実行するには、4つの環境変数をコマンドの前に設定する必要があります。peer0.org1.example.comはCLIコンテナに組み込まれているので、それらを渡さずに操作できます。ただし他のピアまたはordererに呼び出しを送信したい場合は、以下の例に示すように環境変数をオーバーライドします。


```:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
```

次に、「Channel Configuration Transactionを作成する」セクションで生成した、Channel Configuration Transaction（以下channel.tx）をチャネル構成の要求の一部としてordererに渡します。

チャネル名を-cで指定し、-fでchannel.txを指定します。

```:
$ export CHANNEL_NAME=mychannel
$ peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
```

*--cafileはoredereの証明書へのローカルパスで、TLSハンドシェイクを検証*


peer0.org1.example.comをチャネルに参加させます。

```:
peer channel join -b mychannel.block
```

全てのピアを参加させるのではなく、チャネル内のアンカーピアの定義を正しく更新することができるように、peer0.org2.example.comだけを参加させます。
peer channel joinを実行する前に、環境変数を設定する必要があります。

```:
#環境変数の設置
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

#チャネルに参加
peer channel join -b mychannel.block
```

##アンカーピアを更新する
以下のコマンドでチャネルを更新し、チャネルの定義を伝搬させることができます。チャネルのジェネシスブロック上に設定情報を追加します。ジェネシスブロックを修正するのではなく、アンカーピアを定義するチェーンに変数を追加することで更新します。

チャネル定義を更新して、Org1のアンカーピアpeer0.org1.example.comとして定義します。
先ほど、環境変数を設定したので、それを設定し直してから実行します。

```:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
```

次に、Org2のアンカーピアpeer0.org2.exampleとして定義します。
環境変数の設定が必要です。

```:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
```

##Chaincodeのインストール・インスタンス化
アプリケーションはチェーンコードを通して台帳をやり取りします。
トランザクションを実行・承認するすべてのピアにチェーンコードをインストールしてから、チャネル上でインスタンス化する必要があります。

###インストール
以下のコマンドで、指定されたソースコードをピアのファイルシステムに置きます。
*(同じチェーンコード名・バージョンのソースコードは一つしかインストールできない)*

・Golang

```:
peer chaincode install -n mycc -v 1.0 -p /opt/gopath/src/github.com/chaincode/chaincode_example02/go/
```

・Node.js

```:
peer chaincode install -n mycc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/chaincode_example02/node/
```
・Java

```:
peer chaincode install -n mycc -v 1.0 -l java -p /opt/gopath/src/github.com/chaincode/chaincode_example02/java/
```

とりあえず、Node.jsのチェーンコードをインストールしました。
公式によるとNode.jsはインスタンス化が遅いです。

チャネルでチェーンコードのインスタンス化をするとき、エンドースメントポリシーは、Org1,Org2の両方でピアからの承認を要求する設定となっています。
そのため、Org2でもチェーンコードをインストールします。

環境変数を設定してから、インストールします。

```:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

peer chaincode install -n mycc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/chaincode_example02/node/
```

言語・バージョン・チェーンコード名がチャネル内で一致している必要がある(?以下のインスタンス化作業を一回しか行えない)のでNode.jsのチェーンコードをインストールしました。

###インスタンス化
次にチャネルのチェーンコードをインスタンス化します。インスタンス化では以下の3点をおこなっています。

* チェーンコードの初期化
* チェーンコードのためのエンドースメントポリシーの設定
* ターゲットピアのためのチェーンコードコンテナの起動

・Golang

```:
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
```

・Node.js

```:
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -l node -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
```
・Java

```:
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -l java -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
```

 -P引数でこのチェーンコードに対するトランザクションの検証に必要な承認レベルを指定しています。
```-P "AND ('Org1MSP.peer','Org2MSP.peer')"```として指定しています。 これは、Org1 AND Org2に属するピアからの「承認」（つまり、2つの承認）が必要であることを意味します。構文をORに変更した場合は、どちらか1つの承認が必要になります。

ピアを台帳とやりとりさせるためには、

* チャネルに参加させる
* 適切なチェーンコード名・バージョン・言語のチェーンコードを適切なピアのファイルシステムにインストール

という作業が必要です。

##チェーンコードを動かす
チェーンコードが正しくインスタンス化され、stateDBが生成されたか確認します。

###query(stateDBの参照)
aの値を問い合わせます。

```:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

(略)
100
```
インスタンス化で初期値として100を設定していたので正しいようです。

###invoke(stateDBの更新)
```:
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
```

{a:100, b:200}の状態からa-->bへ10移動させる処理です。
また、orederer,Org1のピア, Org2のピアそれぞれの認証をおこなっています。

aが90になっているか確認します。

```:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

(略)
90
```

となっていれば正しく処理できています。

###ピアを追加してチェーンコードを動かしてみる
組織2にもう一つピアを追加します。
環境変数を設定してから、Org2のpeer1に対してinstallコマンドを実行します。

```:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer1.org2.example.com:10051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt

peer chaincode install -n mycc -v 1.0 -l node -p /opt/gopath/src/github.com/chaincode/chaincode_example02/node/
```

チェーンコードを実行する前にチャネルに参加する必要があります。

```:
peer channel join -b mychannel.block
```

これでqueryやinvokeができるようになったので確かめてみます。

```:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

(略)
90
```

```:
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
```

queryで確認するとa:80になっていたので大丈夫そうです。


#CouchDB
StateDBはデフォルト（goleveldb）からCouchDBに切り替えることができます。 CouchDBでも同じチェーンコード機能を使用できますが、チェーンコードデータがJSONとしてモデル化されていることを条件として、豊富で複雑なクエリを実行する機能が追加されています。

##CouchDBを使用する
CouchDBを使用するためにdocker-compose-coush.yamlを立ち上げます。

```:
docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d
```

上記の手順を使用して、CouchDBのStateDBに対してchaincode_example02チェーンコードを使用できますが、CouchDBのクエリ機能を実行するには、データをJSONとしてモデル化したチェーンコード （marbles02など）を使用する必要があります。 marbles02チェーンコードは、fabric/examples/chaincode/goディレクトリにあります。

##インストール・インスタンス化
チェーンコードをインストール・インスタンス化して行きます。

```:
peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.peer','Org1MSP.peer')"
```

いくつかのビー玉を作成し、それらを動かして行きます。

```:
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["delete","marble1"]}'
```

docker-composeでCouchDBのポートをマッピングしている場合、[こちら](http://localhost:5984/_utils)に移動することで、CouchDBのWebインターフェイスからStateDBを表示できます。

###クエリを実行してみる

・marble2のstateを問い合わせ

```:
peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}'

(略)
{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}
```

![スクリーンショット 2019-05-19 19.17.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393221/dc78ff17-e982-238c-6981-7d849e7c3664.png)



・marble1のstateの履歴をみる

```:
peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'

(略)
[{"TxId":"6a5a44e2cfa88d19bbf23110a6ed46a2e1302a29095dfff99578a2fd801fdb86", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"tom"}, "Timestamp":"2019-05-19 09:14:48.945261713 +0000 UTC", "IsDelete":"false"},{"TxId":"6f16ec0537970e79d59a4c57d9fe98015cee61cd009c038dfb0796448f52f704", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"jerry"}, "Timestamp":"2019-05-19 09:15:18.986398901 +0000 UTC", "IsDelete":"false"},{"TxId":"1cc3aff7a5f0b521c814f5cdb24139b60463a319b66d05db6f0458497c774ff5", "Value":null, "Timestamp":"2019-05-19 09:16:29.081134079 +0000 UTC", "IsDelete":"true"}]
```

![スクリーンショット 2019-05-19 19.16.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393221/7966aead-9628-9705-ac7f-5901cb776d8d.png)

・ビー玉のオーナーから情報検索

```:
peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'

(略)
[{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]
```

![スクリーンショット 2019-05-19 19.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393221/05167300-7395-c033-2523-f89e0cbe551a.png)


##なぜCouchDBか
CouchDBはNoSQLの一種です。
NoSQLの特徴として、大量のデータを扱うサービスで参照や追加処理が主な処理の時は高速だが、データ構造の特性上、更新や削除処理には向かないということが挙げられます。
またCouchDBは、ドキュメント型(キーに対し、XMLやJSONといった、データ構造を柔軟に変更できるドキュメントデータを格納する)なので、アプリケーションで使用しているドキュメントモデル形式を使って、簡単にデータをデータベースに保存し、クエリできます。

この他にも、ブロックチェーンにおけるコンプライアンスとデータ保護のためのセキュリティを強化することができます。トランザクション内の個々の属性をフィルタリングしてマスキングし、必要に応じて読み取り専用権限のみを承認することで、フィールドレベルのセキュリティを実装できるためです。