-
9.3 Fabric v0.6
-
Fabric 目前的稳定版本为 v0.6,最新的版本 1.0 还在演进中,即将发布。
v0.6 的架构相对简单,适合作为实验或 PoC 场景使用。
一.安装和部署
如果是初次接触 Hyperledger Fabric 项目,推荐采用如下的步骤,基于 Docker-Compose 的一键部署。
官方文档现在也完善了安装部署的步骤,具体可以参考代码 doc 目录下内容。
动手前,建议适当了解一些 Docker 相关知识。
安装 Docker
Docker 支持 Linux 常见的发行版,如 Redhat/Centos/Ubuntu 等。$ curl -fsSL https://get.docker.com/ | sh
以 Ubuntu 14.04 为例,安装成功后,修改 Docker 服务配置(/etc/default/docker 文件)。
DOCKER_OPTS="$DOCKER_OPTS -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --api-cors-header='*'"
重启 Docker 服务。
$ sudo service docker restart
Ubuntu 16.04 中默认采用了 systemd 管理启动服务,Docker 配置文件在 /etc/systemd/system/docker.service.d/override.conf。
修改后,需要通过如下命令重启 Docker 服务。
$ sudo systemctl daemon-reload $ sudo systemctl restart docker.service
安装 docker-compose
首先,安装 python-pip 软件包。
$ sudo aptitude install python-pip
安装 docker-compose(推荐为 1.7.0 及以上版本)。
$ sudo pip install docker-compose>=1.7.0
下载镜像
目前 1.0 代码还没有正式发布,推荐使用 v0.6 分支代码进行测试。
下载相关镜像,并进行配置:
$ docker pull yeasy/hyperledger-fabric:0.6-dp \ && docker pull yeasy/hyperledger-fabric-peer:0.6-dp \ && docker pull yeasy/hyperledger-fabric-base:0.6-dp \ && docker pull yeasy/blockchain-explorer:latest \ && docker tag yeasy/hyperledger-fabric-peer:0.6-dp hyperledger/fabric-peer \ && docker tag yeasy/hyperledger-fabric-base:0.6-dp hyperledger/fabric-baseimage \ && docker tag yeasy/hyperledger-fabric:0.6-dp hyperledger/fabric-membersrvc
也可以使用 官方仓库 中的镜像。
$ docker pull hyperledger/fabric-peer:x86_64-0.6.1-preview \ && docker pull hyperledger/fabric-membersrvc:x86_64-0.6.1-preview \ && docker pull yeasy/blockchain-explorer:latest \ && docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-peer \ && docker tag hyperledger/fabric-peer:x86_64-0.6.1-preview hyperledger/fabric-baseimage \ && docker tag hyperledger/fabric-membersrvc:x86_64-0.6.1-preview hyperledger/fabric-membersrvc
之后,用户可以选择采用不同的一致性机制,包括 noops、pbft 两类。
使用 noops 模式
noops 默认没有采用 consensus 机制,1 个节点即可,可以用来进行快速测试。
$ docker run --name=vp0 \ --restart=unless-stopped \ -it \ -p 7050:7050 \ -p 7051:7051 \ -v /var/run/docker.sock:/var/run/docker.sock \ -e CORE_PEER_ID=vp0 \ -e CORE_PEER_ADDRESSAUTODETECT=true \ -e CORE_NOOPS_BLOCK_WAIT=10 \ hyperledger/fabric-peer:latest peer node start
使用 PBFT 模式
PBFT 是经典的分布式一致性算法,也是 hyperledger 目前最推荐的算法,该算法至少需要 4 个节点。
首先,下载 Compose 模板文件。
$ git clone https://github.com/yeasy/docker-compose-files
进入 hyperledger/0.6/pbft 目录,查看包括若干模板文件,功能如下:
4-peers.yml: 启动 4 个 PBFT peer 节点。
4-peers-with-membersrvc.yml: 启动 4 个 PBFT peer 节点 + 1 个 CA 节点,并启用 CA 功能。
4-peers-with-explorer.yml: 启动 4 个 PBFT peer 节点 + 1 个 Blockchain-explorer,可以通过 Web 界面监控集群状态。
4-peers-with-membersrvc-explorer.yml: 启动 4 个 PBFT peer 节点 + 1 个 CA 节点 + 1 个 Blockchain-explorer,并启用 CA 功能。
例如,快速启动一个 4 个 PBFT 节点的集群。
$ docker-compose -f 4-peers.yml up
多物理节点部署
上述方案的典型场景是单物理节点上部署多个 Peer 节点。如果要扩展到多物理节点,需要容器云平台的支持,如 Swarm 等。
当然,用户也可以分别在各个物理节点上通过手动启动容器的方案来实现跨主机组网,每个物理节点作为一个 peer 节点。
首先,以 4 节点下的 PBFT 模式为例,配置 4 台互相连通的物理机,分别按照上述步骤配置 Docker,下载镜像。
4 台物理机分别命名为 vp0 ~ vp3。
vp0
vp0 作为初始的探测节点。
$ docker run --name=vp0 \ --net="host" \ --restart=unless-stopped \ -it --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -e CORE_PEER_ID=vp0 \ -e CORE_PBFT_GENERAL_N=4 \ -e CORE_LOGGING_LEVEL=debug \ -e CORE_PEER_ADDRESSAUTODETECT=true \ -e CORE_PEER_NETWORKID=dev \ -e CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft \ -e CORE_PBFT_GENERAL_MODE=batch \ -e CORE_PBFT_GENERAL_TIMEOUT_REQUEST=10s \ hyperledger/fabric-peer:latest peer node start
vp1 ~ vp3
以 vp1 为例,假如 vp0 的地址为 10.0.0.1。
$ NAME=vp1 $ ROOT_NODE=10.0.0.1 $ docker run --name=${NAME} \ --net="host" \ --restart=unless-stopped \ -it --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -e CORE_PEER_ID=${NAME} \ -e CORE_PBFT_GENERAL_N=4 \ -e CORE_LOGGING_LEVEL=debug \ -e CORE_PEER_ADDRESSAUTODETECT=true \ -e CORE_PEER_NETWORKID=dev \ -e CORE_PEER_VALIDATOR_CONSENSUS_PLUGIN=pbft \ -e CORE_PBFT_GENERAL_MODE=batch \ -e CORE_PBFT_GENERAL_TIMEOUT_REQUEST=10s \ -e CORE_PEER_DISCOVERY_ROOTNODE=${ROOT_NODE}:7051 \ hyperledger/fabric-peer:latest peer node start
服务端口
Hyperledger 默认监听的服务端口包括:
7050: REST 服务端口,推荐 NVP 节点开放,0.6 之前版本中为 5000;
7051:peer gRPC 服务监听端口,0.6 之前版本中为 30303;
7052:peer CLI 端口,0.6 之前版本中为 30304;
7053:peer 事件服务端口,0.6 之前版本中为 31315;
7054:eCAP
7055:eCAA
7056:tCAP
7057:tCAA
7058:tlsCAP
7059:tlsCAA
二.使用 chaincode
下面演示 example02 chaincode,完成两方(如 a 和 b)之间进行价值的转移。
部署 chaincode
集群启动后,进入一个 VP 节点。以 pbft 模式为例,节点名称为 pbft_vp0_1。$ docker exec -it pbft_vp0_1 bash
部署 chaincode example02。
$ peer chaincode deploy -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' 03:08:44.740 [chaincodeCmd] chaincodeDeploy -> INFO 001 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" > Deploy chaincode: ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 03:08:44.740 [main] main -> INFO 002 Exiting.....
返回 chaincode id 为 ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539,后面将用这个 id 来标识这次交易。为了方便,把它记录到环境变量 CC_ID 中。
$ CC_ID="ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539"
部署成功后,系统中会自动生成几个 chaincode 容器,例如:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e86c26bad76f dev-vp1-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 "/opt/gopath/bin/ee5b" 2 minutes ago Up 2 minutes dev-vp1-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 597ebaf929a0 dev-vp2-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 "/opt/gopath/bin/ee5b" 2 minutes ago Up 2 minutes dev-vp2-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 8748a3b47312 dev-vp3-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 "/opt/gopath/bin/ee5b" 2 minutes ago Up 2 minutes dev-vp3-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 cf6e762f6a2e dev-vp0-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 "/opt/gopath/bin/ee5b" 2 minutes ago Up 2 minutes dev-vp0-ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539
查询 chaincode
查询 a 手头的价值,为初始值 100。
$ peer chaincode query -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}' 03:22:31.420 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > > Query Result: 100 03:22:31.420 [main] main -> INFO 002 Exiting.....
a 向 b 转账 10 元。
$ peer chaincode invoke -n ${CC_ID} -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' 03:22:57.345 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Successfully invoked transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"invoke" args:"a" args:"b" args:"10" > > (fc298ffb-c763-4ed0-9da2-072de2ab20b1) 03:22:57.345 [main] main -> INFO 002 Exiting.....
查询 a 手头的价值,为新的值 90。
$ peer chaincode query -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}' 03:23:33.045 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > > Query Result: 90 03:23:33.045 [main] main -> INFO 002 Exiting.....
三.权限管理
权限管理机制是 hyperledger fabric 项目的一大特色。下面给出使用权限管理的一个应用案例。
启动集群
首先下载相关镜像。
$ docker pull yeasy/hyperledger:latest $ docker tag yeasy/hyperledger:latest hyperledger/fabric-baseimage:latest $ docker pull yeasy/hyperledger-peer:latest $ docker pull yeasy/hyperledger-membersrvc:latest
进入 hyperledger 项目,启动带成员管理的 PBFT 集群。
$ git clone https://github.com/yeasy/docker-compose-files $ cd docker-compose-files/hyperledger/0.6/pbft $ docker-compose -f 4-peers-with-membersrvc.yml up
用户登陆
当启用了权限管理后,首先需要登录,例如以内置账户 jim 账户登录。
登录 vp0,并执行登录命令。
$ docker exec -it pbft_vp0_1 bash # peer network login jim 06:57:13.603 [networkCmd] networkLogin -> INFO 001 CLI client login... 06:57:13.603 [networkCmd] networkLogin -> INFO 002 Local data store for client loginToken: /var/hyperledger/production/client/ Enter password for user 'jim': 6avZQLwcUe9b 06:57:25.022 [networkCmd] networkLogin -> INFO 003 Logging in user 'jim' on CLI interface... 06:57:25.576 [networkCmd] networkLogin -> INFO 004 Storing login token for user 'jim'. 06:57:25.576 [networkCmd] networkLogin -> INFO 005 Login successful for user 'jim'. 06:57:25.576 [main] main -> INFO 006 Exiting.....
也可以用 REST 方式:
POST HOST:7050/registrar
Request:
{ "enrollId": "jim", "enrollSecret": "6avZQLwcUe9b" }
Response:
{ "OK": "User jim is already logged in." }
chaincode 部署
登录之后,chaincode 的部署、调用等操作与之前类似,只是需要通过 -u 选项来指定用户名。
在 vp0 上执行命令:
# peer chaincode deploy -u jim -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Function":"init", "Args": ["a","100", "b", "200"]}' 06:58:20.099 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token. 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" > Deploy chaincode: ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539 06:58:22.178 [main] main -> INFO 003 Exiting.....
记录下返回的 chaincode ID。
# CC_ID=ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539
此时,查询账户值应当为初始值。
# peer chaincode query -u jim -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}' 07:28:39.925 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token. 07:28:40.281 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > secureContext:"jim" > Query Result: 100 07:28:40.281 [main] main -> INFO 003 Exiting.....
也可以通过 REST 方式进行:
POST HOST:7050/chaincode
Request:
{ "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": "jim" }, "id": 1 }
Response:
{ "jsonrpc": "2.0", "result": { "status": "OK", "message": "ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" }, "id": 1 }
chaincode 调用
在账户 a、b 之间进行转账 10 元的操作。
# peer chaincode invoke -u jim -n ${CC_ID} -c '{"Function": "invoke", "Args": ["a", "b", "10"]}' 07:29:25.245 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token. 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) 07:29:25.585 [main] main -> INFO 003 Exiting.....
也可以通过 REST 方式进行:
POST HOST:7050/chaincode
Request:
{ "jsonrpc": "2.0", "method": "invoke", "params": { "type": 1, "chaincodeID":{ "name":"980d4bb7f69578592e5775a6da86d81a221887817d7164d3e9d4d4df1c981440abf9a61417eaf8ad6f7fc79893da36de2cf4709131e9af39bca6ebc2e5a1cd9d" }, "ctorMsg": { "function":"invoke", "args":["a", "b", "100"] }, "secureContext": "jim" }, "id": 3 }
Response:
{ "jsonrpc": "2.0", "result": { "status": "OK", "message": "66308740-a2c5-4a60-81f1-778dbed49cc3" }, "id": 3 }
chaincode 查询
查询 a 账户的余额。
# peer chaincode query -u jim -n ${CC_ID} -c '{"Function": "query", "Args": ["a"]}' 07:29:55.844 [chaincodeCmd] getChaincodeSpecification -> INFO 001 Local user 'jim' is already logged in. Retrieving login token. 07:29:56.198 [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 002 Successfully queried transaction: chaincodeSpec:<type:GOLANG chaincodeID:<name:"ee5b24a1f17c356dd5f6e37307922e39ddba12e5d2e203ed93401d7d05eb0dd194fb9070549c5dc31eb63f4e654dbd5a1d86cbb30c48e3ab1812590cd0f78539" > ctorMsg:<args:"query" args:"a" > secureContext:"jim" > Query Result: 90 07:29:56.198 [main] main -> INFO 003 Exiting.....
也可以通过 REST 方式进行:
POST HOST:7050/chaincode
Request:
{ "jsonrpc": "2.0", "method": "query", "params": { "type": 1, "chaincodeID":{ "name":"980d4bb7f69578592e5775a6da86d81a221887817d7164d3e9d4d4df1c981440abf9a61417eaf8ad6f7fc79893da36de2cf4709131e9af39bca6ebc2e5a1cd9d" }, "ctorMsg": { "function":"query", "args":["a"] }, "secureContext": "jim" }, "id": 5 }
Response:
{ "jsonrpc": "2.0", "result": { "status": "OK", "message": "900" }, "id": 5 }
区块信息查询
URL:
GET HOST:7050/chain/blocks/2
Response:
{ "transactions": [ { "type": 2, "chaincodeID": "EoABMjhiYjJiMjMxNjE3MWE3MDZiYjI4MTBlYzM1ZDA5NWY0MzA4NzdiZjQ0M2YxMDYxZWYwZjYwYmJlNzUzZWQ0NDA3MDBhNTMxMmMxNjM5MGQzYjMwMTk5ZmU5NDY1YzNiNzVkNTk0NDM1OGNhYWUwMWNhODFlZjI4MTI4YTFiZmI=", "payload": "Cp0BCAESgwESgAEyOGJiMmIyMzE2MTcxYTcwNmJiMjgxMGVjMzVkMDk1ZjQzMDg3N2JmNDQzZjEwNjFlZjBmNjBiYmU3NTNlZDQ0MDcwMGE1MzEyYzE2MzkwZDNiMzAxOTlmZTk0NjVjM2I3NWQ1OTQ0MzU4Y2FhZTAxY2E4MWVmMjgxMjhhMWJmYhoTCgZpbnZva2USAWESAWISAzEwMA==", "uuid": "2b3b6cf3-9887-4dd5-8f2e-3634ec9c719a", "timestamp": { "seconds": 1466577447, "nanos": 399637431 }, "nonce": "5AeA6S1odhPIDiGjFTFG8ttcihOoNNsh", "cert": "MIICPzCCAeSgAwIBAgIRAMndnS+Me0G6gs4J9/fb8HcwCgYIKoZIzj0EAwMwMTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMQwwCgYDVQQDEwN0Y2EwHhcNMTYwNjIyMDYzMzE4WhcNMTYwOTIwMDYzMzE4WjAxMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDDAKBgNVBAMTA2ppbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDLd2W8PxzgB4A85Re2x44BApbOGqP05tnkygbXSctLiqi5HVfwRAACS6znVA9+toni59Yy+XAH3w2offdjFW3mjgdwwgdkwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwDQYDVR0OBAYEBAECAwQwDwYDVR0jBAgwBoAEAQIDBDBNBgYqAwQFBgcBAf8EQAfASTE6bZ0P5mrEzTa5r1UyKFv+dKezBiGU0V3l2iWzk9evlGMvaC2pwhEKfKDdKxs7YSMYe/7cLq/oF++GBVowSgYGKgMEBQYIBEBEO3TKXuORl5Geuco8Gnn5TkoIl4+b96aPGDGvKbmDjMXR9vEBuUXTnsbDL53j7kC8/XQs1kZboC1ojLeUSN03MAoGCCqGSM49BAMDA0kAMEYCIQCZqyANMFcu1WiMe2So0pC7eRU95F0+qUXLAKZsPWv/YQIhALmNaglP7CoMOe2qxehucmffDlu0BRLSYDHyV9xcxmkH", "signature": "MEYCIQDob3NqdrfwlSGhi+zz+Ypl7S9QQ07RIFr8nV92e8KDNgIhANIljz4tRS8vwQk01hTemNQFJX2zMI6DhSUFZivbbtoR" } ], "stateHash": "7YUoVvYnMLHbLf47uTixLtkjF6xM9DuvgSWC92MbOUzk09xhcRBBLZqe5FvJElgZemELBOcuIFnubL0LiGH0yw==", "previousBlockHash": "On4BlpqCYNpugUKluqvOcbvkr3TAQxmlISLdd6qrONtIgmQ4iUDeWxAA9lUCceZfF8tke8A0Wy7m9tksNpKodw==", "consensusMetadata": "CAI=", "nonHashData": { "localLedgerCommitTimestamp": { "seconds": 1466577447, "nanos": 653618964 }, "transactionResults": [ { "uuid": "2b3b6cf3-9887-4dd5-8f2e-3634ec9c719a" } ] } }
四.Python 客户端前面应用案例,都是直接通过 HTTP API 来跟 hyperledger 进行交互,操作比较麻烦。
还可以直接通过 hyperledger-py 客户端来进行更方便的操作。
安装
$ pip install hyperledger --upgrade
或直接源码安装
$ git clone https://github.com/yeasy/hyperledger-py.git $ cd hyperledger-py $ pip install -r requirements.txt $ python setup.py install
使用
>>> from hyperledger.client import Client >>> c = Client(base_url="http://127.0.0.1:7050") >>> c.peer_list() {u'peers': [{u'type': 1, u'ID': {u'name': u'vp1'}, u'address': u'172.17.0.2:30303'}, {u'type': 1, u'ID': {u'name': u'vp2'}, u'address': u'172.17.0.3:30303'}]}
更多使用方法,可以参考 API 文档。
其它客户端
目前,HyperLedger Fabric 已经成立了 SDK 工作组。
目前在实现的客户端 SDK 包括:
Python SDK
Nodejs SDK
- 留下你的读书笔记
- 你还没登录,点击这里
-
用户笔记留言