Easy-Go-Web3
知识图谱Go 教程React Web3智能合约
需求分析系统设计设计模式Go 微服务
项目实战DevOps
Go 生态React 生态智能合约生态Web3 生态AI × Web3工具箱Web3 公司远程Web3求职
🎯 AA 工程师面试手册博客
GitHub
项目实战Layer2 Rollup 服务
高级扩容方案12-14周

Layer2 Rollup 服务

实现简化版 Optimistic/ZK Rollup 后端,包含批量交易处理、状态提交与欺诈证明

技术栈

GoPostgreSQLRedisgRPCSolidity

核心功能

交易批量打包 (Batching)
状态根计算与提交
Merkle 树状态管理
欺诈证明生成与验证
强制退出机制
Sequencer 服务实现

系统架构

┌─────────────────────────────────────────────────────────────┐
│                      User Interface                          │
│                  (Wallet / DApp / SDK)                       │
├─────────────────────────────────────────────────────────────┤
│                    Sequencer Service                         │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │ TX Receiver  │  │  TX Orderer  │  │Batch Builder │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
├─────────────────────────────────────────────────────────────┤
│                    State Manager                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │ Merkle Tree  │  │State Compute │  │ State Store  │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
├─────────────────────────────────────────────────────────────┤
│                    L1 Interaction                            │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │Batch Submitter│ │Fraud Prover │  │Force Withdraw│       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
├─────────────────────────────────────────────────────────────┤
│            L1 Contracts (Rollup, Bridge, Verifier)          │
└─────────────────────────────────────────────────────────────┘

课程章节

第一章:Sequencer 服务

交易接收与验证4小时
交易排序策略3小时
批次构建与压缩4小时

第二章:状态管理

Sparse Merkle Tree 实现5小时
状态转换执行4小时
状态根计算与验证3小时

第三章:L1 交互层

批次数据提交4小时
状态根提交3小时
L1 事件监听3小时

第四章:欺诈证明系统

欺诈证明生成5小时
挑战期管理3小时
争议解决流程4小时

核心代码实现

Sequencer 批次构建

go
1// Sequencer L2 排序器服务
2type Sequencer struct {
3 pendingTxs chan *Transaction
4 batchSize int
5 batchTime time.Duration
6 stateDB *StateDB
7 l1Submitter *L1Submitter
8}
9
10// Transaction L2 交易
11type Transaction struct {
12 From common.Address
13 To common.Address
14 Value *big.Int
15 Data []byte
16 Nonce uint64
17 Signature []byte
18}
19
20// Batch 交易批次
21type Batch struct {
22 Number uint64
23 Transactions []*Transaction
24 PreStateRoot common.Hash
25 PostStateRoot common.Hash
26 Timestamp time.Time
27}
28
29// BuildBatch 构建交易批次
30func (s *Sequencer) BuildBatch(ctx context.Context) (*Batch, error) {
31 batch := &Batch{
32 Number: s.getNextBatchNumber(),
33 PreStateRoot: s.stateDB.Root(),
34 Timestamp: time.Now(),
35 }
36
37 timer := time.NewTimer(s.batchTime)
38 defer timer.Stop()
39
40 for {
41 select {
42 case tx := <-s.pendingTxs:
43 // 验证交易
44 if err := s.validateTransaction(tx); err != nil {
45 log.Warn("Invalid tx", "err", err)
46 continue
47 }
48
49 // 执行状态转换
50 if err := s.stateDB.ApplyTransaction(tx); err != nil {
51 log.Warn("Apply tx failed", "err", err)
52 continue
53 }
54
55 batch.Transactions = append(batch.Transactions, tx)
56
57 // 达到批次大小上限
58 if len(batch.Transactions) >= s.batchSize {
59 batch.PostStateRoot = s.stateDB.Root()
60 return batch, nil
61 }
62
63 case <-timer.C:
64 // 超时,提交当前批次(即使未满)
65 if len(batch.Transactions) > 0 {
66 batch.PostStateRoot = s.stateDB.Root()
67 return batch, nil
68 }
69 timer.Reset(s.batchTime)
70
71 case <-ctx.Done():
72 return nil, ctx.Err()
73 }
74 }
75}

Sparse Merkle Tree

go
1// SparseMerkleTree 稀疏 Merkle 树
2type SparseMerkleTree struct {
3 db Database
4 root common.Hash
5 height int
6 hasher hash.Hash
7 cache *lru.Cache
8}
9
10// Update 更新叶子节点
11func (t *SparseMerkleTree) Update(
12 key common.Hash,
13 value []byte,
14) (common.Hash, error) {
15 // 计算叶子哈希
16 leafHash := t.hashLeaf(key, value)
17
18 // 获取从根到叶子的路径
19 path := t.getPath(key)
20
21 // 从叶子向上更新
22 currentHash := leafHash
23 for i := t.height - 1; i >= 0; i-- {
24 sibling, err := t.getSibling(path, i)
25 if err != nil {
26 return common.Hash{}, err
27 }
28
29 // 根据路径位确定左右
30 if path[i] == 0 {
31 currentHash = t.hashNode(currentHash, sibling)
32 } else {
33 currentHash = t.hashNode(sibling, currentHash)
34 }
35
36 // 缓存中间节点
37 t.cache.Add(currentHash, struct{}{})
38 }
39
40 // 更新根
41 oldRoot := t.root
42 t.root = currentHash
43
44 // 存储更新
45 t.db.Put(key[:], value)
46
47 log.Debug("SMT updated",
48 "key", key.Hex()[:10],
49 "oldRoot", oldRoot.Hex()[:10],
50 "newRoot", t.root.Hex()[:10],
51 )
52
53 return t.root, nil
54}
55
56// GenerateProof 生成 Merkle 证明
57func (t *SparseMerkleTree) GenerateProof(
58 key common.Hash,
59) (*MerkleProof, error) {
60 path := t.getPath(key)
61 siblings := make([]common.Hash, t.height)
62
63 for i := 0; i < t.height; i++ {
64 sibling, err := t.getSibling(path, i)
65 if err != nil {
66 return nil, err
67 }
68 siblings[i] = sibling
69 }
70
71 return &MerkleProof{
72 Key: key,
73 Siblings: siblings,
74 Root: t.root,
75 }, nil
76}
去中心化预言机网络MEV 保护服务
Easy-Go-Web3

构建 Go 后端与 Web3 的学习之路。从基础到进阶,从理论到实践,助你成为全栈区块链开发者。

学习路径

  • 知识图谱
  • Go 教程
  • Go 微服务
  • 面试手册

资源中心

  • 工具箱
  • DevOps 工具
  • Web3 生态
  • 博客

© 2025 Easy-Go-Web3. All rights reserved.

Created withbyhardybao