• 权限管理
    • 启动集群
    • 用户登陆
    • chaincode 部署
    • chaincode 调用
    • chaincode 查询
    • 区块信息查询

    权限管理

    权限管理机制是 hyperledger fabric 项目的一大特色。下面给出使用权限管理的一个应用案例。

    启动集群

    首先下载相关镜像。

    1. $ docker pull yeasy/hyperledger:latest
    2. $ docker tag yeasy/hyperledger:latest hyperledger/fabric-baseimage:latest
    3. $ docker pull yeasy/hyperledger-peer:latest
    4. $ docker pull yeasy/hyperledger-membersrvc:latest

    进入 hyperledger 项目,启动带成员管理的 PBFT 集群。

    1. $ git clone https://github.com/yeasy/docker-compose-files
    2. $ cd docker-compose-files/hyperledger/0.6/pbft
    3. $ docker-compose -f 4-peers-with-membersrvc.yml up

    用户登陆

    当启用了权限管理后,首先需要登录,例如以内置账户 jim 账户登录。

    登录 vp0,并执行登录命令。

    1. $ docker exec -it pbft_vp0_1 bash
    2. # peer network login jim
    3. 06:57:13.603 [networkCmd] networkLogin -> INFO 001 CLI client login...
    4. 06:57:13.603 [networkCmd] networkLogin -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/
    5. Enter password for user 'jim': 6avZQLwcUe9b
    6. 06:57:25.022 [networkCmd] networkLogin -> INFO 003 Logging in user 'jim' on CLI interface...
    7. 06:57:25.576 [networkCmd] networkLogin -> INFO 004 Storing login token for user 'jim'.
    8. 06:57:25.576 [networkCmd] networkLogin -> INFO 005 Login successful for user 'jim'.
    9. 06:57:25.576 [main] main -> INFO 006 Exiting.....

    也可以用 REST 方式:

    1. POST HOST:7050/registrar

    Request:

    1. {
    2. "enrollId": "jim",
    3. "enrollSecret": "6avZQLwcUe9b"
    4. }

    Response:

    1. {
    2. "OK": "User jim is already logged in."
    3. }

    chaincode 部署

    登录之后,chaincode 的部署、调用等操作与之前类似,只是需要通过 -u 选项来指定用户名。

    在 vp0 上执行命令:

    1. # peer chaincode deploy -u jim -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'
    2. 06:58:20.099 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token.
    3. 06:58:22.178 [chaincodeCmd] chaincodeDeploy -> INFO 002 Deploy result: type:GOLANG chaincodeID:<path:"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"init" args:"a" args:"100" args:"b" args:"200" >
    4. Deploy chaincode: ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539
    5. 06:58:22.178 [main] main -> INFO 003 Exiting.....

    记录下返回的 chaincode ID。

    1. # CC_ID=ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539

    此时,查询账户值应当为初始值。

    1. # peer chaincode query -u jim -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}'
    2. 07:28:39.925 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token.
    3. 07:28:40.281 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > secureContext:"jim" >
    4. Query Result: 100
    5. 07:28:40.281 [main] main -> INFO 003 Exiting.....

    也可以通过 REST 方式进行:

    1. POST HOST:7050/chaincode

    Request:

    1. {
    2. "jsonrpc": "2.0",
    3. "method": "deploy",
    4. "params": {
    5. "type": 1,
    6. "chaincodeID":{
    7. "path":"github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
    8. },
    9. "ctorMsg": {
    10. "function":"init",
    11. "args":["a", "1000", "b", "2000"]
    12. },
    13. "secureContext": "jim"
    14. },
    15. "id": 1
    16. }

    Response:

    1. {
    2. "jsonrpc": "2.0",
    3. "result": {
    4. "status": "OK",
    5. "message": "ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"
    6. },
    7. "id": 1
    8. }

    chaincode 调用

    在账户 a、b 之间进行转账 10 元的操作。

    1. # peer chaincode invoke -u jim -n ${CC_ID} -c '{"Function": "invoke", "Args": ["a", "b", "10"]}'
    2. 07:29:25.245 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token.
    3. 07:29:25.585 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Successfully invoked transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"invoke" args:"a" args:"b" args:"10" > secureContext:"jim" > (f8347e3b-7230-4561-9017-3946756a0bf4)
    4. 07:29:25.585 [main] main -> INFO 003 Exiting.....

    也可以通过 REST 方式进行:

    1. POST HOST:7050/chaincode

    Request:

    1. {
    2. "jsonrpc": "2.0",
    3. "method": "invoke",
    4. "params": {
    5. "type": 1,
    6. "chaincodeID":{
    7. "name":"980d4bb7f69578592e5775a6da86d81a221887817d7164d3e9d4d4df1c981440abf9a61417eaf8ad6f7fc79893da36de2cf4709131e9af39bca6ebc2e5a1cd9d"
    8. },
    9. "ctorMsg": {
    10. "function":"invoke",
    11. "args":["a", "b", "100"]
    12. },
    13. "secureContext": "jim"
    14. },
    15. "id": 3
    16. }

    Response:

    1. {
    2. "jsonrpc": "2.0",
    3. "result": {
    4. "status": "OK",
    5. "message": "66308740-a2c5-4a60-81f1-778dbed49cc3"
    6. },
    7. "id": 3
    8. }

    chaincode 查询

    查询 a 账户的余额。

    1. # peer chaincode query -u jim -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}'
    2. 07:29:55.844 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token.
    3. 07:29:56.198 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > secureContext:"jim" >
    4. Query Result: 90
    5. 07:29:56.198 [main] main -> INFO 003 Exiting.....

    也可以通过 REST 方式进行:

    1. POST HOST:7050/chaincode

    Request:

    1. {
    2. "jsonrpc": "2.0",
    3. "method": "query",
    4. "params": {
    5. "type": 1,
    6. "chaincodeID":{
    7. "name":"980d4bb7f69578592e5775a6da86d81a221887817d7164d3e9d4d4df1c981440abf9a61417eaf8ad6f7fc79893da36de2cf4709131e9af39bca6ebc2e5a1cd9d"
    8. },
    9. "ctorMsg": {
    10. "function":"query",
    11. "args":["a"]
    12. },
    13. "secureContext": "jim"
    14. },
    15. "id": 5
    16. }

    Response:

    1. {
    2. "jsonrpc": "2.0",
    3. "result": {
    4. "status": "OK",
    5. "message": "900"
    6. },
    7. "id": 5
    8. }

    区块信息查询

    URL:

    1. GET HOST:7050/chain/blocks/2

    Response:

    1. {
    2. "transactions": [
    3. {
    4. "type": 2,
    5. "chaincodeID": "EoABMjhiYjJiMjMxNjE3MWE3MDZiYjI4MTBlYzM1ZDA5NWY0MzA4NzdiZjQ0M2YxMDYxZWYwZjYwYmJlNzUzZWQ0NDA3MDBhNTMxMmMxNjM5MGQzYjMwMTk5ZmU5NDY1YzNiNzVkNTk0NDM1OGNhYWUwMWNhODFlZjI4MTI4YTFiZmI=",
    6. "payload": "Cp0BCAESgwESgAEyOGJiMmIyMzE2MTcxYTcwNmJiMjgxMGVjMzVkMDk1ZjQzMDg3N2JmNDQzZjEwNjFlZjBmNjBiYmU3NTNlZDQ0MDcwMGE1MzEyYzE2MzkwZDNiMzAxOTlmZTk0NjVjM2I3NWQ1OTQ0MzU4Y2FhZTAxY2E4MWVmMjgxMjhhMWJmYhoTCgZpbnZva2USAWESAWISAzEwMA==",
    7. "uuid": "2b3b6cf3-9887-4dd5-8f2e-3634ec9c719a",
    8. "timestamp": {
    9. "seconds": 1466577447,
    10. "nanos": 399637431
    11. },
    12. "nonce": "5AeA6S1odhPIDiGjFTFG8ttcihOoNNsh",
    13. "cert": "MIICPzCCAeSgAwIBAgIRAMndnS+Me0G6gs4J9/fb8HcwCgYIKoZIzj0EAwMwMTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMQwwCgYDVQQDEwN0Y2EwHhcNMTYwNjIyMDYzMzE4WhcNMTYwOTIwMDYzMzE4WjAxMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDDAKBgNVBAMTA2ppbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDLd2W8PxzgB4A85Re2x44BApbOGqP05tnkygbXSctLiqi5HVfwRAACS6znVA9+toni59Yy+XAH3w2offdjFW3mjgdwwgdkwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDBNBgYqAwQFBgcBAf8EQAfASTE6bZ0P5mrEzTa5r1UyKFv+dKezBiGU0V3l2iWzk9evlGMvaC2pwhEKfKDdKxs7YSMYe/7cLq/oF++GBVowSgYGKgMEBQYIBEBEO3TKXuORl5Geuco8Gnn5TkoIl4+b96aPGDGvKbmDjMXR9vEBuUXTnsbDL53j7kC8/XQs1kZboC1ojLeUSN03MAoGCCqGSM49BAMDA0kAMEYCIQCZqyANMFcu1WiMe2So0pC7eRU95F0+qUXLAKZsPWv/YQIhALmNaglP7CoMOe2qxehucmffDlu0BRLSYDHyV9xcxmkH",
    14. "signature": "MEYCIQDob3NqdrfwlSGhi+zz+Ypl7S9QQ07RIFr8nV92e8KDNgIhANIljz4tRS8vwQk01hTemNQFJX2zMI6DhSUFZivbbtoR"
    15. }
    16. ],
    17. "stateHash": "7YUoVvYnMLHbLf47uTixLtkjF6xM9DuvgSWC92MbOUzk09xhcRBBLZqe5FvJElgZemELBOcuIFnubL0LiGH0yw==",
    18. "previousBlockHash": "On4BlpqCYNpugUKluqvOcbvkr3TAQxmlISLdd6qrONtIgmQ4iUDeWxAA9lUCceZfF8tke8A0Wy7m9tksNpKodw==",
    19. "consensusMetadata": "CAI=",
    20. "nonHashData": {
    21. "localLedgerCommitTimestamp": {
    22. "seconds": 1466577447,
    23. "nanos": 653618964
    24. },
    25. "transactionResults": [
    26. {
    27. "uuid": "2b3b6cf3-9887-4dd5-8f2e-3634ec9c719a"
    28. }
    29. ]
    30. }
    31. }