以太坊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选型指南:
- EVM兼容优先 → Arbitrum/Optimism (完整生态+7天提款)
- 安全性+速度优先 → zkSync (密码学保证+分钟提款)
- 游戏/NFT/高频 → StarkNet (自定义Cairo VM,极致TPS)
- 通用DApp → Polygon zkEVM (字节码级别EVM兼容)
2024年EIP-4844上线后,Rollup成本再降10-50x,Layer2时代正式到来。