《绿野仙踪》与Layer 2扩展:翡翠城的乐观Rollup
1939年,维克多·弗莱明的《绿野仙踪》(The Wizard of Oz)讲述了一个关于"寻找"的故事:多萝西"被"龙卷风"带到"奥兹国"——一个"魔法"的"世界"——"寻找"回家的"路"。2026年,区块链的"Layer 2扩展"正在"构建"一个"翡翠城"——"乐观Rollup"(Optimistic Rollup)——一个"更快"、"更便宜"、"更高效"的"第二层"世界。
第一幕:Layer 2的"奥兹国"隐喻
第一场:从"堪萨斯"到"奥兹国"——"Layer 1"到"Layer 2"
《绿野仙踪》的"世界"与区块链的"层次":
- 堪萨斯(Layer 1):多萝西的"家"——"安全"、"熟悉"、"稳定"。
- 奥兹国(Layer 2):多萝西"到达"的"魔法"世界——"色彩"丰富、"效率"高、"成本"低。
- 龙卷风(跨链桥):多萝西"被"龙卷风"带到"奥兹国——"资产"被"桥接"到Layer 2。
第二场:从"黄砖路"到"Rollup"——"路径"的"隐喻"
《绿野仙踪》的"黄砖路"——"通向"翡翠城的"路":
- 黄砖路(Rollup):一条"清晰"的"路径"——"引导"用户从Layer 1到Layer 2。
- 翡翠城(Layer 2):一个"更好"的"世界"——"更快"的交易、"更低"的费用。
- 奥兹国的"魔法"(Optimistic Proof):"乐观"的"假设"——"所有"交易都是"有效"的,除非"有人"提出"挑战"。
第三场:从"多萝西"到"用户"——"角色"的"映射"
多萝西的"旅程"与用户的"Layer 2体验":
- 多萝西被"龙卷风"带到奥兹国——用户"桥接"资产到Layer 2。
- 多萝西"跟随"黄砖路——用户"使用"Layer 2"交易"。
- 多萝西"到达"翡翠城——用户"享受"Layer 2的"好处"——"更快"、"更便宜"。
- 多萝西"回家"——用户"提现"资产"回到"Layer 1。
第二幕:乐观Rollup的"技术"深度
第一场:从"乐观"到"欺诈证明"——"Optimistic Rollup"的"核心"
乐观Rollup的"核心"机制:
- 乐观假设:所有交易"默认"是"有效"的——"不"立即"验证"。
- 欺诈证明(Fraud Proof):如果"有人"发现"无效"交易——"提交"欺诈证明。
- 挑战期(Challenge Period):一个"窗口"期——"允许"任何人"挑战"交易。
- 最终性(Finality):挑战期"结束"后——交易"最终"确认。
第二场:从"EVM"到"Layer 2"——"兼容"的"EVM"
乐观Rollup的"EVM兼容性":
- EVM等效:乐观Rollup"兼容"EVM——"Solidity"代码"可以直接"部署。
- 工具兼容:乐观Rollup"兼容"Ethereum"工具"——"MetaMask"、"Hardhat"、"Etherscan"。
- 用户体验:用户"几乎"感觉不到"区别"——"地址"格式、"交易"流程、"Gas"机制。
第三场:从"Optimism"到"Arbitrum"——"乐观Rollup"的"比较"
主流乐观Rollup的"比较":
- Optimism:OP Stack——"模块化"、"可"定制、"开源"。
- Arbitrum:Arbitrum Nitro——"WASM"引擎、"更"高效、"更"兼容。
- Base:基于OP Stack的"Coinbase"Layer 2——"主流"采用、"合规"优先。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract OptimisticRollup is AccessControl, ReentrancyGuard {
bytes32 public constant SEQUENCER_ROLE = keccak256("SEQUENCER_ROLE");
bytes32 public constant CHALLENGER_ROLE = keccak256("CHALLENGER_ROLE");
enum TransactionStatus {
PENDING, OPTIMISTIC, CHALLENGED, FINALIZED, REVERTED
}
struct RollupBlock {
uint256 blockNumber;
bytes32 stateRoot;
bytes32 transactionsRoot;
bytes32 receiptRoot;
address proposer;
uint256 timestamp;
uint256 challengePeriod;
bool isFinalized;
}
struct L2Transaction {
bytes32 txHash;
address sender;
address target;
uint256 value;
bytes data;
uint256 gasLimit;
uint256 nonce;
TransactionStatus status;
uint256 timestamp;
}
struct Challenge {
uint256 challengeId;
bytes32 blockHash;
address challenger;
bytes32 fraudulentTxHash;
bytes proof;
uint256 timestamp;
bool isResolved;
bool isValid;
}
mapping(uint256 => RollupBlock) public blocks;
mapping(bytes32 => L2Transaction) public transactions;
mapping(uint256 => Challenge) public challenges;
uint256 public blockCount;
uint256 public transactionCount;
uint256 public challengeCount;
uint256 public challengePeriod = 7 days;
uint256 public bondAmount = 1 ether;
event BlockProposed(uint256 indexed blockNumber, bytes32 stateRoot, address proposer);
event TransactionSubmitted(bytes32 indexed txHash, address indexed sender, address target);
event ChallengeSubmitted(uint256 indexed challengeId, bytes32 indexed blockHash, address challenger);
event BlockFinalized(uint256 indexed blockNumber, bytes32 stateRoot);
function proposeBlock(bytes32 _stateRoot, bytes32 _transactionsRoot, bytes32 _receiptRoot) external onlyRole(SEQUENCER_ROLE) {
blockCount++;
blocks[blockCount] = RollupBlock({
blockNumber: blockCount,
stateRoot: _stateRoot,
transactionsRoot: _transactionsRoot,
receiptRoot: _receiptRoot,
proposer: msg.sender,
timestamp: block.timestamp,
challengePeriod: challengePeriod,
isFinalized: false
});
emit BlockProposed(blockCount, _stateRoot, msg.sender);
}
function submitTransaction(
address _target,
uint256 _value,
bytes calldata _data,
uint256 _gasLimit
) external returns (bytes32) {
transactionCount++;
bytes32 txHash = keccak256(abi.encodePacked(
msg.sender, _target, _value, _data, _gasLimit, transactionCount
));
transactions[txHash] = L2Transaction({
txHash: txHash,
sender: msg.sender,
target: _target,
value: _value,
data: _data,
gasLimit: _gasLimit,
nonce: transactionCount,
status: TransactionStatus.OPTIMISTIC,
timestamp: block.timestamp
});
emit TransactionSubmitted(txHash, msg.sender, _target);
return txHash;
}
function submitChallenge(
bytes32 _blockHash,
bytes32 _fraudulentTxHash,
bytes calldata _proof
) external payable onlyRole(CHALLENGER_ROLE) {
require(msg.value >= bondAmount, "Insufficient bond");
challengeCount++;
challenges[challengeCount] = Challenge({
challengeId: challengeCount,
blockHash: _blockHash,
challenger: msg.sender,
fraudulentTxHash: _fraudulentTxHash,
proof: _proof,
timestamp: block.timestamp,
isResolved: false,
isValid: false
});
emit ChallengeSubmitted(challengeCount, _blockHash, msg.sender);
}
function resolveChallenge(uint256 _challengeId, bool _isValid) external onlyRole(SEQUENCER_ROLE) {
Challenge storage challenge = challenges[_challengeId];
require(!challenge.isResolved, "Already resolved");
challenge.isResolved = true;
challenge.isValid = _isValid;
if (_isValid) {
L2Transaction storage tx = transactions[challenge.fraudulentTxHash];
tx.status = TransactionStatus.REVERTED;
payable(challenge.challenger).transfer(bondAmount * 2);
} else {
payable(blocks[0].proposer).transfer(bondAmount);
}
}
function finalizeBlock(uint256 _blockNumber) external onlyRole(SEQUENCER_ROLE) {
RollupBlock storage block = blocks[_blockNumber];
require(!block.isFinalized, "Already finalized");
require(block.timestamp + challengePeriod < block.timestamp, "Challenge period not over");
block.isFinalized = true;
emit BlockFinalized(_blockNumber, block.stateRoot);
}
function getTransactionStatus(bytes32 _txHash) external view returns (TransactionStatus) {
return transactions[_txHash].status;
}
function getBlockCount() external view returns (uint256) {
return blockCount;
}
}
第三幕:Layer 2的"应用"场景
第一场:从"DeFi"到"Layer 2"——"DeFi"的"扩展"
Layer 2在DeFi中的"应用":
- Uniswap on Arbitrum:Uniswap"部署"在Arbitrum上——"更快"的交易、"更低"的费用。
- Aave on Optimism:Aave"部署"在Optimism上——"更多"用户、"更"活跃。
- dYdX on StarkNet:dYdX"部署"在StarkNet上——"高频"交易、"低"延迟。
第二场:从"游戏"到"Layer 2"——"游戏"的"扩展"
Layer 2在游戏中的"应用":
- Immutable X:一个"游戏"Layer 2——"无"Gas费、"即时"交易。
- Gods Unchained:一个"卡牌"游戏——"Immutable X"上"交易"卡牌。
- Illuvium:一个"开放"世界游戏——"Layer 2"上"交易"资产。
第三场:从"绿野仙踪"到"Layer 2"——"翡翠城"的"魔法"
《绿野仙踪》的"翡翠城"——"魔法"的"地方"——与Layer 2的"魔法":
- 翡翠城的"魔法":奥兹国的"魔法"——"让"一切"更"美好"。
- Layer 2的"魔法":Rollup的"技术"——"让"交易"更"快"、"更"便宜。
- 奥兹国的"真相":奥兹"不是"魔法师——"只是一个"普通人"。
- Layer 2的"真相":Rollup"不是"完美的——"有"挑战期、"需要"信任"。
import hashlib
import json
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
from datetime import datetime, timedelta
import random
@dataclass
class L2Block:
block_number: int
state_root: str
transactions_root: str
proposer: str
timestamp: int
is_finalized: bool
@dataclass
class L2Transaction:
tx_hash: str
sender: str
target: str
value: int
data: str
status: str
class OptimisticRollupSimulator:
def __init__(self, challenge_period: int = 7):
self.blocks: List[L2Block] = []
self.transactions: Dict[str, L2Transaction] = {}
self.challenges: List[Dict] = []
self.challenge_period = challenge_period
self.block_count = 0
self.tx_count = 0
def propose_block(self, state_root: str, transactions_root: str, proposer: str) -> L2Block:
self.block_count += 1
block = L2Block(
block_number=self.block_count,
state_root=state_root,
transactions_root=transactions_root,
proposer=proposer,
timestamp=int(datetime.now().timestamp()),
is_finalized=False
)
self.blocks.append(block)
return block
def submit_transaction(self, sender: str, target: str, value: int, data: str) -> L2Transaction:
self.tx_count += 1
tx_hash = hashlib.sha256(f"{sender}{target}{value}{data}{self.tx_count}".encode()).hexdigest()[:16]
tx = L2Transaction(
tx_hash=tx_hash,
sender=sender,
target=target,
value=value,
data=data,
status='optimistic'
)
self.transactions[tx_hash] = tx
return tx
def submit_challenge(self, block_number: int, fraudulent_tx_hash: str, challenger: str) -> Dict:
challenge = {
'challenge_id': len(self.challenges) + 1,
'block_number': block_number,
'fraudulent_tx_hash': fraudulent_tx_hash,
'challenger': challenger,
'timestamp': datetime.now().isoformat(),
'is_resolved': False,
'is_valid': False
}
self.challenges.append(challenge)
tx = self.transactions.get(fraudulent_tx_hash)
if tx:
tx.status = 'challenged'
return challenge
def resolve_challenge(self, challenge_id: int, is_valid: bool) -> Dict:
challenge = self.challenges[challenge_id - 1]
challenge['is_resolved'] = True
challenge['is_valid'] = is_valid
if is_valid:
tx = self.transactions.get(challenge['fraudulent_tx_hash'])
if tx:
tx.status = 'reverted'
return {'success': True, 'is_valid': is_valid}
def finalize_block(self, block_number: int) -> Dict:
block = self.blocks[block_number - 1]
if block.is_finalized:
return {'success': False, 'error': 'Already finalized'}
now = int(datetime.now().timestamp())
if now < block.timestamp + self.challenge_period * 86400:
return {'success': False, 'error': 'Challenge period not over'}
block.is_finalized = True
return {'success': True, 'block_number': block_number}
def calculate_l2_gas_savings(self, l1_gas_cost: float, l2_gas_cost: float) -> float:
return (l1_gas_cost - l2_gas_cost) / l1_gas_cost * 100
def simulate_oz_journey(self, num_transactions: int = 100) -> Dict:
proposer = '0xSequencer'
state_root = hashlib.sha256(b'state').hexdigest()
self.propose_block(state_root, hashlib.sha256(b'tx').hexdigest(), proposer)
for i in range(num_transactions):
self.submit_transaction(
f'0xDorothy{i}',
f'0xEmeraldCity{i}',
random.randint(1, 1000),
f'move_to_oz_{i}'
)
return {
'blocks': len(self.blocks),
'transactions': len(self.transactions),
'finalized': sum(1 for b in self.blocks if b.is_finalized),
'gas_savings': self.calculate_l2_gas_savings(100, 0.1)
}
rollup = OptimisticRollupSimulator()
result = rollup.simulate_oz_journey(50)
print(f"L2 transactions: {result['transactions']}, Gas savings: {result['gas_savings']:.1f}%")
第四幕:Layer 2的"未来"与"挑战"
第一场:从"乐观Rollup"到"ZK-Rollup"——"技术"的"演进"
从乐观Rollup到ZK-Rollup的"演进":
- 乐观Rollup:乐观"假设"——"欺诈证明"——"延迟"最终性。
- ZK-Rollup:零知识"证明"——"即时"最终性——"更快"、"更"安全。
- 混合Rollup:乐观+ZK——"灵活"选择。
第二场:从"Layer 2"到"Superchain"——"生态"的"扩展"
Superchain的"概念":
- OP Stack:Optimism的"模块化"协议——"创建"自己的"Layer 2"。
- Superchain:多个"OP Stack"链的"网络"——"共享"安全、"共享"桥、"共享"治理。
- Base、Zora、Mode:基于OP Stack的"Layer 2"——"加入"Superchain"生态"。
第三场:从"绿野仙踪"到"Layer 2"——"回家"的"路"
《绿野仙踪》的"结局"——多萝西"回家"了——"红色"鞋子"的"魔法":
- 多萝西的"回家":多萝西"发现"——"回家"的"能力"一直"在"自己"身上。
- Layer 2的"回家":用户"提现"资产"回到"Layer 1——"安全"、"可靠"。
- 从"奥兹国"到"堪萨斯":从"Layer 2"到"Layer 1"——"去中心化"的"最终"保障。
const { ethers } = require('ethers');
const crypto = require('crypto');
class OptimisticRollupClient {
constructor(providerUrl) {
this.provider = new ethers.providers.JsonRpcProvider(providerUrl);
this.blocks = [];
this.transactions = new Map();
this.challenges = [];
this.blockCount = 0;
this.txCount = 0;
this.challengePeriod = 7 * 86400;
}
async proposeBlock(stateRoot, transactionsRoot, proposer) {
this.blockCount++;
const block = {
blockNumber: this.blockCount,
stateRoot,
transactionsRoot,
proposer,
timestamp: Math.floor(Date.now() / 1000),
isFinalized: false
};
this.blocks.push(block);
return block;
}
async submitTransaction(sender, target, value, data) {
this.txCount++;
const txHash = ethers.utils.keccak256(
ethers.utils.toUtf8Bytes(`${sender}${target}${value}${data}${this.txCount}`)
);
const tx = {
txHash,
sender,
target,
value: ethers.BigNumber.from(value),
data,
status: 'optimistic'
};
this.transactions.set(txHash, tx);
return tx;
}
async submitChallenge(blockNumber, fraudulentTxHash, challenger) {
const challenge = {
challengeId: this.challenges.length + 1,
blockNumber,
fraudulentTxHash,
challenger,
timestamp: Math.floor(Date.now() / 1000),
isResolved: false,
isValid: false
};
this.challenges.push(challenge);
const tx = this.transactions.get(fraudulentTxHash);
if (tx) tx.status = 'challenged';
return challenge;
}
async resolveChallenge(challengeId, isValid) {
const challenge = this.challenges[challengeId - 1];
challenge.isResolved = true;
challenge.isValid = isValid;
if (isValid) {
const tx = this.transactions.get(challenge.fraudulentTxHash);
if (tx) tx.status = 'reverted';
}
return { success: true, isValid };
}
async finalizeBlock(blockNumber) {
const block = this.blocks[blockNumber - 1];
if (!block || block.isFinalized) return { success: false };
const now = Math.floor(Date.now() / 1000);
if (now < block.timestamp + this.challengePeriod) {
return { success: false, error: 'Challenge period not over' };
}
block.isFinalized = true;
return { success: true };
}
calculateGasSavings(l1Gas, l2Gas) {
return ((l1Gas - l2Gas) / l1Gas * 100).toFixed(1);
}
}
const client = new OptimisticRollupClient('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY');
client.proposeBlock('0xStateRoot', '0xTxRoot', '0xSequencer')
.then(b => console.log('L2 block:', b.blockNumber));
终场:从"奥兹国"到"Layer 2"——"扩展"的"魔法"
《绿野仙踪》的"翡翠城"——"魔法"的"地方"——与"Layer 2"的"世界"一样——"更快"、"更便宜"、"更高效"。乐观Rollup是"黄砖路"——"引导"用户从Layer 1到Layer 2。
但Layer 2的"魔法"不是"魔法"——是"技术"。乐观Rollup的"欺诈证明"、ZK-Rollup的"零知识证明"——这些"技术"让"扩展"成为"可能"。
在这个万物皆可Token化的时代,技术的迭代往往比镜头切换更快。作为北京城市学院2021级广播电视编导的毕业生,我始终在影像与区块链的交汇处寻找共鸣。感谢阅读,我是王森涛,让我们在视听与去中心化的世界里,继续探索。