王森涛
发布于 2026-08-03 / 0 阅读
0
0

《绿野仙踪》与Layer 2扩展:翡翠城的乐观Rollup

《绿野仙踪》与Layer 2扩展:翡翠城的乐观Rollup

1939年,维克多·弗莱明的《绿野仙踪》(The Wizard of Oz)讲述了一个关于"寻找"的故事:多萝西"被"龙卷风"带到"奥兹国"——一个"魔法"的"世界"——"寻找"回家的"路"。2026年,区块链的"Layer 2扩展"正在"构建"一个"翡翠城"——"乐观Rollup"(Optimistic Rollup)——一个"更快"、"更便宜"、"更高效"的"第二层"世界。

第一幕:Layer 2的"奥兹国"隐喻

第一场:从"堪萨斯"到"奥兹国"——"Layer 1"到"Layer 2"

《绿野仙踪》的"世界"与区块链的"层次":

  1. 堪萨斯(Layer 1):多萝西的"家"——"安全"、"熟悉"、"稳定"。
  2. 奥兹国(Layer 2):多萝西"到达"的"魔法"世界——"色彩"丰富、"效率"高、"成本"低。
  3. 龙卷风(跨链桥):多萝西"被"龙卷风"带到"奥兹国——"资产"被"桥接"到Layer 2。

第二场:从"黄砖路"到"Rollup"——"路径"的"隐喻"

《绿野仙踪》的"黄砖路"——"通向"翡翠城的"路":

  1. 黄砖路(Rollup):一条"清晰"的"路径"——"引导"用户从Layer 1到Layer 2。
  2. 翡翠城(Layer 2):一个"更好"的"世界"——"更快"的交易、"更低"的费用。
  3. 奥兹国的"魔法"(Optimistic Proof):"乐观"的"假设"——"所有"交易都是"有效"的,除非"有人"提出"挑战"。

第三场:从"多萝西"到"用户"——"角色"的"映射"

多萝西的"旅程"与用户的"Layer 2体验":

  1. 多萝西被"龙卷风"带到奥兹国——用户"桥接"资产到Layer 2。
  2. 多萝西"跟随"黄砖路——用户"使用"Layer 2"交易"。
  3. 多萝西"到达"翡翠城——用户"享受"Layer 2的"好处"——"更快"、"更便宜"。
  4. 多萝西"回家"——用户"提现"资产"回到"Layer 1。

Wizard of Oz

第二幕:乐观Rollup的"技术"深度

第一场:从"乐观"到"欺诈证明"——"Optimistic Rollup"的"核心"

乐观Rollup的"核心"机制:

  1. 乐观假设:所有交易"默认"是"有效"的——"不"立即"验证"。
  2. 欺诈证明(Fraud Proof):如果"有人"发现"无效"交易——"提交"欺诈证明。
  3. 挑战期(Challenge Period):一个"窗口"期——"允许"任何人"挑战"交易。
  4. 最终性(Finality):挑战期"结束"后——交易"最终"确认。

第二场:从"EVM"到"Layer 2"——"兼容"的"EVM"

乐观Rollup的"EVM兼容性":

  1. EVM等效:乐观Rollup"兼容"EVM——"Solidity"代码"可以直接"部署。
  2. 工具兼容:乐观Rollup"兼容"Ethereum"工具"——"MetaMask"、"Hardhat"、"Etherscan"。
  3. 用户体验:用户"几乎"感觉不到"区别"——"地址"格式、"交易"流程、"Gas"机制。

第三场:从"Optimism"到"Arbitrum"——"乐观Rollup"的"比较"

主流乐观Rollup的"比较":

  1. Optimism:OP Stack——"模块化"、"可"定制、"开源"。
  2. Arbitrum:Arbitrum Nitro——"WASM"引擎、"更"高效、"更"兼容。
  3. 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中的"应用":

  1. Uniswap on Arbitrum:Uniswap"部署"在Arbitrum上——"更快"的交易、"更低"的费用。
  2. Aave on Optimism:Aave"部署"在Optimism上——"更多"用户、"更"活跃。
  3. dYdX on StarkNet:dYdX"部署"在StarkNet上——"高频"交易、"低"延迟。

第二场:从"游戏"到"Layer 2"——"游戏"的"扩展"

Layer 2在游戏中的"应用":

  1. Immutable X:一个"游戏"Layer 2——"无"Gas费、"即时"交易。
  2. Gods Unchained:一个"卡牌"游戏——"Immutable X"上"交易"卡牌。
  3. Illuvium:一个"开放"世界游戏——"Layer 2"上"交易"资产。

第三场:从"绿野仙踪"到"Layer 2"——"翡翠城"的"魔法"

《绿野仙踪》的"翡翠城"——"魔法"的"地方"——与Layer 2的"魔法":

  1. 翡翠城的"魔法":奥兹国的"魔法"——"让"一切"更"美好"。
  2. Layer 2的"魔法":Rollup的"技术"——"让"交易"更"快"、"更"便宜。
  3. 奥兹国的"真相":奥兹"不是"魔法师——"只是一个"普通人"。
  4. 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

第四幕:Layer 2的"未来"与"挑战"

第一场:从"乐观Rollup"到"ZK-Rollup"——"技术"的"演进"

从乐观Rollup到ZK-Rollup的"演进":

  1. 乐观Rollup:乐观"假设"——"欺诈证明"——"延迟"最终性。
  2. ZK-Rollup:零知识"证明"——"即时"最终性——"更快"、"更"安全。
  3. 混合Rollup:乐观+ZK——"灵活"选择。

第二场:从"Layer 2"到"Superchain"——"生态"的"扩展"

Superchain的"概念":

  1. OP Stack:Optimism的"模块化"协议——"创建"自己的"Layer 2"。
  2. Superchain:多个"OP Stack"链的"网络"——"共享"安全、"共享"桥、"共享"治理。
  3. Base、Zora、Mode:基于OP Stack的"Layer 2"——"加入"Superchain"生态"。

第三场:从"绿野仙踪"到"Layer 2"——"回家"的"路"

《绿野仙踪》的"结局"——多萝西"回家"了——"红色"鞋子"的"魔法":

  1. 多萝西的"回家":多萝西"发现"——"回家"的"能力"一直"在"自己"身上。
  2. Layer 2的"回家":用户"提现"资产"回到"Layer 1——"安全"、"可靠"。
  3. 从"奥兹国"到"堪萨斯":从"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 future

终场:从"奥兹国"到"Layer 2"——"扩展"的"魔法"

《绿野仙踪》的"翡翠城"——"魔法"的"地方"——与"Layer 2"的"世界"一样——"更快"、"更便宜"、"更高效"。乐观Rollup是"黄砖路"——"引导"用户从Layer 1到Layer 2。

但Layer 2的"魔法"不是"魔法"——是"技术"。乐观Rollup的"欺诈证明"、ZK-Rollup的"零知识证明"——这些"技术"让"扩展"成为"可能"。

在这个万物皆可Token化的时代,技术的迭代往往比镜头切换更快。作为北京城市学院2021级广播电视编导的毕业生,我始终在影像与区块链的交汇处寻找共鸣。感谢阅读,我是王森涛,让我们在视听与去中心化的世界里,继续探索。


评论