在 Corda 4.0 中动态添加参与者到状态
Dynamically adding participants to state in Corda 4.0
是否可以将参与者动态添加到流内的状态,以便在不使用 ReceiveFinalityFlow 中的 StatesToRecord.ALL_VISIBLE 的情况下将状态存储在第三方库中?
我们在 Corda 2.0 中做了同样的事情,它在 Corda 4.0 中不起作用。
Corda 3.2 以上版本不支持吗?我看到 @KeepForDJVM 已添加到 ContractState。
在 IOUState 中的参与者更新为 mutableList 为 [override val participants: MutableList<AbstractParty> = mutableListOf(lender, borrower)]
之后,我尝试在 IOUState 中动态添加参与者为 [iouState.participants.add(thirdParty)]
,这样 IOUState 也将存储在 ThirdParty 保险库中。我也将借款人和第三方的流程会话传递给 CollectSigntaureFlow 和 FinalityFlow。 IOUFlowTests [flow records the correct IOU in both parties' vaults]
失败,在 thridParty 保险库中找不到 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()))
交易对手借款人和第三方都收到流量并签署交易,但在参与者列表中没有看到第三方,也没有存储在第三方保险库中。
我希望 ThirdParty 应该在参与者列表中,IOUState 也应该存储在 ThirdParty Vault 中。
在 Corda 中,状态是不可变的。这意味着您无法将参与者动态添加到流主体中的给定状态。但是,还有其他解决方案可以将状态通知给新的第三方!
这里有两种方法可以实现您的目标:
- 使用更新的参与者列表创建新的 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));
这两种方法都会导致接收节点验证状态的依赖性(构成其历史的所有输入和交易)
是否可以将参与者动态添加到流内的状态,以便在不使用 ReceiveFinalityFlow 中的 StatesToRecord.ALL_VISIBLE 的情况下将状态存储在第三方库中?
我们在 Corda 2.0 中做了同样的事情,它在 Corda 4.0 中不起作用。
Corda 3.2 以上版本不支持吗?我看到 @KeepForDJVM 已添加到 ContractState。
在 IOUState 中的参与者更新为 mutableList 为 [override val participants: MutableList<AbstractParty> = mutableListOf(lender, borrower)]
之后,我尝试在 IOUState 中动态添加参与者为 [iouState.participants.add(thirdParty)]
,这样 IOUState 也将存储在 ThirdParty 保险库中。我也将借款人和第三方的流程会话传递给 CollectSigntaureFlow 和 FinalityFlow。 IOUFlowTests [flow records the correct IOU in both parties' vaults]
失败,在 thridParty 保险库中找不到 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()))
交易对手借款人和第三方都收到流量并签署交易,但在参与者列表中没有看到第三方,也没有存储在第三方保险库中。
我希望 ThirdParty 应该在参与者列表中,IOUState 也应该存储在 ThirdParty Vault 中。
在 Corda 中,状态是不可变的。这意味着您无法将参与者动态添加到流主体中的给定状态。但是,还有其他解决方案可以将状态通知给新的第三方!
这里有两种方法可以实现您的目标:
- 使用更新的参与者列表创建新的 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));
这两种方法都会导致接收节点验证状态的依赖性(构成其历史的所有输入和交易)