这个官方样例
Building Your First Network
我运行了可能有5遍了,今天才真正明白是怎么回事,这里记录一下。运行这个样例之前务必要先弄明白Docker
脚本执行
首先先用现成的脚本执行一次,确保环境安装正确。
./byfn.sh up
如果最后输出如下,说明运行成功。
===================== All GOOD, BYFN execution completed =====================
_____ _ _ ____
| ____| | \ | | | _ \
| _| | \| | | | | |
| |___ | |\ | | |_| |
|_____| |_| \_| |____/
然后一定不要忘记清理运行环境。
./byfn.sh down
分步手动执行
搭建基础网络
组织架构准备
编写组织架构文件
crypto-config.yaml
,其中配置了排序服务节点和组织节点。简要说明一下
- Name: Org2 Domain: org2.example.com EnableNodeOUs: true Template: Count: 2 //表明一个Org有几个peer Users: Count: 1 //表明一个Org有几个User
使用cryptogen工具根据架构文件生成相关的证书,放到
crypto-config
目录下。../bin/cryptogen generate --config=./crypto-config.yaml
生成配置文件
用到configtxgen工具,生成的配置文件都在channel-artifacts
目录下,这里一共会有四个。
要告诉工具去哪里找configtx.yaml
文件。
export FABRIC_CFG_PATH=$PWD
生成orderer genesis block
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
生成通道配置文件
先指定通道名称:
export CHANNEL_NAME=mychannel
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
为Org定义anchor peer
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
启动网络
这里需要用到Docker-Compose模板文件docker-compose-cli.yaml
,里面定义了需要用到的容器,去看代码发现里面其实是扩展了base
目录下的另外两个模板文件,感觉就像是继承一样。
启动网络:docker-compose -f docker-compose-cli.yaml up -d
其中容器CLI的定义如下(截取部分):
cli:
container_name: cli
image: hyperledger/fabric-tools:$IMAGE_TAG
tty: true
stdin_open: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_LOGGING_LEVEL=INFO
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- 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
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
上面的环境变量部分指定是在peer0.org1.example.com节点操作chaincode
还要说明一下,我们是通过CLI容器对其它容器进行配置。
进入CLI容器的命令:docker exec -it cli bash
创建通道
声明通道名:export CHANNEL_NAME=mychannel
创建通道
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
-o 指定排序节点,-c指定通道名字,-f指定通道配置文件,–tls允许tls通信,–cafile指定排序节点根证书目录以允许tls握手
据说这一步会生成
mychannel.block
,不过我没找到在哪个目录。将peer加入通道
加入peer0.org1.example.com节点
peer channel join -b mychannel.block
加入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:7051 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
更新anchor peer
更新Org1的anchor peer
peer0.org1.example.com
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
更新Org2的anchor peer
peer0.org1.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:7051 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 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
注意这里每次设置Org2相关时都需要重新设置环境变量,而Org1不用,可能是和模板文件
docker-compose-cli.yaml
中CLI容器的定义有关,不过如果去看脚本byfn.sh
的话可以发现每次它都重新设置了环境变量。
部署智能合约
这里我们用的是chaincode/chaincode_example02/go/
目录下现成的智能合约,当然也可以自己写。
安装智能合约
在
peer0.org1.example.com
上安装peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
在
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:7051 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 chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
注意这里如果不在
peer0.org2.example.com
上安装智能合约,后面转账(invoke)时会报错实例化智能合约
在
peer0.org1.example.com
上实例化peer chaincode instantiate -o orderer.example.com:7050 --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 -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
-o指定排序节点,–tls允许tls通信,–cafile指定排序节点根证书目录,-C指定通道名字,-n指定智能合约名字,-v指定智能合约版本,-c为调用智能合约传递参数
查询和转账
查询:
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
转账:
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:7051 --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"]}'
这里好像是转账操作的时候会在
peer0.org1.example.com
上实例化智能合约。还有如果转账之后立即查询,可能会发现账本未更新,结果与预期不符,等一下再去查询结果又对了。
查看交易日志
打开一个新的终端:
docker logs dev-peer0.org2.example.com-mycc-1.0
可以用CouchDB替换默认的goleveldb数据库,支持丰富的查询。