StarkEx 是一种可扩展性引擎,同时支持用户自主托管资金;这才刚刚登陆以太坊主网。StarkEx 实现了 STARK 证明系统的零知识(Zero-Knowledge Proof,ZKP)版本。实现自主托管功能的道路崎岖难行:托管方案会更简单、更便宜,而且(最重要的是)更容易理解 —— 大家已经习惯托管型的软件系统很多年了。“自主托管系统”,或者叫 “非托管型系统”,其实运用得相当广泛。只要是用户能预设自己可以(一键)完全控制自己资金的系统,都可以这么称呼:免许可型区块链一开始就是被当成托管型系统的替代方案而提出的,想到这一点,你会觉得现状很魔幻。我们知道建立一个完全自主托管的系统的难度,也知道在这个圈子里搞创新有很多维度。我们还觉得,随着时间推移,大家会发现迁移到一个更加自主托管的系统中总是有用的。本系列的博文会详细说明我们做出的选择,以及我们为 StarkEx (在这个维度上)设定的方向。
本文是我们系列博客的第一篇,准备讲讲我们在保证 StarkEx 是并且永远是自主托管型方案的道路上付出的努力。
首先,有必要定义一下 “自主托管(self-custodial)”是什么意思。在我们看来,仅当一个系统满足下列属性时,它才能被叫做 “自主托管型系统”:
没有用户的明确签名,资金就不能转移;
在签名的时候,用户可(通过钱包的用户体验设计)获得所有的信息;
资金随时可退出;
代码升级机制即使被滥用也不能破坏上述机制。
本文将致力于解释:(1)为什么说证明系统最适合于支持自主托管型方案;(2)StarkEx 智能合约的审计状况。后续博文会依次讲解(3)我们所用的智能合约升级机制;(4)钱包支持 (STARK 签名方案及整合方法);(5)数据可用性(从我们第一个版本所用的数据可用性委员会方案,到完全免信任的链下数据可用性方案)。
自主托管性作为一个神圣的理想,可追溯到区块链最初的愿景,一句话:“没拿着私钥的,就不算你的币(not your keys, not your coins)”。早些时候,因为 Layer-1 的吞吐量局限,自主托管这个理想往往让位于可扩展性(以及流动性)。这种让步的结果就是中心化的交易所:交易所托管着交易者的密码学资产,交易者得到的好处是流动性(还有相当大的对手方风险)。但今天,ZKP 系统背后的科学和工程技术都变得更成熟了,尤其是 STARK,我们已经完全迎来了奇点 —— 再也没必要去作这种让步了。
ZKP 系统的历史既美丽又复杂。重点是,ZKP 系统能以免信任的模式,为公链提供可扩展性和隐私性。而自主托管型解决方案恰好需要免信任的基础设施。换句话说,如果需要信任某个实体,即使没让 “自主托管” 变成一句空话,也会大大削弱其意义。
ZKP 系统有两个部分:提供 “计算完整性(CI)” 的基础层,以及在此之上保证零知识的概率层。要实现可扩展性的时候,我们实际上只需要 CI 层。CI 层可帮助参与协议的一方(即证明者)为任意计算(或者说状态转换)在链下生成一个证明,而任意数量的另一方(验证者)可在链上以非常小的计算开销验证这个证明。
理论上来说,信任假设当然是越少越好。具体而言,对 STARK 来说:
不需要对验证者作任何信任假设,既不需要实时的信任关系,也不需要预处理的信任关系,因为 STARK 不需要受信任的初始化设置(trusted setup)。说得极端一些,即使由一个恶意团体使用恶意的硬件来充当证明者,计算不同则证据一定不同,错误的计算所生成的证明无法通过检验。
验证者在链上运行,需要保证资源是足够的。
StarkEx 是一种为交易所设计的可扩展性引擎,但 STARK 也可以用于为其它应用提供可扩展性。使用的时候,应用的部分逻辑要在链下实现,而需要与链上实体(智能合约、账户,等等)交互的逻辑则要作为应用智能合约(ASC)在链上实现。
StarkEx 的一个用户是我们的合作伙伴,DeversiFi,一个自主托管型交易所。DeversiFi 会使用 StarkEx 来扩展交易操作(包括交易也包括转账)的吞吐量。ASC 保证了没有用户的签名资金就无法转移(签名是通过对 STARK 证据的验证来验明的)。StarkEx 要求用户存储资金到 ASC 中,这就使该 ASC 容易成为黑客的目标。这份 ASC 代码已经经过审计和高强度的测试,以保证其正确性和安全性。此外,我们还计划继续使用其它工具,比如形式化验证,来保证代码的正确性和安全性。
审计并不能保证一个系统是安全的,因为合约的掌控账户(admin)可以给合约做一系列升级,让自主托管变成一个空架子。智能合约的升级(或者换句话说叫迁移)让开发者可以修复 bug 并扩展功能。下一篇博客,我们就要讲讲我们是如何设计智能合约升级机制,来保证 StarkEx 能永远保证其自主托管性。
对了,还要提醒一句:大家一般用来形容 “自主托管型方案” 的形容词是 “非托管型(non-suctodial)”,我们不喜欢这个词,因为它是否定形式的,似乎暗示了托管型系统(比如中心化交易所)才是基准,才是值得借鉴的。但托管型解决方案是与公链的精神相悖的。强制托管方回到自己原有的角色,是比特币和以太坊的精神所在,这就是为什么我们更喜欢 “自主托管” 这个词。
动因
StarkEx 是一种自主托管式可扩展性引擎。我们已经介绍过了自主托管式系统的各个方面,其中可升级性也是一个方面。本文将要介绍我们为 StarkEx 构建的可升级性机制,这是确保 StarkEx 维持自主托管性的关键。
需要升级智能合约代码的情况有两种:增加新功能和修复安全性漏洞。难点在于如何在不损害系统自托管性的前提下引入升级。如果 StarkEx 逻辑被恶意更换,应用运营者就有可能掌控所有用户资产。StarkEx 通过一个新型可升级性机制来保护用户资产。简单来说,这个机制利用了时间锁和三类临时性智能合约(详见下文)。
StarkEx 应用合约简介
StarkEx 应用智能合约(ASC)采用了代理模式(由 openZepplin 率先引入),因此包含多个子组件。代理合约内存储着所有数据和资金,并(通过一个指针)指向一个定义了功能的地址(也就是逻辑合约 Logic Contract)。通过代理合约,我们在代理合约环境内运行委托调用(delegate call)来调用逻辑合约。因此,StarkEx ASC 逻辑是由逻辑合约定义的;整个系统通过部署新的合约和更新代理合约中的指针来升级(逻辑)。验证者(Verifier)合约和数据可用性委员会(Data Availability Committee,DAC)合约的地址均由逻辑合约而非代理合约引用(如果你想要复习关于 StarkEx 组件的简介,请点击此处)。
升级机制和保护自主托管
在第一阶段,我们为逻辑合约、验证者合约和数据可用性委员会合约都单独设置了升级机制。所有升级操作都只能由经过许可的地址执行。
1.逻辑合约升级:
安全性风险及其解决方案
正如我们在上文所述,升级智能合约的主要原因之一是检测出了安全性风险。安全性风险可以分为以下三类:1.资金被锁定:StarkEx 是一种自主托管式可扩展性引擎。我们已经介绍过了自主托管式系统的各个方面,其中就包括钱包。本文将要介绍我们是如何与不同的钱包提供商合作,来确保 StarkEx 保持自主托管型系统的本色。
自主托管型系统的一大重要特征是,每次交互都需要用户签名。我们的首要原则是 “不只要签名,还要验证它。”—— 这是套用的区块链行业的老话:“不要相信它,去验证它。” 换言之,要是用户不能验证,自主托管型系统只是徒有其名而已。用户要能够验证他们的钱包和自主托管型应用之间所进行的交互的参数。例如,如果一名用户向链上合约提供了签名,ta 的钱包显示的应该是经过良好解析的可读消息,而非一团高深莫测的数据。在用户需要签署链下交易的时候,二层应用也应遵循同样的原则。
为了恪守 “不只要签名,还要验证它” 这一原则,我们正在与多个钱包提供商合作,将我们的协议直接整合进他们的产品内。这一整合对零知识证明系统来说尤为重要。为了高效地验证签名,零知识证明二层系统所使用的曲线通常不同于标准的以太坊曲线,使用的哈希函数也不同。一种简单的方法是在浏览器中实现钱包。我们倾向于不这么做,主要有两点原因:首先,StarkEx 的目标是让用户可以直接通过钱包在专业的交易平台中交易,无需再将资金转移到其他地方;第二,构建一个安全的钱包并非易事(路印最近被曝出的高危前端漏洞就是一个很好的例子)。
下文列出了截至 2020 年 5 月支持 StarkEx 的钱包。
Ledger :完全整合
Ledger 是完全整合 StarkEx 的。无论是链上合约调用还是链下订单提交,每一次交互都将由 Ledger 解析,然后向用户显示。用户要先确认过后才能在 Ledger 中签名。用户将能验证每一次交互的参数。此外,Ledger 将在其原生以太坊应用中支持 StarkEx (用户甚至不需要通过 Ledger Live 安装特定的应用)。
为了整合 StarkEx ,我们必须将 STARK 专用曲线添加到 Ledger 的固件中 ,并在 Ledger 的应用中执行 StarkWare 的哈希函数(Pedersen 哈希函数)。通过 StarkWare 和 Ledger 的紧密结合,Ledger 成了首个应用于二层的硬件钱包。
WalletConnect:完全整合
WalletConnect 是完全整合 StarkEx 的。WalletConnect 是一个开放式协议,(通过二维码)将桌面应用连接到使用端到端加密技术的移动钱包。我们与 Pedro Gomes 一起实现了 StarkEx 交互,创建了 StarkEx WalletConnect Provider 。DeversiFi 是首个构建在 StarkEx 上的自主托管型交易所,也将 WalletConnect 整合进了它的应用中。移动钱包 Argent 目前正在整合 StarkEx WalletConnect Provider ,很快就会支持用户在 DeversiFi 上进行自主托管型交易。
MetaMask:混合解决方案
目前,我们为 MetaMask 用户提供混合解决方案。所有链上交易都将由 MetaMask 处理,所有链下交易都将由浏览器内置钱包(第一种就是 DeversiFi 的钱包)处理。这一解决方案与如今绝大多数二层方案相同,而且可以让我们立即支持 MetaMask 庞大的基础用户。这一方案目前还做不到上面几个方案那样完美:用户既不能验证链上合约调用,也不能验证他们的链下交易。一旦 MetaMask 部署好 Snaps 插件系统,这一问题就能得到解决。我们将继续作为 Snaps 上的 Design Partner (设计伙伴)与 MetaMask 团队密切协作(参见我们在 Devcon 5 上的联合演示),让 StarkEx 像我们所描述的最优方法那样为 MetaMask 用户提供服务。
动因
StarkEx 是一种自主托管式可扩展性引擎。这已经是我们的《StarkEx 作为自主托管型方案》系列的第四篇也是最后一篇文章了。本文将要介绍 StarkEx 这个自主托管型系统的最后一部分内容:数据可用性方案的部署以及它将如何引领我们走向更加免信任的未来。
我们先来回顾一下知识点。在 StarkEx 中,交易是批量处理的,然后在链下验证,并生成一个 STARK 证明。我们将这一过程称为有效状态转换。这个证明会和系统新状态的承诺一起被发送到区块链上,然后由区块链验证证明并存储承诺。批量交易的数据存储在链下或链上皆可。如果选择链上数据可用性,交易就会被记录成调用数据(calldata)。如果选择链下数据可用性,交易就会被记录在链下。链下数据可用性更具可扩展性:无论 StarkEx 上有多少活动,消耗的区块链资源都是固定的。
首个部署完成的 StarkEx —— 用于支持 DeversiFi 去中心化交易所 —— 将选择链下数据可用性。DeversiFi 之所以做出这样的选择,一方面是因为可扩展性优势,另一方面是因为这会为其用户提供更好的隐私性,可以帮助用户隐藏其交易策略。因此,想要访问自己账户余额的用户可以从 StarkEx 运营者处获得:应用运营者(Application Operator)和证明运营者(Proof Operator)(在首个部署完成的 StarkEx 项目中,这两个角色分别由 DeversiFi 和 StarkWare 担任)。要验证自己的账户在某个时刻的状态时,用户可以根据自己账户在相关默克尔树上的默克尔路径完成验证。关于用户对运营者的信任,需要注意的一点是:用户不需要基于对运营者的信任来相信系统状态是有效的,因为状态转换的有效性是由 STARK 证据来保证的。用户只需相信运营者会实现数据可用性即可。
数据有效性委员会(DAC)
为了让用户完全不需要信任 StarkEx 运营者,我们已经组建了数据有效性委员会(DAC)。DAC 成员的职责是保存链下数据的副本,并在紧急情况下将这些副本放回公共域。紧急情况指的是 StarkEx 运营者不响应用户提款要求的情况。在紧急情况下,应用智能合约(ASC)将不再接受新的状态更新,而是只允许能够提供最新状态的默克尔证明的用户直接取款。
DAC 成员的职责
在正常情况下
在紧急情况下
将它们保存的数据副本公开。在这种情况下,用户可以访问通往他们账户的默克尔证明,使用这条证明直接从 ASC 那里取回他们的资金,完全不需要信任运营者。通往未来之路
我们认为,将对 DAC 的信任最小化是非常重要的。首先,我们打算将 DAC 存储的数据加密,以此确保 DAC 成员不再掌握任何有关 StarkEx 用户的数据。加密可以确保委员会成员不会透露敏感信息,从而减少他们的责任,也可以免去用户对他们的信任。因此,加密可以让 StarkWare 大幅增加委员会的人数,从而减少在紧急情况下对个体成员履行职责的依赖。之后,我们将实现一个完全免信任的方案,可以让相关方完全不需要信任 DAC 。这个方案需要投入非常有限的资源:或者将他们的数据放到链上,或者监控链下数据的进程(需要投入的资源远少于运营者)。