
1. 介绍
在快速增长的以太坊生态系统中,Layer 2 rollups(二层Rollup) 已经成为扩展的最有效方法——减少 gas 费用、提高吞吐量,并为 dApp 释放新的可能性。
但对于大多数开发者来说,建立自己的 rollup 总是让人望而却步。
大量的样板代码。
太多的活动部件。
很少有关于底层发生情况的可视性。
这正是 OP Stack 所解决的问题。
OP Stack 是一个 模块化和生产级别的框架,用于构建与以太坊等效的 rollups。它是 Optimism 主网的动力——但它也适用于 任何人 使用和 自定义。
如果你曾经想:
- 了解像 Optimism 这样的 rollups 真正是如何工作的,
- 部署你自己的 L2 链用于测试或实验,
- 或者只是更深入地研究以太坊基础设施。
本指南就是为你准备的。
2. 快速概览:OP Stack 组件
在我们开始实践之前,让我们花点时间了解 OP Stack rollup 的核心构建块。
正如以太坊有一个共识客户端(例如 Lighthouse、Prysm)和一个执行客户端(例如 Geth、Nethermind)一样,OP Stack 也有类似的组件——但专为运行 Layer 2 链而设计。
以下是一个快速概览:
1. 执行客户端 → op-geth
执行客户端负责:
- 执行智能合约
- 维护链的状态
- 处理以太坊 JSON-RPC 接口
在 OP Stack 中,执行客户端是 Geth 的一个分支,称为 op-geth。
可以将其视为你的 L2 链的“EVM 大脑”。
2. 共识客户端 → op-node
共识客户端负责:
- 跟踪 L1 区块(在我们的例子中是以太坊 Sepolia)
- 使用 Engine API 与执行客户端协调
- 根据 L1 的输入确定规范的 L2 链
这由 op-node 处理——你的 rollup 的核心驱动程序。
它监视以太坊 L1、处理 L2 输入,并驱动 op-geth 生成 L2 区块。
3. Batcher → op-batcher
一旦你的 rollup 产生区块,你需要将 这些区块发布到以太坊 L1。
这就是 batcher 的工作。
batcher:
- 从
op-geth收集 L2 交易数据 - 将其发布到 L1 的一个特殊合约中
- 确保数据的可用性和可验证性
这就是使 rollups 安全的原因:数据存在于以太坊上。
4. Proposer → op-proposer
最后一个组件是 proposer。
它负责:
- 将你的 L1 链的 状态根 提交到 L1
- 更新 Output Oracle 智能合约
- 允许从 L2 提款到 L1
没有 proposer,你的链无法最终确定。
对于测试来说,它是可选的——但对于一条活跃的链来说,它是必不可少的。
它们如何协同工作
这是一个简化的工作流程:
op-node监视 Sepolia 上的新 L1 区块- 它指示
op-geth产生 L2 区块 op-batcher收集这些区块并将它们发布到 L1op-proposer将最终状态发布到 L1 以进行提款
所有这些组件协同工作,以保持你的 L2 链运行——去中心化、可扩展和 trust-minimised。
3. 设置环境
既然你了解了主要组件,那么是时候卷起袖子,设置你启动自己的 L2 链所需的一切了。
我们将首先克隆相关的存储库、安装依赖项并准备核心二进制文件。
克隆 Optimism Monorepo
首先,克隆主要的 Optimism Monorepo,其中包含 OP Stack 源代码。
git clone <https://github.com/ethereum-optimism/optimism.git>进入克隆的目录:
cd optimism安装 Node.js 依赖项
Optimism Monorepo 使用 yarn 来管理 Node.js 包。
安装所有必要的依赖项:
yarn install注意:在继续之前,请确保你已安装 Node.js 和 yarn。你可以使用以下命令安装 yarn:
npm install --global yarn构建核心二进制文件
安装依赖项后,你需要构建一些重要的二进制文件:
make op-node op-batcher op-proposer这将编译并准备:
op-node(共识客户端)op-batcher(Batcher 服务)op-proposer(Proposer 服务)
所有这些二进制文件都将在你的 Optimism 目录中的 ./bin 文件夹中可用。
克隆执行客户端(op-geth)
执行客户端(修改后的 Geth)位于一个 单独的存储库 中。
克隆它:
git clone <https://github.com/ethereum-optimism/op-geth.git>进入 op-geth 目录:
cd op-geth并构建 geth 二进制文件:
make geth这将生成一个 build/bin/geth 二进制文件,你将使用它来运行你的 L2 执行客户端。
4. 设置钱包和环境变量
在我们启动链的任何部分之前,我们需要用于不同角色的 特殊钱包——Admin、Batcher、Proposer 和 Sequencer。
我们还将准备一个 .envrc 文件,以便轻松地将这些凭据加载到我们的 shell 中。
让我们一步一步地进行。
生成钱包
在克隆的 optimism 目录中,运行钱包生成脚本:
./packages/contracts-bedrock/scripts/getting-started/wallets.sh此脚本将生成:
- Admin 账户(用于部署)
- Batcher 账户(用于发布交易批次)
- Proposer 账户(用于发布状态根)
- Sequencer 账户(用于区块生产)
复制钱包详细信息
输出将如下所示:
Copy the following into your .envrc file: ## Admin address export GS_ADMIN_ADDRESS=0x... export GS_ADMIN_PRIVATE_KEY=0x... ## Batcher address export GS_BATCHER_ADDRESS=0x... export GS_BATCHER_PRIVATE_KEY=0x... ## Proposer address export GS_PROPOSER_ADDRESS=0x... export GS_PROPOSER_PRIVATE_KEY=0x... ## Sequencer address export GS_SEQUENCER_ADDRESS=0x... export GS_SEQUENCER_PRIVATE_KEY=0x...资助你的钱包
由于我们要在 Sepolia 测试网上部署,你需要一些 Sepolia ETH 来资助你的钱包。
建议的资助金额:
- Admin — 0.5 Sepolia ETH
- Batcher — 0.1 Sepolia ETH
- Proposer — 0.2 Sepolia ETH
- Sequencer — 不需要 ETH(它不发送交易)
你可以从公共水龙头获取 Sepolia ETH,或者向朋友/测试网提供商询问。
安装和设置 direnv
为了自动加载这些钱包变量,我们将使用一个名为 direnv 的工具。
安装它:
brew install direnv创建 .envrc 文件
在你的 optimism 文件夹中,创建一个名为 .envrc 的文件。
将导出的环境变量粘贴到其中,如下所示:
## Admin account export GS_ADMIN_ADDRESS=0xYourAdminAddress export GS_ADMIN_PRIVATE_KEY=0xYourAdminPrivateKey ## Batcher account export GS_BATCHER_ADDRESS=0xYourBatcherAddress export GS_BATCHER_PRIVATE_KEY=0xYourBatcherPrivateKey ## Proposer account export GS_PROPOSER_ADDRESS=0xYourProposerAddress export GS_PROPOSER_PRIVATE_KEY=0xYourProposerPrivateKey ## Sequencer account export GS_SEQUENCER_ADDRESS=0xYourSequencerAddress export GS_SEQUENCER_PRIVATE_KEY=0xYourSequencerPrivateKey ## L1 Sepolia RPC URL export L1_RPC_URL="<https://eth-sepolia.g.alchemy.com/v2/your-api-key>" ## Chain IDs and Block Times export L1_CHAIN_ID="11155111" export L2_CHAIN_ID="420" export L1_BLOCK_TIME=12 export L2_BLOCK_TIME=2确保将 your-api-key 替换为你的真实的 alchemy 或 infura endpoint for sepolia。
加载环境
一旦 .envrc 准备就绪,告诉 direnv 加载它:
direnv allow如果一切正常,你应该看到类似以下的输出:
direnv: loading .envrc direnv: export +GS_ADMIN_ADDRESS +GS_ADMIN_PRIVATE_KEY +... (and so on)如果你没有看到这个,请确保你的 .envrc 文件格式正确,然后再次尝试 direnv allow。
5. 配置 Rollup
现在你已经准备好了你的环境和钱包,接下来是设置你的 L2 rollup 的实际配置。
这个配置定义了重要的参数,例如区块时间、链 ID、地址和其他系统设置。
我们将自动生成一个基本配置,你可以在以后根据需要自定义它。
导航到 contracts-bedrock 包
从你的 optimism monorepo 根目录,移动到 contracts-bedrock 包:
cd packages/contracts-bedrock安装 Foundry 依赖项
如果你还没有安装 Foundry,请先安装它:
curl -L <https://foundry.paradigm.xyz> | bash foundryup在 contracts-bedrock 包中,安装依赖项:
forge install这将安装智能合约部署和测试所需的所有必要库。
生成 getting-started.json 配置
运行提供的配置脚本:
./scripts/getting-started/config.sh这将创建一个新文件:
deploy-config/getting-started.json此文件将包含基于你的环境变量的所有基本链配置。
示例:getting-started.json 的样子
这是一个简化的例子:
{ "l1ChainID": 11155111, "l2ChainID": 420, "l2BlockTime": 2, "l1BlockTime": 12, "maxSequencerDrift": 600, "sequencerWindowSize": 3600, "channelTimeout": 300, "p2pSequencerAddress": "0xYourSequencerAddress", "batchSenderAddress": "0xYourBatcherAddress", "l2OutputOracleProposer": "0xYourProposerAddress", "l2OutputOracleChallenger": "0xYourAdminAddress", ... }6. 使用 op-deployer 部署 L1 合约
现在你的 rollup 配置已准备就绪,是时候将 essential OP Stack 合约 部署到 Sepolia 测试网 了。
这是一个关键步骤——这些合约构成了你的 rollup 系统的支柱,包括桥、预言机和系统配置。
我们将使用 op-deployer 工具来处理这个过程。
什么是 op-deployer?
op-deployer 是 Optimism 团队构建的命令行工具,使部署 OP Stack 合约变得简单且可重复。
它处理:
- 合约部署
- Genesis 和 rollup 配置生成
- 链初始化步骤
使用 op-deployer 还可以确保你的部署遵循 OP Stack 标准,如果你想稍后加入 Superchain(超级链),这将使其具有面向未来的能力。
步骤 1:安装 op-deployer
如果你尚未安装它:
克隆 repo:
git clone <https://github.com/ethereum-optimism/optimism.git>(如果你之前已经克隆了它,则无需再次克隆。)
在你的 optimism 目录中,当你运行 make 时,应该已经构建了 op-deployer 二进制文件。
如果没有,你可以手动构建它:
cd optimsim/op-deployer make确保 bin/op-deployer 存在。
步骤 2:初始化 .deployer 目录
现在,我们将创建一个工作目录,op-deployer 将在其中管理部署状态。
从 optimism 根目录 中,运行:
./bin/op-deployer init --l1-chain-id 11155111 --l2-chain-ids 420 --workdir .deployer11155111→ Sepolia L1 链 ID420→ 我们的 rollup 的 L2 链 ID.deployer→ 将存储部署配置和状态文件的目录
此命令创建:
.deployer/intent.json(你的部署配置).deployer/state.json(部署后填充)
步骤 3:自定义你的意图文件
你可以打开 .deployer/intent.json 来调整设置,例如:
- 所有者地址
- 费用接收者地址
- 治理设置
目前,默认设置对于测试网 rollup 来说是可以的。
步骤 4:将合约部署到 L1
现在是真正的操作:
运行此命令以将合约部署到 Sepolia:
./bin/op-deployer apply --workdir .deployer \\ --l1-rpc-url $L1_RPC_URL \\ --private-key $GS_ADMIN_PRIVATE_KEY$L1_RPC_URL→ 你的 Sepolia RPC URL(Alchemy、Infura 等)$GS_ADMIN_PRIVATE_KEY→ 你之前生成的 Admin 钱包的私钥
此步骤中发生了什么?
- 诸如 L1StandardBridge、SystemConfig、OutputOracle 等合约已部署在 Sepolia 上
- 部署程序将所有已部署的合约地址记录到
.deployer/state.json中 - 部署流程遵循你先前创建的配置
如果一切正常,你将看到带有已部署地址的成功消息。
如果出现问题(例如“gas 不足”错误),请检查:
- Admin 账户上的资金余额
- 已加载正确的环境变量
步骤 5:结果——已部署状态
成功部署后,你将拥有:
.deployer/state.json——合约地址、部署数据.deployer/目录 ——完整的部署快照
我们将在后续步骤中使用此数据来 生成 genesis 并 初始化 L2 节点。
7. 生成 Genesis 和 Rollup 配置文件
现在你的智能合约已部署在 Sepolia 上,是时候 生成你的链实际运行所需的核心配置文件 了:
genesis.json→ 用于执行客户端(op-geth)rollup.json→ 用于共识客户端(op-node)
这两个文件都 至关重要。
如果没有它们,你的客户端将不知道从哪个链开始。
让我们创建它们。
步骤 1:生成 genesis.json
genesis.json 文件定义了你的执行客户端的 初始状态。
它告诉 op-geth:
- 第一个区块是什么样的
- 系统账户是谁
- 启动时应用什么设置
要生成它,请运行:
./bin/op-deployer inspect genesis --workdir .deployer <L2_CHAIN_ID> > .deployer/genesis.json在我们的例子中:
./bin/op-deployer inspect genesis --workdir .deployer 420 > .deployer/genesis.json此命令从 .deployer/state.json 读取并生成 .deployer/genesis.json。
步骤 2:生成 rollup.json
rollup.json 文件定义了你的共识客户端的 rollup 配置。
它告诉 op-node:
- 要在 L1 上监视哪些合约
- 如何验证区块
- 时间参数和安全假设
要生成它,请运行:
./bin/op-deployer inspect rollup --workdir .deployer <L2_CHAIN_ID> > .deployer/rollup.json在我们的例子中:
./bin/op-deployer inspect rollup --workdir .deployer 420 > .deployer/rollup.json这将创建 .deployer/rollup.json。
这些文件现在在哪里?
在这两个命令之后,你应该拥有:
.deployer/genesis.json.deployer/rollup.json
在后续步骤中初始化 op-geth 和 op-node 时,我们将把这些文件 复制 到正确的位置。
8. 运行核心客户端
部署合约并生成配置文件后,是时候 启动你的rollup的两个主要引擎 了:
- 执行客户端 (
op-geth) - 共识客户端 (
op-node)
这两个客户端将 协同工作 以驱动你的 L2 rollup。
让我们逐步进行。
步骤 1:初始化 op-geth
首先,我们需要使用我们创建的 genesis.json 初始化执行客户端 (op-geth)。
导航到你的 op-geth 目录:
cd ~/op-geth创建一个用于区块链数据的目录:
mkdir datadir初始化 op-geth:
build/bin/geth init --state.scheme=hash --datadir=datadir ../optimism/.deployer/genesis.json这告诉 op-geth:
- 使用
genesis.json中指定的起始块 - 将区块链数据存储在
datadir/文件夹中
步骤 2:启动 op-geth
现在,启动执行客户端:
./build/bin/geth \\ --datadir ./datadir \\ --http \\ --http.corsdomain="*" \\ --http.vhosts="*" \\ --http.addr=0.0.0.0 \\ --http.api=web3,debug,eth,txpool,net,engine \\ --ws \\ --ws.addr=0.0.0.0 \\ --ws.port=8546 \\ --ws.origins="*" \\ --ws.api=debug,eth,txpool,net,engine \\ --syncmode=full \\ --gcmode=archive \\ --nodiscover \\ --maxpeers=0 \\ --networkid=42069 \\ --authrpc.vhosts="*" \\ --authrpc.addr=0.0.0.0 \\ --authrpc.port=8551 \\ --authrpc.jwtsecret=./jwt.txt \\ --rollup.disabletxpoolgossip=true重要设置:
-gcmode=archive→ 对于 Sequencer 来说很重要,因为op-proposer需要完整状态。-authrpc.jwtsecret=./jwt.txt→ 此 JWT 密钥用于在op-geth和op-node之间进行身份验证。
如果这成功运行,则你的执行客户端已启动!
步骤 3:启动 op-node
打开一个
新的终端窗口
cd ~/optimism/op-node启动共识客户端:
./bin/op-node \\ --l2=http://localhost:8551 \\ --l2.jwt-secret=./jwt.txt \\ --sequencer.enabled \\ --sequencer.l1-confs=5 \\ --verifier.l1-confs=4 \\ --rollup.config=../.deployer/rollup.json \\ --rpc.addr=0.0.0.0 \\ --rpc.port=9545 \\ --p2p.disable \\ --rpc.enable-admin \\ --p2p.sequencer.key=$GS_SEQUENCER_PRIVATE_KEY \\ --l1=$L1_RPC_URL \\ --l1.rpckind=$L1_RPC_KIND这将:
- 将
op-node连接到你的op-geth - 开始生成 L2 区块
- 监视 L1 (Sepolia) 的更新
此时,你应该开始在日志中实时看到 L2 区块的生产!
如何知道它是否正常工作
如果一切设置正确:
op-geth将显示正在导入的新区块op-node将显示正在提议和最终确定的新 L2 区块
你现在拥有一个可正常工作的本地 Sequencer 节点!
9. 运行支持服务(op-batcher 和 op-proposer)
现在你的执行客户端(op-geth)和共识客户端(op-node)已启动并生成 L2 区块,
你仍然需要 两个关键的后台服务 来完成完整的 rollup 生命周期:
- Batcher (
op-batcher) → 将交易数据发布到 L1 - Proposer (
op-proposer) → 将状态根发布到 L1(用于提款和最终确定)
让我们启动它们!
1. 启动 Batcher (op-batcher)
Batcher 从你的 L2 链收集区块和交易数据,将它们捆绑到批次中,并将它们发送到 Sepolia 上的 Batch Inbox 合约。
没有 batcher,你的 rollup 不会向以太坊发布任何数据。
打开一个新的终端窗口。
导航到 batcher 目录:
cd ~/optimism/op-batcher启动 batcher:
./bin/op-batcher \\ --l2-eth-rpc=http://localhost:8545 \\ --rollup-rpc=http://localhost:9545 \\ --poll-interval=1s \\ --sub-safety-margin=6 \\ --num-confirmations=1 \\ --safe-abort-nonce-too-low-count=3 \\ --resubmission-timeout=30s \\ --rpc.addr=0.0.0.0 \\ --rpc.port=8548 \\ --rpc.enable-admin \\ --max-channel-duration=25 \\ --l1-eth-rpc=$L1_RPC_URL \\ --private-key=$GS_BATCHER_PRIVATE_KEY现在,你的 batcher 正在运行!
它将:
- 监视你的
op-geth - 将批处理的 L2 交易提交到 Sepolia (L1)
2. 启动 Proposer (op-proposer)
Proposer 将 L2 状态根 提交到 Sepolia 上的 L2OutputOracle 合约。
这使用户最终能够 将资金提取回 L1。
打开另一个终端窗口。
导航到 proposer 目录:
cd ~/optimism/op-proposer启动 proposer:
./bin/op-proposer \\ --poll-interval=12s \\ --rpc.port=8560 \\ --rollup-rpc=http://localhost:9545 \\ --l2oo-address=$(cat ../packages/contracts-bedrock/deployments/getting-started/.deploy | jq -r .L2OutputOracleProxy) \\ --private-key=$GS_PROPOSER_PRIVATE_KEY \\ --l1-eth-rpc=$L1_RPC_URL现在,你的 proposer 已经启动!
它将:
- 监视你的 L2 链
- 将最终确定的 L2 输出发布到 L1
10. 将你的钱包连接到你的 Rollup
现在你的 rollup 正在完全运行——生成区块、发布批次和最终确定状态——
是时候 连接你的钱包(如 MetaMask)并 直接与你的 L2 网络交互 了。
这就是它开始感觉 真实 的地方——发送交易、部署合约,并在你自己的链上看到活动!
步骤 1:在 MetaMask 中将你的 Rollup 添加为自定义网络
打开 MetaMask 并手动添加一个新的自定义网络。
以下是你需要的信息:
网络名称 → OP Stack Rollup(或你喜欢的任何名称)
新 RPC URL → http:localhost:8545
链 ID → 420(或你在 .envrc 中配置的任何内容)
货币符号 → ETH
区块浏览器 URL →(暂时留空)
保存网络。
你的 MetaMask 现在应该指向你位于 localhost:8545 的本地 Rollup。
步骤 2:确认你已连接
添加后:
- 你应该看到你的钱包已连接到你的 L2 链。
- 你的钱包地址应与 Sepolia 上的地址完全相同(因为私钥相同)。
- 但是你的 L2 上的余额可能为 0 ETH(因为尚未发生桥接)。
不用担心!
我们将在下一节中解决这个问题。
11. 将 ETH 桥接到你的 Rollup
现在你的钱包已连接到你的 L2 rollup,你将注意到你的 rollup 网络上有 0 ETH。
要发送交易或部署合约,你需要 L2 链上的 ETH。
你如何将 ETH 放到你的 rollup 上?
通过 通过你先前部署的 L1 Standard Bridge 合约进行 桥接**。
让我们一步一步地进行。
步骤 1:找到 L1 Bridge 合约地址
导航到你的 contracts-bedrock 包:
cd ~/optimism/packages/contracts-bedrock获取运行 op-deployer 时部署的 L1StandardBridgeProxy 的地址:
cat deployments/getting-started/.deploy | jq -r .L1StandardBridgeProxy这将输出你需要将 ETH 发送到的地址。
保存此地址。
步骤 2:将 Sepolia ETH 发送到 Bridge 合约
打开你的 MetaMask(或任何连接到 Sepolia 的钱包)并将少量 Sepolia ETH(例如 0.05 或 0.1 ETH)发送到你刚刚获得的 L1StandardBridgeProxy 地址。
这将触发向你的 rollup 的 存款。
重要提示:
- 在测试期间不要发送大量资金。
- 等待 Sepolia 交易被确认。
步骤 3:等待桥接完成
将 ETH 发送到桥后:
- 你的 L1 存款必须由 rollup 最终确定。
op-node将观察 L1 存款。- 几个区块后(通常为 2-5 分钟),你将在 L2 上看到 ETH 被铸造。
你可以查看你的op-node和op-geth终端中的日志 — 你应该看到“存款已最终确定”或类似日志。
完成后,你的 Rollup 网络上的钱包将显示桥接的 ETH。
12. 测试你的 Rollup
现在你已经将 ETH 桥接到你的 rollup 上,你终于可以像使用任何其他 EVM 链一样 使用 你的新区块链了!
你现在可以 发送交易、部署智能合约 并 观察你的 rollup 的运行情况。
让我们来演练一下你应该做的基础测试。
步骤 1:发送测试交易
使用你的 MetaMask(或任何连接到你的 L2 网络的钱包)并:
- 将少量 ETH 发送到另一个地址(甚至发回给你自己)。
- 在 MetaMask 中确认交易。
几秒钟内,你应该看到:
- 交易在你的钱包中得到确认。
- 显示交易正在执行的日志出现在你的
op-geth和op-node终端中。
如果这有效,则意味着:
- 你的 RPC 端点(
localhost:8545)已启动 - 你的执行和共识客户端正在处理新的交易
- 你的 rollup 运行状况良好
步骤 2:部署智能合约
为了进行全面测试,我们还部署一个简单的智能合约!
你可以使用 Remix IDE、Hardhat 或 Foundry 等工具。
这是一个使用 Remix 的基本方法:
- 打开 Remix。
- 将环境设置为“Injected Web3”→ 连接到 MetaMask。
- 确保 MetaMask 已连接到你的 OP Stack Rollup (localhost:8545)。
- 编写一个非常简单的合约,例如:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract HelloWorld { string public message = "Hello, Rollup!"; }- 编译并部署它。
✅ 你应该看到:
- 部署交易在你的 L2 上得到确认
- 合约地址可用
- 能够立即调用函数(
message)
你在这里测试什么
你正在验证:
- 你的 rollup 可以接受和处理 用户发起的交易
- 你的链支持 智能合约部署
- Gas 计量、状态更新和存储工作正常
这是完整的 EVM 功能——在你自己的 L2 rollup 上!
13. 最后想法和接下来你可以构建的内容
恭喜你——你已经从头开始 创建了你自己的 OP Stack L2 Rollup 测试网!
这是一项巨大的成就。
你现在了解了现代 rollup 的 完整堆栈:
- 共识 和 执行 分离
- batcher 和 proposer 的角色
- 在 L1 和 L2 之间 桥接 ETH
- 你自己运行 排序器节点
- 在你自己的链上 部署智能合约
这不仅仅是理论知识——你实际上 做到了。
- 原文链接: medium.com/@tomarpari90/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~