前言

总体来看,网络上成体系的可用的 Fabric 教程极少——不是间接在 Fabric 官网复制内容大谈基础理论就是在形容一个简直无奈复现的我的项目实际,以至于学习 Fabric 的效率极低,印象最粗浅的就是我已经破费几天工夫尝试依照官网教程 CA Deployment steps 搭建本人的 CA 服务,却始终无奈胜利也找不到起因。因而,为了进步生产效率,本我的项目虚构了一个工作室联盟链需要并将逐渐实现,致力于提供一个易了解、可复现的Fabric学习我的项目,其中我的项目部署步骤的各个环节都清晰可见,并且将所有过程打包为脚本使之可能被疾速复当初任何一台主机上。

工程介绍

组织架构

有一启明星工作室,其中蕴含三大组织:软件组、WEB组、硬件组、理事会,不同组织间互相独立,偶然有业务往来。现理事会决定搭建一个启明星工作室的联盟链网络,使不同组织间增强单干,冀望最终实现以下工程架构:

  1. 组织阐明

    • council:理事会,负责工作室各组间协调治理,由三组抽调人员独特组成
    • soft:软件组,专一软件开发
    • hard:硬件组,专一硬件开发
    • web:WEB组,专一网站开发
    • orderer:过渡排序组织,为联盟链网络提供排序服务,前期会舍弃
  2. 成员阐明

    • council:一个Orderer节点、三个Admin账号,每组领有一个Admin账号权限
    • soft:一个Orderer节点、一个Peer节点、一个Admin账号、一个User账号
    • hard:一个Orderer节点、一个Peer节点、一个Admin账号、一个User账号
    • web:一个Orderer节点、一个Peer节点、一个Admin账号、一个User账号
    • orderer:一个Orderer节点、一个Admin账号
  3. 根CA服务器(域名)

    • council.fantasy.com:提供/治理组织间TLS证书,又叫TLS CA服务器
    • soft.fantasy.com:提供/治理组织内TLS证书
    • hard.fantasy.com:提供/治理组织内TLS证书
    • web.fantasy.com:提供/治理组织内TLS证书
    • orderer.fantasy.com:提供/治理组织内TLS证书

试验筹备

在开始前,如果你对 Fabric 命令知之甚少,能够先学习fabric的test-network启动过程Bash源码详解;此外应筹备好 Fabric 的开发环境,具体环境搭建和软件版本可参考基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简略案例。为了不便辨别各组织和节点,本工程应用域名的形式进行各节点间的通信,以 web 组织为例,域名调配标准如下:

域名阐明
peer1.web.ifantasy.netweb组第一个 peer 节点地址
peer2.web.ifantasy.netweb组第二个 peer 节点地址
orderer1.web.ifantasy.netweb组第一个 orderer 节点地址

此外,还须要在 \etc\hosts 文件增加 DNS 地址:

echo "127.0.0.1       council.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer.ifantasy.net" >> /etc/hostsecho "127.0.0.1       soft.ifantasy.net" >> /etc/hostsecho "127.0.0.1       web.ifantasy.net" >> /etc/hostsecho "127.0.0.1       hard.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer1.soft.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer1.web.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer1.hard.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer1.orderer.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer2.orderer.ifantasy.net" >> /etc/hostsecho "127.0.0.1       orderer3.orderer.ifantasy.net" >> /etc/hostsecho "127.0.0.1       peer1.soft.ifantasy.net" >> /etc/hostsecho "127.0.0.1       peer1.web.ifantasy.net" >> /etc/hostsecho "127.0.0.1       peer1.hard.ifantasy.net" >> /etc/hosts

本文工作

本我的项目次要以学习为主,所以并未冀望一次实现所有架构和性能。本文所实现的具体内容为,搭建一个简略的工作室联盟链网络,蕴含 councilorderersoftweb 四个组织,并将测试链码部署在通道 mychannel ,网络结构为(试验代码已上传至:https://github.com/wefantasy/FabricLearn 的 1_3Org2Peer1Orderer1TLS 目录下):

运行端口阐明
council.ifantasy.net7050council 组织的 CA 服务, 为联盟链网络提供 TLS-CA 服务
orderer.ifantasy.net7150orderer 组织的 CA 服务, 为联盟链网络提供排序服务
orderer1.orderer.ifantasy.net7151orderer 组织的 orderer1 成员节点
soft.ifantasy.net7250soft 组织的 CA 服务, 蕴含成员: peer1 、 admin1
peer1.soft.ifantasy.net7251soft 组织的 peer1 成员节点
web.ifantasy.net7350web 组织的 CA 服务, 蕴含成员: peer1 、 admin1
peer1.web.ifantasy.net7351web 组织的 peer1 成员节点

其它阐明

集体感觉 Fabric 官网示例的证书构造过于冗余,为了便于本人了解,本工程证书构造跟个别 Fabric 有所出入,先将本工程各文件目录阐明如下:

1_3Org2Peer1Orderer1TLS├── 0_Restart.sh           # 启动根本 CA 网络脚本├── 1_RegisterUser.sh      # 注册账户脚本├── 2_EnrollUser.sh        # 登录账户脚本├── 3_Configtxgen.sh       # 生成创世区块脚本├── 4_TestChaincode.sh     # 链码测试脚本├── asset-transfer-basic   # 测试链码目录├── basic.tar.gz           # 打包后的链码包├── compose                # Docker配置目录│   ├── docker-base.yaml      # 根底通用配置│   └── docker-compose.yaml   # 具体 Docker 配置├── config                 # Fabric 公共配置目录│   ├── config-msp.yaml    # 节点组织单元配置文件│   ├── configtx.yaml      # 初始通道配置│   ├── orderer.yaml      # orderer 节点配置,osnadmin 的配置文件│   └── core.yaml          # peer 配置├── data                   # 长期数据目录├── envpeer1soft           # soft 组织的 peer1 cli环境变量├── envpeer1web            # web 组织的peer1 cli环境变量├── orgs                   # 组织成员证书目录│   ├── council.ifantasy.net  # council 组织目录│   ├── orderer.ifantasy.net  # orderer 组织目录│   ├── web.ifantasy.net      # web组织目录│   └── soft.ifantasy.net     # soft 组织目录│       ├── assets            # 组织公共资料目录│       │   ├── ca-cert.pem      # 本组织根证书│       │   ├── mychannel.block  # mychannel 通道创世区块│       │   └── tls-ca-cert.pem  # TLS-CA 服务根证书│       ├── ca             # 本组织 CA 服务目录│       │   ├── admin      # 本组织 CA 服务疏导管理员 msp 目录│       │   └── crypto     # 本组织 CA 服务默认证书目录│       ├── msp               # 组织 MSP 目录│       │   ├── admincerts    # 组织管理员签名证书目录│       │   ├── cacerts       # 组织 CA 服务根证书目录│       │   ├── config.yaml   # 组织节点单元配置文件│       │   ├── tlscacerts    # TLS-CA 服务根证书目录│       │   └── users         # 空目录,msp 标准所需│       └── registers         # 本组织注册的账户目录│           ├── admin1        # 管理员账户│           └── peer1         # 节点账户└── README.md              

试验步骤

试验筹备

首先将基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简略案例中的/usr/local/fabric/config目录复制到根目录下。如无非凡阐明,环境变量FABRIC_CFG_PATH总是默认指向根目录的config目录(倡议间接将本案例仓库 FabricLearn 下的 1_3Org2Peer1Orderer1TLS 目录拷贝到本地运行)。

fabric 提供一个 fabric-tools 镜像用于提供操作 peer 节点的命令行,其实现形式是在启动 fabric-tools 时指定 peer 节点的身份证书等环境变量,此外咱们也能够间接将这些环境变量写入一个文件中而后通过 source 命令激活。在根目录下创立 envpeer1soft 文件,用于保留 soft 组织的环境变量,写入以下内容:

export LOCAL_ROOT_PATH=$PWDexport LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgsexport DOCKER_CA_PATH=/tmpexport COMPOSE_PROJECT_NAME=fabriclearnexport DOCKER_NETWORKS=networkexport FABRIC_BASE_VERSION=2.4export FABRIC_CA_VERSION=1.5

配置TLS服务

  1. 在根目录下创立 compose 文件夹,用于贮存 docker-compose 配置文件。
  2. compose 下创立 docker-base.yaml 文件,用于写入公共服务配置,先写入以下内容:

    version: "2"services:  ca-base: image: hyperledger/fabric-ca:${FABRIC_CA_VERSION} environment:   - FABRIC_CA_SERVER_HOME=${DOCKER_CA_PATH}/ca/crypto   - FABRIC_CA_SERVER_TLS_ENABLED=true   - FABRIC_CA_SERVER_DEBUG=true networks:   - ${DOCKER_NETWORKS}
  3. compose 下创立 docker-compose.yaml 文件,用于配置工程 docker 容器,写入 councilorderersoftweb 的 TLS 服务配置:

    version: '2'networks:  network:services:  council.ifantasy.net: container_name: council.ifantasy.net extends:   file: docker-base.yaml   service: ca-base command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050' environment:   - FABRIC_CA_SERVER_CSR_CN=council.ifantasy.net   - FABRIC_CA_SERVER_CSR_HOSTS=council.ifantasy.net volumes:   - ${LOCAL_CA_PATH}/council.ifantasy.net/ca:${DOCKER_CA_PATH}/ca ports:   - 7050:7050  orderer.ifantasy.net: container_name: orderer.ifantasy.net extends:   file: docker-base.yaml   service: ca-base command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050' environment:   - FABRIC_CA_SERVER_CSR_CN=orderer.ifantasy.net   - FABRIC_CA_SERVER_CSR_HOSTS=orderer.ifantasy.net volumes:   - ${LOCAL_CA_PATH}/orderer.ifantasy.net/ca:${DOCKER_CA_PATH}/ca ports:   - 7150:7050  soft.ifantasy.net: container_name: soft.ifantasy.net extends:   file: docker-base.yaml   service: ca-base command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050' environment:   - FABRIC_CA_SERVER_CSR_CN=soft.ifantasy.net   - FABRIC_CA_SERVER_CSR_HOSTS=soft.ifantasy.net volumes:   - ${LOCAL_CA_PATH}/soft.ifantasy.net/ca:${DOCKER_CA_PATH}/ca ports:   - 7250:7050  web.ifantasy.net: container_name: web.ifantasy.net extends:   file: docker-base.yaml   service: ca-base command: sh -c 'fabric-ca-server start -d -b ca-admin:ca-adminpw --port 7050' environment:   - FABRIC_CA_SERVER_CSR_CN=web.ifantasy.net   - FABRIC_CA_SERVER_CSR_HOSTS=web.ifantasy.net volumes:   - ${LOCAL_CA_PATH}/web.ifantasy.net/ca:${DOCKER_CA_PATH}/ca ports:   - 7350:7050
  4. 启动各组织的 TLS 服务:

    source envpeer1softdocker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d council.ifantasy.net orderer.ifantasy.net soft.ifantasy.net web.ifantasy.net

    注册账户

  5. 注册 council 组织账户。
    首先设置 council 的环境变量:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pemexport FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/council.ifantasy.net/ca/admin

    而后应用 enroll 登录疏导账户, 它会以 FABRIC_CA_CLIENT_TLS_CERTFILES 指向的 CA 服务器根证书加密通信,并将生成的身份证书保留在 FABRIC_CA_CLIENT_HOME 指向的工作目录下1

    fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@council.ifantasy.net:7050
    留神: enroll 操作后果是保留账号的身份证书至指定目录下,当前就能够间接依据该目录下的证书来应用对应身份,跟传统 web 零碎的登录操作相似所以被我称为登录,但实际上有所区别。

    而后便能够 ca-admin 身份进行注册其它用户的操作:

    fabric-ca-client register -d --id.name orderer1 --id.secret orderer1 --id.type orderer -u https://council.ifantasy.net:7050fabric-ca-client register -d --id.name peer1soft --id.secret peer1soft --id.type peer -u https://council.ifantasy.net:7050fabric-ca-client register -d --id.name peer1web --id.secret peer1web --id.type peer -u https://council.ifantasy.net:7050

    council 为其它组织提供 TLS-CA 服务的具体实现就是为其它组织提供 council 可验证的非法账户,其余组织应用这些账户进行通信就是可信的。前面注册步骤与下面相似,故不再赘述。

  6. 注册 orderer 组织账户:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/ca/crypto/ca-cert.pemexport FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/orderer.ifantasy.net/ca/adminfabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@orderer.ifantasy.net:7150fabric-ca-client register -d --id.name orderer1 --id.secret orderer1 --id.type orderer -u https://orderer.ifantasy.net:7150fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://orderer.ifantasy.net:7150
  7. 注册 soft 组织账户:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/ca/crypto/ca-cert.pemexport FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/ca/adminfabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@soft.ifantasy.net:7250fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u https://soft.ifantasy.net:7250fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://soft.ifantasy.net:7250
  8. 注册 web 组织账户:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/ca/crypto/ca-cert.pemexport FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/web.ifantasy.net/ca/adminfabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@web.ifantasy.net:7350fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u https://web.ifantasy.net:7350fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://web.ifantasy.net:7350

    结构组织成员证书

  9. 在各组织下创立 assets 目录,用于贮存本组织根证书和用于组间通信的 LTS-CA 根证书:

    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/assetscp $LOCAL_CA_PATH/orderer.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pemcp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/assets/tls-ca-cert.pemmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/assetscp $LOCAL_CA_PATH/soft.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pemcp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pemmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/assets cp $LOCAL_CA_PATH/web.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pemcp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pem
  10. 结构 orderer 组织成员证书。
    登录 orderer 管理员账户 admin1

    export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://admin1:admin1@orderer.ifantasy.net:7150
    留神:这里是登录上节咱们注册的管理员账户而非启动 CA 服务时的疏导账户,疏导账户跟管理员账户的区别也是我至今难以了解的中央

    以上命令胜利后便能够看到 FABRIC_CA_CLIENT_HOME/FABRIC_CA_CLIENT_MSPDIR 目录下生成的证书文件。而后须要结构 admin1msp 目录:

    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1/msp/admincertscp $LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1/msp/admincerts/cert.pem

    这里的操作仅仅是将 admin1 的签名证书复制到新建的 admincerts 文件夹下,这样做的起因是 Fabric 的 MSP 标准要求其下需有 admincerts 目录,否则前面操作组织 peer 节点时会报错,因而倡议在所有联盟链网络服务节点的 msp 目录下增加 admincerts 证书。而后登录 ordererorderer1 的组织内账户:

    export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://orderer1:orderer1@orderer.ifantasy.net:7150mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/msp/admincertscp $LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/msp/admincerts/cert.pem

    而后登录 ordererorderer1 的组织间 TLS-CA 账户:

    export FABRIC_CA_CLIENT_MSPDIR=tls-mspexport FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/tls-ca-cert.pemfabric-ca-client enroll -d -u https://orderer1:orderer1@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts orderer1.orderer.ifantasy.netcp $LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/keystore/key.pem

    最初一步便是结构 orderer 的组织 MSP 目录2(MSP 目录阐明可参考 MSP构造):

    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/admincertsmkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/cacertsmkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/tlscacertsmkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/userscp $LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/msp/cacerts/cp $LOCAL_CA_PATH/orderer.ifantasy.net/assets/tls-ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/msp/tlscacerts/cp $LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/msp/admincerts/cert.pemcp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/orderer.ifantasy.net/msp/config.yaml

    下面命令最初一行会在组织 msp 目录下增加节点组织单元配置文件 config.yaml ,其原理能够参考 节点组织单元和MSP ,如果短少该文件或者文件内容谬误,会报以下谬误:

    loadLocalMSP -> Failed to setup local msp with config: administrators must be declared when no admin ou classification is set

    前面的流程跟这里相似,因而不再赘述。

  11. 结构 soft 组织成员证书:

    echo "Start Soft============================="echo "Enroll Admin"export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://admin1:admin1@soft.ifantasy.net:7250mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/admincertscp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/admincerts/cert.pemecho "Enroll Peer1"export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://peer1:peer1@soft.ifantasy.net:7250# for TLSexport FABRIC_CA_CLIENT_MSPDIR=tls-mspexport FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pemfabric-ca-client enroll -d -u https://peer1soft:peer1soft@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts peer1.soft.ifantasy.netcp $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/tls-msp/keystore/key.pemmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/msp/admincertscp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/msp/admincerts/cert.pemmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/admincertsmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/cacertsmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/tlscacertsmkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/userscp $LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/msp/cacerts/cp $LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/msp/tlscacerts/cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/msp/admincerts/cert.pemcp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/soft.ifantasy.net/msp/config.yamlecho "End Soft============================="
  12. 结构 web 组织成员证书:

    echo "Start Web============================="echo "Enroll Admin"export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/web.ifantasy.net/registers/admin1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://admin1:admin1@web.ifantasy.net:7350mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/admincertscp $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/admincerts/cert.pemecho "Enroll Peer1"# for identityexport FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/web.ifantasy.net/registers/peer1export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pemexport FABRIC_CA_CLIENT_MSPDIR=mspfabric-ca-client enroll -d -u https://peer1:peer1@web.ifantasy.net:7350# for TLSexport FABRIC_CA_CLIENT_MSPDIR=tls-mspexport FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pemfabric-ca-client enroll -d -u https://peer1web:peer1web@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts peer1.web.ifantasy.netcp $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/tls-msp/keystore/key.pemmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/msp/admincertscp $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/msp/admincerts/cert.pemmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/admincertsmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/cacertsmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/tlscacertsmkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/userscp $LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pem $LOCAL_CA_PATH/web.ifantasy.net/msp/cacerts/cp $LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pem $LOCAL_CA_PATH/web.ifantasy.net/msp/tlscacerts/cp $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/web.ifantasy.net/msp/admincerts/cert.pemcp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/web.ifantasy.net/msp/config.yamlecho "End Web============================="

    配置零碎通道及测试通道

  13. config 目录下创立 configtx.yaml 配置文件,文件太长在此不做展现,能够在 FabricLearn 中查看,其中各项已加阐明正文3
  14. 通过 configtxgen 生成创世区块和测试通道:

    configtxgen -profile OrgsOrdererGenesis -outputBlock $LOCAL_ROOT_PATH/data/genesis.block -channelID syschannelconfigtxgen -profile OrgsChannel -outputCreateChannelTx $LOCAL_ROOT_PATH/data/mychannel.tx -channelID mychannel
  15. compose/docker-compose.yaml 文件中增加 peerorderer 服务相干配置:

    peer1.soft.ifantasy.net: container_name: peer1.soft.ifantasy.net extends:   file: docker-base.yaml   service: peer-base environment:   - CORE_PEER_ID=peer1.soft.ifantasy.net   - CORE_PEER_ADDRESS=peer1.soft.ifantasy.net:7051   - CORE_PEER_LOCALMSPID=softMSP   - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.soft.ifantasy.net:7051 volumes:   - ${LOCAL_CA_PATH}/soft.ifantasy.net/registers/peer1:${DOCKER_CA_PATH}/peer ports:   - 7251:7051peer1.web.ifantasy.net:   container_name: peer1.web.ifantasy.net   extends:      file: docker-base.yaml      service: peer-base   environment:      - CORE_PEER_ID=peer1.web.ifantasy.net      - CORE_PEER_ADDRESS=peer1.web.ifantasy.net:7051      - CORE_PEER_LOCALMSPID=webMSP      - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.web.ifantasy.net:7051   volumes:      - ${LOCAL_CA_PATH}/web.ifantasy.net/registers/peer1:${DOCKER_CA_PATH}/peer   ports:      - 7351:7051orderer1.orderer.ifantasy.net:   container_name: orderer1.orderer.ifantasy.net   extends:      file: docker-base.yaml      service: orderer-base   environment:      - ORDERER_HOST=orderer1.orderer.ifantasy.net      - ORDERER_GENERAL_LOCALMSPID=ordererMSP   volumes:      - ${LOCAL_CA_PATH}/orderer.ifantasy.net/registers/orderer1:${DOCKER_CA_PATH}/orderer      - ${LOCAL_ROOT_PATH}/data/genesis.block:${DOCKER_CA_PATH}/orderer/genesis.block   ports:      - 7151:7777
  16. 启动 peerorderer 服务:

    docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d peer1.soft.ifantasy.net peer1.web.ifantasy.net orderer1.orderer.ifantasy.net

    此时咱们曾经启动了所有联盟链网络所需的容器如下:

    (base) root@DebianA:1_3Org2Peer1Orderer1TLS# docker psCONTAINER ID   IMAGE                            COMMAND                  CREATED             STATUS             PORTS                              NAMES1c59b88fa847   hyperledger/fabric-peer:2.4      "peer node start"        8 seconds ago       Up 6 seconds       0.0.0.0:7251->7051/tcp             peer1.soft.ifantasy.net3906338f6861   hyperledger/fabric-peer:2.4      "peer node start"        8 seconds ago       Up 6 seconds       0.0.0.0:7351->7051/tcp             peer1.web.ifantasy.net9f127a054343   hyperledger/fabric-orderer:2.4   "orderer"                8 seconds ago       Up 6 seconds       7050/tcp, 0.0.0.0:7151->7777/tcp   orderer1.orderer.ifantasy.net949abd8f7070   hyperledger/fabric-ca:1.5        "sh -c 'fabric-ca-se…"   About an hour ago   Up About an hour   7054/tcp, 0.0.0.0:7150->7050/tcp   orderer.ifantasy.net011fe2b36c01   hyperledger/fabric-ca:1.5        "sh -c 'fabric-ca-se…"   About an hour ago   Up About an hour   0.0.0.0:7050->7050/tcp, 7054/tcp   council.ifantasy.net207879f5bb33   hyperledger/fabric-ca:1.5        "sh -c 'fabric-ca-se…"   About an hour ago   Up About an hour   7054/tcp, 0.0.0.0:7350->7050/tcp   web.ifantasy.netd1850c86e096   hyperledger/fabric-ca:1.5        "sh -c 'fabric-ca-se…"   About an hour ago   Up About an hour   7054/tcp, 0.0.0.0:7250->7050/tcp   soft.ifantasy.net
  17. 补全根目录中 envpeer1soft 的环境变量:

    export LOCAL_ROOT_PATH=$PWDexport LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgsexport DOCKER_CA_PATH=/tmpexport COMPOSE_PROJECT_NAME=fabriclearnexport DOCKER_NETWORKS=networkexport FABRIC_BASE_VERSION=2.4export FABRIC_CA_VERSION=1.5echo "init terminal soft"export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/configexport CORE_PEER_TLS_ENABLED=trueexport CORE_PEER_LOCALMSPID="softMSP"export CORE_PEER_ADDRESS=peer1.soft.ifantasy.net:7251export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pemexport CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/mspexport ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
  18. 复制 envpeer1softenvpeer1web 作为 web 组织的环境变量:

    export LOCAL_ROOT_PATH=$PWDexport LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgsexport DOCKER_CA_PATH=/tmpexport COMPOSE_PROJECT_NAME=fabriclearnexport DOCKER_NETWORKS=networkexport FABRIC_BASE_VERSION=2.4export FABRIC_CA_VERSION=1.5echo "init terminal web"export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/configexport CORE_PEER_TLS_ENABLED=trueexport CORE_PEER_LOCALMSPID="webMSP"export CORE_PEER_ADDRESS=peer1.web.ifantasy.net:7351export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pemexport CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/mspexport ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
  19. 通过 soft 创立 mychannel 测试通道的创世区块:

    source envpeer1softpeer channel create -c mychannel -f $LOCAL_ROOT_PATH/data/mychannel.tx -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --outputBlock $LOCAL_ROOT_PATH/data/mychannel.block

    如果呈现以下谬误,请查看环境变量 FABRIC_CFG_PATH 所指目录是否蕴含 core.yaml 配置文件:

    InitCmd -> ERRO 001 Fatal error when initializing core config : Could not find config file. Please make sure that FABRIC_CFG_PATH is set to a path which contains core.yaml

    如果呈现以下谬误,请查看环境变量 CORE_PEER_TLS_ROOTCERT_FILE 是否只想 TLS-CA 根证书、 环境变量 ORDERER_CA 是否指向 orderer1TLS-CA 根证书:

    ERRO 002 Client TLS handshake failed after 1.116738ms with error: x509: certificate is not valid for any names, but wanted to match localhost remoteaddress=127.0.0.1:7151
  20. mychannel 创世区块复制到其成员组织目录:

    cp $LOCAL_ROOT_PATH/data/mychannel.block $LOCAL_CA_PATH/soft.ifantasy.net/assets/cp $LOCAL_ROOT_PATH/data/mychannel.block $LOCAL_CA_PATH/web.ifantasy.net/assets/
  21. 别离通过成员组织的 cli 退出通道:

    source envpeer1softpeer channel join -b $LOCAL_CA_PATH/soft.ifantasy.net/assets/mychannel.blocksource envpeer1webpeer channel join -b $LOCAL_CA_PATH/web.ifantasy.net/assets/mychannel.block

    如果呈现以下谬误,请查看环境变量 CORE_PEER_ADDRESS 是否与对应组织的 docker 配置中的 peer 地址和端口是否统一:

    Client TLS handshake failed after 1.554615ms with error: x509: certificate is valid for peer1soft, peer1.soft.ifantasy.net, not soft.ifantasy.net remoteaddress=127.0.0.1:7251

    胜利后,便可通过 peer channel getinfo -c mychannel 查看已退出通道:

    装置/测试链码

  22. soft 打包并装置链码:

    source envpeer1softpeer lifecycle chaincode package basic.tar.gz --path asset-transfer-basic/chaincode-go --label basic_1peer lifecycle chaincode install basic.tar.gz

    装置胜利后,可应用 peer lifecycle chaincode queryinstalled 命令查问已装置链码信息(其中 Package ID 须要记下来):

    (base) root@DebianA:1_3Org2Peer1Orderer1TLS# peer lifecycle chaincode queryinstalledInstalled chaincodes on peer:Package ID: basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718, Label: basic_1
  23. web 装置链码:

    source envpeer1webpeer lifecycle chaincode install basic.tar.gz
  24. 设置链码 ID 环境变量:

    export CHAINCODE_ID=basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718
  25. softweb 批准链码:

    source envpeer1softpeer lifecycle chaincode approveformyorg -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA  --channelID mychannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_IDsource envpeer1webpeer lifecycle chaincode approveformyorg -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA  --channelID mychannel --name basic --version 1.0 --sequence 1 --waitForEvent --init-required --package-id $CHAINCODE_ID

    批准后,可应用以下命令查看本组织的链码批准状况:

    (base) root@DebianA:1_3Org2Peer1Orderer1TLS# peer lifecycle chaincode queryapproved -C mychannel -n basic --sequence 1Approved chaincode definition for chaincode 'basic' on channel 'mychannel':sequence: 1, version: 1.0, init-required: true, package-id: basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718, endorsement plugin: escc, validation plugin: vscc

    也可应用以下命令查看指定链码是否已筹备好被提交:

    (base) root@DebianA:1_3Org2Peer1Orderer1TLS# peer lifecycle chaincode checkcommitreadiness -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID mychannel --name basic --version 1.0 --sequence 1 --init-requiredChaincode definition for chaincode 'basic', version '1.0', sequence '1' on channel 'mychannel' approval status by org:softMSP: truewebMSP: true
  26. 应用任意非法组织提交链码:

    source envpeer1softpeer lifecycle chaincode commit -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID mychannel --name basic --init-required --version 1.0 --sequence 1 --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE

    可应用以下命令查看链码提交状况:

    peer lifecycle chaincode querycommitted --channelID mychannel --name basic -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE
  27. 初始化链码(非必须):

    peer chaincode invoke --isInit -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID mychannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["InitLedger"]}'

    其中带 --isInit 参数示意以后调用为链码初始化调用,在不须要初始化的链码中能够省略此步骤。如果呈现下列谬误,请查看:

    • 整个 docker 内的 networks 的值必须为 ${DOCKER_NETWORKS}
    • 环境变量中 COMPOSE_PROJECT_NAMEDOCKER_NETWORKS 是否被赋值、
    • docker-base.yamlCORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE 的值必须是 ${COMPOSE_PROJECT_NAME}_${DOCKER_NETWORKS}
    error starting container: error starting container: API error (404): network hyperledger_fabric-ca not found"
  28. 调用链码:

    peer chaincode invoke -o orderer1.orderer.ifantasy.net:7151 --tls --cafile $ORDERER_CA --channelID mychannel --name basic --peerAddresses peer1.soft.ifantasy.net:7251 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE --peerAddresses peer1.web.ifantasy.net:7351 --tlsRootCertFiles $CORE_PEER_TLS_ROOTCERT_FILE -c '{"Args":["GetAllAssets"]}'

    如果呈现下列谬误,请查看 approveformyorg 的链码包 IDinstall 的链码包 ID 必须统一:

    endorsement failure during invoke. response: status:500 message:"make sure the chaincode fabcar has been successfully defined on channel mychannel and try again: chaincode definition for 'basic' exists, but chaincode is not installed"

    调用胜利后可在控制台查看链码输入:

    2022-04-05 14:25:16.529 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"[{\"ID\":\"asset1\",\"color\":\"blue\",\"size\":5,\"owner\":\"Tomoko\",\"appraisedValue\":300},{\"ID\":\"asset2\",\"color\":\"red\",\"size\":5,\"owner\":\"Brad\",\"appraisedValue\":400},{\"ID\":\"asset3\",\"color\":\"green\",\"size\":10,\"owner\":\"Jin Soo\",\"appraisedValue\":500},{\"ID\":\"asset4\",\"color\":\"yellow\",\"size\":10,\"owner\":\"Max\",\"appraisedValue\":600},{\"ID\":\"asset5\",\"color\":\"black\",\"size\":15,\"owner\":\"Adriana\",\"appraisedValue\":700},{\"ID\":\"asset6\",\"color\":\"white\",\"size\":15,\"owner\":\"Michel\",\"appraisedValue\":800}]"

参考

<!-- 1: 作者. 文章题目. 发表地. [发表或更新日期] -->


  1. Nisen. Fabric账号、cryptogen和fabirc-ca. github.io. [2018-06-19] ↩
  2. Hyperledger. 成员服务提供者 (MSP). hyperledger-fabric.readthedocs.io. [2021-05-22] ↩
  3. hubwiz.com. configtx.yaml中文详解. hubwiz.com. [2019-04-24 ] ↩