[Blockchain]Hyperledger Fabricを試す(更新履歴の抽出方法の調査)

## 目的・背景

要員管理へBlockchainを適用できるか調査を進めていましたが、要員情報が過去どのような更新が行われてきたかを参照できる必要がある、という条件がありました。

BlockChainは過去実行したトランザクション情報を含んだブロックはすべて保存されているので理論上は参照可能なはずです。

実際、Hyperledger Fabric Explorerでは過去のブロックやトランザクションが参照可能となっていることは確認できました。

ですが、どのような更新命令を発行したのかまでは参照できず、更新された結果が参照出来ただけにとどまっています。

### (参考)Hyperledger Fabric Explorerでのブロック情報の参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/1a31602b-e54f-f365-060d-a5e4aba173c8.png)

### (参考)Hyperledger Fabric Explorerでのトランザクション情報の参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/0c0165f0-fff9-7aff-b0c4-e233598f1fed.png)

初期データとして、aに100、bに200のコインを登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/380261e0-9990-f270-bebe-d8b5e2f99918.png)


その後、aからbにコインを10移動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/8854dcf1-22bf-03bb-44ee-9deb43c21f68.png)


## 目標

どのようなコマンドでブロック、トランザクションの情報を取得しているか調査する。

## 参考サイト

[Hyperledger Fabricでアプリケーション設計するのに参考にした情報](https://qiita.com/kai_kou/items/8314e8e18c3d679947c0)

[Hyperledger Fabric v1.0.1 のセットアップとサンプルの実行](https://qiita.com/comeonyama/items/add6a9c77193740ab65d)


## わかっていること

fabcarでcarNumberを指定して最新情報を取得することは出来ているが、過去の更新情報の取得が行えません。

### chaincode

/home/ubuntu/fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js

        queryCar  条件検索
        createCar  登録
        queryAllCars  全件検索
        changeCarOwner  更新

## わかったこと

/home/ubuntu/fabric-samples/balance-transfer/testAPIs.sh を解析することで、Blockchain内の情報を取得することが可能だということが分かりました。

### Block HASHとPreHash

Hyperleddger Fabric ExplorerのBlock情報を見ると、Block HASHとPrePathがあります。
Block HASHは自ブロックのハッシュ値、PreHashは直前のブロックのハッシュ値のようです。

Block Numberが4、3、2と遷移していますが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/ab276f07-d204-38a2-30af-9f7dd0503d53.png)

Block Number 4のPrehashはBlock Number 3のBlock HASHで、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/83d53f5f-1363-b57d-3fbf-a4704bb6b1de.png)

Block Number 3のPrehashはBlock Number 2のBlock HASHであることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/a02a7602-37d0-94a1-8c38-3f2c9241e3e4.png)

### 最新ブロックの情報の取得

以下のRestAPIを実行することで現在のBlockChainの情報を取得することが出来ました。

```
echo "GET Block Chain info"
echo
BLOCK_INFO=$(curl -s -X GET \
  "http://localhost:4000/channels/mychannel" \
  -H "authorization: Bearer $ORG1_TOKEN" \
  -H "content-type: application/json")
echo $BLOCK_INFO
# Assign previous block hash to HASH
HASH=$(echo $BLOCK_INFO | jq -r ".header.previous_hash")
echo
```

実行結果

```
GET Block Chain info

{"height":{"low":11,"high":0,"unsigned":true},"currentBlockHash":{"buffer":{"type":"Buffer","data":[8,11,18,32,162,7,143,12,3,85,68,129,30,5,53,185,172,4,197,20,146,197,59,254,87,141,161,43,75,54,242,91,238,250,142,123,26,32,29,205,171,157,11,144,92,183,8,103,62,167,33,72,58,112,238,162,177,169,159,151,151,162,240,162,171,77,100,190,191,22]},"offset":4,"markedOffset":-1,"limit":36,"littleEndian":true,"noAssert":false},"previousBlockHash":{"buffer":{"type":"Buffer","data":[8,11,18,32,162,7,143,12,3,85,68,129,30,5,53,185,172,4,197,20,146,197,59,254,87,141,161,43,75,54,242,91,238,250,142,123,26,32,29,205,171,157,11,144,92,183,8,103,62,167,33,72,58,112,238,162,177,169,159,151,151,162,240,162,171,77,100,190,191,22]},"offset":38,"markedOffset":-1,"limit":70,"littleEndian":true,"noAssert":false}}
```

上記「{"height":{"low":11」のlowが最新のBlock Numberとなるようです。


### Block情報の取得

「GET query Block by blockNumber」の引数に最新Block Numberを指定することで最新Blockの情報を取得することができました。

```
echo "GET query Block by blockNumber"
echo
BLOCK_INFO=$(curl -s -X GET \
  "http://localhost:4000/channels/mychannel/blocks/2?peer=peer0.org1.example.com" \
  -H "authorization: Bearer $ORG1_TOKEN" \
  -H "content-type: application/json")
echo $BLOCK_INFO
# Assign previous block hash to HASH
HASH=$(echo $BLOCK_INFO | jq -r ".header.previous_hash")
echo
```

### トランザクション情報の取得

ブロック情報の取得結果に「tx_id」があります。

```
"tx_id":"fa16c35e58d7249eaadf786ab0b750ad4e26c3597882e014095ebb5af721a3d0"
```

これがトランザクションIDになるようです。
このトランザクションIDを使用してどのような結果となったのかを逆引きすることができました。

```
TRX_ID="fa16c35e58d7249eaadf786ab0b750ad4e26c3597882e014095ebb5af721a3d0"
echo "GET query Transaction by TransactionID"
echo
curl -s -X GET http://localhost:4000/channels/mychannel/transactions/$TRX_ID?peer=peer0.org1.example.com \
  -H "authorization: Bearer $ORG1_TOKEN" \
  -H "content-type: application/json"
echo
echo
```

実行結果

```
"writes":[{"key":"a","is_delete":false,"value":"30"},{"key":"b","is_delete":false,"value":"270"}]
```

これを繰り返すことで過去履歴を取得することができるでしょう。

## 検証履歴

[Hyperledger Fabric v1.0.1 のセットアップとサンプルの実行](https://qiita.com/comeonyama/items/add6a9c77193740ab65d)
[サンプル２: Balance transfer](https://qiita.com/comeonyama/items/add6a9c77193740ab65d#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%EF%BC%92-balance-transfer)

testAPIs.shを実行すると、解説通り「GET query Block by blockNumber」の結果に

```  
「"writes":[{"key":"a","is_delete":false,"value":"90"},{"key":"b","is_delete":false,"value":"210"}]」
```
という出力がありました。
これはまさにHyperledger Fabric Explorerから確認できたこの値と思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589067/6dfbe8b7-1a57-402d-31aa-38f05092dfd4.png)

## 終わりに

今回はHyperledger Explorerの画面で確認できていたことが裏ではどういう形で情報を取得しているのか、自分でもできるのかを確認することが出来ました。
この検証を活かせば、過去にどのような更新が行われたのかを遡って参照することができそうです。