第4章:Optimistic Rollup 实战:Arbitrum 架构解析、开发环境搭建、部署第一个合约

好,咱们进入实战环节了。

前面聊了那么多理论,说实话,我自己当年学的时候也觉得有点虚。直到亲手在 Arbitrum 上跑通第一个合约,才真正理解 Optimistic Rollup 到底在干什么。

这一章,我带你从架构到代码,一步步走通。

4.1 Arbitrum 架构:到底长什么样?

先看架构。Arbitrum 的核心思路,说白了就是「链下执行,链上验证」。

它分两层:

  • Layer 1(以太坊主网):负责存数据、做裁决。所有交易数据都会压缩后发到 L1 上。
  • Layer 2(Arbitrum 链):负责跑交易、维护状态。节点们在这里执行交易,生成新的状态根。

关键组件有这么几个:

组件 作用
Inbox 接收 L1 发来的消息(比如用户存款、合约调用)
Outbox 处理 L2 到 L1 的消息(比如提现)
Sequencer 排序交易,快速给用户确认。我习惯叫它「排序器」
Validator 验证者,负责挑战欺诈证明

嗯,这里要注意:Sequencer 是 Arbitrum 的一个特色。它先帮你把交易排好序,然后批量提交到 L1。用户几乎秒确认,体验跟 L1 差不多。

核心要点:Arbitrum 的「乐观」体现在——它默认所有交易都是对的。只有有人发现错了,才启动挑战。这跟 Optimistic Rollup 的设计哲学完全一致。

4.2 开发环境搭建:别踩我踩过的坑

好,动手了。

我个人习惯用 Hardhat 做开发框架。Arbitrum 官方也推荐这个。

第一步:安装依赖

mkdir arbitrum-demo && cd arbitrum-demo
npm init -y
npm install --save-dev hardhat @nomiclabs/hardhat-waffle ethereum-waffle chai
npm install --save-dev @arbitrum/sdk

这里有个坑。我曾经在安装 @arbitrum/sdk 时,因为 Node 版本太低,报了一堆错。建议 Node 版本 >= 16。

第二步:配置 Hardhat

创建 hardhat.config.js

require("@nomiclabs/hardhat-waffle");

module.exports = {
  solidity: "0.8.19",
  networks: {
    arbitrumGoerli: {
      url: "https://goerli-rollup.arbitrum.io/rpc",
      chainId: 421613,
      accounts: [你的私钥]
    }
  }
};

小提示:测试网用 Goerli 的 Arbitrum 测试链。主网的话,chainId 是 42161。别搞混了,我见过有人把测试网合约部署到主网,gas 费烧得心疼。

第三步:获取测试 ETH

你需要先在 Goerli 上领测试 ETH,然后通过 Arbitrum 的桥跨到 L2。官方桥地址:bridge.arbitrum.io

你想想看,没有测试币,部署合约就是空谈。我一般会多领一点,因为每次部署、交互都要消耗 gas。

4.3 部署第一个合约:Hello Arbitrum

写个简单的合约练手。

// contracts/HelloArbitrum.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract HelloArbitrum {
    string public message;

    constructor(string memory _message) {
        message = _message;
    }

    function setMessage(string memory _message) public {
        message = _message;
    }
}

然后写部署脚本:

// scripts/deploy.js
async function main() {
  const HelloArbitrum = await ethers.getContractFactory("HelloArbitrum");
  const contract = await HelloArbitrum.deploy("Hello, Arbitrum!");

  await contract.deployed();

  console.log("合约地址:", contract.address);
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error);
    process.exit(1);
  });

运行部署:

npx hardhat run scripts/deploy.js --network arbitrumGoerli

如果一切顺利,你会看到合约地址打印出来。嗯,那一刻还是挺有成就感的。

注意:部署到 Arbitrum 的 gas 费比 L1 便宜很多,但也不是免费的。我见过有人部署一个简单合约花了 0.01 ETH,其实正常只要 0.001 ETH 左右。检查一下你的 gas price 设置,别被坑了。

4.4 验证合约:确保代码公开

部署完合约,我建议你立刻验证。这样别人才能在 Etherscan 上看到你的源码。

Arbitrum 的区块浏览器是 arbiscan.io。验证方式跟以太坊一样:

npx hardhat verify --network arbitrumGoerli 合约地址 "Hello, Arbitrum!"

如果报错,多半是构造函数参数没传对。我踩过这个坑,折腾了半小时才发现少了个引号。

4.5 交互测试:调用合约

部署完了,咱们试试调用。

// scripts/interact.js
async function main() {
  const contractAddress = "你部署的合约地址";
  const HelloArbitrum = await ethers.getContractFactory("HelloArbitrum");
  const contract = HelloArbitrum.attach(contractAddress);

  // 读取消息
  let msg = await contract.message();
  console.log("当前消息:", msg);

  // 修改消息
  const tx = await contract.setMessage("Arbitrum is awesome!");
  await tx.wait();

  // 再次读取
  msg = await contract.message();
  console.log("修改后消息:", msg);
}

main();

运行:

npx hardhat run scripts/interact.js --network arbitrumGoerli

你会看到消息从 "Hello, Arbitrum!" 变成了 "Arbitrum is awesome!"。

整个过程跟以太坊开发几乎一模一样。这就是 Arbitrum 兼容 EVM 的好处——你不需要学新语言,Solidity 直接拿来用。

4.6 避坑指南:我踩过的几个雷

  • Gas 估算不准:Arbitrum 的 gas 模型跟 L1 不同。我建议用 ethers.jsestimateGas 方法先算一下,别直接写死。
  • 跨链消息延迟:从 L1 到 L2 的消息大概要等 10 分钟。别着急,去区块浏览器看看状态。
  • 测试网水龙头:Goerli 的测试 ETH 有时候很难领。我一般去 goerlifaucet.com 碰运气,或者找朋友借一点。

总结一下:Arbitrum 的开发体验跟以太坊高度一致。你只要会写 Solidity,就能在 Arbitrum 上部署。但要注意 gas 模型和跨链机制,这两块跟 L1 不太一样。

下一章,咱们聊聊 Optimistic Rollup 的进阶玩法——如何自己写一个欺诈证明。嗯,那个更有意思。