Chopsticks 本地分叉平行链实战指南

原文作者:PaperMoon团队

Chopsticks 由 Acala Foundation 开发,是一款面向 Polkadot SDK(Substrate)生态链开发者的多功能工具。借助 Chopsticks,你可以在本地直接 分叉(fork)线上运行的链,并在不部署到真实网络的前提下完成一系列高效的调试与实验,例如:

• 在本地复刻某条主网/测试网的状态(Fork live chains locally)

• 回放区块(replay blocks)并分析区块内的 extrinsics(交易/调用)

• 模拟复杂场景,比如 XCM 跨链交互(无需上链实测)

本指南将带你完成 Chopsticks 的安装,并说明如何配置本地 fork 环境。通过"本地分叉 + 可控回放 + 可编排场景",Chopsticks 能显著提升测试效率,帮助你在 Polkadot 生态中更快迭代链上功能。

如需更多支持与信息,可通过 GitHub Issues 进行反馈和提问。

重要提示(Warning)

Chopsticks 底层使用 Smoldot 轻客户端(light client),而 Smoldot 只支持原生 Polkadot SDK API。因此,基于 Chopsticks 运行的 fork 环境 不支持 Ethereum JSON-RPC 调用。

这意味着:

• 你无法用 Chopsticks fork 一条链后,再用 Metamask 去连接它(因为 Metamask 依赖以太坊 JSON-RPC)。

如果你的使用场景依赖 EVM JSON-RPC(如 Metamask、Hardhat、ethers.js 直接连 RPC),需要使用其他方案或额外的 RPC 层,而不是单纯依赖 Chopsticks fork。

前置条件

开始之前,请确保你的环境已安装:

• Node.js

• 包管理器:npm(默认随 Node.js 安装)或 Yarn

安装 Chopsticks

你可以选择 全局安装或在项目中 本地安装。请根据你的开发习惯选择:

本文档说明的是 Chopsticks 1.2.5 版本的功能与用法。请确保你使用的版本与本文一致,以免出现参数或行为差异。

1)全局安装(Global Installation)

全局安装后,你可以在任何项目中直接使用 chopsticks 命令:

复制代码
npm i -g @acala-network/chopsticks@1.2.5

安装完成后,你应该能在终端直接运行 chopsticks。

2)本地安装(Local Installation)

如果你只希望在某一个项目中使用 Chopsticks,推荐采用本地安装方式:

1)创建目录并初始化 Node.js 项目:

复制代码
mkdir my-chopsticks-project
cd my-chopsticks-project
npm init -y

2)安装 Chopsticks 依赖:

复制代码
npm i @acala-network/chopsticks@1.2.5

3)使用 npx 运行 Chopsticks,并查看帮助信息:

Go 复制代码
npx @acala-network/chopsticks --help

配置 Chopsticks

运行 Chopsticks 之前,需要配置一些关键参数。你可以通过以下两种方式提供配置:

• 配置文件(Configuration File)

• 命令行参数(CLI Flags)

Chopsticks 支持的可配置参数包括:

• genesis:用于构建 fork 的平行链 raw genesis 文件链接(用于替代 endpoint)

• timestamp:从哪个时间点对应的区块开始 fork

• endpoint:要 fork 的平行链节点 endpoint(通常为 WebSocket)

• block:指定从哪个区块高度或区块哈希开始回放/构建 fork

• wasm-override:指定要使用的 runtime Wasm 路径(替代 endpoint 提供的 runtime)

• db:本地数据库文件路径(用于存储 fork 的链状态)

• config:配置文件的路径或 URL

• port:对外暴露服务的端口

• build-block-mode:fork 环境下区块的构建模式:batch / manual / instant

• import-storage:预定义 JSON/YAML 存储覆盖文件,用于覆盖 fork 链上的 storage

• allow-unresolved-imports:使用 Wasm 构建链时,是否允许存在未解析的 imports

• html:生成区块之间 storage diff 的 HTML 预览

• mock-signature-host:启用签名 mock:任何以 0xdeadbeef 开头且用 0xcd 填充的签名都视为合法

实际使用中,最常用的是:endpoint / block / db / build-block-mode / import-storage / mock-signature-host。

配置文件方式

Chopsticks 的源码仓库提供了一组可复用的 YAML 配置文件,可用于在本地快速启动多种 Polkadot SDK 链的 fork。你可以从仓库的 configs 目录下载这些配置文件。

以下是一个 Polkadot 的配置文件示例:

Go 复制代码
endpoint:
  - wss://rpc.ibp.network/polkadot
  - wss://polkadot-rpc.dwellir.com
mock-signature-host: true
block: ${env.POLKADOT_BLOCK_NUMBER}
db: ./db.sqlite
runtime-log-level: 5

import-storage:
  System:
    Account:
      - - - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
        - providers: 1
          data:
            free: '10000000000000000000'
  ParasDisputes:
    $removePrefix: ['disputes'] # those can makes block building super slow

配置文件的能力说明

• 配置文件允许你通过"重写 storage"的方式修改 fork 网络的状态,即指定:

• Pallet 名称

• 存储项(storage item)路径

• 目标值

• 上述示例将 Alice 的 System.Account 存储修改为:free 余额为 10000000000000000000。

• 同时示例还通过 ParasDisputes 的 $removePrefix 移除部分争议数据(disputes),避免这些数据导致区块构建非常慢(这是一个典型的性能优化手段)。

简而言之:你不仅能 fork 线上状态,还能在 fork 的基础上"定制链状态",用于复现实验条件。

命令行参数方式(CLI Flags)

如果你更倾向于命令行操作,Chopsticks 也支持通过 CLI flags 配置所有参数(genesis 与 timestamp 除外)。

这种方式适用于:

• 临时试验、快速切换 endpoint 或区块高度

• 脚本化自动执行(CI / 本地脚本)

WebSocket 控制命令

Chopsticks 内置了一个 WebSocket 服务,提供一组特殊的 RPC 方法,用于直接操控本地 fork 的链行为(例如造块、改 storage、时间旅行等)。

下面是常用方法与参数说明。

1)dev_newBlock (newBlockParams):生成新区块

用于生成一个或多个新区块。

参数:newBlockParams: NewBlockParams

其中 NewBlockParams 包含:

• count(number):要生成的区块数量

• dmp({ msg: string, sentAt: number }[]):要包含的 downward message

• hrmp(Record<string | number, { data: string, sentAt: number }[]>):要包含的 horizontal message

• to(number):指定生成到哪个区块高度

• transactions(string[]):要包含在新区块中的交易(extrinsics)

• ump(Record<number, string[]>):要包含的 upward message

• unsafeBlockHeight(number):用指定高度构建区块(不安全选项)

2)dev_setBlockBuildMode (buildBlockMode):设置造块模式

用于设置本地 fork 的造块模式。

BuildBlockMode 可选值:

Go 复制代码
export enum BuildBlockMode {
  Batch = 'Batch', /** 默认:每批生成一个区块 */
  Instant = 'Instant', /** 每笔交易立刻生成一个区块 */
  Manual = 'Manual', /** 仅在手动触发时生成 */
}

3)dev_setHead (hashOrNumber):设置链头(Head)

将本地链的 head 设置为指定的区块哈希或高度。

参数:

• hashOrNumber:string | number(区块 hash 或区块高度)

4)dev_setRuntimeLogLevel (runtimeLogLevel):设置 Runtime 日志级别

用于调整 runtime 的 log level,便于调试 runtime 内部行为。

参数:

• runtimeLogLevel:number

5)dev_setStorage (values, blockHash):创建或覆盖任意存储值

可以在本地 fork 中直接修改 storage(非常适合快速构造测试场景)。

参数:

• values:object,JSON 对象,结构类似 storage 路径

• blockHash:string,在哪个区块 hash 上设置该 storage

6)dev_timeTravel (date):时间旅行(修改区块时间)

将当前区块时间设置为指定日期/时间点。之后产生的区块时间会从该时间点开始顺序推进。

参数:

• date:string,可以是时间戳或日期字符串

• 例如:2030-08-15T00:00:00

WebSocket 调用示例(Examples)

下面是文档给出的示例代码(保持原样,便于复制使用)。

示例 1:生成 1 个新区块(dev_newBlock)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  await api.rpc('dev_newBlock', { count: 1 });
}

main();

示例 2:设置造块模式为 Instant(dev_setBlockBuildMode)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  await api.rpc('dev_setBlockBuildMode', 'Instant');
}

main();

示例 3:将 Head 设置到区块高度 500(dev_setHead)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  await api.rpc('dev_setHead', 500);
}

main();

示例 4:设置 Runtime 日志级别(dev_setRuntimeLogLevel)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  await api.rpc('dev_setRuntimeLogLevel', 1);
}

main();

示例 5:修改账户 storage(dev_setStorage)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

import { Keyring } from '@polkadot/keyring';
async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  const keyring = new Keyring({ type: 'ed25519' });
  const bob = keyring.addFromUri('//Bob');
  const storage = {
    System: {
      Account: [[[bob.address], { data: { free: 100000 }, nonce: 1 }]],
    },
  };
  await api.rpc('dev_setStorage', storage);
}

main();

示例 6:时间旅行到 2030-08-15(dev_timeTravel)

Go 复制代码
import { ApiPromise, WsProvider } from '@polkadot/api';

async function main() {
  const wsProvider = new WsProvider('ws://localhost:8000');
  const api = await ApiPromise.create({ provider: wsProvider });
  await api.isReady;
  await api.rpc('dev_timeTravel', '2030-08-15T00:00:00');
}

main();

总结

通过 Chopsticks,你可以在本地复刻线上链状态,并通过内置 WebSocket 控制接口实现:

• 快速造块与回放

• 直接修改 storage 构造测试条件

• 调整 runtime 日志

• 控制时间推进以复现时间相关逻辑

• 为 XCM 等复杂场景提供可控实验环境

需要再次强调:由于 Chopsticks 基于 Smoldot,仅支持原生 Polkadot SDK API,不支持 Ethereum JSON-RPC,因此不能直接用于 Metamask 连接场景。

原文链接:https://docs.polkadot.com/parachains/testing/fork-a-parachain/

相关推荐
JMchen1233 小时前
Android网络安全实战:从HTTPS到双向认证
android·经验分享·网络协议·安全·web安全·https·kotlin
科技块儿3 小时前
如何选择合适的IP查询工具?精准度与更新频率全面分析
网络·tcp/ip·安全
暴躁小师兄数据学院3 小时前
【WEB3.0零基础转行笔记】Solidity编程篇-第一讲:简易存储
web3·区块链·智能合约
Hi202402173 小时前
在Docker容器中安全运行OpenClaw:无需虚拟机,体验AI助手
人工智能·安全·docker·openclaw
种时光的人3 小时前
CANN 生态 ×AIGC 合规:cann-compliance 让大模型落地既安全又合规
安全·aigc
hzb666664 小时前
unictf2026
开发语言·javascript·安全·web安全·php
大模型玩家七七5 小时前
基于语义切分 vs 基于结构切分的实际差异
java·开发语言·数据库·安全·batch
Hello.Reader12 小时前
Flink ZooKeeper HA 实战原理、必配项、Kerberos、安全与稳定性调优
安全·zookeeper·flink
智驱力人工智能13 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算