乐趣区

关于区块链:Hyperledger-Fabric的testnetwork启动过程Bash源码详解

前言

在基于 Debian 搭建 Hyperledger Fabric 2.4 开发环境及运行简略案例中,咱们曾经实现了 Fabric 2.4 的环境搭建及 fabric-samples/test-network 官网案例的运行。毫无疑问 test-network 是一个优良的入门我的项目,让咱们仅仅通过几行命令就能搭建起罕用的 Fabric 联盟链网络,但我置信很多人第一次应用 ./network.sh up 胜利启动联盟链网络时跟我一样是懵的:网络是怎么启动的?它在背地做了什么?该网络蕴含哪些节点?蕴含哪些性能?它有什么用?为了解决这些问题,本文依据 test-network 中的几个 Bash 脚本源码,从启动流程、创立通道、部署链码等多个入口函数着手详细分析了脚本执行过程,对将来定制本人的 Fabric 网络提供参考。本文剖析源码次要蕴含启动默认网络、启动 CA 网络、创立通道、部署链码四个方面,每节分为官网调用和过程详解:官网调用是应用官网 Bash 脚本实现对应性能、过程详解是该脚本的理论实现流程,依据过程详解中的代码可能搭建出齐全可用的网络。

筹备

在开始前,须要筹备好 Fabric 的开发环境,具体环境搭建和软件版本可参考基于 Debian 搭建 Hyperledger Fabric 2.4 开发环境及运行简略案例。之后将 fabric-samples1 下的 test-network 目录拷贝到本地,因为官网示例中过于封装导致难以独自应用,因而本文对原 test-network 我的项目进行批改,批改内容包含但不限于以下几个方面(倡议间接将本案例仓库 FabricLearn 下的 0_TestNetworkExplain 目录拷贝到本地运行):

  1. 批改 compose-test-net.yamlcompose-ca.yamldocker/docker-compose-test-net.yamldocker/docker-compose-ca.yaml 文件中镜像版本:

    hyperledger/fabric-tools:latest    ->  hyperledger/fabric-tools:2.4
    hyperledger/fabric-peer:latest     ->  fabric-peer:2.4
    hyperledger/fabric-orderer:latest  ->  fabric-orderer:2.4
    hyperledger/fabric-ca:latest       ->  fabric-ca:1.5
  2. 将基于 Debian 搭建 Hyperledger Fabric 2.4 开发环境及运行简略案例中的 /usr/local/fabric/config 目录复制到 test-network 根目录下。如无非凡阐明,环境变量 FABRIC_CFG_PATH 总是默认指向 test-network/config 目录。
  3. 批改 docker-compose-test-net.yaml,将${DOCKER_SOCK} 改成/var/run/docker.sock
  4. 批改 createChannel.shdeployCC.sh,将FABRIC_CFG_PATH=$PWD/../config/ 改成FABRIC_CFG_PATH=$PWD/config/
  5. 如无非凡阐明,本文所有命令皆运行在 test-network 根目录下。

启动默认网络

官网调用

test-network 中,蕴含一个默认最简网络,该网络只蕴含两个 peer 节点、一个 orderer 节点和一个 cli 节点,其中各节点的证书应用 cryptogen 工具动态生成。能够间接运行以下命令启动默认最简网络:

./network.sh up

过程详解

  1. 查看依赖:
  2. 查看 peer 版本
  3. 查看 ./config 配置目录是否存在
  4. 查看 peer 版本与 docker image 版本是否匹配
  5. 查看 fabric-ca 环境是否失常,默认应用cryptogen
  6. 创立组织证书:

    cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations"
    cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations"
    cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"
  7. docker-compose启动所有容器:

    docker-compose -f compose/compose-test-net.yaml -f compose/docker/docker-compose-test-net.yaml up -d


    其中 compose-test-net.yaml 蕴含根本镜像配置,docker-compose-test-net.yaml蕴含根底通用变量,二者缺一不可。以上命令实现后即可实现与 ./network.sh up 完全相同的成果,进行下节试验前可应用 ./network.sh down 敞开此网络。

启动 CA 网络

官网调用

在 test-network 中,能够通过 fabric-ca 启动网络,该网络应用 fabric-ca 治理所有节点的身份证书,其中蕴含三个 ca 节点、两个 peer 节点、一个 orderer 节点和一个 cli 节点。能够间接运行以下命令启动 CA 网络(前面所有试验基于此网络):

./network.sh up -ca

过程详解

  1. 查看软件、版本依赖:
  2. 启动 fabric-ca 容器:

    docker-compose -f compose/compose-ca.yaml -f compose/docker/docker-compose-ca.yaml up -d
  3. 创立 org1 证书目录:

    # 创立组织证书根目录
    mkdir -p organizations/peerOrganizations/org1.example.com/
  4. enroll管理员账户:

    # enroll 组织默认管理员账户,其配置对应在 compose/compose-ca.yaml 的 command 中,enroll 过程会获取该账户的全副证书并保留至 FABRIC_CA_CLIENT_HOME 目录下
    export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/
    fabric-ca-client enroll -u https://admin:adminpw@localhost:7054 --caname ca-org1 --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
  5. 创立 org1 组织的 OU 配置文件:

    # 创立组织 msp 的 OU 配置文件
    echo 'NodeOUs:
      Enable: true
      ClientOUIdentifier:
     Certificate: cacerts/localhost-7054-ca-org1.pem
     OrganizationalUnitIdentifier: client
      PeerOUIdentifier:
     Certificate: cacerts/localhost-7054-ca-org1.pem
     OrganizationalUnitIdentifier: peer
      AdminOUIdentifier:
     Certificate: cacerts/localhost-7054-ca-org1.pem
     OrganizationalUnitIdentifier: admin
      OrdererOUIdentifier:
     Certificate: cacerts/localhost-7054-ca-org1.pem
     OrganizationalUnitIdentifier: orderer'>"${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml"
  6. 结构 tlscacerts 证书目录(用于不同组织通信):

    # 因为该 CA 同时充当组织 CA 和 tlsca,因而间接将 CA 启动时生成的组织根证书复制到组织级 CA 和 TLS CA 目录中
    mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts"
    cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/msp/tlscacerts/ca.crt"
  7. 结构 tlsca 证书目录(用于组织内客户端通信):

    mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/tlsca"
    cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem"
  8. 结构 ca 证书目录(用于组织内客户端通信):

    mkdir -p "${PWD}/organizations/peerOrganizations/org1.example.com/ca"
    cp "${PWD}/organizations/fabric-ca/org1/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"
  9. 为 org1 注册新账户:

    fabric-ca-client register --caname ca-org1 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    fabric-ca-client register --caname ca-org1 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    fabric-ca-client register --caname ca-org1 --id.name org1admin --id.secret org1adminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
  10. 结构 peer0 的身份证书目录:

    # 结构 peer0 的 msp 证书目录,证书文件会存在 - M 指定的文件夹下
    fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp" --csr.hosts peer0.org1.example.com --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/config.yaml"
    # 结构 peer0 的 msp-tls 证书目录
    fabric-ca-client enroll -u https://peer0:peer0pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls" --enrollment.profile tls --csr.hosts peer0.org1.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    # 结构 peer0 的 tls 证书目录并格式化文件名——用于启动 peer docker 容器
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/tlscacerts/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/signcerts/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt"
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/keystore/"* "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key"
  11. 结构其它用户身份证书目录:

    # 结构 user1 的 msp 证书目录,因为不用于组织间通信,所以不必配置 tls
    fabric-ca-client enroll -u https://user1:user1pw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/config.yaml"
    
    # 结构 org1admin 的 msp 证书目录
    fabric-ca-client enroll -u https://org1admin:org1adminpw@localhost:7054 --caname ca-org1 -M "${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org1/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/config.yaml"
  12. 结构 org2 的组织证书,要害代码如下(各代码含意如上):

    mkdir -p organizations/peerOrganizations/org2.example.com/
    export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org2.example.com/
    
    fabric-ca-client enroll -u https://admin:adminpw@localhost:8054 --caname ca-org2 --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    
    echo 'NodeOUs:
    Enable: true
    ClientOUIdentifier:
    Certificate: cacerts/localhost-8054-ca-org2.pem
    OrganizationalUnitIdentifier: client
    PeerOUIdentifier:
    Certificate: cacerts/localhost-8054-ca-org2.pem
    OrganizationalUnitIdentifier: peer
    AdminOUIdentifier:
    Certificate: cacerts/localhost-8054-ca-org2.pem
    OrganizationalUnitIdentifier: admin
    OrdererOUIdentifier:
    Certificate: cacerts/localhost-8054-ca-org2.pem
    OrganizationalUnitIdentifier: orderer'>"${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml"mkdir -p"${PWD}/organizations/peerOrganizations/org2.example.com/msp/tlscacerts"cp"${PWD}/organizations/fabric-ca/org2/ca-cert.pem""${PWD}/organizations/peerOrganizations/org2.example.com/msp/tlscacerts/ca.crt"
    mkdir -p "${PWD}/organizations/peerOrganizations/org2.example.com/tlsca"
    cp "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem"
    mkdir -p "${PWD}/organizations/peerOrganizations/org2.example.com/ca"
    cp "${PWD}/organizations/fabric-ca/org2/ca-cert.pem" "${PWD}/organizations/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem"
    
    fabric-ca-client register --caname ca-org2 --id.name peer0 --id.secret peer0pw --id.type peer --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    fabric-ca-client register --caname ca-org2 --id.name user1 --id.secret user1pw --id.type client --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    fabric-ca-client register --caname ca-org2 --id.name org2admin --id.secret org2adminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    
    fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp" --csr.hosts peer0.org2.example.com --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp/config.yaml"
    fabric-ca-client enroll -u https://peer0:peer0pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls" --enrollment.profile tls --csr.hosts peer0.org2.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/tlscacerts/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/signcerts/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt"
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/keystore/"* "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.key"
    
    fabric-ca-client enroll -u https://user1:user1pw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/User1@org2.example.com/msp/config.yaml"
    
    fabric-ca-client enroll -u https://org2admin:org2adminpw@localhost:8054 --caname ca-org2 -M "${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/org2/ca-cert.pem"
    cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/config.yaml"
  13. 结构 orderer 的组织证书,要害代码如下:

    mkdir -p organizations/ordererOrganizations/example.com
    export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/ordererOrganizations/example.com
    
    fabric-ca-client enroll -u https://admin:adminpw@localhost:9054 --caname ca-orderer --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    
    echo 'NodeOUs:
    Enable: true
    ClientOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: client
    PeerOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: peer
    AdminOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: admin
    OrdererOUIdentifier:
    Certificate: cacerts/localhost-9054-ca-orderer.pem
    OrganizationalUnitIdentifier: orderer'>"${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml"mkdir -p"${PWD}/organizations/ordererOrganizations/example.com/msp/tlscacerts"cp"${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem""${PWD}/organizations/ordererOrganizations/example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
    mkdir -p "${PWD}/organizations/ordererOrganizations/example.com/tlsca"
    cp "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem" "${PWD}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem"
    
    fabric-ca-client register --caname ca-orderer --id.name orderer --id.secret ordererpw --id.type orderer --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    fabric-ca-client register --caname ca-orderer --id.name ordererAdmin --id.secret ordererAdminpw --id.type admin --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp" --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    
    cp "${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml" "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/config.yaml"
    
    fabric-ca-client enroll -u https://orderer:ordererpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls" --enrollment.profile tls --csr.hosts orderer.example.com --csr.hosts localhost --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    
    cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
    cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/signcerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt"
    cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/keystore/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key"
    mkdir -p "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts"
    cp "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/tlscacerts/"* "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"
    
    fabric-ca-client enroll -u https://ordererAdmin:ordererAdminpw@localhost:9054 --caname ca-orderer -M "${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp" --tls.certfiles "${PWD}/organizations/fabric-ca/ordererOrg/ca-cert.pem"
    cp "${PWD}/organizations/ordererOrganizations/example.com/msp/config.yaml" "${PWD}/organizations/ordererOrganizations/example.com/users/Admin@example.com/msp/config.yaml"
  14. 启动所有容器

    docker-compose -f compose/compose-test-net.yaml -f compose/docker/docker-compose-test-net.yaml up -d

    以上命令胜利后便可应用 docker ps 命令看到运行的镜像:

    CONTAINER ID   IMAGE                            COMMAND                  CREATED          STATUS          PORTS                                                                    NAMES
    75e842d165ea   hyperledger/fabric-tools:2.4     "/bin/bash"              10 seconds ago   Up 8 seconds                                                                             cli
    576b578063c5   hyperledger/fabric-peer:2.4      "peer node start"        16 seconds ago   Up 10 seconds   0.0.0.0:9051->9051/tcp, 7051/tcp, 0.0.0.0:9445->9445/tcp                 peer0.org2.example.com
    512d7d98c8c4   hyperledger/fabric-orderer:2.4   "orderer"                16 seconds ago   Up 14 seconds   0.0.0.0:7050->7050/tcp, 0.0.0.0:7053->7053/tcp, 0.0.0.0:9443->9443/tcp   orderer.example.com
    276f463cc6a7   hyperledger/fabric-peer:2.4      "peer node start"        16 seconds ago   Up 12 seconds   0.0.0.0:7051->7051/tcp, 0.0.0.0:9444->9444/tcp                           peer0.org1.example.com
    8faaaaa7e17a   hyperledger/fabric-ca:1.5        "sh -c'fabric-ca-se…"   21 seconds ago   Up 20 seconds   0.0.0.0:9054->9054/tcp, 7054/tcp, 0.0.0.0:19054->19054/tcp               ca_orderer
    c253d9b790be   hyperledger/fabric-ca:1.5        "sh -c'fabric-ca-se…"   21 seconds ago   Up 20 seconds   0.0.0.0:7054->7054/tcp, 0.0.0.0:17054->17054/tcp                         ca_org1
    0aa90a2686a8   hyperledger/fabric-ca:1.5        "sh -c'fabric-ca-se…"   21 seconds ago   Up 20 seconds   0.0.0.0:8054->8054/tcp, 7054/tcp, 0.0.0.0:18054->18054/tcp               ca_org2

    创立通道

    官网调用

    本大节基于上一节 启动 CA 网络,在上节 CA 网络启动胜利后,能够间接运行以下命令创立通道:

    ./network.sh createChannel -c mychannel

    创立通道的前提是创立该通道的创世区块,在上节步骤中,咱们通过无通道、无创世区块的形式启动了整个网络,所在本节创立通道蕴含创立创世区块的过程。

    过程详解

  15. 查看依赖,并启动网络(同上)。
  16. 设置环境变量,用于操作区块链网络

    export CORE_PEER_TLS_ENABLED=true
    export CHANNEL_NAME=mychannel
    export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
    export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
    export PEER0_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
    export PEER0_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem
    export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
    export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
  17. 创立通道创世区块:

    # 创立通道数据目录
    mkdir channel-artifacts
    # 配置创世区块环境变量
    export FABRIC_CFG_PATH=${PWD}/configtx
    configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID ${CHANNEL_NAME}
  18. 创立通道:

    # 配置通道环境变量
    export FABRIC_CFG_PATH=./config
    osnadmin channel join --channelID ${CHANNEL_NAME} --config-block ./channel-artifacts/${CHANNEL_NAME}.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
  19. 使 peer 节点退出通道:

    # 将 org1 的 peer 退出通道
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    peer channel join -b ./channel-artifacts/${CHANNEL_NAME}.block
    # 将 org2 的 peer 退出通道
    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    peer channel join -b ./channel-artifacts/${CHANNEL_NAME}.block

    组织新退出通道后,前面为组织设置锚节点(非必须)。

  20. 为通道获取通道最新配置块(以下流程为 org1 环境):

    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c ${CHANNEL_NAME} --tls --cafile "$ORDERER_CA"
  21. 将配置块解码为 JSON 并输入为${CORE_PEER_LOCALMSPID}config.json

    configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
    jq .data.data[0].payload.data.config config_block.json >"${CORE_PEER_LOCALMSPID}config.json"
  22. 追加锚节点配置:

    jq '.channel_group.groups.Application.groups.'${CORE_PEER_LOCALMSPID}'.values += {"AnchorPeers":{"mod_policy":"Admins","value":{"anchor_peers": [{"host":"'$HOST'","port":'$PORT'}]},"version":"0"}}' ${CORE_PEER_LOCALMSPID}config.json > ${CORE_PEER_LOCALMSPID}modified_config.json
  23. 依据链上配置 ${CORE_PEER_LOCALMSPID}config.json 和追加配置 ${CORE_PEER_LOCALMSPID}modified_config.json 计算更新的配置,并将其作为一个新交易写入${CORE_PEER_LOCALMSPID}anchors.tx

    configtxlator proto_encode --input ${CORE_PEER_LOCALMSPID}config.json --type common.Config --output original_config.pb
    configtxlator proto_encode --input ${CORE_PEER_LOCALMSPID}modified_config.json --type common.Config --output modified_config.pb
    configtxlator compute_update --channel_id "${CHANNEL_NAME}" --original original_config.pb --updated modified_config.pb --output config_update.pb
    configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
    echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL_NAME'","type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
    configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output "${CORE_PEER_LOCALMSPID}anchors.tx"
  24. 更新锚节点:

    peer channel update -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME -f ${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile "$ORDERER_CA"
  25. org2 反复以上流程即创立胜利:

    echo "update org2 anchor==========="
    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    peer channel fetch config config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c ${CHANNEL_NAME} --tls --cafile "$ORDERER_CA"
    sleep 3
    
    configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
    jq .data.data[0].payload.data.config config_block.json >"${CORE_PEER_LOCALMSPID}config.json"
    
    jq '.channel_group.groups.Application.groups.'${CORE_PEER_LOCALMSPID}'.values += {"AnchorPeers":{"mod_policy":"Admins","value":{"anchor_peers": [{"host":"localhost","port": 9051}]},"version":"0"}}' ${CORE_PEER_LOCALMSPID}config.json > ${CORE_PEER_LOCALMSPID}modified_config.json
    
    configtxlator proto_encode --input ${CORE_PEER_LOCALMSPID}config.json --type common.Config --output original_config.pb
    configtxlator proto_encode --input ${CORE_PEER_LOCALMSPID}modified_config.json --type common.Config --output original_config.pb
    configtxlator compute_update --channel_id "${CHANNEL_NAME}" --original original_config.pb --updated modified_config.pb --output config_update.pb
    configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
    echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL_NAME'","type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
    configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output "${CORE_PEER_LOCALMSPID}anchors.tx"
    
    peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c $CHANNEL_NAME -f ${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile "$ORDERER_CA"
    sleep 3

部署链码

官网调用

本大节基于上一节 创立通道,在上节通道创立胜利后,能够间接运行以下命令部署链码:

./network.sh deployCC -ccn mychaincode -ccp ./asset-transfer-basic-go -ccv 1.0 -ccl go

过程详解

  1. 查看参数是否失常:
  2. 下载 asset-transfer-basic-go 的包依赖:

    pushd asset-transfer-basic-go            # 进入 asset-transfer-basic-go 目录
    GO111MODULE=on go mod vendor    # 下载 go 包依赖
    popd                            #返回当前目录
  3. 查看链码是否须要初始化、设置策略、公有数据集:
  4. 设置环境变量:

    export FABRIC_CFG_PATH=$PWD/config/
    export CORE_PEER_TLS_ENABLED=true
    export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
    export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem
    export PEER0_ORG2_CA=${PWD}/organizations/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem
    export PEER0_ORG3_CA=${PWD}/organizations/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem
    export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
    export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
  5. 打包链码:

    peer lifecycle chaincode package mychaincode.tar.gz --path ./asset-transfer-basic-go --lang golang --label mychaincode_1.0
  6. 装置链码:

    # ORG1 装置链码
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    peer lifecycle chaincode install mychaincode.tar.gz
    # ORG2 装置链码
    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    peer lifecycle chaincode install mychaincode.tar.gz

    装置链码后会返回一个链码 ID 须要记下:

  7. 将链码 ID 设为环境变量:

    export PACKAGE_ID=mychaincode_1.0:39889cf0623cce2500261b22914a7aa9037a897bc7f6c5b36df7a922f29b05e0
  8. ORG1 查问已装置链码并批准链码:

    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    # 查问已装置链码
    peer lifecycle chaincode queryinstalled
    # 批准链码
    peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID mychannel --name mychaincode --version 1.0 --package-id ${PACKAGE_ID} --sequence 1
  9. ORG2 查问已装置链码并批准链码:

    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    # 查问已装置链码
    peer lifecycle chaincode queryinstalled
    # 批准链码
    peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" --channelID mychannel --name mychaincode --version 1.0 --package-id ${PACKAGE_ID} --sequence 1
  10. 查看链码是否已筹备好被提交:

    peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name mychaincode --version 1.0 --sequence 1 --output json

  11. 提交链码:

    peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA"  --channelID mychannel --name mychaincode --version 1.0 --sequence 1 --peerAddresses localhost:7051 --tlsRootCertFiles $PEER0_ORG1_CA --peerAddresses localhost:9051 --tlsRootCertFiles $PEER0_ORG2_CA
  12. 查问提交的链码:

    peer lifecycle chaincode querycommitted --channelID mychannel --name mychaincode
  13. 调用链码:

    peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" -C mychannel -n mychaincode --peerAddresses

    总结

    本文先是阐明了 fabric-samples 适度的封装不利于咱们理解把握其中各个操作的实在过程,而后独自拿出 test-network 进行批改定制,最初详细分析了 test-network 中启动默认网络、启动 CA 网络、创立通道、部署链码的具体过程,并且给出了每个过程的代码,使咱们可能依据代码一步步搭建所述网络,进一步了解 Fabric 架构。

相干试验源码已上传:https://github.com/wefantasy/…

参考


  1. hyperledger. fabric-samples. Github. ↩
退出移动版