FabZK-Supporting-privacy-preserving,-auditable-smart-contracts-in-Hyperledger-Fabric
slug
series-status
status
summary
date
series
type
password
icon
tags
category
FabZK: Supporting privacy-preserving, auditable smart contracts in Hyperledger Fabric
文章背景
- 一般来说,许可链上都是通过强制进行访问控制来实现对数据的隐私保护,只有被允许加入通道的节点才能访问资源(包括:链码、交易、分类账本状态等)。
- 但是此类的私有通道默认是不支持进行隐私保护的基础上的审计的。
<aside>
🔗 文中提到了一个概念:可审计的隐私保护交易,也成为零知识资产转移,是针对这种场景进行设计的审计模型。支持成员交互资产并在共享的分类账本中记录交易但是不需要透露他们正在交易、与谁交易或者交易金额的事实。
这一理念在参考文献[18]中提出。
</aside>
前人研究
- 之前存在的几种支持审计的解决方案包括Solidus(文献19)和zkLedger(文献20)都是基于类似的思想实现的。
- Solidus 仅适用于银行中介系统,其中少量银行维护大量用户帐户。它暴露了用户与其附属银行之间的交易图,以及银行之间的交易图。此外,Solidus 需要通过向审计员透露系统中使用的所有密钥来实现公共审计,因此它不能完全保护用户隐私。
- 而 zkLedger 支持私有审计,但效率低下:它要求审计者和所有参与者依次主动验证和提交每笔交易,这显着降低了事务的整体吞吐量。
本文贡献
概述
- 提出了FabZK,是一个针对Hyperledger Fabric的扩展,可以保护数据完整性、隐私和机密性
- 通过设计一组关于 Pedersen 承诺的非交互式零知识 (NIZK) 证明,实现了高效、可私人审计和保护隐私的点对点交易。
- 引入了一种两步验证方法来支持并发事务。
- 在 FabZK 中,当交易附加到公共分类账时,每个参与者都会进行主动和轻量级的自动验证。
- 审计员定期监控分类账活动并仅根据加密数据和证明验证交易。
具体贡献
- 通过 Pedersen 承诺和改进的 NIZK 证明开发了一个理论模型。增强的 NIZK 证明提供强大的交易隐私、公共可验证性和可证明的审计。
- 在 Fabric 之上设计了一个应用程序开发框架,包括 API,这允许应用程序开发人员轻松创建可审计和保护隐私的区块链应用程序。
- 将提出的模型实施到现实世界的解决方案中,即 FabZK,并引入各种优化以实现合理的性能。
- 将 FabZK 与最先进的方法进行比较,例如 zk-SNARKs、本机 Fabric 和 zkLedger,根据结果评估表明,FabZK 提供了卓越的性能权衡。FabZK 在生成和验证证明方面比 zk-SNARK 更有效。与原生 Fabric 系统相比,它能够以 3% 到 32% 的吞吐量损失和不到 10% 的延迟增加为代价实现可审计的隐私保护交易。与 zkLedger 相比,FabZK 的吞吐量高达 180 倍。
本文的目标
- 在私人渠道上,所有成员都可以看到交易详情,无论他们是否参与了交易。本文的目标是制定计划,以防止非参与组织(以下称为非交易组织)从分类帐中访问交易细节,例如交易金额和交易组织(即发送方和接收方)。同时,还需要这些方案是可审计的。
涉及的技术
- 采用并扩展了 FabZK 中的三种现有技术:
- 表格结构化分类帐 [20]
- Pedersen 承诺 [21]
- NIZK 证明 [30]
本文的结论
- 数据隐私和机密性对于区块链系统中的点对点交易至关重要。虽然 Hyperledger Fabric 禁止身份不明的对等方访问通道资源,但交易数据会暴露给所有通道参与者。
- 为了克服这一限制,提出了 FabZK,它是 Fabric 的一个扩展,它通过结构良好且可验证的加密原语(包括 Pedersen 承诺和非交互式零知识证明)支持可审计的隐私保护智能合约。
- FabZK 为客户端代码和链代码提供了一组 API,以实现按需自动验证。目前已经在 Fabric v1.3.0 上实现了 FabZK,并针对其他最先进的方法(即 zk-SNARKs、zkLedger)评估了它的性能。
- 根据微基准测试结果表明,FabZK 使用的加密原语在生成和验证非交互式零知识证明方面优于 zk-SNARKs。
- 作者还演示了使用 FabZK API 的示例应用程序。
- 对其性能的评估表明,与原生 Fabric 系统相比,FabZK 能够以 3% 至 32% 的吞吐量下降和不到 10% 的延迟增加为代价实现可审计的隐私保护交易。
- FabZK 的吞吐量比 zkLedger 高 180 倍。
背景技术
表格结构化账本
- 表格结构化账本是 zkLedger 中提出的一种匿名方案,用于隐藏交易图并防止组织将资产隐藏在账本上。它维护一个二维表,其中每一行代表一个事务,每一列代表一个组织的事务历史。例如,一个 N 组织通道的表格结构分类帐有 N 列,如果该通道上总共发生了 M 笔交易,则有 M 行。
Pedersen承诺的应用
- 为了隐藏交易金额 u,使用随机数 r 为 u 计算 Pedersen 承诺
$$
om = com(u,r) = g^uh^r \tag{1}
$$
- 其中 g 和 h 是循环群 G 的两个随机生成器,s = |G|,以及素数阶 p
- 局外人无法从 Pedersen 承诺中判断交易金额,或者是正数、负数还是 0。
- 此外,只要对交易组织和非交易组织都计算了 Pedersen 承诺,就不可能识别交易的发送者和接收者,因此交易图也被隐藏了。
- 为了支持审计,审计令牌被分配给 Pedersen 承诺 com(u, r)
$$
Token = pk^r \tag{2}
$$
- 其中 pk 是组织的公钥
$$
pk = h^{sk}
$$
- sk 是组织的私钥,r 和 h 与等式中的相同
- 由于交易被加密为 Pedersen 承诺,系统需要允许对加密数据进行验证和审计。这是通过一组 NIZK 证明来实现的。
系统结构
非交互式零知识证明 NIZK 的设计
- 在 FabZK 中,由支出组织(即发送者)负责创建承诺、代币和 NIZK 证明,以供其他组织或审计员进行验证。并且假设每笔交易在整篇论文中都有一个支出和一个接收组织。
Proof of Balance
- 一种用于验证单个交易行中的整体余额的方法,通过利用 Pedersen 承诺的同态性来验证连续的承诺。
Proof of Correctness
- 可防止组织进行不正确或欺诈性的交易以窃取他人的资产。
- 为了验证转账金额的正确性 $tx_m$(m 是当前交易的索引),每个组织使用审计令牌检查是否满足以下算式
$$
Token_m \cdot g^{sk \cdot u_m} = (Com_m)^{sk} \tag{3}
$$
- 其中 sk 是组织的私钥, $u_m$ 是其交易金额。对于非交易组织,他们知道 $tx_m$ 的存在,但不参与 $tx_m$,因此他们的交易量为 0。如果任何组织未能验证公式(3),则表明 $tx_m$ 不正确
- 等式(3)表明,仅使用当前交易 $tx_m$ 中的数据即可验证正确性证明;PoB 也是如此。这是后文的两步验证中利用的一个重要特征。
Proof of Assets
- 用于确保支出组织有足够的资产来执行交易。在表格结构化分类账中,一列代表组织已收到或花费的所有资产。资产证明验证一列中所有承诺值的总和,包括当前交易的总和,是非负的。
- 本文使用的方法为:让证明者为支出组织的余额生成一个如下的范围证明
$$
RP=ZK(u_{RP},r_{RP}: Com_{RP} \land l_0\leq u \leq l_p) \tag{4}
$$
- 其中 $ZK(u_{RP},r_{RP}:Com_{RP})$ 是一个针对 $u_{RP}$ 的零知识证明,使得验证者可以获得 $Com_{RP} = g^{u_{RP}h^{r_{RP}}}$,$g$ 和 $h$ 。而 $u_{RP}=\Sigma^m_{i=0}u_i$ 和 $u_i$ 是不同于等式(1)中的 $$$r$ 的一个随机数。$l_0$ 和 $l_p$ 是两个边界值。
- 本文使用的是 BulletProods 的内积范围证明来以加密的形式证明账户的剩余资产 $\Sigma^m_{i=0}u_i \geq0$
Proof of Amount
- 保证交易金额在一定范围内。在单一支出和单一收款机构的场景下,证明者对收款机构的交易金额生成内积范围证明 $u_{recv} \in [0,2^t)$ 以及一个随机数 $r_{recv}$。
- 在每笔交易中,证明者还需要为所有非交易组织生成不可区分的密码原语,以隐藏交易图。这些原语是带有随机数 $r_i$ 的 Pedersen 承诺、审计令牌、带有另一个随机数 $r_{{RP}_i}$ 的 0 范围证明和分离证明。
<aside>
💯 除了上述的四个非交互式零知识证明以外,每个组织还需要进一步去检查这些证明相互之间的一致性,即同一个组织在不同的证明中使用的参数是一致的。
</aside>
Proof of Consistency
- 用于确保
- 对于一个支出组织,生成的范围证明与其剩余资产 $\Sigma_{i=0}^mu_i$ 一致,而不是一些任意的 $u_{arb}\in[0,2^t)$
- 对于其他组织,生成的范围证明与他们当前的交易金额一致。
- 同时还需要确保验证者可以在不知道支出组织身份的情况下验证一致性证明。
- 而为了提供这样的一致性证明,文中使用了 Chaum-Pedersen 零知识证明的非交互式变体来构建交易 $tx_m$ 的析取零知识证明(DZKP)
- DZKP会将支出组织的私钥 sk或者随机数 $r$ 和 $r_{RP}$ (对其他组织而言的)作为输入,并生成两个非交互式的 $\Sigma$ - 协议。
- 同时,生成两个与DZKP配对的令牌 Token’ 和 Token’’
$$
Token' = \begin{cases}
pk^{r_{RP}}, & \text{for the spending org.}\\
t\cdot(Com_{RP}/s)^{sk}, &\text{otherwise.}
\end{cases} \tag{5}
$$
$$
Token'' = \begin{cases}
Token\cdot(Com_{RP}/s)^{sk}, & \text{for the spending org.}\\
pk^{r_{RP}}, &\text{otherwise.}
\end{cases} \tag{6}
$$
- 其中,$r_{RP}$ 是等式(4)中使用的随机数,$s=\prod_{i=0}^mCom_i=g^{\sum_{i=0}^mu_i}h^{\sum r_i}$是组织从第0行到第m行的承诺的乘积,并且 $t=\prod _{i=0}^mToken_i = h^{sk \sum _{i=0}^mr_i}$是组织的审计令牌从第0行到第m行的乘积。
公有账本和私有账本
公有账本
- 公共分类帐通过计算第一行中所有组织的 Pedersen 承诺和审计令牌的初始值来引导,交易标识符为 $tid_0$,由 $\langle Com, Token\rangle$ 元组表示。我们要求每个组织的客户自己验证正确性证明。系统假设所有组织的初始资产在引导时都已经过验证。
- FabZK 遵循类似Fabric链码的设计原则:加密原语由扩展的 Fabric 系统计算,而不是由上层应用程序在外部计算。这保证了没有恶意用户可以操纵 FabZK 生成的输出,因此验证是可信的。
- FabZK 在交易和非交易组织的公共分类账中写入 $\langle Com, Token, RP,DZKP, Token', Token''\rangle$ 六重奏。尽管额外的填充会在存储大小上产生一些开销,但这种设计允许 FabZK 隐藏交易图并实现私有和公共分类帐之间的一对一映射。此外,一对一的映射使组织或审计员更容易跟踪和验证交易。
FabZK 系统设计
概述
- 增强了当前的 Fabric 系统,允许通道参与者彼此进行隐私保护交易
- 允许非交易组织和受信任的第三方审计员审计结果
- FabZK 程序分四个阶段运行:$perparation,\ execution,\ notification,\ two-step\ validation$
- 准备和通知阶段在客户端节点上运行
- 执行和验证阶段在背书人的链码中运行
- 在四个阶段中,执行和两步验证专门用于支持隐私和审计

图3. 系统架构和程序执行流程
灰色框代表 FabZK 的四个主要阶段:准备、执行、通知和两步验证。虚线框代表孤立的组织。
- 整体的交易执行流程如上图所示
程序执行流程
Preparation
- 在执行开始时,FabZK 要求支出和接收组织首先确定区块链网络之外的转账金额(u)。然后,支出组织的客户代码构造交易,该交易由对应于公共分类账的 N 列的 N 个元组组成。每个元组包含交易金额(交易组织为 ±u,非交易组织为 0)、一个随机数和组织的公钥。
Execution
- 收到交易规范后,执行使用 FabZK 的 API 编写的传输链代码,将明文规范转换为$N\ \langle Com, Token\rangle\$ 元组。元组代表各个组织的转账金额,并在公共账本上形成新的一行。执行结果作为背书返回给客户端代码。客户端代码组装背书,并将其广播到排序服务。如图 3 所示,传输链码仅由支出组织执行。
Notification
- 一旦执行,通道上的所有组织都会通过标准的 Fabric 通知机制通知交易输出(即 $N\ \langle Com, Token\rangle\$ 元组)
- 具体来说,排序者对来自不同组织的交易进行排序,将它们分批成块,然后将块交付给提交者。提交者验证每个交易中的背书者签名,检查读写集冲突,并将交易附加到公共分类帐中。
- 同时,会向每个组织的客户端代码发送通知。使用 FabZK API,每个客户端代码都从其私有分类帐中检索信息,并调用两步验证过程来验证公共分类帐上的更改。
Two-step Validation
- 如果支出组织构建了交易的 N 个元组,则所有其他组织都需要使用前文描述的五个 NIZK 证明来验证这些元组是否包含有效交易。为了提高性能,将验证过程设计为两个步骤以实现并行执行
- 第一步确保在交易过程中没有资产被创建或销毁,以及没有组织窃取他人的资产。每个组织检查公共分类账上的一行是否满足 PoB 证明,以及该行中其对应的单元格是否满足 PoC 证明。
- 第二步确保支出组织拥有足够的资产来执行交易,并且交易金额在预定义的上下限内。此步骤通常由受信任的第三方审核员激活。为了开始这一步,审计员要求支出组织生成范围证明和析取证明。
- 对于第 m 行,支出组织的客户代码构建了一个审计规范,其中包括其剩余余额(即 $\sum_{i=0}^mu_i$ )、其余组织的一组交易金额、三组随机数(即, 等式(4)中的 $r_{RP}$ 和等式(7)中的 $w_1$, $w_2$),承诺产品集(组织从第 0 行到第 m 行的承诺的乘积),代币产品集(组织从第 0 行到第 m 行的审计代币的乘积)第 0 行到第 m 行)、所有组织的公钥和支出组织的私钥。
支出组织将其私钥提供给链码是安全的,因为链码在组织自己的背书人上运行。审计规范被发送给组织的背书者以调用审计链码执行。然后,链码将明文审计数据转换为每个组织的 $\langle RP,DZKP,Token',Token''\rangle$ 。审计师检查所有组织的资产证明、金额证明和一致性证明。只有当所有检查都是肯定的时,交易才被认为是有效的。最后,验证结果会在公共分类账上更新,这会向所有组织发出另一个通知,然后他们将更新他们的私人分类账。
链码接口
- FabZK 提供了两组编程接口来实现应用程序与 Fabric 系统的交互。
- 客户端代码 API 支持 $Preparation$ 和 $Notification$ 阶段的交互。
- 链码 API 支持 $Execution$ 期间的交互和 $Two-step\ Validation$。
- 客户端代码 API 支持读取和写入组织的私有分类帐。通过这些 API,应用程序可以构建和维护私有账本,以及通过 Fabric SDK 向区块链网络提交交易。
- PvlGet API 用于按事务标识符检索行。
- 当新交易到达或提交的交易被验证时,调用 PvlPut API 来更新私有账本。
- 客户端代码使用 Validate API 调用验证链代码来验证新交易。
- 为了生成有效且可公开验证的 PoB 证明,交易规范中的随机数必须满足 $\sum_{i=0}^Nr_i=0$。
- 这些随机数可以在链码中生成,也可以由客户端代码作为参数提供。
- 在 Fabric 中,每个组织都可以拥有多个对等节点以实现容错。可以将交易请求发送到发起组织的多个对等方以获得背书。为确保独立对等点对同一事务使用一致的随机数,本文向客户端代码提供了 GetR API,以便将相同的随机数分发给所有背书对等点。
- 链码 API 用于从/向公共分类账读取/写入数据。ZkPutState API 在执行阶段被调用,此时支出组织初始化转账。它将事务规范转换为承诺和审计令牌,将它们序列化为字节流,并调用本机 Fabric API PutState 以生成写入集,该写入集存储在背书节点上的临时数据存储中并返回给支出组织。
- ZkVerify 和 ZkAudit API 在 $two-step\ Validation$ 阶段协同调用,以验证公共账本中的交易。
- 在第一步中,各个组织调用 ZkVerify 来检查给定交易行的 PoB 证明和 Poc 证明。
- 在第二步中,所有组织在链码中调用 ZkAudit 来创建范围证明、析取证明,以及等式(5)和(6)中的两个代币,即每笔交易的 $\langle RP,DZKP,Token',Token''\rangle$ 四元组
- 最后再次调用 ZkVerify 来检查资产证明、数量证明和一致性证明。
- 如果 ZkVerify 成功验证了所有五个证明,则交易被认为是有效的。
系统实施
公共账本的数据结构

图 4:FabZK 的公共账本中一行的数据结构,采用 protobuf 语言
- zkrow 将所有组织的数据构造为多个列,并保存该行的验证状态。每列是一个键/值对,其中键是组织的名称(或 ID),值被键入为 OrgColumn,存储三种类型的交易数据。
- 账本数据结构的内容由链码 API 填充。$\langle Com,Token\rangle$ 元组和 $\langle RP,DZKP,Token',Token''\rangle$ 四元组分别由 ZkPutState 和 ZkAudit API 创建。
- 两个验证状态,即 OrgColumn.isValidBalCor 和 OrgColumn.isValidAsset 由 ZkVerify API 在两步验证期间设置。
- 设置好所有 OrgColumns 的验证状态后,将这些状态的逻辑与运算结果分别赋值给 zkrow.isValidBalCor 和 zkrow.isValidAsset。
并行计算
- 专注于在 $Execution$ 和 $two-step\ Validation$ 阶段并行计算,因为这两个阶段占了大部分计算开销。
Execution
- 在这个阶段,由于 $\langle Com,Token\rangle$ 元组的计算式相互独立的,并且这些计算也不需要访问历史数据,因此在本文中作者选择让支出组织创建多个线程来同时为所有的组织计算 $\langle Com,Token\rangle$ 元组。
two-step Validation
- 在这个阶段,PoB 证明和 PoC 证明的计算式不依赖于历史数据或者跨组织的,而其他的三个证明必须按顺序计算。
- 首先,在计算第 m 行的范围证明需要从第 0 行到第 m 行的数据,例如 $u_{RP_{m}}=\sum_{i=0}^mu_i$。因此,在这一步得到所有的结果之前不能调用 ZkAudit。
- 其次,范围证明和析取证明只能由支出组织计算,因为其他组织不知道发送者的可用资产或交易细节。
- 这两个约束,连同支出组织因交易而异的事实,决定了范围证明和析取证明的计算必须按顺序执行。
<aside>
🔬 在作者的实现中,验证的第一步是完全并行的,即 PoB 证明和 PoC 证明的计算分布到所有对等节点。
验证的第二步是部分并行化的:支出组织可以启动多个线程来验证所有组织的范围证明和析取证明,但这两个证明是按顺序计算的。
</aside>
编写FabZK应用
- FabZK 应用程序由应用程序链代码和客户端代码组成:前者安装在背书节点上,后者安装在链下节点上。
- 当应用程序链码在通道上实例化时,其 init 函数会为每个组织初始化公共分类帐的表格结构。
- 组织名称(或 ID)、公钥和初始资产数量等值可以从通道的创世块中加载。
- init 函数调用 ZKPutState API 在公共账本上创建第一行。
- 应用程序链码需要支持三种链码方法:transfer、audit和validation。它们都接受来自客户端代码的输入参数。
- transfer 方法调用 ZkPutState API 在公共账本上创建一行包含$\langle Com,Token\rangle$元组的列。
- validation和audit方法通过其底层 FabZK API 调用两步验证。
- validation方法运行两次调用 ZkVerify API,分别验证两组 NIZK 证明。
- audit方法调用 ZkAudit API 来计算 $\langle RP,DZKP,Token',Token''\rangle$ 四元组。
<aside>
🔬 请注意,可以定期(例如,每周一次)调用审计链代码方法以提供自动审计。
</aside>
- 开发人员编写客户端代码来访问私有分类帐。为传输链码方法准备输入交易规范,客户端代码通过 PvlGet API 检索私有账本上的当前资产,并调用 GetR API 获取一组随机数。在收到新的交易 tid 通知后,客户端代码从其私有分类帐中检索信息以检查其组织是否参与。
- 如果涉及,它会通过 PvlPut API 在私有分类帐中附加一个新的交易行,其中包含 tid 和转账金额。
- 客户端代码还可以调用验证链码方法,并将转账金额、组织的密钥和剩余资产作为输入。
- 根据返回的结果,客户端代码更新其私有分类账的该行的有效字段。
<aside>
💯 根据本文的一个小示例所述,虽然审计可以识别无效交易,但此过程通常滞后于交易。因此,在被拒绝之前,无效交易仍然可能发生。在实践中,参与组织的联合体应该就某些业务规则达成一致,对违反范围证明和析取证明的行为进行处罚。但是,此逻辑超出了本文的范围,因此未在示例应用程序中实现。
</aside>
性能评估
目标
- FabZK 加密算法的效率,与其他替代方案相比
- 在使用 FabZK 提供的隐私和审计功能时引入应用程序的开销
测试环境
Hyperledger Fabric 版本 | 链码编写语言 | 客户端 API 编写语言 | 计算承诺所的依赖 |
1.3.0 | Go | NodeJS | btcec库下的椭圆曲线secp256k1 |
基于的协议 | 析取协议 |
BulletProofs 协议 | 修改后的 Chaum-Pedersen 证明和两个非交互式的 Σ 协议 |
<aside>
💯 由于上述协议的隐私性已经被验证过了,本文仅针对性能做了评估。
</aside>
服务器供应商 | 服务器版本 | 系统硬件 |
IBM Cloud | Ubuntu 16.04VM | 8个2.1GHz内核 |
算法性能
- 测试数据:系统为每个组织处理 128 字节的数据(包括转账金额、私钥、资产等)
- 如表二所示,FabZK 在数据加密和证明验证方面都优于 libsnark。随着组织数量的增加,其证明生成的开销越来越大。 libsnark 的证明生成时间几乎是恒定的(~196 毫秒),因为它只需要为每笔交易生成一组 NIZK 证明。相比之下,在 FabZK 的公共分类账中,每一行都包含所有组织的加密数据。因此,随着组织数量的增加,FabZK 需要更长的时间来生成证明。
- 从表二也可以看出证明生成的多线程实现是有效的。延迟增加是适度的,直到系统支持超过 8 个组织,因为实验中使用的节点只有 8 个核心。在未来的工作中,将通过探索跨节点作业调度方案来进一步提升 FabZK 的性能。

表二:libsnark 和 FabZK 为不同数量的组织运行加密算法的时间(以毫秒为单位)
应用性能
- 主要评估 FabZK 的隐私和审计功能引入的开销
Testbed
- 将示例应用程序部署在 Hyperledger Fabric 网络中,每个组织都拥有一个作为其背书者和提交者的对等节点,以及一个证书颁发机构 (CA) 节点。
- 设置了一个基于 Kafka 的排序服务,其中包含 3 个 ZooKeeper 节点、4 个 Kafka 代理和一个 Fabric 排序器。
- orderer 节点使用默认配置创建块:2 秒批量超时和每个块≤10 个事务。
- 将 5 个八核 VM 分组到一个 docker swarm 集群中,然后将所有 Fabric 组件配置为集群中的容器。
- 所有组织的 Peer 节点和 CA 节点均匀分布在 4 个 VM 上,排序服务节点在另一个 VM 上。
吞吐量评估
- 本文比较了在三个系统上运行的示例应用程序的吞吐量:FabZK、zkLedger,2 和本机 Fabric(即基线)。
- 在本实验中,所有组织同时产生交易,每个组织依次提交 500 笔交易。当账本累积 500 笔新交易时,会触发一轮审计。结果如图 5 所示。
- 可以观察到 FabZK 的吞吐量与基线类似。在不开启审计的情况下,与基线相比,FabZK 仅引入了 3% 到 10% 的吞吐量下降。每 500 笔交易开启审计,与基线相比,FabZK 的吞吐量开销变为 3% 到 32%。显然,计算和验证范围和析取证明的额外开销是相当大的。然而,在实践中,这可以通过更换审计频率来缓解,尤其是运营的高峰时期。
- 相比 zkLedger,FabZK 的效率是显而易见的。其带有(不带)审计的吞吐量是 zkLedger 的 5 (5) 到 189 (235) 倍。这是意料之中的,因为 zkLedger 中的交易是按顺序验证和提交的,而 FabZK 受益于前面描述的并行执行。

图 5:使用原生 Fabric API(基线)、zkLedger 和 FabZK 的 API 的原型资产交换交易的吞吐量,有和没有审计(越高越好)
延迟评估
- 图 6 说明了资产交换交易期间每个步骤的时间安排,没有触发审计。从应用程序的角度来看,运行传输链码方法和验证方法分别需要大约 45.3 毫秒和 32.4 毫秒。 ZkPutState 的运行时间(2.8ms)包括计算 hCom、Tokeni 元组的 0.8ms 以及将元组序列化为字节流并将其写入对等点的瞬态数据存储的 2ms。
- ZkVerify 的运行时间(1.9 毫秒)包括 0.5 毫秒验证 PoB 证明和 PoC 证明,以及 1.4 毫秒将它们序列化并写入对等方的数据存储。
- 此外,orderer 节点经常等待在单个块中批处理多个事务。与 Fabric 中端到端的事务延迟相比,FabZK API 的绝对开销相对较小:ZkPutState 和 ZkVerify 对整体延迟的影响不到 10%,而超过 90% 的延迟是由节点到节点通信引起的、序列化/反序列化、块验证、分类帐的 I/O 等。
- 接下来,将评估审计延迟,即计算和验证公共分类账上转移行的范围证明和分离证明。特别是,作者研究了对等节点中 CPU 内核数量对 FabZK 链码 API:ZkAudit 和 ZkVerify 性能的影响。
- 图 7 描绘了一个 4 组织网络的 ZkAudit 和 ZkVerify 的延迟,因为 CPU 内核的数量从 2 个增加到 8 个。对于 ZkAudit,与使用 2 个内核相比,使用具有 4 个和 8 个 CPU 内核的对等节点分别将其性能提高了 50% 和 90%。
- 这种性能提升得益于范围证明和析取证明的并行计算。
- 然而,改进从 4 核减少到 8 核,因为链码只需要为 4 个组织生成 4 个线程。还可以观察到并行处理对 ZkVerify 的性能影响最小,因为该验证的计算强度较低。

图 7:在具有不同 CPU 内核数量的 VM 上运行 ZkAudit 和 ZkVerify 的延迟
相关工作
加密交易
- 支持机密交易的机制之前已经被广泛研究过。为了隐藏余额和交易价值,可公开验证的加密承诺方案已被用于允许匿名转移资产。
- 为了防止双重支出,还使用范围证明来展示资产证明。例如,Borromean 环签名 [39] 在参考文献 [14]、[15]、[19]、[20]、[40] 中广泛用于范围证明。但是,这种范围证明的开销很大:具有两个输出和 32 位精度的交易需要 5 KiB 的范围证明 [31]。为了减少范围证明的大小,使用零知识简洁非交互式知识证明(zk-SNARKs)[12]、[41]、[42]、[43]、[44]、[45]、 [46]、[47]、[48]。尽管这些方法可以提供短距离证明,但它们需要昂贵的可信setup。最近,在 Bulletproofs [31] 中提出了一种内积范围证明,它具有较短的证明大小,以及线性证明和验证时间。
- 本文的FabZK 使用 Pedersen 承诺 [14] 和内积范围证明 [31] 来实现高效的机密交易。
匿名交易
- 以前的工作通过匿名化交易参与者以使用身份混合、不经意的 RAM 或表格结构的分类账来隐藏交易图。
- 在当前加密货币和区块链系统中使用身份混合方法的示例是参考文献 [49]、[50]、[51]、[52]、[53]、[54]、[55]、[56]。
- 尽管 Mixes 可以保护参与用户,但它仅提供了部分匿名性。
- 混合类型的方法容易受到攻击工具的攻击,例如 Coinjoin Sudoku [57],这些工具可以通过关联交易输出和输入来识别交易中的用户 [58]。
- 其他研究解决问题的方案:
- Solidus [19] 通过可公开验证的遗忘 RAM 机 (PVORM) 模糊了交易图。
- PVORM 为用户提供从逻辑内存地址到远程物理地址的映射。它通过隐藏内存访问模式来提供事务图和事务细节的机密性。然而,Solidus 仅适用于银行中介网络,这意味着它只能隐藏银行用户的信息,但仍会暴露银行(或组织)之间的交易图。
- 与本文工作最相关的是,zkLedger [20] 使用表格结构的分类帐来隐藏交易图。
- 在每笔交易中,zkLedger 都会计算所有组织的承诺。
- 通过在每笔交易中添加额外的不可区分的承诺,zkLedger 隐藏了发送者和接收者的身份,从而隐藏了交易图。
- 然而,zkLedger 要求审计人员和每个参与者在每笔交易被账本接受之前都必须主动验证,这不可避免地增加了延迟并降低了吞吐量。
- 在 FabZK 设计中,采用了 zkLedger 的表格结构化账本,但开发了额外的证明和验证机制来提高审计性能。
一些不确定的疑惑
Loading...