创建涉及三个不同方的机密身份的交易的示例如下所示。诀窍是仅使用发起者生成的两个机密身份之一作为对SwapIdentitiesFlow 的两个初始调用的一部分。然后,您需要使用 IdentitySyncFlow 向未将其视为原始交换一部分的一方显示您选择的机密身份。
我们的州:
data class PartyState(val parties: List<AnonymousParty>) : ContractState {
override val participants = parties
}
我们的合同:
class PartyContract : Contract {
companion object {
val ID = "com.template.PartyContract"
}
object PartyCommand: CommandData
override fun verify(tx: LedgerTransaction) {}
}
我们的初始流程:
@InitiatingFlow
@StartableByRPC
class Initiator(val alice: Party, val bob: Party) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
// Exchange anonymous identities with Alice.
val aliceSession = initiateFlow(alice)
val firstSwapIdentities = subFlow(SwapIdentitiesFlow(alice))
val anonymousMe = firstSwapIdentities[ourIdentity]!!
val anonymousAlice = firstSwapIdentities[alice]!!
// Exchange anonymous identities with Bob.
val bobSession = initiateFlow(bob)
val secondSwapIdentities = subFlow(SwapIdentitiesFlow(bob))
// We ignore our second generated anonymous identity. We've already
// created one in the exchange with Alice.
val anonymousBob = secondSwapIdentities[bob]!!
val notary = serviceHub.networkMapCache.notaryIdentities.first()
val anonymousParties = listOf(anonymousMe, anonymousAlice, anonymousBob)
val outputState = PartyState(anonymousParties)
val command = PartyContract.PartyCommand
val txBuilder = TransactionBuilder(notary)
.addOutputState(outputState, PartyContract.ID)
.addCommand(command, anonymousParties.map { it.owningKey })
// Sign the transaction with our anonymous key.
val stx = serviceHub.signInitialTransaction(txBuilder, anonymousMe.owningKey)
// Sync identities with Bob. We already synced them with Alice as part
// of SwapIdentitiesFlow.
subFlow(IdentitySyncFlow.Send(bobSession, stx.tx))
// Pass our new anonymous key into the CollectSignaturesFlow.
val ftx = subFlow(CollectSignaturesFlow(stx, listOf(aliceSession, bobSession), listOf(anonymousMe.owningKey)))
subFlow(FinalityFlow(ftx))
}
}
第一响应者:
@InitiatedBy(Initiator::class)
class AliceResponder(val counterpartySession: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val signTxFlow = object: SignTransactionFlow(counterpartySession) {
override fun checkTransaction(stx: SignedTransaction) {}
}
subFlow(signTxFlow)
}
}
第二响应者:
@InitiatedBy(Initiator::class)
class BobResponder(val counterpartySession: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val signTxFlow = object: SignTransactionFlow(counterpartySession) {
override fun checkTransaction(stx: SignedTransaction) {}
}
// Unlike Alice, Bob needs to sync identities with the initiator.
subFlow(IdentitySyncFlow.Receive(counterpartySession))
subFlow(signTxFlow)
}
}