目录
  1. 1. 一、Hyperledger 项目家族概览
    1. 1.1. 1.1 Hyperledger Fabric
    2. 1.2. 1.2 Hyperledger Burrow
    3. 1.3. 1.3 Hyperledger Iroha
    4. 1.4. 1.4 Hyperledger Sawtooth
    5. 1.5. 1.5 其他项目
  2. 2. 二、Hyperledger Fabric 系统架构
    1. 2.1. 2.1 核心组件
    2. 2.2. 2.2 成员服务提供者(MSP)
  3. 3. 三、交易流程详解
    1. 3.1. 3.1 交易全生命周期
    2. 3.2. 3.2 读写集与 MVCC 版本控制
    3. 3.3. 3.3 背书策略
  4. 4. 四、Chaincode(智能合约)
    1. 4.1. 4.1 Chaincode 生命周期
    2. 4.2. 4.2 Chaincode API 详解
    3. 4.3. 4.3 私有数据集合(Private Data Collections)
  5. 5. 五、排序服务(Ordering Service)
    1. 5.1. 5.1 Raft 共识实现
    2. 5.2. 5.2 区块切割参数
  6. 6. 六、Gossip 协议
  7. 7. 七、Fabric 与其他区块链对比
    1. 7.1. 7.1 Fabric vs Ethereum
    2. 7.2. 7.2 Fabric vs Bitcoin
    3. 7.3. 7.3 Fabric 的独特优势
  8. 8. 八、Fabric 网络部署实战
  9. 9. 九、Fabric 状态数据库 — CouchDB 富查询
  10. 10. 十、Fabric 性能调优建议
区块链源码分析-Hyperleger

Hyperledger(超级账本)是一个旨在推动区块链跨行业应用的开源项目,由 Linux 基金会在 2015 年 12 月主导发起,成员包括金融、银行、物联网、供应链、制造和科技行业的领头羊。

官方网站:https://www.hyperledger.org/

一、Hyperledger 项目家族概览

Hyperledger 旗下有多个区块链项目,各有侧重:

1.1 Hyperledger Fabric

Fabric 是最成熟、应用最广的 Hyperledger 项目,一个许可制的区块链架构(Permissioned Blockchain Infrastructure)。由 IBM 和 Digital Asset 最初贡献。它提供模块化的架构,把架构中的节点、智能合约执行(Fabric 中称为 chaincode)以及可配置的共识和成员服务解耦。

1.2 Hyperledger Burrow

Burrow 是一个包含 “built-to-specification” 以太坊虚拟机的区块链客户端。主要由 Monax 贡献,并由 Monax 和英特尔赞助。支持 Solidity 智能合约,适合需要 EVM 兼容性的联盟链场景。

1.3 Hyperledger Iroha

Iroha 是一个基于 Hyperledger Fabric 主要面向移动应用的协议,由 Soramitsu 贡献。特点是简单、易用,提供丰富的客户端库(iOS、Android、JavaScript)。

1.4 Hyperledger Sawtooth

由 Intel 贡献的 Sawtooth 利用一种新型共识机制称为时间流逝证明(Proof of Elapsed Time),它是一种基于可信执行环境的彩票设计模式的共识协议,由英特尔的 Software Guard Extensions (SGX) 提供。Sawtooth 还支持动态共识切换(通过 transaction family 机制)。

1.5 其他项目

  • Hyperledger Indy:专注于去中心化身份管理(Self-Sovereign Identity)
  • Hyperledger Besu:以太坊客户端,支持私有网络和许可制网络
  • Hyperledger Cactus:区块链互操作框架
  • Hyperledger Cello:区块链即服务(BaaS)管理平台

二、Hyperledger Fabric 系统架构

2.1 核心组件

Fabric 网络的四个核心角色:

┌──────────┐ ┌──────────┐ ┌──────────┐
│ Peer │────▶│ Orderer │────▶│ Peer │
│ (Endorser)│ │ (排序服务)│ │(Committer)│
└──────────┘ └──────────┘ └──────────┘
▲ │
│ ┌──────────┐ │
└────────────│ CA │──────────┘
│(证书颁发) │
└──────────┘

┌──────┴──────┐
│ Client SDK │
│ (应用程序) │
└─────────────┘

各角色职责:

1. Peer(对等节点):
- Endorsing Peer: 执行 chaincode 并签名背书交易
- Committing Peer: 验证交易并更新账本
- 每个 Peer 维护完整的账本副本和状态数据库

2. Orderer(排序节点):
- 对交易排序,打包成区块
- 将区块广播给所有 Peer
- 不执行 chaincode,不访问账本状态
- 确保全网的交易顺序一致

3. CA (Certificate Authority):
- 发放和管理 X.509 数字证书
- 验证成员身份和角色
- 支持中间 CA 和证书撤销列表(CRL)

4. Client SDK:
- 应用程序通过 SDK 与 Fabric 网络交互
- 构造交易提案、收集背书、提交交易

2.2 成员服务提供者(MSP)

MSP(Membership Service Provider)是 Fabric 中管理身份和权限的核心组件:

MSP 的层级结构:

Network MSP
├── Organization MSP 1
│ ├── Admin Certificates(管理员证书)
│ ├── Peer Certificates(节点证书)
│ ├── Client Certificates(客户端证书)
│ └── TLS Certificates(TLS 证书)
├── Organization MSP 2
│ └── ...
└── Orderer MSP
└── ...

MSP 目录结构(本地 MSP):
msp/
├── admincerts/ # 管理员 X.509 证书
│ └── admin.pem
├── cacerts/ # 根 CA 证书
│ └── ca.pem
├── intermediatecerts/ # 中间 CA 证书(可选)
├── signcerts/ # 节点自身签名证书
│ └── peer.pem
├── keystore/ # 节点私钥
│ └── priv_sk
├── tlscacerts/ # TLS 根 CA 证书
│ └── tls-ca.pem
└── config.yaml # MSP 配置(OU 标识符等)

MSP 配置文件示例:

# config.yaml
NodeOUs:
Enable: true
ClientOUIdentifier:
Certificate: cacerts/ca.pem
OrganizationalUnitIdentifier: client
PeerOUIdentifier:
Certificate: cacerts/ca.pem
OrganizationalUnitIdentifier: peer
AdminOUIdentifier:
Certificate: cacerts/ca.pem
OrganizationalUnitIdentifier: admin
OrdererOUIdentifier:
Certificate: cacerts/ca.pem
OrganizationalUnitIdentifier: orderer

三、交易流程详解

Fabric 的交易流程是实现许可链高性能和私密性的核心设计。它采用了”执行-排序-验证”(Execute-Order-Validate)的三阶段架构,与传统区块链的”排序-执行”(Order-Execute)架构相反。

3.1 交易全生命周期

完整交易流程(以一次转账为例):

Phase 1: Proposal(提案阶段)
Client → Endorsing Peers:
1. Client 创建交易提案(调用 chaincode 函数名和参数)
2. Client 将提案签名后发送给指定的背书节点(按背书策略)

Phase 2: Endorsement(背书阶段)
Endorsing Peers:
3. 验证 Client 身份和权限
4. 模拟执行 chaincode(读写集记录在本地,不更新账本)
5. 生成 Read-Write Set:
- Read Set: {key: version}
- Write Set: {key: new_value}
6. 对执行结果签名 → 返回背书响应(Proposal Response)

Phase 3: Submission(提交阶段)
Client:
7. 收集足够的背书(满足背书策略)
8. 将交易(包含读写集和所有背书签名)发送给 Orderer

Phase 4: Ordering(排序阶段)
Orderer:
9. 验证交易格式和签名
10. 对所有通道的交易进行排序
11. 按区块打包(满足 BatchSize 或 BatchTimeout 条件)
12. 将区块广播给通道内所有 Committing Peers

Phase 5: Validation(验证阶段)
Committing Peers:
13. 验证每个交易的背书策略是否满足
14. 验证读写集的版本冲突:
- Read Set 的 version 必须与当前状态一致
- 如果不一致(另一个交易已修改了相同的 key)→ 标记为无效
15. 将有效交易的 Write Set 写入状态数据库
16. 将整个区块(含有效和无效交易)追加到区块链账本

Phase 6: Notification(通知阶段)
17. Client 注册的事件监听器收到交易完成通知
18. 如果注册了 block event,收到新区块通知

3.2 读写集与 MVCC 版本控制

Fabric 使用多版本并发控制(MVCC)解决并发执行的冲突问题:

// Chaincode 执行时的读写集结构(简化 Go 伪代码)

type TxReadWriteSet struct {
// 命名空间(chaincode 名称)→ 读写集
NsRwSets []*NsReadWriteSet
}

type NsReadWriteSet struct {
Namespace string // chaincode 名称
Reads []*KVRead // 读集
Writes []*KVWrite // 写集
RangeQueriesInfo []*RangeQueryInfo // 范围查询信息
}

type KVRead struct {
Key string
Version *Height // BlockNum + TxNum,唯一标识状态版本
}

type KVWrite struct {
Key string
IsDelete bool
Value []byte
}

type Height struct {
BlockNum uint64
TxNum uint64
}

// MVCC 验证逻辑(Commit 阶段)
func (v *Validator) ValidateMVCC(tx *Transaction) bool {
for _, read := range tx.ReadSet {
currentVersion := v.stateDB.GetVersion(read.Key)
// 检查版本是否一致
if !currentVersion.Equals(read.Version) {
// 版本不匹配 → 读到的数据已被其他交易修改
tx.MarkAsInvalid(TxValidationCode_MVCC_READ_CONFLICT)
return false
}
}
return true
}

MVCC 冲突场景示例:

状态初始: key="balance", version={BlockNum:5, TxNum:0}, value=100

交易 A(Client A): 读取 balance → 增加 50
交易 B(Client B): 读取 balance → 减少 30

两者同时执行(在同一个区块中):
Read Set A: {key:"balance", version:{5,0}}
Write Set A: {key:"balance", value:150}

Read Set B: {key:"balance", version:{5,0}}
Write Set B: {key:"balance", value:70}

Orderer 将两个交易放入同一区块(Block 6):
Block 6, Tx 0: 交易 A → 版本匹配 ✓ → 成功(balance = 150, version = {6,0})
Block 6, Tx 1: 交易 B → 读版本 {5,0} ≠ 当前版本 {6,0} ✗ → MVCC 冲突,标记无效

结果:只有交易 A 生效。交易 B 虽然被记录在区块链上,但状态更新被拒绝。

3.3 背书策略

背书策略定义了哪些组织的 Peer 需要为交易背书:

// 背书策略语法示例

// AND 策略:需要 Org1 和 Org2 的 Peer 同时背书
AND('Org1MSP.member', 'Org2MSP.member')

// OR 策略:Org1 或 Org2 任一的 Peer 背书即可
OR('Org1MSP.member', 'Org2MSP.member')

// NOutOf 策略:需要 Org1, Org2, Org3 中至少 2 个背书
OutOf(2, 'Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member')

// 更复杂的组合
OR(
AND('Org1MSP.member', 'Org2MSP.member'),
OutOf(2, 'Org3MSP.member', 'Org4MSP.member', 'Org5MSP.member')
)

// Chaincode 级别的背书策略
// 在链码定义时指定(configtx.yaml 或在 chaincode lifecycle approve 时)

四、Chaincode(智能合约)

4.1 Chaincode 生命周期

Fabric 2.x 的 Chaincode 生命周期(无需系统级 Chaincode):

Install:
peer lifecycle chaincode install mycc.tar.gz
各组织的 Peer 将链码包安装到本地文件系统

Approve(组织级批准):
peer lifecycle chaincode approveformyorg \
--channelID mychannel --name mycc --version 1.0 \
--package-id mycc:hash123 --sequence 1 \
--signature-policy "AND('Org1MSP.member','Org2MSP.member')"
每个组织独立批准链码定义(背书策略、初始化要求等)

Commit(提交到通道):
peer lifecycle chaincode commit \
--channelID mychannel --name mycc --version 1.0 --sequence 1
当足够数量的组织批准后,一个组织将链码定义提交到通道

Invoke / Query(调用 / 查询):
peer chaincode invoke -C mychannel -n mycc -c '{"Args":["transfer","A","B","100"]}'
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","A"]}'

4.2 Chaincode API 详解

package main

import (
"encoding/json"
"fmt"

"github.com/hyperledger/fabric-contract-api-go/contractapi"
)

// SmartContract 提供资产管理逻辑
type SmartContract struct {
contractapi.Contract
}

// Asset 描述基本资产
type Asset struct {
ID string `json:"id"`
Owner string `json:"owner"`
Value int `json:"value"`
}

// InitLedger 初始化账本(可选)
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
assets := []Asset{
{ID: "asset1", Owner: "Alice", Value: 100},
{ID: "asset2", Owner: "Bob", Value: 200},
}
for _, asset := range assets {
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
err = ctx.GetStub().PutState(asset.ID, assetJSON)
if err != nil {
return fmt.Errorf("failed to put state: %v", err)
}
}
return nil
}

// CreateAsset 创建新资产
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface,
id string, owner string, value int) error {

// 检查资产是否已存在
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("asset %s already exists", id)
}

asset := Asset{ID: id, Owner: owner, Value: value}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

return ctx.GetStub().PutState(id, assetJSON)
}

// ReadAsset 读取资产
func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface,
id string) (*Asset, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return nil, fmt.Errorf("failed to read state: %v", err)
}
if assetJSON == nil {
return nil, fmt.Errorf("asset %s does not exist", id)
}

var asset Asset
err = json.Unmarshal(assetJSON, &asset)
if err != nil {
return nil, err
}
return &asset, nil
}

// TransferAsset 转让资产
func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface,
id string, newOwner string) error {
asset, err := s.ReadAsset(ctx, id)
if err != nil {
return err
}

asset.Owner = newOwner
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

return ctx.GetStub().PutState(id, assetJSON)
}

// DeleteAsset 删除资产
func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface,
id string) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("asset %s does not exist", id)
}
return ctx.GetStub().DelState(id)
}

// GetHistoryForKey 查询某 key 的所有历史修改记录
func (s *SmartContract) GetHistory(ctx contractapi.TransactionContextInterface,
id string) ([]string, error) {

resultsIterator, err := ctx.GetStub().GetHistoryForKey(id)
if err != nil {
return nil, err
}
defer resultsIterator.Close()

var history []string
for resultsIterator.HasNext() {
response, err := resultsIterator.Next()
if err != nil {
return nil, err
}
history = append(history, fmt.Sprintf(
"TxID: %s, Value: %s, Timestamp: %v, IsDelete: %v",
response.TxId, string(response.Value),
response.Timestamp, response.IsDelete,
))
}
return history, nil
}

// GetAllAssets 范围查询所有资产(使用富查询需启用 CouchDB)
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) {
resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil {
return nil, err
}
defer resultsIterator.Close()

var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
var asset Asset
err = json.Unmarshal(queryResponse.Value, &asset)
if err != nil {
return nil, err
}
assets = append(assets, &asset)
}
return assets, nil
}

// AssetExists 检查资产是否存在
func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface,
id string) (bool, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return false, fmt.Errorf("failed to read state: %v", err)
}
return assetJSON != nil, nil
}

// 核心 Ledger API 汇总:
// GetState(key) → ([]byte, error) — 读取 key 的当前值
// PutState(key, value) → error — 写入 key 的值
// DelState(key) → error — 删除 key
// GetStateByRange(startKey, endKey) → iterator — 范围查询
// GetHistoryForKey(key) → iterator — 历史查询
// GetQueryResult(query) → iterator — 富查询(需 CouchDB)
// GetPrivateDataHash(collection, key) → ([]byte, error) — 获取私有数据哈希

func main() {
chaincode, err := contractapi.NewChaincode(&SmartContract{})
if err != nil {
fmt.Printf("Error creating chaincode: %v", err)
return
}
if err := chaincode.Start(); err != nil {
fmt.Printf("Error starting chaincode: %v", err)
}
}

4.3 私有数据集合(Private Data Collections)

私有数据允许通道内的部分组织共享数据,而其他组织仅能看到数据存在的证明(哈希值):

// collections_config.json
[
{
"name": "assetPrivateDetails",
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
"requiredPeerCount": 1,
"maxPeerCount": 2,
"blockToLive": 100,
"memberOnlyRead": true,
"memberOnlyWrite": true,
"endorsementPolicy": {
"signaturePolicy": "OR('Org1MSP.member', 'Org2MSP.member')"
}
},
{
"name": "assetPriceDetails",
"policy": "OR('Org2MSP.member')",
"requiredPeerCount": 1,
"maxPeerCount": 1,
"blockToLive": 0, // 0 表示永不删除
"memberOnlyRead": true
}
]

私有数据读写流程:

写入私有数据:
1. Client 提交交易提案给授权组织的 Peer
2. Chaincode 调用 ctx.GetStub().PutPrivateData(collection, key, value)
3. 私有数据存储在 Peer 的私有状态数据库(SideDB)中
4. 私有数据的哈希值写入公共账本(通过 gossip 协议传播给所有 Peer)

读取私有数据:
1. Client 必须是授权组织的成员
2. Chaincode 调用 ctx.GetStub().GetPrivateData(collection, key)
3. 从本地 Peer 的 SideDB 读取数据

跨组织共享:
- 通过 Gossip 协议在授权组织之间传播私有数据
- 非授权组织的 Peer 只能验证哈希匹配,但不能查看数据内容

五、排序服务(Ordering Service)

5.1 Raft 共识实现

Fabric 从 v1.4.1 开始推荐使用 Raft 作为排序服务的共识机制(替代早期的 Kafka 和 Solo 模式):

Raft 排序服务架构:

Orderer 集群 = 多个 Raft 节点
┌──────────────┐
│ Orderer 1 │──┐
│ (Leader) │ │
└──────────────┘ │ Raft 共识
┌──────────────┐ │ (日志复制 + 领导者选举)
│ Orderer 2 │──┤
│ (Follower) │ │
└──────────────┘ │
┌──────────────┐ │
│ Orderer 3 │──┘
│ (Follower) │
└──────────────┘

每个应用通道运行一个独立的 Raft 实例(每个通道有各自的 Raft 日志)
不同通道的 Leader 可以分布在不同的 Orderer 节点上(负载均衡)

每个通道独立的 Raft 实例:

Channel A:  Leader = Orderer1, Followers = Orderer2, Orderer3
Channel B: Leader = Orderer2, Followers = Orderer1, Orderer3
Channel C: Leader = Orderer3, Followers = Orderer1, Orderer2

这自然实现了负载均衡,无需外部负载均衡器

5.2 区块切割参数

# configtx.yaml 中的 Orderer 配置片段
Orderer: &OrdererDefaults
OrdererType: etcdraft
Addresses:
- orderer1.example.com:7050
- orderer2.example.com:7050
- orderer3.example.com:7050

BatchTimeout: 2s # 超过 2 秒未满 → 切割区块
BatchSize:
MaxMessageCount: 500 # 每个区块最多 500 条交易
AbsoluteMaxBytes: 10 MB # 区块大小硬上限
PreferredMaxBytes: 2 MB # 优先达到的区块大小(达到即切割)

# 区块切割条件:
# 1. 交易数 >= MaxMessageCount → 立即切割
# 2. 区块大小 >= PreferredMaxBytes → 立即切割
# 3. 时间 >= BatchTimeout → 至少有一笔交易时切割
# 4. 区块大小 >= AbsoluteMaxBytes → 强制切割(可能会拆分大交易)

EtcdRaft:
Consenters:
- Host: orderer1.example.com
Port: 7050
ClientTLSCert: path/to/cert1.pem
ServerTLSCert: path/to/cert1.pem
- Host: orderer2.example.com
Port: 7050
ClientTLSCert: path/to/cert2.pem
ServerTLSCert: path/to/cert2.pem
- Host: orderer3.example.com
Port: 7050
ClientTLSCert: path/to/cert3.pem
ServerTLSCert: path/to/cert3.pem
Options:
TickInterval: 500ms
ElectionTick: 10 # 5 秒无心跳 → 触发选举
HeartbeatTick: 1 # 500ms 一次心跳
MaxInflightBlocks: 5 # 最大未完成的区块请求
SnapshotIntervalSize: 16 MB # 日志快照间隔

六、Gossip 协议

Gossip 协议是 Fabric 中 Peer 之间同步状态的机制,实现了去中心化、高容错的消息传播:

Gossip 协议的工作机制:

1. Membership(成员发现):
- 每个 Peer 维护邻居 Peer 列表
- 定期向随机邻居发送 Alive 消息(心跳)
- 通过邻居的邻居列表发现新节点
- 节点故障时通过"疑似死亡"→"确认死亡"机制传播

2. State Dissemination(状态传播):
- 区块通过 Gossip 在 Peer 之间传播
- 收到新区块 → 验证 → 存储 → 随机转发给 N 个邻居
- 如果本地缺失某些区块 → 向邻居请求(pull 机制)

3. Leader Election(领导者选举):
- 每个组织选举一个 Leader Peer
- Leader 负责从 Orderer 拉取新区块
- 其他 Peer 通过 Gossip 从 Leader 获取区块
- 避免所有 Peer 都连接 Orderer(可扩展性)

Gossip 消息类型:
- AliveMsg: 心跳消息(节点存活证明)
- MembershipRequest/Response: 成员查询
- DataMsg: 区块数据
- DataRequest: 数据请求
- StateInfo: 账本高度信息
- LeadershipMessage: 领导者声明

七、Fabric 与其他区块链对比

7.1 Fabric vs Ethereum

维度 Hyperledger Fabric Ethereum
网络类型 许可制(Permissioned) 无需许可(Permissionless)
身份管理 MSP (X.509 证书) 匿名公钥地址
共识机制 Raft / PBFT(可插拔) PoS (Casper)
智能合约 Chaincode (Go/Java/JS) Solidity
交易模型 Execute-Order-Validate Order-Execute
最终性 绝对最终(一旦 commit 即不可逆) 概率性最终(需等待确认)
数据隐私 通道 + 私有数据集合 所有数据公开
吞吐量 数千 TPS 30 TPS (L1)
代币 无内置代币 ETH
适用场景 企业联盟链(供应链、金融) 公链 DApp

7.2 Fabric vs Bitcoin

维度 Hyperledger Fabric Bitcoin
共识 Raft/CFT PoW (Nakamoto)
区块时间 < 1 秒(可配置) ~10 分钟
交易模型 账户模型(链码状态) UTXO
确定性 是(交易执行结果确定) 否(脚本执行结果取决于上下文)
能源消耗 极低(无挖矿) 极高
治理 联盟治理 社区治理(BIP)
升级 通道配置更新 软分叉/硬分叉

7.3 Fabric 的独特优势

  1. 通道隔离:不同通道的数据完全隔离(包括账本、链码、共识),提供内置的多租户能力
  2. 可插拔性:共识机制、身份管理、状态数据库(LevelDB/CouchDB)均可按需替换
  3. 无内置代币:适合企业场景,无需考虑代币经济模型
  4. 私密交易:通过私有数据集合实现组织间的选择性数据共享
  5. 高性能:并行执行 + 背书-排序-验证分离架构,支持数千 TPS
  6. 丰富的 SDK:Go、Node.js、Java、Python 等多语言支持

八、Fabric 网络部署实战

# === 使用 Fabric 测试网络快速开始 ===

# 1. 克隆 Fabric 示例仓库
git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples/test-network

# 2. 启动测试网络(2 个组织,每个 1 个 Peer,1 个 Raft Orderer)
./network.sh up -ca -s couchdb
# -ca: 使用 Fabric CA 作为证书颁发机构
# -s couchdb: 使用 CouchDB 作为状态数据库(支持富查询)

# 3. 创建通道
./network.sh createChannel -c mychannel

# 4. 部署 Chaincode(以 asset-transfer-basic 为例)
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go \
-ccl go -ccep "AND('Org1MSP.member','Org2MSP.member')"

# 5. 设置环境变量以与网络交互
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

# 6. 调用 Chaincode
# InitLedger
peer chaincode invoke -o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" \
-C mychannel -n basic \
--peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" \
--peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" \
-c '{"function":"InitLedger","Args":[]}'

# ReadAsset
peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset1"]}'

# 7. 关闭网络
./network.sh down

九、Fabric 状态数据库 — CouchDB 富查询

Fabric 支持两种状态数据库:LevelDB(默认,键值存储)和 CouchDB(文档存储,支持 JSON 富查询)。

// CouchDB 富查询示例(Chaincode 内)
func (s *SmartContract) QueryAssetsByOwner(
ctx contractapi.TransactionContextInterface,
owner string) ([]*Asset, error) {

// CouchDB 查询语法(类似 MongoDB)
queryString := fmt.Sprintf(
`{"selector":{"owner":"%s"}}`, owner)

resultsIterator, err := ctx.GetStub().GetQueryResult(queryString)
if err != nil {
return nil, fmt.Errorf("failed to query: %v", err)
}
defer resultsIterator.Close()

var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
var asset Asset
err = json.Unmarshal(queryResponse.Value, &asset)
if err != nil {
return nil, err
}
assets = append(assets, &asset)
}
return assets, nil
}

// 复杂查询示例:分页 + 排序 + 组合条件
func (s *SmartContract) QueryWithPagination(
ctx contractapi.TransactionContextInterface,
pageSize int32, bookmark string) ([]*Asset, string, error) {

queryString := `{
"selector": {
"value": {"$gt": 100},
"owner": {"$regex": ".*"}
},
"sort": [{"value": "desc"}]
}`

resultsIterator, metadata, err := ctx.GetStub().GetQueryResultWithPagination(
queryString, pageSize, bookmark)
if err != nil {
return nil, "", err
}
defer resultsIterator.Close()

var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, "", err
}
var asset Asset
json.Unmarshal(queryResponse.Value, &asset)
assets = append(assets, &asset)
}
return assets, strconv.Itoa(int(metadata.FetchedRecordsCount)), nil
}

十、Fabric 性能调优建议

  1. 区块大小与超时:根据交易频率调整 BatchSize 和 BatchTimeout,高频交易减小超时,低频交易增大超时以避免空区块
  2. CouchDB 索引:对频繁查询的字段建立 CouchDB 索引(放在 chaincode 目录的 META-INF 中)
  3. Gossip 配置:调整 peer.gossip.endpoint 和 anchor peers 以优化消息传播路径
  4. 并行验证:利用 Fabric 的多核能力进行交易并行验证
  5. 私有数据清理:设置 blockToLive 及时清理过期私有数据,控制 SideDB 大小
  6. Orderer 部署:Orderer 节点分布在不同的物理/云区域以提高容灾能力

Hyperledger Fabric 以其模块化架构、许可制网络模型、”执行-排序-验证”的独特交易范式,在联盟链领域建立了标志性的技术方案。相比以太坊等公链,Fabric 在企业所需的身份管理、数据隐私、高性能方面有显著优势。理解 Fabric 的交易流程、Chaincode 编程模型、MSP 身份管理和排序服务,是掌握联盟链架构设计的关键。随着 Hyperledger 生态的不断扩展(Besu、Cactus、FireFly 等),Fabric 在供应链金融、跨境贸易、数字身份等领域的应用将持续深化。

文章作者: Leo·Cheung
文章链接: http://tufusi.com/2020/12/10/%E5%8C%BA%E5%9D%97%E9%93%BE%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-Hyperleger/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ONE·PIECE
打赏
  • 微信
  • 支付宝

评论