在Corda中,如何使用'CompositeKey'作为必需的签名者?

在Corda中,如何使用'CompositeKey'作为必需的签名者?,corda,Corda,在Corda中,事务上所需的签名者可以是CompositeKeys,而不是常规公钥。如何创建一个CompositeKey,并使其成为交易所需的签名者?如何收集相应的签名?以下是一个创建复合键的流程,使其成为交易中所需的签名者,并收集相应的签名: object OurFlow { @InitiatingFlow @StartableByRPC class Initiator(val otherPartyA: Party, val otherPartyB: Party) :

在Corda中,事务上所需的签名者可以是
CompositeKey
s,而不是常规公钥。如何创建一个
CompositeKey
,并使其成为交易所需的签名者?如何收集相应的签名?

以下是一个创建
复合键的流程,使其成为交易中所需的签名者,并收集相应的签名:

object OurFlow {
    @InitiatingFlow
    @StartableByRPC
    class Initiator(val otherPartyA: Party, val otherPartyB: Party) : FlowLogic<Unit>() {

        @Suspendable
        override fun call() {
            // We create a composite key that requires signatures from ourselves
            // and one of the other parties (each weight is one and the threshold is 2)
            val compositeKey = CompositeKey.Builder()
                    .addKey(ourIdentity.owningKey, weight = 1)
                    .addKey(otherPartyA.owningKey, weight = 1)
                    .addKey(otherPartyB.owningKey, weight = 1)
                    .build(2)

            // We make the `CompositeKey` the required signer.
            val txBuilder = TransactionBuilder(serviceHub.networkMapCache.notaryIdentities[0])
                    .addCommand(OurContract.Commands.Create(), compositeKey)
                    .addOutputState(OurState(ourIdentity, otherPartyA, otherPartyB), OurContract.ID)

            val partStx = serviceHub.signInitialTransaction(txBuilder)

            // We gather the signatures. Note that we cannot use
            // `CollectSignaturesFlow` because:
            // * The `CompositeKey` does not correspond to a specific
            //   counterparty
            // * The counterparty may refuse to sign
            val sessions = listOf(otherPartyA, otherPartyB).map { initiateFlow(it) }
            // We filter out any responses that are not
            // `TransactionSignature`s (i.e. refusals to sign).
            val signatures = sessions
                    .map { it.sendAndReceive<Any>(partStx).unwrap { it } }
                    .filter { it is TransactionSignature }
                    as List<TransactionSignature>
            val fullStx = partStx.withAdditionalSignatures(signatures)

            subFlow(FinalityFlow(fullStx))
        }
    }

    @InitiatedBy(Initiator::class)
    class Acceptor(val otherPartySession: FlowSession) : FlowLogic<Unit>() {
        @Suspendable
        override fun call() {
            otherPartySession.receive<SignedTransaction>().unwrap { partStx ->
                // We return either a `TransactionSignature` (if we're willing
                // to sign) or `false`.
                val payload = if (CONDITION) {
                    serviceHub.createSignature(partStx)
                } else {
                    false
                }

                otherPartySession.send(payload)
            }
        }
    }
}
最后,这里是我们对州的定义:

class OurState(val partyA: Party, val partyB: Party, val partyC: Party) : ContractState {
    override val participants = listOf(partyA, partyB, partyC)
}

假设一个场景只需要3个签名中的2个(阈值=2),那么如何在流中处理它?我想到了一个场景,在这个场景中,我向两方调用sendAndReceive,但只需要一个签名。我想,即使如此,流也必须等待所有响应,一个或两个单独地对事务进行签名,对吗?我已经更新了答案来处理这个场景。收集签名时,每个节点都会以
TransactionSignature
false
响应。
class OurState(val partyA: Party, val partyB: Party, val partyC: Party) : ContractState {
    override val participants = listOf(partyA, partyB, partyC)
}