Hyperledger Fabric多机及explorer搭建

Hyperledger Fabric多机及explorer搭建

https://blog.csdn.net/g950904/article/details/121143167

参考上方这篇博客,成功搭建多机网络并使用fabric自带浏览器,其中遇到一些小问题,根据自己遇到的问题对搭建过程进行了修改并记录下来。具体过程如下:

基于fabric2.x搭建

原则上是3台虚拟机搭建的网络,我的搭建过程是orderer和org1放在192.168.159.152 , org2放在192.168.159.153

192.168.159.152 orderer.example.com
192.168.159.152 peer0.org1.example.com
192.168.159.153 peer0.org2.example.com

1.配置ssh 使用scp命令来跨主机传输文件(可选)

2.生成fabric 证书

创建项目目录

在三台虚拟机上使用以下命令创建相同的项目目录(三台虚拟机项目路径要相同)。

cd ../hyperledger
mkdir multinodes

编写证书文件

cd ../hyperledger/multinodes

​ 使用以下命令将模板文件复制到当前目录下。

cryptogen showtemplate > crypto-config.yaml

​ 改写:

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs: 
  # ---------------------------------------------------------------------------
  # Orderer
  # ---------------------------------------------------------------------------
  - Name: Orderer  ##  定义Orderer组织结构
    Domain: example.com  ##  组织的命名域
    EnableNodeOUs: true  
    # 如果设置了EnableNodeOUs,就在msp下生成config.yaml文件
    # ---------------------------------------------------------------------------
    # "Specs" - See PeerOrgs below for complete description
    # ---------------------------------------------------------------------------
    Specs:
      - Hostname: orderer

# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1
    Domain: org1.example.com
    EnableNodeOUs: 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: ##允许定义从模板顺序创建的1个或多个主机。 默认情况下,这看起来像是从0到Count-1的“peer”。 您可以覆盖节点数(Count),起始索引(Start)或用于构造名称的模板(Hostname)。
      Count: 1  ##  表示生成几个Peer
      # Start: 5
      # Hostname: {
    
    {.Prefix}}{
    
    {.Index}} # default
      # SANS:
      #   - "{
    
    {.Hostname}}.alt.{
    
    {.Domain}}"

    # ---------------------------------------------------------------------------
    # "Users"
    # ---------------------------------------------------------------------------
    # Count: The number of user accounts _in addition_ to Admin
    # ---------------------------------------------------------------------------
    Users:
      Count: 1  ##  表示生成几个 普通User

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

生成证书文件

cryptogen generate --config=crypto-config.yaml

使用scp命令将证书文件复制到其他两台虚拟机中(使用scp命令时会要求输入主机密码)。我只要复制我org2那台就好了。

scp -r ./crypto-config [email protected]:/home/zyp/go/src/github.com/hyperledger/multinodes

复制后使用ls命令在其他两台虚拟机的multinodes目录下查看是否复制成功。

3.生成通道文件

创世块文件的编写

​ 在orderer节点的虚拟机

cd ../hyperledger/multinodes

​ 新建configtx.yaml,可以参考官方示例项目test-network中的configtx.yaml配置文件

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

---
################################################################################
#
#   Section: Organizations
#
#   - This section defines the different organizational identities which will
#   be referenced later in the configuration.
#
################################################################################
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
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: OrdererOrg

        # ID to load the MSP definition as
        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')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"
        OrdererEndpoints:
            - orderer.example.com:7050

    - &Org1
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: Org1MSP

        # ID to load the MSP definition as
        ID: Org1MSP

        MSPDir: ./crypto-config/peerOrganizations/org1.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('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
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: Org2MSP

        # ID to load the MSP definition as
        ID: Org2MSP

        MSPDir: ./crypto-config/peerOrganizations/org2.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('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

################################################################################
#
#   SECTION: 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 capability ensures that orderers and peers behave according
        # to v2.0 channel capabilities. Orderers and peers from
        # prior releases would behave in an incompatible way, and are therefore
        # not able to participate in channels at v2.0 capability.
        # 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
        # V2_0 orderer capability ensures that orderers behave according
        # to v2.0 orderer capabilities. Orderers from
        # prior releases would behave in an incompatible way, and are therefore
        # not able to participate in channels at v2.0 orderer capability.
        # Prior to enabling V2.0 orderer capabilities, ensure that all
        # orderers on 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 application capability ensures that peers behave according
        # to v2.0 application capabilities. Peers from
        # prior releases would behave in an incompatible way, and are therefore
        # not able to participate in channels at v2.0 application capability.
        # Prior to enabling V2.0 application capabilities, ensure that all
        # peers on channel are at v2.0.0 or later.
        V2_0: true

################################################################################
#
#   SECTION: Application
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults

    # Organizations is the list of orgs which are defined as participants 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:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
        Endorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"

    Capabilities:
        <<: *ApplicationCapabilities
################################################################################
#
#   SECTION: 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
    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:
        - orderer.example.com:7050

    EtcdRaft:
        Consenters:
        - Host: orderer.example.com
          Port: 7050
          ClientTLSCert: ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
          ServerTLSCert: ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt

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

        # Max Message Count: The maximum number of messages to permit in a batch
        MaxMessageCount: 10

        # Absolute Max Bytes: The absolute maximum number of bytes allowed for
        # the serialized messages in a batch.
        AbsoluteMaxBytes: 99 MB

        # Preferred Max Bytes: The preferred maximum number of bytes allowed for
        # the serialized messages in a batch. A message larger than the preferred
        # max bytes will result in a batch larger than preferred max bytes.
        PreferredMaxBytes: 512 KB

    # Organizations is the list of orgs which are defined as participants 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"

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

################################################################################
#
#   Profile
#
#   - Different configuration profiles may be encoded here to be specified
#   as parameters to the configtxgen tool
#
################################################################################
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

生成创世块文件和通道文件

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

configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP

使用以下命令将生成的文件拷贝到另两台主机(过程中会需要输入宿主机的密码)。

scp -r ./channel-artifacts [email protected]:/home/zyp/go/src/github.com/hyperledger/multinodes/

复制后使用ls命令在其他两台虚拟机的multinodes目录下查看是否复制成功。(只要复制channel-artifacts就可以)

4.docker-compose文件编写

给3个节点都编写 oderer org1 放在152的multinodes下 ; org2放在153

orderer.yaml

version: '2'

services:
  orderer.example.com:
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer:latest
    environment:
      - FABRIC_LOGGING_SPEC=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
      - ORDERER_GENERAL_LISTENPORT=7050
      - ORDERER_GENERAL_GENESISMETHOD=file
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
      - ORDERER_GENERAL_TLS_ENABLED=true
      - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
      - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
      - ORDERER_KAFKA_VERBOSE=true
      - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer
    volumes:
      - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
      - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
      - ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
    ports:
      - 7050:7050
    extra_hosts:
      - "orderer.example.com:192.168.159.152"
      - "peer0.org1.example.com:192.168.159.152"
      - "peer0.org2.example.com:192.168.159.153"

org1.yaml

version: '2'

services:
  
  couchdb0.org1.example.com:
    container_name: couchdb0.org1.example.com
    image: couchdb:3.1
    environment:
      - COUCHDB_USER=admin
      - COUCHDB_PASSWORD=adminpw
    ports:
      - 5984:5984

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    image: hyperledger/fabric-peer:latest
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_PEER_ID=peer0.org1.example.com
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_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_EXECUTETIMEOUT=300s
      - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
      - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org1.example.com:5984
      - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
      - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
    depends_on:
      - couchdb0.org1.example.com

    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    volumes:
      - /var/run/:/host/var/run/
      - ./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
    ports:
      - 7051:7051
      - 7052:7052
      - 7053:7053
    extra_hosts:
      - "orderer.example.com:192.168.159.152"
      - "peer0.org1.example.com:192.168.159.152"
      - "peer0.org2.example.com:192.168.159.153"
  cli:
    container_name: cli
    image: hyperledger/fabric-tools:latest
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
      - /var/run/:/host/var/run/
      - ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go
      - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
      - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    extra_hosts:
      - "orderer.example.com:192.168.159.152"
      - "peer0.org1.example.com:192.168.159.152"
      - "peer0.org2.example.com:192.168.159.153"

org2.yaml

version: '2'

services:
  couchdb0.org2.example.com:
    container_name: couchdb0.org2.example.com
    image: couchdb:3.1
    environment:
      - COUCHDB_USER=admin
      - COUCHDB_PASSWORD=adminpw
    ports:
      - 5984:5984

  peer0.org2.example.com:
    container_name: peer0.org2.example.com
    image: hyperledger/fabric-peer:latest
    environment:
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_PEER_ID=peer0.org2.example.com
      - CORE_PEER_ADDRESS=peer0.org2.example.com:7051
      - CORE_PEER_LISTENADDRESS=0.0.0.0:7051
      - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:7052
      - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_GOSSIP_USELEADERELECTION=true
      - CORE_PEER_GOSSIP_ORGLEADER=false
      - CORE_PEER_PROFILE_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_EXECUTETIMEOUT=300s
      - CORE_LEDGER_STATE_STATEDATABASE=CouchDB
      - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0.org2.example.com:5984
      - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
      - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=adminpw
    depends_on:
      - couchdb0.org2.example.com

    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start
    volumes:
      - /var/run/:/host/var/run/
      - ./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
    ports:
      - 7051:7051
      - 7052:7052
      - 7053:7053
    extra_hosts:
      - "orderer.example.com:192.168.159.152"
      - "peer0.org1.example.com:192.168.159.152"
      - "peer0.org2.example.com:192.168.159.153"
  cli:
    container_name: cli
    image: hyperledger/fabric-tools:latest
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org2.example.com:7051
      - CORE_PEER_LOCALMSPID=Org2MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
      - /var/run/:/host/var/run/
      - ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go
      - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
      - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    extra_hosts:
      - "orderer.example.com:192.168.159.152"
      - "peer0.org1.example.com:192.168.159.152"
      - "peer0.org2.example.com:192.168.159.153"

5.通道操作

首先要启动服务

docker-compose -f orderer.yaml up -d
docker-compose -f org1.yaml up -d
docker-compose -f org2.yaml up -d

创建通道

在org1主机操作

docker exec -it cli bash
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem

在这里插入图片描述

使用ls命令查看生成的文件(在Org1容器上操作)。

使用以下命令将通道文件 mychannel.block 拷贝到宿主机(从容器cli里拿出来)(在Org1主机上操作)。

docker cp cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/mychannel.block ./

然后使用以下命令拷贝到其他服务器上用于其他节点加入通道(在Org1主机上操作)。

scp -r mychannel.block [email protected]:/home/zyp/go/src/github.com/hyperledger/multinodes/

在这里插入图片描述

使用以下命令将通道文件拷贝到容器中(在Org2主机上操作)。

docker cp mychannel.block cli:/opt/gopath/src/github.com/hyperledger/fabric/peer/

加入通道

使用以下命令让peer0节点加入通道(在Org1和Org2容器上操作)。

docker exec -it cli bash
peer channel join -b mychannel.block

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JA48YrE3-1640681920666)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226223450884.png)]

更新锚节点

org1

peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q99ljvzE-1640681920667)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226223509810.png)]

org2

peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBgdeWqB-1640681920668)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226223535345.png)]

6.安装调用智能合约

将链码放入相应文件夹

cd …/hyperledger/multinodes/chaincode/go/atcc

使用以下命令进入链码所在目录

docker exec -it cli bash
cd /opt/gopath/src/github.com/hyperledger/fabric-cluster/chaincode/go/atcc

使用以下命令设置go语言依赖包。

go env -w GOPROXY=https://goproxy.cn,direct
go mod vendor

打包链码

peer lifecycle chaincode package atcc.tar.gz --path github.com/hyperledger/fabric-cluster/chaincode/go/atcc/ --label atcc_1

可以使用ls命令看看atcc下面有没有生成链码包,生成了再把链码包复制到org2的atcc下即可。

安装链码

使用以下命令分别在两个组织的虚拟机上安装链码(Org1和Org2的虚拟机中都要进行以下操作)。

peer lifecycle chaincode install atcc.tar.gz 

使用以下命令分别在两个组织的虚拟机上安装链码(Org1和Org2的虚拟机中都要进行以下操作)。

peer lifecycle chaincode queryinstalled

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCaOgkQx-1640681920669)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226224333802.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFQX41yc-1640682507192)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226224357563.png)]

批准链码

使用以下命令批准链码(Org1和Org2的虚拟机中都要进行以下操作,其中链码的ID要根据上面查询的结果替换到下面的命令中)。

peer lifecycle chaincode approveformyorg --channelID mychannel --name atcc --version 1.0 --init-required --package-id atcc_1:f8c5050802c36350169ec1f0d258a9a8acb1c2bd577d1bb10578ced10f9b090e --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

在这里插入图片描述

使用以下命令查看链码是否就绪(Org1和Org2的虚拟机中都要进行以下操作)

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name atcc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7pUsQ5Vm-1640681920672)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226224534255.png)]

提交链码

org1或org2 提交一次即可

peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID mychannel --name atcc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FiGqGsaD-1640682627916)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226224746756.png)]

初始化链码

peer chaincode invoke -o orderer.example.com:7050 --isInit --ordererTLSHostnameOverride orderer.example.com --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n atcc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"initLedger","Args":[]}'

调用查询方法

若搭建成功,初始化在org1完成 那么就可以org2中查询到结果。

peer chaincode query -C mychannel -n atcc -c '{"Args":["getAllAssets"]}'

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j921PAPX-1640681920674)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211226224803361.png)]

7、搭建超级账本区块链浏览器

下载配置文件

因为不能翻墙,经常会遇到与github连接失败的情况。可以直接下载包或自己编写。

mkdir explorer //创建fabric服务器的根目录

这里就不下载包了,给出代码直接创建文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2azI6932-1640681920676)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211228152314670.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mptMPSrG-1640681920676)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211228152329879.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kHML0TTx-1640681920677)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211228152351405.png)]

修改配置文件

cd connection-profile/
vim org1-network.json

{
    
    
	"name": "org1-network",
	"version": "1.0.0",
	"client": {
    
    
		"tlsEnable": true,
		"adminCredential": {
    
    
			"id": "exploreradmin",
			"password": "exploreradminpw"
		},
		"enableAuthentication": true,
		"organization": "Org1MSP",
		"connection": {
    
    
			"timeout": {
    
    
				"peer": {
    
    
					"endorser": "300"
				},
				"orderer": "300"
			}
		}
	},
	"channels": {
    
    
		"mychannel": {
    
    
			"peers": {
    
    
				"peer0.org1.example.com": {
    
    }
			}
		}
	},
	"organizations": {
    
    
		"Org1MSP": {
    
    
			"mspid": "Org1MSP",
			"adminPrivateKey": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp/keystore/priv_sk"
			},
			"peers": ["peer0.org1.example.com"],
			"signedCert": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp/signcerts/[email protected]"
			}
		}
	},
	"peers": {
    
    
		"peer0.org1.example.com": {
    
    
			"tlsCACerts": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
			},
			"url": "grpcs://peer0.org1.example.com:7051"
			
		}
	}
}

vim org2-network.json
{
    
    
	"name": "org2-network",
	"version": "1.0.0",
	"client": {
    
    
		"tlsEnable": true,
		"adminCredential": {
    
    
			"id": "exploreradmin",
			"password": "exploreradminpw"
		},
		"enableAuthentication": true,
		"organization": "Org2MSP",
		"connection": {
    
    
			"timeout": {
    
    
				"peer": {
    
    
					"endorser": "300"
				},
				"orderer": "300"
			}
		}
	},
	"channels": {
    
    
		"mychannel": {
    
    
			"peers": {
    
    
				"peer0.org2.example.com": {
    
    }
			}
		}
	},
	"organizations": {
    
    
		"Org2MSP": {
    
    
			"mspid": "Org2MSP",
			"adminPrivateKey": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp/keystore/priv_sk"
			},
			"peers": ["peer0.org2.example.com"],
			"signedCert": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp/signcerts/[email protected]"
			}
		}
	},
	"peers": {
    
    
		"peer0.org2.example.com": {
    
    
			"tlsCACerts": {
    
    
				"path": "/tmp/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
			},
			"url": "grpcs://peer0.org2.example.com:7051"
		}
	}
}


cd ..
vim config.json
{
    
    
        "network-configs": {
    
    
                "org1-network": {
    
    
                        "name": "org1-Network",
                        "profile": "./connection-profile/org1-network.json"
                },
                "org2-network": {
    
    
                        "name": "org2-Network",
                        "profile": "./connection-profile/org2-network.json"
                }
        },
        "license": "Apache-2.0"
}

修改docker-compose文件

# SPDX-License-Identifier: Apache-2.0
version: '2.1'

volumes:
  pgdata:
  walletstore:

networks:
  mynetwork.com:
    external:
      name: multinodes_default

services:

  explorerdb.mynetwork.com:
    image: hyperledger/explorer-db:latest
    container_name: explorerdb.mynetwork.com
    hostname: explorerdb.mynetwork.com
    environment:
      - DATABASE_DATABASE=fabricexplorer
      - DATABASE_USERNAME=exploreradmin
      - DATABASE_PASSWORD=exploreradminpw
    healthcheck:
      test: "pg_isready -h localhost -p 5432 -q -U postgres"
      interval: 30s
      timeout: 100s
      retries: 10
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - mynetwork.com

  explorer.mynetwork.com:
    image: hyperledger/explorer:latest
    container_name: explorer.mynetwork.com
    hostname: explorer.mynetwork.com
    environment:
      - DATABASE_HOST=explorerdb.mynetwork.com
      - DATABASE_DATABASE=fabricexplorer
      - DATABASE_USERNAME=exploreradmin
      - DATABASE_PASSWD=exploreradminpw
      - LOG_LEVEL_APP=debug
      - LOG_LEVEL_DB=debug
      - LOG_LEVEL_CONSOLE=debug
      - LOG_CONSOLE_STDOUT=true
      - DISCOVERY_AS_LOCALHOST=false
    volumes:
      - ./config.json:/opt/explorer/app/platform/fabric/config.json
      - ./connection-profile:/opt/explorer/app/platform/fabric/connection-profile
      - ./organizations:/tmp/crypto
      - walletstore:/opt/explorer/wallet
    ports:
      - 8080:8080
    depends_on:
      explorerdb.mynetwork.com:
        condition: service_healthy
    networks:
      - mynetwork.com

启动区块链浏览器

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

然后docker ps 查看容器是否正在运行(可能 explorer会自动退出,可以docker logs ID 看看具体错误)

注意用fabric的网络

注意org2节点端口号

然后localhost:8080即可访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-neOIezi5-1640682736644)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231626981.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8u7UCh6F-1640682763988)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231640512.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPzRKq7e-1640681920679)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231700648.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qehahU7c-1640681920680)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231756316.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCy80btS-1640681920680)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231811053.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eLmNAaM8-1640681920681)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231821815.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PZx4Y26Y-1640681920681)(C:\Users\zengyangpu\AppData\Roaming\Typora\typora-user-images\image-20211224231845437.png)]

猜你喜欢

转载自blog.csdn.net/weixin_48879513/article/details/122197629