step-by-step搭建fabric的开发环境
搭建一个只有一个orderer/peer/cli一共就三个节点的fabric环境,让orderer使用solo模式,peer使用leveldb作为状态数据库。
当然这个环境只能用来作为开发调试chaincode使用。
这个教程是基于官方的byfn例子简化而来,所以里面很多的配置文件都是从byfn例子改出来的。
第一步:生产所有的证书文件
1.1 定义证书配置文件 crypto-config.yaml
$ cat crypto-config.yaml
OrdererOrgs:
- Name: OrdererOrg
Domain: example.com
Specs:
- Hostname: orderer
PeerOrgs:
- Name: PeerOrg
Domain: example.com
Template:
Count: 2
Users:
Count: 1
这里我们只定义了一个peer Org。
1.2 使用cryptogen工具生产证书文件
${GOPATH}/src/github.com/hyperledger/fabric/build/docker/bin/cryptogen generate --config=./crypto-config.yaml
运行完成后,会在当前目录下面生产一个文件夹:crypto-config
$ ls -1 crypto-config
ordererOrganizations
peerOrganizations
包含整个fabric网络中所有节点的证书信息。
第二步:生成genesis block文件
2.1 定义fabric网络genesis block配置文件
$ cat configtx.yaml
Profiles:
OrdererOrgGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *PeerOrg
PeerOrgChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *PeerOrg
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/example.com/msp
- &PeerOrg
Name: PeerOrg
ID: PeerOrgMSP
MSPDir: crypto-config/peerOrganizations/example.com/msp
AnchorPeers:
- Host: peer0.example.com
Port: 7051
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Organizations:
Application: &ApplicationDefaults
Organizations:
2.2 使用工具configtxgen生成genesis block
创建channel-artifacts子目录,存储genesis block
mkdir -p ./channel-artifacts
然后使用configtxgen工具生产genesis block
FABRIC_CFG_PATH=. ${GOPATH}/src/github.com/hyperledger/fabric/build/docker/bin/configtxgen -profile OrdererOrgGenesis -outputBlock ./channel-artifacts/genesis.block
生成的genesis block文件存放在 channel-artifacts/genesis.block
第三步:定义channel初始block
假设channel的名字为:mychannel
FABRIC_CFG_PATH=. ${GOPATH}/src/github.com/hyperledger/fabric/build/docker/bin/configtxgen -profile PeerOrgChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
比较第三步和第二步,第二步是生成genesis block文件是包含整个fabric网络的信息,在orderer加载的时候被引用;第三步生成的是channel个block文件,包含针对特定channel的初始信息文件,在channel创建的时候被引用。
最后生成的文件是:channel-artifacts/mychannel.block
第四步:启动fabric
4.0 首先需要准备fabric用到的image
- hyperledger/fabric-tools
- hyperledger/fabric-peer
- hyperledger/fabric-orderer
4.1 定义core.yaml和orderer.yaml
可以从byfn例子里面拷过来了,按需要做一些调整。
4.2 定义.env 文件
这个文件只有一行,定义了变量COMPOSE_PROJECT_NAME的值。
$ cat .env
COMPOSE_PROJECT_NAME=net
否则chaincode instantiate的时候回失败;但是我认为这应该算是fabric或者docker-compose,或者他们之间现衔接的一个bug。
这个变量在docker-compose.yaml里面用到。
4.3 定义docker compose 文件
$ cat docker-compose.yaml
version: '2'
networks:
byfn:
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
- ORDERER_GENERAL_TLS_ENABLED=true
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
- ./orderer.yaml:/etc/hyperledger/fabric/orderer.yaml
ports:
- 7050:7050
networks:
- byfn
peer0.example.com:
container_name: peer0.example.com
image: hyperledger/fabric-peer
environment:
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
- CORE_PEER_ID=peer0.example.com
- CORE_PEER_ADDRESS=peer0.example.com:7051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.example.com:7051
- CORE_PEER_LOCALMSPID=PeerOrgMSP
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
volumes:
- ./crypto-config/peerOrganizations/example.com/peers/peer0.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/example.com/peers/peer0.example.com/tls:/etc/hyperledger/fabric/tls
- ./core.yaml:/etc/hyperledger/fabric/core.yaml
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 7051:7051
- 7053:7053
networks:
- byfn
cli:
container_name: cli
image: hyperledger/fabric-tools
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_LOGGING_LEVEL=DEBUG
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
volumes:
- ./:/opt/gopath/src/github.com/hyperledger/fabric/peer
depends_on:
- orderer.example.com
- peer0.example.com
networks:
- byfn
4.4 启动docker-compose
$ docker-compose -d up
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------
cli /bin/bash Up
orderer.example.com orderer Up 0.0.0.0:7050->7050/tcp
peer0.example.com peer node start Up 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp
看到有三个container在运行,一个orderer,一个peer,和一个cli。
第五步:进入到cli容器运行fabric接口命令
$ docker exec -it cli bash
root@482e1e3001c3:/opt/gopath/src/github.com/hyperledger/fabric/peer#
5.1 设置环境
export FABRIC_CFG_PATH=.
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_ROOTCERT_FILE=${FABRIC_CFG_PATH}/crypto-config/peerOrganizations/example.com/peers/peer0.example.com/tls/ca.crt
export CORE_PEER_TLS_KEY_FILE=${FABRIC_CFG_PATH}/crypto-config/peerOrganizations/example.com/peers/peer0.example.com/tls/server.key
export CORE_PEER_TLS_CERT_FILE=${FABRIC_CFG_PATH}/crypto-config/peerOrganizations/example.com/peers/peer0.example.com/tls/server.crt
export CORE_PEER_ADDRESS=peer0.example.com:7051
export CORE_PEER_LOCALMSPID=PeerOrgMSP
export CORE_PEER_MSPCONFIGPATH=${FABRIC_CFG_PATH}/crypto-config/peerOrganizations/example.com/users/Admin@example.com/msp
5.2 创建channel
# peer channel create \
-t 15 \
-o orderer.example.com:7050 \
-c mychannel \
-f ./channel-artifacts/mychannel.tx \
--tls true \
--cafile ${FABRIC_CFG_PATH}/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
创建完channel之后会在当前目录生成一个文件:mychannel.block
5.3 加入channel
# peer channel join -b ./mychannel.block
5.4 安装chaincode
假定chaincode的源代码放在如下路径:
# ls chaincode/go/chaincode_example02
chaincode_example02.go
安装脚本
# peer chaincode install -n mychaincode -v 1.0 -p github.com/hyperledger/fabric/peer/chaincode/go/chaincode_example02
5.5 实例化chaincode
# peer chaincode instantiate \
-o orderer.example.com:7050 \
--tls true \
--cafile ${FABRIC_CFG_PATH}/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel -n mychaincode -v 1.0 -c '{"Args":["init","a","1000","b","2000"]}'
5.6 查询和调用chaincode
至此整个chaincode的部署已经完成了,下面就可以调用chaincode的代码逻辑了。
5.6.1 查询
# peer chaincode query -C mychannel -n mychaincode -c '{"Args":["query","a"]}'
5.6.2 转账
# peer chaincode invoke \
-o orderer.example.com:7050 \
--tls true \
--cafile ${FABRIC_CFG_PATH}/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
-C mychannel -n mychaincode -c '{"Args":["invoke","b","a","1"]}'
第六步,停止
$ docker-compose down