当前位置: 首页 > news >正文

Hyperledger Fabric Docker 方式多机部署生产网络

规划网络拓扑

3 个 orderer 节点;组织 org1 , org1 下有两个 peer 节点, peer0 和 peer1; 组织 org2 , org2 下有两个 peer 节点, peer0 和 peer1;

因为我只有 3 台虚拟机资源所以没法实现完全的多机部署,资源使用规划如下:

节点宿主机 IPhosts端口
cli192.168.0.105N/AN/A
orderer0192.168.0.105orderer0.example.com7050
orderer1192.168.0.105orderer1.example.com8050
orderer2192.168.0.105orderer2.example.com9050
org1-peer0192.168.0.109peer0.org1.example.com7051
org1-peer1192.168.0.109peer1.org1.example.com8051
org2-peer0192.168.0.110peer0.org2.example.com7051
org2-peer1192.168.0.110peer1.org2.example.com8051
vim /etc/hosts# 新增192.168.0.105 orderer0.example.com
192.168.0.105 orderer1.example.com
192.168.0.105 orderer2.example.com192.168.0.109 peer0.org1.example.com
192.168.0.109 peer1.org1.example.com192.168.0.110 peer0.org2.example.com
192.168.0.110 peer1.org2.example.com

生成网络需要的身份文件

Fabric 项目还提供了 cryptogen 工具来在本地生身份文件,这种方式需要提供一个 crypto-config.yaml 配置文件。

准备 crypto-config.yaml 配置文件

生成的文件内容如下:

./cryptogen showtemplate > ../crypto-config.yaml

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:# ---------------------------------------------------------------------------# Orderer# ---------------------------------------------------------------------------- Name: OrdererDomain: example.comEnableNodeOUs: false# ---------------------------------------------------------------------------# "Specs" - See PeerOrgs below for complete description# ---------------------------------------------------------------------------Specs:- Hostname: orderer# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:# ---------------------------------------------------------------------------# Org1# ---------------------------------------------------------------------------- Name: Org1Domain: org1.example.comEnableNodeOUs: 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: Org2Domain: org2.example.comEnableNodeOUs: falseTemplate:Count: 1Users:Count: 1

按照规划的网络拓扑对 crypto-config.yaml 进行修改:


# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:# ---------------------------------------------------------------------------# Orderer# ---------------------------------------------------------------------------- Name: OrdererDomain: example.comEnableNodeOUs: true# ---------------------------------------------------------------------------# "Specs" - See PeerOrgs below for complete description# ---------------------------------------------------------------------------Specs:- Hostname: orderer0- Hostname: orderer1- Hostname: orderer2SANS:- "*"- "192.168.0.105"# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:# ---------------------------------------------------------------------------# Org1# ---------------------------------------------------------------------------- Name: Org1Domain: org1.example.comEnableNodeOUs: trueTemplate:Count: 2# Start: 5# Hostname: {{.Prefix}}{{.Index}} # default# SANS:#   - "{{.Hostname}}.alt.{{.Domain}}"SANS:- "*"- "192.168.0.109"# ---------------------------------------------------------------------------# "Users"# ---------------------------------------------------------------------------# Count: The number of user accounts _in addition_ to Admin# ---------------------------------------------------------------------------Users:Count: 1# ---------------------------------------------------------------------------# Org2: See "Org1" for full specification# ---------------------------------------------------------------------------- Name: Org2Domain: org2.example.comEnableNodeOUs: falseTemplate:Count: 2SANS:- "*"- "192.168.0.110"Users:Count: 1

生成组织身份文件

根据 crypto-config.yaml 配置文件生成组织身份文件并保存在 ../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 目录结构如下:

crypto-config
├── ordererOrganizations
│   └── example.com
│       ├── ca
│       │   ├── ca.example.com-cert.pem
│       │   └── priv_sk
│       ├── msp
│       │   ├── admincerts
│       │   ├── cacerts
│       │   │   └── ca.example.com-cert.pem
│       │   ├── config.yaml
│       │   └── tlscacerts
│       │       └── tlsca.example.com-cert.pem
│       ├── orderers
│       │   ├── orderer0.example.com
│       │   │   ├── msp
│       │   │   │   ├── admincerts
│       │   │   │   ├── cacerts
│       │   │   │   │   └── ca.example.com-cert.pem
│       │   │   │   ├── config.yaml
│       │   │   │   ├── keystore
│       │   │   │   │   └── priv_sk
│       │   │   │   ├── signcerts
│       │   │   │   │   └── orderer0.example.com-cert.pem
│       │   │   │   └── tlscacerts
│       │   │   │       └── tlsca.example.com-cert.pem
│       │   │   └── tls
│       │   │       ├── ca.crt
│       │   │       ├── server.crt
│       │   │       └── server.key
│       │   ├── orderer1.example.com
│       │   │   ├── msp
│       │   │   │   ├── admincerts
│       │   │   │   ├── cacerts
│       │   │   │   │   └── ca.example.com-cert.pem
│       │   │   │   ├── config.yaml
│       │   │   │   ├── keystore
│       │   │   │   │   └── priv_sk
│       │   │   │   ├── signcerts
│       │   │   │   │   └── orderer1.example.com-cert.pem
│       │   │   │   └── tlscacerts
│       │   │   │       └── tlsca.example.com-cert.pem
│       │   │   └── tls
│       │   │       ├── ca.crt
│       │   │       ├── server.crt
│       │   │       └── server.key
│       │   └── orderer2.example.com
│       │       ├── msp
│       │       │   ├── admincerts
│       │       │   ├── cacerts
│       │       │   │   └── ca.example.com-cert.pem
│       │       │   ├── config.yaml
│       │       │   ├── keystore
│       │       │   │   └── priv_sk
│       │       │   ├── signcerts
│       │       │   │   └── orderer2.example.com-cert.pem
│       │       │   └── tlscacerts
│       │       │       └── tlsca.example.com-cert.pem
│       │       └── tls
│       │           ├── ca.crt
│       │           ├── server.crt
│       │           └── server.key
│       ├── tlsca
│       │   ├── priv_sk
│       │   └── tlsca.example.com-cert.pem
│       └── users
│           └── Admin@example.com
│               ├── msp
│               │   ├── admincerts
│               │   ├── cacerts
│               │   │   └── ca.example.com-cert.pem
│               │   ├── config.yaml
│               │   ├── keystore
│               │   │   └── priv_sk
│               │   ├── signcerts
│               │   │   └── Admin@example.com-cert.pem
│               │   └── tlscacerts
│               │       └── tlsca.example.com-cert.pem
│               └── tls
│                   ├── ca.crt
│                   ├── client.crt
│                   └── client.key
└── peerOrganizations├── org1.example.com│   ├── ca│   │   ├── ca.org1.example.com-cert.pem│   │   └── priv_sk│   ├── msp│   │   ├── admincerts│   │   ├── cacerts│   │   │   └── ca.org1.example.com-cert.pem│   │   ├── config.yaml│   │   └── tlscacerts│   │       └── tlsca.org1.example.com-cert.pem│   ├── peers│   │   ├── peer0.org1.example.com│   │   │   ├── msp│   │   │   │   ├── admincerts│   │   │   │   ├── cacerts│   │   │   │   │   └── ca.org1.example.com-cert.pem│   │   │   │   ├── config.yaml│   │   │   │   ├── keystore│   │   │   │   │   └── priv_sk│   │   │   │   ├── signcerts│   │   │   │   │   └── peer0.org1.example.com-cert.pem│   │   │   │   └── tlscacerts│   │   │   │       └── tlsca.org1.example.com-cert.pem│   │   │   └── tls│   │   │       ├── ca.crt│   │   │       ├── server.crt│   │   │       └── server.key│   │   └── peer1.org1.example.com│   │       ├── msp│   │       │   ├── admincerts│   │       │   ├── cacerts│   │       │   │   └── ca.org1.example.com-cert.pem│   │       │   ├── config.yaml│   │       │   ├── keystore│   │       │   │   └── priv_sk│   │       │   ├── signcerts│   │       │   │   └── peer1.org1.example.com-cert.pem│   │       │   └── tlscacerts│   │       │       └── tlsca.org1.example.com-cert.pem│   │       └── tls│   │           ├── ca.crt│   │           ├── server.crt│   │           └── server.key│   ├── tlsca│   │   ├── priv_sk│   │   └── tlsca.org1.example.com-cert.pem│   └── users│       ├── Admin@org1.example.com│       │   ├── msp│       │   │   ├── admincerts│       │   │   ├── cacerts│       │   │   │   └── ca.org1.example.com-cert.pem│       │   │   ├── config.yaml│       │   │   ├── keystore│       │   │   │   └── priv_sk│       │   │   ├── signcerts│       │   │   │   └── Admin@org1.example.com-cert.pem│       │   │   └── tlscacerts│       │   │       └── tlsca.org1.example.com-cert.pem│       │   └── tls│       │       ├── ca.crt│       │       ├── client.crt│       │       └── client.key│       └── User1@org1.example.com│           ├── msp│           │   ├── admincerts│           │   ├── cacerts│           │   │   └── ca.org1.example.com-cert.pem│           │   ├── config.yaml│           │   ├── keystore│           │   │   └── priv_sk│           │   ├── signcerts│           │   │   └── User1@org1.example.com-cert.pem│           │   └── tlscacerts│           │       └── tlsca.org1.example.com-cert.pem│           └── tls│               ├── ca.crt│               ├── client.crt│               └── client.key└── org2.example.com├── ca│   ├── ca.org2.example.com-cert.pem│   └── priv_sk├── msp│   ├── admincerts│   │   ├── Admin@org2.example.com-cert.pem│   │   └── ca.org2.example.com-cert.pem│   ├── cacerts│   │   └── ca.org2.example.com-cert.pem│   └── tlscacerts│       └── tlsca.org2.example.com-cert.pem├── peers│   ├── peer0.org2.example.com│   │   ├── msp│   │   │   ├── admincerts│   │   │   │   └── Admin@org2.example.com-cert.pem│   │   │   ├── cacerts│   │   │   │   └── ca.org2.example.com-cert.pem│   │   │   ├── keystore│   │   │   │   └── priv_sk│   │   │   ├── signcerts│   │   │   │   └── peer0.org2.example.com-cert.pem│   │   │   └── tlscacerts│   │   │       └── tlsca.org2.example.com-cert.pem│   │   └── tls│   │       ├── ca.crt│   │       ├── server.crt│   │       └── server.key│   └── peer1.org2.example.com│       ├── msp│       │   ├── admincerts│       │   │   └── Admin@org2.example.com-cert.pem│       │   ├── cacerts│       │   │   └── ca.org2.example.com-cert.pem│       │   ├── keystore│       │   │   └── priv_sk│       │   ├── signcerts│       │   │   └── peer1.org2.example.com-cert.pem│       │   └── tlscacerts│       │       └── tlsca.org2.example.com-cert.pem│       └── tls│           ├── ca.crt│           ├── server.crt│           └── server.key├── tlsca│   ├── priv_sk│   └── tlsca.org2.example.com-cert.pem└── users├── Admin@org2.example.com│   ├── msp│   │   ├── admincerts│   │   │   └── Admin@org2.example.com-cert.pem│   │   ├── cacerts│   │   │   └── ca.org2.example.com-cert.pem│   │   ├── keystore│   │   │   └── priv_sk│   │   ├── signcerts│   │   │   └── Admin@org2.example.com-cert.pem│   │   └── tlscacerts│   │       └── tlsca.org2.example.com-cert.pem│   └── tls│       ├── ca.crt│       ├── client.crt│       └── client.key└── User1@org2.example.com├── msp│   ├── admincerts│   │   └── User1@org2.example.com-cert.pem│   ├── cacerts│   │   └── ca.org2.example.com-cert.pem│   ├── keystore│   │   └── priv_sk│   ├── signcerts│   │   └── User1@org2.example.com-cert.pem│   └── tlscacerts│       └── tlsca.org2.example.com-cert.pem└── tls├── ca.crt├── client.crt└── client.key

crypto-config 目录拷贝到另外两台机器上:

scp -r crypto-config root@192.168.0.109:/usr/project/fabric-docker-multiple/crypto-configscp -r crypto-config root@192.168.0.110:/usr/project/fabric-docker-multiple/crypto-config

生成系统通道初始区块

可以使用 configtxgen 工具生成,生成过程依赖 conf igtx.yaml 配置文件,configtx.yaml 配置文件定义了整个网络中的相关配置和拓扑结构信息 。

编辑 configtx.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#---
################################################################################
#
#   ORGANIZATIONS
#
#   This section defines the organizational identities that can be referenced
#   in the configuration profiles.
#
################################################################################
Organizations:# SampleOrg defines an MSP using the sampleconfig. It should never be used# in production but may be used as a template for other definitions.- &OrdererOrg# Name is the key by which this org will be referenced in channel# configuration transactions.# Name can include alphanumeric characters as well as dots and dashes.Name: OrdererOrg# SkipAsForeign can be set to true for org definitions which are to be# inherited from the orderer system channel during channel creation.  This# is especially useful when an admin of a single org without access to the# MSP directories of the other orgs wishes to create a channel.  Note# this property must always be set to false for orgs included in block# creation.SkipAsForeign: false# ID is the key by which this org's MSP definition will be referenced.# ID can include alphanumeric characters as well as dots and dashes.ID: OrdererMSP# MSPDir is the filesystem path which contains the MSP configuration.MSPDir: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/msp# Policies defines the set of policies at this level of the config tree# For organization policies, their canonical path is usually#   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>Policies:Readers:Type: SignatureRule: "OR('OrdererMSP.member')"# If your MSP is configured with the new NodeOUs, you might# want to use a more specific rule like the following:# Rule: "OR('SampleOrg.admin', 'SampleOrg.peer', 'SampleOrg.client')"Writers:Type: SignatureRule: "OR('OrdererMSP.member')"# If your MSP is configured with the new NodeOUs, you might# want to use a more specific rule like the following:# Rule: "OR('SampleOrg.admin', 'SampleOrg.client')"Admins:Type: SignatureRule: "OR('OrdererMSP.admin')"Endorsement:Type: SignatureRule: "OR('OrdererMSP.member')"# OrdererEndpoints is a list of all orderers this org runs which clients# and peers may to connect to to push transactions and receive blocks respectively.OrdererEndpoints:- "orderer0.example.com:7050"- "orderer1.example.com:8050"- "orderer2.example.com:9050"# AnchorPeers defines the location of peers which can be used for# cross-org gossip communication.## NOTE: this value should only be set when using the deprecated# `configtxgen --outputAnchorPeersUpdate` command. It is recommended# to instead use the channel configuration update process to set the# anchor peers for each organization.#AnchorPeers:#    - Host: 127.0.0.1#      Port: 7051- &Org1Name: Org1MSPID: Org1MSPMSPDir: /usr/project/fabric-docker-multiple/crypto-config/peerOrganizations/org1.example.com/mspPolicies:Readers:Type: SignatureRule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"Writers:Type: SignatureRule: "OR('Org1MSP.admin', 'Org1MSP.client')"Admins:Type: SignatureRule: "OR('Org1MSP.admin')"Endorsement:Type: SignatureRule: "OR('Org1MSP.peer')"AnchorPeers:- Host: peer0.org1.example.comPort: 7051- &Org2Name: Org2MSPID: Org2MSPMSPDir: /usr/project/fabric-docker-multiple/crypto-config/peerOrganizations/org2.example.com/mspPolicies:Readers:Type: SignatureRule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"Writers:Type: SignatureRule: "OR('Org2MSP.admin', 'Org2MSP.client')"Admins:Type: SignatureRule: "OR('Org2MSP.admin')"Endorsement:Type: SignatureRule: "OR('Org2MSP.peer')"AnchorPeers:- Host: peer0.org2.example.comPort: 7051################################################################################
#
#   CAPABILITIES
#
#   This section defines the capabilities of fabric network. This is a new
#   concept as of v1.1.0 and should not be utilized in mixed networks with
#   v1.0.x peers and orderers.  Capabilities define features which must be
#   present in a fabric binary for that binary to safely participate in the
#   fabric network.  For instance, if a new MSP type is added, newer binaries
#   might recognize and validate the signatures from this type, while older
#   binaries without this support would be unable to validate those
#   transactions.  This could lead to different versions of the fabric binaries
#   having different world states.  Instead, defining a capability for a channel
#   informs those binaries without this capability that they must cease
#   processing transactions until they have been upgraded.  For v1.0.x if any
#   capabilities are defined (including a map with all capabilities turned off)
#   then the v1.0.x peer will deliberately crash.
#
################################################################################
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
#
#   This section defines the values to encode into a config transaction or
#   genesis block for application-related parameters.
#
################################################################################
Application: &ApplicationDefaultsACLs: &ACLsDefault# This section provides defaults for policies for various resources# in the system. These "resources" could be functions on system chaincodes# (e.g., "GetBlockByNumber" on the "qscc" system chaincode) or other resources# (e.g.,who can receive Block events). This section does NOT specify the resource's# definition or API, but just the ACL policy for it.## Users can override these defaults with their own policy mapping by defining the# mapping under ACLs in their channel definition#---New Lifecycle System Chaincode (_lifecycle) function to policy mapping for access control--## ACL policy for _lifecycle's "CheckCommitReadiness" function_lifecycle/CheckCommitReadiness: /Channel/Application/Writers# ACL policy for _lifecycle's "CommitChaincodeDefinition" function_lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers# ACL policy for _lifecycle's "QueryChaincodeDefinition" function_lifecycle/QueryChaincodeDefinition: /Channel/Application/Writers# ACL policy for _lifecycle's "QueryChaincodeDefinitions" function_lifecycle/QueryChaincodeDefinitions: /Channel/Application/Writers#---Lifecycle System Chaincode (lscc) function to policy mapping for access control---## ACL policy for lscc's "getid" functionlscc/ChaincodeExists: /Channel/Application/Readers# ACL policy for lscc's "getdepspec" functionlscc/GetDeploymentSpec: /Channel/Application/Readers# ACL policy for lscc's "getccdata" functionlscc/GetChaincodeData: /Channel/Application/Readers# ACL Policy for lscc's "getchaincodes" functionlscc/GetInstantiatedChaincodes: /Channel/Application/Readers#---Query System Chaincode (qscc) function to policy mapping for access control---## ACL policy for qscc's "GetChainInfo" functionqscc/GetChainInfo: /Channel/Application/Readers# ACL policy for qscc's "GetBlockByNumber" functionqscc/GetBlockByNumber: /Channel/Application/Readers# ACL policy for qscc's  "GetBlockByHash" functionqscc/GetBlockByHash: /Channel/Application/Readers# ACL policy for qscc's "GetTransactionByID" functionqscc/GetTransactionByID: /Channel/Application/Readers# ACL policy for qscc's "GetBlockByTxID" functionqscc/GetBlockByTxID: /Channel/Application/Readers#---Configuration System Chaincode (cscc) function to policy mapping for access control---## ACL policy for cscc's "GetConfigBlock" functioncscc/GetConfigBlock: /Channel/Application/Readers# ACL policy for cscc's "GetChannelConfig" functioncscc/GetChannelConfig: /Channel/Application/Readers#---Miscellaneous peer function to policy mapping for access control---## ACL policy for invoking chaincodes on peerpeer/Propose: /Channel/Application/Writers# ACL policy for chaincode to chaincode invocationpeer/ChaincodeToChaincode: /Channel/Application/Writers#---Events resource to policy mapping for access control###---## ACL policy for sending block eventsevent/Block: /Channel/Application/Readers# ACL policy for sending filtered block eventsevent/FilteredBlock: /Channel/Application/Readers# Organizations lists the orgs participating on the application side of the# network.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: &ApplicationDefaultPoliciesLifecycleEndorsement:Type: ImplicitMetaRule: "MAJORITY Endorsement"Endorsement:Type: ImplicitMetaRule: "MAJORITY Endorsement"Readers:Type: ImplicitMetaRule: "ANY Readers"Writers:Type: ImplicitMetaRule: "ANY Writers"Admins:Type: ImplicitMetaRule: "MAJORITY Admins"# Capabilities describes the application level capabilities, see the# dedicated Capabilities section elsewhere in this file for a full# descriptionCapabilities:<<: *ApplicationCapabilities################################################################################
#
#   ORDERER
#
#   This section defines the values to encode into a config transaction or
#   genesis block for orderer related parameters.
#
################################################################################
Orderer: &OrdererDefaults# Orderer Type: The orderer implementation to start.# Available types are "solo", "kafka" and "etcdraft".OrdererType: etcdraft# Addresses used to be the list of orderer addresses that clients and peers# could connect to.  However, this does not allow clients to associate orderer# addresses and orderer organizations which can be useful for things such# as TLS validation.  The preferred way to specify orderer addresses is now# to include the OrdererEndpoints item in your org definitionAddresses:- orderer0.example.com:7050- orderer1.example.com:8050- orderer2.example.com:9050# Batch Timeout: The amount of time to wait before creating a batch.BatchTimeout: 2s# Batch Size: Controls the number of messages batched into a block.# The orderer views messages opaquely, but typically, messages may# be considered to be Fabric transactions.  The 'batch' is the group# of messages in the 'data' field of the block.  Blocks will be a few kb# larger than the batch size, when signatures, hashes, and other metadata# is applied.BatchSize:# Max Message Count: The maximum number of messages to permit in a# batch.  No block will contain more than this number of messages.MaxMessageCount: 500# Absolute Max Bytes: The absolute maximum number of bytes allowed for# the serialized messages in a batch. The maximum block size is this value# plus the size of the associated metadata (usually a few KB depending# upon the size of the signing identities). Any transaction larger than# this value will be rejected by ordering.# It is recommended not to exceed 49 MB, given the default grpc max message size of 100 MB# configured on orderer and peer nodes (and allowing for message expansion during communication).AbsoluteMaxBytes: 10 MB# Preferred Max Bytes: The preferred maximum number of bytes allowed# for the serialized messages in a batch. Roughly, this field may be considered# the best effort maximum size of a batch. A batch will fill with messages# until this size is reached (or the max message count, or batch timeout is# exceeded).  If adding a new message to the batch would cause the batch to# exceed the preferred max bytes, then the current batch is closed and written# to a block, and a new batch containing the new message is created.  If a# message larger than the preferred max bytes is received, then its batch# will contain only that message.  Because messages may be larger than# preferred max bytes (up to AbsoluteMaxBytes), some batches may exceed# the preferred max bytes, but will always contain exactly one transaction.PreferredMaxBytes: 2 MB# Max Channels is the maximum number of channels to allow on the ordering# network. When set to 0, this implies no maximum number of channels.MaxChannels: 0Kafka:# Brokers: A list of Kafka brokers to which the orderer connects. Edit# this list to identify the brokers of the ordering service.# NOTE: Use IP:port notation.Brokers:- kafka0:9092- kafka1:9092- kafka2:9092# EtcdRaft defines configuration which must be set when the "etcdraft"# orderertype is chosen.EtcdRaft:# The set of Raft replicas for this network. For the etcd/raft-based# implementation, we expect every replica to also be an OSN. Therefore,# a subset of the host:port items enumerated in this list should be# replicated under the Orderer.Addresses key above.Consenters:- Host: orderer0.example.comPort: 7050ClientTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crtServerTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt- Host: orderer1.example.comPort: 8050ClientTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crtServerTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crt- Host: orderer2.example.comPort: 9050ClientTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crtServerTLSCert: /usr/project/fabric-docker-multiple/crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt# Options to be specified for all the etcd/raft nodes. The values here# are the defaults for all new channels and can be modified on a# per-channel basis via configuration updates.Options:# TickInterval is the time interval between two Node.Tick invocations.TickInterval: 500ms# ElectionTick is the number of Node.Tick invocations that must pass# between elections. That is, if a follower does not receive any# message from the leader of current term before ElectionTick has# elapsed, it will become candidate and start an election.# ElectionTick must be greater than HeartbeatTick.ElectionTick: 10# HeartbeatTick is the number of Node.Tick invocations that must# pass between heartbeats. That is, a leader sends heartbeat# messages to maintain its leadership every HeartbeatTick ticks.HeartbeatTick: 1# MaxInflightBlocks limits the max number of in-flight append messages# during optimistic replication phase.MaxInflightBlocks: 5# SnapshotIntervalSize defines number of bytes per which a snapshot is takenSnapshotIntervalSize: 16 MB# Organizations lists the orgs participating on the orderer side of the# network.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: ImplicitMetaRule: "ANY Readers"Writers:Type: ImplicitMetaRule: "ANY Writers"Admins:Type: ImplicitMetaRule: "MAJORITY Admins"# BlockValidation specifies what signatures must be included in the block# from the orderer for the peer to validate it.BlockValidation:Type: ImplicitMetaRule: "ANY Writers"# Capabilities describes the orderer level capabilities, see the# dedicated Capabilities section elsewhere in this file for a full# descriptionCapabilities:<<: *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' APIReaders:Type: ImplicitMetaRule: "ANY Readers"# Who may invoke the 'Broadcast' APIWriters:Type: ImplicitMetaRule: "ANY Writers"# By default, who may modify elements at this config levelAdmins:Type: ImplicitMetaRule: "MAJORITY Admins"# Capabilities describes the channel level capabilities, see the# dedicated Capabilities section elsewhere in this file for a full# descriptionCapabilities:<<: *ChannelCapabilities################################################################################
#
#   PROFILES
#
#   Different configuration profiles may be encoded here to be specified as
#   parameters to the configtxgen tool. The profiles which specify consortiums
#   are to be used for generating the orderer genesis block. With the correct
#   consortium members defined in the orderer genesis block, channel creation
#   requests may be generated with only the org member names and a consortium
#   name.
#
################################################################################
Profiles:TwoOrgsOrdererGenesis:<<: *ChannelDefaultsOrderer:<<: *OrdererDefaultsOrganizations:- *OrdererOrgCapabilities:<<: *OrdererCapabilitiesConsortiums:SampleConsortium:Organizations:- *Org1- *Org2TwoOrgsChannel:Consortium: SampleConsortium<<: *ChannelDefaultsApplication:<<: *ApplicationDefaultsOrganizations:- *Org1- *Org2Capabilities:<<: *ApplicationCapabilities

生成创世区块:

./configtxgen -configPath ../config  -profile TwoOrgsOrdererGenesis -channelID fabric-channel -outputBlock ../channel-artifacts/orderer.genesis.block

channel-artifacts/
└── orderer.genesis.block

生成通道文件:

./configtxgen -configPath ../config  -profile TwoOrgsChannel  -channelID businesschannel -outputCreateChannelTx ../channel-artifacts/businesschannel.tx

channel-artifacts/
├── businesschannel.tx
└── orderer.genesis.block

生成锚节点配置更新文件:

./configtxgen -configPath ../config  -profile TwoOrgsChannel -channelID businesschannel -asOrg Org1MSP -outputAnchorPeersUpdate ../channel-artifacts/Org1MSPanchors.tx./configtxgen -configPath ../config  -profile TwoOrgsChannel -channelID businesschannel -asOrg Org2MSP -outputAnchorPeersUpdate ../channel-artifacts/Org2MSPanchors.tx
channel-artifacts/
├── businesschannel.tx
├── orderer.genesis.block
├── Org1MSPanchors.tx
└── Org2MSPanchors.tx

channel-artifacts 目录拷贝到另外两台机器上:

scp -r channel-artifacts/ root@192.168.0.109:/usr/project/fabric-docker-multiple/channel-artifactsscp -r channel-artifacts/ root@192.168.0.110:/usr/project/fabric-docker-multiple/channel-artifacts

部署 orderer 节点

编写 orderer 节点 docker-compose 文件

参考 docker-compose 文件:https://github.com/yeasy/docker-compose-files/tree/master/hyperledger_fabri

编写 orderer 节点 docker-compose 文件

version: '2.0'services:cli:image: hyperledger/fabric-tools:2.4.1restart: alwayscontainer_name: fabric-clihostname: fabric-clitty: trueextra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- CORE_PEER_ID=fabric-cli- CORE_PEER_ADDRESS=peer0.org1.example.com:7051 # default to operate on peer0.org1- CORE_PEER_LOCALMSPID=Org1MSP- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp- FABRIC_LOGGING_SPEC=DEBUG- FABRIC_LOGGING_FORMAT=%{color}[%{id:03x} %{time:01-02 15:04:05.00 MST}] [%{module}] %{shortfunc} -> %{level:.4s}%{color:reset} %{message}- CORE_PEER_TLS_ENABLED=true  # to enable TLS, change to true- ORDERER_CA=/etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pemvolumes:- ./config/crypto-config.yaml:/etc/hyperledger/fabric/crypto-config.yaml- ./config/configtx.yaml:/etc/hyperledger/fabric/configtx.yaml- ./crypto-config:/etc/hyperledger/fabric/crypto-config- ./channel-artifacts:/tmp/channel-artifacts- ./chaincodes:/etc/hyperledger/fabric/chaincodesworking_dir: /opt/gopath/src/github.com/hyperledger/fabric/peercommand: bash -c 'cd /tmp; source scripts/func.sh; while true; do sleep 20170504; done'orderer0.example.com:  # There can be multiple orderersimage: hyperledger/fabric-orderer:2.4.1restart: alwayscontainer_name: orderer0.example.comhostname: orderer0.example.comports:- "7050:7050"extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1- ORDERER_GENERAL_LISTENPORT=7050- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp- ORDERER_GENERAL_LEDGERTYPE=file#- ORDERER_GENERAL_LEDGERTYPE=json  # default: file- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443  # operation RESTful API- ORDERER_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from orderer via /metrics RESTful API#- ORDERER_RAMLEDGER_HISTORY_SIZE=100  #only useful when use ram ledger# enabled TLS- ORDERER_GENERAL_TLS_ENABLED=true # default: false- 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]# Only required by raft mode- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]- FABRIC_LOGGING_SPEC=DEBUGvolumes:- ./crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/:/etc/hyperledger/fabric/tls- ./channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.blockexpose:- "7050"  # gRPC- "8443"  # Operation RESTcommand: orderer startorderer1.example.com:image: hyperledger/fabric-orderer:2.4.1restart: alwayscontainer_name: orderer1.example.comhostname: orderer1.example.comports:- "8050:7050"extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=DEBUG- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1- ORDERER_GENERAL_LISTENPORT=7050- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp- ORDERER_GENERAL_LEDGERTYPE=file#- ORDERER_GENERAL_LEDGERTYPE=json  # default: file- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443  # operation RESTful API- ORDERER_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from orderer via /metrics RESTful API#- ORDERER_RAMLEDGER_HISTORY_SIZE=100  #only useful when use ram ledger# enabled TLS- ORDERER_GENERAL_TLS_ENABLED=true # default: false- 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]# Only required by raft mode- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]- ORDERER_GENERAL_CLUSTER_SENDBUFFERSIZE=10volumes:- ./crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/:/etc/hyperledger/fabric/tls- ./channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.blockcommand: orderer start    orderer2.example.com:image: hyperledger/fabric-orderer:2.4.1restart: alwayscontainer_name: orderer2.example.comhostname: orderer2.example.comports:- "9050:7050"extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=DEBUG  # default: INFO- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 # default: 127.0.0.1- ORDERER_GENERAL_LISTENPORT=7050- ORDERER_GENERAL_GENESISMETHOD=file # default: provisional- ORDERER_GENERAL_BOOTSTRAPFILE=/etc/hyperledger/fabric/orderer.genesis.block # by default, all materials should be put under $FABRIC_CFG_PATH, which defaults to /etc/hyperledger/fabric- ORDERER_GENERAL_LOCALMSPID=OrdererMSP # default: DEFAULT- ORDERER_GENERAL_LOCALMSPDIR=/etc/hyperledger/fabric/msp- ORDERER_GENERAL_LEDGERTYPE=file#- ORDERER_GENERAL_LEDGERTYPE=json  # default: file- ORDERER_OPERATIONS_LISTENADDRESS=0.0.0.0:8443  # operation RESTful API- ORDERER_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from orderer via /metrics RESTful API#- ORDERER_RAMLEDGER_HISTORY_SIZE=100  #only useful when use ram ledger# enabled TLS- ORDERER_GENERAL_TLS_ENABLED=true # default: false- 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]# Only required by raft mode- ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/etc/hyperledger/fabric/tls/server.key- ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/etc/hyperledger/fabric/tls/server.crt- ORDERER_GENERAL_CLUSTER_ROOTCAS=[/etc/hyperledger/fabric/tls/ca.crt]- ORDERER_GENERAL_CLUSTER_SENDBUFFERSIZE=10volumes:- ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/:/etc/hyperledger/fabric/tls- ./channel-artifacts/orderer.genesis.block:/etc/hyperledger/fabric/orderer.genesis.blockcommand: orderer start

启动 orderer 节点:

docker-compose -f docker-compose-3orderer.yaml up -d

如果想停止并且删除服务:

docker-compose -f docker-compose-3orderer.yaml down

部署 org1 peer 节点

编写 docker-compose 文件

version: '2.0'services:peer0.org1.example.com:image: hyperledger/fabric-peer:2.4.1restart: alwayscontainer_name: peer0.org1.example.comhostname: peer0.org1.example.comports:- 7051:7051- 7052:7052- 9443:9443extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=INFO- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- CORE_PEER_ADDRESSAUTODETECT=false- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host  # uncomment this to use specific network- CORE_PEER_GOSSIP_USELEADERELECTION=true- CORE_PEER_GOSSIP_ORGLEADER=false  # whether this node is the org leader, default to false- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443  # operation RESTful API- CORE_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from fabric via /metrics RESTful API- CORE_PEER_PROFILE_ENABLED=false- 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_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.4.1- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.4.1- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.4.1- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4.1- CORE_PEER_ID=peer0.org1.example.com- CORE_PEER_ADDRESS=peer0.org1.example.com:7051- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051- CORE_PEER_LOCALMSPID=Org1MSP- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug- CORE_LEDGER_STATE_STATEDATABASE=CouchDB- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer0.org1.couchdb:5984- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpwvolumes:- /var/run/docker.sock:/var/run/docker.sock- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tlsexpose:- "7051"  # gRPC- "9443"  # Operation REST#command: bash -c 'bash /tmp/peer_build.sh; peer node start'command: peer node startdepends_on:- orderer0.example.com- orderer1.example.com- orderer2.example.com- peer0.org1.couchdbpeer1.org1.example.com:image: hyperledger/fabric-peer:2.4.1restart: alwayscontainer_name: peer1.org1.example.comhostname: peer1.org1.example.comports:- 8051:7051- 8052:7052- 9444:9443extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=INFO- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- CORE_PEER_ADDRESSAUTODETECT=false- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host  # uncomment this to use specific network- CORE_PEER_GOSSIP_USELEADERELECTION=true- CORE_PEER_GOSSIP_ORGLEADER=false  # whether this node is the org leader, default to false- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443  # operation RESTful API- CORE_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from fabric via /metrics RESTful API- CORE_PEER_PROFILE_ENABLED=false- 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_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.4.1- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.4.1- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.4.1- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4.1- CORE_PEER_ID=peer1.org1.example.com- CORE_PEER_ADDRESS=peer1.org1.example.com:8051- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052- CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8052- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051- CORE_PEER_LOCALMSPID=Org1MSP- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug- CORE_LEDGER_STATE_STATEDATABASE=CouchDB- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer1.org1.couchdb:5984- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpwvolumes:- /var/run/docker.sock:/var/run/docker.sock- ./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tlsexpose:- "8051"  # gRPC- "8052"  # chaincode- "9444"  # Operation REST#command: bash -c 'bash /tmp/peer_build.sh; peer node start'command: peer node startdepends_on:- orderer0.example.com- orderer1.example.com- orderer2.example.com- peer1.org1.couchdbpeer0.org1.couchdb:image: couchdb:3.1.1container_name: peer0.org1.couchdbports:- 5984:5984  # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/environment:- COUCHDB_USER=admin- COUCHDB_PASSWORD=adminpwpeer1.org1.couchdb:image: couchdb:3.1.1container_name: peer1.org1.couchdbports:- 6984:5984  # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/environment:- COUCHDB_USER=admin- COUCHDB_PASSWORD=adminpw

启动 org1 peer 节点:

docker-compose -f docker-compose-org1-2peer.yaml up -d

如果看到如下报错,是因为关闭了防火墙之后没有重启 docker 服务。service docker restart [+] Running 0/1 ⠿ Network fabric-docker-multiple_default Error 0.4s failed to create network fabric-docker-multiple_default: Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-7ed0ba02c359 -j RETURN: iptables: No chain/target/match by that name. (exit status 1))


部署 org2 peer 节点

编写 docker-compose 文件

version: '2.0'services:peer0.org2.example.com:image: hyperledger/fabric-peer:2.4.1restart: alwayscontainer_name: peer0.org2.example.comhostname: peer0.org2.example.comports:- 7051:7051- 7052:7052- 9443:9443extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=INFO- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- CORE_PEER_ADDRESSAUTODETECT=false- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host  # uncomment this to use specific network- CORE_PEER_GOSSIP_USELEADERELECTION=true- CORE_PEER_GOSSIP_ORGLEADER=false  # whether this node is the org leader, default to false- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443  # operation RESTful API- CORE_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from fabric via /metrics RESTful API- CORE_PEER_PROFILE_ENABLED=false- 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_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.4.1- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.4.1- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.4.1- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4.1- CORE_PEER_ID=peer0.org2.example.com- CORE_PEER_ADDRESS=peer0.org2.example.com:7051- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051- CORE_PEER_LOCALMSPID=Org2MSP- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug- CORE_LEDGER_STATE_STATEDATABASE=CouchDB- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer0.org1.couchdb:5984- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpwvolumes:- /var/run/docker.sock:/var/run/docker.sock- ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tlsexpose:- "7051"  # gRPC- "9443"  # Operation REST#command: bash -c 'bash /tmp/peer_build.sh; peer node start'command: peer node startdepends_on:- orderer0.example.com- orderer1.example.com- orderer2.example.com- peer0.org1.couchdbpeer1.org2.example.com:image: hyperledger/fabric-peer:2.4.1restart: alwayscontainer_name: peer1.org2.example.comhostname: peer1.org2.example.comports:- 8051:7051- 8052:7052- 9444:9443extra_hosts:- "orderer0.example.com:192.168.0.105"- "orderer1.example.com:192.168.0.105"- "orderer2.example.com:192.168.0.105"- "peer0.org1.example.com:192.168.0.109"- "peer1.org1.example.com:192.168.0.109"- "peer0.org2.example.com:192.168.0.110"- "peer1.org2.example.com:192.168.0.110"environment:- FABRIC_LOGGING_SPEC=INFO- FABRIC_LOGGING_FORMAT="%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}"- CORE_PEER_ADDRESSAUTODETECT=false- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=host  # uncomment this to use specific network- CORE_PEER_GOSSIP_USELEADERELECTION=true- CORE_PEER_GOSSIP_ORGLEADER=false  # whether this node is the org leader, default to false- CORE_OPERATIONS_LISTENADDRESS=0.0.0.0:9443  # operation RESTful API- CORE_METRICS_PROVIDER=prometheus  # prometheus will pull metrics from fabric via /metrics RESTful API- CORE_PEER_PROFILE_ENABLED=false- 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_CHAINCODE_BUILDER=hyperledger/fabric-ccenv:2.4.1- CORE_CHAINCODE_GOLANG_RUNTIME=hyperledger/fabric-baseos:2.4.1- CORE_CHAINCODE_JAVA_RUNTIME=hyperledger/fabric-javaenv:2.4.1- CORE_CHAINCODE_NODE_RUNTIME=hyperledger/fabric-nodeenv:2.4.1- CORE_PEER_ID=peer1.org2.example.com- CORE_PEER_ADDRESS=peer1.org2.example.com:8051- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052- CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:8052- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:8051- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:8051- CORE_PEER_LOCALMSPID=Org2MSP- FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug- CORE_LEDGER_STATE_STATEDATABASE=CouchDB- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer1.org2.couchdb:5984- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpwvolumes:- /var/run/docker.sock:/var/run/docker.sock- ./crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp- ./crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tlsexpose:- "8051"  # gRPC- "9444"  # Operation REST#command: bash -c 'bash /tmp/peer_build.sh; peer node start'command: peer node startdepends_on:- orderer0.example.com- orderer1.example.com- orderer2.example.com- peer1.org2.couchdbpeer0.org1.couchdb:image: couchdb:3.1.1container_name: peer0.org1.couchdbports:- 5984:5984  # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/environment:- COUCHDB_USER=admin- COUCHDB_PASSWORD=adminpwpeer1.org2.couchdb:image: couchdb:3.1.1container_name: peer1.org2.couchdbports:- 6984:5984  # this is the restful API addr, can also access fauxton web ui thru http://localhost:5984/_utils/environment:- COUCHDB_USER=admin- COUCHDB_PASSWORD=adminpw

启动 org2 peer 节点:

docker-compose -f docker-compose-org2-2peer.yaml up -d


创建通道

进入 cli 容器:

docker exec -it fabric-cli bash
export APP_CHANNEL=businesschannel
export TIMEOUT=30
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msppeer channel create -o orderer0.example.com:7050 -c ${APP_CHANNEL} -f "/tmp/channel-artifacts/$APP_CHANNEL.tx" --timeout "${TIMEOUT}s" --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

创建成功后会在当前路径下生成 businesschannel.block 文件。

mv businesschannel.block /tmp/channel-artifacts/

加入通道

进入 cli 容器:

docker exec -it fabric-cli bash

org1-peer0 加入通道:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051peer channel join -b /tmp/channel-artifacts/businesschannel.block

结果如下:

[020 02-18 03:57:28.30 UTC] [channelCmd] executeJoin -> INFO Successfully submitted proposal to join channel

org1-peer1 加入通道:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer1.org1.example.com:8051peer channel join -b /tmp/channel-artifacts/businesschannel.block

org2-peer0 加入通道:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051peer channel join -b /tmp/channel-artifacts/businesschannel.block

org2-peer1 加入通道:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer1.org2.example.com:8051peer channel join -b /tmp/channel-artifacts/businesschannel.block

更新锚节点

org1 更新锚节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051peer channel update -o orderer0.example.com:7050 -c businesschannel -f /tmp/channel-artifacts/Org1MSPanchors.tx --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

org2 更新锚节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051peer channel update -o orderer0.example.com:7050 -c businesschannel -f /tmp/channel-artifacts/Org2MSPanchors.tx --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

锚节点配置更新后,同一通道内不同组织之间的 Peer 也可以进行 Gossip 通信,共同维护通道账本。后续,用户可以通过智能合约使用通道账本。


安装链码

进入 cli 容器:

docker exec -it fabric-cli bash

在宿主机和 docker cli 容器挂载的 chaincodes 目录下下载合约代码:

git clone https://gitee.com/kernelHP/hyperledger-fabric-contract-java-demo.gitcd hyperledger-fabric-contract-java-demo/

编译打包源码:

mvn compile package -DskipTests -Dmaven.test.skip=true
mv target/chaincode.jar $PWD# 删除编译后产生的 target 目录; src 源代码目录; pom.xml
rm -rf target/ src pom.xml

得到如下结构目录:

hyperledger-fabric-contract-java-demo/
├── chaincode.jar
├── collections_config.json
├── META-INF
│   └── statedb
│       └── couchdb
│           └── indexes
│               └── indexNameColor.json

打包链码

peer lifecycle chaincode package hyperledger-fabric-contract-java-demo.tar.gz --path ./hyperledger-fabric-contract-java-demo/ --lang java --label hyperledger-fabric-contract-java-demo_1

在 peer 节点安装链码

cd /etc/hyperledger/fabric/chaincodes/

org1-peer0 节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051peer lifecycle chaincode install hyperledger-fabric-contract-java-demo.tar.gz

结果如下:

[020 02-18 03:26:06.78 UTC] [cli.lifecycle.chaincode] submitInstallProposal -> INFO Installed remotely: response:<status:200 payload:"\nhhyperledger-fabric-contract-java-demo_1:bbc6a881b7cf349cd608a608d32e638b546341575e48614524761ab51fc6a457\022'hyperledger-fabric-contract-java-demo_1" > 
[021 02-18 03:26:06.78 UTC] [cli.lifecycle.chaincode] submitInstallProposal -> INFO Chaincode code package identifier: hyperledger-fabric-contract-java-demo_1:bbc6a881b7cf349cd608a608d32e638b546341575e48614524761ab51fc6a457

org1-peer1 节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer1.org1.example.com:8051peer lifecycle chaincode install hyperledger-fabric-contract-java-demo.tar.gz

org2-peer0 节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051peer lifecycle chaincode install hyperledger-fabric-contract-java-demo.tar.gz

org2-peer1 节点:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer1.org2.example.com:8051peer lifecycle chaincode install hyperledger-fabric-contract-java-demo.tar.gz

查询包 ID:

peer lifecycle chaincode queryinstalled

包 ID 是链码标签和链码二进制文件的哈希值的组合。每个 peer 节点将生成相同的包 ID。你应该看到类似于以下内容的输出:

Installed chaincodes on peer:
Package ID: hyperledger-fabric-contract-java-demo_1:bbc6a881b7cf349cd608a608d32e638b546341575e48614524761ab51fc6a457, Label: hyperledger-fabric-contract-java-demo_1

将包 ID 保存为环境变量:

export CC_PACKAGE_ID=hyperledger-fabric-contract-java-demo_1:bbc6a881b7cf349cd608a608d32e638b546341575e48614524761ab51fc6a457

批准链码定义

org1 批准链码定义:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051peer lifecycle chaincode approveformyorg -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --channelID businesschannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

结果如下:

[025 02-18 05:37:12.44 UTC] [chaincodeCmd] ClientWait -> INFO txid [895c0d4b9eee30419e068072b816906f660c1f9ddb7400b63d6892a001470c38] committed with status (VALID) at peer0.org1.example.com:7051

org2 批准链码定义:

export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051peer lifecycle chaincode approveformyorg -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --channelID businesschannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

检查通道成员是否已批准相同的链码定义:

peer lifecycle chaincode checkcommitreadiness --channelID businesschannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

输出结果如下:

{"approvals": {"Org1MSP": true,"Org2MSP": true}
}

将链码提交到通道:

peer lifecycle chaincode commit -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --channelID businesschannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

结果如下:

[029 02-18 05:50:47.62 UTC] [chaincodeCmd] ClientWait -> INFO txid [2c06365cd94ebcc95e4fc6e5a5334aafda35e874bf894ef604fd3a9fe18d86be] committed with status (VALID) at peer0.org2.example.com:7051
[02a 02-18 05:50:47.81 UTC] [chaincodeCmd] ClientWait -> INFO txid [2c06365cd94ebcc95e4fc6e5a5334aafda35e874bf894ef604fd3a9fe18d86be] committed with status (VALID) at peer0.org1.example.com:7051

peer lifecycle chaincode querycommitted 命令来确认链码定义已提交给通道:

peer lifecycle chaincode querycommitted --channelID businesschannel --name hyperledger-fabric-contract-java-demo --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

结果如下:

Committed chaincode definition for chaincode 'hyperledger-fabric-contract-java-demo' on channel 'businesschannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]

调用链码


# 调用 createCat 函数
peer chaincode invoke -o orderer0.example.com:7050 --ordererTLSHostnameOverride orderer0.example.com --tls --cafile /etc/hyperledger/fabric/crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C businesschannel -n hyperledger-fabric-contract-java-demo --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"createCat","Args":["cat-0" , "tom" ,  "3" , "蓝色" , "大懒猫"]}'# 调用 queryCat 函数
peer chaincode query -C businesschannel -n hyperledger-fabric-contract-java-demo -c '{"Args":["queryCat" , "cat-0"]}'

fabrichyperledgerpeers

相关文章:

Hyperledger Fabric Docker 方式多机部署生产网络

规划网络拓扑 3 个 orderer 节点&#xff1b;组织 org1 , org1 下有两个 peer 节点&#xff0c; peer0 和 peer1; 组织 org2 , org2 下有两个 peer 节点&#xff0c; peer0 和 peer1; 因为我只有 3 台虚拟机资源所以没法实现完全的多机部署&#xff0c;资源使用规划如下&#…...

高效降压控制器FP7132XR:为高亮度LED提供稳定可靠的电源

目录 一. FP7132概述 二. 驱动电路&#xff1a;FP7132 三. FP7132应用 高亮度LED作为新一代照明技术的代表&#xff0c;已经广泛应用于各种领域。然而&#xff0c;高亮度LED的工作电压较低&#xff0c;需要一个高效降压控制器来为其提供稳定可靠的电源。在众多降压控制器…...

Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent

文章目录 Pre概述Code源码分析 Pre Spring Boot - Application Events 的发布顺序_ApplicationEnvironmentPreparedEvent 概述 Spring Boot 的广播机制是基于观察者模式实现的&#xff0c;它允许在 Spring 应用程序中发布和监听事件。这种机制的主要目的是为了实现解耦&#…...

华为HCIE课堂笔记第十三章 IPv6地址配置

目录 第十三章 IPv6地址配置 13.1 IPv6地址无状态自动配置 13.1.1 RS和RA报文格式 13.1.2 RA的Flags字段 13.1.3 地址的生存周期 13.1.4 RA报文中前缀中的Flags 13.2 DHCPv6 13.2.1 DHCPV6的概念 13.2.2 DCHPv6的报文 第十三章 IPv6地址配置 13.1 IPv6地址无状态自动…...

计算机网络-VLAN间通信

之前复习了VLAN的概念以及几个接口类型。VLAN在二层可以实现广播域的划分&#xff0c;VLAN间可以实现二层通信&#xff0c;但是不能实现三层通信&#xff0c;需要借助其它方式。 一、概述 实际网络部署中一般会将不同IP地址段划分到不同的VLAN。同VLAN且同网段的PC之间可直接进…...

vue3的福音框架arco.design

前言&#xff1a; 在vue2于2023年底正式宣布不在维护&#xff0c;vue3使用越来越频繁的时刻&#xff0c;我们实现项目的辅助框架也越来越多。element, iview, antd 等经典框架继续风靡一时&#xff0c;不过也有很多好的框架&#xff0c;功能也强大&#xff0c;比如我们今天说的…...

BSP视频教程第29期:J1939协议栈CAN总线专题,源码框架,执行流程和应用实战解析,面向车通讯,充电桩,模组通信等(2024-01-08)

视频教程汇总帖&#xff1a;【学以致用&#xff0c;授人以渔】2024视频教程汇总&#xff0c;DSP第12期&#xff0c;ThreadX第9期&#xff0c;BSP驱动第29期&#xff0c;USB实战第5期&#xff0c;GUI实战第3期&#xff08;2024-01-08&#xff09; - STM32F429 - 硬汉嵌入式论坛 …...

Java lambda表达式如何自定义一个toList Collector

匿名类&#xff1a; package l8;import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import java.util.s…...

【hcie-cloud】【18】华为云Stack灾备服务介绍【容灾解决方案介绍、灾备方案架构介绍、管理组件灾备方案介绍、高阶云服务容灾简介、缩略词】【下】

文章目录 灾备方案概述、备份解决方案介绍容灾解决方案介绍华为云容灾解决方案概览云容灾服务云硬盘高可用服务 (VHA)VHA组网结构VHA逻辑组网架构VHA管理组件介绍VHA服务实现原理云服务器高可用服务&#xff08;CSHA&#xff09;CSHA物理组网架构CSHA逻辑组网架构CSHA服务组件间…...

linux建立软链接——以matlab为例

如果软件没有建立软连接&#xff0c;每次打开terminal就只是个黑黑的窗口&#xff0c;每次打开软件都要自己load一次&#xff0c;比较麻烦。 第一步&#xff1a; 在工作夹新建文档&#xff1a;project.cshrc 第二步&#xff1a; 在夹新建文档中写入&#xff1a;module laod m…...

ubuntu20固定串口名称

查看串口的详细信息 udevadm info --name/dev/ttyUSB0结果&#xff1a; P: /devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0 N: ttyUSB0 L: 0 S: serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UAR…...

扩散模型(二)——DDIM学习笔记-大白话推导

扩散模型系列&#xff1a; &#xff08;1&#xff09;扩散模型(一)——DDPM推导笔记-大白话推导 &#xff08;2&#xff09;扩散模型(二)——DDIM学习笔记-大白话推导 请提前关注&#xff0c;后续待更新&#xff0c;谢谢… 写在前面&#xff1a; &#xff08;1&#xff09;建议…...

【软件测试作业_TPshop商城】农业工程学院-测试需求分析与测试计划+自动化+性能+测试用例+报告软件缺陷+测试计划+单元测试+系统测试

1测试需求分析与测试计划 1.1 被测系统简介 1.2测试需求分析 1.2.1单元测试层面的测试需求分析 1.2.2系统测试层面的测试需求分析 1.3测试计划 1.31测试范围与任务 1.3.2 测试环境 1.3.3测试进度安排 测试用例的设计2 2.1单元测试层面的测试用例设计 2.2系统测试层面的测试用例…...

屏幕截图编辑工具Snagit中文

Snagit是一款优秀的屏幕、文本和视频捕获与转换程序。它能够捕获屏幕、窗口、客户区窗口、最后一个激活的窗口或用鼠标定义的区域&#xff0c;并支持BMP、PCX、TIF、GIF或JPEG格式的保存。Snagit还具有自动缩放、颜色减少、单色转换、抖动等功能&#xff0c;并能将捕获的图像转…...

12GoF之代理模式

解决问题的思维&#xff1a;AOP 解决问题技术&#xff1a;代理技术 代理技术太麻烦&#xff0c;因此使用框架 Spring AOP框架&#xff08;底层是代理技术&#xff1a;jdk动态daili&#xff0c;cglib&#xff09; 代理模式是GoF23种设计模式之一。属于结构型设计模式。 代理…...

Unity中URP下实现能量罩(扭曲流光花纹)

文章目录 前言一、能量罩花纹1、在属性面板接收能量罩花纹纹理2、申明 纹理 和 采样器3、在顶点着色器&#xff0c;应用 Tilling 和 Offset4、在片元着色器&#xff0c;纹理采样后&#xff0c;与之前的结果相乘输出 二、能量罩流光1、在顶点着色器&#xff0c;记录原uv值2、在片…...

南京银行高管上新:“70后董事长”谢宁将上任,能否及时救场?

撰稿|行星 来源|贝多财经 2024年上市银行的首例“换帅”事件&#xff0c;由南京银行拉开帷幕。 1月8日&#xff0c;南京银行&#xff08;SH:601009&#xff09;发布公告称&#xff0c;该行2024年第一次临时股东大会选举产生了第十届董事会11名董事&#xff0c;同意选举谢宁担…...

K8S容器编排基本使用

Kubernetes容器编排技术基本使用 1.部署模式发展历程 物理单机 – 虚拟机&#xff08;VMware&#xff09;-- IAAS&#xff08;基础设施即服务 比如够买jsp主机模式&#xff09;-- OPENSTACK&#xff08;多个机器分片使用思想&#xff09;-- docker&#xff08;容器化&#xf…...

PyTorch 各种池化层函数全览与用法演示

目录 torch.nn.functional子模块Pooling层详解 avg_pool1d 用法与用途 参数 注意事项 示例代码 avg_pool2d 用法与用途 参数 注意事项 示例代码 avg_pool3d 用法与用途 参数 注意事项 示例代码 max_pool1d 用法与用途 参数 注意事项 示例代码 max_pool2d…...

Redis:原理速成+项目实战——Redis实战7(优惠券秒杀+细节解决超卖、一人一单问题)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;Redis&#xff1a;原理速成项目实战——Redis实战6&#xff08;封装缓存工具&#xff08;高级写法&#xff09;&&缓存总…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...