Corda 4.0中动态添加参与方到状态的方法

4

是否可以在流程中动态向状态添加参与方,以便将状态存储在第三方库中,而不需要在ReceiveFinalityFlow中使用StatesToRecord.ALL_VISIBLE?

在Corda 2.0中我们已经实现了同样的功能,但在Corda 4.0中不再适用。

在Corda 3.2及以上版本中是否不支持该功能?我看到在ContractState中添加了@KeepForDJVM。

我尝试在IOUState中动态添加参与方,例如:[iouState.participants.add(thirdParty)],并在更新IOUState的参与方列表为可变列表时([override val participants: MutableList<AbstractParty> = mutableListOf(lender, borrower)]),以使IOUState也存储在ThirdParty vault中。 我还将借款人和第三方的流程会话传递给CollectSigntaureFlow和FinalityFlow。 可是,IOUFlowTests [flow records the correct IOU in both parties' vaults]失败,提示在thridParty vault中找不到iouState。

IOUState:
@BelongsToContract(IOUContract::class)
data class IOUState(val value: Int,
                    val lender: Party,
                    val borrower: Party,
                    val thirdParty: Party,
                    override val linearId: UniqueIdentifier = UniqueIdentifier()):
        LinearState, QueryableState {
    /** The public keys of the involved parties. */
    //override val participants: MutableList<AbstractParty> get() = mutableListOf(lender, borrower)
    override val participants = mutableListOf(lender, borrower)


ExampleFlow:
var iouState = IOUState(iouValue, serviceHub.myInfo.legalIdentities.first(), otherParty, thirdParty)

iouState.participants.add(thirdParty)

val txCommand = Command(IOUContract.Commands.Create(), iouState.participants.map { it.owningKey })

val counterparties = iouState.participants.map { it as Party }.filter { it.owningKey != ourIdentity.owningKey }.toSet()

counterparties.forEach { p -> flowSessions.add(initiateFlow(p))}

val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, flowSessions, GATHERING_SIGS.childProgressTracker()))

            // Stage 5.
            progressTracker.currentStep = FINALISING_TRANSACTION
            // Notarise and record the transaction in both parties' vaults.
            return subFlow(FinalityFlow(fullySignedTx, flowSessions, FINALISING_TRANSACTION.childProgressTracker()))

双方借方和第三方都接收流量并签署交易,但在参与者列表中看不到第三方,并且未存储在第三方保险库中。

我希望第三方应该出现在参与者列表中,同时IOUState也应存储在第三方保险库中。

1个回答

1
在 Corda 中,状态是不可变的。这意味着您无法在流程体中动态地向给定状态添加参与者。但是,有其他解决方案可以通知新的第三方状态!
在此处实现目标有两种方法:
1. 创建一个具有更新的参与者列表的新 IOUState tx 输出。
在流程体中,您应该创建一个具有更新的参与者列表的新 IOUState。您将不得不更新 IOUState,以便 participants 是主要构造函数中的一个值。然后,您可以使用像这样的帮助程序方法来添加参与者:
fun addParticipant(partyToAdd: Party): IOUState = copy(participants + partyToAdd)

这里的重要部分是:您必须将旧的 IOUState 作为此交易的输入,将新的 IOUState 作为输出包含在其中。 Corda 基于 UTXO 模型 - 更新状态的唯一方法是将其标记为历史记录(将其用作输入),然后将更新版本持久化到分类帐中。
注意:作为参与者,知情方现在将能够提出对此 IOUState 的更改建议 - 这些必须在 Corda 合同中予以考虑。
使用 SendStateAndRefFlow(可能是您问题的更好解决方案)
SendStateAndRefFlow 将(如其名称所示)发送状态及其关联的 stateRef 到接收节点。 对等方(接收节点)必须在流程会话的正确点使用 ReceiveStateAndRefFlow。
subFlow(new SendStateAndRefFlow(counterpartySession, dummyStates));

这两种方法都会导致接收节点验证状态的依赖关系(包括其历史记录中的所有输入和交易)。

谢谢你的回复,Nick。我尝试按照你提到的方法添加copy方法,但是ContractState中的参与者在copy方法中不可见。这会导致编译错误。我们遵循了你在第一点中提到的方法。由于它是MutableList,我们能够在流程中添加参与者,在Corda 2.0中可以工作,但在Corda 4.0中无法工作。 - Muthu
现在它已经可以工作了,因为参与者属性被添加到构造函数而不是主体中。 - Muthu
如果将override val participants = mutableListOf(lender,borrower)移动到构造函数中,则我们将能够使用thirdParty复制IOUState并正常工作。 - Muthu
@Muthu - 太好了!很高兴它起作用了。坦白地说,我在 Corda 2.0 上的经验较少,但我知道你需要生成一个带有更新参与者列表的新状态,以实现分配上的变更。 - Nicholas Rogers
这解决了你的问题吗?我应该编辑我的答案,加入更多信息吗? - Nicholas Rogers
谢谢@Muthu - 你介意点击勾选标记来表示问题已经得到解答吗? - Nicholas Rogers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接