オープンソースのブロックチェーン Hyperledger Fabric を試してみる の続き
Hyperledger Fabric の REST API を一通り試したときのメモです。
Bluemix 上の IBM Blockchain を使っています。
REST Endpoints
- Blockchain API
- GET /chain
- ブロックチェーンの現在の状態を取得するAPI
- GET /chain
- Block API
- GET /chain/blocks/{block-id}
- ブロックチェーンから特定のブロックの内容を取得するAPI
- GET /chain/blocks/{block-id}
- Transactions API
- GET /transactions/{UUID}
- ブロックチェーンから個々のトランザクションの内容を取得するAPI
- GET /transactions/{UUID}
- Network API
- GET /network/peers
- ピアノードの一覧と、それぞれのネットワークに関する情報を取得するAPI
- GET /network/peers
- Registrar API
- POST /registrar
- 認証局にユーザを登録・ローカルストレージに登録証明書を保存するAPI
- GET /registrar/{enrollmentID}
- 認証局にユーザが登録されているかどうかを確認するAPI
- DELETE /registrar/{enrollmentID}
- ローカルストレージからユーザのログイントークンを削除するAPI
- GET /registrar/{enrollmentID}/ecert
- ローカルストレージからユーザの登録証明書を取得するAPI
- GET /registrar/{enrollmentID}/tcert
- 認証局に登録されているユーザのトランザクション証明書を取得するAPI
- POST /registrar
- Chaincode API
- POST /chaincode
- チェインコードを設置・実行・参照するAPI
- POST /chaincode
Blockchain API
GET /chain
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/chain"
{
"height": 5,
"currentBlockHash": "RWVzXnp4wuXdLSxeBTE93GM62vXyld2D6HakM/nYdXQQi7NcEW6AfFdkaPI7E+RWWS5Ma1RtEqFnbfo+3dtv2Q==",
"previousBlockHash": "YCSaBj8URoEpNwTgRqqHFakvXX1POR2GELwHjtJNqLd1hAPCho0vAXvdgBHYijTaEQi6jeCNNFm9KWlJC1pqEw=="
}
- ブロックチェーンの現在の状態を取得するAPI
-
height
: ブロック数 -
currentBlockHash
: 現在のブロックのハッシュ値。次のブロックを繋げる際に使われる? -
previousBlockHash
: 一つ前のブロックのハッシュ値。現在のブロックに使われている
-
Block API
GET /chain/blocks/{block-id}
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/chain/blocks/1"
{
"transactions": [
{
"type": 1,
"chaincodeID": "CkpodHRwczovL2dpdGh1Yi5jb20vbWFzdGVyRGV2MTk4NS9oeXBlcmxlZGdlcl9jaGFpbmNvZGUvY2hhaW5jb2RlX2V4YW1wbGUwMhKAATcyYzNjMzk1NzA3YmU3ZGE2ZTI2ODQxYmI5NDc1ZWM5NmFjMDY2ODdjZGY1ZWE1NTc5NjIwMjgwMWU2NThkMGJhZmUyNTcxMDllYzdlZWJkMTgxNGNhNWM3NmI4YmU1ZjAzZDMyMzNiNzA0ZmQyOTdlOGZjYjgxZGJhYjczMDVl",
"payload": "CuwBCAESzwEKSmh0dHBzOi8vZ2l0aHViLmNvbS9tYXN0ZXJEZXYxOTg1L2h5cGVybGVkZ2VyX2NoYWluY29kZS9jaGFpbmNvZGVfZXhhbXBsZTAyEoABNzJjM2MzOTU3MDdiZTdkYTZlMjY4NDFiYjk0NzVlYzk2YWMwNjY4N2NkZjVlYTU1Nzk2MjAyODAxZTY1OGQwYmFmZTI1NzEwOWVjN2VlYmQxODE0Y2E1Yzc2YjhiZTVmMDNkMzIzM2I3MDRmZDI5N2U4ZmNiODFkYmFiNzMwNWUaFgoEaW5pdBIBYRIDMTAwEgFiEgMyMDA=",
"uuid": "72c3c395707be7da6e26841bb9475ec96ac06687cdf5ea55796202801e658d0bafe257109ec7eebd1814ca5c76b8be5f03d3233b704fd297e8fcb81dbab7305e",
"timestamp": {
"seconds": 1476936384,
"nanos": 762271536
},
"nonce": "PoSNNChCKd07Zs6yhq1rELq5Ccl3llQc",
"cert": "MIICTjCCAfWgAwIBAgIQDGBmkNuYRHSliV7jSnH1MjAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYxMDIwMDQwNTI0WhcNMTcwMTE4MDQwNTI0WjA7MQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMR4wHAYDVQQDDBVkYXNoYm9hcmR1c2VyX3R5cGUxXzAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQlhbRj1/FEdRQbqbMut5dfzX13A1lXzlxIuCIvFmR8b9/nHVuLJck8HIizuHtsqkFq4vDqPqaNrBoW3U/fi+G7o4HsMIHpMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwTQYGKgMEBQYHAQH/BEA187+DA+DNcWcGuId+ULDeX6sliQMD01ikz8XgHme7nhaqLDMMcTOLQy5g552aH1SrdM4VBSLhtYlVCMMlWn89MFoGBioDBAUGCARQOI/vAW5lmwAc3GcBU9R97IOGW9EKKPciV4Ov/gIHL2RDBM9REJ4ErvaafN7GlYy0E3ZwsIQNr4qM0QA3ojMid1NITNXH/y/UMykyzvY/ATQwCgYIKoZIzj0EAwMDRwAwRAIgKtqz/xRQUgKrv48EiuHS8XzMErYckGvAWPirTsh8PFUCIDZF/lAbj9uW2oq5FiwL47R4ALPWMuQsrcPBh9Vx2JhG",
"signature": "MEQCIFPvLCoL6PogUpLxUyUs8zZ70y/KnbBnEiEvuwhgDTbtAiBwJNC5tjQzaRufdV4dGMaGRl9lzlxTgQm/2t5ejlQogA=="
}
],
"stateHash": "7QPE8yCGIJqZu/ts70iG2v5ab4HqMYHHA5u345gix/sGcVt/nsrbEXodPJvJj6uy/MwH44l3XAHCSJZm0xRA6Q==",
"previousBlockHash": "RrndKwuojRMjOz/rdD7rJD/NUupiuBuCtQwnZG7Vdi/XXcTd2MDyAMsFAZ1ntZL2/IIcSUeatIZAKS6ss7fEvg==",
"consensusMetadata": "CAE=",
"nonHashData": {
"localLedgerCommitTimestamp": {
"seconds": 1476936411,
"nanos": 26062785
},
"transactionResults": [
{
"uuid": "72c3c395707be7da6e26841bb9475ec96ac06687cdf5ea55796202801e658d0bafe257109ec7eebd1814ca5c76b8be5f03d3233b704fd297e8fcb81dbab7305e"
}
]
}
}
- ブロックチェーンから特定のブロックの内容を取得するAPI
-
transacitons
; トランザクションの配列-
type
: トランザクションのタイプ。['UNDEFINED', 'CHAINCODE_DEPLOY', 'CHAINCODE_INVOKE', 'CHAINCODE_QUERY', 'CHAINCODE_TERMINATE']
の添字が返ってくる模様 -
chaincodeID
: チェーンコードID -
payload
: チェーンコードの関数を実行するためのペイロード -
uuid
: トランザクションを特定する一意の UUID -
timestamp
: チェーンコードが実行可能になった時刻 -
nonce
: 乱数 -
cert
: このトランザクションを送信したクライアントの証明書 -
signature
: このトランザクションを送信したクライアントの署名
-
-
timestamp
: ブロックが作成された時刻 -
previousBlockHash
: 前のブロックのハッシュ値 -
consensusMetadata
: コンセンサスのためのメタデータ -
nonHashData
: ブロックハッシュに含まれないブロックのデータ
-
- ブロックチェーンはブロックの連なり
- ブロックは複数の取引(トランザクション)のあつまり
- ブロックは時系列で繋がっている
- ブロックのデータには一つ前のブロックのハッシュも含まれる
- ブロックのデータはハッシュ化され、次のブロックを作るのに使われる
- refs: 5分で分かるブロックチェーンの基本的な仕組み http://www.slideshare.net/cookle/5-58379474
- ネットワークタブを開くと、チェインコードが順に展開されているのが分かる
- 各検証ピアにデータが同期されている
- ブロックの中に複数トランザクションが入る状況はどんなときか?
- Fabric におけるトランザクションは Chaincode のデプロイと Chaincode の実行の2種類しかない
- Chaincode を作るとトランザクションが作成され、同時にブロックも作られる(ように見える)
- つまり Chaincode とトランザクションは1対1、かつブロックに含まれるトランザクションも常に1つのみ?
- ブロックハッシュはどこで使うのか?
- 次のブロックを追加するとき?
- トランザクションの
uuid
の形式はトランザクションの種類によって異なる?- Chaincode のデプロイ(Deployment Transaction): ハッシュに似たID
- Chaincode の実行(Invocation Transaction): UUID
- (
uuid
なのに UUID じゃない...)
Transaction API
GET /transactions/{UUID}
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/transactions/72c3c395707be7da6e26841bb9475ec96ac06687cdf5ea55796202801e658d0bafe257109ec7eebd1814ca5c76b8be5f03d3233b704fd297e8fcb81dbab7305e"
{
"type": 1,
"chaincodeID": "CkpodHRwczovL2dpdGh1Yi5jb20vbWFzdGVyRGV2MTk4NS9oeXBlcmxlZGdlcl9jaGFpbmNvZGUvY2hhaW5jb2RlX2V4YW1wbGUwMhKAATcyYzNjMzk1NzA3YmU3ZGE2ZTI2ODQxYmI5NDc1ZWM5NmFjMDY2ODdjZGY1ZWE1NTc5NjIwMjgwMWU2NThkMGJhZmUyNTcxMDllYzdlZWJkMTgxNGNhNWM3NmI4YmU1ZjAzZDMyMzNiNzA0ZmQyOTdlOGZjYjgxZGJhYjczMDVl",
"payload": "CuwBCAESzwEKSmh0dHBzOi8vZ2l0aHViLmNvbS9tYXN0ZXJEZXYxOTg1L2h5cGVybGVkZ2VyX2NoYWluY29kZS9jaGFpbmNvZGVfZXhhbXBsZTAyEoABNzJjM2MzOTU3MDdiZTdkYTZlMjY4NDFiYjk0NzVlYzk2YWMwNjY4N2NkZjVlYTU1Nzk2MjAyODAxZTY1OGQwYmFmZTI1NzEwOWVjN2VlYmQxODE0Y2E1Yzc2YjhiZTVmMDNkMzIzM2I3MDRmZDI5N2U4ZmNiODFkYmFiNzMwNWUaFgoEaW5pdBIBYRIDMTAwEgFiEgMyMDAa442cAR+LCAAACW6IAP/s/Xl720aSOI7vv+KrQLi/ZEmHok7bM5po95ElO9FnYlsjyUnm5/HjByRBCmsSYABQEkfr9/6tqy8cPHQ5BzkZiwS6q6urq6urq6ur0qS7MQizi0mn3Y1HGyM/zYLkKLjc+utfnm5cTMdBMgx6gyD52L3ww6gb94IN/e1jcO2PxsNgc7vsWXsQ/wd/Nrc2N5/t7v7HJn9yf7d2tzd31DN+vrP5dOf5f3ib//EIn0ma+Qk0f1c4+c79Tj4bT2o/ht0gSoOel8VedhF4B2O/C3/O4n525SeB9yqeRD0/C+PIaxycvWp68DNIvDgKanHijWIo0o2jLAk7kwweDBmc5w.........",
"uuid": "72c3c395707be7da6e26841bb9475ec96ac06687cdf5ea55796202801e658d0bafe257109ec7eebd1814ca5c76b8be5f03d3233b704fd297e8fcb81dbab7305e",
"timestamp": {
"seconds": 1476936384,
"nanos": 762271536
},
"nonce": "PoSNNChCKd07Zs6yhq1rELq5Ccl3llQc",
"cert": "MIICTjCCAfWgAwIBAgIQDGBmkNuYRHSliV7jSnH1MjAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYxMDIwMDQwNTI0WhcNMTcwMTE4MDQwNTI0WjA7MQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMR4wHAYDVQQDDBVkYXNoYm9hcmR1c2VyX3R5cGUxXzAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQlhbRj1/FEdRQbqbMut5dfzX13A1lXzlxIuCIvFmR8b9/nHVuLJck8HIizuHtsqkFq4vDqPqaNrBoW3U/fi+G7o4HsMIHpMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwTQYGKgMEBQYHAQH/BEA187+DA+DNcWcGuId+ULDeX6sliQMD01ikz8XgHme7nhaqLDMMcTOLQy5g552aH1SrdM4VBSLhtYlVCMMlWn89MFoGBioDBAUGCARQOI/vAW5lmwAc3GcBU9R97IOGW9EKKPciV4Ov/gIHL2RDBM9REJ4ErvaafN7GlYy0E3ZwsIQNr4qM0QA3ojMid1NITNXH/y/UMykyzvY/ATQwCgYIKoZIzj0EAwMDRwAwRAIgKtqz/xRQUgKrv48EiuHS8XzMErYckGvAWPirTsh8PFUCIDZF/lAbj9uW2oq5FiwL47R4ALPWMuQsrcPBh9Vx2JhG",
"signature": "MEQCIFPvLCoL6PogUpLxUyUs8zZ70y/KnbBnEiEvuwhgDTbtAiBwJNC5tjQzaRufdV4dGMaGRl9lzlxTgQm/2t5ejlQogA=="
}
- ブロックチェーンから個々のトランザクションの内容を取得するAPI
- Block の
transactions
と内容は同じ
- Block の
- payload の長さのみ異なるのはなぜか?
- Block の
transaction
が省略されている? - それをデコードすると3MBになる。なぜか?
- ステートや実行環境も含む?
- Block の
Network API
GET /network/peers
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/network/peers"
{
"peers": [
{
"ID": {
"name": "vp3"
},
"address": "1ba11756fe4d445e8f380701269a1075-vp3.us.blockchain.ibm.com:30304",
"type": 1,
"pkiID": "1B9LHNu3D8B4cO3WYJ+prpLoOCoGOzG308BvYkGCqKo="
},
{
"ID": {
"name": "vp2"
},
"address": "1ba11756fe4d445e8f380701269a1075-vp2.us.blockchain.ibm.com:30304",
"type": 1,
"pkiID": "0KQ+J9WBH4cpQiljmoOeLWHwkgQzQ077JlR3J6fnu4c="
},
{
"ID": {
"name": "vp0"
},
"address": "1ba11756fe4d445e8f380701269a1075-vp0.us.blockchain.ibm.com:30304",
"type": 1,
"pkiID": "6D5vTiGCOXVs0Q1IiLNprcC/xJ1PFvFCxdHYRroz2vg="
},
{
"ID": {
"name": "vp1"
},
"address": "1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:30304",
"type": 1,
"pkiID": "Gvu6b/ihMb6Ygq320yMjxkatkl5eOCaTFuiWhUA0yrI="
}
]
}
- ピアノードの一覧と、それぞれのネットワークに関する情報を取得するAPI
-
peers.ID.name
はユニークな値 -
address
は grpc の開いているポートであり、REST API や CLI の受け口となるポートとは別 -
type
はピアのタイプ。検証ピアかそうでないか。['UNDEFINED', 'VALIDATOR', 'NON_VALIDATOR']
の添字 -
pkiID
はネットワークピア向けの PKI ID、ネットワークピアにもPKIがある
Registrar API
- Registrar API
- POST /registrar
- DELETE /registrar/{enrollmentID}
- GET /registrar/{enrollmentID}
- GET /registrar/{enrollmentID}/ecert
- GET /registrar/{enrollmentID}/tcert
POST /registrar
curl -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d '{"enrollId":"admin","enrollSecret":"504443dd0f"}' https://4c78f026da5c4b5c86f9d0d216d2eb8e-vp0.us.blockchain.ibm.com:444/registrar
{"OK": "Login successful for user 'admin'."}
- 認証局にユーザを登録・ローカルストレージに登録証明書を保存するAPI
- 検証ピアごとにログインできる
- ログインには enrollId と enrollSecret が必要
- ログインするとログイントークンが作成され、そのトークンを元にメンバーシップサービスで証明書を作成する
- ログインするとトランザクションを実行できるようになる
GET /registrar/{enrollmentID}
// ログイン済
curl -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' https://4c78f026da5c4b5c86f9d0d216d2eb8e-vp0.us.blockchain.ibm.com:444/registrar/admin
{"OK": "User admin is already logged in."}
// 未ログイン
curl -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' https://4c78f026da5c4b5c86f9d0d216d2eb8e-vp1.us.blockchain.ibm.com:444/registrar/admin
{"Error": "User admin must log in."}
- 認証局にユーザが登録されているかどうかを確認するAPI
- 検証ピアにおけるユーザのログイン状態がわかる
- 参照時はメンバーシップサービスでは何もしない?
- ログは出ない
DELETE /registrar/{enrollmentID}
curl -X DELETE -H 'Accept: application/json' -H 'Content-Type: application/json' https://4c78f026da5c4b5c86f9d0d216d2eb8e-vp1.us.blockchain.ibm.com:444/registrar/user_type1_0
{"OK": "Deleted login token and directory for user user_type1_0."}
- ローカルストレージからユーザのログイントークンを削除するAPI
- 検証ピアにおけるユーザのログイントークンを削除する
- そのユーザでログインしていないときは削除されない
- 削除すると検証サーバにあるローカルストレージからログイントークンが削除される
- ログイントークンが削除されるとログイン状態を参照してもエラーになる
- ログイントークンが削除されるとトランザクションが実行できない
- ログイントークンが削除されると同じユーザにログインしようとしてもエラーになる
- 一度削除するとマッチングできなくなる
- 削除時はメンバーシップサービスは何もしない?
- ログは出ない
- 削除後にログインしようとすると
- CA はトークンを受けて証明書を作ろうとする
- 証明書を作れずにエラーになる
- 存在しないユーザでログインすると登録されるのか?
-
{"Error": "rpc error: code = 2 desc = 'Identity or token does not match.'"}
になる
-
- 複数ユーザでログインしても保持される
- どこかでログインすると別のピアサーバではログインできなくなる
- 他のサーバでログインしている間はログインできないのか?
- あるいはログイン情報は一回きりしか使えないか?
- ユーザの登録はどうやるか?
- NodeSDK であれば可能。REST API では用意されていない
GET /registrar/{enrollmentID}/ecert
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/registrar/WebAppAdmin/ecert"
{
"OK": "-----BEGIN+CERTIFICATE-----%0AMIIBpTCCAUugAwIBAgIBATAKBggqhkjOPQQDAzApMQswCQYDVQQGEwJVUzEMMAoG%0AA1UEChMDSUJNMQwwCgYDVQQDEwNlY2EwHhcNMTYxMDIwMDQzNTUzWhcNMTcwMTE4%0AMDQzNTUzWjA9MQswCQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMSAwHgYDVQQDDBdX%0AZWJBcHBBZG1pblxncm91cDFcMDAwMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA%0ABDKgvGGxWeL27SO8Z5vjk7r1Tx3DX7ZOJJKt2p5lM9cIzsdy5cPCskmmW0RbZaod%0AghK7GnL4G6RgQIPfeElQCqSjUDBOMA4GA1UdDwEB%2FwQEAwIHgDAMBgNVHRMBAf8E%0AAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwDgYGUQMEBQYHAQH%2F%0ABAExMAoGCCqGSM49BAMDA0gAMEUCIQCWWJz7H6xH3Fqh6vpShbMv%2BNabOvsFSzJV%0Ast0a9l3CaAIgXK28xUU08SauPNv%2F1kFgV4SFh44%2BdCbTtKx5c3VifEU%3D%0A-----END+CERTIFICATE-----%0A"
}
- ローカルストレージからユーザの登録証明書を取得するAPI
GET /registrar/{enrollmentID}/tcert
curl -X GET --header "Accept: application/json" "https://1ba11756fe4d445e8f380701269a1075-vp1.us.blockchain.ibm.com:444/registrar/WebAppAdmin/tcert?count=2"
{
"OK": [
"-----BEGIN+CERTIFICATE-----%0AMIICNTCCAdugAwIBAgIQOwpkin7NT%2F%2BOWj0SDH4RkzAKBggqhkjOPQQDAzApMQsw%0ACQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYxMDIw%0AMDQzNjI4WhcNMTcwMTE4MDQzNjI4WjAxMQswCQYDVQQGEwJVUzEMMAoGA1UEChMD%0ASUJNMRQwEgYDVQQDEwtXZWJBcHBBZG1pbjBZMBMGByqGSM49AgEGCCqGSM49AwEH%0AA0IABDQ7QFZnqd2mqu1fBpoGUvReSssESyaSVXO1xtCLgQ1x0ub51XCr0WFg68Va%0AxTO%2B1%2BWL4RgX8EsZhRTljrDD67OjgdwwgdkwDgYDVR0PAQH%2FBAQDAgeAMAwGA1Ud%0AEwEB%2FwQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDBNBgYqAwQF%0ABgcBAf8EQE8Rpgb3CTbF9tsbPqO6EF7IAT9V9IJkfqEnRftvMM6Vb0iRKVuTVcKn%0AML9yS5gJENqrRPxIkJb%2Bd8xtn7Y8pgwwSgYGKgMEBQYIBEBc95kT9B1FCV2WfMk9%0AHk8V6EJ8kJRUtGzETeyURBUrYFblotI2DGFb%2BEKoAvGF%2BIcQ9ZSqamn8vBXvaIMx%0Ac28vMAoGCCqGSM49BAMDA0gAMEUCIFnolGV4nt9qk0Jy7hvBoxpT0L1ha4NOZzum%0AWDVytOn8AiEA1SEakxfuFADI2sex5gmleC%2F1JTe4drOBawcQ97zi%2FrU%3D%0A-----END+CERTIFICATE-----%0A",
"-----BEGIN+CERTIFICATE-----%0AMIICNTCCAdugAwIBAgIQOwpkin7NT%2F%2BOWj0SDH4RkzAKBggqhkjOPQQDAzApMQsw%0ACQYDVQQGEwJVUzEMMAoGA1UEChMDSUJNMQwwCgYDVQQDEwN0Y2EwHhcNMTYxMDIw%0AMDQzNjI4WhcNMTcwMTE4MDQzNjI4WjAxMQswCQYDVQQGEwJVUzEMMAoGA1UEChMD%0ASUJNMRQwEgYDVQQDEwtXZWJBcHBBZG1pbjBZMBMGByqGSM49AgEGCCqGSM49AwEH%0AA0IABDQ7QFZnqd2mqu1fBpoGUvReSssESyaSVXO1xtCLgQ1x0ub51XCr0WFg68Va%0AxTO%2B1%2BWL4RgX8EsZhRTljrDD67OjgdwwgdkwDgYDVR0PAQH%2FBAQDAgeAMAwGA1Ud%0AEwEB%2FwQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDBNBgYqAwQF%0ABgcBAf8EQE8Rpgb3CTbF9tsbPqO6EF7IAT9V9IJkfqEnRftvMM6Vb0iRKVuTVcKn%0AML9yS5gJENqrRPxIkJb%2Bd8xtn7Y8pgwwSgYGKgMEBQYIBEBc95kT9B1FCV2WfMk9%0AHk8V6EJ8kJRUtGzETeyURBUrYFblotI2DGFb%2BEKoAvGF%2BIcQ9ZSqamn8vBXvaIMx%0Ac28vMAoGCCqGSM49BAMDA0gAMEUCIFnolGV4nt9qk0Jy7hvBoxpT0L1ha4NOZzum%0AWDVytOn8AiEA1SEakxfuFADI2sex5gmleC%2F1JTe4drOBawcQ97zi%2FrU%3D%0A-----END+CERTIFICATE-----%0A"
]
}
- 認証局に登録されているユーザのトランザクション証明書を取得するAPI
- ワンタイム証明書であり、トランザクションに使われる
-
count
の数だけ、同じ証明書が返ってくる
Chaincode API
POST /chaincode
echo '{
"jsonrpc": "2.0",
"method": "deploy",
"params": {
"type": 1,
"chaincodeID": {
"path": "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
},
"ctorMsg": {
"function": "init",
"args": ["a", "1000", "b", "2000"]
},
"secureContext": "admin"
},
"id": 1
}' |
curl -X POST -H 'Content-Type: application/json' -d @- https://1ba11756fe4d445e8f380701269a1075-vp0.us.blockchain.ibm.com:444/chaincode
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "28bb2b2316171a706bb2810ec35d095f430877bf443f1061ef0f60bbe753ed440700a5312c16390d3b30199fe9465c3b75d5944358caae01ca81ef28128a1bfb"
},
"id": 1
}
echo '{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID": {
"name": "28bb2b2316171a706bb2810ec35d095f430877bf443f1061ef0f60bbe753ed440700a5312c16390d3b30199fe9465c3b75d5944358caae01ca81ef28128a1bfb"
},
"ctorMsg": {
"function": "invoke",
"args": [ "a", "b", "100" ]
},
"secureContext": "{{enroll_id}}"
},
"id": 1
}' |
curl -X POST -H 'Content-Type: application/json' -d @- https://1ba11756fe4d445e8f380701269a1075-vp0.us.blockchain.ibm.com:444/chaincode
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "902bcb1f-809e-4a1b-9a3f-3c355cad7a7c"
},
"id": 1
}
echo '{
"jsonrpc": "2.0",
"method": "query",
"params": {
"type": 1,
"chaincodeID": {
"name": "28bb2b2316171a706bb2810ec35d095f430877bf443f1061ef0f60bbe753ed440700a5312c16390d3b30199fe9465c3b75d5944358caae01ca81ef28128a1bfb"
},
"ctorMsg": {
"function": "query",
"args": [ "a" ]
},
"secureContext": "{{enroll_id}}"
},
"id": 1
}' |
curl -X POST -H 'Content-Type: application/json' -d @- https://1ba11756fe4d445e8f380701269a1075-vp0.us.blockchain.ibm.com:444/chaincode
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "900"
},
"id": 1
}
- Chaincode API は三種類ある
- deploy(設置)
- invoke(実行)
- query(参照)
-
type
はチェインコードに使用されている開発言語。['UNDEFINED = 0', 'GOLANG = 1', 'NODE = 2']
の添字 -
chaincodeID.name
は invoke と query のリクエストで必ず必要になる- deploy 後のレスポンスとしてresultで返ってくる値が Chaincode ID になる
- deploy には トランザクション UUID はない
- invoke するとトランザクション UUID が返ってくる
- チェインコード内の init, invoke, query 関数は deploy, invoke, query と1対1
- チェインコードの書き方が分かる: https://github.com/IBM-Blockchain/learn-chaincode
- query は block が増えない、トランザクションは作成しない
- デプロイされたチェインコードの実体はどこに置かれるか?
- 検証ピア?レッジャー上?
- 他のピアで deploy されたら他のピアで invoke できるため、Chaincode は何らかの方法で共有されている
- コードの実行結果はどこか?
- 実行結果には他のピアの実行結果が引き継がれるため、データも何らかの方法で共有されている
- レッジャー上にすべて記録されているためそこから計算?
- Fabric にはワールドステートという概念があり、そこにトランザクション結果を保持する