Hyperledger Fabric訂製聯盟鏈網路工程實踐
- 2022 年 4 月 8 日
- 筆記
- 區塊鏈, blockchain, fabric
前言
總體來看,網路上成體系的可用的 Fabric 教程極少——不是直接在 Fabric 官網複製內容大談基礎理論就是在描述一個幾乎無法復現的項目實踐,以至於學習 Fabric 的效率極低,印象最深刻的就是我曾經花費幾天時間嘗試按照官方教程 CA Deployment steps 搭建自己的 CA 服務,卻始終無法成功也找不到原因。因此,為了提高生產效率,本項目虛擬了一個工作室聯盟鏈需求並將逐步實現,致力於提供一個易理解、可復現的Fabric學習項目(儘管它比較簡單),其中項目部署步驟的各個環節都清晰可見,並且將所有過程打包為腳本使之能夠被快速復現在任何一台主機上。
工程介紹
組織架構
有一啟明星工作室,其中包含三大組織:軟體組、WEB組、硬體組、理事會,不同組織間相互獨立,偶爾有業務往來。現理事會決定搭建一個啟明星工作室的聯盟鏈網路,使不同組織間加強合作,期望最終實現以下工程架構:
- 組織說明
council:理事會,負責工作室各組間協調管理,由三組抽調人員共同組成soft:軟體組,專註軟體開發hard:硬體組,專註硬體開發web:WEB組,專註網站開發orderer:過渡排序組織,為聯盟鏈網路提供排序服務,後期會捨棄
- 成員說明
council:一個Orderer節點、三個Admin帳號,每組擁有一個Admin帳號許可權soft:一個Orderer節點、一個Peer節點、一個Admin帳號、一個User帳號hard:一個Orderer節點、一個Peer節點、一個Admin帳號、一個User帳號web:一個Orderer節點、一個Peer節點、一個Admin帳號、一個User帳號orderer:一個Orderer節點、一個Admin帳號
- 根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
本文工作
本項目主要以學習為主,所以並未期望一次實現所有架構和功能。本文所實現的具體內容為,搭建一個簡單的工作室聯盟鏈網路,包含 council 、 orderer 、 soft 、 web 四個組織,並將測試鏈碼部署在通道 mychannel ,網路結構為(實驗程式碼已上傳至://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服務
- 在根目錄下創建
compose文件夾,用於儲存docker-compose配置文件。 - 在
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}
- 在
compose下創建docker-compose.yaml文件,用於配置工程 docker 容器,寫入council、orderer、soft、web的 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
- 啟動各組織的 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
註冊賬戶
-
註冊
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 //ca-admin:[email protected]:7050注意:
enroll操作結果是保存帳號的身份證書至指定目錄下,以後就可以直接根據該目錄下的證書來使用對應身份,跟傳統 web 系統的登錄操作類似所以被我稱為登錄,但實際上有所區別。然後便可以
ca-admin身份進行註冊其它用戶的操作:fabric-ca-client register -d --id.name orderer1 --id.secret orderer1 --id.type orderer -u //council.ifantasy.net:7050 fabric-ca-client register -d --id.name peer1soft --id.secret peer1soft --id.type peer -u //council.ifantasy.net:7050 fabric-ca-client register -d --id.name peer1web --id.secret peer1web --id.type peer -u //council.ifantasy.net:7050council為其它組織提供 TLS-CA 服務的具體實現就是為其它組織提供council可驗證的合法賬戶,其他組織使用這些賬戶進行通訊就是可信的。後面註冊步驟與上面類似,故不再贅述。 -
註冊
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 //ca-admin:[email protected]:7150 fabric-ca-client register -d --id.name orderer1 --id.secret orderer1 --id.type orderer -u //orderer.ifantasy.net:7150 fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u //orderer.ifantasy.net:7150 -
註冊
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 //ca-admin:[email protected]:7250 fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u //soft.ifantasy.net:7250 fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u //soft.ifantasy.net:7250 -
註冊
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 //ca-admin:[email protected]:7350 fabric-ca-client register -d --id.name peer1 --id.secret peer1 --id.type peer -u //web.ifantasy.net:7350 fabric-ca-client register -d --id.name admin1 --id.secret admin1 --id.type admin -u //web.ifantasy.net:7350
構造組織成員證書
-
在各組織下創建
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 -
構造
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 //admin1:[email protected]:7150注意:這裡是登錄上節我們註冊的管理員賬戶而非啟動
CA服務時的引導賬戶,引導賬戶跟管理員賬戶的區別也是我至今難以理解的地方以上命令成功後便可以看到
FABRIC_CA_CLIENT_HOME/FABRIC_CA_CLIENT_MSPDIR目錄下生成的證書文件。然後需要構造admin1的msp目錄: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 證書。然後登錄orderer的orderer1的組織內賬戶: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 //orderer1:[email protected]: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然後登錄
orderer的orderer1的組織間 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 //orderer1:[email protected]: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後面的流程跟這裡類似,因此不再贅述。
-
構造
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 //admin1:[email protected]: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 //peer1:[email protected]: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 //peer1soft:[email protected]: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============================="
- 構造
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 //admin1:[email protected]: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 //peer1:[email protected]: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 //peer1web:[email protected]: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============================="
配置系統通道及測試通道
- 在
config目錄下創建configtx.yaml配置文件,文件太長在此不做展示,可以在 FabricLearn 中查看,其中各項已加說明注釋[^3]。 - 通過
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 - 在
compose/docker-compose.yaml文件中添加peer和orderer服務相關配置: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 - 啟動
peer和orderer服務:
此時我們已經啟動了所有聯盟鏈網路所需的容器如下: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 - 補全根目錄中
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 - 複製
envpeer1soft為envpeer1web作為 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 - 通過
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.blockFABRIC_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.yamlCORE_PEER_TLS_ROOTCERT_FILE是否只想TLS-CA根證書、 環境變數ORDERER_CA是否指向orderer1的TLS-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 - 將
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/ - 分別通過成員組織的 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.blockCORE_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:7251peer channel getinfo -c mychannel查看已加入通道:

安裝/測試鏈碼
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.gzpeer 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_1web安裝鏈碼:source envpeer1web peer lifecycle chaincode install basic.tar.gz- 設置鏈碼
ID環境變數:export CHAINCODE_ID=basic_1:06613e463ef6694805dd896ca79634a2de36fdf019fa7976467e6e632104d718 soft和web批准鏈碼:
批准後,可使用以下命令查看本組織的鏈碼批准情況: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- 使用任意合法組織提交鏈碼:
可使用以下命令查看鏈碼提交情況: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_FILEpeer 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 - 初始化鏈碼(非必須):
其中帶 --isInit 參數表示當前調用為鏈碼初始化調用,在不需要初始化的鏈碼中可以省略此步驟。如果出現下列錯誤,請檢查: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"]}'- 整個
docker內的networks的值必須為${DOCKER_NETWORKS} - 環境變數中
COMPOSE_PROJECT_NAME和DOCKER_NETWORKS是否被賦值、 docker-base.yaml中CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE的值必須是${COMPOSE_PROJECT_NAME}_${DOCKER_NETWORKS}
error starting container: error starting container: API error (404): network hyperledger_fabric-ca not found" - 整個
- 調用鏈碼:
如果出現下列錯誤,請檢查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的鏈碼包ID與install的鏈碼包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}]"
參考
Nisen. Fabric帳號、cryptogen和fabirc-ca. github.io. [2018-06-19] ↩︎
Hyperledger. 成員服務提供者 (MSP). hyperledger-fabric.readthedocs.io. [2021-05-22] ↩︎


