如何在Corda中定义一个非共享事实

如何在Corda中定义一个非共享事实,corda,Corda,目前,我们计划有一份合同的“草案”版本,不会发送给交易对手,发起人可以在将其发送到网络之前进行任何更改,因此这应该是一个“非共享事实”。正如我们所知,Corda和vault用于共享事实,因此我不确定我们是否仍然可以使用vault来存储这种类型的“非共享事实”,我的想法如下,并且我已经可以根据教程CorDapp在本地实现这一点,但我想从其他Corda团队/专家那里获得一些输入 主要变化在启动器流程中: 仅使用启动器的密钥启动create命令 不要调用“CollectSignaturesFlow”

目前,我们计划有一份合同的“草案”版本,不会发送给交易对手,发起人可以在将其发送到网络之前进行任何更改,因此这应该是一个“非共享事实”。正如我们所知,Corda和vault用于共享事实,因此我不确定我们是否仍然可以使用vault来存储这种类型的“非共享事实”,我的想法如下,并且我已经可以根据教程CorDapp在本地实现这一点,但我想从其他Corda团队/专家那里获得一些输入

主要变化在启动器流程中:

  • 仅使用启动器的密钥启动create命令
  • 不要调用“CollectSignaturesFlow”,这样就不会将其发送给任何其他人
  • 在verify()之后调用“FinalityFlow”,以便将其提交到分类账
以下是上述各点的代码

override fun call(): SignedTransaction  {
    // We create a transaction builder
    val txBuilder = TransactionBuilder()
    val notaryIdentity = serviceHub.networkMapCache.getAnyNotary()
    txBuilder.notary = notaryIdentity

    // We create the transaction's components.
    val ourIdentity = serviceHub.myInfo.legalIdentity
    val iou = TemplateState(iouValue, ourIdentity, ourIdentity)
    val txCommand = Command(TemplateContract.Create(), listOf(ourIdentity.owningKey))

    // Adding the item's to the builder.
    txBuilder.withItems(iou, txCommand)

    // Verifying the transaction.
    txBuilder.toWireTransaction().toLedgerTransaction(serviceHub).verify()

    // Signing the transaction.
    val partSignedTx = serviceHub.signInitialTransaction(txBuilder)

    // Finalising the transaction.
    return subFlow(FinalityFlow(partSignedTx)).single()
}

您确实可以在Corda中创建一个非共享事实!这里的关键是州的
参与者
列表。只需将您自己添加到参与者列表中,并且仅将您的公钥添加到命令中即可。下面是一个简单的例子:

//Contract and State.
class UnsharedFact: Contract {
    override val legalContractReference: SecureHash = SecureHash.zeroHash
    override fun verify(tx: TransactionForContract) = Unit // Stubbed out.
    class Create: CommandData

    data class State(val parties: Set<Party>): ContractState {
        override val contract: Contract get() = UnsharedFact()
        override val participants: List<AbstractParty> get() = parties.toList()
        fun addParty(newParty: Party) = copy(parties = parties + newParty)
    }
}

// Create flow.
@InitiatingFlow
@StartableByRPC
class CreateUnsharedFact(): FlowLogic<SignedTransaction>() {
    @Suspendable
    override fun call(): SignedTransaction {
        val me = serviceHub.myInfo.legalIdentity
        val notary = serviceHub.networkMapCache.getAnyNotary()
        val state = UnsharedFact.State(setOf(me))
        val command = Command(UnsharedFact.Create(), listOf(me.owningKey))
        val utx = TransactionBuilder(notary = notary).withItems(state, command)
        val stx = serviceHub.signInitialTransaction(utx)
        return subFlow(FinalityFlow(stx)).single()
    }
}
//合同和状态。
类非共享行为:合同{
override val legalContractReference:SecureHash=SecureHash.zeroHash
覆盖乐趣验证(tx:TransactionForContract)=单位//断头。
类Create:CommandData
数据类状态(val:集):ContractState{
覆盖val合同:合同get()=非共享行为()
覆盖val参与者:List get()=parties.toList()
乐趣添加派对(新派对:派对)=副本(派对=派对+新派对)
}
}
//创建流。
@启动流
@星表
类CreateUnsharedFact():FlowLogic(){
@暂停
重写趣味调用():SignedTransaction{
val me=serviceHub.myInfo.legaldentity
val notary=serviceHub.networkMapCache.getAnyNotary()
val state=UnsharedFact.state(setOf(me))
val command=command(UnsharedFact.Create(),listOf(me.owningKey))
val utx=TransactionBuilder(公证人=公证人)。withItems(状态,命令)
val stx=serviceHub.signInitialTransaction(utx)
返回子流(FinalityFlow(stx)).single()
}
}
调用
FinalityFlow
时,您将是唯一接收输出状态的节点

如果您希望随后涉及另一方,则可以使用
UnsharedFact.state
上的
addParty
方法创建状态的新版本。然后,创建一个新事务,将原始状态添加为输入,将新版本(有新的参与方)添加为输出。该交易完成(公证)后,双方将在各自的保险库中保存一份副本。现在,我想‘UnsharedFact’这个名字不合适:)


您也可以使用类似的方法删除参与方。

感谢罗杰的评论。所以回到我们的合同“草稿”版本,尽管这不是一个共享事实,但它是存储在vault中的事实,所以要更新甚至删除它,我们仍然应该使用输入和输出来完成,但不应该更新或删除vault中的原始数据,Corda本身也不提供任何物理更新/删除状态的功能。我说的对吗?罗杰,我刚刚注意到,在Corda的核心项目《商业票据演示流程》中,它有一个
selfissuesemecommercialpaper
功能,它使用
serviceHub.recordTransactions(listOf(tx))
来记录交易及其到vault的输出状态,而不是
FinalityFlow
,这是我们可以使用的另一种方法吗?对于您的第一个评论-是的!要更新和/或删除它,您将使用事务。第二个评论。我建议使用
FinalityFlow
而不是
recordTransactions
FinalityFlow
获取公证人签名(如果需要),然后通过调用
BroadcastTransactionFlow
将tx分发给所有需要的方。接收方运行
NotifyTransactionHandler
(响应
BroadcastTransactionFlow
),然后解析发送依赖项并存储事务。感谢确认。