以下是我们如何收集每个州的签名的示例:
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 的调用封装在CollectSignaturesInitiatingFlow 中。为什么?在 Corda 中,有两种类型的流:Initiating 和内联。每个Initiating 流实例都有一个唯一的 ID,而每个内联流都继承了将其称为子流的流的 ID。从 Corda 3 开始,如果响应者为同一个流 ID 调用两次,则会引发异常。通过将 CollectSignaturesFlow(内联流)包装在 CollectSignaturesInitiatingFlow(Initiating 流)中,我们为每次收集签名的尝试创建一个新的流 ID,并且不会引发异常
获得完全签名的交易后,您可以循环调用FinalityFlow:
for (transaction in fullySignedTransactions) {
subFlow(FinalityFlow(transaction))
}