Hyperledger Fabric 二三事 - 私有数据

私有数据

私有数据集合

我们都知道在Fabric中,若有利益相关方想要共享账本或数据又不想向利益无关方泄露,可以创建一个通道共同加入进去。但现在有下面这种场景:

设想一个通道上的五个组织,他们从事农产品贸易:
	1. 农民在国外售卖他的货物
	2. 分销商将货物运往国外
	3. 托运商负责参与方之间的货物运输
	4. 批发商向分销商采购商品
	5. 零售商向托运人和批发商采购商品
分销商可能希望与农民和托运商进行私下交易,以对批发商和零售商保密交易条款
(以免暴露他们收取的加价)

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

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

如果想要实现上述分销商和批发商的小心思,首先我们可能会想到可以让他们与各自的上下游建立一个小通道。但是,在每种情况下创建单独的通道会产生额外的管理开销(维护链码版本、策略、MSP等),并且不能在保留一部分数据私有的同时,可以让所有通道参与者看到该事务。

下面我们来介绍一种基于定义私有数据集合(PDC)的方法。从v1.2开始,Fabric 提供了创建私有数据集合的功能,它允许在通道上定义的组织子集能够背书、提交或查询私有数据,而无需创建单独的通道。

首先来了解下什么是私有数据集合,集合是两个元素的组合:

  • 实际的私有数据,通过 Gossip 协议点对点地发送给授权可以看到它的组织。私有数据保存在被授权的组织的节点上的私有数据库上,它们可以被授权节点的链码访问。排序节点不能影响这里也不能看到私有数据。注意,由于 gossip 以点对点的方式向授权组织分发私有数据,所以必须设置通道上的锚节点,也就是每个节点上的 CORE_PEER_GOSSIP_EXTERNALENDPOINT 配置,以此来引导跨组织的通信。
  • 该数据的 hash 值,该 hash 值被背书、排序之后写入通道上每个节点的账本。Hash 值作为交易的证明用于状态验证,并可用于审计。

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

所以,对于上面那个问题,我们可以分成3个PDC:

  • PDC1: 分销商, 农民 和 托运商
  • PDC2:分销商 和 批发商
  • PDC3:批发商, 零售商 和 托运商
    image
    其中,属于分销商的节点将在其账本中包含多个私有的私有数据库,其中包括来自分销商、农民和托运商子集合关系和分销商和批发商子集合关系的私有数据。
    image

使用私有数据的交易流

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

  1. 客户端应用程序提交一个提案请求,让属于授权集合的背书节点执行链码函数(读取或写入私有数据)。 私有数据,或用于在链码中生成私有数据的数据,被发送到提案的 transient(瞬态)字段中。
  2. 背书节点模拟交易,并将私有数据存储在 瞬态数据存储( transient data store ,节点的本地临时存储)中。它们根据组织集合的策略将私有数据通过gossip分发给授权的 Peer 节点。
  3. 背书节点将提案响应发送回客户端。提案响应中包含经过背书的读写集,这其中包含了公共数据,还包含任何私有数据键和值的 hash。私有数据不会被发送回客户端。
  4. 客户端应用程序将交易(包含带有私有数据 hash 的提案响应)提交给排序服务。带有私有数据 hash 的交易同样被包含在区块中。带有私有数据 hash 的区块被分发给所有节点。这样,通道中的所有节点就可以在不知道真实私有数据的情况下,用同样的方式来验证带有私有数据 hash 值的交易。
  5. 在区块提交的时候,授权节点会根据集合策略来决定它们是否有权访问私有数据。如果节点有访问权,它们会先检查自己的本地 瞬态数据存储 ,以确定它们是否在链码背书的时候已经接收到了私有数据。如果没有的话,它们会尝试从其他已授权节点那里拉取私有数据,然后对照公共区块上的 hash 来验证私有数据并提交交易和区块。当验证或提交结束后,私有数据会被移动到这些节点私有数据库和私有读写存储的副本中。随后 瞬态数据存储 中存储的这些私有数据会被删除。

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

  1. 链下,资产所有者和意向买家同意以某一特定价格交易该资产。
  2. 卖家通过以下方式提供资产所有权证明:利用带外数据传输私有信息;或者出示证书以供买家在其自身节点或管理员节点上查询私有数据。
  3. 买家验证私有信息的 hash 是否匹配链上公共 hash。
  4. 买家通过调取链码来在其自身私有数据集合中记录投标细节信息。一般在买家自己的节点上调取链码,但如果集合背书策略有相关规定,则也可能会在管理员节点上调取链码。
  5. 当前的资产所有者(卖家)调取链码来卖出、转移资产,传递私有信息和投标信息。在卖家、买家和管理员的节点上调用链码,以满足公钥的背书策略以及买家和买家私有数据集合的背书策略。
  6. 链码验证交易发送方是否为资产拥有者,根据卖家私有数据集合中的 hash 来验证私有细节信息,同时还会根据买家私有数据集合中的 hash 来验证投标细节信息。随后链码为公钥书写提案更新(将资产拥有者设定为买家,将背书策略设定为买家和管理员),把私有细节信息写入买家的私有数据集合中,以上步骤成功完成后链码会把卖家私有数据集合中的相关私有细节信息删除。在最终背书之前,背书节点会确保已将私有数据分布给卖家和管理员的所有授权节点。
  7. 卖家提交交易等待排序,其中包括了公钥和私钥 hash,随后该交易被分布到区块中的所有通道节点上。
  8. 每个节点的区块验证逻辑都将一致性地验证背书策略是否得到满足(买家、卖家和管理员都作出背书),同时还验证链码中已读取的公钥和私钥自链码执行以来未被任何其他交易更改。
  9. 所有节点提交的交易都是有效的,因为交易已经通过验证。如果买家和管理员节点在背书时未收到私有数据的话,它们将会从其他授权节点那里获取这些私有数据,并将这些数据保存在自己的私有数据状态数据库中(假定私有数据与交易的 hash 匹配)。
  10. 交易完成后,资产被成功转移,其他对该资产感兴趣的通道成员可能会查询公钥的历史以了解该资产的来历,但是它们无法访问任何私有细节信息,除非资产拥有者在须知的基础上共享这些信息。
posted @ 2021-04-01 10:28  压伤的芦苇  阅读(244)  评论(0)    收藏  举报