Fabric框架的学习-3-手动组建Fabric网络(重点!含自动化部署脚本一键操作)

四、 Fabric核心模块

在搭建自己的网络之前还需要了解下核心模块

对于模块的说明:

模块名称 说明
peer /
orderer /
cryptogen 编写配置文件,根据配置文件生成证书
cryfigtxgen 生成创世块文件(不是创世快)、生成通道文件
configtxlator 对区块文件修改,可以将二进制的区块文件变为JSON的可读模式。以及动态的添加组织

操作这些模块,就主要使用这些模块给我们提供的shell命令,这些shell命令都在bin目录下

并且之前已经将这些命令加入到/usr/local/bin`全局变量下了

命令手册:

http://cw.hubwiz.com/card/c/fabric-command-manual/1/1/1/

五、手动组建Fabric网络

5.1 生成Fabric证书-yaml 命令:cryptogen

cryptogen --help
cryptogen showtemplate # 会输出配置文件的模板

Fabric V1.2.0中的版本cryptogen:

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

对于每一子命令可以查看:

 cryptogen generate --help

获取配置文件模板

cryptogen showtemplate
# 会直接输出到终端
# 重定向到一个新yaml文件
cryptogen showtemplate > a.yaml
vim a.yaml  # 这样就可以直接使用了

模板文档解释(一些注释做了删减):

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
# 排序节点组织信息
OrdererOrgs:
  # ---------------------------------------------------------------------------
  # Orderer
  # ---------------------------------------------------------------------------
  - Name: Orderer  			# 排序节点组织名
    Domain: example.com		# 根域名,排序节点组织的根域名,在实际开发环境中需要使用真实已经备案的域名,测试环境下自己随便起就可以
    EnableNodeOUs: false	# 链码是否支持nodejs

    # ---------------------------------------------------------------------------
    # "Specs" - See PeerOrgs below for complete description
    # ---------------------------------------------------------------------------
    Specs:
      - Hostname: orderer  	# 子域名,因为一个域名只能绑定一个ip,而orderer是多个的,所以要多个子域名,这里就只有这一个orderer一个即可
      						# 访问这台orderer对应的域名就是orderer.example.com 

# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
# peer节点组织
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  # 组织还可以进行细分,分为Org1、Org2等等,在下方添加即可
  - Name: Org1    	# 组织名字可以自己制定
    Domain: org1.example.com   		# 访问第一个组织用到的根域名
    EnableNodeOUs: false			# 链码是否支持nodejs
    Template:						# 模板, 根据默认的规则生成2个peer数据存储节点
      Count: 2						# 第一个节点域名: peer0.org1.example.com  第二个节点域名: peer1.org1.example.com
    Users:							# 创建普通用户的个数
      Count: 1
  # ---------------------------------------------------------------------------
  # Org2: See "Org1" for full specification
  # ---------------------------------------------------------------------------
  # 组织2同理
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: false
    Template:
      Count: 1
    Users:
      Count: 1


注意事项:

  • Domain: example.com 根域名,排序节点组织的根域名,在实际开发环境中需要使用真实已经备案的域名,测试环境下自己随便起就可以

  • 使用Specs或者Template指定节点的子域名两者都可以,区别就在于用Specs可以自己规划子域名,而Template则是例如pee0、peer1这样的默认设置

    两个还可以一起用,最终节点数是两者之和

    例:

    Template:						
          Count: 2	 # 两个默认域名	
    Specs:
          - Hostname: orderer  # 一个指定域名
    # 这样是指定三个节点
    

小练习:

要求:

mkdir fabric-test01   #创建一个空目录作为环境
cd fabric-test01/
cryptogen showtemplate > crypto-config.yaml  # 创建空模板文件
vim crypto-config.yaml
# 修改模板
  2 # ---------------------------------------------------------------------------
  3 # "OrdererOrgs" - Definition of organizations managing orderer nodes
  4 # ---------------------------------------------------------------------------
  5 OrdererOrgs:
  6   # ---------------------------------------------------------------------------
  7   # Orderer
  8   # ---------------------------------------------------------------------------
  9   - Name: Orderer
 10     Domain: xwj.com
 11     EnableNodeOUs: false
 12 
 13     # ---------------------------------------------------------------------------
 14     # "Specs" - See PeerOrgs below for complete description
 15     # ---------------------------------------------------------------------------
 16     Specs:
 17       - Hostname: orderer
 18 
 19 # ---------------------------------------------------------------------------
 20 # "PeerOrgs" - Definition of organizations managing peer nodes
 21 # ---------------------------------------------------------------------------
 22 PeerOrgs:
 23   # ---------------------------------------------------------------------------
 24   # Org1
 25   # ---------------------------------------------------------------------------
 26   - Name: OrgGo
 27     Domain: orggo.xwj.com
 28     EnableNodeOUs: true
 29     Template:
 30       Count: 2
 31     Users:
 32       Count: 3
 33      
 34   # ---------------------------------------------------------------------------
 35   # Org2: See "Org1" for full specification
 36   # ---------------------------------------------------------------------------
 37   - Name: OrgCpp
 38     Domain: orgcpp.xwj.com
 39     EnableNodeOUs: true
 40     Template:
 41       Count: 2
 42     Users:
 43       Count: 3

使用–config命令去执行配置文件,如果不指定配置文件,则会按照模板文件来执行

cryptogen generate --config=crypto-config.yaml   # 出现自己写的组织名称则说明成功了
# 随后生成crypto-config文件

检查peer和user创建的个数,符合要求即成功

5.2 创世块文件和通道文件的生成命令:configtxgen

5.2.1 命令介绍:

参数如下:

configtxgen --help
# 没有子命令
Usage of configtxgen:
  -asOrg string  #所属组织,也就是为某个特定组织生成配置
  -channelID string  #channel名称,如果不指定默认是"testchainid"   
  -inspectBlock string #打印指定区块文件中配置内容   
  -inspectChannelCreateTx string #打印指定创建通道交易的配置文件   
  -outputAnchorPeersUpdate string #生成一个更新锚点的更新channel配置信息       
  -outputBlock string #输出区块文件路径     
  -outputCreateChannelTx string #指定一个路径,来生成channel配置文件  
  -profile string   #配置文件中的节点,用于生成相关配置文件,默认是 "SampleInsecureSolo")      
  -version #显示版本信息

执行这个命令,必须要指定固定名字的一个配置文件 configtx.yaml

cp /home/xwj/fabric-1.2/fabric-samples/first-network/configtx.yaml /home/xwj/fabric-1.2/test01/   
# 这个没有模板,所以在之前的first-network文件夹中复制一个到自己的目录中修改即可
 6 ---
 15 Organizations:  # 固定的
 19     - &OrdererOrg  # 排序节点组织的名字,这里的组织名可以随便取  *OrdererOrg代表这整个块
 22         Name: OrdererOrg		# 组织名
 23 
 25         ID: OrdererMSP			# 排序节点组织的ID
 26 
 28         MSPDir: crypto-config/ordererOrganizations/example.com/msp   # 这里是创建证书时MSP的地址,这里是相对地址
 29 
 30     - &Org1						# 第一个组织,名字自己起
 33         Name: Org1MSP			# 第一个组织的名字
 34 
 36         ID: Org1MSP				# 组织ID
 37 
 38         MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
 39 
 40         AnchorPeers:			# 锚节点
 44             - Host: peer0.org1.example.com   	# 指定该组织中任一个节点peer节点的域名,其就作为该组织的锚节点。一个组织只有一个锚节点
 45               Port: 7051						# 固定端口
 46 
 47     - &Org2
 50         Name: Org2MSP
 51 
 53         ID: Org2MSP
 54 
 55         MSPDir: crypto-config/peerOrganizations/org2.example.com/msp
 56 
 57         AnchorPeers:
 61             - Host: peer0.org2.example.com
 62               Port: 7051
 63 	### 如果有多个组织,基础添加即可
 83 Capabilities:  # 能力  V1.1之后出现的,设置时全部设置为True(为了向上兼容)
 86     Global: &ChannelCapabilities
 91         V1_1: true
 96     Orderer: &OrdererCapabilities
101         V1_1: true
102 
106     Application: &ApplicationCapabilities
111         V1_2: true
112 
121 Application: &ApplicationDefaults  #一般就用默认配置
122 
125     Organizations:
126 
135 Orderer: &OrdererDefaults   # 对orderer节点组织设置一些更加细的命令
136 
137     # Orderer Type: The orderer implementation to start
138     # Available types are "solo" and "kafka"
        # 共识机制 == 排序算法  ,Fabric V1.2  提供的共识机制有两种solo和kafka,测试环境一般用solo。真实环境用kafka(适用于高并发)
        # solo就是指orderer节点就只有一个不需要共识算法
139     OrdererType: solo   # 共识算法
140 
141     Addresses:			# orderer节点的地址
142         - orderer.example.com:7050   # 端口一般不修改
143 
145     BatchTimeout: 2s	# 多长时间产生一个区块
146 
		##### BatchTimeout、MaxMessageCount、AbsoluteMaxBytes这三者有一个超过了就产生区块
148     BatchSize:  
149 
150         # Max Message Count: The maximum number of messages to permit in a batch
151         MaxMessageCount: 10			# 交易的最大数量,,建议100
152 
153         # Absolute Max Bytes: The absolute maximum number of bytes allowed for
154         # the serialized messages in a batch.
155         AbsoluteMaxBytes: 99 MB		# 数据大小最大值,数据量达到99M也会产生区块,一般32M/64M
156 
160         PreferredMaxBytes: 512 KB 	# 建议的最大数量
161 
162     Kafka:
165         Brokers:    # 代理人
166             - 127.0.0.1:9092    #kafka的服务器
167 
170     Organizations:
171 
174 #   Profile    上面分散的设置的总结
180 Profiles:   # 固定的不能修改
181     # *是引用上面&的数据
182     TwoOrgsOrdererGenesis:   	# 区块名字 可以改
183         Capabilities:		 	# 能力,即上面设置的
184             <<: *ChannelCapabilities	# 通道的能力
185         Orderer:
186             <<: *OrdererDefaults   		# orderer组织的细节配置
187             Organizations:
188                 - *OrdererOrg			# orderer组织的配置
189             Capabilities:
190                 <<: *OrdererCapabilities	# orderer的能力
191         Consortiums:					# 联盟
192             SampleConsortium:			# 实例联盟 可以自定义
193                 Organizations:			# 两个peer节点组织
194                     - *Org1
195                     - *Org2
196     TwoOrgsChannel:						# 通道名字可以自定义
197         Consortium: SampleConsortium   	# 对应上面的联盟名字,要保持一致
198         Application:
199             <<: *ApplicationDefaults
200             Organizations:				# 事先声明组织在改通道中,后续其中的节点就可以选择加入该通道
201                 - *Org1
202                 - *Org2
203             Capabilities:
204                 <<: *ApplicationCapabilities
                                                                  

锚节点

5.2.2 修改配置文件

事先需要做的事:

  • 找出orderer的msp的位置:

    /home/xwj/fabric_1.2/fabric-test01/crypto-config/ordererOrganizations/xwj.com/msp


  • 找出两个peer组织的msp的位置

    go组织:

    /home/xwj/fabric_1.2/fabric-test01/crypto-config/peerOrganizations/orggo.xwj.com/msp

    cpp组织同样的方法。。。不再赘述

    /home/xwj/fabric_1.2/fabric-test01/crypto-config/peerOrganizations/orgcpp.xwj.com/msp

configtx.yaml 配置文件如下

---
Organizations:

    - &OrdererOrg

        Name: OrdererOrg

        ID: OrdererMSP
        
        MSPDir: crypto-config/ordererOrganizations/xwj.com/msp

    - &org_go

        Name: OrgGoMSP

        ID: OrgGoMSP

        MSPDir: crypto-config/peerOrganizations/orggo.xwj.com/msp

        AnchorPeers:

            - Host: peer0.orggo.xwj.com
              Port: 7051

    - &org_cpp

        Name: OrgCppMSP


        ID: OrgCppMSP

        MSPDir: crypto-config/peerOrganizations/orgcpp.xwj.com/msp

        AnchorPeers:
            - Host: peer0.orgcpp.xwj.com
              Port: 7051

Capabilities:

    Global: &ChannelCapabilities
   
        V1_1: true

  
    Orderer: &OrdererCapabilities

        V1_1: true

    Application: &ApplicationCapabilities

        V1_2: true


Application: &ApplicationDefaults

    Organizations:

Orderer: &OrdererDefaults

    OrdererType: solo

    Addresses:
        - orderer.xwj.com:7050

    BatchTimeout: 2s

    BatchSize:

        MaxMessageCount: 100

        AbsoluteMaxBytes: 32 MB

        PreferredMaxBytes: 512 KB

    Kafka:

        Brokers:
            - 127.0.0.1:9092


    Organizations:

Profiles:

    XwjOrdererGenesis:
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Consortiums:
            SampleConsortium:
                Organizations:
                    - *org_go
                    - *org_cpp
    XwjOrgsChannel:
        Consortium: SampleConsortium
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *org_go
                - *org_cpp
            Capabilities:
                <<: *ApplicationCapabilities
                                                                                                                                

5.2.3 命令执行配置文件

  • 创建创世块

    configtxgen -profile XwjOrdererGenesis -outputBlock ./genesis.block
    

    注意参数不是configtx.yaml的文件名,而是其中Profiles创世块的这个名字(因为是创建创世块的命令需要这些配置信息):

    没有报错信息,并且看到genesis.block文件生成则说明成功了。

    为了适应后面的配置文件的默认目录,一般会将genesis.block文件放到channel-artifacts文件夹下:

    mkdir channel-artifacts
    mv genesis.block channel-artifacts/
    
  • 生成通道文件

    configtxgen -profile XwjOrgsChannel -outputCreateChannelTx channel-artifacts/channel.tx -channelID xwjChannel
    # outputCreateChannelTx 参数后接 保存的文件名,一般tx后缀
    # channelID 是自己指定的通道的id,这个与configtx.yaml中的配置名字无关
    

    注意后接通道配置名:

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

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

  • 生成锚节点更新文件

    这个操作是可选的,可以做可以不做

    这个锚节点更新文件是为了当你选定的锚节点失效的时候,更新整个组织的锚节点(重新指定一个锚节点)的作用

    configtxgen -profile XwjOrgsChannel -outputAnchorPeersUpdate channel-artifacts/GoMSPanchors.tx -channelID xwjChannel -asOrg OrgGoMSP
    # profile 还是指定通道配置名
    # outputAnchorPeersUpdate 指定输出文件名
    # channelID 之前设置的通道id
    # asOrg 指明锚节点属于哪个组织
    configtxgen -profile XwjOrgsChannel -outputAnchorPeersUpdate channel-artifacts/CPPMSPanchors.tx -channelID xwjChannel -asOrg OrgCppMSP
    

    对应生成两个更新文件

    每个组织都生成一个对应的锚节点更新文件

5.3 docker-compose文件的编写

5.3.1 文件关系介绍

一个网络中有非常多的各类节点,每个节点都是在docker容器中运行的,需要编写docker-compose文件去管理这些docker

  • docker-compose-cli.yaml

    官方实例first-network中的docker-compose-cli.yaml解析

     version: '2'   # docker-compose的版本号
    
     volumes:		# 官方实例有五个节点,所以分别对应五个数据卷的映射  映射本地主机地址一般在/var/lib/docker/volumes
       # 这里的映射只写了一半,在docker-compose-base中写了完整的映射关系
       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:	# 服务名 可以自己指定
         extends: 				# 继承下方文件中的服务
           file:   base/docker-compose-base.yaml
           service: orderer.example.com   # 具体继承文件中哪项服务
         container_name: orderer.example.com 	# 指定容器的名字
         networks:								# 节点所在网络
           - byfn
    
       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:
         container_name: peer1.org1.example.com
         extends:
           file:  base/docker-compose-base.yaml
           service: peer1.org1.example.com
         networks:
           - byfn
    
       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:
         container_name: peer1.org2.example.com
         extends:
           file:  base/docker-compose-base.yaml
           service: peer1.org2.example.com
     cli:  # 客户端的终端  可以用linux也可以用nodejs、java编写  这里是linux
         container_name: cli   # 容器名字
         image: hyperledger/fabric-tools:$IMAGE_TAG  # 客户端所对应的镜像
         tty: true # 终端打开
         stdin_open: true # 标准输入打开
         environment:   # 环境变量
         - GOPATH=/opt/gopath
         - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
         #- CORE_LOGGING_LEVEL=DEBUG
         - CORE_LOGGING_LEVEL=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/:/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个容器(包含客户端cli)

  • base目录下的docker-compose-base.yaml

    version: '2'
    
    services:
    
      orderer.example.com:  							# 被上面那个文件所继承的服务
        container_name: orderer.example.com  			# 容器名
        image: hyperledger/fabric-orderer:$IMAGE_TAG	# $IMAGE_TAG环境变量指定运行镜像的版本tag	
        environment:									# orderer镜像运行需要使用的环境变量
          - ORDERER_GENERAL_LOGLEVEL=INFO
          - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
          - ORDERER_GENERAL_GENESISMETHOD=file
          - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
          - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
          - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
          # enabled TLS
          - 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]
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric	# 启动后的工作目录
        command: orderer  	# 启动order服务
        volumes:    		# 数据卷映射
        - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block   # 创世块映射
        # order节点的身份证书msp
        - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
        # tls证书
        - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
        # 完整的映射关系
        # 把/var/lib/docker/volumes/order.xwj.com 映射到/var/hyperledger/production/orderer
        - orderer.example.com:/var/hyperledger/production/orderer
        ports:
          - 7050:7050  # 端口映射  orderer一个端口用于通信,而peer有两个端口
    
      peer0.org1.example.com:
        container_name: peer0.org1.example.com
        extends:    	# 又继承了一个文件peer-base.yaml中的peer-base服务,peer-base是peer节点的一个通用配置,所以单独提出来了
          file: peer-base.yaml
          service: peer-base
        environment: 	
          - CORE_PEER_ID=peer0.org1.example.com
          - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
          - CORE_PEER_LOCALMSPID=Org1MSP
        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	# 一般情况 ~51端口用于通信
          - 7053:7053	# ~53端口用于事件传播
      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:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051
          - 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:7051
          - 8053:7053
    
      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:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:7051
          - 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:7051
          - 9053:7053
    
      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:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:7051
          - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051
          - 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:7051
          - 10053:7053
    
    

    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
          - CORE_LOGGING_LEVEL=INFO
          #- CORE_LOGGING_LEVEL=DEBUG
          - 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
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer  # 工作目录
        command: peer node start		# 启动peer
    

5.3.2 客户端角色需要使用的环境变量

 # 客户端docker容器启动之后,go的工作目录
 - GOPATH=/opt/gopath		# 一般不变
	  # docker启动之后的本地套接字,一般不变
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      # 日志级别: critical 严重错误 | error | warning | notice | info | debug
      - CORE_LOGGING_LEVEL=INFO
      # 当前客户端节点的id,自己指定
      - CORE_PEER_ID=cli
      # 客户端需要连接的peer节点地址(同一个组织下),客户端必须要连接一个peer节点才能通信,端口一般不该
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      # 客户端、peer节点所属的组织
      - CORE_PEER_LOCALMSPID=Org1MSP
      # 通信是否使用tls加密,true对应下方的一系列设置
      - CORE_PEER_TLS_ENABLED=true
      # 证书文件 这些文件对应的是客户端要连接peer节点的证书目录
      -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

修改客户端的配置:

 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
      - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.orggo.xwj.com:7051
      - CORE_PEER_LOCALMSPID=OrgGoMSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.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/:/opt/gopath/src/github.com/chaincode
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.xwj.com
      - peer0.orggo.xwj.com
      - peer1.orggo.xwj.com
      - peer0.orgcpp.xwj.com
      - peer1.orgcpp.xwj.com
    networks:
      - byfn

5.3.3 orderer节点需要使用的环境变量

环境配置解析:

 environment:									# orderer镜像运行需要使用的环境变量
      - ORDERER_GENERAL_LOGLEVEL=INFO			# 日志级别
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0	# orderer监听的ip地址
      - ORDERER_GENERAL_GENESISMETHOD=file		# 创世块的来源,指定file来源就是文件
      # 创世快对应的文件,这个目录被挂载,不需要改
      #  - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 
      - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
      - ORDERER_GENERAL_LOCALMSPID=OrdererMSP	# orderer的所属组id
      - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp	# 当前节点的msp账号
      # enabled TLS
      - ORDERER_GENERAL_TLS_ENABLED=true  		# 是否使用tls加密	
      - 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]		# 根证书

修改环境配置:

5.3.4 peer节点需要使用的环境变量

peer节点需要配置的环境变量解析:

extends:    	# 又继承了一个文件peer-base.yaml中的peer-base服务,peer-base是peer节点的一个通用配置,所以单独提出来了
      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节点的ip地址信息
      # 启动后向哪些节点发起gossip连接,以加入网络
      # gossip流言协议,每个节点只向没有收到流言的节点传播
      # 一般配置就写自己的ip+端口就可以了(不知道写谁的话)
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051	
      # 为了被其他节点感知到。设置自己的地址和端口,不设置别的节点就不知道
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
      # peer节点所属组的组id
      - CORE_PEER_LOCALMSPID=Org1MSP

# peer-base.yaml 中环境配置

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
      - CORE_LOGGING_LEVEL=INFO 				# 日志级别
      #- CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_TLS_ENABLED=true 				# 是否加密
      - CORE_PEER_GOSSIP_USELEADERELECTION=true	# 下方单独解释
      - CORE_PEER_GOSSIP_ORGLEADER=false		# 下方单独解释
      - CORE_PEER_PROFILE_ENABLED=true 			# 在peer节点中有一个profile服务,在此指定是否开启
      - 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_PEER_GOSSIP_USELEADERELECTION=true 是否使用自动选举
  • CORE_PEER_GOSSIP_ORGLEADER=false 当前节点是否为leader节点

一个组织中的leader节点可以手动设置,也可以让网络自动指定。但是手动设置的节点一旦故障那么网络不会自动替代,所以一般采用网络自动选举的机制CORE_PEER_GOSSIP_USELEADERELECTION环境变量就是设置是否由网络指定

CORE_PEER_GOSSIP_ORGLEADER=false 表明当前节点是否为leader节点,如果设置了网络自动选举,那么这一项就设置为false

修改docker-compose-cli.yaml docker-compose-base.yaml peer-base.yaml

# docker-compose-cli文件中的peer部分
peer0.orggo.xwj.com:
    container_name: peer0.orggo.xwj.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.orggo.xwj.com
    networks:
      - byfn

  peer1.orggo.xwj.com:
    container_name: peer1.orggo.xwj.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.orggo.xwj.com
    networks:
      - byfn

  peer0.orgcpp.xwj.com:
    container_name: peer0.orgcpp.xwj.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer0.orgcpp.xwj.com
    networks:
      - byfn

  peer1.orgcpp.xwj.com:
    container_name: peer1.orgcpp.xwj.com
    extends:
      file:  base/docker-compose-base.yaml
      service: peer1.orgcpp.xwj.com
    networks:
      - byfn

# docker-compose-base.yaml文件中的peer部分
  peer0.orggo.xwj.com:
    container_name: peer0.orggo.xwj.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.orggo.xwj.com
      - CORE_PEER_ADDRESS=peer0.orggo.xwj.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.orggo.xwj.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orggo.xwj.com:7051
      - CORE_PEER_LOCALMSPID=OrgGoMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls:/etc/hyperledger/fabric/tls
        - peer0.orggo.xwj.com:/var/hyperledger/production
    ports:
      - 7051:7051
      - 7053:7053

  peer1.orggo.xwj.com:
    container_name: peer1.orggo.xwj.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.orggo.xwj.com
      - CORE_PEER_ADDRESS=peer1.orggo.xwj.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.orggo.xwj.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orggo.xwj.com:7051
      - CORE_PEER_LOCALMSPID=OrgGoMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/orggo.xwj.com/peers/peer1.orggo.xwj.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/orggo.xwj.com/peers/peer1.orggo.xwj.com/tls:/etc/hyperledger/fabric/tls
        - peer1.orggo.xwj.com:/var/hyperledger/production

    ports:
      - 8051:7051
      - 8053:7053

  peer0.orgcpp.xwj.com:
    container_name: peer0.orgcpp.xwj.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer0.orgcpp.xwj.com
      - CORE_PEER_ADDRESS=peer0.orgcpp.xwj.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.orgcpp.xwj.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.orgcpp.xwj.com:7051
      - CORE_PEER_LOCALMSPID=OrgCppMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/orgcpp.xwj.com/peers/peer0.orgcpp.xwj.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/orgcpp.xwj.com/peers/peer0.orgcpp.xwj.com/tls:/etc/hyperledger/fabric/tls
        - peer0.orgcpp.xwj.com:/var/hyperledger/production
    ports:
      - 9051:7051
      - 9053:7053

  peer1.orgcpp.xwj.com:
    container_name: peer1.orgcpp.xwj.com
    extends:
      file: peer-base.yaml
      service: peer-base
    environment:
      - CORE_PEER_ID=peer1.orgcpp.xwj.com
      - CORE_PEER_ADDRESS=peer1.orgcpp.xwj.com:7051
      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.orgcpp.xwj.com:7051
      - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.orgcpp.xwj.com:7051
      - CORE_PEER_LOCALMSPID=OrgCppMSP
    volumes:
        - /var/run/:/host/var/run/
        - ../crypto-config/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/msp:/etc/hyperledger/fabric/msp
        - ../crypto-config/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/tls:/etc/hyperledger/fabric/tls
        - peer1.orgcpp.xwj.com:/var/hyperledger/production
    ports:
      - 10051:7051
      - 10053:7053
                                
# peer-base.yaml


version: '2'

services:
  peer-base:
    image: hyperledger/fabric-peer:latest
    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
      - CORE_LOGGING_LEVEL=INFO
      #- CORE_LOGGING_LEVEL=DEBUG
      - 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
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: peer node start

5.3.5 配置文件结构目录

5.3.6 docker-compose 启动配置文件中的镜像

现在first-network中测试:

cd first-network
sudo ./byfn.sh down  		# 先关闭以防止之前开启过
sudo ./byfn.sh generate  	# 创建证书,因为配置文件中需要使用
docker-compose -f docker-compose-cli.yaml up -d    	# 使用配置文件运行各个镜像
docker-compose -f docker-compose-cli.yaml ps		# 查看,全部为绿色up状态才表示镜像开启成功

注意: 这里的done并不代表着就启动成功了,必须还要去查看

查看,全部为绿色up状态才表示镜像开启成功


启动自己的构建的网络配置文件:

将docker-compose-cli文件更名为docker-compose,为了方便使用docker-compose命令,不用在敲-f 文件名

创建文件夹,把 docker-compose-base.yaml peer-base.yaml两个文件放到base文件夹下(适应配置文件中的数据卷映射)

# 先关闭之前所有已运行的镜像
docker stop $(docker ps -qa)
# 或者
docker-compose down -v
# 检查是否还有相关镜像运行
docker ps
# 没有后开始运行配置文件 
# 在包含docker-compose.yaml文件的目录下运行,会自动找docker-compose.yaml文件执行
docker-compose up -d
# 检查运行状态
docker-compose ps

运行成功则出现:

COMPOSE_PROJECT_NAME是在peer-base.yaml中设置的

test01_byfn => network网络名字是 [当前目录_配置文件中的名字]

所以,我们可以设置环境变量:

vim ~/.bashrc
# 加入这一行
export COMPOSE_PROJECT_NAME=xwj_fabric_12  # 自己取名   不要用特殊的符号,小写的字母加数字其实就可以了
# 保存
source ~/.bashrc
# 重新运行
docker-compose up -d

大功告成!

5.4 客户端操作peer节点 命令:peer

5.4.0 客户端对peer节点的总体操作流程

  • 创建通道,通过客户端节点来完成

    • 进入到客户端节点来完成
  • 将每个组织中的每个节点都加入到通道中,也是通过客户端完成

    • 以客户端同时只能连接一个peer节点

      所以需要改变客户端的配置属性连接到不同的客户端,实现一个一个的加入到通道中

  • 每个peer节点安装链码(智能合约) -> 链代码程序:go nodejs java

  • 对智能合约进行初始化,对应智能合约中的init函数

    • 智能合约只需要初始化一次,在任意节点均可,数据会自动同步到各个组织的各个节点中
  • 对数据进行查询(读),对数据进行交易(写)

5.4.1 创建channel通道

这个动作需要在cli容器中运行,也就是上面配置好的文件,docker-compose启动后的运行容器cli中

# 进入cli容器
docker exec -it cli bash
# 创建通道
peer channel create -o ubuntu.itcast.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA
# 参数说明
	-o 后面接连接的orederer的地址,hostname:port
	-$CHANNEL_NAME: 创建通道文件的时候写的IDchannel的id,没指定默认为mychannel,通道创建成功后会在磁盘生成一个文件:$CHANNEL_NAME.block
	-$CORE_PEER_TLS_ENABLED: 和docker通信时是否启用tls
	-$ORDERER_CA: 使用tls时,所使用的orderer节点的pem格式证书文件
peer channel create -o orderer.xwj.com:7050 -c xwjchannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/xwj.com/orderers/orderer.xwj.com/msp/tlscacerts/tlsca.xwj.com-cert.pem

orderer证书的绝对路径目录($ORDERER_CA),可按同样的方式去以下目录查找:(此目录是在镜像中的目录,与本机目录无关)

/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/xwj.com/orderers/orderer.xwj.com/msp/tlscacerts/tlsca.xwj.com-cert.pem

注意:必须先进入cli容器中再执行创建通道的命令

注意:如果提示路径错误请检查!存放证书的文件夹我们之前命名为crypto-config,映射到cli镜像中则变成了crypto,所以命令中需要注意。

注意:$CHANNEL_NAME不能为出现大写字母,不然会报错!(只能是小写或者数字或者破折号)

重新创建通道文件(命令可见上方),命名规范要注意,然后再次执行即可:

显示0 block(创世区块)则说明创建成功!

5.4.2 加入通道

$ peer channel join[flags],常用参数为:
	-b, --blockpath: 通过peer channel create命令生成的通道文件
# example
$ peer channel join -b 生成的通道block文件
peer channel join -b xwjchannel.block

注意,加入到channel只有当前一个peer节点成功了,并不是所有的peer,还需要加入其他节点

加入其它的节点,通道无需重新创建,只需要修改当前客户端的环境变量,使其连接其他的peer节点就可以了

具体改变只有一下内容:

例:go组织的二个节点,在cli容器中输入以下命令:

export CORE_PEER_ADDRESS=peer0.orggo.xwj.com:7051
export CORE_PEER_LOCALMSPID=OrgGoMSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.orggo.xwj.com:7051
export CORE_PEER_LOCALMSPID=OrgGoMSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer1.orggo.xwj.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer1.orggo.xwj.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer1.orggo.xwj.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/users/[email protected]/msp

cpp组织的两个节点:

export CORE_PEER_ADDRESS=peer0.orgcpp.xwj.com:7051
export CORE_PEER_LOCALMSPID=OrgCppMSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer0.orgcpp.xwj.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer0.orgcpp.xwj.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer0.orgcpp.xwj.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer1.orgcpp.xwj.com:7051
export CORE_PEER_LOCALMSPID=OrgCppMSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/users/[email protected]/msp

显示成功,则此节点完成。

一个一个节点这样操作即可

5.4.3 更新锚节点

锚节点的指定在docker-compose.yaml中就指定好了,要更换才需要操作,非必需操作

锚节点的更新文件路径:

5.4.4 安装链码

准备工作:

# 复制first-network中的一个链码到项目目录
cp ~/fabric-1.2/fabric-samples/chaincode/chaincode_example02/go/chaincode_example02.go chaincode/
# 重命名 
cd chaincode/
mv chaincode_example02.go test.go
# 进入客户端cli
docker exec -it cli bash
# 查看映射文件是否已经存在
ls /opt/gopath/src/github.com/chaincode/
# 发现重命名的文件存在则说明已经成功


# 安装链码
peer chaincode install [flags], 常用参数为:
	-c, --ctor: Json格式的构造函数,默认是“{
    
    }”
	-l, --lang: 编写链码的编程语言,默认是golang
	-n, --name: 链码的名字
	-p, --path: 链码源代码的目录,从$GOPATH/src 路径后开始写
	-v, --version: 当前操作的链码的版本,适用于这些命令:install/instantiate/upgrade
# example
peer chaincode install -n 链码的名字 -v 链码的版本 -l 链码的语言 -p 链码的位置
	- 链码名字自定义
	- 链码的版本,自己根据实际情况去指定
	- 这里的路径不是写完全的绝对路径,而是从$GOPATH/src 路径后开始写 
	
peer chaincode install -n testcc -v 1.0 -l golang -p github.com/chaincode/
# 安装完之后的检查
peer chaincode list --installed

返回响应为200, OK则代表成功

注意,每个peer节点都需要安装链码!初始化只需要初始化一个就可以,和上面加入通道同样的操作(修改配置,一个一个安装)

5.4.5 链码初始化

注意链码的初始化只需要在一个节点上即可,其后会自动进行同步

peer chaincode instantiate [flags], 常用参数为:
	-C, --channelID: 当前命令运行的通道,默认值是“testchainid”
	-c, --ctor: JSON格式的构造参数,默认值是“{
    
    }”
	-l, --lang: 编写链码的编程语言,默认是golang
	-n, --name: 链码的名字
	-P, --policy: 当前Chaincode的背书策略
	-v, --version: 当前操作的链码的版本,适用于这些命令:install/instantiate/upgrade
	--tls: 通信时是否使用tls加密
	--cafile: 当前orderer节点pem格式的tls证书文件,要使用绝对路径
# example
# -c '{"Args":["init","a","100","b","200"]}'			# 给构造函数传参数
# -P "AND ('OrgGoMASP.member', 'OrgCppMSP.member')"    	
# AND表示这两个组织中的成员都需要参与,member表示组织中任一节点均可。如果是“OR”则表示任何一个组织成员都可以
peer chaincode instantiate -o orderer节点地址:端口 --tls true --cafile orderer节点pem格式的证书文件 -C 通道名称 -n 链码名称 -l 链码语言 -v 链码语言 -v 链码版本 -c 链码函数调用 -P 背书策略

背书策略:交易的规则,哪些人参与这笔交易,确定后进行模拟交易(测试)

注意这里的背书策略目前是初始化的指定作用,真正使用还需要到交易产生的时候

peer chaincode instantiate -o orderer.xwj.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/xwj.com/orderers/orderer.xwj.com/msp/tlscacerts/tlsca.xwj.com-cert.pem -C xwjchannel -n testcc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('OrgGoMSP.member', 'OrgCppMSP.member')"

此处错误集合:

  1. err Proposal response was not successful, error code 500, msg cannot get package for chaincode (testcc:1.0)

    解决办法:

    检查链码是否布置安装存在

    peer chaincode list --installed

    不存在的话先安装。退出cli容器要从创建channel通道开始重头再来

  2. API error (404): network xwj_fabric_1.2_byfn not found

    peer-base.yaml文件中的网络设置环境变量与启动网络的配置不一致,我之前export COMPOSE_PROJECT_NAME=xwj_fabric_1.2 这个“.”导致了问题,所以自己取名不要用“点”符号

    重新启动网络,重新操作

5.4.6 查询

# 查询账户A余额
peer chaincode query -C xwjchannel -c '{"Args":["query","a"]}' -n testcc
# 查询账户B的余额
peer chaincode query -C xwjchannel -c '{"Args":["query","b"]}' -n testcc

5.4.7 交易

peer chaincode invoke -o orderer.xwj.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/xwj.com/orderers/orderer.xwj.com/msp/tlscacerts/tlsca.xwj.com-cert.pem -C xwjchannel -n testcc --peerAddresses peer0.orggo.xwj.com:7051 --tlsRootCertFiles  /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.xwj.com/peers/peer0.orggo.xwj.com/tls/ca.crt --peerAddresses peer1.orgcpp.xwj.com:7051 --tlsRootCertFiles  /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.xwj.com/peers/peer1.orgcpp.xwj.com/tls/ca.crt -c '{"Args": ["invoke", "a", "b", "10"]}'

5.4.8 自动化shell脚本

先进入客户端

deploy.sh

# 将各个组织的所有节点加入到一个通道中,对每个节点部署链码,并对其中一个初始化链码
# 变量
CHANNEL_ID=xwjchannel 								# 通道id
CHANNEL_FIEL=./channel-artifacts/channel.tx			# 通道文件
ORDER_CAFILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/xwj.com/orderers/orderer.xwj.com/msp/tlscacerts/tlsca.xwj.com-cert.pem					# order的tls证书

# 组织
ORG01_NAME=orggo.xwj.com
ORG01_MSPID=OrgGoMSP

ORG02_NAME=orgcpp.xwj.com
ORG02_MSPID=OrgCppMSP

# 节点配置
ORDERER=orderer.xwj.com
ORDERER_PORT=7050
ORG01_PEERS=(peer0.$ORG01_NAME peer1.$ORG01_NAME)
ORG02_PEERS=(peer0.$ORG02_NAME peer1.$ORG02_NAME)
PEERS_PORT=7051


# 链码配置
CHAINCODE_NAME=testcc
CHAINCODE_VERSION=1.0
CHAINCODE_LANG=golang
CHAINCODE_PATH=github.com/chaincode/

# 背书策略
ENDORSE_POLICY="AND('$ORG01_MSPID.member','$ORG02_MSPID.member')"

# 初始化链码函数调用
INIT_FUNC='{"Args":["init","a","100","b","200"]}'


# 创建通道
peer channel create -o $ORDERER:$ORDERER_PORT -c $CHANNEL_ID -f $CHANNEL_FIEL --tls true --cafile $ORDER_CAFILE
if [ -f $CHANNEL_ID.block ];then
	echo -e "\033[32m create channel: $CHANNEL_ID path: $CHANNEL_FIEL ==> OK! \033[0m"
else
	echo -e "\033[31m create channel: $CHANNEL_ID ==> ERR! \033[0m"
fi	


# 遍历各个组织 给每个节点加入通道和安装链码
# 对于第一个组织Org1
for PEER in ${ORG01_PEERS[@]};do
    # 切换配置(换节点)
    export CORE_PEER_ADDRESS=$PEER:$PEERS_PORT
    export CORE_PEER_LOCALMSPID=$ORG01_MSPID
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG01_NAME/peers/$PEER/tls/server.crt
    export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG01_NAME/peers/$PEER/tls/server.key
    export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG01_NAME/peers/$PEER/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG01_NAME/users/Admin@$ORG01_NAME/msp
    
	# 加入通道并且安装链码
    echo -e "\033[32m $CORE_PEER_ADDRESS Configuring...... \033[0m"
    peer channel join -b $CHANNEL_ID.block
    peer chaincode install -n $CHAINCODE_NAME -v $CHAINCODE_VERSION -l $CHAINCODE_LANG -p $CHAINCODE_PATH
    echo -e "\033[32m $PEER Add channel: $CHANNEL_ID ==> OK! \033[0m"
    echo -e "\033[32m $PEER Install chaincode: $CHAINCODE_NAME ==> OK! \033[0m"
done

# 对于第二个组织
for PEER in ${ORG02_PEERS[@]};do
    # 切换配置(换节点)
    export CORE_PEER_ADDRESS=$PEER:$PEERS_PORT
    export CORE_PEER_LOCALMSPID=$ORG02_MSPID
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG02_NAME/peers/$PEER/tls/server.crt
    export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG02_NAME/peers/$PEER/tls/server.key
    export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG02_NAME/peers/$PEER/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/$ORG02_NAME/users/Admin@$ORG02_NAME/msp

	# 加入通道并且安装链码
    echo -e "\033[32m $CORE_PEER_ADDRESS Configuring...... \033[0m"
    peer channel join -b $CHANNEL_ID.block
    peer chaincode install -n $CHAINCODE_NAME -v $CHAINCODE_VERSION -l $CHAINCODE_LANG -p $CHAINCODE_PATH
    echo -e "\033[32m $PEER Add channel: $CHANNEL_ID ==> OK! \033[0m"
    echo -e "\033[32m $PEER Install chaincode: $CHAINCODE_NAME ==> OK! \033[0m"
done


# 对其中一个节点初始化链码
peer chaincode instantiate -o $ORDERER:$ORDERER_PORT --tls true --cafile $ORDER_CAFILE -C $CHANNEL_ID -n $CHAINCODE_NAME -l $CHAINCODE_LANG -v $CHAINCODE_VERSION -c $INIT_FUNC -P $ENDORSE_POLICY
echo -e "\033[32m $CORE_PEER_ADDRESS Instantiate chaincode: $CHAINCODE_NAME ==> OK! \033[0m"

爽的一p

Tips

1. 从Linux的vim中复制内容到系统的剪贴板

# 下载第三方插件
sudo apt-get install vim-gnome
# 再使用yy命令即可

注意,通过远程访问的无法复制到远程访问主机的剪贴板

2. 重复创建通道出错

error validating ReadSet: readset expected key [Group] /Channel/Application at version 0, but got version 1

原因:旧的通道还没删除,新的通道重复创建

解决办法,重新部署:

$ docker-compose down -v
$ docker volume prune
$ docker-compose up -d

猜你喜欢

转载自blog.csdn.net/weixin_43988498/article/details/109128683
今日推荐