本文是在阅读《区块链开发实战-Hyperledger Fabric关键技术与案例分析》一书的同时,在实践中记录的一些实践步骤与经验分享。
Hyperledger Fabric开发实战-03智能合约
上一节中,我们安装了基本的运行环境,现在,就开始运行第一个fabric网络,由于fabric涉及到很多配置,我们将配置放在某个目录
mkdir -p ~/fabricwksp/02-helloworld
cd ~/fabricwksp/02-helloworld
# 下面以HELLO_PATH代表上面的目录
export set HELLO_PATH=$PWD
1.预规划网络
在第一个例子中,我们规划Domain为cmbc.com
,有两个组织org1
和org2
,其中org1有两个peer节点和3个用户,org2有两个peer节点和2个用户
2.生成证书
在配置目录下创建fabricconfig文件夹,将生成证书的配置文件和生产的证书放在里面
mkdir -p $HELLO_PATH/fabricconfig
cd $HELLO_PATH/fabricconfig
# 将配置模板保存到文件中
cryptogen showtemplate >> crypto-config.yaml
接下来,就需要编辑配置文件了
# orderer配置
OrdererOrgs:
- Name: Orderer
Domain: cmbc.com
Specs:
- Hostname: orderer
# peer配置
PeerOrgs:
- Name: Org1
Domain: org1.cmbc.com
Template:
Count: 2
Users:
Count: 3
- Name: Org2
Domain: org2.cmbc.com
Template:
Count: 2
Users:
Count: 2
编辑完成后,使用命令生成证书
cd $HELLO_PATH/fabricconfig/
cryptogen generate --config=crypto-config.yaml --output ./crypto-config
cryptogen会将orderer和peer需要使用到的证书都保持到crypto-config文件夹下,在后面的配置中会设置这些证书的路径,使用tree命令,我们可以看到fabric为peer都分配了地址,我们需要将这些地址映射到本地ip
vim /etc/hosts
#加入下面的内容
127.0.0.1 orderer.cmbc.com
127.0.0.1 peer0.org1.cmbc.com
127.0.0.1 peer1.org1.cmbc.com
127.0.0.1 peer0.org2.cmbc.com
127.0.0.1 peer1.org2.cmbc.com
3.生成创世块
创建存放的文件夹,并将配置目标拷贝进去
mkdir -p $HELLO_PATH/orderer
cp -r $GOAPTH/src/github.com/hyperledger/fabric/sampleconfig/configtx.yaml $HELLO_PATH/orderer
cd $HELLO_PATH/orderer
拷贝完成后,就需要修改配置文件了,主要是对orderer的配置(如设置排序策略)和对channel的配置,以及对org1和org2设置证书路径 由于配置较为复杂,具体的配置在
https://github.com/ssj234/fabric/blob/master/02-helloworld/orderer/configtx.yaml
编辑完成后,使用下面的命令生成创世块
cd $HELLO_PATH/orderer
configtxgen -profile TestTwoOrgsOrdererGenesis -outputBlock ./orderer.genesis.block
顺便创建channel的tx文件
# $HELLO_PATH/orderer/channel.sh
cd $HELLO_PATH/orderer
configtxgen -profile TestTwoOrgsChannel -outputCreateChannelTx ./cmbcchannel666.tx -channelID cmbcchannel666
创建Org的锚文件,需要注意的是:在创建channel的时候,已经将AnchorPeer的配置保存到了Org的ConfigGroup的Values中的AnchorPeers
字段,所以,如果没有修改,也就不需要生成AnchorPeersUpdate文件了,下面是生成的命令,会生成对组织Org1MSP
和Org2MSP
中针对AnchorPeers的配置进行更新的文件。
# $HELLO_PATH/orderer/anchor.sh
cd $HELLO_PATH/orderer
configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org1MSPAnchors.tx -channelID cmbcchannel666 -asOrg Org1MSP
configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org2MSPAnchors.tx -channelID cmbcchannel666 -asOrg Org2MSP
4.启动orderer
启动orderer节点时,需要制定其配置文件,我们还是先拷贝一个示例文件,修改其中相关的私钥,证书等
cd $HELLO_PATH/orderer
cp -r $GOAPTH/src/github.com/hyperledger/fabric/sampleconfig/orderer.yaml $HELLO_PATH/orderer
可以参照,需要注意的是要正确配置RootAs,否则在创建channel的时候会报错证书验证不通过
https://github.com/ssj234/fabric/blob/master/02-helloworld/orderer/orderer.yaml
orderer start
启动orderer节点
5.启动peer
mkdir $HELLO_PATH/peer
cd $HELLO_PATH/peer
cp -r $GOAPTH/src/github.com/hyperledger/fabric/sampleconfig/core.yaml $HELLO_PATH/peer
参照下面的文件,修改配置文件
https://github.com/ssj234/fabric/blob/master/02-helloworld/peer/core.yaml
使用命令启动peer
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
peer node start
6.创建通道
服务都启动了以后,我们需要使用之前生成的channel的tx文件在网络上创建channel
- 创建通道
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/[email protected]/msp
peer channel create -t 50 -o orderer.cmbc.com:7050 -c cmbcchannel666 -f /home/ssj234/fabricwksp/02-helloworld/orderer/cmbcchannel666.tx
- 让peer加入channel
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/[email protected]/msp
peer channel join -b /home/ssj234/fabricwksp/02-helloworld/cmbcchannel666.block
- 更新锚节点
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/[email protected]/msp
peer channel update -o orderer.cmbc.com:7050 -c cmbcchannel666 -f /home/ssj234/fabricwksp/02-helloworld/orderer/Org1MSPAnchors.tx
7.Chaincode
网络运行后,我们创建了channel,并将peer加入了channel,这样一个简单的fabric网络就创建好了,之后我们可以在这个网络上运行智能合约,fabric的智能合约成为Chaincode
,会在docker容器中运行。
Chaincode使用fabric源码中自带的示例,我们使用$GOPATH/fabric/examples/chaincode/go/chaincode_example02
的例子
- 设置环境变量
export set FABRIC_CFG_PATH=/home/ssj234/fabricwksp/02-helloworld/peer
export set CORE_PEER_LOCALMSPID=Org1MSP
export set CORE_PEER_ADDRESS=peer0.org1.cmbc.com:7051
export set CORE_PEER_MSPCONFIGPATH=/home/ssj234/fabricwksp/02-helloworld/fabricconfig/crypto-config/peerOrganizations/org1.cmbc.com/users/[email protected]/msp
- 部署chaincode
cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
go build
peer chaincode install -n r_test_cc6 -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
如果报出如下错
../../../../vendor/github.com/miekg/pkcs11/pkcs11.go:29:18: fatal error: ltdl.h: No such file or directory
需要安装相关依赖,执行下面的命令即可
sudo apt-get install libtool libltdl7 libltdl-dev
- 实例化chaincode
peer chaincode instantiate -o orderer.cmbc.com:7050 -C cmbcchannel666 -n r_test_cc6 -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
- chaincode写入数据
peer chaincode invoke -o orderer.cmbc.com:7050 -C cmbcchannel666 -n r_test_cc6 -c '{"Args":["invoke","a","b","1"]}'
- chaincode查询数据
peer chaincode query -C cmbcchannel666 -n r_test_cc6 -c '{"Args":["query","a"]}'
返回的数据如下:
2018-11-28 10:35:45.891 CST [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2018-11-28 10:35:45.891 CST [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
Query Result: 93
2018-11-28 10:35:45.905 CST [main] main -> INFO 003 Exiting.....