Hyperledger Fabric 1.0 安装和使用

注意:代码路径已更新,可以直接参考 https://github.com/yeasy/docker-compose-files/tree/master/hyperledger_fabric/

Hyperledger Fabric 1.0 版本整体 重新设计了架构,预计将于今年 3 月份发布。目前已经进入了 alpha 阶段,可以进行功能性验证。

本文将介绍如何快速启动一个 Fabric 1.0 的网络,并部署和调用 chaincode 进行测试。

安装 Docker

Docker 支持 Linux 常见的发行版,如 Redhat/Centos/Ubuntu 等,推荐使用 1.12 或者更新的版本。

$ 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.8.0 及以上版本)。

$ sudo pip install docker-compose>=1.8.0

获取 Docker 镜像

Docker 镜像可以自行从源码编译,或从社区 DockerHub 仓库下载。这里也提供了调整(精简指令,基于 golang:1.7 基础镜像制作)后的镜像,与社区版本略有差异,但功能是一致的。

通过如下命令拉去相关镜像,并更新镜像别名。

$ docker pull yeasy/hyperledger-fabric-base:latest \
&& docker pull yeasy/hyperledger-fabric-peer:latest \
&& docker pull yeasy/hyperledger-fabric-orderer:latest \
&& docker pull yeasy/hyperledger-fabric-ca:latest \
&& docker pull yeasy/blockchain-explorer:latest \
&& docker tag yeasy/hyperledger-fabric-peer hyperledger/fabric-peer \
&& docker tag yeasy/hyperledger-fabric-orderer hyperledger/fabric-orderer \
&& docker tag yeasy/hyperledger-fabric-ca hyperledger/fabric-ca \
&& docker tag yeasy/hyperledger-fabric-base hyperledger/fabric-baseimage \
&& docker tag yeasy/hyperledger-fabric-base hyperledger/fabric-ccenv:x86_64-1.0.0-snapshot-preview

启动 fabric 1.0 网络

下载 Compose 模板文件。

$ git clone https://github.com/yeasy/docker-compose-files

进入 hyperledger/1.0 目录,查看包括若干模板文件,功能如下。

  • peers.yml: 包含 peer 节点的服务模板。
  • docker-compose.yml: 启动 1 个 最小化的环境,包括 1 个 peer 节点、1 个 Orderer 节点、1 个 CA 节点。

通过如下命令快速启动。

$ docker-compose up

注意输出日志中无错误信息。

此时,系统中包括三个容器。

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc55d2334c38 hyperledger/fabric-peer "peer node start" 15 minutes ago Up 15 minutes 7050/tcp, 7052-7059/tcp, 0.0.0.0:7051->7051/tcp fabric-peer0
9c0afbba97ad hyperledger/fabric-orderer "orderer" 15 minutes ago Up 15 minutes 0.0.0.0:7050->7050/tcp fabric-orderer
ef96fa77bf45 hyperledger/fabric-ca "fabric-ca server sta" 15 minutes ago Up 15 minutes 7054/tcp, 0.0.0.0:8888->8888/tcp fabric-ca

测试 chaincode 操作

启动 fabric 网络后,可以进行 chaincode 操作,验证网络启动正常。

部署 chaincode

通过如下命令进入容器 peer0。

$ docker exec -it fabric-peer0 bash

在容器中执行部署命令,注意输出日志无错误提示,最终返回结果应该为 response:<status:200 message:"OK" payload:"100" >

root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode deploy -n test_cc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a","100","b","200"]}'
...
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" payload:"100" > payload:"\n \361\031\221\246\213\277\220C\016\370\265\034Vw\350\326\241\020\254\311\306\276gz\335n\"\\`;W\035\0224\n(\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\001\001a\004\001\001\001\001\000\000\032\010\010\310\001\032\003100" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0E\002!\000\275O9UM\334}\356\304D\260\267\315\230\210O\030\342\200\027B\346\347(U\272\224],\275\235:\002 -_-H$\315\332\363*c\325\373\253\320\201j\216\374\363<\037\r5\3257\356\312\354\003\314\266\013" >
[main] main -> INFO 019 Exiting.....

此时,系统中生成类似 dev-peer0-test_cc-0-305216ca522e84d0bf8c2b542b16bd3901dcb1879a970ae7c1eee3a74fbdee583eb8b74ad88edefc3d9647d47663f6b14574734c93a36b3968b077f3870d79cf 的 chaincode Docker 镜像,但并没有启动新的容器。

查询 chaincode

对部署成功的 chaincode 执行查询操作,查询 a 的余额。

同样的,在 peer0 容器中执行如下命令,注意输出无错误信息,最后的结果为 <status:200 message:"OK" payload:"100" >

root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["query","a"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" payload:"100" > payload:"\n \235\034J[\217!\334\240\354\376\265\374X\211)a\336q\302\024\274N\004M\271b\006\255#2Q\253\0224\n(\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\001\001a\004\001\001\001\001\000\000\032\010\010\310\001\032\003100" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0D\002 l`\362\365\342\356a\3562\211N\255\253F\200\365]\321\257\013^\303o\266\301}\266M\362\336\256\346\002 D\037.\347\261G\257\274J.\265\206}=\261(\036(\021\370\306_*\3122g\005q\346h>{" >
[main] main -> INFO 019 Exiting.....

类似的,查询 b 的余额,注意最终返回结果为 response:<status:200 message:"OK" payload:"200" >

[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" payload:"200" > payload:"\n U\207\330\255\023\344M\014\321\231\013\036\267\353\251DW4d\372j_/\236m<\201\333\221?\243\325\0224\n(\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\001\001b\004\001\001\001\001\000\000\032\010\010\310\001\032\003200" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0E\002!\000\271-\211\017\277!)g\005\005\252h\355\253U\216p\242\351\304@\372\361\241\360\274\351\362\374a\243\010\002 \021\266R\027\373\254\351?\351u\200RWQY1w|\361\217G\353\221\010\013\002\207\222b\324\330\320" >
[main] main -> INFO 019 Exiting.....

对部署后的 chaincode 执行查询或调用操作后,如果系统中没有对应的 chaincode 容器,则会利用之前生成的镜像自动启动新的容器。

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c95c6b078116 dev-peer0-test_cc-0-305216ca522e84d0bf8c2b542b16bd3901dcb1879a970ae7c1eee3a74fbdee583eb8b74ad88edefc3d9647d47663f6b14574734c93a36b3968b077f3870d79cf "/opt/gopath/bin/test" 13 minutes ago Up 13 minutes dev-peer0-test_cc-0-305216ca522e84d0bf8c2b542b16bd3901dcb1879a970ae7c1eee3a74fbdee583eb8b74ad88edefc3d9647d47663f6b14574734c93a36b3968b077f3870d79cf
fc55d2334c38 hyperledger/fabric-peer "peer node start" 15 minutes ago Up 15 minutes 7050/tcp, 7052-7059/tcp, 0.0.0.0:7051->7051/tcp fabric-peer0
9c0afbba97ad hyperledger/fabric-orderer "orderer" 15 minutes ago Up 15 minutes 0.0.0.0:7050->7050/tcp fabric-orderer
ef96fa77bf45 hyperledger/fabric-ca "fabric-ca server sta" 15 minutes ago Up 15 minutes 7054/tcp, 0.0.0.0:8888->8888/tcp fabric-ca

调用 chaincode

对部署成功的 chaincode 执行调用操作,如 a 向 b 转账 10 元。

在 peer0 容器中执行如下操作,注意最终结果状态正常 response:<status:200 message:"OK" >

root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["invoke","a","b","10"]}'
...
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" > payload:"\n \356\330\226\263z\315?\271@\327x\307\375V_\277\367vp1)\232!<\230\207\367n*c\271\311\022C\n<\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\002\001a\004\001\001\001\001\001b\004\001\001\001\001\002\001a\000\00290\001b\000\003210\000\032\003\010\310\001" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0E\002!\000\333\240\t\\\275\225{\230\3704D\366p\251\255\211\251\225\367\r1y\211\004\337\311k,\355\276e\273\002 Q\33242u\251s\267\025Q\271\222\367\321i\344\002\331\022\214\243\206\274\206C*\204k2\373\021\001" >
[main] main -> INFO 019 Exiting.....

此时,再次查询 a 和 b 的余额,发现发生变化。

root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["query","a"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" payload:"90" > payload:"\n \306\264k\315\327\262\345\207\013@*8\373\376\345B\222r\177\254\375\304\354c\3478(qT\267n\005\0223\n(\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\001\001a\004\001\005\001\001\000\000\032\007\010\310\001\032\00290" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0E\002!\000\273\014\323\264\003\252\275\341\n\304\021\237\331\267\253\325\250jS\262$~\251z\227\304\022\0179X\024\267\002 v\364h\265\301w\366\274\272\2723/F{u\037v1\372\031\331I\255]\000f\324\237\235t\341\212" >
[main] main -> INFO 019 Exiting.....

a 的新余额为 90。

root@peer0:/go/src/github.com/hyperledger/fabric# peer chaincode invoke -n test_cc -c '{"Args":["query","b"]}'
[chaincodeCmd] chaincodeInvokeOrQuery -> INFO 018 Invoke result: version:1 response:<status:200 message:"OK" payload:"210" > payload:"\n \004=\242\355\266\262\202V\332fA\256\227\001a\007\363G\226\277\032B6kN\317\010\332\331\251\212\227\0224\n(\002\004lccc\001\007test_cc\004\001\001\001\001\000\000\007test_cc\001\001b\004\001\005\001\001\000\000\032\010\010\310\001\032\003210" endorsement:<endorser:"\n\007DEFAULT\022\232\007-----BEGIN -----\nMIICjDCCAjKgAwIBAgIUBEVwsSx0TmqdbzNwleNBBzoIT0wwCgYIKoZIzj0EAwIw\nfzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xHzAdBgNVBAoTFkludGVybmV0IFdpZGdldHMsIEluYy4xDDAK\nBgNVBAsTA1dXVzEUMBIGA1UEAxMLZXhhbXBsZS5jb20wHhcNMTYxMTExMTcwNzAw\nWhcNMTcxMTExMTcwNzAwWjBjMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGgg\nQ2Fyb2xpbmExEDAOBgNVBAcTB1JhbGVpZ2gxGzAZBgNVBAoTEkh5cGVybGVkZ2Vy\nIEZhYnJpYzEMMAoGA1UECxMDQ09QMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nHBuKsAO43hs4JGpFfiGMkB/xsILTsOvmN2WmwpsPHZNL6w8HWe3xCPQtdG/XJJvZ\n+C756KEsUBM3yw5PTfku8qOBpzCBpDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw\nFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFOFC\ndcUZ4es3ltiCgAVDoyLfVpPIMB8GA1UdIwQYMBaAFBdnQj2qnoI/xMUdn1vDmdG1\nnEgQMCUGA1UdEQQeMByCCm15aG9zdC5jb22CDnd3dy5teWhvc3QuY29tMAoGCCqG\nSM49BAMCA0gAMEUCIDf9Hbl4xn3z4EwNKmilM9lX2Fq4jWpAaRVB97OmVEeyAiEA\n25aDPQHGGq2AvhKT0wvt08cX1GTGCIbfmuLpMwKQj38=\n-----END -----\n" signature:"0D\002 6H\037>\321Er\232&\205\245\274;\201\225\333\371|8\035\235\3354u\003\371\310\245\347\261nk\002 gF\362\304!0E\236\320\0148\203\236\330WdU\004C\007\010bC\234\026\351\264\335ZoC\316" >
[main] main -> INFO 019 Exiting.....

b 的新余额为 210。

更多 Hyperledger Fabric 相关的应用和技术话题,可以参考 社区文档 和 《区块链技术指南》

转载请注明:http://blog.csdn.net/yeasy/article/details/54928343


猜你喜欢

转载自blog.csdn.net/yeasy/article/details/54928343