Polygon zkEVM zkROM代码解析(3)

本文解析了Polygon zkEVM zkROM代码中的批处理验证和执行收尾阶段,包括localExitRoot的验证、交易大小检查及batchHashData与globalHash的计算与验证过程。

1. 引言

Polygon zkEVM zkROM代码库为:

zkROM的基本流程为:

  • 1)A:加载输入变量;
  • 2)B:设置batch storage state-tree:batchHash (oldStateRoot) & globalExitRoot;
  • 3)C:循环解析RLP交易;
  • 4)D:循环处理交易;
  • 5)E:batch asserts:localExitRoot、transactions size、batchHashData & globalHash;
  • 6)F:finalize execution

前序博客为:

本文重点包含E/F步骤。

2. E:batch asserts:localExitRoot、transactions size、batchHashData & globalHash

zkROM第五步为batch asserts,即包含对localExitRoot、transactions size、batchHashData & globalHash的断言:

processTxsEnd:

;;;;;;;;;;;;;;;;;;
;; E - Batch asserts: localExitRoot, transactions size, batchHashData & globalHash
;;;;;;;;;;;;;;;;;;

;; Assert local exit root
        ; Read 'localExitRoot' variable from GLOBAL_EXIT_ROOT_MANAGER_L2 and check
        ; it is equal to the 'newLocalExitRoot' input
        ; 常量值CONSTL %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 = 0xAE4bB80bE56B819606589DE61d5ec3b522EEB032n
        %ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2  => A
        ; 常量值CONST %SMT_KEY_SC_STORAGE = 3
        %SMT_KEY_SC_STORAGE => B
        ; 常量值CONST %LOCAL_EXIT_ROOT_STORAGE_POS = 1
        %LOCAL_EXIT_ROOT_STORAGE_POS => C
        ; 从Storage中读取以A/B/C为key的value值,给A
        $ => A                                          :SLOAD
        ; 将Storage中读取的值存入newLocalExitRoot
        A                                               :MSTORE(newLocalExitRoot)
assertNewLocalExitRoot:
		; 断言ctx.input.newLocalExitRoot值 与 Storage中读取的值 相等
        ${getNewLocalExitRoot()}                        :ASSERT


;; Transactions size verification
        ; Ensure bytes added to compute the 'batchHashData' matches the number of bytes loaded from input
        ; 全局变量batchHashPos表示hash batchHashData position
        $ => A                          :MLOAD(batchHashPos)
        ; 全局变量Transactions bytes read from the input表示 Transactions bytes read from the input
        ; 断言batchL2DataLength 与 batchHashPos 相等
        $                               :MLOAD(batchL2DataLength), ASSERT

;; Compute and check 'batchHashData'
        ; Compute 'batchHashData'
        ; Ensure hash result 'batchHashData' mathes the input
        ; 此时A为batchHashPos
        ; 全局变量batchHashPos表示hash batchHashData position
        A => HASHPOS
        ; 全局变量batchHashDataId表示 hash address used when adding bytes to batchHashData
        $ => E                          :MLOAD(batchHashDataId)

        32 => D
        ; 全局变量globalExitRoot表示 Global exit-tree root
        $ => A                          :MLOAD(globalExitRoot)
        ; 附加32个字节的globalExitRoot,为Keccak(transactions | globalExitRoot
        A                               :HASHK(E)

        20 => D
        $ => A                          :MLOAD(sequencerAddr)
        ; 附加20个字节的sequencerAddr,为Keccak(transactions | globalExitRoot | sequencerAddr
        A                               :HASHK(E)
		; 执行哈希运算 Keccak(transactions | globalExitRoot | sequencerAddr)
        HASHPOS                         :HASHKLEN(E)
        ; 全局变量batchHashData表示 ; batchHashData = H_keccak( transactions | globalExitRoot | sequencerAddr )
        $ => A                          :MLOAD(batchHashData)
        ; 断言2个哈希值相等
        $                               :HASHKDIGEST(E), ASSERT

;; Compute and check 'globalHash'
		; 全局变量 globalHash = H_keccak(oldStateRoot | oldLocalStateRoot | newStateRoot | newLocalExitRoot | batchHashData | numBatch | timestamp )
		; 全局变量oldHashPos表示 Save hash data position for globalHash
        $ => HASHPOS                    :MLOAD(oldHashPos) ; Retrieve 'globalHash' hash postion

        32 => D
        ; 附加32字节的newStateRoot SR,addr为0,Keccak(oldStateRoot | oldLocalExitRoot | SR
        SR                              :HASHK(0) ; add 'newStateRoot' to `globalHash`
		; 全局变量newLocalExitRoot表示 Updated local exit-tree root
        $ => A                          :MLOAD(newLocalExitRoot)
        ; 附加32字节的newLocalExitRoot,addr为0,Keccak(oldStateRoot | oldLocalExitRoot | SR | newLocalExitRoot
        A                               :HASHK(0)
		; 全局变量batchHashData表示 batchHashData = H_keccak( transactions | globalExitRoot | sequencerAddr )
        $ => A                          :MLOAD(batchHashData)
        ; 附加32字节的batchHashData,addr为0,Keccak(oldStateRoot | oldLocalExitRoot | SR | newLocalExitRoot | batchHashData
        A                               :HASHK(0)

        8 => D
        ; 全局变量numBatch表示 Current batch to process
        $ => A                          :MLOAD(numBatch)
        ; 附加8字节的numBatch,addr为0,Keccak(oldStateRoot | oldLocalExitRoot | SR | newLocalExitRoot | batchHashData | numBatch
        A                               :HASHK(0)
		; 全局变量timestamp表示 Current batch timestamp
        $ => A                          :MLOAD(timestamp)
        ; 附加8字节的timestamp,addr为0,Keccak(oldStateRoot | oldLocalExitRoot | SR | newLocalExitRoot | batchHashData | numBatch | timestamp
        A                               :HASHK(0)
		; 执行哈希运算,Keccak(oldStateRoot | oldLocalExitRoot | SR | newLocalExitRoot | batchHashData | numBatch | timestamp)
        HASHPOS                         :HASHKLEN(0)
		; 全局变量 globalHash = H_keccak(oldStateRoot | oldLocalStateRoot | newStateRoot | newLocalExitRoot | batchHashData | numBatch | timestamp )
        $ => A                          :MLOAD(globalHash)
assertNewStateRoot:
		; 断言2个哈希值相等
        $                               :HASHKDIGEST(0), ASSERT
		; 打印日志,表示当前batch处理完毕
        ${eventLog(onFinishBatch)}

3. F:finalize execution

zkROM第六步为finalize execution,即将各寄存器初始化为0:

;;;;;;;;;;;;;;;;;;
;; F - Finalize execution
;;;;;;;;;;;;;;;;;;
finalizeExecution:
		; 寄存器清零
        0 => A,B,C,D,E,CTX, SP, PC, GAS, MAXMEM, SR, HASHPOS, RR ; Set all registers to 0
                                                                        :JMP(finalWait)
; 在主业务流程和最后清零操作之后,进行补零到execution trace表的倒数第二行。
finalWait:
    ${beforeLast()}     :JMPN(finalWait)
                        :JMP(start)

附录:Polygon Hermez 2.0 zkEVM系列博客

【源码免费下载链接】:https://renmaiwang.cn/s/nhrcw 深度优先搜索(DFS,Depth-First Search)是一种用于遍历或搜索树或图的算法,它选择一个节点并尽可能深地探索其分支。在迷宫生成中,DFS被用来创建复杂的路径结构。以下是对给定内容的详细解释:1. **Python深度优先算法生成迷宫的原理**: 迷宫生成的基本思想是随机地在空白区域添加墙壁,形成一条可以从起点到终点的路径。DFS在这里的作用是从起始点开始,随机选择一个方向进行移动,并将该路径标记为已访问。当遇到障碍(已存在的墙壁)或者到达终点时,算法回溯到上一步,选择其他未尝试过的路径。2. **代码解析**: - 定义矩阵`dfs`来记录迷宫中每个单元格是否已被访问。 - 定义矩阵`maze`来表示最终生成的迷宫,其中`#`代表墙壁,空格代表可通行路径。 - `operation`字典存储了四个可能的方向(上、下、左、右)对应的坐标偏移量。 - `direction`列表包含所有可能的方向,用于随机选择移动方向。 - `stack`用于存储深度优先搜索过程中的路径。3. **函数说明**: - `show(graph)`:打印迷宫矩阵,便于观察迷宫结构。 - `showRouter(stack)`:打印DFS过程中访问的路径,展示从起点到终点的路径。 - `generateMaze(start)`:核心函数,使用DFS生成迷宫。首先将起始点标记为已访问,然后随机排序方向,依次尝试这些方向,如果新位置未被访问且在有效范围内,则打通墙壁并递归调用自身。4. **迷宫生成流程**: - 创建一个全墙的初始迷宫矩阵,奇数行和奇数列的位置代表实际的墙壁,偶数位置代表路径。 - 起点设为`(0, 0)`,调用`generateMaze((0,0))`开始生成迷宫。 - 在递归过程中,每次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值