特别鸣谢 Balaji Srinivasan、Coinbase、Kraken 和 Binance 的讨论研究。每当有大型中心化交易所爆雷时,一个常被提及的问题是:我们是否可以利用加密技术来解决这个问题。交易所可以通过创建密码学证明的方式证明其链上持有的资金足以偿付用户,而不仅仅依靠政府牌照、审计员、调查公司治理以及交易所法人背调等“法币”方案。
甚至可以想得更远一点,交易所可以建立一个未经储户同意无法提取储户资金的系统。我们可以尝试探索“不作恶”有职业素养的 中心化交易所(CEX)与“无法作恶”却泄漏隐私的低效去中心化交易所(DEX)之间的界限。这篇文章将深入探讨让中心化交易所更加去信任化的历史尝试,与其采用技术的局限性,以及一些依赖 ZK-SNARK 等先进技术的有力手段。
Balance lists 和 Merkle 树(Merkle tree):传统的偿付能力证明
交易所尝试用密码学方式来证明没有欺骗用户可以追溯到很久以前。2011 年,当时最大的比特币交易所 MtGox 通过发送一笔交易,将 424242 枚比特币转移到预先公布的地址中,以此来证明他们有足够的资金。2013 年,大家开始讨论解决问题的另一个方面—证明用户存款的总规模:如果可以证明用户的存款等于 X(负债证明 proof of liabilities),并证明拥有 X 个代币的私钥(资产证明 proof of assets),那么就有了偿付能力证明,即证明交易所拥有可以偿还用户资金的能力。
最简单的验证存款的方法是发布一个 (username, balance) 列表(list)。每个用户都可以检查自己的 balance 值是否包含在列表中,而任何人都可以验证以下内容:(i)所有 balance 值都是非负的,(ii)balance 值总和等于所宣称的金额。然而,这种方法会破坏隐私。为了解决这个问题,我们可以稍作修改:发布一个 (hash(username, salt), balance) 列表,并私下向每个用户发送他们的 salt 值。即使进行了这样的修改,它仍然泄漏了 balance 值信息和变化。为了保护隐私,我们引入了后续技术:Merkle 树技术( the Merkle tree technique)。

Merkle 树技术(Merkle tree technique)把用户 balance 值放在 Merkle sum tree 中。在 Merkle sum tree 中,每个节点都为都是 (balance, hash) 对。最底层的叶节点(leaf node)代表了各个单独用户的 balance 值及其 salted username hashes。在每个更高层节点中,其 balance 值为底层 2 个节点的 balance 值之和,hash 为底层 2 个节点的哈希值。而 Merkle sum proof 与 Merkle proof 类似,为Merkle tree 的 “branch(分支)” ,包含了由该叶节点(leaf node)到根节点(root node)的所有姐妹节点(sister node)。
交易所将给每个用户发送其 balance 值的 Merkle sum proof,然后用户就相当于得到了其 balance 值被正确包含在 total 中的保证。一个简单的代码示例见:

这种设计方案要比完整公开列表(fully public list)的隐私泄露要少,同时可在每次发布 root 时对 branches 进行 shuffling 来进一步降低隐私泄露,但一定程度的隐私泄露仍然存在:Chalie 知道某人有164 ETH,某两个用户的 balance 值之和为 70 ETH 等等。控制着多账户的攻击者仍有可能获得交易所用户的大量信息。
该方案的一个重要的细节是可能存在负数 balance 值的情况:如果一个交易所在储备金中只有 890 ETH,但客户余额总量却达到了1390 ETH,交易所通过在树的某个地方添加一个 balance 值为-500 ETH 虚假账户来弥补差额该怎么办呢?尽管存在这种可能性,但不会破坏该方案,原因在于此处设计的是 Merkle sum tree,而不是常规的 Merkle tree。假设 Henry 是由交易所控制的虚假账户,交易所在那里存入了-500 ETH 的余额:

Greta 的证明验证将失败:因交易所在其证明中包含了 Henry 的-500 ETH 的节点,该节点无效会被 Greta 拒绝。而 Fred 和 Eve 的证明验证也将失败,因其证明中包含了 Henry 之上的-230 ETH 的中间节点,因此也是无效的。为了盗用行为不被发现,交易平台只能寄望于树的右半部分没人检查其余额证明(balance proof)。
如果交易所能保证有 500ETH 的用户不去校验其 balance proof,或者不会抱怨其从未收到过相应的 balance proof,则交易所就作弊成功了。交易所也可直接将这些用户剔除出树,也具有相同的效果。因此,如果仅仅实现负债证明是目标的话,Merkle 树技术基本上是一个很好的方案,但它的隐私性仍然不理想。可以通过更巧妙地使用 Merkle 树来达到这一目的,例如将每个 satoshi 或 wei 作为单独的叶节点,可以进一步提高隐私性。不过,借助更现代的技术,还有更好的方法可以实现这一点。
通过 ZK-SNARK 技术加强隐私性和稳健性
ZK-SNARK(零知识可扩展非交互式证明)是一项强大的技术。ZK-SNARK 可能对密码学而言就像 transformers对 AI(人工智能)一样:它是一种强大的通用技术,可以完全淘汰之前几十年为各种问题开发的特定应用技术。因此,我们可以利用 ZK-SNARK 来极大地简化和改善负债证明协议中的隐私性问题。
最简单的方法是将所有用户的存款放入一个 Merkle 树(或者 KZG多项式承诺)中,并使用 ZK-SNARK 证明树中所有 balance 值均为非负数,并且总和为某个宣称的值。如果我们为了保护隐私而添加了哈希层,那么每个用户获得的 Merkle 分支(或 KZG 证明)将不会透露任何其他用户的 balance 值信息。

可在 KZG 的基础上,采用一种特殊用途的 zk-SNARK 来证明 balance 值总和以及每个 balance 值为非负数。我们引入了一个辅助多项式 I(x),其「构建出用户余额的每一位」(为了举例,我们假设余额低于 215),其中每第 16 个位置追踪差额保证,只有当实际总额与宣称总额相等该值才会是 0。如果 z 是一个 128 阶的原根,我们可以证明方程成立:

I(x) 的有效设定的第一个值将为 0 0 0 0 0 0 0 0 0 0 1 2 5 10 20 -165 0 0 0 0 0 0 0 0 0 1 3 6 12 25 50 -300 ...
关于如何将这样的方程式转化为多项式检验,然后再转化为 ZK-SNARK,请参见 ZK-SNARK 文章中的此处及此处,以进一步解释。这不是最佳的协议,但它确实表明了这些类型的加密证明并没有那么吓人。
只需几个额外的方程式,像这样的约束系统就可以适配更复杂的设置。例如,在杠杆交易系统中,个别用户出现负余额是可以接受的,但前提是他们有足够的其他资产,可以用抵押保证金来弥补资金。SNARK 可以用来证明这个更复杂的约束,向用户保证交易所没有背地里违规豁免某些用户从而从而危及用户资产。
长远来看,这种 ZK 负债证明也许不仅可以用于交易所的用户存款,还可以用于更广泛的借贷。任任何申请贷款的人都会将贷款记录放入一个多项式或树中,然后将该结构的根(root)发布到区块链上。这样,任何寻求贷款的人都可以通过零知识证明向贷款人证明他们没有过多的其他贷款。最终,法律创新甚至可以使以这种方式承诺的贷款具有比尚未承诺的贷款更高的优先级。这正是《Decentralized Society: Finding Web3's Soul》论文中讨论的一个观点所指向的方向:通过某种形式的“灵魂绑定代币(SBT)”,在链上实现负面声誉或限制的一般概念。
资产证明
资产证明的最简单版本是我们上面看到的协议:为证明您持有 X 个币,只需在某个预先约定的时间转移 X 个币,或其交易的数据字段包含“这些资金属于 Binance”。为免去支付交易费用,可以签署一个链下信息来代替。比特币和以太坊都有链下签名信息的标准。
这种简单的资产证明技术有两个实际的问题:
- 冷钱包(离线存储)处理
- 抵押品双花
交易所有几种方式可选:
- 维护少量公开长期使用的地址:交易所生成少量地址,为每个地址发布一次所有权证明,然后重复使用这些地址。这是最简单的方案,但却存在如何保证安全性和隐私性的问题。
- 持有多个地址,随机证明其中几个:交易所有很多地址,甚至可能每个地址只用一次,并在单次交易后不再使用。在这种情况下,交易所需要有一个协议,不时会随机选择一些地址“开放”来证明所有权。一些交易所已通过审计员进行了类似的操作,但原则上,这种技术可以转化为完全自动化的程序。
- 更复杂的零知识证明:例如,交易所将其所有地址设置为 1/2 多签,其中一个密钥每个地址都不同,另一个则是以某种复杂但非常安全的方式存储的“大型”紧急备份密钥,例如 12/16 多签。为了保护隐私,避免暴露地址集合,交易所甚至可以在链上运行一个零知识证明,来证明链上所有具有这种格式的地址总余额。
最后一个问题是:能否在法定货币上进行资产证明?交易所不仅持有加密货币,还持有银行系统中的法定货币。其答案是肯定的,但这样的程序不可避免地依赖于"法定"信任模式:银行本身可以证明余额,审计员可以证明资产负债表等。鉴于法币无法通过密码学来验证,这是在该框架内所能做到的最佳方式,仍是值得一试的。
另一种方法是将一个运行交易所和处理 USDC 等资产支持的稳定币的实体,和另一个处理加密货币和传统银行系统之间的现金流入和流出过程的实体(USDC 本身)清晰地分开。因为 USDC 的“负债”只是链上的 ERC20 代币,负债证明是“免费的”,只需要资产证明。
Plasma 和 Validium:中心化交易所可以成为非托管的吗?
更进一步假设,我们不想只是证明交易所具备足够资金来偿还用户债务。相反,我们想完全防止交易所窃取用户资金。
Plasma 在这方面做出了首次尝试,它是一个在 2017-18 年在以太坊研究圈内流行的扩展解决方案。Plasma 的工作方式是将余额分割成一组单独的“币”,每个币都分配了一个索引,并放在了 Plasma 区块的默克尔树中一个特定的位置。对每个币进行有效转移都需要将交易放到树中的正确位置,树的根会在链上公布。

OmiseGo 试图在这个协议的基础上做一个去中心化交易所,但从那时起他们就转向了其他方向,和 Plasma 团队自身一样,现在是 Optimism,一个 EVM Rollup 项目。
没有必要将 2018 年构思的 Plasma 的技术限制(例如,证明代币碎片化)作为整个概念的道德寓言来看待。自 2018 年 Plasma 的讨论达到高峰以来,ZK-SNARK 在与可扩展性相关的用例中变得更加可行,正如我们之前所说,ZK-SNARK 彻底改变了一切。
Plasma 创意的现代版本是 StarkWare 所称的 validium:基本上与 ZK-Rollup 相同,除了数据保存在链下。这种结构可以用于很多用例,可以想象任何中心化服务器需要运行代码并证明它正在正确执行代码的地方。在 validium 中,运营商无法窃取资金,但根据实施的细节,如果运营商直接消失,用户资金存在被卡住的可能。
这一切都很好:CEX 与 DEX 并非是二元对立的,事实证明存在一整套包括各种形式混合中心化的选择。在这些选择中,你可以获得更高的效率,但仍有很多加密护栏,防止中心化运营商进行大多数形式的滥用。

然而,余下的基本问题也值得思考:如何处理用户错误。目前最重要的错误类型是:如果用户忘记密码、丢失设备、被黑客攻击或以其他方式无法访问他们的账户怎么办?
交易所可以解决这个问题:首先是电子邮件恢复,如果仍然失败,则通过 KYC 进行更复杂的恢复。但为了能够解决此类问题,交易所需要实际控制代币。为了能够出于正当理由收回用户账户的资金,交易所需要拥有也可以用于出于不良理由窃取用户账户资金的权力。这是一个不可避免的取舍思维。
理想的长期解决方案是依靠自我托管,在未来用户可以轻松访问多重签名和社交恢复钱包等技术来帮助处理紧急情况。但在短期内,有两种明确的替代方案,它们的成本和收益截然不同:

另一个重要的问题是跨链支持:交易所需要支持许多不同的链,像 Plasma 和 Validium 这样的系统需要用不同的语言编写代码来支持不同的平台,并且根本无法在其它(尤其是比特币)上实现目前的形式。从长远来看,这有望通过技术升级和标准化得到解决;然而,在短期内,这是支持托管交易所暂时保持托管状态的另一个论据。
总结:更好的交易所的未来
短期内,交易所分为两个明确的“类别”:托管交易所和非托管交易所。今天,后一类只是 DEX,例如 Uniswap,未来我们可能还会看到加密“受限”的 CEX,其中用户资金保存在类似于 Validium 智能合约中。我们也可能会看到半托管交易所,用法定货币而不是加密货币来信任它们。
两种类型的交易所都将继续存在,而提高托管交易所安全性的最简单的向后兼容方式是添加储备证明。这包括资产证明和负债证明的组合。为两者制定良好的协议存在技术挑战,但我们可以而且应该尽可能地在两者上取得进展,并尽可能开源软件和流程,以便所有交易所都能受益。
从长远来看,我希望我们越来越接近于所有交易所都是非托管的,至少在加密方面是这样。将存在钱包恢复,并且可能需要为处理小额交易的新用户以及出于法律原因需要此类安排的机构提供高度集中的恢复选项,但这可以在钱包层而不是在交易所本身内完成。在法定货币方面,传统银行系统和加密生态系统之间的移动可以通过 USDC 等资产支持的稳定币原生的进/出流程来完成。但是,这还有很长的一段路要走。