まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:blockchain

BMXUG(IBM Cloud ユーザー会)の勉強会がきっかけで知り合いになる機会のあった MonAmie さんが今月出版した SF 小説、「H -アッシュ- 仮想通貨BLOODとAIになった歌姫」を読了しました:



近未来である西暦 2025 年、ブロックチェーンと AI の技術が普及した東京を舞台としています。この作品最大の特徴の1つ(と思っている)血液と交換可能な仮想通貨 "BLOOD" を巡るストーリーです。ここでは世の中のいたるところに AI が活用されていて、またそのセキュリティシステムにも話が及び、ひとりの IT エンジニアとして読んでいても興味深い内容でした。

感想として、まず何よりもこれを伝えたいのですが、血液という(現代の日本では法律でお金との交換が禁じられているものの)非常に高価なアイテムを電子的に取引する、というブロックチェーンのユースケースが非常にユニークであり、かつ技術的には実現が不可能と思えるほどでもなく、いろいろな意味で興味深い仕組みが描かれていました。「そうか、血液が扱えるなら○○だって・・・」とブロックチェーンの応用アイデアを刺激される内容でした。

次にこの小説の中では「ブロックチェーン」、「人工知能」、「セキュリティ」という IT の中でも比較的ホットな3つの分野がテーマとして描かれています。この3つの分野全てに精通したエンジニアの存在だけでも珍しいのではないかと思っていますが、(フィクションとはいえ)それらの近未来ユースケースと考えると IT の読み物としても先進的で面白いと感じる人が多くいるのではないかと思いました。

また西暦 2025 年の東京という舞台から見た、現在である西暦 2018 年がブロックチェーンや仮想通貨の黎明期として描かれていて(どこかで聞いたような流出事件が過去事例になっていたりして)、タイムリーな話題が物語の中で自然に取り込まれて紹介されていました。この点も面白く読み進められた理由だったと感じています。気の早い話かもしれませんが、次回作を読んでみたいと思いました。


ブロックチェーンに携わる機会のあるエンジニアや、ブロックチェーンで新しいビジネスを興そうと考えている人にとっては興味深い近未来のユースケースとしても是非読んでいただきたいと感じた一冊でした。


僕自身はオープンソース製品である Hyperledger FabricHyperledger Composer を使ったブロックチェーンプラットフォームや、その対応アプリケーションを業務で開発する機会が多くあります。

ありがたいことに実際に作る機会も多いのですが、「作る」という決断に到達する前に方針を変更することも少なくありません。よくある理由としては「(現行の)ブロックチェーンに向かない要件」であるというケースです。パフォーマンス要件だったり、検索機能の要件だったり、現在のブロックチェーンでは本格運用に向かないケースが前提になっていたりすると、そのことを伝えた上で「それでも作るかどうか」を判断していただいています。そして「作らずに検討し直す」と判断されることもある、という意味です。

でも、これはブロックチェーンを使いたいと思いながらも「現在のブロックチェーン技術」では向かない、と判断されたからです。需要としては存在していることも意味しています。

そんな場面を多く見ている中で「だったらブロックチェーンといえるかどうかはともかく、同じような仕組みで耐改竄性を高めながら、この要件も満たせるようなデータストアの仕組みを作れないか?」と考えるようになりました。それが今回紹介するものです。


【「ブロックチェーン」の定義】
まず最初に、以下で紹介するアプリケーションは「ブロックチェーン」と呼べるものかどうかと言われると、私個人的には「呼べないのではないか」と考えています。これは「ブロックチェーンの定義」をどのようにするか、という問題にも関わってくるのですが、ここでは1つの目安として、JBA("Japan Blockchain Association" 日本ブロックチェーン協会)が定義した以下の2つの定義を満たすものをブロックチェーンと定義するものとします:

・ビザンチン障害を含む不特定多数のノードを用い、時間の経過とともにその時点の合意が覆る確率が0へ収束するプロトコル、またはその実装をブロックチェーンと呼ぶ。
・電子署名とハッシュポインタを使用し改竄検出が容易なデータ構造を持ち、且つ、当該データをネットワーク上に分散する多数のノードに保持させることで、高可用性及びデータ同一性等を実現する技術を広義のブロックチェーンと呼ぶ。

(参照)
http://jba-web.jp/archives/2011003blockchain_definition

2018062901



要するに「ブロックチェーンとは『ブロック』が『チェーン』のようにつながって格納される仕組み」というゆるい定義ではなく(注 私個人的にはこれがブロックチェーンの定義でもいいと思ってます)、「ハッシュポインタを用いて接続し、データを複数のノード上に分散して保持し、かつその複数ノードが耐ビザンチン障害性を持っている実装」のことを「ブロックチェーン」と定義する、ということです。 そしてこの定義の上で考えた場合、以下で紹介するものはブロックチェーンではない、ということになることを予め伝えておきます。

自分の考えは、上記のものだと耐ビザンチン障害性をもたせるためのコンセンサスアルゴリズムに問題が発生したり(最近だと「51%攻撃」と呼ばれる手法が話題になりました)、そのためにトランザクションのパフォーマンスを高く実現するのが難しかったりする、と思っています。なのでこの要件が必須でないケースでは、この条件を確保しないことでパフォーマンスや検索機能など他の要件機能を向上させることができるのではないかと考えました。


【色々出てきている】
現状のブロックチェーンにはパフォーマンス遅延や電力消費など当初は想定していなかったことが問題になっていることもあって、それらの苦手部分に対処した新しい仕組みも生まれています(それらが上記ブロックチェーンの定義を満たしているかどうかはともかく)。例えば全参加者のコンセンサスを得る上でのパフォーマンス遅延を解決するために、ランダムに選ばれた一部参加者のコンセンサスを得るように改良したものも出ているようです:
ブロックチェーンを超える?ハッシュグラフ(Hashgraph)とは?


【作ってみようと思ったもの】
今回、自分は以下4つの特徴を持つようなデータストアシステムを新たに開発してみようと思いました:
(1)ハッシュポインタを利用した、改竄検出が容易なブロックチェーンの仕組みはそのまま取り入れる
(2)データは中央集権管理型とする。これによりコンセンサスアルゴリズムや耐ビザンチン障害性の問題を発生させなくした上で、トランザクションパフォーマンスの向上を実現する
(3)データそのものは分散データストアに格納して(格納可能にして)高可用性を実現する。つまり単なる1ピア運用とは異なる
(4)バイナリデータやファイル添付を含む大きなレコードのデータストアへの格納や全文検索機能、データを読み書きするための REST API を標準装備する



(2)の時点で上記ブロックチェーンの定義を満たさなくなっています(ブロックチェーンは非中央管集権管理型)。(3)ただ単に1ピアにデータを格納するのではなく、論理的な1データストアが実際には複数のロケーションに分散できるようにしており、これにより特定ロケーションが単一障害点とはならないようにします。そして(4)ブロックチェーンが比較的苦手とする巨大オブジェクトの格納や検索機能もこのシステムでは標準装備することを目標としています。加えて標準で REST API を準備することで(導入すればすぐ使えるようになって)導入時の負担軽減も実現するつもりです。

2018062902



【作っているもの】
上記仕組みを実現するためのソフトウェア(というかプラットフォームというか、API 群というか・・)を開発中です。まだ開発中ですが Github にて MIT ライセンスで公開しています:
https://github.com/dotnsf/hashchainsolo


上記の事情もあり、開発コード名には「ブロックチェーン」は含めず「ハッシュチェーンソロ」という表現にしました。レコードのブロックをチェーンのようにつなげていくものではあるのですが、上述の定義を満たすようなものではなく(むしろそこを犠牲にしている)、自分も「ブロックチェーン」という表現にこだわるわけではないので「ハッシュチェーン」という表現にしたかったのですが、これはこれで別の意味に使われており、ややこしいことになりそうだったので(ブロックチェーンだと単一ピアに相当する設計になるという意味で)「ハッシュチェーンソロ」と命名しています。某○icrosoft Office 365 Solo の影響とかではありませんw

インフラとして、分散データストアには IBM Cloudant を採用しています。Apache CouchDB をベースとした NoSQL 型のマネージド DBaaS で、容量・トランザクションパフォーマンスに制約があるものの無料プランを選択することもできるので、「とりあえず動作確認してみる」ためのハードルは低く実現できると思っています。一方でプランを見直して容量やパフォーマンスを変えたり、要件によってはプライベートクラウド版やオンプレミスソフトウェア版を使うことも可能です。またこの Cloudant 自体がバイナリ(添付ファイル)格納や検索インデックスといった機能を内包しているので、ブロックチェーンでいうところの「ステート DB」に相当する仕組みや外部ファイルシステム等がなくても各種データを格納することができ、上述の4つの特徴を兼ね備えた単独の仕組みを比較的作りやすいと思っています。

#現時点では実装していない余談ですが、IBM Cloudant をデータストアに使っていることで、携帯版の PouchDB と組み合わせてモバイルプラットフォームへの移植も想定しやすい設計にしています。

ハッシュポインタを使って耐改ざん性を高める部分は全てスクラッチで実装しています。タイムスタンプと nonce を併用してマイニングを行い、特定条件(変更可)を満たした時だけハッシュを採用できるようにしています。

2018/Jun/30 の現時点での開発状況は「とりあえず一通りの REST API は動くようになっている」レベルです。時間を見つけてぼちぼちと改良中です。


【Call for Code】
この製品で Call for Code に参加予定です。自然災害の支援を目的としたソリューションのコンテストで、ブロックチェーンを使う事例は多く存在すると思いますが、そのブロックチェーン技術の選択肢の1つとして、既存技術では難しいものも場合によっては解決できる、と思っていて、その実装として提供・参加予定です。




 

オープンソースのブロックチェーン環境である Hyperledger Fabric と、その開発ツールである Composer の環境を手元のマシンに導入する手順を紹介します。基本手順は以前に IDCF テックブログに寄稿させていただいた内容と同じですが、各モジュールのバージョンや導入直後のカード作成の部分が異なっているので、補足する形で紹介します。

前提条件

まず、以下の説明では前提プラットフォームとして Ubuntu 16.04 を使います。ここに Docker, Docker-Compose, Node.js V6.x を導入してから Hyperledger Fabric をインストールしていくのですが、この3つ(Docker, Docker-Compose, Node.js V6.x)が導入されていれば macOS でも可能です(macOS でのこれら3つの導入手順は省略させてください、普通にググれば見つかると思うので・・・)。以下はこれら3つが導入されている前提で、それ以降の手順を紹介します(Ubuntu でも macOS でも手順は同じです)。

というわけで、この時点では以下の3つのモジュールが導入されているものとします(バージョンは 2018/02 時点で手順に沿って実施した場合に入るバージョンでした):
 - Docker 17.12.0-ce
 - Docker-Compose 1.12.0
 - Node.js v6.12.3

ここまでの導入手順については、こちらを参照ください:
Hyperledger Fabric でブロックチェーン環境を構築


Hyperledger Composer コマンドラインインターフェース

前提環境を整える時に導入されている npm コマンドを使って、Hyperledger Composer のコマンドラインインターフェース(composer-cli)をインストールします:
$ sudo npm install -g composer-cli

(↓2018/03/27 追記)
以下の PeerAdmin@hlfv1 カードを作成する際の仕様が変わったため、ここでは composer-cli のバージョン v0.16.3 を指定してインストールする必要があります。したがって以下のコマンドを実行してください:
$ sudo npm install -g composer-cli@0.16.3
(↑2018/03/27 追記)


導入に成功すると composer コマンドが使えるようになります。2018/02 時点でのバージョンは 0.16.3 でした:
$ composer
v0.16.3

Hyperledger Fabric 開発環境サポートツール

「サポートツール」と呼ばれるファイル群を使って、開発環境として使える Hyperledger Fabric を導入します。一般的にブロックチェーンでは「分散台帳」と呼ばれる方式でデータを複数のノードに分散して共有する仕組みを取りますが、開発環境では1ノードのみ使います。

まず、この時点で docker サービスが有効になっている必要があります。docker サービスが停止している場合は、このタイミングで起動しておきます:
$ sudo service docker start

改めてサポートツールを使って Hyperledger Fabric 環境を導入します。以下の例では ~/fabric というフォルダを作って、その下にサポートツールを導入しています:
$ cd
$ mkdir fabric  (ホームディレクトリ配下の ~/fabric/ にサポートツールを導入する場合)
$ cd fabric
$ curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.zip
$ unzip fabric-dev-servers.zip

「サポートツールの導入」といっても実質「zip ファイルの展開」です。展開ファイルを確認します:
$ ls
_loader.sh                downloadFabric.sh       startFabric.sh
composer-logs             fabric-dev-servers.zip  stopFabric.sh
createComposerProfile.sh  fabric-scripts          teardownAllDocker.sh
createPeerAdminCard.sh    package.json            teardownFabric.sh

2018/02 版では以前に紹介した時よりもファイルが増えています。これは Hyperledger Composer の仕様変更に伴うもので、以前にはなかった createPeerAdminCard.sh などは環境準備後に使うことになります。

では展開したサポートツールを使って Hyperledger Fabric 環境を構築します。といってもコマンドはこれひとつです:
$ ./downloadFabric.sh

このコマンドの中で必要とされる docker イメージのダウンロード等が行われ、Hyperledger Fabric 環境がローカルマシン内に構築されます。

コマンドが終了したら、いったんこの時点で docker コンテナのプロセスを確認します。他の用途で docker を使っていたりしない限り、この時点では docker コンテナのプロセスは1つも動いていないはずです:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Hyperledger Fabric 環境の起動

ではローカルマシンに導入した Hyperledger Fabric 環境を起動します。これもコマンド1つです:
$ ./startFabric.sh

このコマンドが完了すると Hyperledger Fabric が起動したことになります。改めて docker コンテナのプロセスを確認すると、先程まで空だったコンテナプロセスがいくつか動いていることが確認できるはずです:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             
6eb73fa9bc26        dev-peer0.org....   "chaincode -peer.a..."   
3ce2ff860034        hyperledger/f....   "peer node start -..."
e99420efba7f        hyperledger/f....   "orderer"
0dc1e0deaa92        hyperledger/f....   "sh -c 'fabric-ca-..."
c6bc1fe8a3f8        hyperledger/f....   "tini -- /docker-e..."

なお、起動中の Hyperledger Fabric を停止する場合は ./stopFabric.sh を実行します(以下の作業を続けるのであれば、しなくてもいいです):
$ ./stopFabric.sh


カードファイルの作成

ここからは以前の情報にはなかった、新しい仕様に関わる新しい箇所です。2018/02 時点では Hyperledger Fabric に接続する際に「カードファイル」と呼ばれる仕組みを使ってアクセスを行う必要があります(以前は「プロファイル」と呼ばれる仕組みを使った方法が用いられていました)。

作成&起動した Hyperledger Fabric 環境についてもカードファイルを使わないとアクセスしたり、操作することができません。まずはローカル環境(hlfv1)のデフォルト管理者となる PeerAdmin 用のカードファイルを作成します。サポートツールに含まれる以下のスクリプトを実行します:
$ ./createPeerAdminCard.sh

色々動いて、最後に "Command succeeded" と表示されれば成功で、/tmp/PeerAdmin@hlfv1.card というファイルが作られているので、このファイルを手元に(例えばホームディレクトリに)保存しておきます:
$ cp /tmp/PeerAdmin@hlfv1.card .

同時に、この時点で PeerAdmin@hlfv1 カードは有効に登録されています。登録済みのカードを一覧表示するには以下のコマンドを実行します:
$ composer card list

The following Business Network Cards are available:

Connection Profile: hlfv1
+--------------------+-----------+------------------+
| Card Name          | UserId    | Business Network |
+--------------------+-----------+------------------+
| PeerAdmin@hlfv1    | PeerAdmin |                  |
+--------------------+-----------+------------------+


Issue composer card list --name  to get details a specific card

Command succeeded


 ↑PeerAdmin@hlfv1 が確認できました。




・・・というわけで、2018/02 時点での仕様に合わせた Hyperledger Fabric & Composer 環境の構築手順と、カードファイルの準備手順までを紹介しました。ここまでできていると、composer コマンドとカードファイルを使ってビジネスネットワークを定義したり、起動したり、、、といったことができるようになります。そのための準備作業という意味合いでの紹介でした。


もう少しわかりやすく手を加えた上で、いずれちゃんと紹介する機会(BMXUG勉強会?)を作るつもりですが、オープンソースのブロックチェーン環境であるHyperledger Fabric を使ってユーザーと資産の管理、そして資産の譲渡といった最低限の機能を持ったアセット管理プラットフォームを作って、MIT ライセンスで公開しました。

「資産」=「仮想通貨」とみなせばいろいろ話題の仮想通貨プラットフォーム(の基礎)にもなると思います。仮想通貨でなく、普通の資産の管理や譲渡にも使えると思ってます(むしろそっちをイメージして作ってます)。またそこでの作成や譲渡といったトランザクションはブロックチェーン上に記録されるので改竄時のトラッキング機能を内包していることになります。

現時点では Hyperledger Fabric 環境が用意されていることが必須の上、管理プラットフォームとしてのUI未作成で、REST API のみ実装しているだけです。なので「使える人は使える」レベルのものだと思っています(改良予定あり)。 その代わり MIT ライセンスなのでかなり自由度高く改変・改良・再利用することを認めています。今のままでもブロックチェーン環境のデモ程度には使えると思ってます。


そんな、まだまだ普通に使えるレベルのものではないことは理解した上で、僕自身はこのタイミングあたりからフィードバックももらえたらいいなとか、共同開発に興味ある人がいたら・・・という目的もあって公開することにしました。コードはこちら:


導入方法などは README.md を参照・・・していただきたいのですが、Hyperledger Fabric 環境の用意を前提としているなど、まだ現時点ではハードル高いと思ってます。いずれ PaaS や SaaS でもっと気軽に使えるようになることを期待していますが。。


ちなみに、上記のコードはこの週末に GPD Pocket (Ubuntu 版)に Hyperledger Fabric と、Hyperledger Composer を導入したことでスタンドアロンなブロックチェーンアプリケーション開発環境ができ、嬉しくなって地元の津田沼を散歩しながら持ち歩いて、その休憩時に取り出して作りました。なので開発期間は実質週末の2日くらい。それほど凝ったものは作れておらず、ユーザーや資産の作成、ログイン、資産譲渡、といった API が用意されている程度です:
20180203
(↑開発中の様子)


逆に現時点ではまだ検索用の機能がほぼ手付かずだったり、管理用の UI すらなく、唯一 Swagger スタイルのインタラクティブな API Document が用意されている程度です。なのでまだ低レベルな部分もこれから作っていく必要があるもので、その点でも(良くも悪くも)プラットフォームとしての実装段階です。 そんなことを理解した上で「開発に関わってみたいなあ」とか「Hyperledger Fabric の勉強も兼ねて実装してみたいなあ」とか「ぶっちゃけブロックチェーン分からないけど、UI/UXだけでも関わりたいなあ」とか思っている人がいたら心強いっす。もちろん MIT ライセンスで公開している以上、「勝手に使わせてもらって改良する」でも全然オッケーです。個人的には Hyperledger Fabric が広まってほしいなあ、という思いを優先してます。


最近、業務でブロックチェーンを使う機会が増えてきました。というか、提案段階のものも含めて大半の案件にキーワードとして出て来るようになっています(イノベーティブなアプリケーション開発に関わる部門に所属していることも関係しているとは思います)。ブロックチェーンを API 経由で使うだけでなく、その API を作ったり、データのモデリングをしたりする機会も出てきました。

まだまだ勉強段階ではありますが、実際にお客様と会話している中でも作る前から「これはブロックチェーンに向いてるなあ/向かないなあ・・・」と感じることができるようになってきました。今日のエントリはそういう話です。

ブロックチェーンは革新的な技術で注目されている一方で、まだわかりにくい部分もあり、誤解を受けている部分もあります。典型的なパターンが「現在動いている○○システムのデータベース部分をブロックチェーンに置き換えて信頼性を向上させる」というものです。まさにブロックチェーンの強みをいかしたシステム改変のようにも聞こえますが、実現に向けては落とし穴も見受けられます。


ブロックチェーンは「分散台帳」と呼ばれる改竄の難しい仕組みでデータを格納します。その意味ではブロックチェーンはデータベースであるとみなすことはできますし、その中に格納されている情報の信頼性は非常に高いと言えます。ここがブロックチェーンの従来のデータベースに対する強みであり、こういった目的で使うにはブロックチェーンは向いていると考えます。

ただ一方で、従来のデータベース(ここではリレーショナルデータベースとしましょう)にもブロックチェーンと比較した時のメリットや得意分野があります。例えば SQL のような標準化されたクエリー言語による検索はリレーショナルデータベースの特徴であり、ブロックチェーンがこの機能を持っているわけではありません(例えばブロックチェーンの実装の1つである Hyperledger Fabric の場合、SQL ライクなクエリーを定義することはできますが、SQL とは異なるものです)。またトランザクション処理のパフォーマンスはまだまだリレーショナルデータベースの方が上と言わざるを得ません。そのような状況であるにも関わらず、興味以上の理由で「今使っているシステムのデータベースをブロックチェーンに単純に置き換える」ことは必ずしも正しくならない可能性があります。


・・・と、ここまでは「ブロックチェーン」を「NoSQL データベース」に置き換えても同じ話なので、NoSQL データベースが出現した頃にも同様の議論があり、特別目新しいことではないかもしれません。ただブロックチェーンの場合はブロックチェーン特有の事情を考慮する必要もあります。

リレーショナルデータベースと NoSQL データベース(やらメモリキャッシュやら検索エンジンやら・・)を比較する場合は、それぞれのデータベースの得意・不得意を見極めた上で適材適所に配置することが理想回答になると思います。例えば商品のコマースサイトであればこんな感じでしょうか?
2017083101

↑商品マスターと、その商品を分類するためのカテゴリーマスターが存在しているものとします。商品マスターと比べてカテゴリーマスターの情報は変更頻度が少ないため、アプリケーション実行時にメモリキャッシュに一括してロードし、実行時は高速なメモリアクセスだけで参照できるような設計にします。また商品情報は柔軟かつ高速な検索ができるよう、検索サーバーを用意します(定期的に情報を更新します)。またこのアプリケーションを使って発生した取引の情報も管理するものとします。

このシステムを一般的なデータベースを使って作る場合は↓このようになります。マスターをデータベースで持ち、商品情報の一部は検索サーバーに同期します。また取引が発生した際のログもデータベースに保存します。比較的一般的で、特別に珍しい点はないと思っています:
2017083102


さて、上記の構成を持ったシステムが現在動いているものとします。この現状のシステムに対して、例えば「商品情報や取引記録の正当性を保証する目的でブロックチェーン対応する」ことを考えてみます。上述のようにブロックチェーンには向き・不向きがあるのですが、例えば現状データベースで管理している「商品情報をブロックチェーン化する」ケースを考えてみます:
2017083103


↑単純に考えるとこんな感じです。データベースで管理していた商品マスターの情報をブロックチェーンに格納するというケースです。もちろんアプリケーションの書き換えは必要ですが、システム構成自体には問題なさそうに見え、商品マスターの情報がよりセキュアに守られるように見えます。

しかし実は問題点をはらんでいます。上述のように、今回のシステムでは商品情報は検索目的で検索サーバーと同期しています。端的にいうと「商品情報は2重管理されている」想定になります。商品マスターをブロックチェーン化して改竄を困難にしたつもりが、検索サーバーが管理している商品情報については何の対策もしていないことになるので、ブロックチェーンで管理しているケースと比較すると、検索サーバー側に弱点(というか盲点)が存在していることになってしまいます:
2017090100


一方でこのシステムを使って生成される取引情報をブロックチェーン管理にする、という部分はこの取引情報の改竄は非常に困難になるため、上述のような情報の正当性を保証する目的においては(トランザクション量などの考慮を除けば)「ブロックチェーン向き」と言える改良といえます:
2017083104


ただこれについても上述のように情報のクエリーなどデータベースが得意とする機能が重要視されるケースもあるでしょう。したがってブロックチェーンがフィットするかどうかという意味では単純にデータベースをブロックチェーンに置き換える、という考え方は危険で、「何を目的として、何をブロックチェーンで管理するのか」、「データベースの方が適している要素を無視していないか」という観点でシステムを設計する必要があります。


このページのトップヘ