zoukankan      html  css  js  c++  java
  • Fabric1.4:手动启动 first-network 网络(三)

    注意:本文所使用的 fabric 版本为 v1.4.3,与其它版本的网络存在差异。

    手动启动 first-network 网络系列分为三部分:

    第一篇单纯使用命令行的形式执行 byfn.sh 脚本中的内容,第二篇和第三篇是对手动启动网络过程所使用的命令和配置文件的解释。

    1 启动分布式网络

    手动生成 fabric 网络所需的配置文件(查看手动启动 first-network 网络(二))后,接下来需要启动区块链中提供网络服务的各个节点。fabric 采用容器技术,使用 docker-compose 这个工具来实现区块链网络所需的节点容器管理,实现方式只需要编写节点相应的配置文件即可。

    1.1 docker-compose-cli.yaml

    first-network目录下提供了一个dokcer-compose工具所需的配置文件docker-compose-cli.yaml,我们使用该文件启动网络节点,下面是该文件的内容:

    version: '2'      # 表示用的版本 2 的 YAML 版本
    
    volumes:
      orderer.example.com:
      peer0.org1.example.com:
      peer1.org1.example.com:
      peer0.org2.example.com:
      peer1.org2.example.com:
    
    networks:
      byfn:
    
    services:
      orderer.example.com:                   # Orderer 节点
        extends:          # 扩展自 base/docker-compose-base.yaml 文件的 orderer.example.com 
          file:   base/docker-compose-base.yaml    
          service: orderer.example.com
        container_name: orderer.example.com  # 容器名称
        networks:
          - byfn
    
      peer0.org1.example.com:                 # peer0.org1.example.com 节点
        container_name: peer0.org1.example.com  
        extends:         
          file:  base/docker-compose-base.yaml
          service: peer0.org1.example.com    
        networks:
          - byfn
    
      peer1.org1.example.com:                 # peer1.org1.example.com 节点
        container_name: peer1.org1.example.com  
        extends:
          file:  base/docker-compose-base.yaml
          service: peer1.org1.example.com
        networks:
          - byfn
    
      peer0.org2.example.com:                 # peer0.org2.example.com 节点
        container_name: peer0.org2.example.com
        extends:
          file:  base/docker-compose-base.yaml
          service: peer0.org2.example.com
        networks:
          - byfn
    
      peer1.org2.example.com:                  # peer1.org2.example.com 节点
        container_name: peer1.org2.example.com
        extends:
          file:  base/docker-compose-base.yaml
          service: peer1.org2.example.com
        networks:
          - byfn
    
      cli:                                     # CLI 用户客户端节点
        container_name: cli                 		# 容器名称
        image: hyperledger/fabric-tools:$IMAGE_TAG  # 依赖的容器镜像
        tty: true                                   
        stdin_open: true
        environment:                                # 环境变量
          - SYS_CHANNEL=$SYS_CHANNEL
          - GOPATH=/opt/gopath
          - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock    
          #- FABRIC_LOGGING_SPEC=DEBUG
          - FABRIC_LOGGING_SPEC=INFO                        # 容器日志级别
          - CORE_PEER_ID=cli                                # 当前节点名字 cli
          - CORE_PEER_ADDRESS=peer0.org1.example.com:7051   # 连接的 peer 节点的地址
          - CORE_PEER_LOCALMSPID=Org1MSP                    # 连接的 peer 节点所属的组织 MSPID
          - CORE_PEER_TLS_ENABLED=true                      # 是否启动 TLS 通信 
          # 通信用的 TLS 证书
          - 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
          # TLS 证书对应的私钥
          - 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
          # TLS 证书的根证书
          - 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  
          
          # 设置 CLI 客户端身份账号(MSP),客户端的角色不同,权限不同,此处是管理员账号
          # 普通用户账号:对账本数据进行读写操作
          # 管理员账号:对账本数据进行读写,创建通道,让节点加入通道,安装并实例化链码
          - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp    
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer   # 容器的默认工作目录
        command: /bin/bash      # 容器启动时执行的命令
        volumes:                # 本地系统文件路径与容器指定路径的映射
            - /var/run/:/host/var/run/
            - ./../chaincode/:/opt/gopath/src/github.com/chaincode
            - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
            - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
            - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
        depends_on:            # 依赖的相关容器
          - orderer.example.com
          - peer0.org1.example.com
          - peer1.org1.example.com
          - peer0.org2.example.com
          - peer1.org2.example.com
        networks:
          - byfn
    

    以上配置文件指定了网络中各个节点容器(共计 6 个容器,包括 1 个 Orderer节点、4 个 Peer节点和 1 个 CLI 客户端)的信息。除了 CLI 容器之外的,其他容器都有 extends 指向 base/docker-compose-base.yaml 文件,下面是关联的 docker-compose-base.yaml 文件的具体内容:

    version: '2'
    
    services:
      orderer.example.com:
        container_name: orderer.example.com   # 容器名称
        extends:                              # 扩展自 peer-base.yaml 文件的 orderer-base
          file: peer-base.yaml
          service: orderer-base
        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  
            - orderer.example.com:/var/hyperledger/production/orderer
        ports:    
          - 7050:7050                           # 本地系统端口与容器监听端口的映射
    
      peer0.org1.example.com:
        container_name: peer0.org1.example.com   # 容器名称
        extends:                                 # 扩展自 peer-base.yaml 文件的 peer-base
          file: peer-base.yaml
          service: peer-base
        environment:                             # 环境变量
          - CORE_PEER_ID=peer0.org1.example.com              # peer 节点的名字
          - CORE_PEER_ADDRESS=peer0.org1.example.com:7051    # peer 节点的访问地址
          - CORE_PEER_LISTENADDRESS=0.0.0.0:7051             # peer 节点的监听地址,设置为 0.0.0.0 会自动读取网卡,识别实际的本机 IP
          - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052   # peer 节点上链码的访问地址 
          - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052    # peer 节点上链码的监听地址,设置为 0.0.0.0 会自动读取网卡,识别实际的本机 IP
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051   # gossip协议配置
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
          - CORE_PEER_LOCALMSPID=Org1MSP          # 所属组织的 MSPID
        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
            - peer0.org1.example.com:/var/hyperledger/production
        ports:                                     
          - 7051:7051                              # 本地系统端口与容器监听端口的映射
    
      peer1.org1.example.com:
        container_name: peer1.org1.example.com
        extends:
          file: peer-base.yaml
          service: peer-base
        environment:
          - CORE_PEER_ID=peer1.org1.example.com
          - CORE_PEER_ADDRESS=peer1.org1.example.com:8051
          - CORE_PEER_LISTENADDRESS=0.0.0.0:8051
          - CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8052
          - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
          - CORE_PEER_LOCALMSPID=Org1MSP
        volumes:
            - /var/run/:/host/var/run/
            - ../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
            - peer1.org1.example.com:/var/hyperledger/production
    
        ports:
          - 8051:8051
    
      peer0.org2.example.com:
        container_name: peer0.org2.example.com
        extends:
          file: peer-base.yaml
          service: peer-base
        environment:
          - CORE_PEER_ID=peer0.org2.example.com
          - CORE_PEER_ADDRESS=peer0.org2.example.com:9051
          - CORE_PEER_LISTENADDRESS=0.0.0.0:9051
          - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052
          - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:10051
          - CORE_PEER_LOCALMSPID=Org2MSP
        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
            - peer0.org2.example.com:/var/hyperledger/production
        ports:
          - 9051:9051
    
      peer1.org2.example.com:
        container_name: peer1.org2.example.com
        extends:
          file: peer-base.yaml
          service: peer-base
        environment:
          - CORE_PEER_ID=peer1.org2.example.com
          - CORE_PEER_ADDRESS=peer1.org2.example.com:10051
          - CORE_PEER_LISTENADDRESS=0.0.0.0:10051
          - CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:10052
          - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:10052
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:10051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051
          - CORE_PEER_LOCALMSPID=Org2MSP
        volumes:
            - /var/run/:/host/var/run/
            - ../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
            - peer1.org2.example.com:/var/hyperledger/production
        ports:
          - 10051:10051
    

    docker-compose-cli.yaml 配置文件中,由 extends 指向了一个 peer-base.yaml 配置文件,下面是又关联的 peer-base.yaml 配置文件的具体内容:

    version: '2'
    
    services:
      peer-base:
        image: hyperledger/fabric-peer:$IMAGE_TAG    # 容器所依赖的镜像
        environment:                                 # 环境变量
          - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
          # the following setting starts chaincode containers on the same
          # bridge network as the peers
          # https://docs.docker.com/compose/networking/
          - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
          - FABRIC_LOGGING_SPEC=INFO
          #- FABRIC_LOGGING_SPEC=DEBUG
          - CORE_PEER_TLS_ENABLED=true                # 是否开启 TLS 验证
          - CORE_PEER_GOSSIP_USELEADERELECTION=true   # 是否采用选举方式产生主节点
          - CORE_PEER_GOSSIP_ORGLEADER=false          # 是否将当前节点设定为主节点
          - CORE_PEER_PROFILE_ENABLED=true            # 节点启动后 PROFILE 进程是否启动
          - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt # Peer 节点的 TLS 证书所在路径
          - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key  # Peer 节点的 TLS 证书对应的密钥所在路径
          - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt # Peer 节点的 TLS 证书的根证书所在路径
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer    # 进入容器后的默认工作目录
        command: peer node start   # 容器启动执行的命令
    
      orderer-base:
        image: hyperledger/fabric-orderer:$IMAGE_TAG    # 指定容器的镜像
        environment:                                    # 设置环境变量
          - FABRIC_LOGGING_SPEC=INFO
          - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0       # 监听本机地址,如果使用 0.0.0.0 会自动读取网卡,识别实际的本机 IP
          - ORDERER_GENERAL_GENESISMETHOD=file          # 创世区块的形式
          - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block  # 指定在 Orderer 容器中创世区块的所在路径
          - ORDERER_GENERAL_LOCALMSPID=OrdererMSP       # 当前 Orderer 节点的 MSPID
          - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp   # 指定当前 Orderer 节点的 MSP 所在路径
          # enabled TLS
          - ORDERER_GENERAL_TLS_ENABLED=true            # 是否开启 TLS 验证
          - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key  # Orderer 节点的 TLS 证书所在路径
          - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt # Orderer 节点的 TLS 证书对应的密钥所在路径
          - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]  # Orderer 节点的 TLS 证书的根证书所在路径
          - 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    # 容器启动执行的命令
    

    1.2 启动网络节点

    使用 docker-compose 工具将 docker-compose-cli.yaml 文件作为参数,启动提供网络服务的各个节点:

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

    参数说明:

    • -f: 启动容器时所使用的 docker-compose 配置文件
    • -d:是否显示网络启动过程中的实时日志信息,如果需要查看详细网络启动日志,则可以不提供此参数

    如果节点启动成功,会出现如下信息:

    Creating network "net_byfn" with the default driver
    Creating volume "net_peer0.org2.example.com" with default driver
    Creating volume "net_peer1.org2.example.com" with default driver
    Creating volume "net_peer1.org1.example.com" with default driver
    Creating volume "net_peer0.org1.example.com" with default driver
    Creating volume "net_orderer.example.com" with default driver
    Creating orderer.example.com ... 
    Creating peer0.org2.example.com ... 
    Creating peer1.org2.example.com ... 
    Creating peer0.org1.example.com ... 
    Creating peer1.org1.example.com ... 
    Creating orderer.example.com
    Creating peer0.org2.example.com
    Creating peer0.org1.example.com
    Creating peer1.org1.example.com
    Creating peer1.org2.example.com ... done
    Creating cli ... 
    Creating cli ... done
    

    Peer 节点启动之后,默认情况下没有加入区块链网络中的任何应用通道,也不会与 Orderer 节点建立连接,只是单纯的容器启动。我们需要使用 CLI 客户端对 Peer 节点进行操作,让它加入网络和指定的应用通道。


    2 应用通道的创建与测试

    我们使用 docker exec 命令进行 CLI 容器:

    $ docker exec -it cli bash 
    

    启动成功,会看到以下内容:

    root@5e7e7a9c84ef:/opt/gopath/src/github.com/hyperledger/fabric/peer# 
    

    CLI 容器是用户客户端节点,默认情况下是以 admin.org1 身份连接 peer0.org1 运行命令。如果想切换 CLI 客户端的身份和连接的节点,则需要对以下四个环境变量进行修改:

    # peer0.org1 的环境变量
    CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    CORE_PEER_ADDRESS=peer0.org1.example.com:7051
    CORE_PEER_LOCALMSPID="Org1MSP"
    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
    

    2.1 创建应用通道

    使用以下命令通道,设置的通道名称必须与创建通道交易配置文件时指定的通道名称相同:

    # export CHANNEL_NAME=mychannel
    # export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
    
    # peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile $ORDERER_CA
    

    参数说明:

    • -o:要连接的 Orderer 节点地址
    • -c:要创建的应用通道的名称
    • -f:创建应用通道时所使用的应用通道交易配置文件
    • --tls:开启 TLS 验证
    • --cafile: Orderer 节点的根证书路径,用于验证 TLS 握手

    成功执行,返回如下内容:

    2019-12-02 14:01:20.468 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    2019-12-02 14:01:20.642 UTC [cli.common] readBlock -> INFO 002 Received block: 0
    

    该命令执行之后,会返回一个与应用通道同名的的区块文件 mychannel.block,该文件是应用通道的创世区块,peer 节点只有拥有该文件才可以加入到已创建的应用通道中。返回的区块文件保存在 CLI 容器的当前目录下,使用 ll 命令查看容器当前目录,可以找到该区块文件:

    total 44
    drwxr-xr-x 5 root root  4096 Dec  2 14:01 ./
    drwxr-xr-x 3 root root  4096 Dec  2 13:47 ../
    drwxr-xr-x 2 1000 1000  4096 Dec  2 13:46 channel-artifacts/
    drwxr-xr-x 4 1000 1000  4096 Dec  2 13:45 crypto/
    -rw-r--r-- 1 root root 20559 Dec  2 14:01 mychannel.block
    drwxr-xr-x 2 1000 1000  4096 Oct 14 14:24 scripts/
    

    2.2 各节点加入应用通道

    peer0.org1 加入应用通道

    CLI 客户端默认的身份为 admin.org1,连接 peer0.org1 节点。使用如下命令将 peer0.org1 加入应用通道:

    # peer channel join -b mychannel.block
    

    参数说明:

    • join:将当前 Peer 节点加入应用通道中

    • -b: 指定当前节点要加入/连接至哪个应用通道

    • mychannel.block: 是先前创建应用通道时保存在 CLI 容器当前目录的区块文件

    成功执行,返回如下内容:

    2019-12-02 14:15:44.673 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    2019-12-02 14:15:44.802 UTC [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
    

    peer1.org1 加入应用通道

    更改 CLI 容器的环境变量,让当前节点变为 peer1.org1

    # CORE_PEER_ADDRESS=peer1.org1.example.com:8051
    

    使用如下命令将 peer1.org1 加入应用通道:

    # peer channel join -b mychannel.block
    

    peer0.org2 加入应用通道

    更改 CLI 容器的环境变量,让当前用户变为 admin.org2,连接 peer0.org2

    # CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    # CORE_PEER_ADDRESS=peer0.org2.example.com:9051
    # CORE_PEER_LOCALMSPID="Org2MSP"
    # 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
    

    使用如下命令将 peer0.org2 加入应用通道:

    # peer channel join -b mychannel.block
    

    peer1.org2 加入应用通道

    更改 CLI 容器的环境变量,让当前节点变为 peer1.org2

    # CORE_PEER_ADDRESS=peer1.org2.example.com:10051
    

    使用如下命令将 peer1.org2 加入应用通道:

    # peer channel join -b mychannel.block
    

    注意:

    上述节点加入都能使用 mychannel.block,是因为使用同一个 CLI 容器连接所有节点。如果各节点使用不同的 CLI 容器,有以下两个解决方式:

    • mychannel.block 复制过去

    • 使用通道提取命令:

      # peer channel fetch oldest mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
      

      需要注意,一般只有管理员 Admin 或有读取权限的用户 User 才能使用通道提取的节点(可以在 configtx.yaml 预定义策略规则中设置)。


    2.3 更新锚节点并安装链码

    peer0.org1 更新为锚节点并安装链码

    # CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    # CORE_PEER_ADDRESS=peer0.org1.example.com:7051
    # CORE_PEER_LOCALMSPID="Org1MSP"
    # 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
    

    使用如下命令更新将 peer0.org1节点定义为 org1 的锚节点:

    # peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile $ORDERER_CA
    
    2019-12-02 15:08:09.306 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
    2019-12-02 15:08:09.335 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
    

    peer0.org1 节点上安装链码:

    # peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    
    2019-12-02 15:08:16.912 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
    2019-12-02 15:08:16.912 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
    2019-12-02 15:08:17.113 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" >
    

    peer0.org2 更新为锚节点并安装链码

    # CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    # CORE_PEER_ADDRESS=peer0.org2.example.com:9051
    # CORE_PEER_LOCALMSPID="Org2MSP"
    # 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
    

    使用如下命令更新将 peer0.org2 节点定义为 org2 的锚节点:

    # peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile $ORDERER_CA
    

    peer0.org2 节点上安装链码:

    # peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    

    2.4 实例化链码并测试

    实例化链码

    通道上的链码采用多次安装,一次实例化的方式,且必须是管理员用户 admin 实例化链码。在通道上实例化链码,为链码设置背书策略,在目标节点上启动链码容器。

    # peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')"
    
    2019-12-02 15:22:44.911 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
    2019-12-02 15:22:44.911 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
    

    实例化之后,某个安装有链码的 peer 尝试与链码交换,就会为它们启动一个链码容器。任何安装链码的 peer,在被调用时都会检查是否生成了链码容器,如果没有生成,则首先生成链码容器。

    Query

    查询 a 的值,确保是否正确实例化了链码并写入状态数据库:

    # peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    

    返回了 100,说明正确安装和实例化了。

    Invoke

    现在从 a 账户转 10 到 b 账户,这个交易将创建一个新的区块并更新状态 DB。因此,该交易需要 peer0.org1peer0.org2 的背书,多个节点的背书由 --peerAddresses 标志指定:

    # peer chaincode invoke -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc --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:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
    
    2019-12-02 15:25:16.413 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 
    

    在 peer1.org1 上安装链码

    # CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    # CORE_PEER_ADDRESS=peer1.org1.example.com:8051
    # CORE_PEER_LOCALMSPID="Org1MSP"
    # CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
    
    # peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    
    2019-12-02 15:29:56.247 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
    2019-12-02 15:29:56.251 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
    2019-12-02 15:29:56.399 UTC [chaincodeCmd] install -> INFO 003 Installed remotely response:<status:200 payload:"OK" > 
    

    Query

    查询 a 的值,确保是否正确实例化了链码并写入状态数据库:

    # peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    

    返回了 90,说明正确安装和实例化了。

    查看日志:

    使用 docker ps 命令,可以查看到有三个链码容器运行,分别是:dev-peer0.org1.example.com-mycc-1.0dev-peer0.org2.example.com-mycc-1.0dev-peer1.org1.example.com-mycc-1.0。可以使用 docker logs 命令查看日志:

    $ docker logs dev-peer0.org2.example.com-mycc-1.0
    ex02 Init
    Aval = 100, Bval = 200
    ex02 Invoke
    Query Response:{"Name":"a","Amount":"100"}
    ex02 Invoke
    Aval = 90, Bval = 210
    
    $ docker logs dev-peer0.org1.example.com-mycc-1.0
    ex02 Invoke
    Aval = 90, Bval = 210
    
    $ docker logs dev-peer1.org1.example.com-mycc-1.0
    ex02 Invoke
    Query Response:{"Name":"a","Amount":"90"}
    

    3 清除分布式网络

    $ docker-compose -f docker-compose-cli.yaml down
    

    成功执行返回:

    Stopping cli                    ... done
    Stopping orderer.example.com    ... done
    Stopping peer1.org2.example.com ... done
    Stopping peer0.org1.example.com ... done
    Stopping peer1.org1.example.com ... done
    Stopping peer0.org2.example.com ... done
    Removing cli                    ... done
    Removing orderer.example.com    ... done
    Removing peer1.org2.example.com ... done
    Removing peer0.org1.example.com ... done
    Removing peer1.org1.example.com ... done
    Removing peer0.org2.example.com ... done
    Removing network net_byfn
    

    该命令暂停并移除网络中的容器节点,但是不会删除网络启动过程生成的配置文件,所以手动删除 crypto-config channel-artifacts 目录下的全部配置文件。需要注意的是,channel-artifacts 文件夹不能删除,网络启动过程会自动创建 crypto-config 文件夹,但不会创建 channel-artifacts 文件夹。因此,如果误删了 channel-artifacts 文件夹,请手动创建它。


    参考

    1. 《Hyperledger Fabric 菜鸟进阶攻略》
    2. 《Hyperledger Fabric技术内幕 架构设计与实现原理》
  • 相关阅读:
    表的相关内容
    数据类型
    mysql入门练习
    mysql入门
    协程
    多进程
    装饰器
    网络编程
    心路历程
    gensim的使用
  • 原文地址:https://www.cnblogs.com/zongmin/p/12180584.html
Copyright © 2011-2022 走看看