本文在Ubuntu18.04运行,fabric版本为2.3.0。
Hyperledger Fabric环境搭建过程
注:假设所有的配置文件和数据文件都存放在目录/home/yulin/blockchain/fabric/Hyperledger中,下面的演示将采用直接运行模块可执行文件的方式,不采用Docker的方式运行。
启动Fabric之前首先需要生成相关的证书,生成证书是通过cryptogen模块完成的,cryptogen模块会根据提供的配置文件生成后序模块运行过程中需要的证书和数据文件。在生成证书之前需要先创建一个文件夹存放配置文件和生成的证书文件。
创建存放证书的文件夹:
mkdir -p /home/yulin/blockchain/fabric/Hyperledger/fabricconfig
cryptogen提供了一个命令可以获取cryptogen模块所需要的配置文件的样式:
cryptogen showtemplate
把上述命令生成的内容复制到一个文件中。
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer
Domain: example.com
EnableNodeOUs: false
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: false
# ---------------------------------------------------------------------------
# "CA"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of the CA for this
# organization. This entry is a Spec. See "Specs" section below for details.
# ---------------------------------------------------------------------------
# CA:
# Hostname: ca # implicitly ca.org1.example.com
# Country: US
# Province: California
# Locality: San Francisco
# OrganizationalUnit: Hyperledger Fabric
# StreetAddress: address for org # default nil
# PostalCode: postalCode for org # default nil
# ---------------------------------------------------------------------------
# "Specs"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of hosts in your
# configuration. Most users will want to use Template, below
#
# Specs is an array of Spec entries. Each Spec entry consists of two fields:
# - Hostname: (Required) The desired hostname, sans the domain.
# - CommonName: (Optional) Specifies the template or explicit override for
# the CN. By default, this is the template:
#
# "{
{.Hostname}}.{
{.Domain}}"
#
# which obtains its values from the Spec.Hostname and
# Org.Domain, respectively.
# - SANS: (Optional) Specifies one or more Subject Alternative Names
# to be set in the resulting x509. Accepts template
# variables {
{
.Hostname}}, {
{
.Domain}}, {
{
.CommonName}}. IP
# addresses provided here will be properly recognized. Other
# values will be taken as DNS names.
# NOTE: Two implicit entries are created for you:
# - {
{
.CommonName }}
# - {
{
.Hostname }}
# ---------------------------------------------------------------------------
# Specs:
# - Hostname: foo # implicitly "foo.org1.example.com"
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
# SANS:
# - "bar.{
{.Domain}}"
# - "altfoo.{
{.Domain}}"
# - "{
{.Hostname}}.org6.net"
# - 172.16.10.31
# - Hostname: bar
# - Hostname: baz
# ---------------------------------------------------------------------------
# "Template"
# ---------------------------------------------------------------------------
# Allows for the definition of 1 or more hosts that are created sequentially
# from a template. By default, this looks like "peer%d" from 0 to Count-1.
# You may override the number of nodes (Count), the starting index (Start)
# or the template used to construct the name (Hostname).
#
# Note: Template and Specs are not mutually exclusive. You may define both
# sections and the aggregate nodes will be created for you. Take care with
# name collisions
# ---------------------------------------------------------------------------
Template:
Count: 1
# Start: 5
# Hostname: {
{
.Prefix}}{
{
.Index}} # default
# SANS:
# - "{
{.Hostname}}.alt.{
{.Domain}}"
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
# ---------------------------------------------------------------------------
# Org2: See "Org1" for full specification
# ---------------------------------------------------------------------------
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: false
Template:
Count: 1
Users:
Count: 1
在上面的配置文件中有一个属性Domain,这个值是由用户设置的。
将上面的内容保存到/home/yulin/blockchain/fabric/Hyperledger/fabricconfig中,并命名为crypto-config.yaml。保存后执行如下命令:
cd /home/yulin/blockchain/fabric/Hyperledger/fabricconfig
cryptogen generate --config=crypto-config.yaml --output ./crypto-config
文件夹里面会新增加一个文件夹crypto-config,里面存放着本例的相关配置文件,通过tree查看一下生成证书文件的内容。
$ tree -L 5
.
├── crypto-config
│ ├── ordererOrganizations
│ │ └── example.com
│ │ ├── ca
│ │ │ ├── ca.example.com-cert.pem
│ │ │ └── priv_sk
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ └── tlscacerts
│ │ ├── orderers
│ │ │ └── orderer.example.com
│ │ ├── tlsca
│ │ │ ├── priv_sk
│ │ │ └── tlsca.example.com-cert.pem
│ │ └── users
│ │ └── Admin@example.com
│ └── peerOrganizations
│ ├── org1.example.com
│ │ ├── ca
│ │ │ ├── ca.org1.example.com-cert.pem
│ │ │ └── priv_sk
│ │ ├── msp
│ │ │ ├── admincerts
│ │ │ ├── cacerts
│ │ │ └── tlscacerts
│ │ ├── peers
│ │ │ └── peer0.org1.example.com
│ │ ├── tlsca
│ │ │ ├── priv_sk
│ │ │ └── tlsca.org1.example.com-cert.pem
│ │ └── users
│ │ ├── Admin@org1.example.com
│ │ └── User1@org1.example.com
│ └── org2.example.com
│ ├── ca
│ │ ├── ca.org2.example.com-cert.pem
│ │ └── priv_sk
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ └── tlscacerts
│ ├── peers
│ │ └── peer0.org2.example.com
│ ├── tlsca
│ │ ├── priv_sk
│ │ └── tlsca.org2.example.com-cert.pem
│ └── users
│ ├── Admin@org2.example.com
│ └── User1@org2.example.com
└── crypto-config.yaml
通过上述步骤所有的整数文件都已经生成完毕,现在需要将测试域名映射到本机的IP地址上面,否则后面的操作可能会出现错误。
从上述的内容中提取出后缀为example.com的域名。本例中提取出的信息如下:
orderer.example.com
peer0.org1.example.com
peer0.org2.example.com
打开端映射文件:
gedit /etc/hosts
添加上如下内容:
192.168.178.144 orderer.example.com
192.168.178.144 peer0.org1.example.com
192.168.178.144 peer0.org2.example.com
检查是否设置成功,只需使用ping,ping得通这说明设置成功。
Fabric是基于区块链的分布式账本,每个账本都拥有自己的区块链,账本的区块链中会存储账本的交易数据,但账本区块链中的第一个区块是个例外,该区块不存储交易数据而是存储配置信息。通常将账本的第一个区块称为创始块。综上所述,Fabric中账本的第一个区块是需要手动生成的。configtxgen模块是专门负责生成系统的创始块和Channel(Fabric中的Channel就是账本,关于Channel的概念在后续章节会介绍)的创始块。configtxgen模块也需要一个配置文件来定义相关的属性。
下面是在Fabric源码中提供的configtxgen模块所需要的配置文件的例子。该文件的路径是$GOPATH/src/github.com/hyperledger/fabric/sampleconfig,在这个目录下面有一个名为configtx.yaml的文件,对这个文件进行修改即可使用。由于创始块文件是提供给Orderer节点使用,因此创建一个文件夹来存储Oderer节点相关的文件。创建之后再把样例配置文件复制到该文件夹中。
创建存放configtxgen模块相关配置文件的文件夹的命令如下所示。
$ mkdir -p /home/yulin/blockchain/fabric/Hyperledger/order/
$ cp -r $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/configtx.yaml /home/yulin/blockchain/fabric/Hyperledger/order/
$ cd /home/yulin/blockchain/fabric/Hyperledger/order/
对configtx.yaml进行修改,修改后的内容如下所示:
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: ../fabricconfig/crypto-config/ordererOrganizations/example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: ../fabricconfig/crypto-config/peerOrganizations/org1.example.com/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.peer')"
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: ../fabricconfig/crypto-config/peerOrganizations/org2.example.com/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.peer')"
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Capabilities:
# Channel capabilities apply to both the orderers and the peers and must be
# supported by both.
# Set the value of the capability to true to require it.
Channel: &ChannelCapabilities
# V2.0 for Channel is a catchall flag for behavior which has been
# determined to be desired for all orderers and peers running at the v2.0.0
# level, but which would be incompatible with orderers and peers from
# prior releases.
# Prior to enabling V2.0 channel capabilities, ensure that all
# orderers and peers on a channel are at v2.0.0 or later.
V2_0: true
# Orderer capabilities apply only to the orderers, and may be safely
# used with prior release peers.
# Set the value of the capability to true to require it.
Orderer: &OrdererCapabilities
# V1.1 for Orderer is a catchall flag for behavior which has been
# determined to be desired for all orderers running at the v1.1.x
# level, but which would be incompatible with orderers from prior releases.
# Prior to enabling V2.0 orderer capabilities, ensure that all
# orderers on a channel are at v2.0.0 or later.
V2_0: true
# Application capabilities apply only to the peer network, and may be safely
# used with prior release orderers.
# Set the value of the capability to true to require it.
Application: &ApplicationCapabilities
# V2.0 for Application enables the new non-backwards compatible
# features and fixes of fabric v2.0.
# Prior to enabling V2.0 orderer capabilities, ensure that all
# orderers on a channel are at v2.0.0 or later.
V2_0: true
Application: &ApplicationDefaults
Organizations:
# Policies defines the set of policies at this level of the config tree
# For Application policies, their canonical path is
# /Channel/Application/<PolicyName>
Policies: &ApplicationDefaultPolicies
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 describes the application level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 10
AbsoluteMaxBytes: 99 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
Organizations:
# Policies defines the set of policies at this level of the config tree
# For Orderer policies, their canonical path is
# /Channel/Orderer/<PolicyName>
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
# BlockValidation specifies what signatures must be included in the block
# from the orderer for the peer to validate it.
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
# Capabilities describes the orderer level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *OrdererCapabilities
################################################################################
#
# CHANNEL
#
# This section defines the values to encode into a config transaction or
# genesis block for channel related parameters.
#
################################################################################
Channel: &ChannelDefaults
# Policies defines the set of policies at this level of the config tree
# For Channel policies, their canonical path is
# /Channel/<PolicyName>
Policies:
# 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 describes the channel level capabilities, see the
# dedicated Capabilities section elsewhere in this file for a full
# description
Capabilities:
<<: *ChannelCapabilities
Profiles:
TestTwoOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- <<: *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- <<: *Org1
- <<: *Org2
TestTwoOrgsChannel:
<<: *ChannelDefaults
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- <<: *Org1
- <<: *Org2
配置文件修改完成之后执行如下命令生成创始块文件。
$ cd /home/yulin/blockchain/fabric/Hyperledger/order
$ configtxgen -profile TestTwoOrgsOrdererGenesis -channelID syschannel -outputBlock ./orderer.genesis.block
2021-02-07 16:06:48.432 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-02-07 16:06:48.459 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: solo
2021-02-07 16:06:48.460 CST [common.tools.configtxgen.localconfig] Load -> INFO 003 Loaded configuration: /home/yulin/blockchain/fabric/Hyperledger/order/configtx.yaml
2021-02-07 16:06:48.761 CST [common.tools.configtxgen] doOutputBlock -> INFO 004 Generating genesis block
2021-02-07 16:06:48.768 CST [common.tools.configtxgen] doOutputBlock -> INFO 005 Creating system channel genesis block
2021-02-07 16:06:48.833 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Writing genesis block
上述命令执行完成之后会在文件夹/home/yulin/blockchain/fabric/Hyperledger/order中生成文件orderer.genesis.block。这是Fabric系统的创始块文件。
通道Channel是Fabric中非常重要的概念,一个Channel表示一个账本。Fabric和其他区块链平台最大的区别是fabric支持多账本。每个fabric应用都至少包含一个Channel,因此创建Channel是fabric中比较重要的步骤。
创建Channel命令:
$ configtxgen -profile TestTwoOrgsChannel -outputCreateChannelTx ./mychannel.tx -channelID mychannel
2021-02-09 16:25:12.501 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-02-09 16:25:12.524 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/yulin/blockchain/fabric/Hyperledger/order/configtx.yaml
2021-02-09 16:25:12.524 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2021-02-09 16:25:12.538 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
执行完之后会生成mychannel.tx,该文件用来生成Channel。除此之外还需要生成相关的锚点文件,而生成锚点文件需要执行以下命令:
$ configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
2021-02-09 16:31:18.108 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-02-09 16:31:18.150 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/yulin/blockchain/fabric/Hyperledger/order/configtx.yaml
2021-02-09 16:31:18.154 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Generating anchor peer update
2021-02-09 16:31:18.161 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 004 Writing anchor peer update
$ configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
2021-02-09 16:31:39.833 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2021-02-09 16:31:39.858 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /home/yulin/blockchain/fabric/Hyperledger/order/configtx.yaml
2021-02-09 16:31:39.858 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 003 Generating anchor peer update
2021-02-09 16:31:39.860 CST [common.tools.configtxgen] doOutputAnchorPeersUpdate -> INFO 004 Writing anchor peer update
命令执行完成之后会在相应的文件夹下面生成文件Org1MSPanchors.tx和Org2MSPanchors.tx,这些文件在后面会用到。