@chainsafe/persistent-merkle-tree

中文文档
1.3.1发布于 2026/08/18Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 50.6万

默克勒树作为持续的数据结构执行

中文使用文档
文档目录6 节
  1. 示例
  2. 动机
  3. 特征
  4. 另见:
  5. 审计
  6. 许可证

持久默克勒树

ES Version Node Version

二进制墨克勒树 持续的数据结构。 。 。 .

示例


// LeafNode and BranchNode are used to build nodes in a tree
// Nodes may not be changed once initialized

import {LeafNode, BranchNode} from "@chainsafe/persistent-merkle-tree";

const leaf = LeafNode.fromRoot(Buffer.alloc(32, 0xaa));
const otherLeaf = LeafNode.fromRoot(Buffer.alloc(32, 0xbb));

const branch = new BranchNode(leaf, otherLeaf);

// The `root` property returns the merkle root of a Node

// this is equal to `hash(leaf.root, otherLeaf.root));`
const r: Uint8Array = branch.root;

// The `isLeaf` method returns true if the Node is a LeafNode

branch.isLeaf() === false;
leaf.isLeaf() === true;

// Well-known zero nodes are provided

import {zeroNode} from "@chainsafe/persistent-merkle-tree";

// 0x0
const zero0 = zeroNode(0);

// hash(0, 0)
const zero1 = zeroNode(1);

// hash(hash(0, 0), hash(0, 0))
const zero1 = zeroNode(2);

// Tree provides a mutable wrapper around a "root" Node

import {Tree} from "@chainsafe/persistent-merkle-tree";

const tree = new Tree(zeroNode(10));

// `rootNode` property returns the root Node of a Tree

const rootNode: Node = tree.rootNode;

// `root` property returns the merkle root of a Tree

const rr: Uint8Array = tree.root;

// A Tree is navigated by Gindex

const gindex = BigInt(...);

const n: Node = tree.getNode(gindex); // the Node at gindex
const rrr: Uint8Array = tree.getRoot(gindex); // the Uint8Array root at gindex
const subtree: Tree = tree.getSubtree(gindex); // the Tree wrapping the Node at gindex. Updates to `subtree` will be propagated to `tree`

// A merkle proof for a gindex can be generated

const proof: Uint8Array[] = tree.getSingleProof(gindex);

// Multiple types of proofs are supported through the `getProof` interface

// For example, a multiproof for multiple gindices can be generated like so

import {ProofType} from "@chainsafe/persistent-merkle-tree";

const gindices: BigInt[] = [...];

const proof: Proof = tree.getProof({
  type: ProofType.treeOffset,
  gindices,
});

// `Proof` objects can be used to recreate `Tree` objects
// These `Tree` objects can be navigated as usual for all nodes contained in the proof
// Navigating to unknown/unproven nodes results in an error

const partialTree: Tree = Tree.createFromProof(proof);

const unknownGindex: BigInt = ...;

gindices.includes(unknownGindex) // false

partialTree.getRoot(unknownGindex) // throws

动机

在处理大型数据集时,将数据集整体化是非常昂贵的. 在大数据集在更新和添加之间经常被重现的情况下,使用等离子结构来进行中间散列,导致大量重复工作,因为许多中间散列会被重编并丢弃在每次分解上. 在这些情况下,维持整个树的结构,包括中间节点,可以减轻这些问题并允许额外的用例(例如:证明生成). 这一执行还利用了已知的节点的不可变能性,在不同版本数据的共同子树之间共享数据.

特征

中间节点有缓存和懒散计算散列

该树作为连接的树被代表 Nodes,目前为 BranchNodes 或 (简体中文) LeafNode编号. A 类 BranchNode 有一个 left 财务报告和审定财务报表 right 儿童 Node,则a root, 32 字节 Uint8Array。 。 。 . A 类 LeafNode 有一个 root。 。 。 . 这个 root 页:1 Node 在请求之前不计算,然后缓存.

共享数据 betwen 常见子树

对一棵树的任何更新(无论是叶子还是中间节点)都是作为再绑定的,产生出一棵新的更新树,在版本之间最大限度地共享数据. 垃圾收集使得来自未使用节点的内存最终被回收.

持久性核心的可变包装器

A 类 Tree 对象包 Node ,并提供了用于树导航的API并透明地重新约束更新.

通过gindex或(深度,索引)进行导航

许多树法允许用gindex来导航. 一个gindex(或泛指指数)描述了从根起从下而上从树上取出的一个路径.

     1
   /   \
  2     3
/  \   /  \
4  5   6  7

也可以被解释为位字符串,从"1"开始,再将"0"附加到每个导航左侧,或者将"1"附加到每个导航右侧.

        1
    /      \
   10       11
 /    \    /    \
100  101  110  111

或者,几种树法,名称以 AtDepth,允许通过(深度,索引)进行导航。 深度和索引导航通过首先从上方向下导航到树上,从0(深度)开始,从左侧索引出节点,从0(index)开始.

     0          <- depth 0
   /   \
  0     1       <- depth 1
/  \   /  \
0  1   2  3     <- depth 2

内存效率

作为执行细节,节点保持其价值 HashObject (javascript 对象为 h0,, , , , , , , , . h7 金特32号 number 而不是作为32字节 Uint8Array。内存基准显示,这导致内存减少~3x Uint8Array。这种优化可以使这个库在实际上扩展到有上百万个节点的树上.

导航效率

在表现关键应用程序中,许多对树进行读取和写作,聪明地使用树导航至关重要。 这个库正确提供了树导航方法,可以处理几个重要的优化案例:多节点获取和设置,以及得到-当时设置的操作.

另见:

https://github.com/protolambda/remerkleble (中文(简体) )

审计

这一回购额由最不发达国家管理局审计,作为 本次安全审计,于2020-03-23发布. 提交 8b5ad7 报告已核实.

许可证

阿帕奇 - 2.0

版本与发布记录

@chainsafe/persistent-merkle-tree 共发布 36 个版本,首次发布于 2020/02/11;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.3.1latest2026/08/182 个月前
1.3.02026/05/185 个月前
1.2.52026/04/216 个月前
1.2.12025/08/251.2 年前
1.2.02025/05/301.4 年前
1.0.22025/03/131.7 年前

关于 @chainsafe/persistent-merkle-tree 的常见问题

@chainsafe/persistent-merkle-tree 是什么?

默克勒树作为持续的数据结构执行

如何安装 @chainsafe/persistent-merkle-tree?

在项目目录运行 npm install @chainsafe/persistent-merkle-tree,或使用 pnpm add / yarn add / bun add。

@chainsafe/persistent-merkle-tree 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@chainsafe/persistent-merkle-tree 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@chainsafe/persistent-merkle-tree 可以商用吗?

@chainsafe/persistent-merkle-tree 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@chainsafe/persistent-merkle-tree 的下载量有多少?

根据 npm 官方下载统计,@chainsafe/persistent-merkle-tree 在 2026/10/10 – 2026/11/08 这 30 天内被下载 505,836 次,日均约 16,861 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@chainsafe/persistent-merkle-tree 还在维护吗?

最新版本 1.3.1 发布于 2026/08/18(2 个月前);至今共发布 36 个版本,其中过去 12 个月发布了 3 个;首次发布于 2020/02/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。