在相同类型的 Corda 州之间强制实施属性值的唯一性?



如何确保状态的属性对于账本上该状态的所有实例都是唯一的?

假设我有一个PersonStatenamessn(社会安全号码),如何确保没有PersonState写入与分类账上已经存在的任何PersonState具有相同ssn值的分类账?

如果PersonState是一个数据库表,namessn是列,那么很容易在ssn上指定唯一性约束,但我看不出如何使用 Corda 做到这一点。

新交易的提议者,将导致一个新的PersonState最终出现在账本上,显然可以在构建提案时检查现有状态。但这只确认了最初提案时的唯一性 - 我不明白如何确保事物在相关流的生命周期内保持唯一,以便该值仍然保证在最终性流结束时是唯一的(或者如果它不再是唯一的,则保证在这一点上被拒绝)?

我试图思考是否可以通过预言机实现某种唯一价值服务,如果公证人可以以某种方式强制执行这一点?也许我可以围绕这些想法想出一些东西(可能有一些致命的逻辑缺陷),但如果Corda已经为这种事情建立了一些既定的流程,那么那显然会更好。

PS 是的,我知道将 SSN 存储到分类帐可能是一个坏主意,这只是一个例子。

我认为您需要在验证公证人流程中检查此ssn的唯一性。 每次您收到交易时,您都会与Corda的公证人一起检查双花,因此在这种情况下,他只会在FLow的每一步检查他是否尚未收到应用于此ssn的特殊规则的PersonState状态。

请注意,它会将此数据泄露给公证人。

用户@Anoop发布了一个答案,但由于我不清楚的原因而被删除。以下是他回答的扩展。

用于持久性的 Corda API 文档描述了如何使用 JPA 指定如何将状态映射到底层保管库数据库。

他们以PersistentCashState为例 - 如果你看一下它,你会看到:

class PersistentCashState(
/** X500Name of owner party **/
@Column(name = "owner_name")
var owner: AbstractParty,
@Column(name = "pennies")
var pennies: Long,
...

注意:以上是 Kotlin 而不是 Java。

如您所见,使用了@Column注释 - 如果您查看@Column文档,您会发现您可以使用它来标记unique=true

列的唯一:

列是否是唯一键。这是表级别 UniqueConstraint 注释的快捷方式,当唯一键约束仅对应于单个列时非常有用。除了主键映射所需的任何约束以及在表级别指定的约束之外,此约束还适用。

我还没有尝试过这个来看看它在实践中是如何工作的。使用这样的约束只有在使用公证人时才有意义 - 因为只有公证人才能保证所有各方都尊重订单。即,如果您不使用公证人,一方可能会有效地提交涉及具有给定ssn状态的一笔交易,而另一方可能首先提交涉及同一ssn的不同交易。

我不确定当公证人尝试FinalityFlow然后在将状态保存到数据库时失败时会发生什么。但是这种方法听起来比我迄今为止看到的任何其他方法都更少受到竞争条件的影响(即首先检查 vault,然后希望另一个线程中的任何内容都不会打败您坚持涉及应该唯一的值的状态),即听起来它应该实现所需的事务性。

将这项工作委托给公证人有几个缺点:

  • 它通过强制使用验证公证人而构成隐私泄露。在大多数部署中,您可能希望使用非验证公证人
  • 这意味着只有运行自定义流的特殊公证人才能用于公证这些SSN交易
  • 它排除了一些分布式公证算法,因为集群中的所有公证人都必须就SSN唯一性和交易唯一性达成共识。

在这种情况下,我更喜欢神谕。预言机将保留已分配SSN的内部数据库,并且仅在以前未使用过SSN的事务中签名。您可以使用撕下来防止预言机看到交易的其余部分(请参阅 https://docs.corda.net/key-concepts-oracles.html#hiding-data),以便保护隐私。

预言机只需要签署发行 - 合同规则可以确保状态的SSN一旦发布就不会被修改。

最新更新