make native
命令可编译出二进制可执行文件,然后将fabric/build/bin目录拷贝到fabric-samples目录中;./byfn generate
报错的问题。因此可考虑直接从github上下载稳定的二进制可执行文件,运行命令wget https://github.com/hyperledger/fabric/releases/download/v2.0.1/hyperledger-fabric-linux-amd64-2.0.1.tar.gz
,解压后同样将bin目录拷贝到fabric-samples目录中。在fabric目录中执行make docker
命令,可得到所需的相关镜像。
从Fabric2.0开始docker镜像将基于Alpine Linux,这是一种面向安全的轻量级Linux发行版,只占5MB左右的空间,且更加安全可靠。另外Alpine Linux还提供了自己的包管理工具apk,我们在构建docker镜像过程中存在“apk add”的动作,可能会有从“dl-cdn.alpinelinux.org/alpine/v3.10”下载包失败的问题,这是由于在中国大陆无法连接官方的更新源,因此可考虑在所有Dockerfile中修改为使用阿里云的更新源:
FROM alpine:${ALPINE_VER} as base
RUN echo "#aliyun" > /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/main/" >> /etc/apk/repositories
RUN echo "https://mirrors.aliyun.com/alpine/v3.10/community/" >> /etc/apk/repositories
在fabric-samples/first-network目录中,执行./byfn.sh up
命令启动测试网络,默认会生成crypto-config和channel-artifacts目录中的文件。最后控制台输出如下内容,表示运行成功。
执行“./byfn.sh up”命令调用的就是networkUp,脚本逻辑步骤如下:
# Generate the needed certificates, the genesis block and start the network.
function networkUp() {
checkPrereqs
# generate artifacts if they don't exist
if [ ! -d "crypto-config" ]; then
generateCerts
generateChannelArtifacts
fi
COMPOSE_FILES="-f ${COMPOSE_FILE} -f ${COMPOSE_FILE_RAFT2}"
if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
fi
if [ "${IF_COUCHDB}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
fi
IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
docker ps -a
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start network"
exit 1
fi
echo "Sleeping 15s to allow Raft cluster to complete booting"
sleep 15
if [ "${NO_CHAINCODE}" != "true" ]; then
echo Vendoring Go dependencies ...
pushd ../chaincode/abstore/go
GO111MODULE=on go mod vendor
popd
echo Finished vendoring Go dependencies
fi
# now run the end to end script
docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $CC_SRC_LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
}
下面将对networkUp中的一些具体细节进行剖析。
generateCerts使用cryptogen工具生成组织证书,主要包括两个步骤:
cryptogen generate --config=./crypto-config.yaml
将根据crypto-config.yaml中的配置生成证书./ccp-generate.sh
生成调用SDK的相关配置文件。# Generates Org certs using cryptogen tool
function generateCerts() {
which cryptogen
if [ "$?" -ne 0 ]; then
echo "cryptogen tool not found. exiting"
exit 1
fi
echo
echo "##########################################################"
echo "##### Generate certificates using cryptogen tool #########"
echo "##########################################################"
if [ -d "crypto-config" ]; then
rm -Rf crypto-config
fi
set -x
cryptogen generate --config=./crypto-config.yaml
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate certificates..."
exit 1
fi
echo
echo "Generate CCP files for Org1 and Org2"
./ccp-generate.sh
}
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
- Hostname: orderer2
- Hostname: orderer3
- Hostname: orderer4
- Hostname: orderer5
OrdererOrgs:
- Name: Orderer
Domain: example.com
Specs:
- Hostname: orderer
CommonName: myorderer.example.com
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
generateChannelArtifacts使用工具configtxgen,生成创世区块的脚本为:configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
,SampleMultiNodeEtcdRaft 用于生成创始区块,支持etcdraft模式的共识。
raft共识的创世区块配置如下,里面包含所有的raft节点配置:
SampleMultiNodeEtcdRaft:
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults # 引用OrdererDefaults详细配置
OrdererType: etcdraft # 排序类型为etcdraft
EtcdRaft:
Consenters: # 系统channel中raft节点配置
- Host: orderer.example.com
Port: 7050
ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
# 此处省略了其他orderer节点
Addresses:
- orderer.example.com:7050
- orderer2.example.com:8050
- orderer3.example.com:9050
- orderer4.example.com:10050
- orderer5.example.com:11050
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- <<: *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
orderer详细配置及配置项的说明:
Orderer: &OrdererDefaults
OrdererType: etcdraft
BatchTimeout: 2s # 打包区块的超时时间
BatchSize: # 控制打包到区块的交易量
MaxMessageCount: 10 # 打包到一个区块中的最大消息数量
AbsoluteMaxBytes: 99 MB # 打包到一个区块中允许的绝对最大字节数
PreferredMaxBytes: 512 KB # 打包到一个区块中的首选最大字节数
Organizations: # 参与orderer的组织列表
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation: # 指定orderer的区块中必须包含哪些orderer组织的签名,以便peer节点进行验证
Type: ImplicitMeta
Rule: "ANY Writers"
生成用户channe配置交易的脚本为:configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
,TwoOrgsChannel 用于生成两个组织的channel。
用户channel的配置及配置项的说明:
TwoOrgsChannel:
Consortium: SampleConsortium # 联盟名称
<<: *ChannelDefaults # 引用ChannelDefaults详细配置
Application:
<<: *ApplicationDefaults # 引用ApplicationDefaults详细配置
Organizations: # channel组织定义
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
用户channel的详细配置主要是针对channel的权限策略:
Channel: &ChannelDefaults
Policies: # channel权限策略
# Who may invoke the 'Deliver' API
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
# Who may invoke the 'Broadcast' API
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
# By default, who may modify elements at this config level
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
正如第2章节所分析的,节点容器启动脚本中的yaml文件默认是两个:docker-compose-cli.yaml、docker-compose-etcdraft2.yaml。
docker-compose-cli.yaml中将会启动6个容器,脚本中使用命令docker-compose -f docker-compose-cli.yaml up -d 2>&1
启动这些节点,包括:
docker-compose-etcdraft2.yaml中将会启动剩余的4个orderer容器,脚本中使用命令docker-compose -f docker-compose-etcdraft2.yaml up -d 2>&1
启动这些节点,包括:
第一个排序节点的yaml配置如下:
orderer.example.com:
extends:
file: base/docker-compose-base.yaml
service: orderer.example.com
container_name: orderer.example.com
networks:
- byfn
其中引入了外部的yaml文件base/docker-compose-base.yaml;引入的orderer.example.com的相关配置如下:
orderer.example.com:
container_name: orderer.example.com
extends:
file: peer-base.yaml
service: orderer-base
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.example.com:/var/hyperledger/production/orderer
ports:
- 7050:7050
再次引入了外部的peer-base.yaml文件,还定义了挂载目录、暴露的服务端口;peer-base.yaml中的orderer-base服务如下:
orderer-base:
image: hyperledger/fabric-orderer:$IMAGE_TAG
environment:
- FABRIC_LOGGING_SPEC=INFO
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_BOOTSTRAPMETHOD=file
- ORDERER_GENERAL_BOOTSTRAPFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- 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]
- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
里面定义了镜像名称、环境变量配置、工作目录、启动命令,环境变量配置包括监听地址、证书地址等。
orderer启动后会建立一个raft集群。
使用命令docker logs -f orderer.example.com
可查看到第一个orderer启动的日志,可查看到主要过程为:
peer的yaml文件配置结构与orderer类似,不在赘述。
使用命令docker logs -f peer0.org1.example.com
可查看到其中一个peer的启动日志:
日志中会输出容器的基本信息,peer节点启动过程主要是:
docker-compose-etcdraft2.yaml中将会启动剩余的4个orderer容器。脚本中使用命令docker-compose -f docker-compose-etcdraft2.yaml up -d 2>&1
启动这些节点。
查看一开始启动的第一个orderer的日志,可看到orderer.example.com以及成功连接其他raft节点,并且在raft 的term2,leader从orderer.example.com(0)变成orderer5.example.com(5)。
查看orderer5.example.com的日志,在term2 经过一轮投票后,orderer5获得5票回应成为了term2的raft leader。
Fabric网络已完全启动,docker ps
命令查看所有启动的节点:
感谢富强的博客:
https://blog.csdn.net/qq_28540443/article/details/104298137