@ethereumjs/trie

中文文档
6.2.1发布于 2024/08/15MPL-2.0TypeScriptESM + CJS近 30 天下载 36.1万

实施伊特鲁姆"黄纸"所指明的经过改造的"墨克勒活生生树".

中文使用文档
文档目录22 节
  1. 安装
  2. 使用量
  3. 初始化和基本使用
  4. WASM 加密支持
  5. 使用静态构造器
  6. 走着走着
  7. Trie 配置选项
  8. 证据
  9. 默克勒证明
  10. 范围证明
  11. 实例
  12. 浏览器
  13. API 密码
  14. 文档
  15. 混合 CJS/ESM 构建
  16. 缓冲 - > Uint8 阵列
  17. BigInt 支持
  18. 基准制定
  19. 调试
  20. 参考资料
  21. 爱丽丝
  22. 许可证

@ethereumjs/trie (英语)

NPM Package GitHub Issues Actions Status Code Coverage Discord

执行《公约》 修改后的梅克勒·帕特里夏·特里 一、导 言 黄纸

已修改的Merkle Patricia树(trie)提供了一个持续的数据结构来映射任意长的二进制数据(字节数组). 它被定义为可变数据结构来映射出256位二元碎片和任意长二元数据之间的相去. 三相体的核心,以及它在协议规格方面的唯一要求,是提供一个单一的32字节值,以识别出一组特定的键值对.

安装

要获得最新版本,只需使用 npm数字 :

npm install @ethereumjs/trie

使用量

此类执行基本 修改后的梅克勒·帕特里夏·特里 输入 Trie 基础类,您可以使用 useKeyHashing 选项设置为 true 创建三进制,将值存储在 keccak256 它的散列键(这是Ethereum生产系统中使用的Trie口味).

检查功能到 Trie 通过方法 checkpoint, (中文(简体) ), commit 财务报告和审定财务报表 revert。 。 。 .

最好选择最适合您独有的用例的变体 .

初始化和基本使用

// ./examples/basicUsage.ts

import { Trie } from '@ethereumjs/trie'
import { bytesToUtf8, MapDB, utf8ToBytes } from '@ethereumjs/util'

async function test() {
  const trie = await Trie.create({ db: new MapDB() })
  await trie.put(utf8ToBytes('test'), utf8ToBytes('one'))
  const value = await trie.get(utf8ToBytes('test'))
  console.log(value ? bytesToUtf8(value) : 'not found') // 'one'
}

test()

WASM 加密支持

这个库默认使用 JavaScript 执行,用于像散列键一样的基本标准加密原始. 见 @ethereumjs/common 读取 如何使用共享的WASM执行器等 common 举个例子.

使用静态构造器

创建新 Trie

// ./examples/basicUsage.ts

import { Trie } from '@ethereumjs/trie'
import { bytesToUtf8, MapDB, utf8ToBytes } from '@ethereumjs/util'

async function test() {
  const trie = await Trie.create({ db: new MapDB() })
  await trie.put(utf8ToBytes('test'), utf8ToBytes('one'))
  const value = await trie.get(utf8ToBytes('test'))
  console.log(value ? bytesToUtf8(value) : 'not found') // 'one'
}

test()

当静态 Trie.create 构造器在没有任何选项的情况下使用 trie 对象被即时化,并配置出与Ethereum生产谱相匹配的默认值(即密钥被用 SHA256 散列)。 它也坚持树的状态根在每次写入操作上,确保您下次启动应用程序时的三进制保留在您离开的状态.

从一个证明创建

三进制库支持基本创建 EIP-1186 (英语) 证据以及从现有证据中即兴尝试.

下面是使用该软件的例子 Trie.createFromProof() 静态构造器。 这只根据所提供的证据中包含的三者分支,即刻宣布一个新的部分三者.

// ./examples/createFromProof.ts

import { Trie } from '@ethereumjs/trie'
import { bytesToUtf8 } from '@ethereumjs/util'
import { utf8ToBytes } from 'ethereum-cryptography/utils'

async function main() {
  const k1 = utf8ToBytes('keyOne')
  const k2 = utf8ToBytes('keyTwo')

  const someOtherTrie = new Trie({ useKeyHashing: true })
  await someOtherTrie.put(k1, utf8ToBytes('valueOne'))
  await someOtherTrie.put(k2, utf8ToBytes('valueTwo'))

  const proof = await someOtherTrie.createProof(k1)
  const trie = await Trie.createFromProof(proof, { useKeyHashing: true })
  const otherProof = await someOtherTrie.createProof(k2)

  // To add more proofs to the trie, use `updateFromProof`
  await trie.updateFromProof(otherProof)

  const value = await trie.get(k1)
  console.log(bytesToUtf8(value!)) // valueOne
  const otherValue = await trie.get(k2)
  console.log(bytesToUtf8(otherValue!)) // valueTwo
}

main()

关于进一步的证据使用文件,见下文其他文件部分.

走着走着

从v6发布开始,有一个新的API用于行走并使用Aync行走生成器来活取一个三行,现在它能够行走尝试而无需改变行走控制器,现在也能够行走一个稀疏的(没有完全填满)三行.

新的行走功能可以使用如下:

// ./examples/trieWalking.ts

import { Trie } from '@ethereumjs/trie'
import { utf8ToBytes } from 'ethereum-cryptography/utils'

async function main() {
  const trie = await Trie.create()
  await trie.put(utf8ToBytes('key'), utf8ToBytes('val'))
  const walk = trie.walkTrieIterable(trie.root())

  for await (const { node, currentKey } of walk) {
    // ... do something
    console.log({ node, currentKey })
  }
}
main()

Trie 配置选项

数据库选项

这个 DB 选择在 TrieOpts 允许您使用符合 DB 用于存储 tree 数据的界面。 我们提供几个 实例 数据库执行。 这个 职等.js 示例在 ethereumjs client 时 (日语) 是一种使用大众 语言数据库 作为其基础数据库.

若无 db 选项,由 一个 Javascript 地图 将履行这一角色(从 @ethereumjs/util,参见 映射数据库 页:1.

如果您想要使用替代数据库,可以通过写一个符合 DB 接口 (单位:千美元) @ethereumjs/util) (中文(简体) ). 这个 DB 界面定义方法 get, (中文(简体) ), put, (中文(简体) ), del, (中文(简体) ), batch 财务报告和审定财务报表 copy 具体落实《公约》 DB 接口需要执行.

级别DB

举个例子,利用 LevelDB 用于所有操作时,您应该创建文件 执行我们的食谱 在你的项目。 然后将您的 DB 和 trie 分解如下:

// ./examples/customLevelDB.ts#L127-L131

async function main() {
  const trie = new Trie({ db: new LevelDB(new Level('MY_TRIE_DB_LOCATION') as any) })
  console.log(await trie.database().db) // LevelDB { ...
}
main()

节点删除( 运行)

默认情况下,从基础数据库中删除三相节点并不会发生,以避免老三相状态腐败(截至 v4.2.0) (中文(简体) ). 如果您只希望与 trie 的最新状态合作, 您可以使用 : useNodePruning 构造器选项(详见更改日志中的相关释放注释).

根持久性

您可以通过设置 useRootPersistence 选项到 true 当建造一个三角穿行 Trie.create 函数。 因此,这个值在创建trie副本时被保存,一旦一个trie被即时修改后就无法被修改.

// ./examples/rootPersistence.ts

import { Trie } from '@ethereumjs/trie'
import { bytesToHex } from '@ethereumjs/util'

async function main() {
  const trie = await Trie.create({
    useRootPersistence: true,
  })

  // this logs the empty root value that has been persisted to the trie db
  console.log(bytesToHex(trie.root())) // 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421
}
main()

证据

默克勒证明

这个 createProof 财务报告和审定财务报表 verifyProof 函数允许您验证某个值是否存在于 Merkle Patricia 内 有给定根树.

列入证明

以下代码演示了如何构建并随后验证证实密钥存在的证据 test (与值相对应) one)在给定之三. 这也被称为"包容",因此名称为"Proof-of-incluation"

// ./examples/proofs.ts#L12-L16

// proof-of-inclusion
await trie.put(k1, v1)
let proof = await trie.createProof(k1)
let value = await trie.verifyProof(trie.root(), k1, proof)
console.log(value ? bytesToUtf8(value) : 'not found') // 'one'

排除证明

以下代码演示了如何构建并随后验证证实钥匙的证据 test3 不存在在给定的三进制中。 这也被称为排斥,因此取名"Proof-exclusion"

// ./examples/proofs.ts#L18-L23

// proof-of-exclusion
await trie.put(k1, v1)
await trie.put(k2, v2)
proof = await trie.createProof(utf8ToBytes('key3'))
value = await trie.verifyProof(trie.root(), utf8ToBytes('key3'), proof)
console.log(value ? bytesToUtf8(value) : 'null') // null

无效的证明

若为 verifyProof 检测无效的证明,它会丢出错误。 下面的例子说明了在一次验证器篡改了元数据时所产生的错误条件.

// ./examples/proofs.ts#L25-L34

// invalid proof
await trie.put(k1, v1)
await trie.put(k2, v2)
proof = await trie.createProof(k2)
proof[0].reverse()
try {
  const value = await trie.verifyProof(trie.root(), k2, proof) // results in error
} catch (err) {
  console.log(err)
}

范围证明

你可以用这个 Trie.verifyRangeProof() 函数来确认给定的叶子节点和边缘证明是否具有证明给定的三叶树叶范围与特定根相匹配的能力(例如,这有利于同步).

实例

您可以在详细解释后找到补充实例 这里。 。 。 .

浏览器

随着2023年夏季的断开发行回合,我们增加了混合无害环境管理/CJS,用于我们所有图书馆(见下文一节),并取消了以前阻止使用无摩擦浏览器的许多警告.

现在很容易在现代浏览器内运行一个EthereumJS图书馆的浏览器构建,使用所提供的无害环境管理构建。 关于设置的例子,见 ./例/浏览器.html。 。 。 .

API 密码

文档

生成类型Doc API 文档

混合 CJS/ESM 构建

随着2023年夏季发行的中断,我们开始将我们的图书馆与两个共同JS(共同JS)一起运送cjs 和建立无害环境管理esm 文件夹,参见 package.json 为详细设置.

如果你使用ES6型的话 import 将在您来自无害环境管理架构的代码文件中使用:

import { EthereumJSClass } from '@ethereumjs/[PACKAGE_NAME]'

如果您使用 Node.js 特定 require,CJS建筑将使用:

const { EthereumJSClass } = require('@ethereumjs/[PACKAGE_NAME]')

使用无害环境管理将比CJS给您更多的优势,超出浏览器的使用范围,如静态代码分析/树摇,CJS无法提供.

缓冲 - > Uint8 阵列

随着2023年夏天的解禁 我们取消了所有节点 Buffer 我们图书馆的用法,取而代之 Uint8 阵列 表示式,在Node.js和浏览器中都可以使用(Buffer 是一个子类 Uint8Array) (中文(简体) ).

我们已经将现有的缓冲转换方法转换为 Uint8Array 转换方法 @ethereumjs/用户 bytes 模块中,请参见相应的 README 部分.

BigInt 支持

随着5.0.0发行, 大点 替换 国家银行。 。 。 .

BigInt是一种原始的,用来代表并操纵原始的 bigint 数值,原始数字因其数值而不能表示. ES2020 报告介绍了这一特点。 请注意,这一版本更新导致与数字相关的API签名被更改,最低构建目标现在设定为: ES2020。 。 。 .

基准制定

你会发现两个简单的 基准 输入 benchmarks 文件夹 :

  • random.ts 随机运行 PUT 在树上操作,以及
  • checkpointing.ts 管理检查站,并犯 PUT 业务

还正在考虑第三个基准,利用主网数据模拟实际负荷.

您可以使用下列方法运行基准:

npm run benchmarks

运行一个 剖析器 编辑 random.ts 基准和生成火焰图 0个,您可以使用:

npm run profiling

0x 处理堆栈并生成一个 profile 文件夹(<pid>.0x包含 flamegraph.html。 。 。 .

调试

这个 Trie 类特性可选调试日志... 单个调试选择可在 CL 上激活 DEBUG=ethjs,[Logger Selection]。 。 。 .

ethjs 必须 列入 DEBUG 启用的环境变量 任意 木头. 附加的日志选择可以用逗号分隔列表来添加(没有空格). 带有扩展名的日志可以用冒号启用 :,以及 * 可用于包含所有扩展.

DEBUG=ethjs,thislog,thatlog,otherlog,otherlog:sublog,anotherLog:* node myscript.js

有以下备选方案:

锁定器说明
trie所有 tree 方法的最小信息记录
trie:<METHOD>特定 tree 方法的调试记录
trie:<METHOD>:*特定 tree 方法的动词调试记录
trie:*所有 tree 方法的动词调试记录

观察不同级别的伐木情况:

最小记录运行 :

DEBUG=ethjs,trie npx vitest test/util/log.spec.ts

运行 设置 方法记录 :

DEBUG=ethjs,trie:PUT npx vitest test/util/log.spec.ts

运行 三进制 + 键 设置编号 :起来编号 :三角形 日志 :

DEBUG=ethjs,trie,trie:PUT,trie:GET,trie:DEL npx vitest test/util/log.spec.ts

运行 查找路径 调试日志 :

DEBUG=ethjs,trie:FIND_PATH npx vitest test/util/log.spec.ts

运行 查找路径 动词记录 :

DEBUG=ethjs,trie:FIND_PATH:* npx vitest test/util/log.spec.ts

使用最大记录运行 :

DEBUG=ethjs,trie:* npx vitest test/util/log.spec.ts

参考资料

爱丽丝

看我们的组织 文档 介绍 EthereumJS 以及关于现行标准和最佳做法的资料。 如果你想参加工作或改进图书馆,请审查我们 捐款准则 先说.

许可证

MPL - 2.0 导弹

版本与发布记录

@ethereumjs/trie 共发布 18 个版本,首次发布于 2022/06/30;过去 12 个月发布了 0 个版本。

版本发布日期距今
6.2.1latest2024/08/152 年前
6.2.02024/03/182 年前
6.1.12024/02/092 年前
6.1.02024/02/092 年前
6.0.12023/11/023 年前
6.0.02023/08/093 年前

其他发布通道:beta → 5.0.0-beta.3,rc → 6.0.0-rc.1。

关于 @ethereumjs/trie 的常见问题

@ethereumjs/trie 是什么?

实施伊特鲁姆"黄纸"所指明的经过改造的"墨克勒活生生树".

如何安装 @ethereumjs/trie?

在项目目录运行 npm install @ethereumjs/trie,或使用 pnpm add / yarn add / bun add。

@ethereumjs/trie 支持 TypeScript 吗?

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

@ethereumjs/trie 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@ethereumjs/trie 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@ethereumjs/trie 可以商用吗?

@ethereumjs/trie 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@ethereumjs/trie 的下载量有多少?

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

@ethereumjs/trie 还在维护吗?

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