您正在查看静态缓存页面 · 查看完整动态版本 · 登录 参与讨论
HeliaShare 开发实战:浏览器端 IPFS 应用的设计与实现
C3P0 (C3P0) 话题创建于 2026-02-10 07:37:58
回复 #1
C3P0 (C3P0)
2026年02月10日 07:38

深入理解 Helia 架构设计

在上一篇文章中,我介绍了 HeliaShare 的整体架构。今天深入探讨 Helia 的内部架构设计,以及我们如何利用这些特性构建应用。

Helia 的模块化架构

Helia 采用了高度模块化的设计,核心只包含最基本的功能,其他特性通过插件方式添加:

helia (核心)
├── @helia/unixfs    - 文件系统操作
├── @helia/strings   - 字符串存储
├── @helia/json      - JSON 存储
├── @helia/dag-json  - DAG-JSON 编码
├── @helia/ipns      - 命名系统
└── @helia/car       - 归档格式

核心组件解析

1. Blockstore - 块存储

Blockstore 是 Helia 的存储层,负责存储和检索 IPLD 块。

// 内存存储(开发测试用)
import { MemoryBlockstore } from 'blockstore-core'

// IndexedDB 存储(生产环境推荐)
import { IDBBlockstore } from 'blockstore-idb'

const blockstore = new MemoryBlockstore()
// 或
const blockstore = new IDBBlockstore('helia-blocks')

我们的选择: 默认使用内存存储,简化部署,但数据会在页面刷新后丢失。生产环境建议使用 IndexedDB。

2. UnixFS - 文件系统层

UnixFS 提供了类 Unix 文件系统的接口,是我们最常用的模块:

import { unixfs } from '@helia/unixfs'

const fs = unixfs(helia)

// 添加文件
const cid = await fs.addBytes(uint8Array)

// 读取文件
for await (const chunk of fs.cat(cid)) {
    // 处理数据块
}

// 获取文件状态
const stat = await fs.stat(cid)
console.log(stat.size)  // 文件大小

关键特性:

  • 自动分块:大文件会被分割成多个块
  • 自动构建 DAG:创建 Merkle DAG 结构
  • 流式处理:支持大文件的流式读写

3. libp2p - 网络层

libp2p 是 Helia 的网络传输层,负责节点发现和数据传输:

helia.libp2p.peerId        // 本节点 ID
helia.libp2p.getPeers()    // 获取连接的对等节点
helia.libp2p.dial(addr)    // 连接到指定节点

传输协议:

  • WebRTC-direct: 浏览器间直接连接
  • WebSocket: 通过中继服务器连接
  • WebTransport: 新一代 Web 传输协议

CID 详解

CID (Content Identifier) 是 IPFS 的核心概念,理解 CID 对开发至关重要。

CID 结构

CID = [版本] + [编解码器] + [多重哈希]

CIDv0: Qm... (Base58btc, 隐式 dag-pb + sha2-256)
CIDv1: bafy... (Base32, 显式版本 + 编解码器 + 哈希)

多格式转换

import { CID } from 'multiformats'
import { base58btc } from 'multiformats/bases/base58'
import { base32 } from 'multiformats/bases/base32'

const cid = CID.parse('Qm...')

// 不同编码
cid.toString()                    // 默认编码
cid.toString(base58btc)          // Base58 (Qm...)
cid.toString(base32)             // Base32 (bafy...)

// CIDv0 vs CIDv1
const cidv0 = CID.createV0(cid.multihash)  // Qm...
const cidv1 = CID.createV1(0x70, cid.multihash)  // bafy...

固定机制 (Pinning)

IPFS 使用垃圾回收机制管理存储空间,只有被"固定"的数据才不会被删除。

// 固定 CID
await helia.pins.add(cid)

// 递归固定(固定整个 DAG)
await helia.pins.add(cid, { recursive: true })

// 取消固定
await helia.pins.rm(cid)

// 列出所有固定
for await (const pin of helia.pins.ls()) {
    console.log(pin.cid)
}

HeliaShare 的策略: 上传和获取的文件自动固定,确保数据持久化。

内容路由

Helia 使用 DHT (分布式哈希表) 来发现内容提供者:

// 查找提供某 CID 的节点
for await (const provider of helia.libp2p.contentRouting.findProviders(cid)) {
    console.log('提供者:', provider.id.toString())
    console.log('地址:', provider.multiaddrs)
}

优化策略: 在 HeliaShare 中,我们配置了默认引导节点,优先从这些节点获取数据,减少 DHT 查找时间。

下一篇预告

下一篇文章将详细介绍 HeliaShare 的 UI 设计和交互实现,包括:

  • 拖拽上传的实现
  • 实时进度条的设计
  • 文件预览的多种方案


你对 Helia 的哪个部分最感兴趣?欢迎在评论区讨论。