Hyperledger Fabric と戯れる part.6
Commercial Paper Tutorial (つづき)
前回に続き、 Commercial Paper チュートリアルをやるにあたり Developing Applications ドキュメントを読む作業を続ける。
hyperledger-fabric.readthedocs.io
hyperledger-fabric.readthedocs.io
アプリケーション
hyperledger-fabric.readthedocs.io
前回 ChainCode 側を実装したので今回は Client 側となる。
該当ディレクトリは commercial-paper/organization/magnetocorp/application
あるいは commercial-paper/organization/digibank/application
となる。 diff -r
すればわかるが、これら2つは殆ど同じだけど色々違う。
既にクライアントアプリの書き方は Writing Your First Application チュートリアルで理解しているが、ここではその基本フローとして以下のように定義されている
- Wallet から Identity を選択
- Gateway に接続
- 目的のネットワークにアクセス
- ChainCode に対するトランザクションリクエストを作成
- ネットワークにリクエストを送信
- レスポンスを処理する
ところで、解説では papernetConnection.yaml
の中身を説明してるが、スクリプトは実際には Basic Network と同等の構成の networkConnection.yaml
を使用している。じゃあ papernetConnection.yaml
は何なのって話だが、どこにも使われてないっぽい。説明中や papernetConnection.yaml
にある設定内容はネットワーク構成等をながめても何処にも反映されてないし、そもそも解説中の connectionProfile.yaml
というファイルも存在しない。
API
hyperledger-fabric.readthedocs.io
なにも書かれていない。何なんだ。
アプリデザイン要素(?)
hyperledger-fabric.readthedocs.io
ここにきて更にページ数が増される。正直前2ページあたりからボロボロなのでかなり流し読みである。
なおここらへんに書かれている事はサンプルリポジトリには一切含まれていない。
Commercial Paper Tutorial
ということで Developing Applications は読み終えたのでサクっとやっちゃう。
Create network
やっぱり basic-network (1 org, 1 peer, 1 orderer) をつくってる。各社ごとに org 作ってそうに見えるドキュメントだったのに非常に残念である。
Working as MagnetoCorp
途中で ./monitordocker.sh
を実行しているが、gliderlabs/logspout
というコンテナを起動しているだけの模様。 logspout
って何だよと思ったが、複数の docker log をまとめてくれるものらしい。超便利。
それ以降
あとはこれまで読んだ内容通りなかんじであった。
今日はここまで
すっごいグダグダであった。そして基本的なところはこれでもう問題なさそうなので、次回はとりあえず何か作ってみようと思う。
Hyperledger Fabric と戯れる part.5
けっこう日が空いてしまったが、その間に Blockchain Engineer Night 2019 #2 に参加するなどしてた。
IBM の人らが話してるイベントなだけあって、なかなか実りある話が聞けた。参加者の平均年齢が妙に高いのが気になったんだけど、Fabric 興味あるひとってオッサンばっかなん? 若い人らはやっぱ Ethereum とかなのかな?
Commercial Paper Tutorial
予定通り Commercial Paper チュートリアルをやる。
hyperledger-fabric.readthedocs.io
が、このチュートリアルはより実践的なものとなっており、ビジネス上の課題を解決していく目的から見て、要件の分析、設計、開発、構築までカバーされてるとかいないとかって事なので、Developing Applications ドキュメントをまず読んでから進める。
hyperledger-fabric.readthedocs.io
シナリオ
hyperledger-fabric.readthedocs.io
コマーシャルペーパー(以下CP。短期・無担保の約束手形) の発行・売買・償還を行うネットワークを構築する。
本文では各社の背景の設定まで作り込んでてなかなか面白いが、正直あんまり意味ない設定なので読み飛ばしても良い。
まとめると、本ネットワークの参加団体は 6 団体で、それぞれ以下のような感じ。 MagnetoCorp(発行) と RateM(評価) とそれ以外(売買)、で覚えておけばよい。
- MagnetoCorp
- CP の発行をする
- 発行した CP の償還をする
- RateM
- CP の売買を観察する
- CP の価値を評価する
- DigiBank
- CP の売買をする
- 購入した CP の償還をする
- BigFund
- (同上)
- BrokerHouse
- (同上)
- HedgeMatic
- (同上)
分析
hyperledger-fabric.readthedocs.io
CP を 状態 としてこんな感じで定義してる。
- CommercialPaper
- Issuer (発行者)
- Paper (CP番号)
- Issuer + Paper で pkey となるらしい
- Owner (所有者)
- CurrentState != Trading のときは Owner == Issuer となる
- IssueDate (発行日)
- Maturity (償還日)
- FaceValue (額面)
- 購入額ではなく、償還時に返却される金額
- CurrentState (現在のステータス)
- Issued (発行済) | Trading (取引中) | Redeemed (償還済)
また、「発行」「購入」「償還」の取引を トランザクション として以下のように定義している。
Issue (発行)
- Issuer (発行者)
- Paper (CP番号)
- IssueTime (発行日時)
- MaturityDate (償還日)
- FaceValue (額面)
Buy (購入)
- Issuer (発行者)
- Paper (CP番号)
- CurrentOwner (元の所有者 = 売る人)
- NewOwner (新しい所有者 = 買う人)
- PurchaseTime (購入日時)
- Price (購入額)
Redeem (償還)
- Issuer (発行者 = 償還する人)
- Paper (CP番号)
- CurrentOwner (元の所有者 = 償還される人)
- RedeemTime (償還日時)
CP は償還済なら消しちゃえばいいんじゃないの?と思ったが、償還された CP の記録は保存しないとダメって事らしい。
また、CP に償還額だけあって購入額がないのはおかしいんじゃ?とも思ったが、「購入額」は CP という 状態 に紐付く物ではなく、「購入」という トランザクションに紐付くものだという理解らしい。
さらに、なんで Buy や Redeem で Issuer や CurrentOwner を指定する必要があるのか謎に思ったが、Issuer は Paper とセットで pkey になるのでそのため。 CurrentOwner は CP の Owner と照合して合致しなければエラーとするためだけに使われている。
プロセスとデータの設計
hyperledger-fabric.readthedocs.io
上で太字にしていたように、 状態 と トランザクション は重要な概念らしい。
説明読めばなんとなくわかるんだけど、うまくまとめにくい。基本的に台帳に保存されるのはなにがしかの 状態 で、それが トランザクション に応じて変化・遷移していく、というモデルがこの技術に向いたデータ形式やその手続きということなのだろうか。
あるいはイミュータブルな トランザクション の積み重ねがミュータブルな 状態 を作る、と捉えることもできそうな気がする。
スマートコントラクト処理
hyperledger-fabric.readthedocs.io
スマートコントラクト、つまり ChainCode のコード読みとなる。
該当ディレクトリは commercial-paper/organization/magnetocorp/contract
あるいは commercial-paper/organization/digibank/contract
となる。 diff -r
すればわかるが、これら2つは全く同じ。
lib/papercontract.js
の CommercialPaperContract
を見ると、issue
、buy
、redeem
が定義されている。これらが上述した トランザクション 3種に相当する。
また、 createContext
がオーバーライドされていて、このなかで Context
を継承した CommercialPaperContext
を生成するようにされている。
CommercialPaperContext
は PaperList
をフィールドに持ち、その PaperList
は StateDB に対する CommercialPaper
の add
update
および get
を提供する。
CommercialPaper
は Key
と CurrentState
をもつ State
の子として定義され、issuer
paperNumber
issueDateTime
maturityDateTime
faceValue
owner
を持つ。(State.Key
は [issuer, paperNumer]
で定義する。) つまりこれが上述した 状態 のそれに相当する。
今回はここまで
また中途半端なところで止まっちゃったけど、GW はガッツリ遊ぶ気なのであまり更新間隔あけないほうがいいかなって思ったのでここで中断。
次回はこの続き。
Hyperledger Fabric と戯れる part.4
Writing Your First Application (つづき)
前回に続き、Writing Your First Application チュートリアルをすすめてく。
hyperledger-fabric.readthedocs.io
node query.js
前々回あたりからチラホラ query とか invoke とか普通に言ってたが、基本的に query は参照などの read only なアクセス、invoke は追加・更新などの write を伴うアクセスに使う。
(実際のところ invoke で read only な事とかも出来たりするので不正確だったりするけど、まあさておき。)
../../basic-network/connection.json
をccp
として読み込み- 前回と同じ
- 以下、
mychannel
へのアクセスをするために使用している
new FileSystemWallet()
として./wallet
を使用- 前回と同じ
- これまでの操作により、
./wallet
にはadmin
とuser1
の Identity が存在している
gateway.connect(ccp, {wallet, identity: 'user1' ...})
でuser1
としてゲートウェイに接続admin
でなくuser1
として接続する点以外は前回と同じ- これで、各ノードに対し
wallet
を使用して接続し、client
のuser1@org1.department1
として振舞える
network = await gateway.getNetwork('mychannel')
でmychannel
へのアクセスを獲得contract = network.getContract('fabcar')
で ChainCodefabcar
へのアクセスを獲得result = await contract.evaluateTransaction('queryAllCars')
で ChainCode のqueryAllCars()
をコール- Hyperledger Fabric SDK for node.js Class: Contract
- 引数を渡したいときは第二引数以降に渡す
- 結果は result に JSON として返る
- 現在保存されている全ての car 情報が返ってきている
で、肝心の ChainCode 側を見ていく。ChainCode 側のドキュメントはこちら。
lib/fabcar.js
が本体。 (index.js
もあるけど、module の export しかしてない)
class FabCar extends Contract
のように fabric-contract-api.Contract
を継承しているクラスのメソッドがそのまま SDK 側から呼べるようになっている。
メソッドは Context
クラスを第一引数に必ず取り、以降の引数(省略可能) を取れば、クライアントSDK側からデータを受けとることができる。
詳しくはこちらを参照。
なお、Context の class API にはクラス変数の説明がないが上記ドキュメントの「Structure of the Transaction Context」を読めばわかる通り、ctx.stub
で ChainCodeStub
オブジェクト、 ctx.identity
で ClientIdentity
オブジェクトをそれぞれ取得できる。
-
ClientIdentity
- Hyperledger Fabric Node.js Contract and Shim Class: ClientIdentity
- 名前の通りリクエスト元クライアントの Identity 情報。今回の場合
./wallet/user1/user1
に含まれていた証明書の内容 getAttributeValue()
は同証明書における1.2.3.4.5.6.7.8.1
の値のattrs
にあった Object に対する getter- たとえば、
getAttributevalue("hf.Affiliation")
の結果は"org1.department1"
になる
- たとえば、
-
ChainCodeStub
- Hyperledger Fabric Node.js Contract and Shim Class: ChaincodeStub
- 台帳への getter/setter や、リクエストに関する情報などが含まれる
やってることは単純にこれだけ。
FabCar.queryAllCars(ctx)
ctx.stub.getStateByRange(...)
で車データを全件取得する- データは
Buffer
なので、toString()
したりJSON.parse()
したりして JSON に変換 - 文字列に戻して
return
なお、取得したデータは startFabric.sh
で invoke
していた、initLedger()
で格納している。
せっかくなので内容を見てみるけど、queryAllCars
以上にやってる事は単純。
FabCar.initLedger(ctx)
- 初期データを定義
ctx.stub.putState(...)
で 1 つずつ保存していく
node invoke.js
query.js
と diff を取るとわかるが、違いは最後の contract.evaluateTransaction('queryAllCars')
が contract.submitTransaction('createCar', ...)
になっている事と、明示的に gateway.disconnect()
しているところのみ。
evaluateTransaction -> submitTransaction
- Hyperledger Fabric SDK for node.js Class: Contract
- 名前の通りで、
query
は「トランザクションの評価」をしていただけで、invoke
では「トランザクションの送信」をしている
FabCar.createCar()
- 引数で指定された内容で Car オブジェクトを作って、それを
ctx.stub.putState()
で保存してるだけ
- 引数で指定された内容で Car オブジェクトを作って、それを
gateway.disconnect()
の実行- コメントアウトして実行してみるとわかるけど、これをやらないと
invoke.js
は永久に終わらない。 - 不可解だが、
query
にこの行を足しても問題は起きないし、極めて一般的な感覚としてconnect
したら必ずdisconnect
するべきと思うので、そういうもんだと思っておく
- コメントアウトして実行してみるとわかるけど、これをやらないと
おしまい
話長くなるかと思ったけど、すげえ短かった。
次回は Commercial paper tutorial をやる予定。
Hyperledger Fabric と戯れる part.3
Writing Your First Application
予告通り、Writing Your First Application チュートリアルに進む。
hyperledger-fabric.readthedocs.io
startFabric.sh xxx
各ノードを構築して chaincode のインストール・インスタンス化まで実施。
xxx に javascript|typescript|go を指定することで chaincode の実装言語を選べる。デフォルトは Go だがチュートリアル的には JavaScript で説明している。 前回までの BYFN では Go をつかってたし、せっかくだから今回はチュートリアル通りに JavaScript でやってみる。好みではないんだけどね。
なお、それぞれの chaincode のソースコードは ../chaincode/fabcar
に置いてある。
javascript-low-level
というディレクトリがあるが、これは v1.4 以前のプログラムモデルによる実装。詳細は以下を参照。
hyperledger-fabric.readthedocs.io
- (TypeScriptのみ) JavaScript へのトランスパイル
- Go のコンパイルは chaincode のインストール時に行われてるように見えていたが、TypeScript のトランスパイルはこの時点で行う
- つまり、実装言語は TypeScript だとしても、実際に chaincode としてインストールされるのは(トランスパイルされた) JavaScript ということになる。
docker-compose
で必要なノードを起動する- 設定ファイルは
../basic-network/docker-compose.yml
- 前回までは
crypto-config
を生成していたが、今回は最初から出来てる../basic-network/generate.sh
で作ることもできるっぽいが、なんか微妙に違うものができる- generate 時の設定ファイル
../basic-network/crypto-configl.yaml
はorderer
およびorg1
の設定のみがある
- generate 時の設定ファイル
- 今回作成するのは以下。なお全てのノードは
basic
ネットワークに含まれる。ca.example.com
- CA サーバ。今回初出。
ca.org1
の証明書と鍵をもつ
orderer.example.com
- Orderer
orderer
の証明書と鍵をもつpeer0.org1
の証明書と鍵をもつ
peer0.org1.example.com
- peer. 今回は 1 Organization, 1 Peer 構成ということになる
peer0.org1
の証明書と鍵をもつorg1
の User1 と Admin の証明書と鍵をもつ
couchdb
- CouchDB. 台帳の最新状況を保持するためのもの。今回初出。
cli
peer0.org1
に対する操作がセットアップされている- 全
crypto-config
データを持っている
- 設定ファイルは
mychannel
チャンネルを作成- 設定は
../basic-network/channel.tx
- これまた既に作成済み。元となるものは
../basic-network/configtx.yaml
- チャンネル参加者は
orderer
およびpeer0.org1
のみ。
- チャンネル参加者は
- 設定は
mychannel
にpeer0.org1
を joinmchannel.block
も作成済み。
mychannel
に ChainCodefabcar
v1.0 をインストール- ChainCode のパスは上述の通り
mychannel
の ChainCodefabcar
v1.0 をインスタンス化mychannel
の ChainCodefabcar
に対しinitLedger()
を invoke- 動作確認がてら初期データの挿入を行っている模様
- 以下を読み進めればわかる事だが、呼ばれているのは
../fabcar/javascript/lib/fabcar.js
クライアント側セットアップ
上記で chaincode の使用準備は整ったが、このままでは peer コマンド経由で叩くくらいしか使い道がない。 したがってクライアントアプリの構築をする。
startFabric.sh
の出力を見てもわかるとおり、クライアントアプリの実装言語を選んで cd
し、ビルドコマンドを叩くだけ。
クライアントアプリは JavaScript か TypeScript が選べ、また ChainCode 同様 v1.4 以前のプログラムモデルによる javascript-low-level
もある。
ここも TypeScript はトランスパイルの 1 手間がかかるだけで大した違いはないっぽいので、素直にチュートリアルの指示通り JavaScript を選択した。
node enrollAdmin.js
クライアント用の Admin ユーザを登録。ざっくり読んでいく。
なお、Client側 (以下 SDK) API ドキュメントはコレ。
../../basic-network/connection.json
をccp
として読み込み- 当該ファイルは今回のシステムの構成情報を記述してある。
- 以下、CA の URL を得るために使用している
new FabricCAServices()
で CA に接続wallet = new FileSystemWallet()
として./wallet
を使用- 現時点では
./wallet
は空ディレクトリ - Hyperledger Fabric SDK for node.js Class: FileSystemWallet
- 現時点では
identity = await ca.enroll({ enrollmentID: 'admin' ... })
して CA にadmin
を登録。- Hyperledger Fabric SDK for node.js Class: FabricCAServices
- レスポンスには
admin
の証明書と秘密鍵、ルート証明書が含まれる
X509WalletMixin.createIdentity(identity...)
で、上で取得した鍵と証明書、MSPID (=Org1MSP
) から Identity を生成wallet.import('admin', identity)
でwallet
にadmin
としてidentity
を登録
これで wallet に admin
が登録される。
-
./wallet
は以下のようになる。
$ tree wallet wallet └── admin ├── 81e6bfa(略)691478-priv ├── 81e6bfa(略)691478-pub └── admin 1 directory, 3 files
81e6bfa(略)691478-priv
,81e6bfa(略)691478-pub
は名前の通り中身はそれぞれ秘密鍵と公開鍵81e6bfa(略)691478
はランダムな値で、毎回違う値になる。
admin
は JSON ファイルで、以下のようなかんじ。
{ "name": "admin", "mspid": "Org1MSP", "roles": null, "affiliation": "", "enrollmentSecret": "", "enrollment": { "signingIdentity": "31b577222c67(略)73516ea3c2483a", "identity": { "certificate": "-----BEGIN CERTIFICATE-----\nMIICAjCCA(略)BAd8GA=\n-----END CERTIFICATE-----\n" } } }
-
certificate
部分は証明書なので平文に戻してみると以下ca.org1.example.com
がclient
のadmin
に発行した証明書であることがわかる。- これらは
ca.enroll
時に生成されたもので、../../basic-network/crypto-config
にあるAdmin@ca.org1.example.com
等の cert とは異なるもの。
$ Cat wallet/admin/admin \ | jq -r '.enrollment.identity.certificate' \ | openssl x509 -inform PEM -text -noout
Certificate: Data: Version: 3 (0x2) Serial Number: 02:af:ba:bd:ec:(略):c0:6c:27:1c:66 Signature Algorithm: ecdsa-with-SHA256 Issuer: C=US, ST=California, L=San Francisco, O=org1.example.com, CN=ca.org1.example.com Validity Not Before: Apr 17 07:34:00 2019 GMT Not After : Apr 16 07:39:00 2020 GMT Subject: OU=client, CN=admin Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:1d:36:c3:b7:64:20:03:7f:82:39:f8:58:2d:37: (略) 5d:3a:c9:72:0b ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: 67:49:65:58:49:(略):86:CA:A9:96:F7:91 X509v3 Authority Key Identifier: keyid:42:39:AA:(略):6A:57:36:5E:49:7C Signature Algorithm: ecdsa-with-SHA256 30:44:02:20:7c:7c:58:29:d9:5e:db:6a:91:af:1b:3b:19:8d: (略) 16:60:52:00:0c:91:58:3a:f0:75:88:ae:3d:15:1f:df
node registerUser.js
../../basic-network/connection.json
をccp
として読み込み- 当該ファイルは今回のシステムの構成情報を記述してある。
- 以下、CA の URL を得るために使用している
new FileSystemWallet()
として./wallet
を使用- 現時点では、
./wallet
には./wallet/admin
だけが存在している - Hyperledger Fabric SDK for node.js Class: FileSystemWallet wallet を使用することで client の admin として振舞える
- 現時点では、
gateway.connect(ccp, {wallet, identity: 'admin' ...})
でゲートウェイに接続- Hyperledger Fabric SDK for node.js Class: Gateway
- これで、各ノードに対し
wallet
を使用して接続し、client
のadmin
として振舞える
secret = await ca.register(...)
でユーザを作成- Hyperledger Fabric SDK for node.js Class: FabricCAServices
- CA に対し
admin
の権限で実行 client
ロールをもつuser1@org1.department1
ユーザを作成するsecret
はuser1
のパスワード(自動生成)- まだ作っただけで登録は済んでいない。次の
enroll()
ではじめて登録される。
await ca.enroll()
,X509WalletMixin.createIdentity()
,wallet.import()
でwallet
にuser1
を保存admin
の時と全く同じ。
これで wallet に user1
が登録される。
-
./wallet
は以下のようになる。
$ tree wallet wallet ├── admin │ ├── 81bab1e(略)724a0e-priv │ ├── 81e6bfa(略)691478-priv │ ├── 81e6bfa(略)691478-pub │ └── admin └── user1 ├── 81bab1e(略)724a0e-priv ├── 81bab1e(略)724a0e-pub └── user1 2 directories, 7 files
user1
ディレクトリができ、鍵ペアと証明書が新たに追加されたadmin
の下に新しい秘密鍵が増え、user1
のそれと同じというのが謎- あとでしらべる
- 先ほど同様
user1
のcertificate
部分を平文に戻してみると以下ca.org1.example.com
がclient
のadmin
に発行した証明書であることがわかる。1.2.3.4.5.6.7.8.1:
という属性が追加されており、ユーザ作成時に指定したaffiliation
やrole
などの追加情報が埋め込まれている- これが MSP で使用されるのだろう、たぶん。
Certificate: Data: Version: 3 (0x2) Serial Number: 28:38:98:15:77:(略):48:ce:39:9c:58 Signature Algorithm: ecdsa-with-SHA256 Issuer: C=US, ST=California, L=San Francisco, O=org1.example.com, CN=ca.org1.example.com Validity Not Before: Apr 17 09:26:00 2019 GMT Not After : Apr 16 09:31:00 2020 GMT Subject: OU=client, OU=org1, OU=department1, CN=user1 Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:52:7b:ef:f4:49:b7:30:07:e6:a1:40:e7:90:70: (略) 6a:9f:ae:ce:5d ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: 5C:B5:E3:84:9F:(略):0B:C6:10:55:AF:38 X509v3 Authority Key Identifier: keyid:42:39:AA:(略):6A:57:36:5E:49:7C 1.2.3.4.5.6.7.8.1: {"attrs":{"hf.Affiliation":"org1.department1","hf.EnrollmentID":"user1","hf.Type":"client"}} Signature Algorithm: ecdsa-with-SHA256 30:45:02:21:00:e9:10:09:8b:4b:d8:29:c8:e8:e8:52:b4:2f: (略) 79:02:91:e1:04:32:af:65:b1:6e:42:ea:09:ab:72:33:86
今日はここで中断
さあこれから query と invoke を叩いて SDK 側だけじゃなく ChainCode の内側まで入っていくよ、という所なのだが、話が長くなりそうなので今回はここで中断。
次回はこの続きを読んでいくよ。
Hyperledger Fabric と戯れる part.2
ということで、今日も今日とてチュートリアル。まだコード書かないんかい。
前回の補足
前回やってたチュートリアルはこちら。
hyperledger-fabric.readthedocs.io
./byfn.sh down
しないで以下のようにコンテナとイメージを削除するだけだと次の ./byfn.sh up
でいろいろ失敗する。なにがいかんのかはパッと見分からなかったが、とにかく ./byfn.sh down
しよう。
$ docker rm -f $(docker ps -aq) $ docker rmi -f $(docker images | grep 'dev-' | awk '{print $3}') $ git clean -fdx .
Adding an Org to a Channel チュートリアル
hyperledger-fabric.readthedocs.io
今回から eyfn.sh
を使う。byfn が Build Your First Network の略っぽいから、eyfn は Edit 以下略とかって事なのかな。 ネーミングセンス・・・
ともあれ、 eyfn.sh
にも サブコマンド generate
, up
, down
(あと一応 restart
も) がある。
チュートリアル本文では generate
を省略して up
を呼ぶ指示があるが、これは up
のなかで generate
の出力の有無をチェックして、必要があれば適宜呼んでいるから。(実は ./byfn.sh
もここらへんの仕組みは同じ。)
初期状態 (前回のおさらい)
./byfn.sh up
が完了した状態が今回の初期状態とある。つまり前回解説した通り、
- チャンネル名
mychannel
があって、 - 以下のノードが登録されていて、
- orderer.example.com
- peer0.org1.example.com
- peer1.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
- cli
- ChainCode
mycc
の v1.0 が以下 3 つの peer にインストールされていて、- peer0.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
- ChainCode
mycc
の v1.0 がインスタンス化され、動作確認まで出来ている状態
ということになる。
./eyfn.sh generate
cryptogen
でorg3-artifacts/org3-crypto.yaml
の設定通りに証明書を発行して./org3-artifacts/crypto-config
を生成cryptogen
は以下を生成して、各ノード、ユーザの設定となるようディレクトリツリーをつくり配置する- org3.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
- 証明書はそれぞれ交互に配布しあう (ユーザ同士は交換しない)
- org3.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
configtxgen
でorg3-artifacts/configtx.yaml
の設定通りに Org3 の設定を生成して./channel-artifacts/org3.json
を生成- 前回と違って Anchor Peer の設定ファイルとして .tx ファイルを作ってるわけではない。
org3-artifacts/configtx.yaml
から organization の構成について抜粋したみたいなファイルを作っている。
crypto-config/ordererOrganizations
をorg3-artifacts/crypto-config/
にコピー- 前回作った Orderer まわりの証明書と鍵。
cli
にscripts/step1org3.sh
を実行させるapt-get install jq
- 知ってる人も多いと思うけど、
jq
は JSON の操作をするコマンド。色つけたり整形したりもできて便利なのでみんな使おう
- 知ってる人も多いと思うけど、
peer channel fetch config ...
- Orderer から
mychannel
の設定を取得している - 結果を
configtxlator proto_decode --type common.Block
することで JSON 形式に変換、jq
で必要情報を抜き出している- 内容は色々あるが、おおよそ
mychannel
の構成情報
- 内容は色々あるが、おおよそ
- Orderer から
- 上で抜き出した channel 設定に、上記で作成した
./channel-artifacts/org3.json
を埋め込み configtxlator proto_encode
,configtxlator compute_update
等を駆使して更新用のデータを作成- ここらへんの仕様にかんするドキュメントがまるで見当らないので詳細は不明
peer channel signconfigtx ...
peer0.org1
に対して上で作った更新用データへの署名を手動で付加
peer channel update ...
peer0.org2
に対して変更を送信- channel の管理者は
peer0.org*
の 2 つであり、変更ポリシは過半数の承認で受け入れれらるように設定されている。つまり 2 つ両方の承認が必要peer0.org1
は先ほど手動で署名済みpeer0.org2
は今回の要求でorg2
の Admin として送付されるため、問題なければ署名され、そのまま変更が受け入れられる
- なおコレが
mychannel
のブロック5 にあたる。
./byfn.sh up
この時点では、mychannel
に org3
を含ませるように設定できている。
だが実際に org3
の peer は mychannel
に参加はしていない。(というより、org3
の peer 自体まだ存在していない)
docker-compose
でorg3
の各ノードを起動する- 設定ファイルは
docker-compose-org3.yaml
- 内容的には
org1
,org2
と大差ない
- 内容的には
- 起動するのは以下。なおすべて
byfn
ネットワークに属する。- peer0.org3.example.com
- peer1.org3.example.com
- Org3cli
org3
専用のクライアントノード。
- 設定ファイルは
- 作った
Org3cli
にscripts/step2org3.sh
を実行させるpeer channel fetch 0 ...
- Orderer から
mychannel
のジェネシスブロックを取得している - 前回は
peer channel create
の結果として生成されていたので取得の必要はなかったが、今回はこうして取得する
- Orderer から
peer channel join
- Org3 の peer ノード(2つ)それぞれに対して実行してる。
- 上で取得した
mychannel.block
を渡して、対象 peer ノードを mychannel に参加させる
- 上で取得した
- Org3 の peer ノード(2つ)それぞれに対して実行してる。
peer chaincode install
- Anchor Peer である
peer0.org3.example.com
に対し実施- chaincode 名は
mycc
、 バージョン2.0
、実装言語はgolang
、とそれぞれ指定している。 - chaincode 自体には変更がないが、バージョンを前回の 1.0 でなく 2.0 としているところに注意
- chaincode 名は
- Anchor Peer である
cli
にscripts/step3org3.sh
を実行させる- ここだけ
Org3cli
ではなくcli
に実行させてるので注意 peer chaincode install
- Anchor Peer のうち残り 2 つである
peer0.org1.example.com
peer0.org2.example.com
に対し実施- chaincode 名は
mycc
、 バージョン2.0
、実装言語はgolang
、とそれぞれ指定している。 - org3 のとき同様、バージョンが上がっている。
- chaincode 名は
- Anchor Peer のうち残り 2 つである
peer chaincode upgrde
peer0.org1.example.com
ノード 1 つのみに対して実行されているpeer chaincode instantiate
とほとんど同じだが、バージョンアップ時はこちらを使うっぽい。- orderer
orderer.example.com
に対し、 mychannel
において、- 初期化メッセージ
{"Args":["init","a","90","b","210"]}
を渡し、- "a" に "90" を、 "b" に "210" をそれぞれセットしているっぽい
- ポリシー
AND ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')
も渡して、- Org1、Org2、Org3 の承認の 3 つが必要ということ
mycc
のバージョン2.0
をインスタンス化する
- orderer
- インスタンス化の操作は channel 内の全 peer に伝達される
- この時点で
Org3
は他のOrg1
,Org2
と同様にmychannel
の参加者となっている
- ここだけ
- 再度
Org3cli
にscripts/testorg3.sh
を実行させる- 動作確認。目新しいことはしていないので省略。
ここで、Docker コンテナを一覧してみると
$ docker ps --format "table {{.Names}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}" | sort NAMES CREATED AT STATUS PORTS Org3cli 2019-04-15 13:50:36 +0900 JST Up About an hour cli 2019-04-15 10:55:05 +0900 JST Up 4 hours dev-peer0.org1.example.com-mycc-1.0 2019-04-15 10:55:56 +0900 JST Up 4 hours dev-peer0.org1.example.com-mycc-2.0 2019-04-15 13:50:51 +0900 JST Up About an hour dev-peer0.org2.example.com-mycc-1.0 2019-04-15 10:55:39 +0900 JST Up 4 hours dev-peer0.org2.example.com-mycc-2.0 2019-04-15 13:51:24 +0900 JST Up About an hour dev-peer0.org3.example.com-mycc-2.0 2019-04-15 13:51:09 +0900 JST Up About an hour dev-peer1.org2.example.com-mycc-1.0 2019-04-15 10:56:13 +0900 JST Up 4 hours orderer.example.com 2019-04-15 10:55:04 +0900 JST Up 4 hours 0.0.0.0:7050->7050/tcp peer0.org1.example.com 2019-04-15 10:55:04 +0900 JST Up 4 hours 0.0.0.0:7051->7051/tcp peer0.org2.example.com 2019-04-15 10:55:04 +0900 JST Up 4 hours 0.0.0.0:9051->9051/tcp peer0.org3.example.com 2019-04-15 13:50:35 +0900 JST Up About an hour 0.0.0.0:11051->11051/tcp peer1.org1.example.com 2019-04-15 10:55:04 +0900 JST Up 4 hours 0.0.0.0:8051->8051/tcp peer1.org2.example.com 2019-04-15 10:55:04 +0900 JST Up 4 hours 0.0.0.0:10051->10051/tcp peer1.org3.example.com 2019-04-15 13:50:35 +0900 JST Up About an hour 0.0.0.0:12051->12051/tcp
のように、
- クライアントノード 2 種
- mycc v1.0 インスタンス 3つ (peer0.org1, peer0.org2, peer1.org2)
- mycc v2.0 インスタンス 3つ (peer0.org1, peer0.org2, peer0.org3)
- orderer 1 つ
- org 3種 x peer 2つで計 6 つの Peer ノード
が起動していることがわかる。 chaincode はアップグレードしてもコンテナ自体は消えないのな。
./eyfn.sh down
単純なおそうじスクリプト。上記までで作ったものをみんな削除する。
おしまい
今回は前回の内容を踏襲してる部分が殆どだったので、わりと簡単だった。
次回は、前回飛ばしていた Writing Your First Application チュートリアルに進む予定。
Hyperledger Fabric と戯れる part.1
ということで今日はさくっと Hyperledger Fabric を動かしてみる。
ちょっと調べたかんじ Hyperledger Composer も便利そうだったので、あわせて導入だけしておく。
その前に
Hyperledger Fabric がどんなもんか、用語とその内容がわかる程度にザックリ読んどく。
hyperledger-fabric.readthedocs.io
理解したことをすげえざっくりまとめると
- Network
- Hyperledger Fabric をつかって作るシステム全体を指すよ
- 1つ以上の Organization が network の管理をする権利を持てるよ
- これは厳密には System Channel という特別な channel として扱われるよ
- 1つ以上の Channel を含むよ
- 1つ以上の Orderer を含むよ
- Organization
- この network に参加する組織を指すよ
- 1つ以上の channel に参加できるよ
- 1つ以上の peer を持つよ
- 1つの MSP を持つよ
- Peer
- (物理的な意味で) organization が管理するノードだよ
- つまり、 1 つ以上の channel に参加できるよ
- つまり、 1 つ以上の台帳を持つよ
- (論理的な意味では) channel にホストされるノードだよ
- つまり、 1 つ以上の channel に参加できるよ
- 4 種の役割があり、各 peer は1つ以上の役割を担うよ
- Commitment Peer
- Endorsement Peer
- Anchor Peer
- network に参加する他の organization との通信の窓口になるよ
- Leader Peer
- orderer と直接やりとりするよ
- leader じゃない peer は、leader からトランザクションを分配されるよ
- 1 organization につき必ず 1 leader peer が必要だよ
- orderer と直接やりとりするよ
- (物理的な意味で) organization が管理するノードだよ
- Channel
- 1つの台帳と、それを扱う organization たちをまとめた単位だよ
- channel に所属する organization だけが channel に所属する台帳を保持、制御できるよ
- 1つ以上の peer をもつよ
- 常に 1 つの Leader Peer をもつよ
- 少なくとも 1 つの Commitment Peer をもつよ
- 少なくとも 1 つの Endorsement Peer をもつよ
- 台帳
- そのままだよ
- 内部的には、現在(最新)の状態を保持した DB と、それまでの操作履歴を保持した BlockChain で構成されるよ
- 台帳とおなじ channel に所属する organization (の peer) がそれぞれ全く同じ台帳のコピーを保持してるよ
- 台帳とおなじ channel に所属する organization (の peer) が chaincode を通して台帳を制御できるよ
- DB みたいなノリでアクセスできるよ
- そのままだよ
- Endorsement Policy
- トランザクションが受け入れられるために、どの organization が承認する必要があるかの定義だよ
- channel 構成に含まれ、channel 内のすべての endorsement peer は同一のポリシで動く必要があるよ
- Chain Code
- 台帳に対する操作を定義したプログラムみたいなものだよ
- peer にインストールし、インスタンス化することで使用することができるよ
- バージョンは管理されるよ
- Orderer
- CA
- ただの認証局だよ
- Peer や Orderer、 Client とかに X.509 証明書を分配するよ
- Fabric-CA というものがパッケージに含まれてるけど、普通に組織独自の CA 使えばいいよ
- 通常、各 organization がそれぞれ CA を持ってるよ
- ただの認証局だよ
- MSP
- Membership Services Provider
- CA をつかって、network 内の各ノードやチャンネル、ユーザなんかの Hyperledger Fabric 特有のあれこれを管理するよ
- 各 organization がそれぞれ運用するよ
- Client
- network 中の台帳を参照・制御するアプリケーションだよ
- あくまでも Hypeledger Fabric システムに対するクライアントを指すので混乱しないよう注意だよ
- たいていは各 organization がそれぞれに作成・管理するよ
- network 中の台帳を参照・制御するアプリケーションだよ
Identity と MSP あたりがわりと理解あやしい。それら含め何か勘違いしてるようなら後ほど修正する。 (ので、指摘等してくれる人がいたら嬉しい。)
インストール
公式ドキュメント通り進める。インストールマニュアルを和訳する趣味はないのでリンクだけ貼っとく。
注意すべきところは、 Node.js は v8 系じゃないとダメとの事なので nvm を使ってバージョンを指定すること、pyenv などで python
コマンドのバージョンを 3 系にしてるときは忘れず 2.7 系になるようにしておくこと、くらい。 ということで prereqs がわりと重要なのであわせて貼っとく。
- Hyperledger Fabric
- Hyperledger Composer
なお Fabric のインストールスクリプトはカレントディレクトリに samples リポジトリをクローンするので、変な場所で実行すると微妙な気持ちになるので注意。
もう既にインストール済なものもあったので色々飛ばしたり等したのもあるが、 MacOS 10.14.4 の環境でだいたいこんなかんじになった。
$ node --version v8.15.1 $ python --version Python 2.7.10 $ go version go version go1.12.1 darwin/amd64 $ docker --version Docker version 18.09.2, build 6247962 $ docker-compose --version docker-compose version 1.23.2, build 1110ad01 $ composer --version v0.20.8 $ docker images -a | sort REPOSITORY TAG IMAGE ID CREATED SIZE hyperledger/fabric-ca 1.2.1 be8400395e15 6 months ago 251MB hyperledger/fabric-ca 1.4.1 3a1799cda5d7 9 hours ago 252MB hyperledger/fabric-ca latest 3a1799cda5d7 9 hours ago 252MB hyperledger/fabric-ccenv 1.2.1 8651e7160d88 6 months ago 1.43GB hyperledger/fabric-ccenv 1.4.1 d7433c4b2a1c 9 hours ago 1.43GB hyperledger/fabric-ccenv latest d7433c4b2a1c 9 hours ago 1.43GB hyperledger/fabric-couchdb 0.4.10 3092eca241fc 9 months ago 1.61GB hyperledger/fabric-couchdb 0.4.15 8de128a55539 3 weeks ago 1.5GB hyperledger/fabric-couchdb latest 8de128a55539 3 weeks ago 1.5GB hyperledger/fabric-javaenv 1.4.1 b8c9d7ff6243 11 hours ago 1.74GB hyperledger/fabric-javaenv latest b8c9d7ff6243 11 hours ago 1.74GB hyperledger/fabric-kafka 0.4.15 b4ab82bbaf2f 3 weeks ago 1.44GB hyperledger/fabric-kafka latest b4ab82bbaf2f 3 weeks ago 1.44GB hyperledger/fabric-orderer 1.2.1 b1a1dd788841 6 months ago 152MB hyperledger/fabric-orderer 1.4.1 ec4ca236d3d4 9 hours ago 173MB hyperledger/fabric-orderer latest ec4ca236d3d4 9 hours ago 173MB hyperledger/fabric-peer 1.2.1 ef0e7788ead0 6 months ago 159MB hyperledger/fabric-peer 1.4.1 a1e3874f338b 9 hours ago 178MB hyperledger/fabric-peer latest a1e3874f338b 9 hours ago 178MB hyperledger/fabric-tools 1.4.1 432c24764fbb 9 hours ago 1.55GB hyperledger/fabric-tools latest 432c24764fbb 9 hours ago 1.55GB hyperledger/fabric-zookeeper 0.4.15 20c6045930c8 3 weeks ago 1.43GB hyperledger/fabric-zookeeper latest 20c6045930c8 3 weeks ago 1.43GB
CA とか Orderer とか Peer なんかのイメージがインストールされてることが確認できた。
Hyperledger Fabric の最新版は 1.4.1 だが、Composer の最新版の対象バージョンはいまだ 1.2 系なので一部 1.2 系が含まれている。 v1.4 系が LTS なのと、v1.4 系からプログラミングモデルが更新されたとの事なので、できるかぎり v1.2 は使わないで行きたいところではある。
チュートリアルを動かす
チュートリアルめっちゃ沢山あるのでガンガンすすめてく。
sample リポジトリは上述の通りインストールスクリプトを実行した場所に clone されている。
以降は tags/v1.4.1(6c0203a) での勉強結果。
Building Your First Application チュートリアル
チュートリアルの目次を見ると Writing Your First Application を先にやるべきっぽいのだが、動かしかた知る前に書きかたから入るのってどうなのと思ったので先にこっち。
./byfn.sh generate
出力を見ればなんとなくわかるけど、以下のことをやってる。(自力で分析した内容も多分に含まれるため、正確かどうかは怪しい)
cryptogen
でcrypto-config.yaml
の設定通りに証明書を発行して./crypto-config
を生成cryptogen
は以下を生成して、各ノード、ユーザの設定となるようディレクトリツリーをつくり配置する- orderer ドメイン(example.com) の CA、全ユーザ(Admin)、全ノード(orderer〜orderer5) それぞれに対する証明書と鍵
- 証明書はそれぞれ交互に配布しあう
- org1.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
- 証明書はそれぞれ交互に配布しあう (ユーザ同士は交換しない)
- org2.example.com ドメインの CA、全ユーザ(Admin, User1)、全ノード(peer0, peer1) それぞれに対する証明書と鍵
- 証明書はそれぞれ交互に配布しあう (ユーザ同士は交換しない)
- orderer ドメイン(example.com) の CA、全ユーザ(Admin)、全ノード(orderer〜orderer5) それぞれに対する証明書と鍵
- 上記で生成した鍵内容を
docker-compose-e2e-template.yaml
に適用してdocker-compose-e2e.yaml
を生成- この
docker-compose-e2e.yaml
なんだけど、以降どこでも使われてない。 - これは別のテスト用のものなので今回は無視する。
- この
configtxgen
でconfigtx.yaml
の設定通りに Orderer の設定を生成して./channel-artifacts/genesis.block
を生成configtxgen
でconfigtx.yaml
の設定通りに Channel の設定を生成して./channel-artifacts/channel.tx
を生成configtx.yaml
から channel の構成について抜粋したみたいなバイナリファイルを作っている。- 以降の手順で channel を作成する際に設定ファイルとして渡されている
configtxgen
でconfigtx.yaml
の設定通りに Peer1 の設定を生成して./channel-artifacts/Org1MSPanchors.tx
を生成configtxgen
でconfigtx.yaml
の設定通りに Peer2 の設定を生成して./channel-artifacts/Org2MSPanchors.tx
を生成configtx.yaml
から organization の構成について抜粋したみたいなバイナリファイルを作っている。- 以降の手順で anchor peer を channel に登録する際に設定ファイルとして渡されている
./byfn.sh up
オプションで chaincode を Go 実装じゃなくて Node 実装や Java 実装に切り替えられたり、デフォルトで 1 こしか起動させない orderer を Kafka ないし Raft で並列に動かさせることもできる。StateDB を CouchDB (デフォルトは LevelDB) にすることもできるらしい。
今回は既にわりとおなかいっぱいなのでデフォルトオプションにて実行した。
以降、やはり自力で分析した内容も多分に含まれるため、正確かどうかは怪しい
docker-compose
で各ノードを起動する- オプション等をつけなかった場合、
docker-compose-cli.yaml
だけが使用される。- ここに orderer2 〜 orderer5 までの 4 つの orderer は含まれていない
- 各ノードは
cryptogen
で作ったディレクトリツリーの自身に対応する部分を適宜マウントするようになっている
- 起動するのは以下。なおすべて
byfn
ネットワークに属する。- orderer.example.com
- peer0.org1.example.com
- peer1.org1.example.com
- peer0.org2.example.com
- peer1.org2.example.com
- cli
- CA サーバは起動してない。
- (あとで調べる)
- オプション等をつけなかった場合、
- 作った
cli
にscripts/script.sh
を実行させるpeer channel create
- orderer に対して実行している
- ここで
mychannel.block
がcli
の working directory に作成される
peer channel join
- 全 peer ノード(4つ)それぞれに対して実行してる。
- 上で作成された
mychannel.block
を渡して、対象 peer ノードを mychannel に参加させる
- 上で作成された
- 全 peer ノード(4つ)それぞれに対して実行してる。
peer channel update
- orderer に対して実行している
- これで Org* のアンカーピアとして
peer0.org*.example.com
が設定される- 設定内容は channel 内の全 peer に伝達される
peer chaincode install
- Anchor Peer である 2つの
peer0.org*.example.com
ノードに対して実行されている- 文字通り chaincode をインストールしている
- パス は
../chaincode/chaincode_example02/go/
- ビルドとかはせず、そのまんま渡しているっぽい
- chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
- chaincode 名は
mycc
、 バージョン1.0
、実装言語はgolang
、とそれぞれ指定している。
- Anchor Peer である 2つの
peer chaincode instantiate
peer0.org2.example.com
ノード 1 つのみに対して実行されている- orderer
orderer.example.com
に対し、 mychannel
において、- 初期化メッセージ
{"Args":["init","a","100","b","200"]}
を渡し、- "a" に "100" を、 "b" に "200" をそれぞれセットしているっぽい
- ポリシー
AND ('Org1MSP.peer','Org2MSP.peer')
も渡して、- Org1 の承認、および Org2 の承認の 2 つが必要ということ
mycc
のバージョン1.0
をインスタンス化する
- orderer
- どうもこのタイミングでソースコードのビルドが行われているらしい
- インスタンス化の操作は channel 内の全 peer に伝達される
- インストールされているのは
peer0.org*
の 2 ノードだけなので、実際に query, invoke ができるのはこれら 2 ノードだけとなる
- インストールされているのは
peer chaincode query
peer0.org1
ノードに対する query の動作確認- "a" の値を問い合わせて "100" であることを確認しているっぽい
- chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
peer chaincode invoke
peer chaincode install
peer chaincode query
peer1.org2
ノードに対する query の動作確認- "a" の値を問い合わせて "90" であることを確認しているっぽい
- chaincode の内容は次のチュートリアルで学ぶのでとりあえず無視。
ここで、Docker コンテナを一覧してみると
$ docker ps --format "table {{.Names}}\t{{.CreatedAt}}\t{{.Status}}\t{{.Ports}}" | sort NAMES CREATED AT STATUS PORTS cli 2019-04-12 17:04:04 +0900 JST Up 2 hours dev-peer0.org1.example.com-mycc-1.0 2019-04-12 17:04:55 +0900 JST Up 2 hours dev-peer0.org2.example.com-mycc-1.0 2019-04-12 17:04:38 +0900 JST Up 2 hours dev-peer1.org2.example.com-mycc-1.0 2019-04-12 17:05:12 +0900 JST Up 2 hours orderer.example.com 2019-04-12 17:04:03 +0900 JST Up 2 hours 0.0.0.0:7050->7050/tcp peer0.org1.example.com 2019-04-12 17:04:03 +0900 JST Up 2 hours 0.0.0.0:7051->7051/tcp peer0.org2.example.com 2019-04-12 17:04:03 +0900 JST Up 2 hours 0.0.0.0:9051->9051/tcp peer1.org1.example.com 2019-04-12 17:04:03 +0900 JST Up 2 hours 0.0.0.0:8051->8051/tcp peer1.org2.example.com 2019-04-12 17:04:03 +0900 JST Up 2 hours 0.0.0.0:10051->10051/tcp
こんな感じで dev-*-mycc-1.0 というものが出来ている。これが要するにインスタンス化した chaincode って事らしい。
./byfn.sh down
単純なおそうじスクリプト。上記までで作ったものをみんな削除する。
まとめ
まずは起動と動作確認とを実施できた。今回はお勉強項目がやたらと多かったのですっごい疲れた。
Hyperledger Fabric と戯れる part.0
首題について勉強した結果をどこかに纏めておきたかったのだが、適した場所がとくに見当らなかったのでここに残しとく。 あとでより適したどこかに移動するかも。
ブロックチェーンてなーに
ブロックのチェーンである。
ブロックは主に
で構成され、それが一つなぎに続くことでシステム全体における取引履歴などをつくりあげる。
このとき、Block(n-1) のトランザクションを改竄しようとすると、Block(n) にある Block(n-1) のハッシュ値と不整合が起きる。では Block(n) にある Block(n-1) のハッシュ値も改竄しよう、となると Block(n+1) にある Block(n) のハッシュ値と不整合が起きる・・・といったかんじで、改竄がわりと困難になるため、そういった後から改竄とかそういうのが簡単にできないようなもの(それこそ仮想通貨の取引とかね)に使われる。
もちろん上記説明だけだと不十分で、ブロックを作ること自体が膨大な計算コストを要しているため改竄対象以降のブロックを悉く改竄していくのが余計に大変になっているだとか、ブロックチェーンが分散管理されているため一箇所だけ改竄しても意味ないとか、いろいろな理論や仕組みが複雑に絡んで所謂「セキュアな」帳簿を構成することができている。
当然だが俺はその全てを正確に説明できないし知ってもいない。そういうの全部わかってて実際にゼロからそういうのを作れる人は年収2000万とか貰う超一流のブロックチェーンエンジニアなわけで、俺はそうでない年収3桁万の一般的なシステムエンジニアである。ああ、金が欲しい
分散台帳ってなーに
ブロックチェーンで構成した台帳を、分散管理するシステム。実際は分散台帳技術がブロックチェーンの派生らしいのだが、一般には分散台帳技術も含めて「ブロックチェーン技術」て言いがちよね。
分散台帳は、そのネットワークの参加者がそれぞれにトランザクションを検証し、コンセンサスが取れたことを確認して、その後に全参加者の台帳(ブロックチェーン)にトランザクションを追加する。 そうすることによって、各参加者の持つ台帳の整合性が取れ、全参加者が同一の台帳を分散保持していると言うことができるらしい。
ようするにブロックチェーンて何が嬉しいの?
データ構造的に改竄されにくいとか、分散管理による中央集権化の回避だの冗長性だのと色々言われるが、ようするに信頼性が高くなるって事で良いらしい。
ただし、そのために(普通のRDBなんかと比べたら)速度とかは多少なり犠牲になってしまうとのこと。
Hyperledger Fabric てなーに
Linux Foundation が主導するOSS のブロックチェーンプラットフォーム 「Hyperledger Project」のうちの 1 つで、コンソーシアム型の分散台帳フレームワーク。 「うちの 1 つ」といってるがコレくらいしか名前聞かない。あとは開発ツール? の Composer はたまに聞くかな程度。
コンソーシアム型てなーに
Bitcoin や Ethereumみたいな(悪意ある奴も含む)不特定多数が参加するもの(パブリック型)に対し、予めお互い信頼しあっている複数の組織だけで利用するものがコンソーシアム型。
特定組織だけの許可制での参加を前提とすることで、パブリック型ほどには膨大な計算を必要としなくて済み、ようするに比較的速いらしい。
また、1 組織だけのプライベート型なるものもあるらしいが、「分散台帳」なのに分散管理しないとはこれいかに? あまり意味なさそうなので興味もなく調べてもいない。
なんで Hyperledger Fabric なの?
仕事で使うと指示されたからである。
もちろん他にもブロックチェーン基盤はたくさんあり、それぞれにメリットデメリット、長所短所、向き不向きなどはあるのだろうが、調べてすらいない。かなしい。
今日はここまで
そう、Hyperledger Fabric とまだ一切戯れてない。