一文读懂Uniswap,附Uniswap使用教程
一、加密货币交易形式当我们要进行加密货币交易时,使用最早也是目前使用最多的形式还是中心化交易所,在中心化交易所,我们首先需要注册,然后加密货币也需要存入到交易所,由交易所进行托管,如果要提现加密货币出来,也需要经过交易所审核同意。 虽然中心化交易所有诸多优势,例如交易速度较快、用户不需要管理私钥,降低了用户的使用门槛,但是它的弊端也是显而易见的,用户的加密货币由交易所托管,交易所是有跑路风险的。也确实发生过多起交易所跑路的事件,几乎每年都有发生。 那么,有没有更好的加密货币交易形式呢? 随着区块链技术的不断发展,加密货币交易形式也变得越来越多样化,我们不但可以使用中心化交易所进行交易,也可以使用去中心化交易所进行交易。 在中心化交易所进行交易时,不需要注册,只需要使用数字钱包连接去中心化交易所就可以进行加密货币的交易了,交易完成后,相应的加密货币会自动转入到用户的数字钱包中,用户的资产始终在自己的钱包中,并非像中心化交易所那样托管在交易所,所以,在去中心化交易所进行交易,安全性大大提高了。 目前,去中心化交易所主要有两种形式,一种是交易所撮合买方用户和卖方用户的订单,只不过操作过...
多签钱包Gnosis Safe使用教程
原作者:Gnosis Safe 团队 在过去的 4 年里,多重签名钱包 Gnosis Safe 的发展已经到达了全新的高度。它已经成为 Web3 的关键基础设施,为 DAO、机构、项目和个人保护数字资产。仅在以太坊主网上,Gnosis Safe 用户就管理着价值超过640 亿美元的资产,并且所有这些都是自我保管的!什么是多重签名?Gnosis Safe 的基础知识大多数以太坊用户习惯于使用单一密钥钱包(例如:MetaMask),通常称为外部账户(EOA)。这些帐户使用私钥进行保护,私钥可以转换为用户的 12 个单词的"助记词"。如果该私钥以任何方式被泄露,则资金可能会被盗。 如果您的企业由多于 1 个人组成,则外部帐户不是管理加密业务资金的安全方式。如果员工道德低劣或对于私钥不够小心,资金将永远丢失。即使您的企业只由您自己组成,我认为这仍然是一种糟糕的资金管理方式。那么,更好的解决方案是什么? 使用多重签名。Gnosis Safe 是一个运行在以太坊上的智能合约钱包,需要最少数量的人在交易发生之前批准,交易才会发生(M-of-N)。例如,如果您的企业中有 3 个主要利益相关者,则...
零知识证明——zk-stark数学入门
原文:CYC Labs咕咕 STARK的出现是为了解决计算完整性(CI)的问题。CI是商业的基本属性,有了CI我们才能信任银行账单和账户余额。文章讨论了无需可区块链中在无信任的情况下完成CI。 在旧世界的金融系统中,会有机制激励他们诚信的给社会服务,还有一个变体,就是可信执行环境(TEE)。比如Intel生产SGX芯片,Intel是一个可信的硬件制造商,所以现在的CI是基于对硬件和它的制造商的信任,并且假设不可能在这样的物理设备中提取密钥。在新世界中,即区块链,提供了一种更加直接的方式实现CI,“dont trust, verify” ,就是直接验证,只需要一个节点,只需要它设置了标准计算,比如一个联网的笔记本电脑就可以给所有交易提供完整性验证。但是这也直接导致两个挑战,隐私和可扩展。所以这就引出了证明系统。 证明系统开始于1985年提出的交互证明(interactive proof),通过prover和verifier两个实体,发送信息进行多轮交互,利用随机性产生零知识证明,验证者最后会输出一个决策来接受或者拒绝这个新状态。当状态A更新到B,证明系统解决了CI时,就会有可靠性(...
Buidling Web3.
一文读懂Uniswap,附Uniswap使用教程
一、加密货币交易形式当我们要进行加密货币交易时,使用最早也是目前使用最多的形式还是中心化交易所,在中心化交易所,我们首先需要注册,然后加密货币也需要存入到交易所,由交易所进行托管,如果要提现加密货币出来,也需要经过交易所审核同意。 虽然中心化交易所有诸多优势,例如交易速度较快、用户不需要管理私钥,降低了用户的使用门槛,但是它的弊端也是显而易见的,用户的加密货币由交易所托管,交易所是有跑路风险的。也确实发生过多起交易所跑路的事件,几乎每年都有发生。 那么,有没有更好的加密货币交易形式呢? 随着区块链技术的不断发展,加密货币交易形式也变得越来越多样化,我们不但可以使用中心化交易所进行交易,也可以使用去中心化交易所进行交易。 在中心化交易所进行交易时,不需要注册,只需要使用数字钱包连接去中心化交易所就可以进行加密货币的交易了,交易完成后,相应的加密货币会自动转入到用户的数字钱包中,用户的资产始终在自己的钱包中,并非像中心化交易所那样托管在交易所,所以,在去中心化交易所进行交易,安全性大大提高了。 目前,去中心化交易所主要有两种形式,一种是交易所撮合买方用户和卖方用户的订单,只不过操作过...
多签钱包Gnosis Safe使用教程
原作者:Gnosis Safe 团队 在过去的 4 年里,多重签名钱包 Gnosis Safe 的发展已经到达了全新的高度。它已经成为 Web3 的关键基础设施,为 DAO、机构、项目和个人保护数字资产。仅在以太坊主网上,Gnosis Safe 用户就管理着价值超过640 亿美元的资产,并且所有这些都是自我保管的!什么是多重签名?Gnosis Safe 的基础知识大多数以太坊用户习惯于使用单一密钥钱包(例如:MetaMask),通常称为外部账户(EOA)。这些帐户使用私钥进行保护,私钥可以转换为用户的 12 个单词的"助记词"。如果该私钥以任何方式被泄露,则资金可能会被盗。 如果您的企业由多于 1 个人组成,则外部帐户不是管理加密业务资金的安全方式。如果员工道德低劣或对于私钥不够小心,资金将永远丢失。即使您的企业只由您自己组成,我认为这仍然是一种糟糕的资金管理方式。那么,更好的解决方案是什么? 使用多重签名。Gnosis Safe 是一个运行在以太坊上的智能合约钱包,需要最少数量的人在交易发生之前批准,交易才会发生(M-of-N)。例如,如果您的企业中有 3 个主要利益相关者,则...
零知识证明——zk-stark数学入门
原文:CYC Labs咕咕 STARK的出现是为了解决计算完整性(CI)的问题。CI是商业的基本属性,有了CI我们才能信任银行账单和账户余额。文章讨论了无需可区块链中在无信任的情况下完成CI。 在旧世界的金融系统中,会有机制激励他们诚信的给社会服务,还有一个变体,就是可信执行环境(TEE)。比如Intel生产SGX芯片,Intel是一个可信的硬件制造商,所以现在的CI是基于对硬件和它的制造商的信任,并且假设不可能在这样的物理设备中提取密钥。在新世界中,即区块链,提供了一种更加直接的方式实现CI,“dont trust, verify” ,就是直接验证,只需要一个节点,只需要它设置了标准计算,比如一个联网的笔记本电脑就可以给所有交易提供完整性验证。但是这也直接导致两个挑战,隐私和可扩展。所以这就引出了证明系统。 证明系统开始于1985年提出的交互证明(interactive proof),通过prover和verifier两个实体,发送信息进行多轮交互,利用随机性产生零知识证明,验证者最后会输出一个决策来接受或者拒绝这个新状态。当状态A更新到B,证明系统解决了CI时,就会有可靠性(...
Buidling Web3.

Subscribe to DK

Subscribe to DK
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
区块链公链自诞生以来,虽然大大降低了信任的门槛,但一直面临着一个效率问题:即 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 树来组织其账户状态。

最简单的账户状态可以包含:账户的 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 的格式大体如下:

以上 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 框架还有:
zk Rollup 是一种新型的 Layer 2 扩容方案,该技术的核心思想是:
将主链作为存储媒介,而非共识引擎 ;
将交易压缩,并在链下达成状态共识 ;
用零知识证明保证链下状态共识的安全性。
目前,zk Rollup 最典型的应用场景是去中心化的交易所。
PPIO 也在积极探索 zk Rollup 技术,并尝试将其应用到 去中心化的带宽和存储交易领域中去。
Transcript: Scalable blockchains as data layers | Vitalik Buterin
ZK Rollup: Ethereum Scalability with ZKPs:https://www.youtube.com/watch?v=QyM9qdFKsEA
On-chain scaling to potentially ~500 tx/sec through mass tx validation
区块链公链自诞生以来,虽然大大降低了信任的门槛,但一直面临着一个效率问题:即 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 树来组织其账户状态。

最简单的账户状态可以包含:账户的 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 的格式大体如下:

以上 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 框架还有:
zk Rollup 是一种新型的 Layer 2 扩容方案,该技术的核心思想是:
将主链作为存储媒介,而非共识引擎 ;
将交易压缩,并在链下达成状态共识 ;
用零知识证明保证链下状态共识的安全性。
目前,zk Rollup 最典型的应用场景是去中心化的交易所。
PPIO 也在积极探索 zk Rollup 技术,并尝试将其应用到 去中心化的带宽和存储交易领域中去。
Transcript: Scalable blockchains as data layers | Vitalik Buterin
ZK Rollup: Ethereum Scalability with ZKPs:https://www.youtube.com/watch?v=QyM9qdFKsEA
On-chain scaling to potentially ~500 tx/sec through mass tx validation
No activity yet