ZK Rollup 简介

逍遥 3676 0

布景


区块链技术自诞生以来,虽然大大降低了信赖的门槛,但一贯面临着一个功率问题:即 TPS 不高。例如比特币每秒仅支撑7笔生意,而现在的以太坊也仅支撑每秒 15 笔左右的生意。这样的 TPS 很支撑大型运用。因而业界许多技能人员查验为区块链扩容。现在扩容计划主要有两类:


· Layer 1 扩容计划,即直接增加链上的生意处理才调,这种方法也被称为链上扩容。常见的技能计划有:Sharding 和 DAG;

· Layer 2 扩容计划,即将链上的恰当一部分工作量转移到链下来完毕。常见的技能有:State Channel, Plasma, Truebit 和 最近比较火的 zk Rollup。


ZK Rollup 并非新概念,@barrywhitehat 在一年前提出,现在由 Matter Lab 和 den3 进行工程完毕。


原理


· 那么,zk Rollup 欠好的原理是什么?


zk Rollup 的实质是将链上的用户状况紧缩存储在一棵 Merkle 树中,并将用户状况的改动转移到链下来,一同经过 zkSNARK 的证明来确保该链下用户状况改动进程的正确性。在链上直接处理用户状况的改动成本是比较高的,但是只是运用链上的智能合约来验证一个零知识证明的 PROOF 是否正确,成本是相对低许多的。其他必要的转账信息也会被和证明一同提交到合约,便运用户查账。


两类人物


zkRollup 体系中包含两类人物:transactor 和 relayer。


· transactor,即普通用户,对应以太坊上的外部账户。用户构建转账生意并用私钥签名,然后将生意发送给 relayer。


· relayer 担任收集并验证用户的 transaction,之后将 transaction 批量打包,并生成 zkSNARK 的 PROOF,毕竟将用户 transaction 中的中心数据和 zkSNARK 的 PROOF 以及新的全局用户状况的 Merkle 根提交到链上的智能合约。


当然 relayer 不会免费为 transactor 供给服务,毕竟 relayer 向链上提交证明和数据是需求耗费 gas 的。因而,transactor 向 relayer 发送的生意里,也有必要包含相应的手续费。


状况搬迁函数


当 relyer 收到 transaction 后,有必要 “实施” 它。transaction 的实施,实质上是改动相关账户的状况,而 STF 就是改动账户状况的函数。STF 是状况搬迁函数(state transition function)的缩写。


状况是针对状况机而言的,每个状况机在某一时间都有一个状况。咱们能够假定某状况机的初始状况是 S[0]。当某个 Action T[1] 作用在该状况机上时,状况机的状况发作了搬迁。咱们能够用以下式子来标明搬迁进程。


S[1] = STF(S[0], T[1])


这儿,S[0] 是初始状况,S[1] 是状况机实施 Action T[1] 之后的状况。


紧接着有新的若干 Action T[2], T[3], ..., T[n] 继续作用在该状况机上,则状况机的状况顺次发作搬迁。


S[2] = STF(S[1], T[2])

S[3] = STF(S[2], T[3])

...

S[n] = STF[S[n-1], T[n]]


简略地,咱们也能够将 T[1], T[2], ..., T[n] 看作一个全体,则状况搬迁进程能够简化为


S[n] = STF(S[0], T[1], T[2], ..., T[n])


更一般地,假定其时状况机的状况是 PRE_STATE,然后有 n 个 Action T[1], T[2], ..., T[n] 顺次作用到状况机上,之后状况机的状况是 POST_STATE,此能够标明为


`POST_STATE = STF(PRE_STATE, T[1], T[2], ..., T[n])`


假定将以上 Action 换成转账生意 transaction,把 体系中的账户集结看作是一个状况机,那么整个进程也就是链上生意实施的进程了。生意的实施,使得整个链上的全局状况发作改动。链上的全局状况也就是各个账户的状况集结,将全部账户的状况组成一棵 Merkle 树,树的叶子节点是账户状况,树的根能够直接用来标明状况集结。因而,上述的 PRE_STATE 和 POST_STATE 也就是全局账户状况树的根。


账户状况模型


刚才咱们提到链上的整个体系中的账户状况,可由一棵 Merkle 树来处理。Merkle 树的叶子节点,即用户的状况信息。相同,链下扩容计划 zk Rollup 也能够用相似的 Merkle 树来安排其账户状况。



157283391084937.jpg

最简略的账户状况能够包含:账户的 public key,nonce 和 balance。而叶子节点在Merkle 树中是有仅有方位的,因而方位的索引信息可直接引证这个账户信息。


假定咱们用3个字节来标明这个索引信息的话,那么这棵 Merkle 树一共能够支撑 2^24 = 16,777,216 个账户。这关于一般的体系来说现已满意。因而,以太坊为例,账户地址能够由 address 的 20个字节 转为 Merkle 树的叶子节点索引 3 个字节。这样账户地址就被“紧缩”了。


除了对账户地址进行紧缩,咱们也能够对转账金额数据进行紧缩。例如,在以太坊上金额用256位的大整型来标明,但是实践运用进程中几乎很少用到超大金额和超小的金额。因而假定咱们就假定体系中转账的最小单位是 0.001 ETH,并且用 4 个字节来标明转账金额的话,咱们就能够支撑 0.001 ~ 4,294,967.295 ETH 的转账,这关于一般的体系来说也现已够了。假定还不可能够恰当再增加字节来标明金额,或许引进浮点数标明方法。


手续费与转账金额相似,实践手续费会在必定的规划之内起浮,因而咱们也能够为手续费设定一个最小单位,例如:0.001 ETH。然后用 1 个字节来标明 0.001 ~ 0.255 ETH 的手续费。这儿的手续费也就是 transactor 向 relayer 支付的手续费。


相同,咱们假定在正常运用环境下一个账户的转账次数不会抵达上万次,因而用2个字节来标明账户的 nonce 也差不多够了,因为 2 个字节 能够标明的规划抵达 0~65535。


毕竟签名字段不能紧缩,以以太坊为例,签名 (r, s, v) 一共需求 65 个字节。但实践的zk Rollup 体系中运用 EdDSA的较多。

因而,一个 transaction 的格式大体如下:

157283394947082.jpg


以上 transaction 各字段的长度仅作参看,在完毕具体体系的时分需求根据实践状况调整字段长度,以防止发作字段溢出的状况,但原则上仍是能省则省。因为生意数据越少,在相同存储容量的前提下,所能包容的生意数也就越多。


证明和验证


了解了状况搬迁函数和账户状况模型后,咱们再来了解下 relayer 收集 transaction 后做了些什么。


咱们刚才提到在 zk Rollup 的体系里,全部用户的账户信息由一棵 Merkle 树处理。而 Merkle 树的根被记录在了链上的智能合约里,这个根的值也代表着整个体系其时全部账户的状况。当有用户建议转账 transaction 时,这个状况就要发作改动。但改动有必要依照规则进行。


· 首要,有必要要确保 transaction 的合法性:

转出账户是否有满意的钱支付转账金额和手续费

转出账户的 nonce 是否正确

转账 transaction 的签名是否正确


· 接着,relayer  实施该转账 transaction,修改 Merkle 树中的转出账户和转入账户的叶子节点,然后从头核算新的 Merkle 树的根。


· 重复第二步,relayer 会依照先后顺序一次性处理多个 transaction,然后将毕竟核算得到的 Merkle 树的根作为新的状况提交到链上合约中。


但上述流程存在问题:假定仅提交状况树的根到合约,那么用户怎样信赖新的状况根是如实地根据上述逻辑核算出来的。假定 relayer 作恶,成心调大 transaction 的手续费呢?


处理这个问题的一个方法是,要求 relayer 提交状况树的根到合约时,一同也将全部 transaction 提交到合约,这样任何人都能够根据这些 transaction 来验证 relayer 在核算新的状况树时,有没有做弊。但这等所以将全部链下的数据搬回了链上,没有完毕 layer 2 扩容的目的。


运用零知识证明就能够很好地处理这个问题。zk Rollup 中的 zk 也就是 zero-knowledge 的缩写。relayer 在收集了一系列的 transactions 后,需求用预先定义好的 ZK circuits 来生成一个 PROOF:


确保每个生意 T[1], T[2], ..., T[n] 中的 nonce, value, fee 等值都没有问题,且 signature 正确。


确保状况搬迁进程没有问题,即 STF(PRE_STATE, T[1], T[2], ..., T[n]) = POST_STATE


然后将这个 PROOF 与 POST_STATE, t[1], t[2], ..., t[n] 一同提交到链上合约。其间 t[1], t[2], ..., t[n]是 transaction 的简化信息,不包含 nonce 和 signature。所以 t[i] 比 T[i] 更小。


然后智能合约只需求验证这个 PROOF 是否正确。假定 PROOF 正确且合约中保存的状况与 PRE_STATE 持平,那么新的状况 POST_STATE 将会被记录到合约中,替换原有状况。


因为 relayer 有必要生成 zkSNARK 的 PROOF,然后才调向合约提交,因而假定 relayer 作恶 修改用户的 transaction,那么 PROOF 将无法被验证经过。


其他,因为提交到链上的生意 t[1], t[2], ..., t[n] 是不包含 nonce 和 signature 的,因而上链的数据将会变得更小(上例中每个 transaction 仅会有11个字节上链)。


此刻,relayer 因为证明的绑缚,现已无法修改用户的 transaction。但是 恶意的 relayer 仍然能够回绝为某个 transactor 服务,不收集该 transactor 的 tranaction。为了防止这种行为,合约上有必要支撑 on-chain withdrawal,也就是任何一个 transactor 都能够从链大将自己的 token 提走。


现在的运用


现在一个典型的 zk Rollup 运用场景是去中心化的生意所,其代表是 Loopring DEX Protocol (v3)。有喜爱的小伙伴能够深化研究一下。


此外,开源的 zk Rollup 结构还有:


barryWhiteHat/roll_up -C++

matter-labs/rollup - rust


总结


zk Rollup 是一种新式的 Layer 2 扩容计划,该技能的中心思想是:


· 将主链作为存储前语,而非一同引擎 ;

· 将生意紧缩,并在区块链技术下抵达状况一同 ;

· 用零知识证明确保链下状况一同的安全性。


现在,zk Rollup 最典型的运用场景是去中心化的生意所。


PPIO 也在积极探索 zk Rollup 技能,并查验将其运用到 去中心化的带宽和存储生意范畴中去。


标签: 区块链作用

  • 评论列表 (0)

留言评论