(Fabric 学习七)Fabric2.4.x 区块链多机部署(重新整一遍)

时隔很久没有学习区块链了,今天重新搭建一下区块链网络,有了更多新的体会。

我是跟着b站up主 DevX_ 一步一步往下搭建的。这是大神的视频,简洁易懂而且很符合我目前的技术栈(java应用端+java链码),而且代码开源,非常适合新手学习!!

DevX亡命天涯的个人空间-DevX亡命天涯个人主页-哔哩哔哩视频

经过测试已成功。为了今后学习便利,记录一遍搭建过程。

一、区块链搭建网络拓扑结构:

本次环境搭建要求:3个Orderer节点以满足raft共识;2个组织:org1、org2;两个组织内都有两个peer节点。

但是我懒得开多台虚拟机,索性利用一台虚拟机整多个端口来搞了,划分清楚端口就好。

资源规划如下:

节点  ip hosts 端口
cli容器 192.168.235.129 N/A N/A
orderer0 192.168.235.129 orderer0.example.com 7050:7050
8443:8443
orderer1 192.168.235.129 orderer1.example.com

8050:7050

8444:8443

orderer2 192.168.235.129 orderer2.example.com 9050:7050
8445:8553
org1.peer0 192.168.235.129 peer0.org1.example.com 7051:7051
7052:7052
9443:9443
org1.peer1 192.168.235.129 peer1.org1.example.com 8051:7051
8052:7052
9444:9443
org2.peer0 192.168.235.129 peer0.org2.example.com 9051:7051
9052:7052
9445:9443
org2.peer1 192.168.235.129 peer1.org2.example.com 10051:7051
10052:7052
9446:9443

 之后我们可以在hosts文件夹下保存一下映射的关系:

这里是我的虚拟机ip,换成自己的虚拟机ip就好,如果多机的就换成多个机子的ip。

vim /etc/hosts

192.168.235.129 orderer0.example.com
192.168.235.129 orderer1.example.com
192.168.235.129 orderer2.example.com

192.168.235.129 peer0.org1.example.com
192.168.235.129 peer1.org1.example.com

192.168.235.129 peer0.org2.example.com
192.168.235.129 peer1.org2.example.com

二、编写生成身份证书文件

生成证书文件的配置文件:crypto-config.yaml

新建一个文件夹 ,名为3orderer-org1-2peer-org2-2peer-network:

mkdir 3orderer-org1-2peer-org2-2peer-network

为了后续操作便利可以将fabric的可执行文件夹bin放入其中:(这样是为了方便,如果export成环境变量也行)

在fabric-samples下是有这么一个东西的,给他copy一下。

 完了以后进入到你新建的文件夹的bin目录下,执行:

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

生成了证书文件的模板,并将文件放到config文件夹中,然后我们对其进行修改:

vim ../config/crypto-config.yaml

这里要修改的是Specs的HostName要把三个orderer节点都写上;EnableNodeOUs设置为true;每一个组织template的count设置为2,意思是有两个peer节点。


# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
  # ---------------------------------------------------------------------------
  # Orderer
  # ---------------------------------------------------------------------------
  - Name: Orderer
    Domain: example.com
    EnableNodeOUs: true

    # ---------------------------------------------------------------------------
    # "Specs" - See PeerOrgs below for complete description
    # ---------------------------------------------------------------------------
    Specs:
      - Hostname: orderer0
      - Hostname: orderer1
      - Hostname: orderer2
        SANS:
             - "*"
             - "192.168.235.129"   

# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: true

    # ---------------------------------------------------------------------------
    # "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: 2
      # Start: 5
      # Hostname: {
   
   {.Prefix}}{
   
   {.Index}} # default
      # SANS:
      #   - "{
   
   {.Hostname}}.alt.{
   
   {.Domain}}"
      SANS:
           - "*"
           - "192.168.235.129"

    # ---------------------------------------------------------------------------
    # "Users"
    # ---------------------------------------------------------------------------
    # Count: The number of user accounts _in addition_ to Admin
    # ---------------------------------------------------------------------------
    Users:
      Count: 1

  # ---------------------------------------------------------------------------
  # Org2: See "Org1" for full specification
  # ---------------------------------------------------------------------------
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
      SANS:
        - "*"
        - "192.168.235.139"
    Users:
      Count: 1

文件编辑完后利用bin文件下的cryptogen工具,根据crypto-config.yaml配置文件生成证书:

./cryptogen generate --config=../config/crypto-config.yaml --output ../crypto-config

如果修改了配置还可以extend子命令来更新crypto-config目录:

./cryptogen extend --config=../crypto-config.yaml --input ../crypto-config

结束之后查看一下是否真的生成了身份证书文件,并且确认一下节点信息是否完整,没有遗漏。

tree ../crypto-config

三、编写生成通道初始区块、通道文件、锚节点配置更新文件

生成通道文件的配置文件:configtx.yaml

我们可以利用bin文件架下的configtxgen工具来生成网络配置和拓补结构信息。

编辑configtx.yaml文件:

这里要改的主要是一些文件目录要对,比如MSPDir等;OrdererEndpoints、Addresses(Order节点的端口号),以及完成raft共识的各个orderer节点的tls证书目录。

注意:我这里定义的org1和org2的锚节点是他们的peer0节点。

# 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: ../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: Signature

                Rule: "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: Signature

                Rule: "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: Signature

                Rule: "OR('OrdererMSP.admin')"

            Endorsement:

                Type: Signature

                Rule: "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



    - &Org1



        Name: Org1MSP

        ID: Org1MSP

        MSPDir: ../crypto-config/peerOrganizations/org1.example.com/msp

        Policies:

            Readers:

                Type: Signature

                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"

            Writers:

                Type: Signature

                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"

            Admins:

                Type: Signature

                Rule: "OR('Org1MSP.admin')"

            Endorsement:

                Type: Signature

                Rule: "OR('Org1MSP.peer')"

        AnchorPeers:

            - Host: peer0.org1.example.com

              Port: 7051





    - &Org2



        Name: Org2MSP

        ID: Org2MSP

        MSPDir: ../crypto-config/peerOrganizations/org2.example.com/msp

        Policies:

            Readers:

                Type: Signature

                Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"

            Writers:

                Type: Signature

                Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"

            Admins:

                Type: Signature

                Rule: "OR('Org2MSP.admin')"

            Endorsement:

                Type: Signature

                Rule: "OR('Org2MSP.peer')"

        AnchorPeers:

            - Host: peer0.org2.example.com

              Port: 9051





################################################################################

#

#   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: &ApplicationDefaults

    ACLs: &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" function

        lscc/ChaincodeExists: /Channel/Application/Readers



        # ACL policy for lscc's "getdepspec" function

        lscc/GetDeploymentSpec: /Channel/Application/Readers



        # ACL policy for lscc's "getccdata" function

        lscc/GetChaincodeData: /Channel/Application/Readers



        # ACL Policy for lscc's "getchaincodes" function

        lscc/GetInstantiatedChaincodes: /Channel/Application/Readers



        #---Query System Chaincode (qscc) function to policy mapping for access control---#



        # ACL policy for qscc's "GetChainInfo" function

        qscc/GetChainInfo: /Channel/Application/Readers



        # ACL policy for qscc's "GetBlockByNumber" function

        qscc/GetBlockByNumber: /Channel/Application/Readers



        # ACL policy for qscc's  "GetBlockByHash" function

        qscc/GetBlockByHash: /Channel/Application/Readers



        # ACL policy for qscc's "GetTransactionByID" function

        qscc/GetTransactionByID: /Channel/Application/Readers



        # ACL policy for qscc's "GetBlockByTxID" function

        qscc/GetBlockByTxID: /Channel/Application/Readers



        #---Configuration System Chaincode (cscc) function to policy mapping for access control---#



        # ACL policy for cscc's "GetConfigBlock" function

        cscc/GetConfigBlock: /Channel/Application/Readers



        # ACL policy for cscc's "GetChannelConfig" function

        cscc/GetChannelConfig: /Channel/Application/Readers



        #---Miscellaneous peer function to policy mapping for access control---#



        # ACL policy for invoking chaincodes on peer

        peer/Propose: /Channel/Application/Writers



        # ACL policy for chaincode to chaincode invocation

        peer/ChaincodeToChaincode: /Channel/Application/Writers



        #---Events resource to policy mapping for access control###---#



        # ACL policy for sending block events

        event/Block: /Channel/Application/Readers



        # ACL policy for sending filtered block events

        event/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: &ApplicationDefaultPolicies

        LifecycleEndorsement:

            Type: ImplicitMeta

            Rule: "MAJORITY Endorsement"

        Endorsement:

            Type: ImplicitMeta

            Rule: "MAJORITY Endorsement"

        Readers:

            Type: ImplicitMeta

            Rule: "ANY Readers"

        Writers:

            Type: ImplicitMeta

            Rule: "ANY Writers"

        Admins:

            Type: ImplicitMeta

            Rule: "MAJORITY Admins"



    # Capabilities describes the application level capabilities, see the

    # dedicated Capabilities section elsewhere in this file for a full

    # description

    Capabilities:

        <<: *ApplicationCapabilities



################################################################################

#

#   ORDERER

#

#   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 definition

    Addresses:

        - 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: 0



    Kafka:

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

              Port: 7050

              ClientTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt

              ServerTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt

            - Host: orderer1.example.com

              Port: 8050

              ClientTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crt

              ServerTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer1.example.com/tls/server.crt

            - Host: orderer2.example.com

              Port: 9050

              ClientTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt

              ServerTLSCert: ../crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt



        # Options 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 taken

            SnapshotIntervalSize: 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: ImplicitMeta

            Rule: "ANY Readers"

        Writers:

            Type: ImplicitMeta

            Rule: "ANY Writers"

        Admins:

            Type: ImplicitMeta

            Rule: "MAJORITY Admins"

        # BlockValidation specifies what signatures must be included in the block

        # from the orderer for the peer to validate it.

        BlockValidation:

            Type: ImplicitMeta

            Rule: "ANY Writers"



    # Capabilities describes the orderer level capabilities, see the

    # dedicated Capabilities section elsewhere in this file for a full

    # description

    Capabilities:

        <<: *OrdererCapabilities



################################################################################

#

#   CHANNEL

#

#   This section defines the values to encode into a config transaction or

#   genesis block for channel related parameters.

#

################################################################################

Channel: &ChannelDefaults

    # Policies defines the set of policies at this level of the config tree

    # For Channel policies, their canonical path is

    #   /Channel/<PolicyName>

    Policies:

        # Who may invoke the 'Deliver' API

        Readers:

            Type: ImplicitMeta

            Rule: "ANY Readers"

        # Who may invoke the 'Broadcast' API

        Writers:

            Type: ImplicitMeta

            Rule: "ANY Writers"

        # By default, who may modify elements at this config level

        Admins:

            Type: ImplicitMeta

            Rule: "MAJORITY Admins"





    # Capabilities describes the channel level capabilities, see the

    # dedicated Capabilities section elsewhere in this file for a full

    # description

    Capabilities:

        <<: *ChannelCapabilities



################################################################################

#

#   PROFILES

#

#   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:

        <<: *ChannelDefaults

        Orderer:

            <<: *OrdererDefaults

            Organizations:

                - *OrdererOrg

            Capabilities:

                <<: *OrdererCapabilities

        Consortiums:

            SampleConsortium:

                Organizations:

                    - *Org1

                    - *Org2

     TwoOrgsChannel:

        Consortium: SampleConsortium

        <<: *ChannelDefaults

        Application:

            <<: *ApplicationDefaults

            Organizations:

                - *Org1

                - *Org2

            Capabilities:

                <<: *ApplicationCapabilities

生成创世区块:

注意:这里的-channelID指的是系统通道,与下面peer所处的通道不同,系统通道取名为fabric-channel

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

操作后目录如下: 

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

生成通道文件:

注意:我这里通道文件命名为businesschannel,你们可以自己改,后期在创建通道时要根据这个名字来

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

四、部署orderer节点

 需要编写三个不同的docker-compose配置文件,这里我们先编写启动orderer的docker容器的文件,命名为docker-compose-3orderer.yaml。

编辑docker-compose-3orderer.yaml:

这里主要是将ip地址都改成对应的ip地址,端口号也改成上面定好的端口号。

version: '2.0'

services:

    cli:
        image: hyperledger/fabric-tools:2.4.1
        restart: always
        container_name: fabric-cli
        hostname: fabric-cli
        tty: true
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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/[email protected]/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.pem
        volumes:
            - ./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/chaincodes
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        command: bash -c 'cd /tmp; source scripts/func.sh; while true; do sleep 20170504; done'


    orderer0.example.com:  # There can be multiple orderers
        image: hyperledger/fabric-orderer:2.4.1
        restart: always
        container_name: orderer0.example.com
        hostname: orderer0.example.com
        ports:
            - 7050:7050
            - 8443:8443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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=DEBUG
        volumes:
            - ./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.block
        expose:
            - "7050"  # gRPC
            - "8443"  # Operation REST
        command: orderer start

    orderer1.example.com:
        image: hyperledger/fabric-orderer:2.4.1
        restart: always
        container_name: orderer1.example.com
        hostname: orderer1.example.com
        ports:
            - 8050:7050
            - 8444:8443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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=10
        volumes:
            - ./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.block
        command: orderer start    


    orderer2.example.com:
        image: hyperledger/fabric-orderer:2.4.1
        restart: always
        container_name: orderer2.example.com
        hostname: orderer2.example.com
        ports:
            - 9050:7050
            - 8445:8443
        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=10
        volumes:
            - ./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.block
        command: orderer start

写完后启动 orderer 节点:

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

如果想停止也可以删除: 

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

如果想重新来,把容器先关掉再全删了,也可以:

docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2)
docker rm $(docker ps -a | awk '{ print $1}' | tail -n +2)

五、部署org1 peer节点

同上,我们命名为:

编辑docker-compose-org1-2peer.yaml :

这里也是主要修改端口号和ip地址

version: '2.0'

services:

    peer0.org1.example.com:
        image: hyperledger/fabric-peer:2.4.1
        restart: always
        container_name: peer0.org1.example.com
        hostname: peer0.org1.example.com
        ports:
            - 7051:7051
            - 7052:7052
            - 9443:9443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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=adminpw
        volumes:
            - /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/tls
        expose:
            - "7051"  # gRPC
            - "9443"  # Operation REST
        #command: bash -c 'bash /tmp/peer_build.sh; peer node start'
        command: peer node start
        depends_on:
            - peer0.org1.couchdb


    peer1.org1.example.com:
        image: hyperledger/fabric-peer:2.4.1
        restart: always
        container_name: peer1.org1.example.com
        hostname: peer1.org1.example.com
        ports:
            - 8051:7051
            - 8052:7052
            - 9444:9443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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=adminpw
        volumes:
            - /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/tls
        expose:
            - "8051"  # gRPC
            - "8052"  # chaincode
            - "9444"  # Operation REST
        #command: bash -c 'bash /tmp/peer_build.sh; peer node start'
        command: peer node start
        depends_on:
            - peer1.org1.couchdb

    
                    
    peer0.org1.couchdb:
        image: couchdb:3.1.1
        container_name: peer0.org1.couchdb
        ports:
            - 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=adminpw

    peer1.org1.couchdb:
        image: couchdb:3.1.1
        container_name: peer1.org1.couchdb
        ports:
            - 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

六、部署org2 peer节点

同上,文件名为:docker-compose-org2-2peer.yaml

编辑docker-compose-org2-2peer.yaml:

这里也是主要修改端口号和ip地址

注意:最下面的couchdb端口号也要进行修改!!和上面org1要不一样才行。




version: '2.0'

services:

    peer0.org2.example.com:
        image: hyperledger/fabric-peer:2.4.1
        restart: always
        container_name: peer0.org2.example.com
        hostname: peer0.org2.example.com
        ports:
            - 9051:7051
            - 9052:7052
            - 9445:9443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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:9051
            - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
            - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052
            - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051
            - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051
            - CORE_PEER_LOCALMSPID=Org2MSP
            - FABRIC_LOGGING_SPEC=DEBUG # info:core.chaincode=debug
            - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
            - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=peer0.org2.couchdb:5984
            - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
            - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
        volumes:
            - /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/tls
        expose:
            - "9051"  # gRPC
            - "9445"  # Operation REST
        #command: bash -c 'bash /tmp/peer_build.sh; peer node start'
        command: peer node start
        depends_on:
            - peer0.org2.couchdb


    peer1.org2.example.com:
        image: hyperledger/fabric-peer:2.4.1
        restart: always
        container_name: peer1.org2.example.com
        hostname: peer1.org2.example.com
        ports:
            - 10051:7051
            - 10052:7052
            - 9446:9443
        extra_hosts:
            - "orderer0.example.com:192.168.235.129"
            - "orderer1.example.com:192.168.235.129"
            - "orderer2.example.com:192.168.235.129"
            - "peer0.org1.example.com:192.168.235.129"
            - "peer1.org1.example.com:192.168.235.129"
            - "peer0.org2.example.com:192.168.235.129"
            - "peer1.org2.example.com:192.168.235.129"
        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:10051
            - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
            - CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:10052
            - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:10051
            - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:10051
            - 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=adminpw
        volumes:
            - /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/tls
        expose:
            - "10051"  # gRPC
            - "9446"  # Operation REST
        #command: bash -c 'bash /tmp/peer_build.sh; peer node start'
        command: peer node start
        depends_on:
            - peer1.org2.couchdb


    peer0.org2.couchdb:
        image: couchdb:3.1.1
        container_name: peer0.org2.couchdb
        ports:
            - 7984: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

    peer1.org2.couchdb:
        image: couchdb:3.1.1
        container_name: peer1.org2.couchdb
        ports:
            - 8984: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/[email protected]/msp

peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

peer channel join -b /tmp/channel-artifacts/businesschannel.block

结果如下:

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.org1.example.com:8051


peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.org2.example.com:10051

peer channel join -b /tmp/channel-artifacts/businesschannel.block

九、更新锚节点

 更新锚节点的目的是使通道内不同组织间peer可以进行通信,共同维护账本。我们在之前配置文件configtx.yaml中设置了两个组织的peer0节点作为锚节点。

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

peer 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容器中用git下来,我直接从宿主机中复制进来的。

我的链码使用的是DevX_写的demo,我把他的流程也一并复制下来的,在他流程后是我的流程。

DevX_的流程

进入 cli 容器:

docker exec -it fabric-cli bash

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

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

cd 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

我的流程

由于java链码安装比较慢,我是通过idea中maven项目先clean再package然后将包和索引和私有数据集同时存在一个文件夹hyperledger-fabric-contract-java中

具体教程请看:

解决Fabric安装java链码速度慢的问题(使用jar包安装链码)_FD—moremore的博客-CSDN博客

然后弄成一个文件夹后存到容器中 :

docker cp ./hyperledger-fabric-contract-java-demo/ fabric-cli:/etc/hyperledger/fabric/chaincodes/

之后打包链码:

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

结果如下:

十一、节点安装链码

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

peer lifecycle chaincode install hyperledger-fabric-contract-java-demo.tar.gz

结果如下:

 
 

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.org1.example.com:8051

peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

peer 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/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.org2.example.com:10051

peer 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:6b1c76b05811b82cc0101b84908cf0b4077df8f6e44ac447831ac8f0a0e6fc7c, Label: hyperledger-fabric-contract-java-demo_1

将包 ID 保存为环境变量:

export CC_PACKAGE_ID=hyperledger-fabric-contract-java-demo_1:6b1c76b05811b82cc0101b84908cf0b4077df8f6e44ac447831ac8f0a0e6fc7c

十二、批准链码定义

 如果是有私有数据的话,这里就需要进行私有数据集配置了

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

# 普通数据定义
peer 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

结果如下:

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/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051

peer 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

输出结果如下:

将链码提交到通道:

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:9051 --tlsRootCertFiles /etc/hyperledger/fabric/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

结果如下:

 

 此时说明链码已经提交给了通道了。

现在我们可以确认一下是否完成:

用 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

结果如下:

 

十三、调用链码

这块就不是重点了,我直接复制了up主的链码就行了。


# 调用 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:9051 --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"]}'

运行结果如下:

同时,由于在我们在配置过程中设定了couchdb的容器,我们可以打开couchdb

couchdb的ip和端口为:

http://192.168.235.129:5984/_utils/#

端口号可以有四个,分别对应不同的peer节点(5984,6984,7984,8984)

进入后用户名和密码已经在容器配置文件中写过,我们这里默认是admin和adminpw

至于之后调用私有数据需要在批准链码那里配置的,以后再搞。

猜你喜欢

转载自blog.csdn.net/Wannabe_hacker/article/details/129220142