【区块链技术与应用】(二)

本地编译组件

获取代码

编译 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

请添加图片描述

编译安装peer组件

配置版本号和编译参数:

$ 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 路径下。

编译安装 Orderer 组件

通过如下命令编译并安装 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 组件

采用如下命令编译并安装 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

安装 Protobuf 支持和 Go 语言相关工具

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 <IMAGE_NAME:TAG>。
例如,从社区仓库直接获取 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 网络

生成组织关系和身份证书

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
|           `-- Admin@example.com/
`-- 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
    |       |-- Admin@org1.example.com/
    |       `-- 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/Admin@org1.example.com/。

生成系统通道初始区块

系统通道是网络启动后的首个通道,负责管理网络整体配置。排序节点在启动后,可以使用初始区块文件来创建一个新的网络。
初始区块中包括了排序服务的相关配置信息(如排序节点信息、块大小、最大通道数、默认策略等)和示例联盟配置。可以使用 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 节点。
请添加图片描述

启动 Orderer 节点

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
...

启动 Peer 节点

首先,检查配置路径( 默认为 /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 网络

除了上面讲解的手动部署的方式,读者还可以基于容器方式来快速部署 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







请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值