文章目录
Hermez ZK-Rollup 协议
概述
核心协议通过有效性证明来确保状态转换是有效的,该有效性证明将确保已满足某些规则。 规则的集合由智能合约确定,该合约将验证状态转换的证明。 该验证将检查每个状态转换是否正确进行。 这是通过使用ZK-SNARK电路来实现的,并且将确保遵循状态转换的所有规则。 任何证明者都必须提交证明,以证明状态转换计算的正确性。
证明者(又名协调者)负责计算所有状态变化并计算ZK-SNARK证明。 协调员将负责向验证者(智能合约)提交ZK-SNARK,这将确保状态转换验证。
A sparse-Merkle-tree is used to keep the state data where all accounts and balances are stored. This information is kept on L2 and users will sign transactions in order to spend their balances between L2 accounts. These L2 transactions are collected together to create a batch. Afterward, batch data is compressed through a ZK-SNARK and it will prove that the state transitions of all those L2 transactions are correct.
稀疏的Merkle树用于保存所有帐户和余额存储在其中的状态数据。 此信息保留在L2上,用户将签署交易以花费其L2帐户之间的余额。 将这些L2交易收集在一起以创建批次。 然后,通过ZK-SNARK压缩批处理数据,这将证明所有那些L2交易的状态转换是正确的。
为了向协议提供数据可用性,此交易集合在L1上公开,这意味着任何人都可以仅依赖于L1数据来重建L2状态。 因此,无需依赖第三方来提供或存储此数据。
该系统由L1和L2交易组成:
- L1交易是通过智能合约执行并影响L2状态树的交易
- L2交易是仅在L2上执行并影响L2状态树的交易
L1交易被协议中的协调器强制执行。 因此,此类交易将始终在某个时间进行。 L2交易由用户链下生成,并将其发送给协调器。 协调员将负责收集他们。
Some of the rollup functionality depends on a consensus mechanism to decide who can be the coordinator of a given batch. Separate from the rollup smart contract (which mainly handles the queue of L1UserTxs and the forging of batches), there is an external smart contract that implements the consensus mechanism and maintains its own state. During a forge call in the rollup smart contract, a call is made to the consensus smart contract to validate if the caller coordinator is allowed to forge and also to allow the consensus smart contract to update its own state and perform consensus actions if necessary.
一些 rollup 功能依赖于共识机制来决定谁可以成为给定批处理的协调者。 与汇总智能合约(主要处理L1UserTx的队列和批处理的伪造)分开,存在一个外部智能合约,该合约实现共识机制并保持其自身状态。 在汇总智能合约中进行伪造呼叫期间,将对共识智能合约进行呼叫,以验证是否允许呼叫者协调器伪造,并且还允许共识智能合约更新其自身状态并在必要时执行共识动作。
assumption 假设
- L1(以太坊):数据的完整性和不变性
- 哈希:
Poseidon 坚不可摧且耐碰撞
SHA256 坚不可摧且抗碰撞 - 椭圆曲线
L1:
secp256k1
signature scheme is ecdsa
L2:
BabyJubjub
signature scheme is eddsa - State tree transitions are always valid 状态树转换始终有效
- L1 transactions are forced to be processed L1交易被强制处理
notation 符号
H: is the poseidon hash function
elements are always encoded in big endian
Big endian encoding is used since it fits better with EVM encoding
Field Element 字段元素
- the value encoded in a field element must be smaller than the field order
字段元素中编码的值必须小于字段顺序 - first value corresponds to less significant part of the field
第一个值对应于该字段的较低有效部分
dataField: [16 bits] tokenID
[16 bits] nonce
[1 bit ] sign
Example:
dataFieldExample: [16 bits] tokenID = 5
[16 bits] nonce = 4
[1 bit ] sign = 1
dataFieldExample (large integer) = 4295229445;
dataFieldExample (hexadecimal padded 32 bytes) = 0x0000000000000000000000000000000000000000000000000000000100040005;
Buffer Bytes缓冲区字节
- first value corresponds to the first byte of the array
第一个值对应于数组的第一个字节
dataBuffer: [48 bits] fromIdx
[32 bits] tokenID
[16 bit ] amountFloat
Example:
dataBufferExample: [48 bits] fromIdx = 5
[32 bits] tokenID = 4
[16 bit ] amountFloat = 20
dataBufferExample (hexadecimal) = 0x000000000005000000040014;
全局配置
Circuit 电路
-
MAX_NLEVELS:Merkle树深度的绝对最大值(48位)
决定ZK-Rollup中可以存在的最大帐户数: -
MAX_TX:允许在一批中处理的绝对最大L1或L2交易
-
MAX_L1_TXS:允许一次处理的L1交易的绝对最大值
-
MAX_FEE_TX:协调器能够从所包含的交易中批量收取费用的代币的最大数量
-
NLevels:Merkle树深度
应该注意的是,NLevels始终是8的倍数
Contracts 合约
-
MAX_L1_USER_TXS:允许排队批处理的L1用户交易的绝对最大值
-
MAX_AMOUNT_DEPOSIT:创建新帐户时可以添加的最大令牌数量
-
INITIAL_IDX:如果创建新帐户,则填充的第一个Merkle树索引
保留一些索引以指定特殊交易 -
IDX 0:空索引
-
IDX 1:退出
-
2 <= IDX <256:保留的Idx值以备将来使用
-
256 <= IDX <2 ^ MAX_NLEVELS:汇总帐户可用的IDX值
-
MAX_TOKENS:允许在ZK-Rollup中注册的最大令牌数量
Data Types 数据类型
Floating Point Format 浮点格式(Float40)
内部采用了称为Float40的40位自定义浮点编码进行编码,以对大整数进行编码。 这样做是为了在发布L2交易时节省位。
计算公式如下:
v
=
m
×
1
0
e
v=m×10^e
v=m×10e
where:
- v:大整数值进行编码
- m:尾数\定点部分(35位)
- e:指数(5位)
bit position:
[ e | m ]
[ 5 bits | 35 bits]
Account 账号
idx: integer, path in the sparse Merkle tree (NLevels bits)
sign: Baby Jubjub sign (1 bit)
ay: Baby Jubjub public key Y coordinate (253 bits)
ethAddr: Ethereum address (160 bits)
tokenID: token identifier (32 bits)
balance: balance (192 bits)
nonce: nonce (40 bits)
- idx:整数,稀疏Merkle树中的路径(NLevels位)
- sign:Baby Jubjub标志(1位)
- ay:Baby Jubjub公钥Y坐标(253位)
- ethAddr:以太坊地址(160位)
- tokenID:令牌标识符(32位)
- 余额:余额(192位)
- 随机数:随机数(40位)
Transaction Fields
所有交易字段都是构建ZK-SNARK证明所必需的,但是根据交易类型的不同,并非全部使用。 可以在“transaction type section”部分(https://docs.hermez.io/#/developers/protocol/hermez-protocol/protocol?id=transaction-types)中看到详细的交易类型。以下是每个交易字段的摘要及其说明:
- signature_constant:硬编码的交易常量,指示用户正在签署Hermez rollup 交易。 用于在部署其他 rollup 时避免交易重播(32位)
signature_constant = sha256("I authorize this hermez rollup transaction")[:32/8]
- chainId:以太坊链标识符,以防止在进行硬分叉时发生重放攻击,我们仅使用2个字节,因为仅将Hermez部署在以太坊主网或其tesnet之一中,因此仅需要2个字节(16位)
- amountFloat40:ZK-Rollup中要传输的令牌数(40位)
- tokenID:标记标识符(32位)
- nonce:nonce(40位)
- feeSelector:select %fee to apply (8 bits) 选择要应用的费用%(8位)
- maxNumBatch:可以处理交易时允许的最大 batch 号(32位)
- onChain:将交易标记为L1交易(1位)
- newAccount:标记交易以创建新帐户(1位)
- fromIdx: sender account index (NLevels bits) 发件人帐户索引(NLevels位)
- fromBjjCompressed: sender Baby Jubjub public key compressed (256 bits)
- fromEthAddr: sender Ethereum address (160 bits)
- toIdx: recipient account index (NLevels bits)
- toEthAddr: recipient Ethereum address (160 bits)
- toBjjSign: recipient Baby Jubjub sign (1 bits)
- toAy: recipient Baby Jubjub public key Y coordinate (253 bits)
- loadAmountFloat40: L1 amount transfered to L2 (40 bits)
- txCompressedData: transaction fields joined together that fit into a single field * * element (253 bits) See L2Tx specification
- txCompressedDataV2: transaction fields joined together used for other transactions when using atomic transactions feature (193 bits) See L2Tx specification
- rqOffset: relative transaction position to be linked. Used to perform atomic transactions (3 bits)
- rqTxCompressedDataV2: requested txCompressedDataV2
- rqToEthAddr: requested toEthAddr
- rqToBjjAy: requested toBjj
执行原子事务的字段:
rqTxCompressedDataV2
rqToEthAddr
rqToBjjAy
rqOffset
树
- It is assured by protocol a unique idx for each account. Therefore, a given idx identifies uniquely a ZK-Rollup account
通过协议确保每个帐户都有唯一的IDX。 因此,给定的idx唯一标识ZK-Rollup帐户 - idx is incremented sequentially and it is assured by protocol
idx按顺序递增,并通过协议保证
State tree 状态树
Sparse Merkle树用于表示由其根标识的整个ZK-Rollup状态。 状态树(帐户)的每个叶子都包含以下数据:
- Key:Merkle树索引(idx)
- Value: Hash(state)
**field element notation**
State hash = H(e0, e1, e2, e3)
e_0: [ 32 bits ] tokenID
[ 40 bits ] nonce
[ 1 bit ] sign
e_1: [ 192 bits ] balance
e_2: [ 253 bits ] ay
e_3: [ 160 bits ] ethAddr
所有数据都使用 Poseidon 哈希函数 进行哈希处理,并作为键值对插入到稀疏的Merkle树中。
This approach implies a balanced Merkle tree: path is traversed from the root starting with the least significant bit out of the NLevels bits. This allows to have as many accounts as the tree levels:
此方法表示平衡的Merkle树:从根开始遍历路径,从NLevels位中的最低有效位开始。 这样可以拥有与树级别一样多的帐户: M A X A C C O U N T S = 2 M A X _ N L E V E L S MAX_ACCOUNTS = 2^{MAX\_NLEVELS} MAXACCOUNTS=2MAX_NLEVELS
Exit Tree 退出树
Each batch would have an associated exit tree with all the exits performed by the user, either L1 or L2 exit transactions. The exit tree has the same leaf structure as the state tree with some particularities:
每个batch 将具有一个关联的退出树,其中包含用户执行的所有退出(L1或L2退出交易)。 退出树与状态树具有相同的叶结构,但有一些特殊之处:
- nonce始终设置为0
- if several exits are done in the same batch for the same account, the balance is just added on top of the account
如果同一帐户在同一 batch 中完成了多个退出操作,则余额仅会添加到该帐户的顶部
User will need to prove that it owns a leaf in the exit tree in order to perform its withdraw and get back the tokens from the contract. This verification could be done either by submitting a Merkle tree proof or by submitting a ZK Proof.
用户将需要证明其在退出树中拥有一片叶子,以执行退出操作并从合约中获取代币。 可以通过提交Merkle树证明或提交ZK证明来完成此验证。
账号类型
Regular Rollup Account 普通 Rollup 账号
Regular accounts contain an Ethereum address and a Baby Jubjub public key. Accounts are always indexed by Ethereum address in the UX, so it is a requirement that the Ethereum address authorizes the account keys. Once the account is created, the Ethereum key is used to authorize L1 txs and the Baby Jubjub key is used to authorize L2 txs. There are two ways to authorize an account creation (that is, an Ethereum address authorizes the creation of an account containing that same Ethereum address and a Baby Jubjub public key):
普通账户包含一个以太坊地址和一个Baby Jubjub公钥。 帐户始终通过UX中的以太坊地址建立索引,因此要求以太坊地址授权帐户密钥。 创建帐户后,以太坊密钥用于授权L1 tx,Baby Jubjub密钥用于授权L2 tx。 有两种方法可以授权创建帐户(即,以太坊地址授权创建包含相同以太坊地址和Baby Jubjub公钥的帐户):
- Via Ethereum transaction, which has an implicit signature of the Ethereum address. This requires the owner of the Ethereum address to sign the smart contract transaction call
通过以太坊交易,该交易具有以太坊地址的隐式签名。 这要求以太坊地址的所有者签署智能合约交易调用 - Via an authorization signature (AccountCreationAuthSig) that can be used by any party to create accounts on behalf of the user
通过授权签名(AccountCreationAuthSig),任何一方均可使用该签名来代表用户创建帐户。
[32 bytes] compressed-bjj
[ 2 bytes] chainId
[20 bytes] hermezAddress
AccountCreationAuthMsg = “I authorize this babyjubjub key for hermez rollup account creation” || compressed-bjj || chainId || hermezAddress
AccountCreationAuthSig = Sign_ecdsa(AccountCreationAuthMsg)
内部 Rollup 账户
内部 Rollup 帐户不使用以太坊地址,因此只能通过L2 txs进行操作。 由于不涉及以太坊地址,因此创建帐户不需要授权,而只会指定Baby Jubjub公钥。 在内部,此帐户的以太坊地址是 ethAddr = 0xffff …
交易类型
L1User交易中可能的动作组合表:
RollupTx:是通过ZK-SNARK证明的在 rollup 状态下处理的任何交易。
HermezWithdraw: 是通过智能合约执行的交易,旨在将资金从智能合约中取回以太坊地址。 这是通过证明退出树中是否存在叶子来完成的。
NOP事务: 是不执行任何操作的空交易。 当协调器没有足够的交易来填充批处理中的最大事务数时,在电路输入中使用。 NULL事务是强制将值0用作amount或loadAmount的事务。 用于使发现无效的L1UserTx无效,以便它不对状态树进行任何更新。
上图中,具体每一个功能,具体请查看原文,根据需要,用到时直接查官方原文,未做翻译!
数据可用性
ZK-Rollup approach determines that anyone can reconstruct the full tree state by just collecting data from the L1 chain. This is done by not having any dependency of third parties holding essential data to reconstruct the full state. This feature ensures liveness of the system, meaning that no third party needs to be active in order to provide data to rebuild the state tree.
ZK-Rollup方法决定了只要从L1链中收集数据,任何人都可以重建完整树状状态。 这是通过不依赖拥有必要数据的第三方来重建完整状态来完成的。 此功能可确保系统的活动状态,这意味着无需第三方就可以激活以提供用于重建状态树的数据。
交易类型:
紧急机制
This logic is implemented in order to mitigate attacks that could potentially steal funds from Hermez Network. The aim of this method is to mitigate funds stolen while preserving decentralization.
实施此逻辑是为了减轻可能从Hermez Network窃取资金的攻击。 该方法的目的是在保留权力下放的同时减轻资金被盗的风险。
The core mechanism is to set a withdrawal limit in order to avoid infinite withdrawal in case of stolen funds. Therefore, it is assured that the attacker can only steal a certain amount of tokens.
核心机制是设置取款限额,以避免在资金被盗的情况下无限取款。 因此,可以确保攻击者只能窃取一定数量的令牌。
his logic is implemented in a smart contract: WithdrawalDelayer. This contract is for use completely independent of the Hermez Network but it meets the objective we need to mitigate attacks.
此逻辑在智能合约中实现:WithdrawalDelayer。 该合同的使用完全独立于Hermez网络,但符合我们减轻攻击所需的目标。
The purpose of this smart contract is to delay the withdraw. Hence, tokens will be held by the smart contract for a period of D and only afterwards tokens could be really withdrawn.
该智能合约的目的是延迟提款。 因此,令牌将由智能合约持有D期,并且只有在此之后才能真正撤出令牌。
- Hermez emergency mechanism (https://docs.hermez.io/#/developers/protocol/hermez-protocol/contracts/contracts?id=emergency-mechanism)
- Withdrawal delayer mechanism (https://docs.hermez.io/#/developers/protocol/withdrawal-delayer/withdrawal-delayer?id=withdrawal-delayer-protocol)