便座の使用状況をブロックチェーン（Hyperledger Fabric）で管理する

株式会社　日立製作所　福中勝博

# はじめに
ブロックチェーンは2008年頃から始まったビットコインが起源であり、現状では仮想通貨・暗号通貨以外に広く実用化されたシステムはほとんどありませんが、様々な業務に適用可能な汎用的な技術として期待され、世界中で研究開発や実証実験が行われています。

その中で、エンタープライズ向けのブロックチェーン基盤OSSの1つであるHyperledger Fabricは2016年に開発が始まり、2017年7月にはアーキテクチャが刷新されたv1.0がリリースされました。

このHyperledger Fabricを使ったアプリを設計・開発してみたい！ということで、「便座の使用状況をブロックチェーンで管理するシステム」を作ってみることにしました。
今回はその時（2017年秋頃、Hyperledger Fabric v1.0を使用）のお話です。

# 開発の経緯
日立では以前から横浜事業所で「[快適エコオフィス](http://www.hitachi.co.jp/products/it/lumada/usecase/case/lumada_uc_00009.html)」という活動に取り組んでいます。
この活動の中で「最寄りのトイレの便座が全て使用中で困った経験がある」という従業員が多かったことから、トイレにセンサーを設置して使用状況を可視化するシステムを開発して快適なオフィス環境作りに貢献し、さらに「みんなのラズパイコンテスト2015」の優秀賞も頂きました。
https://tech.nikkeibp.co.jp/it/atcl/column/16/060700122/062000022/

一方、ブロックチェーンの代表的なユースケースとしてIoT連携というキーワードがありますが、いきなりセンサー部分から作るのは非常にハードルが高いので、この過去のシステムのセンサーからのデータを流用できないか？と考えました。
ただ、センサーが設置されているのは日立の自社ビル内のトイレであり、そのような環境ではブロックチェーンを使う意味がほとんどないのですが、複数企業が使用するオフィスビルでトイレを共有するシステムと仮定すれば、ブロックチェーンを使う意味があるだろうと考えました。また、トレーサビリティという特性から、使用時間や使用回数も可視化して、異常検知や清掃効率化なども想定できます。
このような流れで、開発するアプリの概要が決定しました。

# ユースケース
様々なパターンがあると思いますが、今回はできるだけシンプルに以下の２つとしました。

- 更新：センサーデータから便座の使用状況を取得してブロックチェーンに格納する。
- 参照：便座の使用状況をブロックチェーンから取得して画面に出力する。

なお、センサーには超音波距離センサーを使用しており、定期的に現在の距離の情報を取得して送信します。
センサーに関する詳しい説明は、今回は割愛させて頂きます。

# 開発範囲
いきなりゼロから全てを構築するのはハードルが高いので、コミュニティから提供されているサンプルのBalance-Transferを活用することにしました。
このサンプル自体の詳細は下記のドキュメントをご参照ください。
https://github.com/hyperledger/fabric-samples/blob/v1.0.2/balance-transfer/README.md

今回は最小限のサンプル改変で済むように、下記のルールでアプリ開発を行いました。

1. Dockerコンテナ（CA・Orderer・Peer）：そのまま
2. スマートコントラクト（Chaincode）：自身で開発したプログラムに変更
3. クライアントアプリ（SDK）：必要に応じて最低限を変更

# Chaincodeの設計・開発
Chaincodeは、ブロックチェーンに格納されたデータの入出力を担います。
Hyperledger FabricはKey-Value型のデータストア（KVS）を採用しているので、SQLのように複雑な検索はできません。
（ドキュメント型DBのCouchDBに差し替えればある程度リッチなクエリが可能なのですが、今回はサンプルのまま標準のKVS型のLevelDBを使用しました。）
まずはこのKVS構造に合わせて、下記のようにデータ設計を行いました。

- Key：各トイレの各便座に割り当てた固有のID
- Value：便座の使用状況（開or閉）

更新時には、入力されるセンサーデータが距離の情報なので、閾値よりも短距離の場合は開、長距離の場合は閉と判断する処理を実装する必要があります。
一方で参照時には、全てのKeyとそれに対応するValueを取得して、クライアントアプリに返却する必要があります。このような場面では、JSON形式のデータを作成することを推奨します。複数データの取り扱いが容易であることはもちろん、ドキュメント型DBのCouchDBを使用する場合にはValueをJSON形式にする必要があったり、Chaincode以外の参照APIの出力データもJSON形式であったりと、拡張時に相性が良いためです。

実装時には、ローカル環境で下記のサンプルChaincodeを書き換えました。
https://github.com/hyperledger/fabric-samples/blob/v1.0.2/balance-transfer/artifacts/src/github.com/example_cc/example_cc.go

# クライアントアプリの設計・開発
クライアントアプリは基本的にサンプルのRESTサーバをそのまま使用しますが、変更が必須な部分としては、Chaincodeの参照処理での出力がBalance-Transfer専用になっているため、以下のように前後の余分な情報を削除する必要があります。

- 改変箇所：https://github.com/hyperledger/fabric-samples/blob/v1.0.2/balance-transfer/app/query.js#L49-L50
- 前：`return args[0]+' now has ' + response_payloads[i].toString('utf8') + ' after the move';`
- 後：`return response_payloads[i].toString('utf8');`

上記の改変によって、RESTサーバからは綺麗なJSON形式のデータが返却されるようになります。
参照用の画面プログラムは定期的にRESTサーバに接続して、JSONデータを解析して各便座の使用状況を出力します。
なおこの時に、ユーザ登録時に発行されるトークン（JWT）を事前に画面プログラムに渡してあげる必要があります。
センサーデータの投入プログラムも同様です。トークンの有効期限（デフォルト10時間）に注意してください。
![benza-blockchain.png](https://qiita-image-store.s3.amazonaws.com/0/320032/ed213782-5ae0-736d-b288-14231951fd63.png)

# まとめ
ブロックチェーンはユースケースを決めることがもっとも重要、かつ、課題となります。
どのブロックチェーン基盤が良いのか？そもそもブロックチェーンが必要なのか？様々な疑問が湧いてくるかと思います。
ただ、実際にアプリを作ってみることでブロックチェーンやHyperledger Fabricに対する理解が深まります。
解決する疑問もあれば、逆に新たに湧いた疑問もあるかと思いますが、いずれにしても大きな前進ではないでしょうか。

例えば、ブロックチェーンに格納済みのデータ、今回であれば便座の使用状況を表すデータは改ざんが困難なデータなのですが、入力されるセンサーデータ自体が正しいデータかどうかは別問題であり、それはブロックチェーンの外側で解決する必要があります。
これはよく考えてみれば当たり前の話なのですが、仮想通貨では特に考慮の必要がない部分であり、実際にセンサーが故障した際のデータを可視化することで気付くことができました。

みなさんも上記の手順を参考にして、ぜひアプリを実際に作ってみてください。
きっと何か新たな気付きを得られるかと思います。
あなたのアプリは何から？私は便座から！

# 参考
ブロックチェーンの特徴やユースケース、日立の取り組みについて（日立のブロックチェーンWebサイト）
https://www.hitachi.co.jp/products/it/blockchain/index.html