编译 Fabric 代码依赖一些开发库,可以通过如下命令安装:
sudo apt-get update \
&& sudo apt-get install -y libsnappy-dev zlib1g-dev libbz2-dev libyaml-dev libltdl-dev libtool
目前,Fabric 官方仓库托管在 Github 仓库(github.com/hyperledger/fabric)中供下载使用。
如果使用 1.13 之前版本的 Go 环境,需要将 Fabric 项目放到 $GOPATH 路径下。如下命令所示,创建 $GOPATH/src/github.com/hyperledger 目录结构并切换到该路径:
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
获取 Peer 和 Orderer 组件编译所需要的代码,两者目前在同一个 fabric 仓库中:
git clone https://github.com/hyperledger/fabric.git
为节约下载时间,读者可以指定 --single-branch -b master --depth 1 命令选项来指定只获取 master 分支最新代码:
git clone --single-branch -b master --depth 1 https://github.com/hyperledger/fabric.git
Fabric CA 组件在独立的 fabric-ca 仓库中,可以通过如下命令获取:
git clone https://github.com/hyperledger/fabric-ca.git
读者也可以直接访问 https://github.com/hyperledger/fabric/releases 和 https://github.com/hyperledger/fabric-ca/releases 来下载特定的 fabric 和 fabric-ca 发行版。
最后,检查确认 fabric 和 fabric-ca 两个仓库下载成功:
ls $GOPATH/src/github.com/hyperledger
fabric fabric-ca
配置版本号和编译参数:
$ PROJECT_VERSION=2.0.0
$ LD_FLAGS="-X github.com/hyperledger/fabric/common/metadata.Version=${PROJECT_VERSION} \
-X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric \
-X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger \
-X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger"
通过如下命令编译并安装 fabric 的 peer 组件到 $GOPATH/bin 下:
$ CGO_CFLAGS=" " go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/peer
当然,用户也可直接使用源码中的 Makefile 来进行编译,相关命令如下:
$ make peer
这种情况下编译生成的 peer 组件会默认放在 build/bin 路径下。
通过如下命令编译并安装 fabric orderer 组件到 $GOPATH/bin 下:
$ CGO_CFLAGS=" " go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/orderer
同样的,也可使用 Makefile 来编译安装 orderer 组件到 build/bin 路径下:
$ make orderer
采用如下命令编译并安装 fabric-ca 相关组件到 $GOPATH/bin 下:
$ go install -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=$PROJECT_VERSION -linkmode external -extldflags '-static -lpthread'" \
github.com/hyperledger/fabric-ca/cmd/...
Fabric 中还提供了一系列配置辅助工具,包括 cryptogen(本地生成组织结构和身份文件)、configtxgen(生成配置区块和配置交易)、configtxlator(解析转换配置信息)、discover(拓扑探测)、idemixgen(Idemix 证书生成)等,可以通过如下命令来快速编译和安装:
# 编译安装 cryptogen,等价于执行 make cryptogen
$ CGO_CFLAGS=" " \
go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/cryptogen
# 编译安装 configtxgen,等价于执行 make configtxgen
$ CGO_CFLAGS=" " \
go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/configtxgen
# 编译安装 configtxlator,等价于执行 make configtxlator
$ CGO_CFLAGS=" " \
go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/configtxlator
# 编译安装 discover,等价于执行 make discover
$ CGO_CFLAGS=" " \
go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/discover
# 编译安装 idemixgen,等价于执行 make idemixgen
$ CGO_CFLAGS=" " \
go install -tags "" -ldflags "$LD_FLAGS" \
github.com/hyperledger/fabric/cmd/idemixgen
另外,fabric 项目还提供了不少常见的编译命令,可以参考 Makefile 文件,例如编译所有的二进制文件可以使用如下命令:
$ make native
Fabric 代码由 Go 语言构建,开发者可以选择安装如下的 Go 语言相关工具,方便开发和调试:
$ go get github.com/golang/protobuf/protoc-gen-go \
&& go get github.com/maxbrunsfeld/counterfeiter/v6 \
&& go get github.com/axw/gocov/... \
&& go get github.com/AlekSi/gocov-xml \
&& go get golang.org/x/tools/cmd/goimports \
&& go get golang.org/x/lint/golint \
&& go get github.com/estesp/manifest-tool \
&& go get github.com/client9/misspell/cmd/misspell \
&& go get github.com/onsi/ginkgo/ginkgo
除了从源码编译外,还可以直接从 Dockerhub 来拉取相关的镜像,命令格式为 docker pull
例如,从社区仓库直接获取 fabric-peer、fabric-orderer、fabric-ca、fabric-tools 等镜像的 2.0.0 版本可以使用如下命令:
$ ARCH=amd64
$ BASEIMAGE_RELEASE=0.4.18
$ PROJECT_VERSION=2.0.0
# 拉取镜像
$ docker pull hyperledger/fabric-peer:$ARCH-$PROJECT_VERSION \
&& docker pull hyperledger/fabric-orderer:$ARCH-$PROJECT_VERSION \
&& docker pull hyperledger/fabric-ca:$ARCH-$PROJECT_VERSION \
&& docker pull hyperledger/fabric-tools:$ARCH-$PROJECT_VERSION \
&& docker pull hyperledger/fabric-ccenv:$ARCH-$PROJECT_VERSION \
&& docker pull hyperledger/fabric-baseimage:$ARCH-$BASEIMAGE_RELEASE \
&& docker pull hyperledger/fabric-baseos:$ARCH-$PROJECT_VERSION
此外,还可以从第三方仓库获取镜像,拉取后可以添加默认的镜像标签别名。
例如,笔者仓库中构建了基于 Golang 基础镜像的相关 fabric 镜像,可以通过如下命令获取:
# 拉取镜像
$ docker pull yeasy/hyperledger-fabric-base:$PROJECT_VERSION \
&& docker pull yeasy/hyperledger-fabric-peer:$PROJECT_VERSION \
&& docker pull yeasy/hyperledger-fabric-orderer:$PROJECT_VERSION \
&& docker pull yeasy/hyperledger-fabric-ca:$PROJECT_VERSION
# 添加标签
$ docker tag yeasy/hyperledger-fabric-peer:$PROJECT_VERSION hyperledger/fabric-peer:$ARCH-$PROJECT_VERSION \
&& docker tag yeasy/hyperledger-fabric-orderer:$PROJECT_VERSION hyperledger/fabric-orderer:$ARCH-$PROJECT_VERSION \
&& docker tag yeasy/hyperledger-fabric-ca:$PROJECT_VERSION hyperledger/fabric-ca:$ARCH-$PROJECT_VERSION \
&& docker tag yeasy/hyperledger-fabric-peer:$PROJECT_VERSION hyperledger/fabric-tools:$ARCH-$PROJECT_VERSION \
&& docker tag yeasy/hyperledger-fabric-base:$PROJECT_VERSION hyperledger/fabric-ccenv:$ARCH-$PROJECT_VERSION \
&& docker tag yeasy/hyperledger-fabric-base:$PROJECT_VERSION hyperledger/fabric-baseimage:$ARCH-$BASEIMAGE_RELEASE \
&& docker tag yeasy/hyperledger-fabric-base:$PROJECT_VERSION hyperledger/fabric-baseos:$ARCH-$PROJECT_VERSION
Fabric 网络作为联盟链,需要多个成员组织共同维护。成员之间通过身份来进行鉴权,网络通过身份来实现资源访问的权限管理。因此各成员组织都需要提前准备对应的身份文件,并部署到其所拥有的节点和客户端上。
用户可通过标准 PKI 服务(如使用 Fabric CA 实现)或 OpenSSL 工具来手动生成各个实体的证书和私钥。Fabric 项目还提供了 cryptogen 工具(基于 Golang crypto 标准库)在本地生成,需要提前准备 crypto-config.yaml 配置文件。
crypto-config.yaml 配置文件的结构十分简单,支持定义两种类型(OrdererOrgs 和 PeerOrgs)的若干组织。每个组织中又可以定义多个节点(Spec)和用户(User)。
一个示例的 crypto-config.yaml 配置文件内容如下,其中定义了一个 OrdererOrgs 类型的组织 example.com,包括 3 个节点;两个 PeerOrgs 类型的组织 org1.example.com 和 org2.example.com,分别包括 2 个节点和 1 个普通用户身份:
OrdererOrgs:
- Name: Orderer
Domain: example.com
CA:
Country: US
Province: California
Locality: San Francisco
Specs:
- Hostname: orderer0
- Hostname: orderer1
- Hostname: orderer2
PeerOrgs:
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
CA:
Country: US
Province: California
Locality: San Francisco
Template:
Count: 2
Users:
Count: 1
使用该配置文件,通过如下命令可生成指定组织结构的身份文件,并存放到 crypto-config 目录下:
$ cryptogen generate \
--config=./crypto-config.yaml \
--output ./crypto-config
用户修改配置后,还可以通过 extend 子命令来更新 crypto-config 目录:
$ cryptogen extend \
--config=./crypto-config.yaml \
--input ./crypto-config
查看刚生成的 crypto-config 目录,结构如下所示:
$ tree -L 4 crypto-config
crypto-config
|-- ordererOrganizations
| `-- example.com
| |-- ca
| | |-- 293def0fc6d07aab625308a3499cd97f8ffccbf9e9769bf4107d6781f5e8072b_sk
| | `-- ca.example.com-cert.pem
| |-- msp
| | |-- admincerts/
| | |-- cacerts/
| | `-- tlscacerts/
| |-- orderers
| | `-- orderer0.example.com/
| | `-- orderer1.example.com/
| | `-- orderer2.example.com/
| |-- tlsca
| | |-- 2be5353baec06ca695f7c3b04ca0932912601a4411939bfcfd44af18274d5a65_sk
| | `-- tlsca.example.com-cert.pem
| `-- users
| `-- [email protected]/
`-- peerOrganizations
|-- org1.example.com
| |-- ca
| | |-- 501c5f828f58dfa3f7ee844ea4cdd26318256c9b66369727afe8437c08370aee_sk
| | `-- ca.org1.example.com-cert.pem
| |-- msp
| | |-- admincerts/
| | |-- cacerts/
| | `-- tlscacerts/
| |-- peers
| | |-- peer0.org1.example.com/
| | `-- peer1.org1.example.com/
| |-- tlsca
| | |-- 592a08f84c99d6f083b3c5b9898b2ca4eb5fbb9d1e255f67df1fa14c123e4368_sk
| | `-- tlsca.org1.example.com-cert.pem
| `-- users
| |-- [email protected]/
| `-- User1@org1.example.com/
`-- org2.example.com
|-- ca
| |-- 86d97f9eb601868611eab5dc7df88b1f6e91e129160651e683162b958a728162_sk
| `-- ca.org2.example.com-cert.pem
|-- msp
| |-- admincerts/
| |-- cacerts/
| `-- tlscacerts/
|-- peers
| |-- peer0.org2.example.com/
| `-- peer1.org2.example.com/
|-- tlsca
| |-- 4b87c416978970948dffadd0639a64a2b03bc89f910cb6d087583f210fb2929d_sk
| `-- tlsca.org2.example.com-cert.pem
`-- users
|-- Admin@org2.example.com/
`-- User1@org2.example.com/
按照 crypto-config.yaml 中定义,crypto-config 目录下包括多级目录结构。其中 ordererOrganizations 下包括构成 Orderer 组织(包括 3 个 Orderer 节点)的身份信息;peerOrganizations 下为所有的 Peer 节点组织(包括2 个组织,4 个节点)的相关身份信息。各个实体都含有 msp 和 tls 目录,分别包括对应的认证身份文件和 TLS 身份文件(公钥证书、私钥等)。
对于 Orderer 节点来说,需要将 ordererOrganizations/example.com/orderers/ordererX.example.com 目录下内容(包括 msp 和 tls 两个子目录)复制到对应 Orderer 节点的配置路径(默认为 /etc/hyperledger/fabric)下。
对于 Peer 节点来说,则需要复制 peerOrganizations 下对应的身份证书文件。以 org1 的 peer0 为例,将 peerOrganizations/org1.example.com/peers/peer0.org1.example.com 目录下内容(包括 msp 和 tls)复制到 Peer0 节点的配置路径(默认为 /etc/hyperledger/fabric)下。
对于客户端节点来说,需要复制对应身份的用户目录,例如 Org1 的管理员身份为 peerOrganizations/org1.example.com/users/[email protected]/。
系统通道是网络启动后的首个通道,负责管理网络整体配置。排序节点在启动后,可以使用初始区块文件来创建一个新的网络。
初始区块中包括了排序服务的相关配置信息(如排序节点信息、块大小、最大通道数、默认策略等)和示例联盟配置。可以使用 configtxgen 工具生成。生成过程依赖 configtx.yaml 文件。
configtx.yaml 配置文件定义了整个网络中的相关配置和拓扑结构信息,用户可参考 sampleconfig/configtx.yaml 示例文件进行编写。这里采用如下内容,各个字段含义可参考后续配置说明章节:
Profiles:
TwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Capabilities:
<<: *ChannelCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
Organizations:
- &OrdererOrg
Name: OrdererOrg
SkipAsForeign: false
ID: OrdererMSP
MSPDir: msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
OrdererEndpoints:
- "orderer0.example.com:7050"
- "orderer1.example.com:7050"
- "orderer2.example.com:7050"
- &Org1
Name: Org1MSP
SkipAsForeign: false
ID: Org1MSP
MSPDir: msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org1MSP.member')"
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
SkipAsForeign: false
ID: Org2MSP
MSPDir: msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org2MSP.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org2MSP.member')"
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
Application: &ApplicationDefaults
ACLs: &ACLsDefault
_lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers
_lifecycle/QueryChaincodeDefinition: /Channel/Application/Readers
_lifecycle/QueryNamespaceDefinitions: /Channel/Application/Readers
lscc/ChaincodeExists: /Channel/Application/Readers
lscc/GetDeploymentSpec: /Channel/Application/Readers
lscc/GetChaincodeData: /Channel/Application/Readers
lscc/GetInstantiatedChaincodes: /Channel/Application/Readers
qscc/GetChainInfo: /Channel/Application/Readers
qscc/GetBlockByNumber: /Channel/Application/Readers
qscc/GetBlockByHash: /Channel/Application/Readers
qscc/GetTransactionByID: /Channel/Application/Readers
qscc/GetBlockByTxID: /Channel/Application/Readers
cscc/GetConfigBlock: /Channel/Application/Readers
peer/Propose: /Channel/Application/Writers
peer/ChaincodeToChaincode: /Channel/Application/Readers
event/Block: /Channel/Application/Readers
event/FilteredBlock: /Channel/Application/Readers
Organizations:
Policies:
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
OrdererType: etcdraft
Addresses:
- orderer0.example.com:7050
- orderer1.example.com:7050
- orderer2.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 500
AbsoluteMaxBytes: 10 MB
PreferredMaxBytes: 2 MB
MaxChannels: 0
EtcdRaft:
Consenters:
- Host: orderer0.example.com
Port: 7050
ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt
ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt
- Host: orderer1.example.com
Port: 7050
ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crt
ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crt
- Host: orderer2.example.com
Port: 7050
ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
Options:
TickInterval: 500ms
ElectionTick: 10
HeartbeatTick: 1
MaxInflightBlocks: 5
SnapshotIntervalSize: 16 MB
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Capabilities:
<<: *OrdererCapabilities
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
该配置文件中定义了两个模板:TwoOrgsOrdererGenesis 和 TwoOrgsChannel,其中前者定义了系统通道配置,可以用来创建系统通道所需初始区块文件;后者定义了应用通道配置,可以用来新建应用通道。排序服务的共识类型采用了 Raft 模式。
可通过如下命令指定使用 configtx.yaml 文件中定义的 TwoOrgsOrdererGenesis 模板,来生成系统通道的初始区块文件:
$ export SYS_CHANNEL=testchainid
$ export ORDERER_GENESIS_PROFILE=TwoOrgsOrdererGenesis
$ export ORDERER_GENESIS=orderer.genesis.block
$ configtxgen \
-configPath ./ \
-channelID ${SYS_CHANNEL} \
-profile ${ORDERER_GENESIS_PROFILE} \
-outputBlock ${ORDERER_GENESIS}
将所生成的初始区块文件复制到排序节点上 ORDERER_GENERAL_BOOTSTRAPFILE 指定路径(默认为 /etc/hyperledger/fabric)下,供启动排序节点使用。
新建应用通道需要先生成配置交易文件,其中包括了属于该通道的组织结构信息,这些信息会写入到该应用通道的初始区块中。
同样使用 configtx.yaml 配置文件和 configtxgen 工具,注意这里使用 TwoOrgsChannel 模板。
采用如下命令来生成配置交易文件,通道中包括两个初始成员:Org1 和 Org2:
$ export APP_CHANNEL=businesschannel
$ export APP_CHANNEL_PROFILE=TwoOrgsChannel
$ configtxgen \
-configPath ./ \
-channelID ${APP_CHANNEL} \
-profile ${APP_CHANNEL_PROFILE} \
-outputCreateChannelTx ${APP_CHANNEL}.tx
所生成的配置交易文件在后续步骤被客户端所使用,需要复制到客户端节点上。
注:状态数据库如果选择 CouchDB 类型,应用通道名称只能包括小写的 ASCII 字符、点或中划线,并且首字符必须为字母,总长度不超过 249 个字符。该限制详情可参考 FAB-2487。
锚节点用来辅助通道内多个组织之间的节点发现,修改锚节点需要发送更新通道配置交易。
同样,基于 configtx.yaml 配置文件,为每个组织都生成配置交易文件,注意需要需要使用对应的组织身份:
$ export UPDATE_ANCHOR_ORG1_TX=Org1MSPanchors.tx
$ export UPDATE_ANCHOR_ORG2_TX=Org2MSPanchors.tx
$ configtxgen \
-configPath ./ \
-channelID ${APP_CHANNEL} \
-profile ${APP_CHANNEL_PROFILE} \
-asOrg Org1MSP \
-outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG1_TX}
$ configtxgen \
-configPath ./ \
-channelID ${APP_CHANNEL} \
-profile ${APP_CHANNEL_PROFILE} \
-asOrg Org2MSP \
-outputAnchorPeersUpdate ${UPDATE_ANCHOR_ORG1_TX}
所生成的锚节点配置更新文件会在后续步骤被客户端所使用,因此需要复制到客户端节点上。
所有配置文件都准备完毕后,即可启动网络。首先要启动 Orderer 节点,然后启动 Peer 节点。
FABRIC_LOGGING_SPEC="info:orderer.common.blockcutter,orderer.operations=warning:orderer.common.cluster=debug"
ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
ORDERER_GENERAL_LISTENPORT=7050
ORDERER_GENERAL_BOOTSTRAPMETHOD=file
ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block
ORDERER_GENERAL_LOCALMSPID=OrdererMSP
ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp
ORDERER_GENERAL_LEDGERTYPE=file
ORDERER_GENERAL_TLS_ENABLED=true
ORDERER_GENERAL_TLS_PRIVATEKEY=/etc/hyperledger/fabric/tls/server.key
ORDERER_GENERAL_TLS_CERTIFICATE=/etc/hyperledger/fabric/tls/server.crt
ORDERER_GENERAL_TLS_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]
ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:8443
CORE_METRICS_PROVIDER=prometheus
之后,用户可以采用如下命令来启动 Orderer 节点。启动成功后可以看到本地输出的开始提供服务的消息,此时 Orderer 采用指定的初始区块文件成功创建了系统通道:
$ orderer start
[orderer/common/server] prettyPrintStruct -> INFO 002 Orderer config values:
General.LedgerType = "file"
General.ListenAddress = "0.0.0.0"
General.ListenPort = 7050
General.TLS.Enabled = true
...
[orderer/common/server] Start -> INFO 007 Beginning to serve requests
...
首先,检查配置路径( 默认为 /etc/hyperledger/fabric )下相关文件是否就绪:
配置文件 core.yaml(可以参考 sampleconfig/core.yaml),指定了节点相关配置;
生成的 msp 文件目录、tls 文件目录,存放身份信息。
Peer 节点的配置可通过配置文件或环境变量方式进行指定,场景设置如下表所示。
FABRIC_LOGGING_SPEC="info:msp,gossip=warning:chaincode=debug"
CORE_PEER_ID=peer0.org1.example.com
CORE_PEER_LISTENADDRESS=0.0.0.0:7051
CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER= false
CORE_PEER_LOCALMSPID=Org1MSP
CORE_PEER_MSPCOCORE_VM_ENDPOINT=unix:///var/run/docker.sockNFIGPATH=msp
CORE_VM_ENDPOINT=unix:///var/run/docker.sock
CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host
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_OPERATIONS_LISTENADDRESS=0.0.0.0:9443
CORE_METRICS_PROVIDER=prometheus
配置完成后,用户可以采用如下命令在多个服务器上分别启动 Peer 服务,启动成功后可以看到本地输出的日志消息:
$ peer node start
UTC [ledgermgmt] initialize -> INFO 002 Starting peer:
Version: 2.0.0
Commit SHA: development build
Go version: go1.13.4
OS/Arch: linux/amd64
Chaincode:
Base Docker Namespace: hyperledger
Base Docker Label: org.hyperledger.fabric
Docker Namespace: hyperledger"
...
UTC [nodeCmd] serve -> INFO 01e Started peer with ID=[name:"peer0.org1.example.com" ], network ID=[dev], address=[peer0.org1.example.com:7051]
...
此时,Peer 节点已经启动起来,会尝试通过 gossip 发现邻居节点。
Peer 节点启动后,由于尚未跟 Orderer 建立连接,暂时还未加入网络中的应用通道。
下面在客户端发送请求给 Orderer 创建应用通道,并让 Peer 节点加入到通道中。
默认情况下,只有联盟中成员组织的管理员身份才可以创建应用通道。例如使用 Org1 的管理员身份来创建新的应用通道,需要指定 msp 的 ID、msp 文件所在路径、排序服务地址、应用通道名称和新建通道交易文件,如果启用了 TLS,还需要指定排序服务的 TLSCA 的证书位置:
$ APP_CHANNEL=businesschannel
$ TIMEOUT=30
$ CORE_PEER_LOCALMSPID="Org1MSP" \
CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp \
peer channel create \
-o orderer.example.com:7050 \
-c ${APP_CHANNEL} \
-f ./$APP_CHANNEL.tx \
--timeout "${TIMEOUT}s" \
--tls \
--cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
通道创建成功后,会在本地生成其初始区块文件(businesschannel.block),其中带有通道的初始配置信息和排序服务信息等。只有拥有该文件的 Peer 节点才可能加入到对应的通道中。
应用通道的成员组织的 Peer 都可以加入到通道中。
在客户端使用管理员身份依次让组织 Org1 和 Org2 中所有节点都加入新的应用通道。操作需要指定所操作的 Peer 的地址,以及通道的初始区块。
以 Org1 中的 peer0 节点为例,可以执行如下操作:
$ CORE_PEER_LOCALMSPID="Org1MSP" \
CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp \
CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \
peer channel join \
-b ${APP_CHANNEL}.block
Peer joined the channel!
此时,所操作的 Peer(如果成为组织的 Gossip Leader)会自动连接到应用通道指定的排序服务,开始接收区块。
锚节点(作为组织内成员代表)负责跟其它组织节点进行信息交换。通道配置内会记录各组织的锚节点列表信息,Peer 通过访问其他组织的锚节点来获取其他组织内的 Peer 信息。
使用锚节点配置更新文件,组织管理员可以更新通道中相关配置。
例如,在客户端使用 Org1 的管理员身份来更新锚节点,如下所示:
$ CORE_PEER_LOCALMSPID="Org1MSP" \
CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp \
peer channel update \
-o orderer.example.com:7050 \
-c ${APP_CHANNEL} \
-f ${UPDATE_ANCHOR_ORG1_TX} \
--tls \
--cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
锚节点配置更新后,同一通道内不同组织之间的 Peer 也可以进行 Gossip 通信,共同维护通道账本。后续,用户可以在通道内通过智能合约更新账本记录。
除了上面讲解的手动部署的方式,读者还可以基于容器方式来快速部署 Fabric 网络并验证功能。
首先,按照如下命令下载 Docker-Compose 模板文件,并进入 hyperledger_fabric 目录,可以看到有对应多个 Fabric 版本的项目,用户可以根据需求选用特定版本:
git clone https://github.com/yeasy/docker-compose-files
cd docker-compose-files/hyperledger_fabric
以 Fabric 2.0.0 版本为例,进入到对应目录下,并先下载所需镜像文件:
cd v2.0.0
make download
查看目录下内容,主要包括若干 Docker-Compose 模板文件,主要包括:
docker-compose-2orgs-4peer-raft.yaml:包括 4 个 peer 节点(属于两个组织)、3 个
Orderer 节点(Raft 模式)、2 个 CA 节点、1 个客户端节点;
docker-compose-1orgs-1peers-dev.yaml:包括 1 个 peer 节点、1 个 Orderer 节点、1
个 CA 节点、1 个客户端节点。本地 Fabric 源码被挂载到了客户端节点中,方便进行调试;
docker-compose-2orgs-4peer-kafka.yaml:包括 4 个 peer 节点(属于两个组织)、3 个
Orderer 节点(Kafka 模式)、2 个 CA 节点、1 个客户端节点;
docker-compose-2orgs-4peer-couchdb.yaml:包括 4 个 peer 节点(属于两个组织,启用
couchDB 作为状态数据库)、2 个 Orderer 节点、1 个 CA 节点、1 个客户端节点。
使用 Make 命令进行操作。例如使用 HLF_MODE 指定排序服务为 Raft 模式,快速启动网络并执行一系列测试:
HLF_MODE=raft make test
运行过程中会自动创建网络并逐个完成通道和链码的相关测试,注意查看输出日志中无错误信息。
网络启动后,可以通过 docker ps 命令查看本地系统中运行的容器信息
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1ee7db027b3f yeasy/hyperledger-fabric-peer:2.0.0 "peer node start" 27 seconds ago Up 22 seconds 9443/tcp, 0.0.0.0:8051->7051/tcp peer1.org1.example.com
8f7bffcd14b3 yeasy/hyperledger-fabric-peer:2.0.0 "peer node start" 27 seconds ago Up 22 seconds 9443/tcp, 0.0.0.0:10051->7051/tcp peer1.org2.example.com
8a4e9aaec7ba yeasy/hyperledger-fabric-peer:2.0.0 "peer node start" 27 seconds ago Up 22 seconds 9443/tcp, 0.0.0.0:9051->7051/tcp peer0.org2.example.com
7b9d394f26c0 yeasy/hyperledger-fabric-peer:2.0.0 "peer node start" 27 seconds ago Up 23 seconds 0.0.0.0:7051->7051/tcp, 9443/tcp peer0.org1.example.com
ce9ca6c7b672 yeasy/hyperledger-fabric-orderer:2.0.0 "orderer start" 30 seconds ago Up 27 seconds 8443/tcp, 0.0.0.0:8050->7050/tcp orderer1.example.com
2646b7f0e462 yeasy/hyperledger-fabric:2.0.0 "bash -c 'cd /tmp; s…" 30 seconds ago Up 15 seconds 7050-7054/tcp fabric-cli
c35e8694c634 yeasy/hyperledger-fabric-orderer:2.0.0 "orderer start" 30 seconds ago Up 27 seconds 8443/tcp, 0.0.0.0:9050->7050/tcp orderer2.example.com
1d6dd5009141 yeasy/hyperledger-fabric-orderer:2.0.0 "orderer start" 30 seconds ago Up 27 seconds 0.0.0.0:7050->7050/tcp, 8443/tcp orderer0.example.com
用户如果希望在客户端、Peer 或 Orderer 容器内执行命令,可以通过 make cli|peer|orderer 命令进入到容器中。
例如,如下命令可以让用户登录到客户端节点,在其中以指定身份发送网络请求:
make cli
用户也可以通过如下命令来查看日志输出:
make logs
一、环境准备
1、apt换源
https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/
sudo gedit /etc/apt/sources.list
sudo apt update
2、安装docker、docker-compose
sudo apt install docker docker-compose
sudo systemctl enable docker
sudo usermod -a -G docker <username>
3、安装golang
https://go.dev/doc/install
sudo su
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.6.linux-amd64.tar.gz
gedit /etc/profile
export PATH=$PATH:/usr/local/go/bin
gedit ~/.bashrc
source /etc/profile
4、docker加速器
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
二、安装fabric-sample
1、手动创建脚本,安装samples、docker
https://github.com/hyperledger/fabric/blob/main/scripts/bootstrap.sh
修改binaries=false
sudo chmod u+x bootstrap.sh
./bootstrap.sh
2、安装binaries
https://github.com/hyperledger/fabric/releases/download/v2.4.6/hyperledger-fabric-linux-amd64-2.4.6.tar.gz
https://github.com/hyperledger/fabric-ca/releases/download/v1.5.5/hyperledger-fabric-ca-linux-amd64-1.5.5.tar.gz
tar -xzvf 压缩包名 -C 目的地
3、配置go代理
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct