本文介绍了PoRv2,一个基于零知识证明(ZKP)的快速、透明的储备证明系统,它结合了zk-proofs和Merkle树,允许用户在不需要外部审计的情况下验证交易所的负债。该系统使用plonky2 ZK算法,提高了效率和透明度,并提供了一个验证服务器以方便用户验证,旨在提高加密货币交易所的透明度和用户信任。
在此,我们将探讨 zk-proofs、Merkle 树以及我们的新开源实现 PoRv2。我们的储备证明使用户无需依赖外部审计师即可验证交易所的负债,从而为信任树立了新标准。
储备证明 (PoR) 的核心是一个至关重要的系统,旨在表明加密货币平台确实持有其欠用户的资金。 交易所和托管人可以通过它使用强大的密码学方法来证明他们有足够的资产来支付所有客户的存款。
这样理解:PoR 是关于实现透明度的。它是一种让平台提供清晰、可验证的财务健康状况证明的方式。 对于用户而言,这意味着更有信心他们的资金在他们使用的平台上是安全的。
从历史上看,传统的储备证明方式通常存在缺陷。 它们可能会泄露太多关于平台的敏感信息,并且在没有直接用户验证方法的情况下,过度依赖外部审计师。
我们 OtterSec 与 Backpack 合作,刚刚开发了一个储备证明系统,可用于证明 CEX 的偿付能力。 我们的 零知识储备证明 (PoRv2) 基于 OKX 储备证明算法,因为它是迄今为止已知最快、最高效的算法。 我们还使用 recursive plonky2 作为零知识证明的算法,但我们对电路进行了一些改进,以提高用户端的透明度和可验证信息,从而消除了对审计公司的信任需求。
此外,我们还创建并开源了一个 PoR 验证器服务器,该服务器接收并验证证明。
证明储备金至关重要,但对于任何持有用户资金的平台来说,这都提出了一个独特的挑战:如何在公开证明偿付能力的同时,又不暴露敏感的用户余额信息或泄露专有的财务细节? 这就是 零知识证明 (ZKP) 成为游戏规则改变者的地方。
简而言之,零知识证明允许一方在不泄露除声明本身有效性之外的任何信息的情况下,向另一方证明某个声明为真。 想象一下,在不实际告诉任何人密码的情况下,证明你知道一个秘密密码。 你确认你拥有该知识,但秘密仍然属于你。
在储备证明的背景下,ZKP 非常适合解决隐私悖论。 它们使平台能够通过密码学方式证明两件重要的事情:
btc_liability = user1_btc + user2_btc + user3_btc + ...
)。值得注意的是,我们无法保证所有用户都包含在 ZK 分析中。 因此,如果我们仅使用 ZKP 来证明这两个声明,交易所可能会通过将用户排除在 PoR 之外来篡改总和证明。 这就是为什么我们还使用 Merkle 树来证明包含的原因。
Merkle 树是一种树数据结构,其中每个叶节点都是单个数据(如用户的余额)的密码哈希,而每个非叶节点都是其子节点的密码哈希。 这种结构允许整个数据集由顶部的单个唯一哈希(称为 Merkle 根)进行概括。
在 PoR 中,我们可以使用 Merkle 树来验证每个用户是否包含在储备证明中。 它的工作原理如下:
sha256({id: 1, balances: {"BTC": 0.1, "ETH": 0.2, ...}})
);换句话说,这样使用 Merkle 树可以让用户轻松验证他们的个人余额是否包含在总体总额中。
我们刚刚开源了我们的储备证明代码 (PoRv2),它使用 plonky2 ZK 算法 来创建一个 Merkle 树和一个最终的 ZK 证明,该证明以递归方式验证较小的总和与非负性证明。
我们将其命名为 PoRv2,因为我们已经有一个基于 Vitalik 的偿付能力证明 的版本,该版本并非最佳版本。
非负性证明
在我们的非负性证明中,电路接收每个用户的资产余额和每种资产的价格。 通过这些输入,它会计算帐户的美元余额并检查其是否大于 0。
我们还检查求和期间的溢出,以防止篡改最终结果。
总和证明
总和证明验证了一个公共电路输入,该输入是通过对每种资产的所有用户余额求和来计算的。 (例如,BTC final: user1_btc + user2_btc ...
)。 请注意,每种资产的最终总和不是基于美元的; 我们使用资产余额本身来计算最终余额。
我们使用两种不同的 ZK 电路来生成最终证明:
通过这两个电路,我们可以生成证明递归树:
注意:我们使用 512 作为
BATCH_SIZE
,8 作为RECURSIVE_SIZE
,这表明每个电路有多少个子电路。 这可以在代码中轻松调整,最佳配置将取决于 PoR 中要证明的帐户数量。注意 2:我们将空证明作为填充添加到没有正确长度的块中。
此树中的每个非叶节点都是 ZK 证明,它是使用相关电路生成的; 每个电路还生成每个节点的 Merkle 树哈希,该哈希包含在 Merkle 树中。
叶节点是帐户信息的哈希。 它的计算方式如下:
h=Poseidon(asset_balances0 ∣∣ asset_balances1 ... ∣∣ SHA256(user_id) ∣∣ user_nonce)
换句话说,所有余额都与哈希的用户 ID(可以是 uuid
、用户名或增量 ID)和一个 nonce 连接在一起。 nonce 是一个随机数,用作针对攻击者的安全措施,他们可能会暴力破解哈希以找出其他用户的余额。 由于 Merkle 树是一个公共证明,因此我们需要小心防范此类数据泄露。
批量电路是 PoR 算法中第一个经过验证的电路。 它接收帐户信息(分组为 512),并使用以下约束生成 ZK 证明:
公共输入
私有输入
约束
account_equityi==Σ account_asset_balancesi[asset_num]∗asset_prices[asset_num]
account_equityi>=0
(非负性)total_asset_balance[asset_num]==Σ account_asset_balancesi[asset_num]
(总和证明)merkle_tree_hash==Poseidon(hash0,hash1, ...,hash511)
(merkle 树哈希)account_asset_balancesi[asset_num]<MAX_SAFE_INT/512
(溢出检查) --> 溢出检查是以这种方式进行的,以提高性能(请注意,512 实际上是 BATCH_SIZE
)这是批量电路输入的可视化方案 + 如何生成用户哈希:
递归电路将八个子证明作为输入,验证所有资产价格是否相同,并计算汇总余额和 Merkle 哈希。 以下是约束。
公共输入
私有输入
约束
total_asset_balance[asset_num]==Σ subproofi.public_input.asset_balances[asset_num]
(总和证明)asset_price[asset_num]==subproofi.public_input.asset_prices[0]
asset_price[asset_num]==subproofi.public_input.asset_prices[asset_num]
(验证所有资产价格是否相同)merkle_tree_hash==Poseidon(hash0,hash1,...,hash31)
(merkle 树哈希)这是递归电路输入的可视化方案。 请注意,此树只有三个级别(L1、L2、L3)。 根据用户数量,它可能具有更多递归级别:
在证明所有批量电路和所有递归电路之后,我们得到了最终证明(这是递归树根的 ZK 证明)、整个 Merkle 树和用户 nonce。 在我们的代码中,它被序列化为 merkle_tree.json
、final_proof.json
和 private_nonces.json
文件。
使用 ZK 证明和 Merkle 树,我们已经可以证明资产余额的总和及其非负性; 我们将其称为 “全局证明”。
对于用户包含证明,我们获取 Merkle 树、用户资产余额、标识哈希和 nonce,以将其捆绑到一个证明文件中 ( inclusion_proof_<id>.json
)。 我们将 Merkle 树的一部分捆绑到包含证明文件中,以使证明更小。
全局证明
为了验证全局证明,代码会反序列化 merkle_tree.json
和 final_proof.json
文件,并执行以下检查:
merkle_tree_hash
公共输入相同。 这确保了 merkle_tree.json
和 final_proof.json
已链接(它们属于同一全局证明)。包含证明
为了验证包含证明,代码会反序列化 inclusion_proof_<id>.json
文件以及 final_proof.json
。 之后,它执行以下检查:
为了自动化验证过程,我们创建了一个 验证器服务器,交易所可以将证明提交到该服务器。 提交后,将验证证明并将其添加到数据库。
添加证明后,任何用户都可以进入网站并查看其信息(请参阅 backpack 的示例):
以下分解了各个字段的含义以及为什么需要它们:
此外,你还可以在网站上查看交易所的负债:
这些是交易所应在其储备中拥有的资产数量,以便在每种资产上都具有偿付能力。 你可以通过检查他们在区块链上的储备钱包来匹配他们是否拥有。 你可以在 https://backpack.exchange/reserves 中查看 backpack 的钱包,并在 https://backpack-por.osec.io/ 中查看我们用于 backpack 的验证器服务器。
作为用户,你可以自行验证这两个证明,包含证明用于验证你是否包含在 PoR 总负债总和中,全局证明用于验证交易所提供的承诺是否有效。
如果你是用户并且想要进行包含的自我验证,则需要按照以下步骤操作:
inclusion_proof_<id>.json
和 final_proof.json
),并将文件放在与 PoRv2 应用程序相同的目录中。./plonky2_por verify-inclusion
。这将验证证明是否有效并显示你的资产余额。 你需要手动验证余额是否正确。 请记住,证明不是实时计算的; 你必须验证余额在证明生成日期是否正确。 这是经过验证的有效证明的示例:
[!] 用于生成证明的信息如下,请手动验证它们是否正确:
[!] 注意:这不是实时信息,请验证该信息相对于证明生成时间是否正确
[!] 注意 2:某些资产余额已四舍五入到某些小数位,请验证它们是否足够接近原始余额
======================
证明生成日期:2025-02-22 19:59:59 UTC
证明生成时间戳(毫秒):1740254399944
已计入资产数量:100
-----资产余额-----
ETH:0
BTC:1.2
USDC:0
...
======================
[!] 正在验证全局证明(信任文件内部的电路数据)...
[+] 全局证明有效!
[!] 正在验证包含证明...
[+] 包含证明根哈希有效! 用户包含在 merkle 树中!
[+] 成功验证文件包含证明:inclusion_proof_00476816e43cf2efffdabdda7f55c5203bc9e28382c551f83931de02fd364a25.json
[+] 所有包含证明均有效!
[+] 在 13.731875 毫秒内完成!
如果你要验证全局证明是否有效,只需按照以下步骤操作:
merkle_tree.json
和 final_proof.json
文件,并将它们放在与 PoRv2 应用程序相同的目录中。 你可以从我们的 PoR 验证器服务器下载这些文件(下载 zip 文件并解压缩)。./plonky2_por verify-global
。 这可能需要一段时间才能验证,因为它需要反序列化一个大文件并验证最终证明电路(这涉及重建它)。这将验证全局证明并打印资产价格以进行手动验证。 请注意,显示的资产价格不是实时的; 你必须将它们与证明生成日期和时间的价格进行匹配。
[!] 正在验证储备证明...
[!] 用于生成证明的信息如下,请手动验证它们是否正确:
[!] 注意:这不是实时信息,请验证该信息相对于证明生成时间是否正确
[!] 注意 2:资产价格已四舍五入到某些小数位,请验证它们是否足够接近原始价格
======================
证明生成日期:2025-02-22 19:59:59 UTC
证明生成时间戳(毫秒):1740254399944
已计入资产数量:100
-----资产价格-----
BTC:95000 美元
ETH:2402.48 美元
...
======================
验证完成后,并且所有证明都有效,系统将打印每种资产的汇总余额。 这些是交易所的负债,你可以使用它们来检查他们是否有储备金来支付。
[!] 正在重建根电路... 这可能需要几分钟...
[+] 根电路重建成功!
[!] 正在验证最终证明...
[+] 证明有效!
[!] 正在验证资产价格...
[+] 资产价格有效!
[!] 正在验证资产小数...
[+] 资产小数有效!
[!] 正在验证 merkle 树根哈希...
[+] Merkle 树根哈希有效!
[!] 正在验证 merkle 树...
[+] Merkle 树有效!
[!] 以下信息是最终所需的资产储备金,已通过零知识证明验证
[!] 注意:这不是实时信息,该信息与证明的生成时间相关
[!] 注意 2:我们无法保证所有用户都包含在证明中,但你可以通过验证包含证明来检查你是否包含在内
======================
证明生成日期:2025-02-22 19:59:59 UTC
证明生成时间戳(毫秒):1740254399944
已计入资产数量:100
-----资产储备金-----
BTC:1.2
ETH:5.4
...
======================
[+] 所有证明均有效!
[+] 在 4.455745214 秒内完成!
总之,储备证明是加密货币平台的重要机制,使它们能够以透明的方式展示偿付能力并获得用户信任。 通过采用零知识证明,平台可以在不暴露敏感用户数据的情况下实现这种透明度,从而有效地证明总负债并确保非负性,同时保护隐私。 我们的系统进一步改进了此过程,提高了效率并消除了手动验证的需要。
我们目前正在与 Backpack 合作,在生产环境中实施此算法,以每 24 小时生成和验证证明。 这标志着朝着建立实时储备证明系统迈出了重要一步,特别是考虑到它提供了更高的透明度,这是减少对外部审计公司需求的一个进步,因为用户将能够自行验证所有内容。
有关 Backpack Exchange 如何在实践中实施储备证明的更多信息,你可以阅读他们的详细文章:Backpack Exchange 的储备证明:真正的透明度,ZK 验证。
- 原文链接: osec.io/blog/2025-08-27-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!