1. zkProver基本设计原则

Polygon zkEVM采用状态机模型来模拟EVM(Ethereum Virtual Machine),从而提供与以太坊相同的用户体验,并支持部署运行相同的以太坊智能合约。

Polygon zkEVM zkRollup扩容策略在于:

  • 开发zkProver,输入a batch of many transactions,证明该batch内所有交易的有效性,然后仅发布最小化size的validity proof供验证。从而可降低交易固化时间,并为以太坊用户节约gas费。
  • 采用前沿工具来提供可验证proof,如Polynomial Identity Language(PIL)。

状态机最适合迭代确定性计算,确定性计算在以太坊中很常见。而算术电路将需要展开loop,从而导致不希望的更大的电路。

基于状态机所实现的zkProver证明系统基本设计原则为:

  • 1)将所需的确定性计算转换为state machine computation。
  • 2)将state transitions以arithmetic constraints描述,arithmetic constraints为每个state transition必须遵循的规则。
  • 3)使用state values interpolation 来构建描述状态机的多项式。
  • 4)定义所有state values必须满足的polynomial identities
  • 5)某特定的密码学证明系统(如STARK、SNARK或二者结合),用于生成任何人都可验证的verifiable proof。

以上前四步通常称为Arithmetization

  • 对应STARKs,为Algebraic Intermediate Representation(AIR)
  • 对应SNARKs,为R1CS

同时,由于zkProver部署的上下文为某公钥密码学系统,还需要一种承诺方案。zkProver证明计算正确性并允许任何独立方验证validity proof能力的基础是多项式承诺方案。

2. Storage状态机


标准状态机为:

  • 将一组状态存储于寄存器中作为输入
  • instructions:表示状态变化的规则
  • 将结果状态存储于相同的寄存器中,作为输出。

Storage状态机为zkProver的二级状态机之一,负责存储于zkProver storage的所有数据操作:

  • 接收来自 主状态机的instructions,该instructions又称为Storage Actions。
  • 主状态机会运行常规的数据库操作:增删改查(CRUD),然后然后指示Storage状态机验证这些操作是否正确执行。

Polygon zkEVM的Storage状态机类似于一个微处理器,具有:

  • 1)firmware部分:包含了逻辑和规则,以JSON形式存储于某ROM中。zkASM(zero-knowledge Assembly)为Polygon zkEVM团队专门开发的语言,用于将来自 主状态机的instructions map到 其它状态机,本文中,即map到Storage状态机的Executor中。
    主状态机的instructions或Storage Actions,会解析到 Storage状态机的Executor中,以便按照JSON文件中指定的规则和逻辑执行。
  • 2)hardware部分:采用PIL(Polynomial Identity Language)。几乎所有的状态机都将计算以多项式表示。状态机内的state transitions必须满足特定的computation-specific polynomial identities。

为了使Storage状态机执行Storage Actions,其Executor生成committed多项式和constant多项式,然后根据多项式恒等式对其进行检查,以证明计算是正确执行的。


小结:

  • 1)下文中的增删改查操作,即为 主状态机 让 Storage状态机 执行的action。
  • 2)下文中的Prover,对应为Storage状态机的Executor。
  • 3)下文中的Verifier,对应为Storage状态机的PIL代码。
  • 4)zkASM为Storage状态机 与 主状态机 之间的interpreter。
  • 5)zkASM为Storage状态机 与 POSEIDON状态机 之间的interpreter。
  • 6)Storage binary SMT中所用到的2个哈希函数 H leaf , H noleaf H_{\text{leaf}},H_{\text{noleaf}} Hleaf​,Hnoleaf​ 为POSEIDON哈希族中的2个特定版本的哈希函数。

2.1 zkProver的SMT

前序博客有:

  • Sparse Merkle Tree
  • Merkle Patricia Tree——Verify Ethereum Account Balance with State Proof

为实现zero-knowledge,所有的数据都存储于Merkle tree中,即意味着Storage SM(State Machine,状态机)需常向其它状态机——Poseidon SM,发送请求(POSEIDON Actions),来执行哈希运算。

key-value数据存储在SMT(Sparse Merkle Tree)中,主状态机基于这些存储在SMT中的key-value数据进行计算。key和value均以256bit string表示,也可解析为256-bit unsigned integers。

zkProver的SMT为Merkle Tree 与 Patricia Tree的结合。

2.1.1 基于key-value pair的binary SMT

以8-bit key length为例。NULL SMT或 empty SMT 的root为0,即在其中未记录任何key或value。zero node或NULL node,意味着该node中国无任何value。key会决定binary SMT的形状。【所谓binary,是指其path上的label只能为0或1。】

在binary SMT中,其branches要么为leaf,要么为zero-node。

如只有一个key-value pair ( K a , V a ) (K_a,V_a) (Ka​,Va​)的binary tree,从 K a K_a Ka​最低有效位起,逐bit代表从root到leaf的分支选择,0表示左侧,1表示右侧。若 K a = 11010110 K_a=11010110 Ka​=11010110,对应的binary SMT为:【最低有效位为0,置于左侧,zero-node置于右侧, L a = H ( V a ) L_a=H(V_a) La​=H(Va​)。若最低有效位为1,则置于右侧,不过 ( r o o t a 0 = H ( L a ∣ ∣ 0 ) ) ≠ ( r o o t 0 a = H ( 0 ∣ ∣ L a ) ) (root_{a0}=H(L_a||0))\neq (root_{0a}=H(0||L_a)) (roota0​=H(La​∣∣0))=(root0a​=H(0∣∣La​)),分别表示的是不同的binary tree。】


若binary SMT中具有2个key-value pair,则,要根据其自最低有效位起,哪个bit不同来摆放。如最低2个有效位都相同,第三个才不同,则摆放情况类似为:

leaf level:表示某leaf到root的深度。如上图: lvl ( L a ) = 3 \text{lvl}(L_a)=3 lvl(La​)=3。SMT中最大的leaf level决定了SMT的height。

SMT中所有的key具有相同的固定的key-length,SMT的最大height为该fixed key-length。

2.1.2 不同于通用SMT之处

不同于通用SMT之处:

  • leaf node L x L_x Lx​中不仅存储了value V x V_x Vx​,还存储了自root到 L x L_x Lx​所未使用的key-bits。这些未使用的key-bits称为remaining key,表示为 R K x RK_x RKx​。

假设某SMT由7个key-value pair,相应的key分别为:
K a = 10101100 , K b = 10010010 , K c = 10001010 , K d = 11100110 , K e = 11110101 , K f = 10001011 , K g = 00011111 K_a =10101100,K_b =10010010,K_c =10001010,K_d =11100110,K_e =11110101,K_f=10001011,K_g =00011111 Ka​=10101100,Kb​=10010010,Kc​=10001010,Kd​=11100110,Ke​=11110101,Kf​=10001011,Kg​=00011111

以上图7 leaf SMT为例,相应的Remaining key分别为:
R K a = 101011 , R K b = 1001 , R K c = 1000 , R K d = 11100 , R K e = 111101 , R K f = 10001 , R K g = 00011 RK_a =101011,RK_b =1001,RK_c =1000,RK_d =11100,RK_e =111101,RK_f=10001,RK_g =00011 RKa​=101011,RKb​=1001,RKc​=1000,RKd​=11100,RKe​=111101,RKf​=10001,RKg​=00011

2.1.3 Fake-Leaf攻击及其解决方案

至此,由于SMT中的leaf具有不同的深度,leaf和branch node采用相同的哈希函数,会存在fake-leaf攻击问题:

解决方案为,leaf和branch node采用不同的哈希函数,进行区分,使得:
B a b = H noleaf ( L a ∣ ∣ L b ) ≠ H leaf ( L a ∣ ∣ L b ) = L ~ f k B_{ab}=H_{\text{noleaf}}(L_a||L_b)\neq H_{\text{leaf}}(L_a||L_b)=\tilde{L}_{fk} Bab​=Hnoleaf​(La​∣∣Lb​)=Hleaf​(La​∣∣Lb​)=L~fk​

从而,在未知 L a , V a , L b , V b L_a,V_a,L_b,V_b La​,Va​,Lb​,Vb​的情况下,无法以 L f k , V f k L_{fk},V_{fk} Lfk​,Vfk​来欺骗Verifier。

2.1.3 key-value pair Non-binding问题及其解决方案

至此,若SMT中有leaf ( K d , V d ) (K_d,V_d) (Kd​,Vd​),Malicous prover可以SMT中不存在的leaf ( K x , V x ) (K_x,V_x) (Kx​,Vx​),其中 V x = V d V_x=V_d Vx​=Vd​,让Verifier误以为 ( K x , V x ) (K_x,V_x) (Kx​,Vx​)存在与SMT中:

引起该问题的根本原因在于,key-value pair中的key与value未实现binding。相应的解决方案有:

  • 1)将整个key-value包裹进leaf的哈希函数中: L x = H leaf ( K x ∣ ∣ V x ) L_x=H_{\text{leaf}}(K_x||V_x) Lx​=Hleaf​(Kx​∣∣Vx​)
  • 2)只将remaining key和value包裹进leaf的哈希函数中: L x = H leaf ( R K x ∣ ∣ V x ) L_x=H_{\text{leaf}}(RK_x||V_x) Lx​=Hleaf​(RKx​∣∣Vx​)

方案2)更优的原因在于,Verifier在验证merkle proof时,仅需要知悉更短的remaining key。

2.1.4 引入zero-knowledge属性

至此,key pair ( K x , V x ) (K_x,V_x) (Kx​,Vx​)的leaf L x L_x Lx​表示为:
L x = H leaf ( R K x ∣ ∣ V x ) L_x=H_{\text{leaf}}(RK_x||V_x) Lx​=Hleaf​(RKx​∣∣Vx​)

将value V x V_x Vx​以明文存储在leaf L x L_x Lx​中,Verifier验证Merkle proof时需知道相应的value值,为实现zero-knowledge属性,可改为在leaf中存储的是 V x V_x Vx​的哈希值(采用不同于leaf的哈希函数 H noleaf H_{\text{noleaf}} Hnoleaf​):
Hashed Value = HV x = H noleaf ( V x ) \text{Hashed Value}=\text{HV}_x=H_{\text{noleaf}}(V_x) Hashed Value=HVx​=Hnoleaf​(Vx​)【从而将value值 V x V_x Vx​隐藏在了 HV x \text{HV}_x HVx​中了。】
L x = H leaf ( R K x ∣ ∣ HV x ) L_x=H_{\text{leaf}}(RK_x||\text{HV}_x) Lx​=Hleaf​(RKx​∣∣HVx​)

2.2 基于SMT的基本操作

Storage状态机执行的操作称为Storage Actions,Storage状态机负责验证 主状态机所执行的增删改查操作 是否正确。

2.2.1 READ/Get 操作

Prover:

  • 对key-value pair ( K x , HV x ) (K_x,\text{HV}_x) (Kx​,HVx​)进行commit,其中 HV x \text{HV}_x HVx​为value V x V_x Vx​的哈希值,
  • 然后声称其创建的leaf L x L_x Lx​包含了value V x V_x Vx​,且位置由key K x K_x Kx​决定。

Prover需给Verifier提供,即,Verifier需要知道:

  • 1)SMT的root
  • 2)定位leaf L x L_x Lx​的key-bits kb j \text{kb}_j kbj​
  • 3)Remaining Key R K x RK_x RKx​
  • 4)Merkle proof

READ ( K x ) \text{READ}(K_x) READ(Kx​)操作有2种结果:【目的是证明相应的 K x K_x Kx​在SMT中未设置

  • 返回zero node:仅需要向Verifier证明该zero-node存在于SMT中,即可证明SMT中未设置相应的key。
  • 返回现有的leaf:需证明该leaf存在于SMT中,同时该leaf对应的key 不等于 所查询的key。

2.2.2 UPDATE操作

UPDATE操作不会改变SMT树的形状。因此,在执行UPDATE时,保留节点的所有labels是很重要的。

UPDATE(key)操作的基本流程为:

  • 1)给Verifier提供如下数据,即:

    • remaining key R K RK RK
    • least-significant key-bits
    • 更新后的new_value值
    • 更新前的old_value值
    • 更新前的old_root
    • 更新前相应key的merkle proof
  • 2)基于更新前的old_root和更新前的old_value值,执行READ(key)操作,检查相应的leaf存在于old_root对应的SMT树中。仅当本环节验证通过后才进入下一环节。
  • 3)从所更新的key对应的leaf开始 到 root,重新计算 更新后,该路径上的所有节点的值,最终计算出新的root值。

2.2.3 CREATE操作

CREATE操作会向SMT中插入新 leaf L n e w L_{new} Lnew​,并在 leaf L n e w L_{new} Lnew​中存储新的 key-value pair ( K n e w , V n e w ) (K_{new}, V_{new}) (Knew​,Vnew​),要求:

  • key K n e w K_{new} Knew​之前从未在SMT中使用
  • 从而使得 key K n e w K_{new} Knew​唯一关联到 leaf L n e w L_{new} Lnew​

实际CREATE操作有2种情况:

  • 1)若新key L n e w L_{new} Lnew​自root开始,指向zero node,即 CREATE Operation at a Zero Node:
  • 2)若新key L n e w L_{new} Lnew​自root开始,指向Non-Zero leaf L z L_z Lz​,则:
    • 2.1)Value-Inclusion Check:需检查Non-Zero leaf L z L_z Lz​中存储的value V z V_z Vz​确实包含在SMT的root中。
    • 2.2)New Leaf Insertion:需为 L z L_z Lz​和 L n e w L_{new} Lnew​创建新的branch B e x t 1 B_{ext1} Bext1​。【有可能需要插入多个branch extension】
    • 2.3)UPDATE of SMT Values:自新branch向上到root,依次更新路径上的值。

2.2.4 DELETE操作

DELETE操作是指从binary SMT中移除某特定的key-value pair,为CREATE的反向操作。

DELETE操作有2种情况:

  • 1)等价为将某non-zero leaf UPDATE 为 NULL leaf。此时SMT的形状不会改变。当所删除的leaf具有non-zero sibling-node时,对应此场景。

  • 2)等同于CREATE的反向操作。需要从树中移除extension branches,数的形状会改变。当所删除的leaf具有zero sibling-node时,对应此场景。

2.3 zkProver的Storage参数

在Storage状态机中,所有的key和value均为256 bits string:

  • 可将key表示为256-bit unsigned integers,对应为4个64-bit field elements:
    Key 0123 = ( Key 0 , Key 1 , Key 2 , Key 3 ) \text{Key}_{0123}=(\text{Key}_0,\text{Key}_1,\text{Key}_2,\text{Key}_3) Key0123​=(Key0​,Key1​,Key2​,Key3​)
    其中每个 Key i ∈ F p \text{Key}_i\in\mathbb{F}_p Keyi​∈Fp​,其中 p = 2 64 − 2 32 + 1 p=2^{64}-2^{32}+1 p=264−232+1
  • committed values,也为256-bit long,但由于POSEIDON状态机惯例,将其表示为8个32-bit值,即:
    V 01..7 = ( V 0 , V 1 , V 2 , ⋯ , V 7 ) V_{01..7}=(V_0,V_1,V_2,\cdots,V_7) V01..7​=(V0​,V1​,V2​,⋯,V7​)
  • 除committed values之外的values,以4个64-bit field elements表示。

2.3.1 Storage SMT中的key生成方式

在Storage状态机中设计的key-value pair SMT上下文中,key可唯一标识leaf,leaf的values会变化,但key不变。

因此,key必须确定性的生成,且不存在碰撞问题。key与leaf之间存在一一对应关系。采用抗碰撞哈希函数来生成key,是个不错的选择。用于生成key的哈希函数参数有:

  • 以太坊地址
  • 以及某些常数

为此,引入了POSEIDON哈希函数来生成key。【实际上,key=POSEIDON_HASH(account_address, storage_slot, query_key)。】

2.3.2 Storage SMT中的path表示

由于Storage SMT中的key采用4个64-bit field elements表示,因此,其path为自root到指定leaf,分别取各个field element的最低有效位、次低有效位等等来组成path:

2.3.3 根据path-bits重构key

当做UPDATE等操作时,需要根据remaining key和path-bits重构出完整的key,这实际为 2.3.2节的反向操作。

实际实现时,为避免做modulo 4运算(因将key以4个元素来表示),引入了 1个寄存器 和 1个操作:

  • 在Storage SM中引入LEVEL寄存器:由4个bits组成,其中3个bit为0,1个bit为1。LEVEL寄存器的初始值为 ( 1 , 0 , 0 , 0 ) (1,0,0,0) (1,0,0,0)。
  • 在Storage ROM中引入ROTATE_LEVEL opcode:每次对 LEVEL寄存器进行左移1位的rotation。【当每次Prover需要climb the tree时,会使用ROTATE_LEVEL opcode。】
    执行4次ROTATE_LEVEL操作,结果保持不变:
    ( 1 , 0 , 0 , 0 ) → ( 0 , 0 , 0 , 1 ) → ( 0 , 0 , 1 , 0 ) → ( 0 , 1 , 0 , 0 ) → ( 1 , 0 , 0 , 0 ) (1,0,0,0)→(0,0,0,1)→(0,0,1,0)→(0,1,0,0)→(1,0,0,0) (1,0,0,0)→(0,0,0,1)→(0,0,1,0)→(0,1,0,0)→(1,0,0,0)

可利用LEVEL寄存器来进行key重构:

2.4 Storage状态机机制

Storage状态机设计为微处理器,由3部分组成:

  • Storage Assembly code
  • Storage Executor code
  • Storage PIL code

2.4.1 Storage Assembly code

Storage Assembly code 为 主状态机 与 Storage Executor之间的 interpreter:

  • Storage状态机 接收到的 主状态机 指令 是以zkASM编写的
  • 然后生成包含相应规则和逻辑的JSON文件
  • 该JSON文件作为Storage状态机的特殊ROM。

Storage状态机中具有primary Storage Assembly code,来将 主状态机的指令,映射为,对应每个基本操作的secondary Assembly code
这些基本操作主要为本文之前提到的CREATE\READ\UPDATE\DELETE操作。

Storage状态机中主要有8种secondary Assembly code,详情见:https://github.com/0xPolygonHermez/zkevm-storage-rom/tree/main/zkasm,具体的映射关系为:

Storage Actions File Names Code Names Action Selectors In Primary zkASM Code
READ Get Get isGet()
UPDATE Set_Update SU isSetUpdate()
CREATE new value at a found leaf Set_InsertFound SIF isSetInsertFound()
CREATE new value at a zero node Set_InsertNotFound SINF isSetInsertNotFound()
DELETE last non-zero node Set_DeleteLast SDL isSetDeleteLast()
DELETE leaf with non-zero sibling Set_DeleteFound SDF isSetDeleteFound()
DELETE leaf with zero sibling Set_DeleteNotFound SDNF isSetDeleteNotFound()
SET a zero node to zero Set_ZeroToZero SZTZ isSetZeroToZero()

Storage状态机的输入和输出状态均为SMT,形如:

  • Merkle roots
  • relevant siblings
  • key-value pairs

不过状态机中采用的为寄存器,而不是变量。基本操作所需的所有值,均存储在primary Assembly code的如下寄存器中:

  • HASH_LEFT, HASH_RIGHT, OLD_ROOT, NEW_ROOT, VALUE_LOW, VALUE_HIGH, SIBLING_VALUE_HASH, RKEY, SIBLING_RKEY, RKEY_BIT, LEVEL.

其中SIBLING_VALUE_HASHSIBLING_RKEY这2个寄存器仅由 Set_InsertFoundSet_DeleteFound 这2个secondary Assembly code使用。其余的寄存器则被所有secondary Assembly code使用。

primary Assembly code 借助 selectors 来将 主状态机指令 转换为 相应的Storage Actions。selectors要么为0,要么为1:

  • 1表示该action被选中执行
  • 0表示指令 与 相应action 不符,即应用JMPZ(“Jump if zero”)

2.4.2 Storage Executor code

Storage Executor类似于a slave-worker to the master,此处master,是指the Storage Assembly code。Executor根据Assembly code中所定义的规则和逻辑来执行所有的Storage Actions。

对于 主状态机中的每个指令,借助之前提到的secondary Assembly code selectors,Storage Executor会调用 以JSON文件存储的Storage ROM 中的特定secondary Assembly code函数。相应的函数有:

  • GetSibling(), GetValueLow(), GetValueHigh(), GetRKey(), GetSiblingRKey(), GetSiblingHash(), GetSiblingValueLow(), GetSiblingValueHigh(), GetOldValueLow(), GetOldValueHigh(), GetLevelBit(), GetTopTree(), GetTopBranch() 以及 GetNextKeyBit()

2.4.3 Storage PIL code

Storage中所执行的所有计算都必须是可verifiable的,因此引入了PIL code来建立Verifier所需的所有多项式约束,以验证执行的正确性。

这些多项式约束是自Storage Executor开始准备的。为此,Storage Executor使用了:

  • selectors
  • setters
  • instructions

这些均为Boolean多项式,具体的Boolean committed多项式有:

Selectors Setters Instructions
selFree[i] setHashLeft[i] iHash
selSiblingValueHash[i] setHashRight[i] iHashType
selOldRoot[i] setOldRoot[i] iLatchSet
selNewRoot[i] setNewRoot[i] iLatchGet
selValueLow[i] setValueLow[i] iClimbRkey
selValueHigh[i] setValueHigh[i] iClimbSiblingRkey
selRkeyBit[i] setSiblingValueLow[i] iClimbSiblngRkeyN
selSiblingRkey[i] setSiblingValueHigh[i] iRotateLevel
selRkey[i] setRkey[i] iJmpz
setSiblingRkey[i] iConst0
setRkeyBit[i] iConst1
setLevel[i] iConst2
iConst3
iAddress

每次使用或执行这些Boolean多项式时,都会在其寄存器中记录“1”,也称为Execution Trace

因此,无需执行某些昂贵的运算来验证执行的正确性,仅对execution trace进行验证即可。

Verifier可获得该execution trace,验证其满足PIL code中的多项式约束(或 多项式identities)。该技术有助于zkProver实现succinctness ZKP。

参考资料

[1] zkProver Design Approach
[2] Storage SM

附录:Polygon Hermez 2.0 zkEVM系列博客

  • ZK-Rollups工作原理
  • Polygon zkEVM——Hermez 2.0简介
  • Polygon zkEVM网络节点
  • Polygon zkEVM 基本概念
  • Polygon zkEVM Prover
  • Polygon zkEVM工具——PIL和CIRCOM
  • Polygon zkEVM节点代码解析
  • Polygon zkEVM的pil-stark Fibonacci状态机初体验
  • Polygon zkEVM的pil-stark Fibonacci状态机代码解析
  • Polygon zkEVM PIL编译器——pilcom 代码解析
  • Polygon zkEVM Arithmetic状态机
  • Polygon zkEVM中的常量多项式
  • Polygon zkEVM Binary状态机
  • Polygon zkEVM Memory状态机
  • Polygon zkEVM Memory Align状态机
  • Polygon zkEVM zkASM编译器——zkasmcom
  • Polygon zkEVM哈希状态机——Keccak-256和Poseidon
  • Polygon zkEVM zkASM语法
  • Polygon zkEVM可验证计算简单状态机示例
  • Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
  • Polygon zkEVM zkROM代码解析(1)
  • Polygon zkEVM zkASM中的函数集合
  • Polygon zkEVM zkROM代码解析(2)
  • Polygon zkEVM zkROM代码解析(3)
  • Polygon zkEVM公式梳理
  • Polygon zkEVM中的Merkle tree
  • Polygon zkEVM中Goldilocks域元素circom约束
  • Polygon zkEVM Merkle tree的circom约束
  • Polygon zkEVM FFT和多项式evaluate计算的circom约束
  • Polygon zkEVM R1CS与Plonk电路转换
  • Polygon zkEVM中的子约束系统
  • Polygon zkEVM交易解析
  • Polygon zkEVM 审计及递归证明
  • Polygon zkEVM发布公开测试网2.0
  • Polygon zkEVM测试集——创建合约交易
  • Polygon zkEVM中的Recursive STARKs
  • Polygon zkEVM的gas定价

Polygon zkEVM zkProver基本设计原则 以及 Storage状态机相关推荐

  1. Polygon zkEVM的pil-stark Fibonacci状态机初体验

    1. 引言 前序博客: Polygon zkEVM 基本概念 第5章 "一个例子--Fibonacci state machine" 实操主要见: 2022年8月8日Jordi B ...

  2. Polygon zkEVM的pil-stark Fibonacci状态机代码解析

    1. 引言 前序博客有: Polygon zkEVM的pil-stark Fibonacci状态机初体验 STARKs and STARK VM: Proofs of Computational In ...

  3. Polygon zkEVM——Hermez 2.0简介

    1. 引言 前序博客有: ZK-Rollups工作原理 近期,Polygon团队开源了其Hermez 2.0 zkEVM代码,公开测试网即将上线: https://github.com/0xpolyg ...

  4. Polygon zkEVM zkROM代码解析(2)

    1. 引言 Polygon zkEVM zkROM代码库为: https://github.com/0xPolygonHermez/zkevm-rom zkROM的基本流程为: 1)A:加载输入变量: ...

  5. Polygon zkEVM交易解析

    1. 引言 前序博客有: Ethereum EVM简介 揭秘EVM Opcodes 剖析Solidity合约创建EVM bytecode Polygon zkEVM zkASM 与 以太坊虚拟机opc ...

  6. Polygon zkEVM zkASM中的函数集合

    1. 引言 前序博客有: Polygon zkEVM zkASM语法 zkASM程序的基本结构为: start(或其它任意label名,序号为0.为主业务流程):assignment : opcode ...

  7. Polygon zkEVM中Goldilocks域元素circom约束

    1. 引言 前序博客有: Goldilocks域 Goldilocks域 p=264−232+1p= 2^{64} - 2^{32} + 1p=264−232+1. Polygon zkEVM中Gol ...

  8. Polygon zkEVM中的Merkle tree

    1. 引言 前序博客有: Merkle tree及其在区块链等领域的应用 以https://github.com/0xPolygonHermez/pil-stark为例,Polygon zkEVM中实 ...

  9. 面向对象的5个基本设计原则

    面向对象的3个基本要素:封装.继承.多态 面向对象的5个基本设计原则: 单一职责原则(Single-Resposibility Principle) 其核心思想为:一个类,最好仅仅做一件事,仅仅有一个 ...

最新文章

  1. c语言基础习题下载,C语言基础题目
  2. git 无法拉取项目,本地ping不通github的解决办法(详解)
  3. 关于main函数中argc和argv的简单介绍
  4. mysql延迟注入br_(原创)安全狗SQL注入绕过思路[sql注入waf绕过][sql注入bypass]
  5. 【数据结构与算法】之深入解析“旋转链表”的求解思路与算法示例
  6. python D28 粘包
  7. hdoj4710 规律题
  8. java 取余_JAVA面试解析(有赞)
  9. java 网格包,求大神解答:JAVA网格包布局管理器小程序问题
  10. ultraedit 运行的是试用模式_原来用Unittest框架写接口测试用例这么简单!
  11. cadence ~ PCB排版 必要流程
  12. Linux系统变慢原因?
  13. 5种尊重您隐私的替代搜索引擎
  14. flex android开发中关于请求报文技术操作问题
  15. form表单内子元素组件按钮button事件冲突 - Vue
  16. android计算器开发论文,基于Android计算器功能的实现毕业设计论文
  17. COCO 与VOC格式转化 -目标识别
  18. python输出间隔符号_间隔符号?
  19. LARS Lasso
  20. 红色警戒3原版V1.00基址大全

热门文章

  1. 三款软件帮你轻松识别手写文字
  2. 计算机组装电源线排,主机箱背部走线技巧 组装电脑走背线与理线教程
  3. 微信支持修改微信号了,我不想为当年的冲动买单了
  4. 宝塔面板配置PHP环境
  5. 关于selenium代码运行完,浏览器自动关闭的问题
  6. 分享4款今日可领的红包封面,王者荣耀,元神,鸿图之下...
  7. Python批量转存百度网盘资源
  8. modelmap前端怎么取值_【ModelMap】jsp中显示springmvc modelmap传递的对象
  9. P2P端口映射 UPnP设置功能和使用详解
  10. H5C3基础学习总结之CSS四种定位模式