Hyperledger Fabricを少し詳しく見てみる

技術メモ

以前の記事で、とりあえず訳も分からぬまま Chaincode API でのチェーンコード設置・実行・参照 を実施してみたのだけど、それがどういった意味かさっぱりわかっていないので(汗)1つ1つ手順を詳しく理解する事にした。

Docker イメージの2つの役割

fabric-peerと、fabric-membersrvcのそれぞれの役割を理解しておく。

hyperledger/fabric-peer

Peerサーバーを立ち上げるためのP2Pを行うためのイメージ。
P2Pは詳しい話は P2P(ピア・ツー・ピア) を見るとわかる。

hyperledger/fabric-membersrvc

証明書(CA)サーバーのイメージ。
参加者に対してログインや、登録証明書(Enrollment Certificates, ECert)や取引証明書(Transaction Certificates, TCert)を発行する認証局(CA)の役割を担う。

docker-compose.ymlの中身

docker-compose に関してはこちらのページ参照
公式なドキュメントだと思われるページ。

以下リンクが復活すればオプション全部書かれていそうなんだが、なぜか404のまま・・・
http://hyperledger-fabric.readthedocs.io/en/latest/dev-setup/devenv.md

-----
membersrvc:
  image: hyperledger/fabric-membersrvc
  command: membersrvc
vp0:
  image: hyperledger/fabric-peer
  environment:
    - CORE_PEER_ADDRESSAUTODETECT=true
    - CORE_VM_ENDPOINT=http://172.17.0.1:2375
    - CORE_LOGGING_LEVEL=DEBUG
    - CORE_PEER_ID=vp0
    - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
    - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
    - CORE_SECURITY_ENABLED=true
    - CORE_SECURITY_ENROLLID=test_vp0
    - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
  links:
    - membersrvc
  command: sh -c "sleep 5; peer node start --peer-chaincodedev"
-----

CORE_PEER_ADDRESSAUTODETECT

値をtrueにするとどうも認証サーバーのアドレスをprivateにし、falseにすると公開するらしい・・・が公式ドキュメントが見つからず。
hyperledger-fabric.readthedocs.ioはリンク切れ多いんだよね。

– CORE_VM_ENDPOINT
これはそのまんま。エンドポイント。受け付けるURL。

– CORE_LOGGING_LEVEL
Debugレベル

– CORE_PEER_ID
CAサーバーのID

– CORE_PEER_PKI_ECA_PADDR、CORE_PEER_PKI_TCA_PADDR、CORE_PEER_PKI_TLSCA_PADDR

Enrollment Certificate Authority (ECA)
・enrollment証明書(ECert)を発行。メンバーとして登録済みである事を証明する証明書。

Transaction Certificate Authority (TCA)
・トランザクション証明書(TCerts) を発⾏する。
・TCertsの番号は、各Ecertから無限に生成される
・TCertはネットワーク参加者によって、トランザクションを送信するために利⽤される

TLS-Certificate Authority (TLS-CA)
・チェーンネットワーク内で、システムがメッセージ転送をするためのTLS証明書を発⾏ する
・TLS証明書は、システム間での通信チャネルをセキュアにするために使われる

以下図に、ECA、TCA、TLSCAの説明が記載がある。
記事元はこちら

– CORE_SECURITY_ENABLED

セキュリティ設定のON, OFF

– CORE_SECURITY_ENROLLID, CORE_SECURITY_ENROLLSECRET

不明

blockchainのサンプルPG動かす

以下を見ると何をやっているかだいたいわかる。

Hyperledger fabric(v0.6)でchaincodeの開発環境を構築する
Hyperledger Fabric の REST API メモ

ログイン

Writing, Building, and Running Chaincode in a Development Environment
の「Terminal 3 (CLI or REST API)」 あたりに記載がある。

以下がログインするためのPOST。

'{"enrollId":"jim","enrollSecret":"6avZQLwcUe9b"}' http://localhost:7050/registrar

分解していくと、
まずport 7050。
7050は指定した覚えがない。
grepなどで調べた結果、peerサーバーでport設定を指定しないとデフォルトで7050で待ち受けるようだ。

ちなみにport変更する場合は以下のようにportsを docker-compose.yml に記載してやればよいようだ。

vp0:
  image: hyperledger/fabric-peer
  ports:
    - "7050:7050"

このport に /registrar に POSTしてあげると。
membersrvc.yaml の eca.users の enrollId, enrollmentPW を使ってログインができる。

deploy -> invoke/query

このサンプルコードが何やってるかよくわからなかった。
ソースを見てみると。以下メソッドを実装している。

CORE_CHAINCODE_ID_NAME=mycc
CORE_PEER_ADDRESS=0.0.0.0:7051
の引数をつけて呼び出すのだが(ちなみに7051はpeerサーバーのデフォルトport)

以下が chaincode_example02 を実行したログ

# CORE_CHAINCODE_ID_NAME=mycc CORE_PEER_ADDRESS=0.0.0.0:7051 ./chaincode_example02
10:11:46.363 [shim] DEBU : Peer address: 0.0.0.0:7051
10:11:46.386 [shim] DEBU : os.Args returns: [./chaincode_example02]
10:11:46.387 [shim] DEBU : Registering.. sending REGISTER
10:11:46.483 [shim] DEBU : []Received message REGISTERED from shim
10:11:46.484 [shim] DEBU : []Handling ChaincodeMessage of type: REGISTERED(state:created)
10:11:46.485 [shim] DEBU : Received REGISTERED, ready for invocations

以下がサーバー側のログ

vp0_1         | 10:12:23.733 [chaincode] HandleChaincodeStream -> DEBU 640 Current context deadline = 0001-01-01 00:00:00 +0000 UTC, ok = false
vp0_1         | 10:12:23.734 [chaincode] processStream -> DEBU 641 []Received message REGISTER from shim
vp0_1         | 10:12:23.735 [chaincode] HandleMessage -> DEBU 642 []Handling ChaincodeMessage of type: REGISTER in state created
vp0_1         | 10:12:23.735 [chaincode] beforeRegisterEvent -> DEBU 643 Received REGISTER in state created
vp0_1         | 10:12:23.735 [chaincode] registerHandler -> DEBU 644 registered handler complete for chaincode mycc
vp0_1         | 10:12:23.735 [chaincode] beforeRegisterEvent -> DEBU 645 Got REGISTER for chaincodeID = name:"mycc" , sending back REGISTERED
vp0_1         | 10:12:23.736 [chaincode] notifyDuringStartup -> DEBU 646 nothing to notify (dev mode ?)

サンプルコードを動かすと、chaincodeの”mycc”を登録している事がわかる。
これで、実行可能バイナリchaincode_example02がmyccという名前で台帳に登録できたらしい。

このサンプルコードを動かしたまま(待ち受けていないといけない)以下deployクエリーを投げると

echo '{
  "jsonrpc": "2.0",
  "method": "deploy",
  "params": {
    "type": 1,
    "chaincodeID": {
      "name": "mycc"
    },
    "ctorMsg": {
      "function": "init",
      "args": ["a", "1000", "b", "2000"]
    },
    "secureContext": "jim"
  },
  "id": 1
}' | 
curl -X POST -H 'Content-Type: application/json' -d @- http://localhost:7050/chaincode

以下出力

10:23:16.061 [shim] DEBU : [mycc]Received message INIT from shim
10:23:16.062 [shim] DEBU : [mycc]Handling ChaincodeMessage of type: INIT(state:established)
10:23:16.062 [shim] DEBU : Entered state init
10:23:16.062 [shim] DEBU : [mycc]Received INIT, initializing chaincode
Aval = 1000, Bval = 2000
10:23:16.071 [shim] DEBU : [mycc]Inside putstate, isTransaction = true
10:23:16.072 [shim] DEBU : [mycc]Sending PUT_STATE
10:23:16.084 [shim] DEBU : [mycc]Received message RESPONSE from shim
10:23:16.084 [shim] DEBU : [mycc]Handling ChaincodeMessage of type: RESPONSE(state:init)
10:23:16.084 [shim] DEBU : [mycc]before send
10:23:16.084 [shim] DEBU : [mycc]after send
10:23:16.084 [shim] DEBU : [mycc]Received RESPONSE, communicated (state:init)
10:23:16.085 [shim] DEBU : [mycc]Received RESPONSE. Successfully updated state
10:23:16.089 [shim] DEBU : [mycc]Inside putstate, isTransaction = true
10:23:16.090 [shim] DEBU : [mycc]Sending PUT_STATE
10:23:16.092 [shim] DEBU : [mycc]Received message RESPONSE from shim
10:23:16.092 [shim] DEBU : [mycc]Handling ChaincodeMessage of type: RESPONSE(state:init)
10:23:16.092 [shim] DEBU : [mycc]before send
10:23:16.092 [shim] DEBU : [mycc]after send
10:23:16.092 [shim] DEBU : [mycc]Received RESPONSE, communicated (state:init)
10:23:16.092 [shim] DEBU : [mycc]Received RESPONSE. Successfully updated state
10:23:16.092 [shim] DEBU : [mycc]Init succeeded. Sending COMPLETED
10:23:16.092 [shim] DEBU : [mycc]Move state message COMPLETED
10:23:16.092 [shim] DEBU : [mycc]Handling ChaincodeMessage of type: COMPLETED(state:init)
10:23:16.092 [shim] DEBU : [mycc]send state message COMPLETED

deploy時に初期化関数initが実行される。

で、invoke。何かを実施する、、、的な。

echo '{
  "jsonrpc": "2.0",
  "method": "invoke",
  "params": {
    "type": 1,
    "chaincodeID": {
      "name": "mycc"
    },
    "ctorMsg": {
      "function": "invoke",
      "args": ["a", "b", "100"]
    },
    "secureContext": "jim"
  },
  "id": 1
}' |
curl -X POST -H 'Content-Type: application/json' -d @- http://localhost:7050/chaincode

ctorMsgのfunctionで呼び出す関数を指定する。上記は chaincode_example02 の invoke メソッドを呼び出して引数に以下を渡している。
a = 100
b = 100

実際のコードchaincode_example02では a の引数分マイナスし、bの引数の値分プラスする。

queryはデータを表示するという意味で理解した。

echo '{
  "jsonrpc": "2.0",
  "method": "query",
  "params": {
    "type": 1,
    "chaincodeID": {
      "name": "mycc"
    },
    "ctorMsg": {
      "function": "query",
      "args": ["a"]
    },
    "secureContext": "jim"
  },
  "id": 1
}' |
curl -X POST -H 'Content-Type: application/json' -d @- http://localhost:7050/chaincode

invokeと同様に、functionにqueryを指定しているので、chaincode_example02のqueryが呼び出され a の状態を返す。

コード登録 -> deploy -> invoke/query の順番。

コード登録はshim.Start。
deployは init メソッドをoverrideして実装
invoke/query メソッドは この名前じゃなくてもよさそうだ。ルール的なやつか?

なんとなーく処理の流れがわかったな。

Sponsored Link
コメントはまだありません

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


仮想通貨全般
TendermintをDocker使って起動してみる

以前、勉強会に行ってきた際にTendermintの事を聞いて ブロックチェーンプロトコルが実装できる …

仮想通貨全般
Bitcoinのdifficultyを決めるnBitsを理解する

マイニングする際の理解を深めようと思い、マイニング難易度(difficulty)を決めるnBitsに …

仮想通貨全般
EOS Night Meetupにいってきた

今回は、以前からEOSに興味があったので EOS Night Meetupにいってきました。 暗号通 …