一、前言

1. 文件介绍

  • crypto-config.yaml

    用于生成相关组织的私钥和证书

  • configtx.yaml

    对相关组织进行配置

    配置orderer,用以生成orderer端初始化时所需的block(Genesis Block)

    配置channel,用以生成创建channel时所需的tx文件

  • core.yaml

    peer端的配置文件

  • orderer.yaml

    orderer端的配置文件

  • docker-compose.yaml

    用以配置fabric网络的相关容器

2. 概念——私钥、证书

使用公钥和私钥就是所谓的非对称加密方式

  • 公钥:是公布出去的给别人使用的,可以被很多人获取。用来加密和验章
  • 私钥:私钥只能自己持有,并且不可以被别人知道。用来解密和签章
  • 证书:是为公钥做认证,为了使公钥真实可信,防止他人伪造公钥;证书颁发机构(CA)会用自己的私钥对用户的公钥和相关信息进行加密,生成“数字证书”,然后证书中心会公布自己的公钥给所有人,用来让别人使用此公钥验证“数字证书”是否由CA颁发,即是否真实可信。

Fabric 中会有两种类型的公私钥和证书

  • 给节点之间通讯安全而准备的TLS证书
  • 用户登录和权限控制的用户证书。

二、生成Fabric证书、私钥

cryptogen工具及 crypto-config.yaml 配置文件,用于生成整个fabric网络的组织架构及对应的身份证书;

在 crypto-config.yaml 文件中定义了 整个fabric网络的组织结构 ,然后工具会根据定义的配置生成对应的组织结构并把对应的身份证书放置对应的目录下以便区分使用;

1. 命令介绍

arpen@arpen-ubuntu20:~/myfab$ cryptogen --help
usage: cryptogen [<flags>] <command> [<args> ...]

Utility for generating Hyperledger Fabric key material

Flags:
  --help  Show context-sensitive help (also try --help-long and --help-man).

Commands:
  help [<command>...]
    Show help.		## 显示帮助信息

  generate [<flags>]
    Generate key material		## 根据配置文件生成证书信息

  showtemplate
    Show the default configuration template		## 显示系统默认的cryptogen模块配置文件信息

  version
    Show version information		## 显示当前模块版本号

  extend [<flags>]
    Extend existing network		## 扩展现有网络

arpen@arpen-ubuntu20:~/myfab$ cryptogen generate --help
usage: cryptogen generate [<flags>]

Generate key material

Flags:
  --help                    Show context-sensitive help (also try --help-long and --help-man).		## 显示帮助信息
  --output="crypto-config"  The output directory in which to place artifacts		## 指定输出目录
  --config=CONFIG           The configuration template to use		## 指定使用的配置文件

2. crypto-config.yaml

1. 默认模板
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# 定义Orderer组织结构
# ---------------------------------------------------------------------------
OrdererOrgs:
  # ---------------------------------------------------------------------------
  # Orderer
  # 生成证书的时候,证书内会包含Name和Domain信息,如下orderer.example.com就是这个组织的地址
  # ---------------------------------------------------------------------------
  - Name: Orderer          #  Orderer组织的名称
    Domain: example.com          # 组织的命名域
    EnableNodeOUs: true          # 是否支持node.js。如果设置了 EnableNodeOUs ,就在msp下生成config.yaml文件
    # ---------------------------------------------------------------------------
    # "Specs" - See PeerOrgs below for complete description
    # 对于一个Spec来说,配置了CommonName,那么文件夹则命名为CommonName
    # ---------------------------------------------------------------------------
    Specs:
      - Hostname: orderer
        # CommonName: orderer.test.com          
        # 启用上一行所示标签,则在 crypto-config/ordererOrganizations/example.com/orderers 目录下
        # 会产生一个目录名为orderer.test.com的文件
        # 如果不启用上一行所示标签,则目录名为order.example.com
        
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# 管理Peer节点的组织的定义
# ---------------------------------------------------------------------------
PeerOrgs:
  # ---------------------------------------------------------------------------
  # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1          # 组织名称
    Domain: org1.example.com          # 组织域名
    EnableNodeOUs: true          # 是否支持node.js。如果设置了EnableNodeOUs,就在msp下生成config.yaml文件
    # ---------------------------------------------------------------------------
    # "Specs"
    # 规格
    # ---------------------------------------------------------------------------
    # Uncomment this section to enable the explicit definition of hosts in your
    # configuration.  Most users will want to use Template, below
    # 取消注释此部分可在配置中启用主机的显式定义。 大多数用户都希望使用下面的模板
    #
    # Specs is an array of Spec entries.  Each Spec entry consists of two fields:
    # Specs是Spec条目的数组。 每个规格条目均包含两个字段
    #   - Hostname:   (Required) The desired hostname, sans the domain.
    #   - 主机名:(必填)所需的主机名,无域。
    #   - CommonName: (Optional) Specifies the template or explicit override for
    #                 the CN.  By default, this is the template:
    #   -通用名:(可选)为CN指定模板或显式替代。 默认情况下,这是模板:
    #
    #                              "{{.Hostname}}.{{.Domain}}"
    #
    #                 which obtains its values from the Spec.Hostname and
    #                 Org.Domain, respectively.
    #                 它分别从Spec.Hostname和Org.Domain获取其值
    # ---------------------------------------------------------------------------
    # 如下如果在这里加入一个Specs,那么会在peers目录下生成文件
    # 命名为 foo.org1.example.com, bar.org1.example.com 和 baz.org1.example.com
    # Specs:
    #   - Hostname: foo # implicitly "foo.org1.example.com"
    #     CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
                                             # 覆盖上面设置的基于主机名的FQDN
    #   - Hostname: bar
    #   - Hostname: baz
    # ---------------------------------------------------------------------------
    # ---------------------------------------------------------------------------
    # "Template"
    # 模板
    # ---------------------------------------------------------------------------
    # Allows for the definition of 1 or more hosts that are created sequentially
    # from a template. By default, this looks like "peer%d" from 0 to Count-1.
    # 允许定义从模板顺序创建的1个或多个主机。默认情况下,它看起来像是从0到Count-1的“peer%d”。
    # You may override the number of nodes (Count), the starting index (Start)
    # or the template used to construct the name (Hostname).
    # 您可以覆盖节点数(Count),起始索引(Start)或用于构造名称(Hostname)的模板。
    #
    # Note: Template and Specs are not mutually exclusive.  You may define both
    # sections and the aggregate nodes will be created for you.  Take care with
    # name collisions
    # 注意:模板和规格不是互斥的。您可以定义两个部分,然后将为您创建聚合节点。注意名称冲突
    # ---------------------------------------------------------------------------
    Template:
      Count: 2          # 表示生成Peer的数量
                        # 该配置会在crypto-config/peerOrganizations/org1.example.com/peers目录下,
                        # 生成两个文件,分别是 peer0.org1.example.com 和 peer1.org1.example.com
      # Start: 5          # 表示生成peer的起始编号
                          # 把Start注释去掉,那么会生成 peer5.org1.example.com 和 peer6.org1.example.com
      # Hostname: {{.Prefix}}{{.Index}} # default
    # ---------------------------------------------------------------------------
    # "Users"
    # 用户
    # ---------------------------------------------------------------------------
    # Count: The number of user accounts _in addition_ to Admin
    # 生成除了Admin之外多少个user,数量由Count决定
    # 对于orderer组织,这个值设置了也没有效果
    # ---------------------------------------------------------------------------
    Users:
      Count: 1
      # 以上配置会在crypto-config/peerOrganizations/org1.example.com/users目录下,
      # 生成两个文件,分别是Admin@org1.example.com和User1@org1.example.com
      # 如果改为2,那么会多一个User2@org1.example.com
  # ---------------------------------------------------------------------------
  # Org2: See "Org1" for full specification
  # ---------------------------------------------------------------------------
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1
2. 简洁模板
# crypto-config.yaml

# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:     # 排序节点orderer的组织信息,不可更改!
  # ---------------------------------------------------------------------------
  # "OrdererOrgs" - Definition of organizations managing orderer nodes
  # ---------------------------------------------------------------------------
  - Name: Orderer     # 排序节点的组织名称,可自行更改
    Domain: example.com     # 排序节点组织的根域名
    EnableNodeOUs: true     # 是否支持node.js
    Specs:
      - Hostname: orderer     # 访问该orderer节点对应的域名:orderer.example.com
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:     # 管理Peer节点的组织信息,不可更改!
   # ---------------------------------------------------------------------------
   # Org1
  # ---------------------------------------------------------------------------
  - Name: Org1     # 第一个组织的名字,可以自行设定
    Domain: org1.example.com     # 访问第一个组织所使用的根域名
    EnableNodeOUs: true     # 是否支持node.js
    Template:     # 模板。根据默认的规则生成指定数量【2】的用于数据存储的Peer节点
      Count: 2     # 生成Peer节点的数量:peer0.org1.example.com 和 peer1.org1.example.com
    Users:     # 创建的普通用户的数量
      Count: 1
  # ---------------------------------------------------------------------------
  # Org2: See "Org1" for full specification
  # ---------------------------------------------------------------------------
  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Users:
      Count: 1

通常来说

  • Name和Domain是必须要有的
  • Specs中的配置和Template里的Count共同决定了,orderers或者是peers目录下的子目录数
  • 对于peer组织来说,Users里的count决定users目录下除了Admin以外的子目录数目
Note:【specs 】和【template 】

​ 在模板中,specs 和 template 均可使用,其中:

​ specs用户可以自定义命名

​ template则会调用预定的规则进行生成

​ 例如:

  - Name: Org2
    Domain: org2.example.com
    EnableNodeOUs: true
    Template:
      Count: 2
    Specs:
      - Hostname: test
    Users:
      Count: 1

以上会生成3个节点,分别是peer0.org2.example.com 、 peer1.org2.example.com 以及test.org2.example.com

3. crypto-config 目录结构

Fabric使用了cryptogen工具 用来调用上面的配置文件生成私钥和证书

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

执行完以后,会在当前目录生成一个 crypto-config 目录,当然也可以在命令中添加 –output 选项来指定输出的目录。在这个目录下就会根据 Orderer 和Peer 各自生成两个文件夹:

  • ordererOrganizations
  • peerOrganizations

它们分别代表着orderer和peer的组织及对应目录下的证书文件。

每个组织下都有ca、tlsca、msp、orderers(或者Peers)、users等5个文件,下面通过 tree 命令的输出结果,分别解释一下各个目录的作用。

arpen@arpen-ubuntu20:~/myfab$ tree crypto-config
crypto-config
├── ordererOrganizations		## 组织配置
│   └── example.com			## 组织根域名
│       ├── ca			## 存放组织根证书及私钥。 私钥(采用EC算法) 证书为【自签名】,组织内的实体将给予该根证书作为证书根
│       │   ├── ca.example.com-cert.pem			## 组织根证书,自签名
│       │   └── priv_sk			## 私钥
│       ├── msp			## 存放该组织身份信息
│       │   ├── admincerts			## 组织管理员
│       │   │   └── Admin@example.com-cert.pem			## 管理员身份验证证书,被根证书签名
│       │   ├── cacerts			## 组织的根证书
│       │   │   └── ca.example.com-cert.pem			## 组织的根证书,与ca里面的一致
│       │   ├── config.yaml			## 配置文件中加了 EnableNodeOUs 参数生成的config.yaml文件,记录 OrganizationalUnitIdentitifiers 信息,包括根证书位置和ID信息
│       │   └── tlscacerts			## 用于TLS的CA证书
│       │       └── tlsca.example.com-cert.pem			## 用于TLS的CA证书,自签名
│       ├── orderers			## 存放所有 Orderer 的身份信息
│       │   └── orderer.example.com			## 第一个orderer的信息,msp与TLS
│       │       ├── msp			## 存放该组织身份信息
│       │       │   ├── admincerts			## 组织管理员的身份验证证书,与 msp.admincerts 保持一致
│       │       │   │   └── Admin@example.com-cert.pem			## orderer被给予这些证书来确认交易签名是否为管理员签名
│       │       │   ├── cacerts			## 存放组织根证书
│       │       │   │   └── ca.example.com-cert.pem			## 组织的根证书,与ca里面的一致
│       │       │   ├── keystore			## 本节点的身份私钥,用来签名
│       │       │   │   └── priv_sk			## 私钥
│       │       │   ├── signcerts			## 验证本节点签名的证书,被根证书签名
│       │       │   │   └── orderer.example.com-cert.pem		## 组织的根证书,与ca里面的一致
│       │       │   └── tlscacerts			## TLS连接用的身份证书,与 msp.tlscacerts 保持一致
│       │       │       └── tlsca.example.com-cert.pem			## 用于TLS的CA证书,自签名
│       │       └── tls			## TLS的相关信息
│       │           ├── ca.crt			## 组织的根证书
│       │           ├── server.crt			## 验证本节点签名的证书,被根证书签名
│       │           └── server.key			## 本节点的身份私钥,用来签名
#############################################################
# 注意:在此若设有其他的orderer节点,会在此继续罗列如上的目录结构
#############################################################
│       ├── tlsca		## 存放tls相关的证书和私钥
│       │   ├── priv_sk			## tls私钥
│       │   └── tlsca.example.com-cert.pem			## tls证书
│       └── users		## 存放属于该组织的用户的实体
│           └── Admin@example.com		## 管理员用户的信息,其中包括msp证书和tls证书两类
│               ├── msp			## 存放身份信息
│               │   ├── admincerts		## 组织管理员的身份验证证书,与 msp.admincerts 保持一致
│               │   │   └── Admin@example.com-cert.pem
│               │   ├── cacerts			## 存放组织根证书,与CA目录里一致
│               │   │   └── ca.example.com-cert.pem
│               │   ├── keystore		## 本用户的身份私钥,用来签名
│               │   │   └── priv_sk
│               │   ├── signcerts		## 验证本用户的身份验证证书,被根证书签名,要被某个Orderer认可,则必须放到该 Orderer 的msp/admincerts目录下,因此上面orderer的msp/admincerts目录下的证书应该要是从这里复制一份过去
│               │   │   └── Admin@example.com-cert.pem
│               │   └── tlscacerts		## TLS连接用的身份证书,与 msp.tlscacerts 保持一致
│               │       └── tlsca.example.com-cert.pem
│               └── tls			## TLS的相关信息
│                   ├── ca.crt
│                   ├── client.crt		## 管理员身份验证证书,被根证书签名
│                   └── client.key		## 管理员的身份私钥,用来签名
└── peerOrganizations			## peer组织
    ├── org1.example.com			##  第一个组织的所有身份证书
    │   ├── ca			## 存放私钥与组织根证书
    │   │   ├── ca.org1.example.com-cert.pem
    │   │   └── priv_sk
    │   ├── msp			## msp信息与order组织类似
    │   │   ├── admincerts
    │   │   │   └── Admin@org1.example.com-cert.pem
    │   │   ├── cacerts
    │   │   │   └── ca.org1.example.com-cert.pem
    │   │   └── tlscacerts
    │   │       └── tlsca.org1.example.com-cert.pem
    │   ├── peers		## peers目录与order组织的orderers目录类似
    │   │   ├── peer0.org1.example.com
    │   │   │   ├── msp
    │   │   │   │   ├── admincerts
    │   │   │   │   │   └── Admin@org1.example.com-cert.pem
    │   │   │   │   ├── cacerts
    │   │   │   │   │   └── ca.org1.example.com-cert.pem
    │   │   │   │   ├── keystore
    │   │   │   │   │   └── priv_sk
    │   │   │   │   ├── signcerts
    │   │   │   │   │   └── peer0.org1.example.com-cert.pem
    │   │   │   │   └── tlscacerts
    │   │   │   │       └── tlsca.org1.example.com-cert.pem
    │   │   │   └── tls
    │   │   │       ├── ca.crt
    │   │   │       ├── server.crt
    │   │   │       └── server.key
    │   │   └── peer1.org1.example.com
    │   │       ├── msp
    │   │       │   ├── admincerts
    │   │       │   │   └── Admin@org1.example.com-cert.pem
    │   │       │   ├── cacerts
    │   │       │   │   └── ca.org1.example.com-cert.pem
    │   │       │   ├── keystore
    │   │       │   │   └── priv_sk
    │   │       │   ├── signcerts
    │   │       │   │   └── peer1.org1.example.com-cert.pem
    │   │       │   └── tlscacerts
    │   │       │       └── tlsca.org1.example.com-cert.pem
    │   │       └── tls
    │   │           ├── ca.crt
    │   │           ├── server.crt
    │   │           └── server.key
    │   ├── tlsca			## 存放tls相关的证书和私钥
    │   │   ├── priv_sk
    │   │   └── tlsca.org1.example.com-cert.pem
    │   └── users
    │       ├── Admin@org1.example.com
    │       │   ├── msp
    │       │   │   ├── admincerts
    │       │   │   │   └── Admin@org1.example.com-cert.pem
    │       │   │   ├── cacerts
    │       │   │   │   └── ca.org1.example.com-cert.pem
    │       │   │   ├── keystore
    │       │   │   │   └── priv_sk
    │       │   │   ├── signcerts
    │       │   │   │   └── Admin@org1.example.com-cert.pem
    │       │   │   └── tlscacerts
    │       │   │       └── tlsca.org1.example.com-cert.pem
    │       │   └── tls
    │       │       ├── ca.crt
    │       │       ├── client.crt
    │       │       └── client.key
    │       ├── User1@org1.example.com
    │       │   ├── msp
    │       │   │   ├── admincerts
    │       │   │   │   └── User1@org1.example.com-cert.pem
    │       │   │   ├── cacerts
    │       │   │   │   └── ca.org1.example.com-cert.pem
    │       │   │   ├── keystore
    │       │   │   │   └── priv_sk
    │       │   │   ├── signcerts
    │       │   │   │   └── User1@org1.example.com-cert.pem
    │       │   │   └── tlscacerts
    │       │   │       └── tlsca.org1.example.com-cert.pem
    │       │   └── tls
    │       │       ├── ca.crt
    │       │       ├── client.crt
    │       │       └── client.key
    │       ├── User2@org1.example.com
    │       │   ├── msp
    │       │   │   ├── admincerts
    │       │   │   │   └── User2@org1.example.com-cert.pem
    │       │   │   ├── cacerts
    │       │   │   │   └── ca.org1.example.com-cert.pem
    │       │   │   ├── keystore
    │       │   │   │   └── priv_sk
    │       │   │   ├── signcerts
    │       │   │   │   └── User2@org1.example.com-cert.pem
    │       │   │   └── tlscacerts
    │       │   │       └── tlsca.org1.example.com-cert.pem
    │       │   └── tls
    │       │       ├── ca.crt
    │       │       ├── client.crt
    │       │       └── client.key
    │       └── User3@org1.example.com
    │           ├── msp
    │           │   ├── admincerts
    │           │   │   └── User3@org1.example.com-cert.pem
    │           │   ├── cacerts
    │           │   │   └── ca.org1.example.com-cert.pem
    │           │   ├── keystore
    │           │   │   └── priv_sk
    │           │   ├── signcerts
    │           │   │   └── User3@org1.example.com-cert.pem
    │           │   └── tlscacerts
    │           │       └── tlsca.org1.example.com-cert.pem
    │           └── tls
    │               ├── ca.crt
    │               ├── client.crt
    │               └── client.key
    └── org2.example.com
    ################################
    # 以下内容与org1.example.com类似
    ################################
        ├── ca
        │   ├── ca.org2.example.com-cert.pem
        │   └── priv_sk
        ├── msp
        │   ├── admincerts
        │   ├── cacerts
        │   │   └── ca.org2.example.com-cert.pem
        │   ├── config.yaml
        │   └── tlscacerts
        │       └── tlsca.org2.example.com-cert.pem
        ├── peers
        │   ├── peer0.org2.example.com
        │   │   ├── msp
        │   │   │   ├── admincerts
        │   │   │   ├── cacerts
        │   │   │   │   └── ca.org2.example.com-cert.pem
        │   │   │   ├── config.yaml
        │   │   │   ├── keystore
        │   │   │   │   └── priv_sk
        │   │   │   ├── signcerts
        │   │   │   │   └── peer0.org2.example.com-cert.pem
        │   │   │   └── tlscacerts
        │   │   │       └── tlsca.org2.example.com-cert.pem
        │   │   └── tls
        │   │       ├── ca.crt
        │   │       ├── server.crt
        │   │       └── server.key
        │   └── peer1.org2.example.com
        │       ├── msp
        │       │   ├── admincerts
        │       │   ├── cacerts
        │       │   │   └── ca.org2.example.com-cert.pem
        │       │   ├── config.yaml
        │       │   ├── keystore
        │       │   │   └── priv_sk
        │       │   ├── signcerts
        │       │   │   └── peer1.org2.example.com-cert.pem
        │       │   └── tlscacerts
        │       │       └── tlsca.org2.example.com-cert.pem
        │       └── tls
        │           ├── ca.crt
        │           ├── server.crt
        │           └── server.key
        ├── tlsca
        │   ├── priv_sk
        │   └── tlsca.org2.example.com-cert.pem
        └── users
            ├── Admin@org2.example.com
            │   ├── msp
            │   │   ├── admincerts
            │   │   ├── cacerts
            │   │   │   └── ca.org2.example.com-cert.pem
            │   │   ├── config.yaml
            │   │   ├── keystore
            │   │   │   └── priv_sk
            │   │   ├── signcerts
            │   │   │   └── Admin@org2.example.com-cert.pem
            │   │   └── tlscacerts
            │   │       └── tlsca.org2.example.com-cert.pem
            │   └── tls
            │       ├── ca.crt
            │       ├── client.crt
            │       └── client.key
            ├── User1@org2.example.com
            │   ├── msp
            │   │   ├── admincerts
            │   │   ├── cacerts
            │   │   │   └── ca.org2.example.com-cert.pem
            │   │   ├── config.yaml
            │   │   ├── keystore
            │   │   │   └── priv_sk
            │   │   ├── signcerts
            │   │   │   └── User1@org2.example.com-cert.pem
            │   │   └── tlscacerts
            │   │       └── tlsca.org2.example.com-cert.pem
            │   └── tls
            │       ├── ca.crt
            │       ├── client.crt
            │       └── client.key
            ├── User2@org2.example.com
            │   ├── msp
            │   │   ├── admincerts
            │   │   ├── cacerts
            │   │   │   └── ca.org2.example.com-cert.pem
            │   │   ├── config.yaml
            │   │   ├── keystore
            │   │   │   └── priv_sk
            │   │   ├── signcerts
            │   │   │   └── User2@org2.example.com-cert.pem
            │   │   └── tlscacerts
            │   │       └── tlsca.org2.example.com-cert.pem
            │   └── tls
            │       ├── ca.crt
            │       ├── client.crt
            │       └── client.key
            └── User3@org2.example.com
                ├── msp
                │   ├── admincerts
                │   ├── cacerts
                │   │   └── ca.org2.example.com-cert.pem
                │   ├── config.yaml
                │   ├── keystore
                │   │   └── priv_sk
                │   ├── signcerts
                │   │   └── User3@org2.example.com-cert.pem
                │   └── tlscacerts
                │       └── tlsca.org2.example.com-cert.pem
                └── tls
                    ├── ca.crt
                    ├── client.crt
                    └── client.key

141 directories, 133 files

说明

  • 在一个组织内部(orderer的example.com,peer的org1.example.com,或peer的org2.example.com),所有的admincerts是一样的。admin的私钥在Users的Admin文件夹下
  • 在一个组织内部,所有的cacerts是一样的,ca的私钥在ca文件夹下
  • 在一个组织内部,所有的tlscacerts是一样的,且和tls文件夹下的ca.crt文件一样。tlsca的私钥在tlsca文件夹下

对于peer/orderer以及users来说,msp/keystore下是私钥,msp/signcerts下是证书。

tls下的server.key(peer下是client.key)和server.crt是私钥和证书

4. cryptogen 工具

cryptogen 工具就是在各个资源下生成 组织 和 私钥 、证书等等,其中最关键的就是 各个资源下的MSP 目录内容:

  1. admincerts: 管理员的身份证书文件
  2. cacerts: 信任的根证书文件
  3. keystore: 节点的签名私钥文件
  4. signcerts: 节点的签名身份证书文件
  5. tlscacerts: TLS连接用的证书

等等 5 种文件

5. 相关的证书配置

  • configtx.yaml,配外层的msp文件夹
MSPDir: crypto-config/ordererOrganizations/example.com/msp
  • peer的core.yaml文件,使用peers下面的msp文件夹
mspConfigPath: ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp
  • orderer的orderer.yaml文件,使用orderer下面的msp文件夹
LocalMSPDir: ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp
  • client和sdk端,使用users下面的msp文件夹
mspConfigPath: ../crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

6. 生成证书文件命令

通过重定向命令生成配置文件。并根据需要进行修改

$ cryptogen showtemplate > crypto-config.yaml

在工作目录下执行下列命令

$ cryptogen generate --config=crypto-config.yaml

三、生成创世块、通道

【1】生成启动 Orderer 需要的创世块;

【2】创建应用通道的配置交易文件;

【3】生成组织锚节点更新配置交易文件;

在 configtx.yaml 配置中主要包括:Profiles、Organizations、Orderer、Application 等等 4 部分;

1. 命令介绍

arpen@arpen-ubuntu20:~/myfab$ configtxgen --help
Usage of configtxgen:
-asOrg string				## 指定所属的组织名称
-channelCreateTxBaseProfile string
-channelID string			## 指定创建的channel的名字,如未指定,系统会提供一个默认名字
-configPath string
-inspectBlock string
-inspectChannelCreateTx string
-outputAnchorPeersUpdate string		## 更新channel的配置信息
-outputBlock string		## 输出创世块区块文件的路径和名字
-outputCreateChannelTx string			## 指定输出通道文件的路径和名字
-printOrg string
-profile string			## 指定配置文件中的节点
-version

2. configtx.yaml

1. 默认模板
---
################################################################################
#
#   Section: Organizations
#
#   - This section defines the different organizational identities which will
#   be referenced later in the configuration.
#   - 本节定义了不同的组织身份,稍后将在配置中引用这些组织身份。
#
################################################################################
Organizations:

    # SampleOrg defines an MSP using the sampleconfig.  It should never be used
    # in production but may be used as a template for other definitions
    # SampleOrg使用sampleconfig定义了一个MSP。 永远不要在生产中使用它,而可以将其用作其他定义的模板
    - &OrdererOrg          # 定义Orderer组织
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        # DefaultOrg定义在fabric.git开发环境的sampleconfig中使用的组织
        Name: OrdererOrg          # 组织名称

        # ID to load the MSP definition as
        ID: OrdererMSP          # Orderer 组织的ID (ID是引用组织的关键)

        # MSPDir is the filesystem path which contains the MSP configuration
        # MSPDir是包含MSP配置的文件系统路径
        MSPDir: crypto-config/ordererOrganizations/example.com/msp          # Orderer的 MSP 证书目录路径

        # Policies defines the set of policies at this level of the config tree
        # 策略在配置树的此级别定义策略集
        # For organization policies, their canonical path is usually
        # 对于组织政策,其规范路径通常是
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:          # 资源访问权限的限制策略,支持AND, OR, 以及 OutOf三种策略规则组合
                           # Signature类型的Rule的格式为:EXPR(E[, E…])
                           # EXPR有三个选项:AND, OR 和 OutOf;E表示责任人(英文:principal)
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"		# 具体策略:允许OrdererMSP中所有member读操作
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"

    - &Org1          # 定义Peer组织 1
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: Org1MSP          # 组织名称

        # ID to load the MSP definition as
        ID: Org1MSP          # 组织ID

        MSPDir: crypto-config/peerOrganizations/org1.example.com/msp          # Peer的MSP 证书目录路径

        # Policies defines the set of policies at this level of the config tree
        # 策略在配置树的此级别定义策略集
        # For organization policies, their canonical path is usually
        # 对于组织政策,其规范路径通常是
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"		# Org1MSP中的admin,peer,client均可进行读操作
            Writers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1MSP.admin')"

        # leave this flag set to true.
        AnchorPeers:
            # AnchorPeers defines the location of peers which can be used
            # for cross org gossip communication.  Note, this value is only
            # encoded in the genesis block in the Application section context
            # AnchorPeers定义了可用于跨组织gossip通信的对等点的位置。 
            # 注意,此值仅在“应用程序”部分上下文中的创世区块中编码
            - Host: peer0.org1.example.com          # 锚节点的主机名
              Port: 7051          # 锚节点的端口号

    - &Org2          # 定义Peer组织 2
        # DefaultOrg defines the organization which is used in the sampleconfig
        # of the fabric.git development environment
        Name: Org2MSP

        # ID to load the MSP definition as
        ID: Org2MSP

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

        # Policies defines the set of policies at this level of the config tree
        # For organization policies, their canonical path is usually
        #   /Channel/<Application|Orderer>/<OrgName>/<PolicyName>
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org2MSP.admin')"

        AnchorPeers:
            # AnchorPeers defines the location of peers which can be used
            # for cross org gossip communication.  Note, this value is only
            # encoded in the genesis block in the Application section context
            - Host: peer0.org2.example.com
              Port: 7051

################################################################################
#
#   SECTION: Capabilities
#  【注意】: 该部分是 V1.1.0 版本提出来的, 不可以在更早的版本中使用
#
#   - This section defines the capabilities of fabric network. This is a new
#   concept as of v1.1.0 and should not be utilized in mixed networks with
#   v1.0.x peers and orderers.  Capabilities define features which must be
#   present in a fabric binary for that binary to safely participate in the
#   fabric network.  For instance, if a new MSP type is added, newer binaries
#   might recognize and validate the signatures from this type, while older
#   binaries without this support would be unable to validate those
#   transactions.  This could lead to different versions of the fabric binaries
#   having different world states.  Instead, defining a capability for a channel
#   informs those binaries without this capability that they must cease
#   processing transactions until they have been upgraded.  For v1.0.x if any
#   capabilities are defined (including a map with all capabilities turned off)
#   then the v1.0.x peer will deliberately crash.
#   - 本节定义了 fabric 网络的功能. 这是v1.1.0中的一个新概念,不应在v1.0.x的peer和orderers中使用。  
#   Capabilities 定义了存在于结构二进制文件中的功能,以便该二进制文件安全地参与结构网络。例如,如果
#   添加了新的MSP类型,则较新的二进制文件可能会识别并验证此类型的签名,而没有此支持的旧二进制文件将
#   无法验证这些事务。这可能导致具有不同世界状态的不同版本的结构二进制文件。 相反,为通道定义功能会
#   通知那些没有此功能的二进制文件,它们必须在升级之前停止处理事务.  对于v1.0.x,如果定义了任何功能
#  (包括关闭所有功能的配置),那么v1.0.x的peer会主动崩溃
#
################################################################################
Capabilities:
    # Channel capabilities apply to both the orderers and the peers and must be
    # supported by both.
    # 通道功能既适用于orderers,也适用于peers,并且必须得到两者的支持。
    # Set the value of the capability to true to require it.
    # 将该配置项设置为ture表明要求节点具备该能力,false则不要求该节点具备该能力
    Channel: &ChannelCapabilities
        V2_2: true     # V2.2的 Channel是一个行为标记,已被确定为运行V2.2.x的所有orderers和peers的行为,
                       # 其修改会导致不兼容。用户应将此标志设置为true.
        V1_3: false 
        V1_1: false
    # Orderer capabilities apply only to the orderers, and may be safely
    # used with prior release peers.
    # Orderer功能仅适用于orderers,可以安全地操作,而无需担心升级peers
    # Set the value of the capability to true to require it.
    # 将该配置项设置为ture表明要求节点具备该能力,false则不要求该节点具备该能力
    Orderer: &OrdererCapabilities
        V2_2: true     # Orderer 的V2.2是行为的一个标记,已经确定为运行V2.2.x的所有orderers 都需要,
                       # 其修改会导致不兼容。用户应将此标志设置为true
        V1_4_2: false
        V1_1: false

    # Application capabilities apply only to the peer network, and may be safely
    # used with prior release orderers.
    # 应用程序功能仅适用于Peer网络,可以安全地操作,而无需担心升级或更新orderers
    # Set the value of the capability to true to require it.
    # 将该配置项设置为ture表明要求节点具备该能力,false则不要求该节点具备该能力
    Application: &ApplicationCapabilities
        V2_2: true     # V2.2的Application是一个行为标记,已被确定为运行V2.2.x的所有peers所需的行为,
                       # 其修改会导致不兼容。用户应将此标志设置为true
        # V1.3 for Application enables the new non-backwards compatible
        # features and fixes of fabric v1.3.(note, this need not be set if
        # later version capabilities are set)
        # V1.3的Application启用了结构v1.3的新的非向后兼容功能和修补程序。
        # (注意,如果设置了更高版本的功能,则无需设置此功能)
        V1_3: false
        # V1.2 for Application enables the new non-backwards compatible
        # features and fixes of fabric v1.2 (note, this need not be set if
        # later version capabilities are set)
        # V1.2 for Application启用了结构v1.2的新的非向后兼容功能和修补程序
        # (注意,如果设置了更高版本的功能,则无需设置此功能)
        V1_2: false
        # V1.1 for Application enables the new non-backwards compatible
        # features and fixes of fabric v1.1 (note, this need not be set if
        # later version capabilities are set).
        # V1.1 for Application启用了结构v1.1的新的非向后兼容功能和修补程序
        # (注意,如果设置了更高版本的功能,则无需设置此功能)。
        V1_1: false

################################################################################
#
#   SECTION: Application
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for application related parameters
#   - 本节定义了要编码为应用程序相关参数的配置事务或创世区块中的值
#
################################################################################
Application: &ApplicationDefaults     # 自定义被引用的地址

    # Organizations is the list of orgs which are defined as participants on
    # the application side of the network
    # Organizations是orgs的列表,这些orgs被定义为网络应用程序端的参与者
    Organizations:     # Organizations配置列出参与到网络中的机构清单

    # Policies defines the set of policies at this level of the config tree
    # 策略在配置树的此级别定义策略集
    # For Application policies, their canonical path is
    # 对于应用程序策略,其规范路径为
    #   /Channel/Application/<PolicyName>
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    # Capabilities配置描述应用层级的能力需求,这里直接引用
    # 前面Capabilities配置段中的ApplicationCapabilities配置项
    Capabilities:
        <<: *ApplicationCapabilities
################################################################################
#
#   SECTION: Orderer
#
#   - This section defines the values to encode into a config transaction or
#   genesis block for orderer related parameters
#   - 本部分定义了要编码为与orderer相关的参数的配置事务或创世区块的值
#
#   Orderer 默认是 solo 的 且不包含任何组织 【主要被 Profiles 部分引用】
################################################################################
Orderer: &OrdererDefaults     # 自定义被引用的地址

    # Orderer Type: The orderer implementation to start
    # Orderer类型:Orderer实施启动
    # Available types are "solo" and "kafka"
    # 可用类型为“ solo”,“ kafka”,“EtcdRaft”
    OrdererType: solo     # 选择启动类型

    Addresses:     # 服务地址,这个地方很重要,一定要配正确
        - orderer.example.com:7050

    # Batch Timeout: The amount of time to wait before creating a batch
    # 区块打包的最大超时时间 (到了该时间就打包区块)
    BatchTimeout: 2s

    # Batch Size: Controls the number of messages batched into a block
    # 区块打包的最大包含交易数(orderer端切分区块的参数)
    BatchSize:

        # Max Message Count: The maximum number of messages to permit in a batch
        # 一个区块里最大的交易数
        MaxMessageCount: 10

        # Absolute Max Bytes: The absolute maximum number of bytes allowed for
        # the serialized messages in a batch.
        # # 一个区块的最大字节数,任何时候都不能超过
        AbsoluteMaxBytes: 99 MB

        # Preferred Max Bytes: The preferred maximum number of bytes allowed for
        # the serialized messages in a batch. A message larger than the preferred
        # max bytes will result in a batch larger than preferred max bytes.
        # 一个区块的建议字节数,如果一个交易消息的大小超过了这个值, 就会被放入另外一个更大的区块中
        PreferredMaxBytes: 512 KB
        
    # MaxChannels: 0     # 【可选项】 表示Orderer 允许的最大通道数, 默认 0 表示没有最大通道数

    Kafka:
        # Brokers: A list of Kafka brokers to which the orderer connects
        #订购者连接的Kafka brokers列表
        # NOTE: Use IP:port notation IP:端口号
        # kafka模式的时候kafka节点的地址,通常至少配2个
        Brokers:
            - 127.0.0.1:9092

    EtcdRaft:	## 定义了EtcdRaft排序类型被选择时的配置
            Consenters:
                - Host: orderer.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                - Host: orderer2.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
                - Host: orderer3.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt
                - Host: orderer4.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt
                - Host: orderer5.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt
    
    # Organizations is the list of orgs which are defined as participants on
    # the orderer side of the network
    # 参与维护Orderer的组织,默认为空
    Organizations:

    # Policies defines the set of policies at this level of the config tree
    # 策略在配置树的此级别定义策略集
    # For Application policies, their canonical path is
    # 对于应用程序策略,其规范路径为
    #   /Channel/Orderer/<PolicyName>
    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        # BlockValidation specifies what signatures must be included in the block
        # from the orderer for the peer to validate it.
        # 指定在orderer的块中必须包含哪些签名,以便peer对其进行验证。
        BlockValidation:
            Type: ImplicitMeta
            Rule: "ANY Writers"

################################################################################
#
#   CHANNEL
#
#   This section defines the values to encode into a config transaction or
#   genesis block for channel related parameters.
#   本部分定义了要编码为通道相关参数的配置事务或创世块的值。
#
################################################################################
Channel: &ChannelDefaults
    # Policies defines the set of policies at this level of the config tree
    # 策略在配置树的此级别定义策略集
    # For Application policies, their canonical path is
    # 对于应用程序策略,其规范路径为
    #   /Channel/<PolicyName>
    Policies:
        # Who may invoke the 'Deliver' API
        # Readers策略定义了调用Deliver API提交交易的许可规则
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        # Who may invoke the 'Broadcast' API
        # Writes策略定义了调用Broadcast API提交交易的许可规则
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        # By default, who may modify elements at this config level
        # Admin策略定义了修改本层级配置的许可规则
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    # Capabilities describes the channel level capabilities, see the
    # dedicated Capabilities section elsewhere in this file for a full
    # description
    # Capabilities配置描通道层级的能力需求,这里直接引用
    # 前面Capabilities配置段中的ChannelCapabilities配置项
    Capabilities:
        <<: *ChannelCapabilities

################################################################################
#
#   Profile
#
#   - Different configuration profiles may be encoded here to be specified
#   as parameters to the configtxgen tool
#   - 此处可以对不同的配置文件进行编码以将其指定为configtxgen工具的参数
#   (定义用于configtxgen工具的配置入口,包括Orderer系统通道模板 和 应用通道类型模板)
#
################################################################################
Profiles:
    
    # TwoOrgsOrdererGenesis用来生成orderer启动时所需的block,用于生成创世区块,名字可以任意
    # 需要包含Orderer和Consortiums两部分
    TwoOrgsOrdererGenesis:
        <<: *ChannelDefaults     # 通道为默认配置,这里直接引用上面channel配置段中的ChannelDefaults
        Orderer:     # 指定Orderer系统通道自身的配置信息
            <<: *OrdererDefaults     # Orderer为默认配置,这里直接引用上面orderer配置段中的OrdererDefaults
            Organizations:
                - *OrdererOrg     # 这里直接引用上面Organizations配置段中的OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities     # 这里直接引用上面Capabilities配置段中的OrdererCapabilities
        Consortiums:     # Orderer 所服务的联盟列表,联盟为默认的 SampleConsortium 联盟,
                         # 添加了两个组织,表示orderer所服务的联盟列表
            SampleConsortium:     # 创建更多应用通道时的联盟 引用 TwoOrgsChannel 所示
                Organizations:
                    - *Org1
                    - *Org2
    
    # TwoOrgsChannel用来生成channel配置信息,名字可以任意
	 # 需要包含Consortium和Applicatioon两部分。 
    TwoOrgsChannel:     # 应用通道配置。默认配置的应用通道,添加了两个组织。联盟为SampleConsortium
        Consortium: SampleConsortium     # 通道所关联的联盟名称
        <<: *ChannelDefaults		# 通道为默认配置,这里直接引用上面channel配置段中的ChannelDefaults
        Application:     # 指定属于某应用通道的信息,主要包括 属于通道的组织信息
            <<: *ApplicationDefaults     # 这里直接引用上面Application配置段中的ApplicationDefaults
            Organizations:     # 初始 加入应用通道的组织
                - *Org1
                - *Org2
            Capabilities:
                <<: *ApplicationCapabilities     # 这里直接引用上面Capabilities配置段中的ApplicationCapabilities

    # SampleInsecureKafka定义了一个使用Kfaka排序节点的配置
    SampleDevModeKafka:
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            OrdererType: kafka
            Kafka:
                Brokers:
                - kafka.example.com:9092

            Organizations:
            - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Application:
            <<: *ApplicationDefaults
            Organizations:
            - <<: *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                - *Org1
                - *Org2
    # SampleInsecureKafka定义了一个使用EtcdRaft排序节点的配置
    SampleMultiNodeEtcdRaft:
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            OrdererType: etcdraft
            EtcdRaft:
                Consenters:
                - Host: orderer.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
                - Host: orderer2.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt
                - Host: orderer3.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt
                - Host: orderer4.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt
                - Host: orderer5.example.com
                  Port: 7050
                  ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt
                  ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt
            Addresses:
                - orderer1.example.com:7050
                - orderer2.example.com:7050

            Organizations:
            - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Application:
            <<: *ApplicationDefaults
            Organizations:
            - <<: *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                - *Org1
                - *Org2
2. 简介模板
# configtx.yaml

---
################################################################################
#
#   Section: Organizations
#
################################################################################
Organizations:

    - &OrdererOrg     # 排序节点组织,可自行定义
        Name: OrdererOrg     # 排序节点的组织名
        ID: OrdererMSP     # 排序节点的组织ID
        MSPDir: crypto-config/ordererOrganizations/example.com/msp     # 排序节点组织的Msp账号信息存放目录路径

        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"

    - &Org1     # 定义节点组织1
        Name: Org1MSP     # 组织1名称
        ID: Org1MSP     # 组织1的ID
        MSPDir: crypto-config/peerOrganizations/org1.example.com/msp     # peer节点组织1的Msp账号信息存放目录路径
        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org1MSP.admin')"
            Endorsement:
                Type: Signature
                Rule: "OR('Org1MSP.peer')"

        # leave this flag set to true.
        AnchorPeers:     # 锚节点
            - Host: peer0.org1.example.com     # 指定一个peer节点的域名(任意一个都可以)
              Port: 7051     # 端口是固定的,不要改

    - &Org2
        Name: Org2MSP
        ID: Org2MSP
        MSPDir: crypto-config/peerOrganizations/org2.example.com/msp

        Policies:
            Readers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')"
            Writers:
                Type: Signature
                Rule: "OR('Org2MSP.admin', 'Org2MSP.client')"
            Admins:
                Type: Signature
                Rule: "OR('Org2MSP.admin')"
            Endorsement:
                Type: Signature
                Rule: "OR('Org2MSP.peer')"

        AnchorPeers:
            - Host: peer0.org2.example.com
              Port: 7051

################################################################################
#
#   SECTION: Capabilities
#
################################################################################
Capabilities:
    Channel: &ChannelCapabilities
        V2_0: true

    Orderer: &OrdererCapabilities
        V2_0: true

    Application: &ApplicationCapabilities
        V2_0: true

################################################################################
#
#   SECTION: Application
#
################################################################################
Application: &ApplicationDefaults
    Organizations:

    Policies: &ApplicationDefaultPolicies
        LifecycleEndorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
        Endorsement:
            Type: ImplicitMeta
            Rule: "MAJORITY Endorsement"
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    Capabilities:
        <<: *ApplicationCapabilities
################################################################################
#
#   SECTION: Orderer
#
################################################################################
Orderer: &OrdererDefaults

    # Orderer Type: The orderer implementation to start
    # Available types are "solo" and "kafka"
    OrdererType: solo

    Addresses:
        - orderer.example.com:7050

    BatchTimeout: 2s     # 打包产生区块的时间

    BatchSize:     # 区块大小
        MaxMessageCount: 10     # 最大交易数,在达到时产生区块
        AbsoluteMaxBytes: 32 MB     # 区块最大字节量,常用32/64M
        PreferredMaxBytes: 512 KB     # 建议区块字节量

    Kafka:
        # Brokers: A list of Kafka brokers to which the orderer connects
        # NOTE: Use IP:port notation
        Brokers:
            - 127.0.0.1:9092
    Organizations:

    Policies:
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"
        BlockValidation:
            Type: ImplicitMeta
            Rule: "ANY Writers"

################################################################################
#
#   CHANNEL
#
################################################################################
Channel: &ChannelDefaults
    Policies:
        # Who may invoke the 'Deliver' API
        Readers:
            Type: ImplicitMeta
            Rule: "ANY Readers"
        # Who may invoke the 'Broadcast' API
        Writers:
            Type: ImplicitMeta
            Rule: "ANY Writers"
        # By default, who may modify elements at this config level
        Admins:
            Type: ImplicitMeta
            Rule: "MAJORITY Admins"

    Capabilities:
        <<: *ChannelCapabilities

################################################################################
#
#   Profile
#
################################################################################
Profiles:

    TwoOrgsOrdererGenesis:     # 区块名字,可以自定义
        <<: *ChannelDefaults
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Consortiums:
            SampleConsortium:     #联盟名称,可以自定义
                Organizations:
                    - *Org1
                    - *Org2
    TwoOrgsChannel:     # 通道名字,可以自定义
        Consortium: SampleConsortium     # 对应上面的联盟名称
        <<: *ChannelDefaults
        Application:
            <<: *ApplicationDefaults
            Organizations:
                - *Org1
                - *Org2
            Capabilities:
                <<: *ApplicationCapabilities

    SampleDevModeKafka:
        <<: *ChannelDefaults
        Capabilities:
            <<: *ChannelCapabilities
        Orderer:
            <<: *OrdererDefaults
            OrdererType: kafka
            Kafka:
                Brokers:
                - kafka.example.com:9092

            Organizations:
            - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Application:
            <<: *ApplicationDefaults
            Organizations:
            - <<: *OrdererOrg
        Consortiums:
            SampleConsortium:
                Organizations:
                - *Org1
                - *Org2

Note:【&】和【*】语法

&variable *variable 这类语法类似 Go中的指针及对象地址,

    - &OrdererOrg     # 排序节点组织,可自行定义
        Name: OrdererOrg     # 排序节点的组织名
        ID: OrdererMSP     # 排序节点的组织ID
        MSPDir: crypto-config/ordererOrganizations/example.com/msp     # 排序节点组织的Msp账号信息存放目录路径

        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"
......

Profiles:

    TwoOrgsOrdererGenesis:     # 区块名字,可以自定义
        <<: *ChannelDefaults
        Orderer:
            <<: *OrdererDefaults
            Organizations:
                - *OrdererOrg
            Capabilities:
                <<: *OrdererCapabilities
        Consortiums:
            SampleConsortium:     #联盟名称,可以自定义
                Organizations:
                    - *Org1
                    - *Org2
......

以上中的- *OrdererOrg 所表示的即为- &OrdererOrg 后的如下内容

        Name: OrdererOrg     # 排序节点的组织名
        ID: OrdererMSP     # 排序节点的组织ID
        MSPDir: crypto-config/ordererOrganizations/example.com/msp     # 排序节点组织的Msp账号信息存放目录路径

        Policies:
            Readers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Writers:
                Type: Signature
                Rule: "OR('OrdererMSP.member')"
            Admins:
                Type: Signature
                Rule: "OR('OrdererMSP.admin')"

3. 生成文件区块命令

  • 生成创世区块
$ mkdir channel-artifacts
$ configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block -channelID genesischannel

在这里插入图片描述

解释:

configtxgen -profile 【configtx.yaml文件中“Profile”部分下’Profiles‘下所定义的区块名称】 -outputBlock 【创世块名称,包括其相对路径】 -channelID 【通道名称】

  • 生成通道文件
$ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel

在这里插入图片描述

  • 生成锚节点更新文件

操作可选

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

在这里插入图片描述

四、编写docker-compose

1. 环境变量

1.1 客户端角色所需
- GOPATH=/opt/gopath     # 客户端docker容器启动之后,go的工作目录。无需更改
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock     # docker容器启动后,对应的守护进程的本地套接字,无需修改
- CORE_LOGGING_LEVEL=INFO     #日志级别:critical | error | warning | notice | info | debug
- CORE_PEER_ID=cli     #当前客户端节点的ID,自己指定
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051     #客户端连接的peer节点(端口不可更改)
- CORE_PEER_LOCALMSPID=Org1MSP     # 组织ID
- CORE_PEER_TLS_ENABLED=true     # 通信是否使用tls加密
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt     # 证书文件
- 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/Admin@org1.example.com/msp     # 指定当前客户端身份

主要修改文件路径的标色部分:

证书、私钥、根证书文件::/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/…

客户端身份::/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

1.2 orderer节点所需
      - FABRIC_LOGGING_SPEC=INFO     # 日志级别:critical | error | warning | notice | info | debug
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0     # orderer节点监听的地址
      # - ORDERER_GENERAL_LISTENPORT=7050     # orderer节点监听的端口
      - ORDERER_GENERAL_GENESISMETHOD=file     # 创始块的来源,来源于file

      - 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]     # 根证书文件
      - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
      - ORDERER_KAFKA_VERBOSE=true
      - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt
      - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key
      - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
1.3 peer节点所需
- CORE_PEER_ID=peer0.org1.example.com     # 当前peer节点的名字,可自定义。建议对应节点域名
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051     # 当前peet节点的地址信息
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:8051     # 启动的时候,指定连接谁,一般写自己
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051     # 为了被其他节点感知到,如果不设置别的节点不知有该节点的存在
- CORE_PEER_LOCALMSPID=Org1MSP     # peer节点所属的组的ID
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock     # 本地套接字地址,无需更改
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn     # 当前节点属于哪个网络
- FABRIC_LOGGING_SPEC=INFO     # 日志级别:critical | error | warning | notice | info | debug
#- FABRIC_LOGGING_SPEC=DEBUG
- CORE_PEER_TLS_ENABLED=true     # 是否使用tls加密
- CORE_PEER_GOSSIP_USELEADERELECTION=true  # 是否自动选举leader节点
- CORE_PEER_GOSSIP_ORGLEADER=false    # 当前不是leader节点
- 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.crtMSP

2. 配置文件

2.1 docker-compose-cli.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

volumes:
  orderer.example.com:
  peer0.org1.example.com:
  peer1.org1.example.com:
  peer0.org2.example.com:
  peer1.org2.example.com:

networks:
  byfn:

services:

  orderer.example.com:
    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
    networks:
      - byfn

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:latest
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - FABRIC_LOGGING_SPEC=DEBUG
      #- FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt     # 私钥文件
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key     # 证书文件
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt     # 根证书文件
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp     # 指定当前客户端身份
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer     #无需更改
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - ./chaincode/:/opt/gopath/src/github.com/chaincode
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        #- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.example.com
      - peer0.org1.example.com
      - peer1.org1.example.com
      - peer0.org2.example.com
      - peer1.org2.example.com
    networks:
      - byfn
2.2 docker-compose-base.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

services:

  orderer.example.com:     #服务名,可以根据自定义的域名定义
    container_name: orderer.example.com
    image: hyperledger/fabric-orderer:latest
    environment:
      - FABRIC_LOGGING_SPEC=INFO
      - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0     # 设置0.0.0.0可自动获取IP地址
      - 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]
      - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
      - ORDERER_KAFKA_VERBOSE=true
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric
    command: orderer
    volumes:     # 宿主机:docker镜像
    - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block     # 注意对应自己生成的创世块名称
    - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
    - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
    - orderer.example.com:/var/hyperledger/production/orderer
    ports:
      - 7050:7050

  peer0.org1.example.com:
    container_name: peer0.org1.example.com
    extends:
      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
      - 7053:7053

  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
2.3 peer-base.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

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
      - FABRIC_LOGGING_SPEC=INFO
      #- FABRIC_LOGGING_SPEC=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

Note:目录结构

arpen@arpen-ubuntu20:~/myfab$ tree -L 2
.
├── base     --------------------> 
│   └── docker-compose-base.yaml
│   └── peer-base.yaml
├── chaincode
├── channel-artifacts
│   ├── channel.tx     ----------> 生成的通道文件
│   ├── genesis.block     -------> 生成的创世区块
│   ├── Org1MSPanchors.tx -------> 生成的Org1组织锚节点文件
│   └── Org2MSPanchors.tx -------> 生成的Org2组织锚节点文件
├── configtx.yaml     -----------> 生成创始块、通道的配置文件
├── crypto-config     -----------> 存放cryptogen生成的文件
│   ├── ordererOrganizations
│   └── peerOrganizations
├── crypto-config.yaml     ------> 生成私钥、证书配置文件
└── docker-compose-cli.yaml

3. 启动

arpen@arpen-ubuntu20:~/myfab$ docker-compose --help
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [--profile <name>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

Options:
  -f, --file FILE             Specify an alternate compose file     # 指定使用的 Compose 模板文件,
                              (default: docker-compose.yml)     # 默认为 docker-compose.yml,可以多次指定
  -p, --project-name NAME     Specify an alternate project name     # 指定项目名称,
                              (default: directory name)     # 默认将使用所在目录名称作为项目名
  --profile NAME              Specify a profile to enable
  -c, --context NAME          Specify a context name
  --verbose                   Show more output
  --log-level LEVEL           Set log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --ansi (never|always|auto)  Control when to print ANSI control characters
  --no-ansi                   Do not print ANSI control characters (DEPRECATED)
  -v, --version               Print version and exit
  -H, --host HOST             Daemon socket to connect to

  --tls                       Use TLS; implied by --tlsverify
  --tlscacert CA_PATH         Trust certs signed only by this CA
  --tlscert CLIENT_CERT_PATH  Path to TLS certificate file
  --tlskey TLS_KEY_PATH       Path to TLS key file
  --tlsverify                 Use TLS and verify the remote
  --skip-hostname-check       Don't check the daemon's hostname against the
                              name specified in the client certificate
  --project-directory PATH    Specify an alternate working directory
                              (default: the path of the Compose file)
  --compatibility             If set, Compose will attempt to convert keys
                              in v3 files to their non-Swarm equivalent (DEPRECATED)
  --env-file PATH             Specify an alternate environment file

Commands:
  build              Build or rebuild services
  config             Validate and view the Compose file
  create             Create services
  down               Stop and remove resources
  events             Receive real time events from containers
  exec               Execute a command in a running container
  help               Get help on a command
  images             List images
  kill               Kill containers
  logs               View output from containers
  pause              Pause services
  port               Print the public port for a port binding
  ps                 List containers
  pull               Pull service images
  push               Push service images
  restart            Restart services
  rm                 Remove stopped containers
  run                Run a one-off command
  scale              Set number of containers for a service
  start              Start services
  stop               Stop services
  top                Display the running processes
  unpause            Unpause services
  up                 Create and start containers
  version            Show version information and quit

启动docker-compose

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

为方便后续操作简化指令,将yaml文件重命名为默认名称

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

关闭网络

$ docker-compose down --volumes --remove-orphans

在这里插入图片描述

查看是否启动成功

$ docker-compose ps

在这里插入图片描述

Note:
arpen@arpen-ubuntu20:~/myfab$ docker-compose up -d
WARNING: The COMPOSE_PROJECT_NAME variable is not set. Defaulting to a blank string.
Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/
Creating network "myfab_byfn" with the default driver
Creating volume "myfab_orderer.example.com" with default driver
Creating volume "myfab_peer0.org1.example.com" with default driver
Creating volume "myfab_peer1.org1.example.com" with default driver
Creating volume "myfab_peer0.org2.example.com" with default driver
Creating volume "myfab_peer1.org2.example.com" with default driver
Creating peer1.org1.example.com ... done
Creating peer1.org2.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating orderer.example.com    ... done
Creating cli                    ... done
  • 在启动 docker-compose 时,出现一个警告:The COMPOSE_PROJECT_NAME variable is not set.

  • 之后创建了一个名为 myfab_byfn 的网络

在 peer-base.yaml 配置文件中设有环境变量- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn 控制

​ 其中 _byfn 是在配置文件中所设置的 network 名称;

​ 而 myfab 这是默认设置为 docker-compose.yaml 文件所在的项目目录名

五、Peer操作命令

1. 创建通道

$ peer channel create [flags], 常用参数为:
	`-o, --order: orderer节点的地址
	`-c, --channelID:要创建的通道ID,必须小写,且在250个字符以内
	`-f, --file: 由configtxgen 生成的通道文件,用于提交给orderer
	`-t, --timeout: 创建通道的超时时长,默认为5s
	`--tls: 通信时是否使用tls加密
	`--cafile: 当前orderer节点pem格式的tls证书文件,要使用绝对路径
# orderer节点pem格式的tls证书文件路径参考
/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
# example
$ peer channel create -o orderer节点地址:端口 -c 通道名 -f 通道文件 --tls true --cafile orderer节点pem格式的证书文件
		- orderer节点地址:可以是IP地址或者域名
		- orderer节点监听的是7050端口

执行命令

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

在这里插入图片描述

此时查看目录

root@c8588c9e8ad5 /opt/gopath/src/github.com/hyperledger/fabric/peer$ ls
channel-artifacts  crypto             mychannel.block
# 此时会生成一个  通道名.block  的文件

2. 加入通道

$ peer channel join [flags], 常用参数为:
  `-b, --blockpath string   通过“peer channel create”创建的.block文件的路径
  `-h, --help               help for join
2.1 将当前客户端所连接的节点(peer0.org1.example.com)加入到通道
$ peer channel join -b mychannel.block

在这里插入图片描述

2.2 修改docker-compose配置文件cli配置,以加入其它节点
  • 第一个节点:org1的peer0
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ENABLED=true
export 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     # 私钥文件
export 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     # 证书文件
export 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     # 根证书文件
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp     # 指定当前客户端身份
  • 第二个节点:org1的peer1
export CORE_PEER_ADDRESS=peer1.org1.example.com:7051
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt     # 私钥文件
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.key     # 证书文件
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt     # 根证书文件
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp     # 指定当前客户端身份
  • 第三个节点:org2的peer0
export CORE_PEER_ADDRESS=peer0.org2.example.com:7051
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt     # 私钥文件
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key     # 证书文件
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt     # 根证书文件
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp     # 指定当前客户端身份
  • 第四个节点:org2的peer1
export CORE_PEER_ADDRESS=peer1.org2.example.com:7051
export CORE_PEER_LOCALMSPID=Org2MSP
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/server.crt     # 私钥文件
export CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/server.key     # 证书文件
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt     # 根证书文件
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp     # 指定当前客户端身份
  • 查看修改状态
echo $CORE_PEER_ADDRESS
echo $CORE_PEER_LOCALMSPID
echo $CORE_PEER_TLS_ENABLED
echo $CORE_PEER_TLS_CERT_FILE
echo $CORE_PEER_TLS_KEY_FILE
echo $CORE_PEER_TLS_ROOTCERT_FILE
echo $CORE_PEER_MSPCONFIGPATH
  • 修改完成环境变量之后,再次执行加入通道命令即可
$ peer channel join -b mychannel.block

3.更新锚节点

4.安装链码

$ peer chaincode install [flags],常用参数为
	`-c, --ctor string:JSON格式的构造参数,默认为"{}"
	`-l, --lang string:编写chaincode的编程语言,默认值为 golong
	`-n, --name string:chaincode的名称
	`-p, --path string:chaincode源代码的目录,从 $GOPATH/src 路径之后开始书写
	`-v, --version string:当前操作的chaincode的版本,适用这些命令install/instantiate/upgrade
# example
$ peer chaincode install -n 链码的名字 -v 链码的版本 -l 链码的语言 -p 链码的位置+
$ peer chaincode install -n testcc -v 1.0 -l golang -p github.com/chaincode
4.1 复制链代码

在这里使用的是测试网络中的链码

# 进入chaincode目录下
$ cd $GOPATH/src/github.com/hyperledger/fabric-samples/chaincode/chaincode_example02/go/
# 复制chaincode文件
$ sudo cp chaincode_example02.go ~/myfab/chaincode/
# 重命名文件
$ cd ~/myfab/chaincode/
$ sudo mv chaincode_example02.go test.go

查看结果如下:

root@c8588c9e8ad5 /opt/gopath/src/github.com/hyperledger/fabric/peer$ ls /opt/gopath/src/github.com/chaincode/
test.go

六、通过客户端操作各节点

1 操作流程

  • 通过客户端节点创建通道

    # 检查启动状态
    arpen@arpen-ubuntu20:~/myfab$ docker-compose ps
             Name                Command       State                        Ports                      
    ---------------------------------------------------------------------------------------------------
    cli                      /bin/bash         Up                                                      
    orderer.example.com      orderer           Up      0.0.0.0:7050->7050/tcp                          
    peer0.org1.example.com   peer node start   Up      0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp  
    peer0.org2.example.com   peer node start   Up      0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp  
    peer1.org1.example.com   peer node start   Up      0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp  
    peer1.org2.example.com   peer node start   Up      0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp
    
    # 进入客户端对应的容器中
    docker exec -it cli /bin/bash
    
  • 通过客户端将每个组织的每个节点加入到通道

    详见本章第五节【Peer操作命令】

一个客户端只能连接一个指定节点,要想使该客户端连接其他节点,则必须修改此客户端中相关的环境变量

  • 给每个Peer节点安装智能合约 --> chaincode(程序:go、node.js、java)
  • 对智能合约进行初始化 --> Init函数

智能合约的初始化只需在任一节点进行一次即可,数据会自动同步到各个组织的各个节点上

  • 对数据进行查询 --> 读
  • 对数据进行调用 --> 写

七、问题处理

1. 进入cli容器后,不显示用户名路径

1.1 具体问题
1.2 解决方案——修改终端提示符显示
  • 编辑 .bash_profile 文件

    vi ~/.bash_profile
    # 在打开的文件添加如下内容:👇
    export PS1='\u@\h \w$ '
    # 保存并退出
    
  • 加载配置生效

source ~/.bash_profile
  • 修改 .bashrc 文件
vi ~/.bashrc
# 在打开的文件添加如下内容:👇
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
# 保存并退出
  • 加载配置生效
source ~/.bashrc
Note:

linux下环境变量PS1简单来说就是设置命令提示符显示的内容

PS1变量中提示符各项含义:

\d :代表日期,格式为weekday month date,例如:Wed Dec 12
\H :完整的主机名称。例如:hostname是debian.linux
\h :仅取主机的第一个名字,如上例,则为debian,.linux则被省略
\t :显示时间为24小时格式,如:HH:MM:SS
\T :显示时间为12小时格式
\A :显示时间为24小时格式:HH:MM
\u :当前用户的账号名称 如:root
\v :BASH的版本信息  如:3.2
\w :完整的工作目录名称。家目录会以 ~代替 如显示/etc/default/
\W :利用basename取得工作目录名称,所以只会列出最后一个目录 如上例则只显示default
\# :下达的第几个命令
\$ :提示字符,如果是root时,提示符为:# ,普通用户则为:$

2. peer节点操作创建通道时报错

2.1 具体问题

在这里插入图片描述

2.2 解决方案

主要原因是创建orderer区块文件时的channelID与创建通道配置文件channelID相同导致的

只需重新设置channelID即可

如果有什么问题,欢迎留言,也欢迎指正文章中的错误。
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐