简介 OP Stack 是 Optimism 开发的模块化区块链技术栈,允许开发者轻松创建自己的 Layer2 网络。本指南提供了在 Ubuntu 环境下从零开始搭建一个完整的 Layer2 网络,包括环境配置、合约部署、节点启动和基本操作验证。
一、准备系统环境 1.1 安装 Ubuntu 打开 Windows PowerShell 终端
1 2 3 4 5 wsl --list --online wsl --install -d Ubuntu-24 .04
1.2 安装软件依赖 打开 Ubuntu-24.04 子系统(在安装 pnpm 和 mise 时,需修改自己环境变量加载的路径)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 sudo apt update && sudo apt upgrade -ysudo apt install -y curl wget git build-essentialwget https://go.dev/dl/go1.25.0.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.25.0.linux-amd64.tar.gzrm go1.25.0.linux-amd64.tar.gzecho -e '\n# Go Language\nexport PATH=$PATH:/usr/local/go/bin' >> ~/.bashrcsource ~/.bashrccurl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt-get install -y nodejscurl -fsSL https://get.pnpm.io/install.sh | sh source /home/eth/.bashrccurl -L https://foundry.paradigm.xyz | bash source ~/.bashrc~/.foundry/bin/foundryup sudo apt install -y makesudo apt install -y jqsudo apt install -y direnvecho -e '\n# Direnv hook\neval "$(direnv hook bash)"' >> ~/.bashrcsource ~/.bashrccurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y . "$HOME /.cargo/env" cargo install just curl https://mise.run | sh echo "eval \"\$(/home/eth/.local/bin/mise activate bash)\"" >> ~/.bashrcsource ~/.bashrc
1.3 验证安装 1 2 3 4 5 6 7 8 9 10 11 12 git --version go version node --version pnpm --version forge --version make --version jq --version direnv --version rustc --version just --version mise --version
二、获取 Sepolia 测试网资源 2.1 获取 Sepolia RPC URL 从以下服务之一获取 Sepolia RPC URL:
2.2 获取测试 ETH 在以下链接中获取测试币 SepoliaETH。
三、构建 OP-Stack 组件 3.1 克隆 optimism 和 op-geth 仓库 1 2 3 4 5 6 7 8 9 10 cd ~git clone https://github.com/ethereum-optimism/optimism.git cd optimismgit checkout v1.13.6 -b v1.13.6 git clone https://github.com/ethereum-optimism/op-geth.git cd op-gethgit checkout v1.101602.0 -b v1.101602.0
3.2 构建 op-geth,op-node,op-batcher,op-proposer 1 2 3 4 5 6 7 8 9 10 11 cd ~/optimism/op-gethmake geth cd ..make op-node op-batcher op-proposer ./op-geth/build/bin/geth --version ./op-node/bin/op-node --version ./op-batcher/bin/op-batcher --version ./op-proposer/bin/op-proposer --version
四、配置环境变量 4.1 生成账户 1 2 cd ~/optimism./packages/contracts-bedrock/scripts/getting-started/wallets.sh
此命令会生成五个地址及其私钥:
Admin(管理员)
Batcher(批处理者)
Proposer(提议者)
Sequencer(排序者)
Challenger(挑战者)
4.2 编辑环境变量文件 创建.envrc 文件
填写以下变量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 export GS_ADMIN_ADDRESS=export GS_ADMIN_PRIVATE_KEY=export GS_BATCHER_ADDRESS=export GS_BATCHER_PRIVATE_KEY=export GS_PROPOSER_ADDRESS=export GS_PROPOSER_PRIVATE_KEY=export GS_SEQUENCER_ADDRESS=export GS_SEQUENCER_PRIVATE_KEY=export GS_CHALLENGER_ADDRESS=export GS_CHALLENGER_PRIVATE_KEY=export L1_RPC_URL=export L1_BEACON_URL="https://ethereum-sepolia-beacon-api.publicnode.com" export L1_RPC_KIND=export L1_CHAIN_ID=11155111export L2_CHAIN_ID=export L1_BLOCK_TIME=12export L2_BLOCK_TIME=2
保存文件(Ctrl+O, Enter, Ctrl+X)
4.3 加载环境变量
验证环境变量是否加载
1 2 3 4 5 6 7 8 9 10 11 12 13 echo "=== 环境变量检查 ===" echo "GS_ADMIN_ADDRESS: $GS_ADMIN_ADDRESS " echo "GS_BATCHER_ADDRESS: $GS_BATCHER_ADDRESS " echo "GS_PROPOSER_ADDRESS: $GS_PROPOSER_ADDRESS " echo "GS_SEQUENCER_ADDRESS: $GS_SEQUENCER_ADDRESS " echo "GS_CHALLENGER_ADDRESS: $GS_CHALLENGER_ADDRESS " echo "L1_RPC_KIND: $L1_RPC_KIND " echo "L1_RPC_URL: $L1_RPC_URL " echo "L1_BEACON_URL: $L1_BEACON_URL " echo "L1_CHAIN_ID: $L1_CHAIN_ID " echo "L2_CHAIN_ID: $L2_CHAIN_ID " echo "L1_BLOCK_TIME: $L1_BLOCK_TIME " echo "L2_BLOCK_TIME: $L2_BLOCK_TIME "
4.4 为账户充值 为以下地址充值 SepoliaETH:
Admin — 0.5 SepoliaETH
Batcher — 0.1 SepoliaETH
Proposer — 0.2 SepoliaETH
1 2 3 4 cast balance $GS_ADMIN_ADDRESS --rpc-url $L1_RPC_URL cast balance $GS_BATCHER_ADDRESS --rpc-url $L1_RPC_URL cast balance $GS_PROPOSER_ADDRESS --rpc-url $L1_RPC_URL
五、部署 L1 合约 5.1 获取 op-deployer 1 2 3 4 5 6 7 8 cd ~/optimismmkdir -p binwget https://github.com/ethereum-optimism/optimism/releases/download/op-deployer%2Fv0.2.6/op-deployer-0.2.6-linux-amd64.tar.gz sudo tar -C ./bin -xzf op-deployer-0.2.6-linux-amd64.tar.gz --strip-components=1rm op-deployer-0.2.6-linux-amd64.tar.gz./bin/op-deployer --version
5.2 初始化 op-deployer 配置 1 2 mkdir -p ~/.deployer./bin/op-deployer init --l1-chain-id $L1_CHAIN_ID --l2-chain-ids $L2_CHAIN_ID --workdir .deployer
此命令会生成 intend.json 和 state.json
5.3 修改 intend.json 配置 1 nano .deployer/intent.toml
确保配置中包含以下内容并替换相应的地址:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 configType = "standard" l1ChainID = 11155111 opcmAddress = "0x6b6f9129efb1b7a48f84e3b787333d1dca02ee34" fundDevAccounts = false useInterop = false l1ContractsLocator = "tag://op-contracts/v2.2.0" l2ContractsLocator = "tag://op-contracts/v1.7.0-beta.1+l2-contracts" [[chains]] id = "0x00000000000000000000000000000000000000000000000000000000004f5da2" baseFeeVaultRecipient = "YOUR_ADMIN_ADDRESS" l1FeeVaultRecipient = "YOUR_ADMIN_ADDRESS" sequencerFeeVaultRecipient = "YOUR_ADMIN_ADDRESS" eip1559DenominatorCanyon = 250 eip1559Denominator = 50 eip1559Elasticity = 6 [chains.roles] l1ProxyAdminOwner = "0x1eb2ffc903729a0f03966b917003800b145f56e2" l2ProxyAdminOwner = "0x2fc3ffc903729a0f03966b917003800b145f67f3" systemConfigOwner = "YOUR_ADMIN_ADDRESS" unsafeBlockSigner = "YOUR_SEQUENCER_ADDRESS" batcher = "YOUR_BATCHER_ADDRESS" proposer = "YOUR_PROPOSER_ADDRESS" challenger = "0xfd1d2e729ae8eee2e146c033bf4400fe75284301"
5.4 部署 L1 合约 1 2 3 4 5 cast gas-price --rpc-url $L1_RPC_URL ./bin/op-deployer apply --workdir .deployer --l1-rpc-url $L1_RPC_URL --private-key $GS_ADMIN_PRIVATE_KEY
5.5 生成 L2 配置文件 1 2 3 4 5 ./bin/op-deployer inspect genesis --workdir .deployer $L2_CHAIN_ID > .deployer/genesis.json ./bin/op-deployer inspect rollup --workdir .deployer $L2_CHAIN_ID > .deployer/rollup.json
六、启动 Layer2 6.1 初始化并启动 op-geth 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 cd ~/optimism/op-gethopenssl rand -hex 32 > jwt.txt cp jwt.txt ../op-node/mkdir -p datadirbuild/bin/geth init --state.scheme=hash --datadir=datadir ../.deployer/genesis.json ./build/bin/geth \ --datadir ./datadir \ --http \ --http.corsdomain="*" \ --http.vhosts="*" \ --http.addr=0.0.0.0 \ --http.api=web3,debug,eth,txpool,net,engine,miner \ --ws \ --ws.addr=0.0.0.0 \ --ws.port=8546 \ --ws.origins="*" \ --ws.api=debug,eth,txpool,net,engine,miner \ --syncmode=full \ --gcmode=archive \ --nodiscover \ --maxpeers=0 \ --networkid=$L2_CHAIN_ID \ --authrpc.vhosts="*" \ --authrpc.addr=0.0.0.0 \ --authrpc.port=8551 \ --authrpc.jwtsecret=./jwt.txt \ --rollup.disabletxpoolgossip=true
6.2 启动 op-node 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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 \ --l1.beacon=$L1_BEACON_URL
6.3 启动 op-batcher 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 cd ~/optimism/op-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
6.4 启动 op-proposer 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 export OP_PROPOSER_WAIT_NODE_SYNC=true export OP_PROPOSER_PROPOSAL_INTERVAL=15mexport OP_PROPOSER_GAME_FACTORY_ADDRESS=$(cat ~/.deployer/state.json | jq -r '.opChainDeployments[0].disputeGameFactoryProxyAddress' )export OP_PROPOSER_GAME_TYPE=1cd ~/optimism/op-proposer./bin/op-proposer \ --poll-interval=12s \ --rpc.port=8560 \ --rollup-rpc=http://localhost:9545 \ --private-key=$GS_PROPOSER_PRIVATE_KEY \ --l1-eth-rpc=$L1_RPC_URL
七、验证部署 7.1 检查 L2 链状态 1 2 3 curl -X POST -H "Content-Type: application/json" \ --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \ $L2_RPC_URL
7.2 连接钱包到 Layer2 在 MetaMask 中添加自定义网络:
7.3 将 SepoliaETH 发送到 Bridge 合约 1 2 3 L1StandardBridge=$(cat ~/optimism/.deployer/state.json | jq -r '.opChainDeployments[0].l1StandardBridgeProxyAddress' ) echo "L1StandardBridge 地址: $L1StandardBridge "
通过 Metamask 向你的 桥接地址 发送(0.0001 SepoliaETH),发送成功后大约需要 5 分钟才能在 Layer2 上看到 ETH.
Hooray!Op Stack 部署成功!!!
八、基本转账 CLI 操作实例 8.1 从 L1 的 Admin 桥接到 L2 的 admin 1 2 3 4 5 6 7 8 9 10 11 cast send $L1StandardBridge \ --rpc-url $L1_RPC_URL \ --private-key $GS_ADMIN_PRIVATE_KEY \ --value 0.0001ether \ "depositETH(uint32,bytes)" \ 200000 \ "0x" cast balance $GS_ADMIN_ADDRESS --rpc-url $L1_RPC_URL cast balance $GS_ADMIN_ADDRESS --rpc-url $L2_RPC_URL
8.2 从 L1 的 Admin 桥接到 L2 的 Batcher 1 2 3 4 5 6 7 8 9 10 11 12 cast send $L1StandardBridge \ --rpc-url $L1_RPC_URL \ --private-key $GS_ADMIN_PRIVATE_KEY \ --value 0.0001ether \ "depositETHTo(address,uint32,bytes)" \ $GS_BATCHER_ADDRESS \ 200000 \ "0x" cast balance $GS_ADMIN_ADDRESS --rpc-url $L1_RPC_URL cast balance $GS_BATCHER_ADDRESS --rpc-url $L2_RPC_URL
8.3 L2 转账 1 2 3 4 5 6 7 8 9 cast send $GS_ADMIN_ADDRESS \ --rpc-url $L2_RPC_URL \ --private-key $GS_BATCHER_PRIVATE_KEY \ --value 0.00001ether cast balance $GS_ADMIN_ADDRESS --rpc-url $L2_RPC_URL cast balance $GS_BATCHER_ADDRESS --rpc-url $L2_RPC_URL