首页 > 解决方案 > Corda 在单个流调用中返回多个事务 ()

问题描述

我有一种情况,其中一方需要读取状态列表(例如 DEAL STATE),然后遍历列表以找出匹配的记录。如果匹配,我们需要通过组合匹配的字段来创建新的输出状态。

因此,一旦在循环内执行匹配,我们就可以获得输入和输出状态列表。

但我对从其他方收集签名感到困惑,因为每条记录的交易对手都是不同的。另外,我将如何在单个流调用方法中调用多个事务的最终流?

@joel,另一个问题 - 假设 outputstate1 参与者是 A、B、C,而 outputstate2 参与者是 B、C、D,即 B 和 C 参与 2 笔交易。所以在匹配状态循环中,当我们制作 flowsessions 映射时,它的签名者是 A、B、C、D。但是当我们调用 CollectSignaturesFlow 时,我们需要传递每个部分签名的 trxn 和会话。那么如何通过一个 trxn 对应的会话呢?

标签: corda

解决方案


这是我们如何收集每个州的签名的示例:

val flowSessionMap = mutableMapOf<Party, FlowSession>()

val fullySignedTransactions = matchingStates.forEach { matchingState ->
    val requiredSigners: List<Party> = TODO("Derive this from the matching state somehow.")
    val signedTransaction: SignedTransaction = TODO("Build transaction.")

    val sessions = requiredSigners.map { signer ->
        flowSessionMap.getOrPut(signer) {
            initiateFlow(signer)
        }
    }

    val fullySignedTransaction = subFlow(CollectSignaturesInitiatingFlow(
        signedTransaction, sessions)
    )
}

其中CollectSignaturesInitiatingFlow定义如下:

@InitiatingFlow
class CollectSignaturesInitiatingFlow(val signedTransaction: SignedTransaction, val sessions: List<FlowSession>): FlowLogic<SignedTransaction>() {
    override fun call(): SignedTransaction {
        return subFlow(CollectSignaturesFlow(signedTransaction, sessions))
    }
}

响应者CollectSignaturesInitiatingFlow定义如下:

@InitiatedBy(CollectSignaturesInitiatingFlow::class)
class CollectSignaturesInitiatingFlowResponder(val otherPartyFlow: FlowSession) : FlowLogic<SignedTransaction>() {
    @Suspendable
    override fun call(): SignedTransaction {
        val signTransactionFlow = object : SignTransactionFlow(otherPartyFlow) {
            override fun checkTransaction(stx: SignedTransaction) {
                TODO("Check the transaction here.")
            }
        }

        return subFlow(signTransactionFlow)
    }
}

注意:

  • 我们小心地为每个交易对手创建一个会话。从 Corda 3 开始,如果流程为每个交易对手创建多个会话,则会引发错误
  • CollectSignaturesFlow我们正在包装对in的调用CollectSignaturesInitiatingFlow。为什么?在 Corda 中,有两种类型的流:Initiating和内联。每个Initiating流实例都有一个唯一的 ID,而每个内联流都继承了将其称为子流的流的 ID。从 Corda 3 开始,如果响应者为同一个流 ID 调用两次,则会引发异常。CollectSignaturesFlow通过将(内联流)包装在CollectSignaturesInitiatingFlow(流)内部Initiating,我们为每次收集签名的尝试创建一个新的流 ID,并且不会抛出异常

一旦你有了完全签名的交易,你就可以FinalityFlow循环调用:

for (transaction in fullySignedTransactions) {
    subFlow(FinalityFlow(transaction))
}

推荐阅读