Hyperledger Fabric定製聯盟鏈網路工程實踐

丿風色幻想發表於2022-04-08

前言

總體來看,網路上成體系的可用的 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.net web組第一個 peer 節點地址
peer2.web.ifantasy.net web組第二個 peer 節點地址
orderer1.web.ifantasy.net web組第一個 orderer 節點地址

此外,還需要在 \etc\hosts 檔案新增 DNS 地址:

echo "127.0.0.1       council.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       orderer.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       soft.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       web.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       hard.ifantasy.net" >> /etc/hosts

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

echo "127.0.0.1       peer1.soft.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       peer1.web.ifantasy.net" >> /etc/hosts
echo "127.0.0.1       peer1.hard.ifantasy.net" >> /etc/hosts

本文工作

本專案主要以學習為主,所以並未期望一次實現所有架構和功能。本文所實現的具體內容為,搭建一個簡單的工作室聯盟鏈網路,包含 councilorderersoftweb 四個組織,並將測試鏈碼部署在通道 mychannel ,網路結構為(實驗程式碼已上傳至:https://github.com/wefantasy/FabricLearn 的 1_3Org2Peer1Orderer1TLS 目錄下):

執行埠 說明
council.ifantasy.net 7050 council 組織的 CA 服務, 為聯盟鏈網路提供 TLS-CA 服務
orderer.ifantasy.net 7150 orderer 組織的 CA 服務, 為聯盟鏈網路提供排序服務
orderer1.orderer.ifantasy.net 7151 orderer 組織的 orderer1 成員節點
soft.ifantasy.net 7250 soft 組織的 CA 服務, 包含成員: peer1 、 admin1
peer1.soft.ifantasy.net 7251 soft 組織的 peer1 成員節點
web.ifantasy.net 7350 web 組織的 CA 服務, 包含成員: peer1 、 admin1
peer1.web.ifantasy.net 7351 web 組織的 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=$PWD
export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
export DOCKER_CA_PATH=/tmp
export COMPOSE_PROJECT_NAME=fabriclearn
export DOCKER_NETWORKS=network
export FABRIC_BASE_VERSION=2.4
export 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}
  1. 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
  1. 啟動各組織的 TLS 服務:
source envpeer1soft
docker-compose -f $LOCAL_ROOT_PATH/compose/docker-compose.yaml up -d council.ifantasy.net orderer.ifantasy.net soft.ifantasy.net web.ifantasy.net

註冊賬戶

  1. 註冊 council 組織賬戶。
    首先設定 council 的環境變數:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem
    export 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:7050
    fabric-ca-client register -d --id.name peer1soft --id.secret peer1soft --id.type peer -u https://council.ifantasy.net:7050
    fabric-ca-client register -d --id.name peer1web --id.secret peer1web --id.type peer -u https://council.ifantasy.net:7050
    

    council 為其它組織提供 TLS-CA 服務的具體實現就是為其它組織提供 council 可驗證的合法賬戶,其他組織使用這些賬戶進行通訊就是可信的。後面註冊步驟與上面類似,故不再贅述。

  2. 註冊 orderer 組織賬戶:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/ca/crypto/ca-cert.pem
    export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/orderer.ifantasy.net/ca/admin
    fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@orderer.ifantasy.net:7150
    fabric-ca-client register -d --id.name orderer1 --id.secret orderer1 --id.type orderer -u https://orderer.ifantasy.net:7150
    fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://orderer.ifantasy.net:7150
    
  3. 註冊 soft 組織賬戶:

    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/ca/crypto/ca-cert.pem
    export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/ca/admin
    fabric-ca-client enroll -d -u https://ca-admin:ca-adminpw@soft.ifantasy.net:7250
    fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u https://soft.ifantasy.net:7250
    fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u https://soft.ifantasy.net:7250
    
  4. 註冊 web 組織賬戶:

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

構造組織成員證書

  1. 在各組織下建立 assets 目錄,用於儲存本組織根證書和用於組間通訊的 LTS-CA 根證書:

    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/assets
    cp $LOCAL_CA_PATH/orderer.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pem
    cp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/orderer.ifantasy.net/assets/tls-ca-cert.pem
    
    mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/assets
    cp $LOCAL_CA_PATH/soft.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pem
    cp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pem
    
    mkdir -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.pem
    cp $LOCAL_CA_PATH/council.ifantasy.net/ca/crypto/ca-cert.pem $LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pem
    
  2. 構造 orderer 組織成員證書。
    登入 orderer 管理員賬戶 admin1

    export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/admin1
    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pem
    export FABRIC_CA_CLIENT_MSPDIR=msp
    fabric-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/admincerts
    cp $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/orderer1
    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/ca-cert.pem
    export FABRIC_CA_CLIENT_MSPDIR=msp
    fabric-ca-client enroll -d -u https://orderer1:orderer1@orderer.ifantasy.net:7150
    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/msp/admincerts
    cp $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-msp
    export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/orderer.ifantasy.net/assets/tls-ca-cert.pem
    fabric-ca-client enroll -d -u https://orderer1:orderer1@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts orderer1.orderer.ifantasy.net
    cp $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/admincerts
    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/cacerts
    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/tlscacerts
    mkdir -p $LOCAL_CA_PATH/orderer.ifantasy.net/msp/users
    cp $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.pem
    cp $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
    

    後面的流程跟這裡類似,因此不再贅述。

  3. 構造 soft 組織成員證書:

echo "Start Soft============================="
echo "Enroll Admin"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://admin1:admin1@soft.ifantasy.net:7250
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/admincerts
cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/admincerts/cert.pem

echo "Enroll Peer1"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://peer1:peer1@soft.ifantasy.net:7250
# for TLS
export FABRIC_CA_CLIENT_MSPDIR=tls-msp
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pem
fabric-ca-client enroll -d -u https://peer1soft:peer1soft@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts peer1.soft.ifantasy.net
cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/tls-msp/keystore/key.pem
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/msp/admincerts
cp $LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/soft.ifantasy.net/registers/peer1/msp/admincerts/cert.pem

mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/admincerts
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/cacerts
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/tlscacerts
mkdir -p $LOCAL_CA_PATH/soft.ifantasy.net/msp/users
cp $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.pem
cp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/soft.ifantasy.net/msp/config.yaml
echo "End Soft============================="
  1. 構造 web 組織成員證書:
echo "Start Web============================="
echo "Enroll Admin"
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/web.ifantasy.net/registers/admin1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://admin1:admin1@web.ifantasy.net:7350
mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/admincerts
cp $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/admincerts/cert.pem

echo "Enroll Peer1"
# for identity
export FABRIC_CA_CLIENT_HOME=$LOCAL_CA_PATH/web.ifantasy.net/registers/peer1
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/ca-cert.pem
export FABRIC_CA_CLIENT_MSPDIR=msp
fabric-ca-client enroll -d -u https://peer1:peer1@web.ifantasy.net:7350
# for TLS
export FABRIC_CA_CLIENT_MSPDIR=tls-msp
export FABRIC_CA_CLIENT_TLS_CERTFILES=$LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pem
fabric-ca-client enroll -d -u https://peer1web:peer1web@council.ifantasy.net:7050 --enrollment.profile tls --csr.hosts peer1.web.ifantasy.net
cp $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/tls-msp/keystore/*_sk $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/tls-msp/keystore/key.pem
mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/msp/admincerts
cp $LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp/signcerts/cert.pem $LOCAL_CA_PATH/web.ifantasy.net/registers/peer1/msp/admincerts/cert.pem

mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/admincerts
mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/cacerts
mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/tlscacerts
mkdir -p $LOCAL_CA_PATH/web.ifantasy.net/msp/users
cp $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.pem
cp $LOCAL_ROOT_PATH/config/config-msp.yaml $LOCAL_CA_PATH/web.ifantasy.net/msp/config.yaml
echo "End Web============================="

配置系統通道及測試通道

  1. config 目錄下建立 configtx.yaml 配置檔案,檔案太長在此不做展示,可以在 FabricLearn 中檢視,其中各項已加說明註釋[^3]。
  2. 通過 configtxgen 生成創世區塊和測試通道:
    configtxgen -profile OrgsOrdererGenesis -outputBlock $LOCAL_ROOT_PATH/data/genesis.block -channelID syschannel
    configtxgen -profile OrgsChannel -outputCreateChannelTx $LOCAL_ROOT_PATH/data/mychannel.tx -channelID mychannel
    
  3. 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:7051
    peer1.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:7051
    orderer1.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
    
  4. 啟動 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 ps
    CONTAINER ID   IMAGE                            COMMAND                  CREATED             STATUS             PORTS                              NAMES
    1c59b88fa847   hyperledger/fabric-peer:2.4      "peer node start"        8 seconds ago       Up 6 seconds       0.0.0.0:7251->7051/tcp             peer1.soft.ifantasy.net
    3906338f6861   hyperledger/fabric-peer:2.4      "peer node start"        8 seconds ago       Up 6 seconds       0.0.0.0:7351->7051/tcp             peer1.web.ifantasy.net
    9f127a054343   hyperledger/fabric-orderer:2.4   "orderer"                8 seconds ago       Up 6 seconds       7050/tcp, 0.0.0.0:7151->7777/tcp   orderer1.orderer.ifantasy.net
    949abd8f7070   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.net
    011fe2b36c01   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.net
    207879f5bb33   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.net
    d1850c86e096   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
    
  5. 補全根目錄中 envpeer1soft 的環境變數:
    export LOCAL_ROOT_PATH=$PWD
    export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
    export DOCKER_CA_PATH=/tmp
    export COMPOSE_PROJECT_NAME=fabriclearn
    export DOCKER_NETWORKS=network
    export FABRIC_BASE_VERSION=2.4
    export FABRIC_CA_VERSION=1.5
    echo "init terminal soft"
    export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/config
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="softMSP"
    export CORE_PEER_ADDRESS=peer1.soft.ifantasy.net:7251
    export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/soft.ifantasy.net/assets/tls-ca-cert.pem
    export CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/soft.ifantasy.net/registers/admin1/msp
    export ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
    
  6. 複製 envpeer1softenvpeer1web 作為 web 組織的環境變數:
    export LOCAL_ROOT_PATH=$PWD
    export LOCAL_CA_PATH=$LOCAL_ROOT_PATH/orgs
    export DOCKER_CA_PATH=/tmp
    export COMPOSE_PROJECT_NAME=fabriclearn
    export DOCKER_NETWORKS=network
    export FABRIC_BASE_VERSION=2.4
    export FABRIC_CA_VERSION=1.5
    echo "init terminal web"
    export FABRIC_CFG_PATH=$LOCAL_ROOT_PATH/config
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="webMSP"
    export CORE_PEER_ADDRESS=peer1.web.ifantasy.net:7351
    export CORE_PEER_TLS_ROOTCERT_FILE=$LOCAL_CA_PATH/web.ifantasy.net/assets/tls-ca-cert.pem
    export CORE_PEER_MSPCONFIGPATH=$LOCAL_CA_PATH/web.ifantasy.net/registers/admin1/msp
    export ORDERER_CA=$LOCAL_CA_PATH/orderer.ifantasy.net/registers/orderer1/tls-msp/tlscacerts/tls-council-ifantasy-net-7050.pem
    
  7. 通過 soft 建立 mychannel 測試通道的創世區塊:
    source envpeer1soft
    peer 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
    
  8. 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/
    
  9. 分別通過成員組織的 cli 加入通道:
    source envpeer1soft
    peer channel join -b $LOCAL_CA_PATH/soft.ifantasy.net/assets/mychannel.block
    source envpeer1web
    peer 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 檢視已加入通道:
    檢視已加入通道

安裝/測試鏈碼

  1. soft 打包並安裝鏈碼:
    source envpeer1soft
    peer lifecycle chaincode package basic.tar.gz --path asset-transfer-basic/chaincode-go --label basic_1
    peer lifecycle chaincode install basic.tar.gz
    
    安裝成功後,可使用 peer lifecycle chaincode queryinstalled 命令查詢已安裝鏈碼資訊(其中 Package ID 需要記下來):
    (base) root@DebianA:1_3Org2Peer1Orderer1TLS# peer lifecycle chaincode queryinstalled
    Installed chaincodes on peer:
    Package ID: basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718, Label: basic_1
    
  2. web 安裝鏈碼:
    source envpeer1web
    peer lifecycle chaincode install basic.tar.gz
    
  3. 設定鏈碼 ID 環境變數:
    export CHAINCODE_ID=basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718
    
  4. softweb 批准鏈碼:
    source envpeer1soft
    peer 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
    source envpeer1web
    peer 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 1
    Approved 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-required
    Chaincode definition for chaincode 'basic', version '1.0', sequence '1' on channel 'mychannel' approval status by org:
    softMSP: true
    webMSP: true
    
  5. 使用任意合法組織提交鏈碼:
    source envpeer1soft
    peer 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
    
  6. 初始化鏈碼(非必須):
    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"
    
  7. 呼叫鏈碼:
    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. Nisen. Fabric賬號、cryptogen和fabirc-ca. github.io. [2018-06-19] ↩︎

  2. Hyperledger. 成員服務提供者 (MSP). hyperledger-fabric.readthedocs.io. [2021-05-22] ↩︎

相關文章