私有数据

什么是私有数据?

如果一个通道上的一组组织需要对该通道上的其他组织保持数据私有,则可以选择创建一个新通道,其中只包含需要访问数据的组织。但是,在每种情况下创建单独的通道会产生额外的管理开销(维护链码版本、策略、MSP等),并且不能在保留一部分数据私有的同时,可以让所有通道参与者看到该事务。

这就是为什么从v1.2开始,Fabric 提供了创建私有数据集合的功能,它允许在通道上定义的组织子集能够背书、提交或查询私有数据,而无需创建单独的通道。

什么是私有数据集合?

集合是两个元素的组合:

  1. 实际的私有数据,通过 Gossip 协议点对点地发送给授权可以看到它的组织。私有数据保存在被授权的组织的节点上的私有数据库上,它们可以被授权节点的链码访问。排序节点不能影响这里也不能看到私有数据。注意,由于 gossip 以点对点的方式向授权组织分发私有数据,所以必须设置通道上的锚节点,也就是每个节点上的 CORE_PEER_GOSSIP_EXTERNALENDPOINT 配置,以此来引导跨组织的通信。

  2. 该数据的 hash 值,该 hash 值被背书、排序之后写入通道上每个节点的账本。Hash 值作为交易的证明用于状态验证,并可用于审计。

下面的图表分别说明了被授权和未被授权拥有私有数据的节点的账本内容。

private-data.private-data

如果集合成员陷入争端,或者他们想把资产转让给第三方,他们可能决定与其他参与方共享私有数据。然后,第三方可以计算私有数据的 hash,并查看它是否与通道账本上的状态匹配,从而证明在某个时间点,集合成员之间存在该状态。

有些情况,你可能选择每个组织会有一套集合。比如一个组织可能会将私有数据记录到他们自己的集合中,之后可以共享给其他的通道成员并且在链码中引用。我们会在下边的共享私有数据部分看到一些例子。

什么时候使用一个通道内的组织集合,什么时候使用单独的通道

解释集合的用例

设想一个通道上的五个组织,他们从事农产品贸易:

分销商可能希望与农民托运商进行私下交易,以对批发商零售商保密交易条款(以免暴露他们收取的加价)。

分销商还可能希望与批发商建立单独的私人数据关系,因为它收取的价格低于零售商

批发商可能还想与零售商托运商建立私有数据关系。

相比于为每一个特殊关系建立各种小的通道来说,更好的做法是,可以定义多个私有数据集合 (PDC),在以下情况下共享私有数据:

  1. PDC1: 分销商, 农民托运商

  2. PDC2:分销商批发商

  3. PDC3:批发商, 零售商托运商

private-data.private-data

使用此示例,属于分销商的节点将在其账本中包含多个私有的私有数据库,其中包括来自分销商农民托运商子集合关系和分销商批发商子集合关系的私有数据。

private-data.private-data

使用私有数据的交易流

当在链码中引用私有数据集合时,交易流程略有不同,以便在交易被提案、背书并提交到账本时保持私有数据的机密性。

关于不使用私有数据的交易流程的详细信息,请参阅我们的交易流程的文档。

  1. 客户端应用程序提交一个提案请求,让属于授权集合的背书节点执行链码函数(读取或写入私有数据)。 私有数据,或用于在链码中生成私有数据的数据,被发送到提案的 transient(瞬态)字段中。

  2. 背书节点模拟交易,并将私有数据存储在 瞬态数据存储( transient data store ,节点的本地临时存储)中。它们根据组织集合的策略将私有数据通过gossip分发给授权的 Peer 节点。

  3. 背书节点将提案响应发送回客户端。提案响应中包含经过背书的读写集,这其中包含了公共数据,还包含任何私有数据键和值的 hash。私有数据不会被发送回客户端。更多关于带有私有数据的背书的信息,请查看这里

  4. 客户端应用程序将交易(包含带有私有数据 hash 的提案响应)提交给排序服务。带有私有数据 hash 的交易同样被包含在区块中。带有私有数据 hash 的区块被分发给所有节点。这样,通道中的所有节点就可以在不知道真实私有数据的情况下,用同样的方式来验证带有私有数据 hash 值的交易。

  5. 在区块提交的时候,授权节点会根据集合策略来决定它们是否有权访问私有数据。如果节点有访问权,它们会先检查自己的本地 瞬态数据存储 ,以确定它们是否在链码背书的时候已经接收到了私有数据。如果没有的话,它们会尝试从其他已授权节点那里拉取私有数据,然后对照公共区块上的 hash 来验证私有数据并提交交易和区块。当验证或提交结束后,私有数据会被移动到这些节点私有数据库和私有读写存储的副本中。随后 瞬态数据存储 中存储的这些私有数据会被删除。

共享私有数据

在多数情况下,一个私有数据集合中的私有数据键或值可能需要与其他通道成员或者私有数据集合共享,例如,当你需要和一个通道成员或者一组通道成员交易私有数据,而初始私有数据集合中并没有这些成员时。私有数据的接收方一般都会在交易过程中对照链上的 hash 来验证私有数据。

私有数据集合的以下几个方面促成了私有数据的共享和验证:

当设计应用程序和相关私有数据集合时需要考虑这种共享和验证私有数据的能力。您当然可以创建出几组多边私有数据集合以供多个通道成员组合之间共享数据,但是这样做的话你就需要定义大量私有数据集合。或者你也可以考虑使用少量私有数据集合(例如,每个组织用一个集合,或者每对组织用一个集合),然后和其他通道成员共享私有数据,有需要时还可以和其他集合共享私有数据。从 Fabric v2.0 开始,隐含的组织特定集合可供所有链码使用,这样一来部署链码的时候你就不用定义每个组织中的私有数据集合。

私有数据共享模式

为各组织的私有数据集合构建模型时,有多种模式可被用来共享或传输私有数据,且无需费力定义多个多边集合。以下是链码应用程序中可以使用的一些共享模式:

结合以上几种模式,我们可以发现,私有数据的交易和普通的通道状态数据交易情况类似,特别是以下几点:

样例场景:使用私有数据集合的资产交易

将上述私有数据共享模式结合起来能够赋能基于链码的应用程序。例如,思考一下如何使用各组织私有数据集合来实现资产转移场景:

一项资产交易的进行情况如下:

  1. 链下,资产所有者和意向买家同意以某一特定价格交易该资产。

  2. 卖家通过以下方式提供资产所有权证明:利用带外数据传输私有信息;或者出示证书以供买家在其自身节点或管理员节点上查询私有数据。

  3. 买家验证私有信息的 hash 是否匹配链上公共 hash。

  4. 买家通过调取链码来在其自身私有数据集合中记录投标细节信息。一般在买家自己的节点上调取链码,但如果集合背书策略有相关规定,则也可能会在管理员节点上调取链码。

  5. 当前的资产所有者(卖家)调取链码来卖出、转移资产,传递私有信息和投标信息。在卖家、买家和管理员的节点上调用链码,以满足公钥的背书策略以及买家和买家私有数据集合的背书策略。

  6. 链码验证交易发送方是否为资产拥有者,根据卖家私有数据集合中的 hash 来验证私有细节信息,同时还会根据买家私有数据集合中的 hash 来验证投标细节信息。随后链码为公钥书写提案更新(将资产拥有者设定为买家,将背书策略设定为买家和管理员),把私有细节信息写入买家的私有数据集合中,以上步骤成功完成后链码会把卖家私有数据集合中的相关私有细节信息删除。在最终背书之前,背书节点会确保已将私有数据分布给卖家和管理员的所有授权节点。

  7. 卖家提交交易等待排序,其中包括了公钥和私钥 hash,随后该交易被分布到区块中的所有通道节点上。

  8. 每个节点的区块验证逻辑都将一致性地验证背书策略是否得到满足(买家、卖家和管理员都作出背书),同时还验证链码中已读取的公钥和私钥自链码执行以来未被任何其他交易更改。

  9. 所有节点提交的交易都是有效的,因为交易已经通过验证。如果买家和管理员节点在背书时未收到私有数据的话,它们将会从其他授权节点那里获取这些私有数据,并将这些数据保存在自己的私有数据状态数据库中(假定私有数据与交易的 hash 匹配)。

  10. 交易完成后,资产被成功转移,其他对该资产感兴趣的通道成员可能会查询公钥的历史以了解该资产的来历,但是它们无法访问任何私有细节信息,除非资产拥有者在须知的基础上共享这些信息。

以上是最基本的资产转移场景,我么可以对其进行扩展,例如,资产转移链码可能会验证一项付款记录是否可用于满足付款和交付要求,或者可能会验证一个银行是否在执行资产转移链码之前已经提交了信用证。交易各方并不直接维护节点,而是通过那些运行节点的托管组织来进行交易。

清除私有数据

对于非常敏感的数据,即使是共享私有数据的各方可能也希望(或者应政府相关法规要求必须)定期“清除”节点上的数据,仅把这些敏感数据的 hash 留在区块链上,作为私有数据不可篡改的证据。

在某些情况下,私有数据只需要在其被复制到节点区块链外部的数据库之前存在于该节点的私有数据库中。而数据或许也只需要在链码业务流程结束之前存在于节点上(交易结算、合约履行等)。

为了支持这些用户案例,如果私有数据已经持续 N 个块都没有被修改,则可以清除该私有数据,N 是可配置的。链码中无法查询已被清除的私有数据,并且其他节点也请求不到。

私有数据集合怎么定义

有关集合定义的更多详细信息,以及关于私有数据和集合的其他更底层的信息,请参阅私有数据主题