Fabric 1.0 alpha快速部署和CouchDB使用

Fabric 1.0 alpha快速部署和CouchDB使用

季宙栋季宙栋

本文档将帮助开发者和用户快速部署Fabric 1.0 alpha框架(Order-Peer集群)并完成通道创建和示例合约执行。本文所涉工具使用shell脚本生成相应yaml文件和用于成员身份验证的证书,真实生产环境需搭配Fabric-ca使用。

一、前置条件和系统配置

  • 配置基础开发环境,安装docker、docker-compose、nodeJS
  • 获取Fabric代码
git clone hyperledger/fabric
  • 编译configtxgen 工具
cd $GOPATH/src/github.com/hyperledger/fabric
make configtxgen
  • 拉取docker镜像
docker pull hyperledger/fabric-orderer:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-peer:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-zookeeper:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-couchdb:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-kafka:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-ca:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-ccenv:x86_64-1.0.0-alpha
docker pull hyperledger/fabric-javaenv:x86_64-1.0.0-alpha

执行 docker tag 将全部fabric镜像设置latest标签,执行docker images 应该具备下面这些镜像内容:



二、生成配置文件


configtxgen工具用于生成两个要素: 1)orderer 的创始区块 2)配置fabric通道的配置文件

orderer block是用于order排序服务的创始区块,在创建通道的时候被广播到order排序服务。

configtx.yaml包含示例区块链网络内角色的定义;/crypto目录包含管理员证书,CA证书,每个角色的私钥和用于签名的证书

三、执行生成配置shell 脚本

你可以设置channel-ID 为你的通道名称,默认名称为 mychannel

cd examples/e2e_cli
./generateCfgTrx.sh <channel-ID>

执行 shell 脚本后, 可以在终端上看到如下输出:

2017/03/18 10:30:25 Generating new channel configtx

2017/03/18 10:30:25 Creating no-op MSP instance

2017/03/18 10:30:25 Obtaining default signing identity

2017/03/18 10:30:25 Creating no-op signing identity instance

2017/03/18 10:30:25 Serializing identity

2017/03/18 10:30:25 signing message

2017/03/18 10:30:25 signing message

2017/03/18 10:30:25 Writing new channel tx

这样,创建区块链网络的必要准备工作就做完了


四、使用Docker运行端到端测试


使用docker-compose 启动fabric集群并执行测试.

cd examples/e2e_cli
[CHANNEL_NAME=<channel-id>] docker-compose up -d

通过在终端执行docker ps可以看到,第一阶段启动了fabric集群,第二阶段部署了智能合约mycc并运行,如下图所示:


一键脚本

这是给懒人使用的,完成了上面全部工作流程

cd examples/e2e_cli
./network_setup.sh up <channel-ID>

端到端测试脚本执行了什么?

  • CLI容器内执行了一个脚本 - script.sh . 脚本首先通过获取指定的通道名称执行 createChannel 命令.
  • createChannel 执行完成的输出是Order的创始区块- <channel-ID>.block .
  • 发送创始区块给四个Peer节点并执行joinChannel命令.
  • 至此,创建了一个由四个Peer节点和两个组织(Org0、Org1)组成的通道.
  • Org关系都在configtx.yaml中定义
  • 接下来执行智能合约 - chaincode_example02 被部署到 PEER0 和 PEER2
  • 部署在PEER2上的合约代码会执行实例化,实例化指启动合约容器并初始化与合约相关联的Key/Value,示例里启动了一个dev-peer2-mycc-1.0的容器
  • 实例化也会传递有关的背书策略,这里背书策略定义为 -P“OR('Org0MSP.member','Org1MSP.member')”,意思是任何交易必须由绑定到Org0或Org1的Peer节点来实施签名背书,交易才有效.
  • 对PEER0发出“a”的query交易。合约之前已经被部署在PEER0上,因此会启动dev-peer0-mycc-1.0容器并返回查询的结果。
  • 向 PEER0 发起invoke交易,从a到b转移10个单位
  • 将智能合约代码部署到 PEER3上
  • 向PEER3发送“a”的query交易,再次启动dev-peer3-mycc-1.0为名称的第三个合约容器并返回查询值90,正确反映之前的交易过程,即a的值被修改了10

如何查看执行交易的过程?

可以通过CLI 容器的日志.

docker logs -f cli

输出如下:

2017/03/18 10:32:55.841 UTC [logging] InitFromViper -> DEBU 001
Setting default logging level to DEBUG for command 'chaincode'
2017/03/18 10:32:55.842 UTC [msp] GetLocalMSP -> DEBU 002
Returning existing local MSP
2017/03/18 10:32:55.842 UTC [msp] GetDefaultSigningIdentity -> DEBU 003
Obtaining default signing identity
2017/03/18 10:32:55.843 UTC [msp] Sign -> DEBU 004 Sign:
plaintext: 0A8F050A59080322096D796368616E6E...6D7963631A0A0A0571756572790A0161
2017/03/18 10:32:55.843 UTC [msp] Sign -> DEBU 005 Sign:
digest: 52F1A41B7B0B08CF3FC94D9D7E916AC4C01C54399E71BC81D551B97F5619AB54
Query Result: 90
2017/03/18 10:32:55.425 UTC [main] main -> INFO 006
Exiting.....
===================== Query on chaincode on PEER0 on channel 'wanda' is successful
=====================
===================== All GOOD, End-2-End execution completed
=====================

如何查看智能合约的日志?

通过合约所在的容器查看有关日志:

$ docker logs dev-peer2-mycc-1.0
04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize
BCCSP [SW]
ex02 Init
Aval = 100, Bval = 200
$ docker logs dev-peer0-mycc-1.0
04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize
BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"100"}
ex02 Invoke
Aval = 90, Bval = 210
$ docker logs dev-peer3-mycc-1.0
04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize
BCCSP [SW]
ex02 Invoke
Query Response:{"Name":"a","Amount":"90"}

五、使用CouchDB


Fabric1.0支持可插拔的状态数据库,可以从默认的goleveldb切换到CouchDB。CouchDB以JSON格式存储数据,同时可以提供更丰富和复杂的查询功能

通过下面步骤激活使用CouchDB:

  • 编译CouchDB 镜像(上文已拉取couchdb镜像)
  • Vim编辑器打开fabric/examples/e2e_cli/docker-compose.yaml 去除 CouchDB containers 和peer container 相关的注释.

为了完整验证CouchDB的功能,使用marbles02示例来做演示.。marbles02 合约放置在 fabric/examples/chaincode/go 目录.

参考之前的步骤创建通道(账本)

  • 在peer0上Install 和 instantiate 合约代码:
peer chaincode install -o orderer0:7050 -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02
peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
-C mychannel -n marbles -v 1.0 -p
github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR      ('Org0MSP.member','Org1MSP.member')"
  • 创建一些弹珠并移动他们:
·       
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
-C mychannel -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
·       
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
·       
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
·       
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
·       
peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'

peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["delete","marble1"]}'
  • 你可以打开浏览器的以下URL,通过CouchDB Web界面(Fauxton)查看状态数据库。
http://localhost:5984/_utils

可以看到一个名为<channel-id>的数据库和有关的文档.

  • 可以从CLI容器执行查询操作 :
peer chaincode query -C mychannel -n marbles -c '{"Args":["readMarble","marble2"]}'

marble2的详细信息如下:

Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}

检索 marble1的历史数据:

peer chaincode query -C mychannel -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'

返回marble1的历史记录:

Query Result: [{"TxId":"1c3d3caf124c89f91a4c0f353723ac736c58155325f02890adebaa15e16e6464", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"tom"}},{"TxId":"755d55c281889eaeebf405586f9e25d71d36eb3d35420af833a20a2f53a3eefd", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"jerry"}},{"TxId":"819451032d813dde6247f85e56a89262555e04f14788ee33e28b232eef36d98f", "Value":}]

  • 还可以对数据内容执行rich查询,例如通过所有者jerry来查询有关的marble信息:
peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'

输出应显示jerry拥有的两个marble的信息:

Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]

按字段owner、值为jerry查询marble信息:

peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"jerry\"}}"]}'

输出如下:

Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}]


六、故障排除


  • 确保在每次运行后清除有关文件
  • 如果编译docker出现报错,可以删除镜像并从头开始.
make clean
make peer-docker orderer-docker
  • 如果出现下面的报错:

Error: Error endorsing chaincode: rpc error: code = 2 desc = Error installing chaincode code mycc:1.0(chaincode /var/hyperledger/production/chaincodes/mycc.1.0 exits)

可能残留先前运行的合约容器镜像(例如peer0-peer0-mycc-1.0或peer1-peer0-mycc1-1.0),删除以后再试一下.

docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}')
  • 清理整个区块链网络, 使用脚本的 down 选项:
./network_setup.sh down
62 条评论