欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-10 17:01:41
...

四、 Fabric核心模块

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

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

对于模块的说明:

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

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

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

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

命令手册:

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

五、手动组建Fabric网络

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

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

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

Fabric V1.2.0中的版本cryptogen:

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

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

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

 cryptogen generate --help

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

获取配置文件模板

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

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

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

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

# ---------------------------------------------------------------------------
# "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  # 一个指定域名
    # 这样是指定三个节点
    

小练习:

要求:

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

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

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命令去执行配置文件,如果不指定配置文件,则会按照模板文件来执行

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

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

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

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

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

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

检查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
                                                                  

锚节点

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

5.2.2 修改配置文件

事先需要做的事:

  • 找出orderer的msp的位置:

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

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


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

    go组织:

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

    /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创世块的这个名字(因为是创建创世块的命令需要这些配置信息):

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

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

    没有报错信息,并且看到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
    

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

    对应生成两个更新文件

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

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/aaa@qq.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个容器(包含客户端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/aaa@qq.com/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/aaa@qq.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/
        - ./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]		# 根证书

修改环境配置:

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

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节点

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

一个组织中的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 配置文件结构目录

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

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状态才表示镜像开启成功

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

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

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

查看,全部为绿色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

运行成功则出现:

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

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

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

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

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

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

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

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

大功告成!

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

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

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

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

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

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

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

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

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

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

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

5.4.1 创建channel通道

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

这个动作需要在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,所以命令中需要注意。

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

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

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

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

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

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

显示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

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

注意,加入到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/aaa@qq.com/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/aaa@qq.com/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/aaa@qq.com/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/aaa@qq.com/msp

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

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

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

5.4.3 更新锚节点

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

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

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

锚节点的更新文件路径:

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

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/
# 发现重命名的文件存在则说明已经成功

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


# 安装链码
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

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

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

返回响应为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')"

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

此处错误集合:

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

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

    解决办法:

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

    peer chaincode list --installed

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

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

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

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

    重新启动网络,重新操作

5.4.6 查询

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

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

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

5.4.7 交易

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

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

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"]}'

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

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/aaa@qq.com$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/aaa@qq.com$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"

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

爽的一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

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

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

解决办法,重新部署:

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