以太坊Layer2扩容:Optimistic vs ZK-Rollup完整对比

以太坊Layer2扩容:Optimistic vs ZK-Rollup完整对比

一、引言

以太坊主网15 TPS、Gas费飙升时动辄$50/笔。Layer2将计算移到链下,仅在L1提交压缩后的数据,实现100-2000x吞吐量提升。两条主线:Optimistic Rollup(乐观假设正确,事后挑战) vs ZK-Rollup(用零知识证明保证正确)。

二、Optimistic Rollup:乐观+欺诈证明

2.1 Arbitrum架构

go 复制代码
// Rollup区块结构
type RollupBlock struct {
    BlockNumber   uint64
    PrevHash      [32]byte
    StateRoot     [32]byte       // 执行后的状态根
    Transactions  [][]byte        // 压缩后的交易数据(CallData)
    Timestamp     uint64
}

// Sequencer: 排序交易并提交到L1
func (s *Sequencer) processBatch(txs []Transaction) *RollupBlock {
    // 1. 在L2执行所有交易
    stateDB := s.stateDB.Copy()
    for _, tx := range txs {
        stateDB.Execute(tx)
    }
    
    // 2. 构造区块
    block := &RollupBlock{
        BlockNumber:  s.nextBlockNum,
        StateRoot:    stateDB.Root(),
        Transactions: compressBatch(txs),  // 压缩交易数据
    }
    
    // 3. 提交到L1(仅提交StateRoot和压缩交易,无需完整状态)
    s.l1Contract.submitBlock(block)
    
    // 4. 立即返回结果(乐观!无需等待L1确认)
    return block
}

2.2 欺诈证明系统

solidity 复制代码
// L1上的Rollup验证合约
contract OptimisticRollup {
    struct Assertion {
        bytes32 stateRoot;     // 声称的状态根
        uint256 inboxCount;    // 处理的交易数
        address asserter;      // 提交者
        uint256 deadline;      // 挑战截止时间(通常7天)
    }
    
    mapping(uint256 => Assertion) public assertions;
    uint256 public confirmedIndex;
    
    // 提交断言(带保证金)
    function submitAssertion(bytes32 stateRoot, bytes calldata batchData) 
        external payable {
        require(msg.value >= MINIMUM_STAKE);
        
        assertions[nextAssertionID] = Assertion({
            stateRoot: stateRoot,
            asserter: msg.sender,
            deadline: block.timestamp + CHALLENGE_PERIOD  // 7天挑战期
        });
    }
    
    // ★ 二分查找欺诈证明(bisection protocol)
    function challengeAssertion(uint256 assertionID) external {
        Assertion memory assertion = assertions[assertionID];
        require(block.timestamp < assertion.deadline);
        
        // 挑战者指出执行中的具体步骤存在错误
        // 通过二分法在L1上单步执行验证
        // 如果挑战成功:挑战者获得保证金+asserter被罚没
    }
    
    // ★ 单步执行证明(One Step Proof)
    function oneStepProof(
        uint256 assertionID,
        uint256 stepIndex,       // 争议的执行步骤
        bytes calldata proof     // 该步骤的前后状态证明
    ) external {
        // 在L1上验证单步执行是否正确
        // 需要的:前状态Merkle证明 + 指令操作码 + 后状态证明
        
        bytes32 preStateRoot = verifyPreState(proof);
        bytes32 postStateRoot = executeOneStep(proof);  // L1执行单步OPCODE
        
        // 对比声称的状态 → 判定胜负
        if (postStateRoot != getClaimedState(assertionID, stepIndex)) {
            // 挑战成功!回滚断言
            slashAsserter(assertionID);
            rewardChallenger();
        }
    }
}

2.3 跨链桥(7天提款延迟的根本原因)

solidity 复制代码
// Optimistic Rollup的提款必须等挑战期结束(7天)
function withdrawToL1(address recipient, uint256 amount) external {
    // 1. 在L2上burn代币
    L2Bridge.burn(msg.sender, amount);
    
    // 2. 提交提款证明到L1
    bytes32 withdrawalRoot = merkleRoot(withdrawals);
    
    // 3. 等待7天挑战期(L1验证者可能发现L2执行错误)
    pendingWithdrawals.push(Withdrawal({
        recipient: recipient,
        amount: amount,
        timestamp: block.timestamp,
        challengeDeadline: block.timestamp + 7 days
    }));
    
    // 4. 7天后(无有效挑战)→ 释放资金
}

// 到期后提取
function finalizeWithdrawal(uint256 withdrawalID) external {
    Withdrawal memory w = pendingWithdrawals[withdrawalID];
    require(block.timestamp >= w.challengeDeadline);
    require(!w.challenged);
    
    // L1释放ETH
    (bool ok,) = w.recipient.call{value: w.amount}("");
    require(ok);
}

三、ZK-Rollup:零知识证明

3.1 zkSync Era架构

复制代码
L2交易 → Operator(Sequencer) → 批量执行 → 生成ZK Proof → 提交L1

Operator:
  1. 收集交易,本地执行
  2. 生成执行轨迹(Execution Trace)
  3. 用Plonky2/Boogie证明系统生成ZK证明
  4. 提交[StateDiff + ZK Proof]到L1

L1合约:
  verifyProof(proof) → 检查Proof有效性
  → 更新StateRoot → 立即可用(无等待期!)

3.2 ZK证明生成(简化版)

rust 复制代码
// ZK电路的简化表示
struct ZkRollupCircuit {
    // 公开输入(提交到L1)
    prev_state_root: Hash,
    new_state_root: Hash,
    transactions_hash: Hash,
    
    // 私有输入(Operator知道,不公开)
    transactions: Vec,
    merkle_proofs: Vec,
}

impl Circuit for ZkRollupCircuit {
    fn synthesize(&self, cs: &mut ConstraintSystem) {
        // 1. 验证Merkle Proof:证明交易涉及的账户在prev_state_root中
        for (tx, proof) in self.transactions.iter().zip(&self.merkle_proofs) {
            let account = self.verify_merkle_proof(proof);
            cs.enforce(account.address == tx.from);
        }
        
        // 2. 执行交易:验证状态转换
        let mut state = self.prev_state_root;
        for tx in &self.transactions {
            state = self.execute_transaction(state, tx);
            // 约束: nonce自增,balance减法,balance加法
            cs.enforce(tx.new_nonce == tx.old_nonce + 1);
            cs.enforce(sender.balance >= tx.amount + tx.fee);
        }
        
        // 3. 最终状态根匹配
        cs.enforce(state == self.new_state_root);
    }
}

3.3 L1验证合约

solidity 复制代码
contract ZKRollup {
    bytes32 public stateRoot;
    IVerifier public verifier;  // ZK验证器合约
    
    struct Batch {
        uint64 batchNumber;
        bytes32 prevStateRoot;
        bytes32 newStateRoot;
        bytes32 transactionsHash;
        bytes proof;  // ZK Proof (Plonky2 ~200bytes)
    }
    
    function commitBatch(Batch calldata batch) external {
        require(batch.prevStateRoot == stateRoot, "Wrong prev root");
        
        // ★ 核心:验证ZK Proof
        require(
            verifier.verify(
                batch.proof,
                [uint256(uint160(uint256(batch.prevStateRoot))),
                 uint256(uint160(uint256(batch.newStateRoot))),
                 uint256(uint160(uint256(batch.transactionsHash)))]
            ),
            "Invalid proof"
        );
        
        // Proof验证通过 → 立即更新状态!
        stateRoot = batch.newStateRoot;
        
        // 不需要等待期! 不需要欺诈证明!
        // 提款立即可用(或数小时内)
    }
}

四、Optimistic vs ZK 终极对比

维度 Optimistic Rollup ZK-Rollup
安全模型 欺诈证明(1-of-N诚实) 有效性证明(密码学)
提款时间 7天(挑战期) 分钟~小时(证明生成)
Gas成本 低(只存Calldata) 中(Calldata+Proof验证Gas)
证明生成 不需要 需要(~2分钟)
EVM兼容性 完整(Arbitrum等效EVM) 部分(zkEVM需适配)
TPS上限 ~4,000(Arbitrum) ~2,000(当前,理论更高)
去中心化程度 较低(Sequencer集中) 较低(Prover集中)
生态代表 Arbitrum, Optimism, Base zkSync, StarkNet, Polygon zkEVM

五、EIP-4844 Blob升级

solidity 复制代码
// EIP-4844 Proto-Danksharding: 引入Blob数据(每块~128KB)
// Rollup从此不需要把数据存在CALLDATA(贵),改用BLOB(便宜100x)
contract L2With4844 {
    function submitBatch(bytes calldata batchData) external {
        // 旧方式: CALLDATA 16 gas/byte
        // bytes memory data = batchData;  // 贵!
        
        // ★ 新方式: Blob 1 gas/byte (便宜16x!)
        // 使用EIP-4844 blob交易类型
        // blobHash = point_evaluation(blob)
        // L1合约只验证blobHash,不需要加载全部数据
        
        // Blob数据的可靠性和可用性:
        // - L1节点存储Blob数据18天(足够挑战期)
        // - 之后数据由L2 Sequencer/DA层维护
    }
}

六、跨链桥安全

solidity 复制代码
// Wormhole 3.26亿美元攻击的根本原因:
// Signature verification被绕过!
contract Bridge {
    mapping(address => bool) public guardians;
    
    function verifySignatures(
        bytes32 hash,
        bytes[] calldata signatures
    ) internal view returns (bool) {
        uint256 validCount = 0;
        address lastSigner = address(0);
        
        for (uint256 i = 0; i < signatures.length; i++) {
            address signer = ecrecover(hash, signatures[i]);
            
            // ❌ Wormhole的漏洞: 没有检查guardian是否有效!
            // 攻击者传入自己创建的假guardian签名
            if (guardians[signer]) {
                validCount++;
            }
            
            // 要求签名者地址递增(防重放), 但没阻止假guardian
        }
        
        return validCount >= requiredGuardians;
    }
}

// ✅ 修复: 严格验证+多重检查
contract SafeBridge {
    function verifySignaturesSafe(
        bytes32 hash,
        bytes[] calldata signatures
    ) internal view returns (bool) {
        uint256 validCount = 0;
        address lastSigner = address(0);
        
        for (uint256 i = 0; i < signatures.length; i++) {
            address signer = recoverSigner(hash, signatures[i]);
            
            // 1. 必须是注册的guardian
            require(guardians[signer], "Not guardian");
            
            // 2. 地址必须严格递增(防重放)
            require(signer > lastSigner, "Invalid order");
            
            // 3. 签名必须唯一(防重复使用相同签名)
            require(!usedSignatures[signatures[i]], "Duplicate sig");
            
            validCount++;
            lastSigner = signer;
            usedSignatures[signatures[i]] = true;
        }
        
        return validCount >= requiredGuardians;
    }
}

七、总结

Layer2选型指南:

  1. EVM兼容优先 → Arbitrum/Optimism (完整生态+7天提款)
  2. 安全性+速度优先 → zkSync (密码学保证+分钟提款)
  3. 游戏/NFT/高频 → StarkNet (自定义Cairo VM,极致TPS)
  4. 通用DApp → Polygon zkEVM (字节码级别EVM兼容)

2024年EIP-4844上线后,Rollup成本再降10-50x,Layer2时代正式到来。

相关推荐
汇策研习社5 小时前
斐波那契均线交易体系:21/55/89三重均线趋势战法详解
大数据·经验分享·金融·区块链·fastbull
同花顺期货通5 小时前
期货新手入门品种筛选:2026年低保证金高流动性品种深度解析
区块链
磐链科技8 小时前
从Truffle到Hardhat:DApp开发框架的技术演进与工程化最佳实践
区块链
网渡科技12 小时前
智能合约审计流程详解:如何在部署前发现高危漏洞
区块链·智能合约
LedgerNinja2 天前
WEEX 真实情况如何?交易平台如何判断是否可靠
大数据·人工智能·区块链
卡牌RWA研究院3 天前
Relique:一张精品卡牌如何从收藏品变成可交易的链上资产?
设计模式·金融·区块链·创业创新
Web3_Daisy3 天前
Pump.fun 与 FOMO 竞争背后的 Meme 市场变局
大数据·人工智能·金融·web3·区块链
磐链科技3 天前
跨链互操作性:打破RWA价值孤岛的终极解决方案
区块链
IvorySQL3 天前
PostgreSQL 日报| PostgreSQL 19 默认 WAL 压缩算法(8 月 8 日)
数据库·postgresql·区块链