规划网络拓扑
3 个 orderer 节点;组织 org1 , org1 下有两个 peer 节点, peer0 和 peer1; 组织 org2 , org2 下有两个 peer 节点, peer0 和 peer1;
因为我只有 3 台虚拟机资源所以没法实现完全的多机部署,资源使用规划如下:
节点 | 宿主机 IP | hosts | 端口 |
---|---|---|---|
cli | 192.168.0.105 | N/A | N/A |
orderer0 | 192.168.0.105 | orderer0.example.com | 7050 |
orderer1 | 192.168.0.105 | orderer1.example.com | 8050 |
orderer2 | 192.168.0.105 | orderer2.example.com | 9050 |
org1-peer0 | 192.168.0.109 | peer0.org1.example.com | 7051 |
org1-peer1 | 192.168.0.109 | peer1.org1.example.com | 8051 |
org2-peer0 | 192.168.0.110 | peer0.org2.example.com | 7051 |
org2-peer1 | 192.168.0.110 | peer1.org2.example.com | 8051 |
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