[Blockchain]Hyperledger Fabricを試す(fabcar検証編)

## 目的

byfnで動作検証ができたHyperledger Fabric。
次はメインのfabcarの検証を行います。

## 参考

## 注意

サーバを再起動後、fabcarを起動するとエラーが発生します。
[こちらの記事にあるように](https://qiita.com/class2glass/items/0dbed30250b4cdce4ee2#%E6%B3%A8%E6%84%8F%E5%86%8D%E8%B5%B7%E5%8B%95%E5%BE%8C)、証明書の情報を書き換えて起動し直す必要がありました。

## 起動

・起動スクリプトを実行

```
$ cd ~/fabric-samples/fabcar
$ ./startFabric.sh javascript
```

・起動状態を確認

```
$ docker ps --format "{{.Names}}"
dev-peer0.org2.example.com-fabcar-1.0
dev-peer0.org1.example.com-fabcar-1.0
cli
peer0.org2.example.com
peer1.org2.example.com
peer1.org1.example.com
peer0.org1.example.com
couchdb3
ca_peerOrg1
couchdb2
orderer.example.com
couchdb1
couchdb0
ca_peerOrg2
```

・必須パッケージのインストールとアカウントの登録

```
$ cd javascript
$ npm install
$ node enrollAdmin.js
$ node registerUser.js
```

## 動作確認

サンプルとして用意されている、登録されている情報全件取得するスクリプトを実行してみます。

```
$ node query.js
Wallet path: /home/comjo/fabric-samples/fabcar/javascript/wallet
Transaction has been evaluated, result is: [{"Key":"CAR0","Record":{"color":"blue","docType":"car","make":"Toyota","model":"Prius","owner":"Tomoko"}},{"Key":"CAR1","Record":{"color":"red","docType":"car","make":"Ford","model":"Mustang","owner":"Brad"}},{"Key":"CAR2","Record":{"color":"green","docType":"car","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"color":"yellow","docType":"car","make":"Volkswagen","model":"Passat","owner":"Max"}},{"Key":"CAR4","Record":{"color":"black","docType":"car","make":"Tesla","model":"S","owner":"Adriana"}},{"Key":"CAR5","Record":{"color":"purple","docType":"car","make":"Peugeot","model":"205","owner":"Michel"}},{"Key":"CAR6","Record":{"color":"white","docType":"car","make":"Chery","model":"S22L","owner":"Aarav"}},{"Key":"CAR7","Record":{"color":"violet","docType":"car","make":"Fiat","model":"Punto","owner":"Pari"}},{"Key":"CAR8","Record":{"color":"indigo","docType":"car","make":"Tata","model":"Nano","owner":"Valeria"}},{"Key":"CAR9","Record":{"color":"brown","docType":"car","make":"Holden","model":"Barina","owner":"Shotaro"}}]
```

この他にも、invoke.jsを実行すると、「car10」というデータの追加を行えました。
素晴らしいサンプルコードです。

## チェインコード

query.js、invoke.jsを見て分かりましたが、「fabric-samples/chaincode/fabcar/javascript/lib/fabcar.js」がこのfabcarで使用されているチェインコードのようです。

「initLedger」は初期データ登録用の処理のようです。
fabcarの起動スクリプト、「startFabric.sh」から呼ばれていました。

```
-c '{"function":"initLedger","Args":[]}' \
```

「queryAllCars」はquery.jsから呼ばれていました。

```
const result = await contract.evaluateTransaction('queryAllCars');
```

「createCar」はinvoke.jsから呼ばれていました。

```
await contract.submitTransaction('createCar', 'CAR10', 'Honda', 'Accord', 'Black', 'Tom');
```

このチェインコードを見ると、全件検索、データ追加の他にも特定のデータの検索やデータの修正もできそうだということが分かりました。

## ちょっと改修

チェインコードを見てできそうなことがわかってきたのでちょっとだけ改修してみます。

### 特定のデータを検索

全件検索の「query.js」を引用し、特定のデータを検索する「findcard.js」を作成してみました。
改修といっても大した内容じゃありません。
以下の修正で完成です。

```
# 既存の全件検索の行をコメント
// queryAllCars transaction - requires no arguments, ex: ('queryAllCars')

# 特定データの検索を行う「queryCar」のチェインコードを呼び出すよう改修
const result = await contract.evaluateTransaction('queryCar', 'CARD11');
```

これを実行すると、指定した「CARD11」のデータのみを抽出し出力されます。

### 特定のデータの更新

チェインコードには「changeCarOwner」という処理がありました。
見ると、検索して、ownerというエンティティの値を更新しているようです。

```
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
if (!carAsBytes || carAsBytes.length === 0) {
    throw new Error(`${carNumber} does not exist`);
}
const car = JSON.parse(carAsBytes.toString());
car.owner = newOwner;
```

invoke.jsを引用して、以下のようにチェインコードを呼び出せば、指定したデータ「CARD11」のownerが変更されました。

```
await contract.submitTransaction('changeCarOwner', 'CARD11', 'TARO');
```

## 終わりに

BlockChainでもコインのような「価値」をやり取りするのではなく、データベースのような情報を管理し、検索や更新が行えることが分かりました。
これを応用すれば本来の目的である要員管理もできそうだと分かりました。

ですが、GUIがありません。
Hyperledger Explorerは利用できますが、更新履歴などを遡って確認するには少々使いづらいです。

であれば、専用のGUIを開発すればよいのですが、今のチェインコードの検索では全件、もしくは特定のデータの最新の情報しか取得できません。

要員管理の要件には「更新履歴を確認できること」という条件がありました。
今のままではこの要件を満たすことができそうにありません。

この課題もなんとか考えなければならないのですが、その前に残りの「balance-transfer」を試してみます。