news 2026/9/19 9:16:49

Fabric 2.0 EtcdRaft分布式集群部署实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Fabric 2.0 EtcdRaft分布式集群部署实战指南

简介:本资源是一份面向区块链开发工程师与联盟链部署实践者的 Hyperledger Fabric 2.0 分布式集群部署实战指南,聚焦企业级生产环境落地痛点,系统解决多节点协同、共识配置简化与链码生命周期管理等核心问题。文档为单个PDF文件(554KB),内容结构完整,涵盖Fabric 2.0四大关键升级:模块化链码生命周期(打包→安装→批准→提交→升级)、基于EtcdRaft的轻量共识机制、智能合约去中心化治理流程,以及Alpine镜像带来的资源优化;同时提供从CentOS基础环境搭建(Docker/Go/Git/fabric-binaries)、三节点分布式拓扑规划(orderer0/peer0.org1等IP映射与防火墙配置),到证书生成、通道创建及网络启停的全流程实操细节。目前已有6482人学习下载,适合具备Linux与容器基础、正开展Fabric联盟链POC或生产部署的技术人员深度参考。

1. 为什么 Fabric 2.0 分布式集群必须用 EtcdRaft,而不是“先搭起来再说”?

很多团队在部署 Hyperledger Fabric 时,习惯性复用 1.x 的 Solo 或 Kafka 模式——结果在生产环境一上线就卡在共识延迟、节点失联、证书校验失败三连击。Fabric 2.0 的核心转折点不是功能堆叠,而是共识层彻底重构:EtcdRaft 不再依赖外部消息中间件,所有排序节点(orderer)自带 Raft 日志复制与 Leader 选举能力,节点间通过 TLS 双向认证直连通信。这意味着你不再需要单独维护 Kafka 集群、ZooKeeper 服务和复杂的 ACL 策略;三台物理机即可构成高可用排序服务,且故障恢复时间从分钟级压缩到秒级。本文实操的 3 节点集群(192.168.137.100/101/102)正是基于这一设计范式:orderer0–2 构成 Raft 共识组,peer0.org1 和 peer0.org2、peer1.org2 分属两个组织,全部启用 mTLS 双向验证。它不适用于 PoW 公链场景,但对供应链溯源、跨境贸易单证、医疗数据共享等联盟链高频写入+强一致性要求的业务,是当前最轻量、最可控、最易审计的 Fabric 生产部署形态。


2. Fabric 2.0 分布式集群的底层支撑:Docker + EtcdRaft + mTLS 三位一体

Fabric 2.0 分布式集群不是“把容器跑起来就行”,而是三个技术层深度咬合的结果:Docker 提供隔离运行时,EtcdRaft 定义节点协作逻辑,mTLS 则是所有通信的准入凭证。任何一层配置偏差都会导致connection refusedx509: certificate signed by unknown authoritycontext deadline exceeded这类典型错误。下面从环境准备开始,逐层拆解关键动作与参数含义。

2.1 基础环境统一:CentOS + Docker 24.0.7 + Go 1.14 + docker-compose 1.22.0

Fabric 对基础组件版本有硬性约束:Go 必须 ≥1.13(因 Fabric 2.0 使用 modules 机制),Docker 推荐 ≥20.10(避免 overlay2 驱动兼容问题),docker-compose 必须 ≥1.21(支持extra_hosts在多节点间解析 host 映射)。以下命令在三台服务器上逐条执行并验证输出

# 关闭防火墙(生产环境应开放特定端口,非直接禁用) sudo systemctl stop firewalld sudo systemctl disable firewalld # 更新 yum 并安装基础工具 sudo yum update -y sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加 Docker 官方源(注意:使用阿里云镜像源可加速) sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 安装指定版本 Docker(避免自动升级破坏兼容性) sudo yum install -y docker-ce-24.0.7 docker-ce-cli-24.0.7 containerd.io # 启动并设为开机自启 sudo systemctl start docker sudo systemctl enable docker # 验证 Docker 版本及 daemon 状态 docker version | grep "Version:" systemctl is-active docker # 应返回 active

提示:若docker version报错Cannot connect to the Docker daemon,检查是否遗漏sudo systemctl start docker;若docker info显示WARNING: No swap limit support,属 CentOS 内核限制,不影响 Fabric 运行,可忽略。

接着安装 Go 1.14(Fabric 2.0 编译链码和二进制工具链必需):

# 下载并解压 Go(使用国内镜像加速) wget https://golang.google.cn/dl/go1.14.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.14.linux-amd64.tar.gz # 配置全局环境变量(写入 /etc/profile 保证所有用户生效) echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee -a /etc/profile echo 'export GOROOT=/usr/local/go' | sudo tee -a /etc/profile echo 'export GOPATH=/root/go' | sudo tee -a /etc/profile # 生效配置并验证 source /etc/profile go version # 应输出 go version go1.14 linux/amd64

最后安装 docker-compose 1.22.0(注意:Fabric 官方脚本bootstrap.sh依赖此版本解析 YAML 中的extra_hosts):

# 下载指定版本(避免使用 pip install 导致权限混乱) sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version # 应输出 docker-compose version 1.22.0

2.2 Fabric 二进制与镜像拉取:bootstrap.sh 的真实作用与替代方案

Fabric 官方bootstrap.sh脚本本质是自动化下载三类资源:

  • fabric-samples:含first-networktest-network等示例目录,提供crypto-config.yamlconfigtx.yaml模板;
  • fabric binariesconfigtxgencryptogenpeerorderer等可执行文件,存于fabric-samples/scripts目录;
  • Docker imageshyperledger/fabric-peerhyperledger/fabric-ordererhyperledger/fabric-tools等镜像,标签为2.0.0latest

但实际部署中,直接运行./bootstrap.sh存在两大风险:一是网络不稳定导致镜像拉取中断(尤其在国内);二是latest标签可能指向非预期版本。更可靠的做法是分步控制:

# 创建标准工作目录结构 mkdir -p ~/fabric-cluster/{channel-artifacts,crypto-config,scripts} cd ~/fabric-cluster # 手动下载 fabric-samples(GitHub Release 页面获取稳定版) wget https://github.com/hyperledger/fabric/archive/refs/tags/v2.0.0.tar.gz tar -xzf v2.0.0.tar.gz mv fabric-2.0.0/scripts ./scripts mv fabric-2.0.0/test-network ./test-network # 备用参考 # 下载并校验二进制文件(官方 SHA256 列表见 fabric GitHub release) cd scripts curl -O https://raw.githubusercontent.com/hyperledger/fabric/v2.0.0/scripts/bootstrap.sh chmod +x bootstrap.sh # 修改 bootstrap.sh:注释掉镜像拉取部分(第 152 行起),保留二进制下载 sed -i '152,170s/^/#/' bootstrap.sh # 执行仅下载二进制(跳过耗时的 docker pull) ./bootstrap.sh -s -d -t 2.0.0 # 将二进制复制到系统路径(便于全局调用) sudo cp ../scripts/* /usr/local/bin/

注意-s参数跳过 samples 下载(已手动获取),-d跳过 docker 镜像拉取,-t 2.0.0指定版本。执行后/usr/local/bin/下应存在configtxgencryptogen等可执行文件,且configtxgen --version输出Fabric 2.0.0

2.3 EtcdRaft 共识配置的核心:configtx.yaml 中 Consenters 字段的语义与校验

Fabric 2.0 的configtx.yaml文件中,Profiles.SampleMultiNodeEtcdRaft.EtcdRaft.Consenters是集群心跳的命脉。它不是简单罗列 IP,而是定义每个 orderer 节点的身份锚点Host必须与/etc/hosts中解析的域名一致,Port必须与容器内监听端口匹配,ClientTLSCertServerTLSCert必须指向该节点生成的 TLS 证书路径(由cryptogen产出)。任何一项不一致,Raft 组建即失败。

orderer0.example.com为例,其Consenters条目如下:

- Host: orderer0.example.com Port: 7050 ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt

对应地,/etc/hosts必须包含:

192.168.137.100 orderer0.example.com 192.168.137.101 orderer1.example.com 192.168.137.102 orderer2.example.com

crypto-config/目录下证书路径必须真实存在:

# 在 192.168.137.100 上验证 ls -l crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls/server.crt # 应输出类似:-r--r--r--. 1 root root 1120 Mar 8 14:22 server.crt

关键逻辑说明ClientTLSCert用于 orderer 向其他 orderer 发起连接时证明身份;ServerTLSCert用于接收连接时被对方校验。二者必须为同一证书(Fabric 默认复用 server.crt),且server.crt的 Subject Common Name(CN)必须等于Host字段值(即orderer0.example.com)。可通过openssl x509 -in server.crt -text -noout | grep CN验证。


3. 三节点分布式集群实战:证书生成、创世区块构建与跨主机服务编排

Fabric 分布式集群的本质是“证书驱动的网络拓扑”。所有节点启动前,必须完成:① 用cryptogen生成全网统一的 MSP 证书体系;② 用configtxgen构建包含 Raft 成员信息的创世区块;③ 将证书与配置文件同步至各主机;④ 编写适配各节点角色的docker-compose.yaml。这四步缺一不可,且顺序严格。

3.1 证书体系生成:crypto-config.yaml 的组织拓扑与 Count 参数含义

crypto-config.yaml定义了 Fabric 网络的 PKI 结构。本文集群包含 1 个 Orderer 组织(3 个 orderer 节点)和 2 个 Peer 组织(Org1 含 1 个 peer,Org2 含 2 个 peers),对应配置如下:

OrdererOrgs: - Name: Orderer Domain: example.com Specs: - Hostname: orderer0 - Hostname: orderer1 - Hostname: orderer2 PeerOrgs: - Name: Org1 Domain: org1.example.com Template: Count: 1 # 生成 1 个 peer(peer0.org1.example.com) Users: Count: 1 # 生成 1 个普通用户(User1@org1.example.com) - Name: Org2 Domain: org2.example.com Template: Count: 2 # 生成 2 个 peers(peer0.org2.example.com, peer1.org2.example.com) Users: Count: 1

执行cryptogen generate --config=./crypto-config.yaml后,生成的目录结构为:

crypto-config/ ├── ordererOrganizations/ │ └── example.com/ │ ├── orderers/ │ │ ├── orderer0.example.com/ # 含 msp、tls 目录 │ │ ├── orderer1.example.com/ │ │ └── orderer2.example.com/ │ └── users/ ├── peerOrganizations/ │ ├── org1.example.com/ │ │ └── peers/ │ │ └── peer0.org1.example.com/ # 含 msp、tls 目录 │ └── org2.example.com/ │ └── peers/ │ ├── peer0.org2.example.com/ │ └── peer1.org2.example.com/

参数说明Template.Count决定同组织下 peer 节点数量,每个节点生成独立的msp(含私钥、签名证书)和tls(含 server.crt/server.key/ca.crt)目录;Users.Count决定该组织下注册用户的数量,用于后续链码调用的身份认证。切勿将 Count 设为 0,否则peer容器启动时因缺失 MSP 目录报错failed to load local MSP

3.2 创世区块与通道配置:configtxgen 的 profile 选择与输出路径

Fabric 2.0 引入SampleMultiNodeEtcdRaftprofile 专门适配多 orderer Raft 集群。它与旧版SampleInsecureSolo的根本区别在于:前者在Orderer.EtcdRaft.Consenters中显式声明所有共识节点,后者仅配置单点ORDERER_GENERAL_ORDERERTYPE=solo。生成步骤如下:

# 生成创世区块(-profile 指定 Raft 模式,-outputBlock 指定输出路径) configtxgen -profile SampleMultiNodeEtcdRaft \ -channelID fabric-cluster-channel \ -outputBlock ./channel-artifacts/genesis.block # 生成通道创建交易(-profile 使用 TwoOrgsChannel,-outputCreateChannelTx 指定路径) configtxgen -profile TwoOrgsChannel \ -outputCreateChannelTx ./channel-artifacts/channel.tx \ -channelID mychannel # 为 Org1 生成锚节点更新交易(-asOrg 指定组织名,-outputAnchorPeersUpdate 指定输出) configtxgen -profile TwoOrgsChannel \ -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx \ -channelID mychannel \ -asOrg Org1MSP # 为 Org2 生成锚节点更新交易 configtxgen -profile TwoOrgsChannel \ -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx \ -channelID mychannel \ -asOrg Org2MSP

生成的channel-artifacts/目录内容必须完整:

文件名用途验证命令
genesis.block排序服务启动所需的创世区块configtxgen -inspectBlock genesis.block | head -n 5
channel.tx创建应用通道的交易文件configtxgen -inspectChannelCreateTx channel.tx | grep "channel_id"
Org1MSPanchors.txOrg1 锚节点配置更新configtxgen -inspectChannelCreateTx Org1MSPanchors.tx | grep "anchor_peers"

逻辑说明genesis.block包含 Raft 共识组初始成员列表(即Consenters),channel.tx定义通道成员(Org1+Org2)和策略,OrgXMSPancho.rs.tx则指定该组织在通道中的代表节点(如peer0.org1.example.com)。三者共同构成 Fabric 网络的“宪法”。

3.3 跨主机文件同步与 docker-compose 角色拆分:为什么不能共用同一份 compose 文件?

Fabric 分布式集群中,每台服务器只运行部分节点:

  • 192.168.137.100orderer0.example.com+peer0.org1.example.com
  • 192.168.137.101orderer1.example.com+peer0.org2.example.com
  • 192.168.137.102orderer2.example.com+peer1.org2.example.com

因此,docker-compose.yaml必须按节点角色拆分。以192.168.137.100为例,其docker-compose-up.yaml仅定义orderer0peer0.org1

version: '2' services: orderer0.example.com: container_name: orderer0.example.com image: hyperledger/fabric-orderer:2.0.0 environment: - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_BOOTSTRAPFILE=/var/hyperledger/orderer/orderer.genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp - ORDERER_GENERAL_TLS_ENABLED=true - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] # Raft 集群必需参数 - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] volumes: - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block - ./crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/msp:/var/hyperledger/orderer/msp - ./crypto-config/ordererOrganizations/example.com/orderers/orderer0.example.com/tls:/var/hyperledger/orderer/tls ports: - 7050:7050 extra_hosts: - "orderer0.example.com:192.168.137.100" - "orderer1.example.com:192.168.137.101" - "orderer2.example.com:192.168.137.102" peer0.org1.example.com: container_name: peer0.org1.example.com image: hyperledger/fabric-peer:2.0.0 environment: - CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt volumes: - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp - ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls ports: - 7051:7051 - 7052:7052 - 7053:7053 extra_hosts: - "orderer0.example.com:192.168.137.100" - "orderer1.example.com:192.168.137.101" - "orderer2.example.com:192.168.137.102"

同步命令需在192.168.137.100上执行:

# 将证书和通道文件推送到其他两台机器 scp -r channel-artifacts/ root@192.168.137.101:/root/fabric-cluster/ scp -r channel-artifacts/ root@192.168.137.102:/root/fabric-cluster/ scp -r crypto-config/ root@192.168.137.101:/root/fabric-cluster/ scp -r crypto-config/ root@192.168.137.102:/root/fabric-cluster/ # 在目标机器上创建各自 compose 文件(以 101 为例) ssh root@192.168.137.101 "cat > /root/fabric-cluster/docker-compose-up.yaml << 'EOF' # 此处粘贴 orderer1 + peer0.org2 的 service 定义 EOF"

关键点extra_hosts确保容器内 DNS 解析正确,volumes映射路径必须与crypto-config.yaml生成的实际路径一致,image标签必须显式指定:2.0.0(避免拉取latest导致版本不一致)。


4. 集群启动与状态验证:从 docker-compose up 到 peer channel list 的全流程诊断

启动 Fabric 分布式集群不是执行一条docker-compose up -d就能完事。由于涉及多节点 TLS 握手、Raft Leader 选举、Gossip 网络发现,必须分阶段验证每个环节是否就绪。以下是经过生产环境验证的标准流程。

4.1 分阶段启动与日志观察:为什么不能所有节点同时启动?

Raft 共识要求至少(N/2)+1个节点在线才能形成多数派(quorum)。对于 3 节点集群,需至少 2 个 orderer 启动成功后,第三个才能加入。因此推荐启动顺序:

  1. 先启动orderer0orderer1(在 100 和 101 上分别执行):

    cd ~/fabric-cluster docker-compose -f docker-compose-up.yaml up -d orderer0.example.com # 等待 30 秒,确认无 crash docker logs orderer0.example.com 2>&1 | grep "Raft leader is"
  2. 再启动orderer2(在 102 上):

    docker-compose -f docker-compose-up.yaml up -d orderer2.example.com # 观察日志是否出现 "joined raft cluster" 和 "became leader" docker logs orderer2.example.com 2>&1 | grep -E "(joined|leader)"
  3. 最后启动所有 peer 节点(100/101/102 同时执行):

    # 在各自机器上 docker-compose -f docker-compose-up.yaml up -d peer0.org1.example.com docker-compose -f docker-compose-up.yaml up -d peer0.org2.example.com docker-compose -f docker-compose-up.yaml up -d peer1.org2.example.com

典型错误定位:若docker logs orderer0.example.com持续输出failed to dial ... context deadline exceeded,检查extra_hosts是否缺失orderer1.example.com解析;若出现x509: certificate is valid for orderer1.example.com, not orderer0.example.com,说明server.crt的 CN 与Host字段不匹配。

4.2 CLI 容器接入与通道操作:使用 tools 镜像执行 peer 命令

Fabric 未提供跨节点的统一管理界面,所有通道操作必须通过hyperledger/fabric-tools容器完成。该容器需挂载所有组织的 MSP 和 TLS 证书,并配置正确的环境变量:

# 在 192.168.137.100 上创建 CLI 容器(复用 peer0.org1 的证书) docker run -it --rm \ --network host \ -v $(pwd)/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto \ -e CORE_PEER_TLS_ENABLED=true \ -e CORE_PEER_LOCALMSPID="Org1MSP" \ -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp \ -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 \ -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ -e CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt \ -e CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key \ hyperledger/fabric-tools:2.0.0 \ peer channel create -c mychannel -f ./channel-artifacts/channel.tx -o orderer0.example.com:7050 --outputBlock ./channel-artifacts/mychannel.block

成功后,mychannel.block生成,且docker logs orderer0.example.com应出现Received block [0]

接着加入 peer 节点:

# 加入 Org1 的 peer peer channel join -b ./channel-artifacts/mychannel.block # 加入 Org2 的 peer(需切换到 Org2 的 MSP 路径) CORE_PEER_LOCALMSPID="Org2MSP" \ CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \ CORE_PEER_ADDRESS=peer0.org2.example.com:7051 \ CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ peer channel join -b ./channel-artifacts/mychannel.block

4.3 最终状态验证表:5 个关键命令及其预期输出

命令执行位置预期输出失败含义
`docker ps | grep -E "(ordererpeer)"`所有三台机器每台显示 2 个 UP 容器
docker logs orderer0.example.com | grep "Raft leader is"100Raft leader is orderer0.example.com:7050Raft 未选举出 leader
peer channel listCLI 容器Channels:+mychannelpeer 未加入通道
peer channel getinfo -c mychannelCLI 容器"height":1+"currentBlockHash"通道未初始化成功
peer chaincode list --installedCLI 容器Package ID:+Label:链码未安装或路径错误

验证技巧:若peer channel list返回空,检查CORE_PEER_ADDRESS是否指向本机 peer(如peer0.org1.example.com:7051),且该 peer 容器确实在运行;若getinfo报错error getting endorser client,确认CORE_PEER_TLS_*路径下的证书文件存在且可读(ls -l检查权限)。


5. Fabric 2.0 链码生命周期实战:从打包、安装到批准提交的七步闭环

Fabric 2.0 最大变革是链码(智能合约)管理去中心化:不再由单一管理员部署,而是通过package → install → approve → commit四步实现多组织协同治理。这要求每个组织独立安装链码,再共同批准版本,最后由足够多组织提交生效。整个过程需精确控制--peerAddresses--signature-policy参数,否则approve会因签名不足失败。

5.1 链码打包与安装:packager 与 install 命令的参数组合

fabcar链码为例(位于fabric-samples/chaincode/fabcar/go),在 CLI 容器中执行:

# 1. 打包链码(生成 .tar.gz,含 metadata.json 和 code) peer lifecycle chaincode package fabcar.tar.gz \ --path github.com/hyperledger/fabric-samples/chaincode/fabcar/go \ --lang golang \ --label fabcar_1.0 # 2. Org1 安装(--peerAddresses 指向本组织 peer) peer lifecycle chaincode install fabcar.tar.gz \ --peerAddresses peer0.org1.example.com:7051 # 3. Org2 安装(需切换环境变量,指向 Org2 peer) CORE_PEER_LOCALMSPID="Org2MSP" \ CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \ CORE_PEER_ADDRESS=peer0.org2.example.com:7051 \ CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ peer lifecycle chaincode install fabcar.tar.gz

参数说明--path是链码源码路径(相对 GOPATH),--label是链码唯一标识(后续 approve 时引用),--peerAddresses必须是本组织已加入通道的 peer 地址。安装成功后,peer lifecycle chaincode queryinstalled会返回Package ID(如cc123...),该 ID 在 approve 阶段必须完全一致。

5.2 批准与提交:背书策略与 Majority 规则的强制执行

Fabric 2.0 要求至少MAJORITY组织批准后才能提交。本集群含 Org1 和 Org2,故需两者都 approve:

# 4. Org1 批准(--sequence 1 表示首个版本,--version 1.0) peer lifecycle chaincode approveformyorg \ -o orderer0.example.com:7050 \ --ordererResponseTimeout 30s \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --package-id cc123... \ --sequence 1 \ --waitForEvent \ --signature-policy "AND('Org1MSP.peer','Org2MSP.peer')" \ --peerAddresses peer0.org1.example.com:7051 # 5. Org2 批准(同样参数,仅改 peer 地址) CORE_PEER_LOCALMSPID="Org2MSP" \ CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \ CORE_PEER_ADDRESS=peer0.org2.example.com:7051 \ CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ peer lifecycle chaincode approveformyorg \ -o orderer0.example.com:7050 \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --package-id cc123... \ --sequence 1 \ --signature-policy "AND('Org1MSP.peer','Org2MSP.peer')" \ --peerAddresses peer0.org2.example.com:7051 # 6. 查询批准状态(确认两者都为 true) peer lifecycle chaincode checkcommitreadiness \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --sequence 1 \ --output json # 输出应含 "Org1MSP": {"Approve": true}, "Org2MSP": {"Approve": true} # 7. 提交链码(由任一组织执行,需指定所有批准组织) peer lifecycle chaincode commit \ -o orderer0.example.com:7050 \ --channelID mychannel \ --name fabcar \ --version 1.0 \ --sequence 1 \ --peerAddresses peer0.org1.example.com:7051 \ --peerAddresses peer0.org2.example.com:7051 \ --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

关键逻辑--signature-policy定义链码调用时的背书策略(此处要求 Org1 和 Org2 的 peer 共同签名),checkcommitreadiness是提交前的强制校验,commit命令中的--peerAddresses必须列出所有已 approve 的组织 peer,且--tlsRootCertFiles需提供对应组织的 CA 证书。提交成功后,peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 9:15:53

Java开发者转型AI:路径、挑战与实战策略

1. 从Java到AI的转型路径解析作为一位经历过Java全栈开发转型AI领域的技术人&#xff0c;我深刻理解这种技术栈跨越的挑战与机遇。Java开发者向AI领域转型并非简单的语言切换&#xff0c;而是思维模式和技术体系的全面升级。2018年我主导的智能推荐系统项目&#xff0c;就是通过…

作者头像 李华
网站建设 2026/9/19 9:13:42

物元可拓评价法Excel模板:多指标决策分析利器

1. 项目概述物元可拓评价法作为一种新兴的多指标综合评价方法&#xff0c;近年来在工程管理、经济决策、环境评估等领域获得了广泛应用。与传统评价方法相比&#xff0c;它能够更好地处理定性指标与定量指标的统一评价问题&#xff0c;尤其擅长解决评价指标间存在矛盾冲突的复杂…

作者头像 李华
网站建设 2026/9/19 9:11:50

NetAssist网络调试助手实战指南:TCP/UDP通信调试与排坑技巧

做嵌入式开发和上位机联调的朋友&#xff0c;肯定离不开网络调试助手。我自己的Windows里常年放着NetAssist这个网络调试助手&#xff0c;别看它界面土&#xff0c;调试TCP和UDP通信时是真的顺手。今天我就把在Windows上从安装到实际调试设备的完整经验写出来&#xff0c;包括那…

作者头像 李华
网站建设 2026/9/19 9:09:31

单招计算机基础题库高效复习:PDF拆分与错题管理指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华