Layer2 扩容解决方案详解 🔄
1. Layer2 基础概念
1.1 什么是 Layer2?
Layer2 是建立在以太坊主网(Layer1)之上的扩容解决方案,它:
- 继承以太坊的安全性
- 提供更高的交易吞吐量
- 降低交易费用
- 保持去中心化特性
1.2 主要类型
- Rollups
- Optimistic Rollups
- ZK Rollups
- 状态通道
- Plasma
- Validium
2. Optimistic Rollups
2.1 工作原理
contract OptimisticRollup {struct Transaction {address from;address to;uint256 value;bytes data;}struct Batch {bytes32 stateRoot;Transaction[] transactions;uint256 timestamp;}mapping(uint256 => Batch) public batches;uint256 public currentBatch;// 挑战期uint256 public constant CHALLENGE_PERIOD = 7 days;function submitBatch(bytes32 newStateRoot,Transaction[] calldata transactions) external {// 提交新批次batches[currentBatch] = Batch({stateRoot: newStateRoot,transactions: transactions,timestamp: block.timestamp});emit BatchSubmitted(currentBatch, newStateRoot);currentBatch++;}function challengeBatch(uint256 batchId,bytes calldata proof) external {require(block.timestamp <= batches[batchId].timestamp + CHALLENGE_PERIOD,"Challenge period expired");// 验证挑战证明require(verifyProof(proof), "Invalid fraud proof");// 回滚状态revertBatch(batchId);}
}
2.2 交易提交
async function submitToOptimisticRollup(transaction) {const rollupProvider = new ethers.providers.JsonRpcProvider(ROLLUP_RPC_URL);const wallet = new ethers.Wallet(PRIVATE_KEY, rollupProvider);// 构建交易const tx = await wallet.sendTransaction({to: transaction.to,value: transaction.value,data: transaction.data});// 等待交易确认await tx.wait();// 等待状态根提交到 L1await waitForStateCommitment(tx.hash);
}
3. ZK Rollups
3.1 基础实现
contract ZKRollup {struct ZKProof {uint256[2] a;uint256[2][2] b;uint256[2] c;}struct Batch {bytes32 stateRoot;bytes32 transactionsHash;ZKProof proof;}mapping(uint256 => Batch) public batches;function verifyAndSubmitBatch(bytes32 newStateRoot,bytes32 txHash,ZKProof calldata proof) external {require(verifyZKProof(proof), "Invalid ZK proof");batches[currentBatch] = Batch({stateRoot: newStateRoot,transactionsHash: txHash,proof: proof});emit BatchVerified(currentBatch, newStateRoot);}
}
3.2 证明生成
async function generateZKProof(transactions, state) {// 使用 circom 和 snarkjs 生成证明const circuit = await compileCircuit("rollup.circom");const setup = await generateSetup(circuit);const input = {transactions: transactions,oldState: state.old,newState: state.new};const proof = await generateProof(circuit, input, setup);return proof;
}
4. 状态通道
4.1 支付通道
contract PaymentChannel {address public participant1;address public participant2;uint256 public expiresAt;mapping(address => uint256) public balances;constructor(address _participant2) payable {participant1 = msg.sender;participant2 = _participant2;balances[msg.sender] = msg.value;expiresAt = block.timestamp + 1 days;}function closeChannel(uint256 amount1,uint256 amount2,bytes memory signature1,bytes memory signature2) external {require(verifySignature(amount1, amount2, signature1, participant1) &&verifySignature(amount1, amount2, signature2, participant2),"Invalid signatures");balances[participant1] = amount1;balances[participant2] = amount2;// 分配资金payable(participant1).transfer(amount1);payable(participant2).transfer(amount2);}
}
4.2 状态更新
async function updateChannelState(channel, newState) {// 签名新状态const signature = await wallet.signMessage(ethers.utils.arrayify(ethers.utils.solidityKeccak256(["address", "uint256", "uint256"],[channel.address, newState.amount1, newState.amount2])));// 交换签名await exchangeSignatures(channel.counterparty, signature);return {state: newState,signature: signature};
}
5. Plasma
5.1 Plasma Chain
contract PlasmaChain {struct PlasmaBlock {bytes32 root; // Merkle rootuint256 timestamp;address operator;}mapping(uint256 => PlasmaBlock) public plasmaBlocks;uint256 public currentBlock;function submitBlock(bytes32 root) external {plasmaBlocks[currentBlock] = PlasmaBlock({root: root,timestamp: block.timestamp,operator: msg.sender});emit BlockSubmitted(currentBlock, root);currentBlock++;}function withdraw(uint256 blockNum,bytes calldata txBytes,bytes32[] calldata proof) external {require(verifyMerkleProof(plasmaBlocks[blockNum].root,keccak256(txBytes),proof),"Invalid merkle proof");// 处理提款processWithdrawal(txBytes);}
}
5.2 Merkle 树实现
class MerkleTree {constructor(leaves) {this.leaves = leaves.map(leaf => keccak256(leaf));this.layers = [this.leaves];this.buildTree();}buildTree() {while (this.layers[this.layers.length - 1].length > 1) {this.layers.push(this.getNextLayer(this.layers[this.layers.length - 1]));}}getProof(index) {let proof = [];let currentIndex = index;for (let i = 0; i < this.layers.length - 1; i++) {const layer = this.layers[i];const isRight = currentIndex % 2;const pairIndex = isRight ? currentIndex - 1 : currentIndex + 1;if (pairIndex < layer.length) {proof.push(layer[pairIndex]);}currentIndex = Math.floor(currentIndex / 2);}return proof;}
}
6. 跨 Layer 通信
6.1 消息桥接
contract MessageBridge {mapping(bytes32 => bool) public processedMessages;event MessageSent(address indexed from,address indexed to,bytes data,uint256 nonce);function sendMessage(address to,bytes calldata data) external {bytes32 messageHash = keccak256(abi.encodePacked(msg.sender,to,data,block.number));emit MessageSent(msg.sender, to, data, block.number);}function receiveMessage(address from,address to,bytes calldata data,uint256 nonce,bytes calldata proof) external {bytes32 messageHash = keccak256(abi.encodePacked(from, to, data, nonce));require(!processedMessages[messageHash],"Message already processed");require(verifyMessageProof(messageHash, proof),"Invalid message proof");processedMessages[messageHash] = true;// 执行跨层消息executeMessage(to, data);}
}
6.2 资产桥接
contract TokenBridge {mapping(address => mapping(address => uint256)) public deposits;function deposit(address token, uint256 amount) external {IERC20(token).transferFrom(msg.sender, address(this), amount);deposits[token][msg.sender] += amount;emit Deposit(msg.sender, token, amount);}function withdraw(address token,uint256 amount,bytes calldata proof) external {require(verifyWithdrawalProof(msg.sender,token,amount,proof),"Invalid withdrawal proof");deposits[token][msg.sender] -= amount;IERC20(token).transfer(msg.sender, amount);emit Withdrawal(msg.sender, token, amount);}
}
7. 性能优化
7.1 批处理优化
contract BatchProcessor {struct Batch {bytes32[] txHashes;uint256 timestamp;bytes32 merkleRoot;}function processBatch(Batch calldata batch) external {require(verifyBatchMerkleRoot(batch.txHashes, batch.merkleRoot),"Invalid merkle root");for (uint i = 0; i < batch.txHashes.length; i++) {processTransaction(batch.txHashes[i]);}}
}
7.2 数据压缩
function compressTransactionData(transactions) {// 使用 RLP 编码const encoded = ethers.utils.RLP.encode(transactions.map(tx => [tx.nonce,tx.gasPrice,tx.gasLimit,tx.to,tx.value,tx.data]));// 使用 zlib 压缩return zlib.deflateSync(encoded);
}
8. 相关资源
- Optimism 文档
- zkSync 文档
- Arbitrum 文档
- Polygon 文档
- Layer2 生态概览