本文探讨了协议设计中的封装复杂性和系统复杂性,强调在设计区块链协议时如何权衡这两种复杂性。作者通过比较BLS签名和Schnorr签名、ZK-SNARKs和欺诈证明等示例,阐述了不同技术选择可能带来的复杂性影响。文章最后指出了对于配置复杂性的判断并没有简单的答案,建议在具体情况中进行权衡。
封装复杂性与系统复杂性在协议设计中的对比
以太坊协议设计的主要目标之一是最小化复杂性:使协议尽可能简单,同时仍然能实现一个有效的区块链所需的功能。以太坊协议在这一点上远非完美,尤其是在2014-16年间设计时我们的理解还很有限,但我们依然积极努力在可能的情况下减少复杂性。
然而,实现这一目标的挑战之一在于,复杂性很难定义,有时为了引入不同类型的复杂性和不同的成本,必须在两个选择之间进行权衡。我们如何进行比较?
一个强大的智力工具,可以更加细致地思考复杂性,是区分我们所称的封装复杂性和系统复杂性。
封装复杂性发生在当一个系统具有内部复杂的子系统,但向外界呈现一个简单的“接口”。系统复杂性发生在系统的不同部分甚至无法清楚地区分,且相互之间有复杂的互动。
以下是一些例子。
BLS 签名和 Schnorr 签名是两种流行的密码签名方案,可以用椭圆曲线实现。
BLS 签名在数学上看起来非常简单:
签名: σ=H(m)∗k
验证: e([1],σ)=?e(H(m),K)
H 是一个哈希函数,m 是消息,k 和 K 是私钥和公钥。到目前为止,看起来很简单。然而,真正的复杂性隐藏在 e 函数的定义中:椭圆曲线配对,这是所有密码学中最难理解的数学之一。
现在,考虑 Schnorr 签名。Schnorr 签名仅依赖于基本的 椭圆曲线。但是,签名和验证的逻辑相对复杂一些:
那么……哪种签名“更简单”? 这取决于你在乎什么!BLS 签名有大量的技术复杂性,但所有复杂性都隐藏在 e 函数的定义中。如果把 e 函数当作黑盒,BLS 签名实际上很简单。另一方面,Schnorr 签名在总体复杂性上较少,但它有更多与外部世界可能产生复杂交互的部分。
例如:
椭圆曲线配对通常是一个强大的“复杂性海绵”,因为它们包含大量的封装复杂性,但能实现更少的系统复杂性。这一特性在多项式承诺领域也同样存在:比较 KZG 承诺 的简单性(需要配对)与 内部乘积论证 的复杂内部逻辑(不需要)。
在许多区块链设计中,一个重要的设计选择是密码学与加密经济学。通常(例如在 Rollups 中),这表现为在 有效性证明(又称 ZK-SNARKs)与 欺诈证明 之间的选择。
ZK-SNARKs 是复杂的技术。虽然 其基本思想 可以在一篇帖子中解释,但实际实现 ZK-SNARK 以验证某种计算涉及的复杂性远超计算本身(因此 ZK-SNARKs 在 EVM 上 仍在开发中,而 EVM 的欺诈证明已经 进入测试阶段)。有效地实现 ZK-SNARK 涉及带有特殊目的优化的电路设计,使用不熟悉的编程语言,以及许多其他挑战。另一方面,欺诈证明 inherently简单:如果有人提出质疑,你只需要直接在链上运行计算。为了效率,有时会增加二分查找方案,但即使如此也不会增加太多复杂性。
但尽管 ZK-SNARKs 复杂,其复杂性是 封装复杂性。另一方面,欺诈证明相对轻量的复杂性是 系统的。以下是欺诈证明引入的一些系统复杂性的例子:
基于这些理由,从复杂性观点出发,纯粹依赖 ZK-SNARK 的密码解决方案更可能在长期安全性上更具优势:ZK-SNARKs 具有更复杂的部分,这是某些人需要考虑的,但具有更少的悬而未决的后果,这是每个人都需要考虑的。
通常,封装复杂性较少的选择也是系统复杂性较少的选择,因此有一个显然简单的选择。但是在其他时候,你必须在一种类型的复杂性和另一种之间做出艰难的选择。此时应该清楚的是,封装的复杂性相对不那么危险。系统复杂性带来的风险不是简单的规范长度的函数;一个与其他所有部分相互作用的小 10 行的规范,比一个长度为 100 行且且其他方面被视为黑盒的函数引入了更多的复杂性。
然而,这种优先选择封装复杂性的方法是有限制的。软件 bugs 可以发生在任何代码段中,随着代码的增大,出现 bug 的概率接近 1。有时,当你需要以意想不到和新的方式与子系统交互时,原本封装的复杂性可能变成系统复杂性。
后者的一个例子是以太坊当前的双层状态树,它的账户对象构成了一棵树,而每个账户对象又有自己的存储树。
这种树结构是复杂的,但最初复杂性似乎得到了良好的封装:协议的其余部分作为一个可以读取和写入的键值存储与树互动,因此我们不必担心树的结构。
然而,后来复杂性显然产生了系统效应:账户具有任意大存储树的能力意味着没有任何方式可以可靠地预期某个状态片段(例如“所有以 0x1234 开头的账户”)具有可预测的大小。这使得将状态拆分成若干部分变得更加困难,复杂化了同步协议的设计和尝试 分发存储过程。封装复杂性为何变成系统复杂性?因为接口发生了变化。 解决方案?当前 向 Verkle 树的提案 还包括对树的良好平衡单层设计的转变。
最终,在任何给定情况下倾向于哪种类型的复杂性是一个没有简单答案的问题。我们能做的最好事情是保持适度偏向封装复杂性的态度,但不要过于极端,并在每个具体案例中做出判断。有时,为了允许大幅降低封装复杂性而牺牲一点系统复杂性确实是做出的最佳选择。而在其他时候,你甚至可以误判什么是封装的,什么不是。每种情况都是不同的。
- 原文链接: vitalik.eth.limo/general...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!