Hyperledger Fabric V2.0(三)手动搭建Fabric网络(first-network)

只愿长相守 提交于 2020-05-02 18:14:15

本文已更新,请移步Hyperledger Fabric(五)手动搭建Fabric网络V2.0(基于first-network案例)

 

基于byfn.sh脚本文件的自动化部署过程如下:

① 进入fabric-samples/first-network目录

cd fabric-samples/first-network   

② 为各种网络实体生成所需的证书及密钥,引导排序服务的genesis块,配置通道所需的配置事务,以及锚节点更新事务

./byfn.sh generate   #可通过如 -c alwayschannel 指定通道名称,默认为mychannel

③ 启动网络,创建通道,安装、定义并调用链码

byfn.sh up   #用默认值启动网络,可通过-c mychannel指定通道名称,-s couchdb指定使用couchdb而不是leveldb,指定参数-n以不安装abstore智能合约(该脚本默认安装该合约),-l java指定安装脚本的语言为java

④ 销毁网络

./byfn.sh down   #停止并删除所有容器,删除chaincode镜像,删除证书及密钥(crypto-config目录下),以及四个通道文件(channel-artifacts目录下,分别为:genesis.block,channel.tx,Org1MSPanchors.tx,Org2MSPanchors.tx,genesis.block为系统通道的创世区块,后三者分别为创建通道,设置组织一、组织二的锚节点的事务,这些配置操作作为系统事务提交到系统通道中)

纯手动搭建Fabric网络(基于first-network),过程如下:

首先将first-network目录下的docker-compose-cli.yaml文件中cli容器配置信息中的FABRIC_LOGGING_SPEC=INFO修改为FABRIC_LOGGING_SPEC=DEBUG以看到更多的执行过程信息

使用cryptogen(密码生成器)和configtxgen(配置事务生成器)手动生成证书/密钥和各种配置构件(等同于执行./byfn.sh generate -c $CHANNEL_NAME):

① 进入fabric-samples/first-network目录

cd fabric-samples/first-network   

② 使用cryptogen工具为各种网络实体生成x509证书和签名密钥,配置文件为crypto-config.yaml,生成的证书及密钥存放在crypto-config目录下

cryptogen generate --config=./crypto-config.yaml

③ 使用configtxgen工具生成系统通道的创世区块,并将系统的配置操作(创建通道,设置某组织的锚节点等)作为系统事务生成提交到系统通道的事务文件(.tx),配置文件为configtx.yaml,生成的配置组件位于channel-artifacts目录下

Ⅰ export FABRIC_CFG_PATH=$PWD   #告诉configtxgen从哪里寻找configtx.yaml文件

Ⅱ configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block   #生成系统通道创世区块genesis.block

Ⅲ export CHANNEL_NAME=mychannel   #通过环境变量设定通道名称

Ⅳ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME   #创建 通道配置 事务

Ⅴ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP   #创建 更新组织Org1在该通道上的锚节点(锚节点为某组织对order可见的节点) 的事务

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP   #创建 更新组织Org2在该通道上的锚节点 的事务

启动网络,创建并加入通道,更新组织锚节点,安装、定义并调用一个链代码(等同于执行./byfn.sh up):

① 启动网络(该过程使用genesis.block文件)

docker-compose -f docker-compose-cli.yaml -f docker-compose-etcdraft2.yaml up -d   #-d用于不显示网络的实时日志,若想查看日志流,则后续命令需要打开另一个终端来执行

② 创建并加入通道,并指定(更新)组织的锚节点(锚节点代表整个组织和order节点进行通信,而不是组织的所有节点,以减少通讯量)

Ⅰ docker exec -it cli bash   #进入CLI(命令行)容器

Ⅱ 配置CLI容器作为peer0.org1.example.com节点执行命令的环境变量:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

Ⅲ export CHANNEL_NAME=mychannel   #以环境变量形式设定通道名称,必须全部小写,长度小于250个字符,并与正则表达式[a-z][a-z0-9.-]*匹配

Ⅳ peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem   #将通道配置事务发送给order节点以创建通道,指定order节点的证书以进行TLS握手,执行结束后该节点将收到来自order节点的对应于所创建通道的创世区块$CHANNEL_NAME.block

peer channel join -b mychannel.block   #将peer0.org1.example.com加入通道,注意命令中的$CHANNEL_NAME.block,根据通道名称而变化
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem   #指定peer0.org1.example.com作为组织Org1的锚节点

Ⅴ 配置CLI容器作为peer0.org2.example.com节点执行命令的环境变量:

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

Ⅵ peer channel join -b mychannel.block   #将peer0.org2.example.com加入通道,注意命令中的$CHANNEL_NAME.block,根据通道名称而变化

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem   #指定peer0.org2.example.com作为组织Org2的锚节点

③ 安装并定义一个链代码(2.0版本中引入了新的Fabric chaincode生命周期,通道的成员组织需要就chaincode定义达成一致。)

Ⅰ 将chaincode安装到对等节点之前,我们需要对它进行打包,生成的打包文件mycc.tar.gz位于/opt/gopath/src/github.com/hyperledger/fabric/peer目录,node链码打包命令与java相同,只需修改语言为--lang node,而go链码略有不同,以下为java版本链码的打包命令

peer lifecycle chaincode package mycc.tar.gz --path /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/java/ --lang java --label mycc_1

Ⅱ 安装链码

peer lifecycle chaincode install mycc.tar.gz

java版本链码报错(尝试go版本没有任何问题):Error: failed to endorse chaincode install: rpc error: code = Unavailable desc = transport is closing
解决:校网环境下,第一次报错后稍等几分钟,再次执行,成功。总之,不断尝试吧。

Ⅲ 查询已安装的链码

peer lifecycle chaincode queryinstalled   #可看到已安装链码包的ID以及标签(lable)

Ⅳ 后续命令将需要链码包的ID,因此我们将它保存为一个环境变量,这个ID是动态的,不要直接复制此命令

CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173

Ⅴ 更改CLI容器的环境变量后,在其它节点上安装链码(不需要再次打包):

peer lifecycle chaincode install mycc.tar.gz

Ⅵ 通道中的组织需要就链码的定义达成一致,以下命令用于批准一个chaincode定义,--init-required用于初始化chaincode时使init函数被调用,--package-id指定链码包的ID,我们还可以提供--signature-policy或--channel-config-policy参数来设置chaincode背书策略,若未提供将使用默认设置-大多数通道成员背书,这种情况下若在该渠道中添加或删除新组织,背书策略将自动更新,以要求更多或更少的背书。在本例中,默认策略将需要来自属于Org1和Org2的peer的背书(即两个背书)

peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

所有组织都需要对定义达成一致,更改CLI容器的环境变量,继续

peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

一旦足够多的通道成员组织批准了chaincode定义,一个成员组织就可以将定义提交给通道。可以通过发出以下查询来检查chaincode定义是否已准备好提交,并查看当前组织的批准情况

peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json   #查看各组织对chaincode定义的批准状况

一旦就链码定义达成一致,则可将chaincode定义提交到通道,可以以Org1或Org2的形式发出此命令

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name mycc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

④ 调用chaincode

Ⅰ 将--isInit标志传递给链码的第一次调用,并将参数提供给Init函数。第一个调用将启动chaincode容器。我们可能需要等待容器启动。(确保通道名称和链码名称正确)

peer chaincode invoke -o orderer.example.com:7050 --isInit --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["Init","a","100","b","100"]}' --waitForEvent

Ⅱ 查询chaincode

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

Ⅲ 调用链码的invoke函数,a向b转账十元

peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}' --waitForEvent

注:若通道成员组织的其它节点想和区块链网络进行交互,只需要加入通道并安装链码包即可,而不需要提交链码定义(每个组织批准一次链码定义即可)。

至此,手动搭建Fabric网络基本完成

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!