Прежде всего, я только начал изучать корду 3 месяца назад, поэтому у меня есть кое-какие знания.
Я унаследовал некоторый код, который отлично работает под Corda v3.3, но клиенты хотят, чтобы он работал на v4. Я пытаюсь следовать инструкциям на основном сайте. У меня есть инициирующий поток, который вызывает подпоток, который, в свою очередь, вызывает поток транспондера.
Инициирующий поток:
@InitiatingFlow(version = 2)
@StartableByRPC
class TransferFlow(private val issuerName: String = "",
private val seller: String = "",
private val amount: BigDecimal = BigDecimal("0"),
private val buyer: String = "",
private val custodianNameOfBuyer: String = "",
private val notaryName: String = "") : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
subFlow(UpdateStatusOfTransferFlow(
sessions,
tokenTransferAgreement.linearId,
"Removed Tokens From Seller"))
}
}
class UpdateStatusOfTransferFlow(
private val sessions: Set<FlowSession>,
private val tokenTransferAgreementID: UniqueIdentifier,
private val newStatus: String) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
sessions.size
val idQueryCriteria = QueryCriteria.LinearStateQueryCriteria(linearId = listOf(tokenTransferAgreementID))
val states = serviceHub.vaultService.queryBy<TokenTransferAgreement>(idQueryCriteria).states
if (states.size != 1) throw FlowException("Can not find a unique state for $tokenTransferAgreementID")
val inputStateAndRef = states.single()
val inputState = inputStateAndRef.state.data
val notary = inputStateAndRef.state.notary
val outputState = inputState.withNewStatus(newStatus)
val cmd = Command(TokenContract.Commands.UpdateStatusOfTransfer(),
inputState.participants.map { it.owningKey })
val txBuilder = TransactionBuilder(notary = notary)
txBuilder.addCommand(cmd)
txBuilder.addInputState(inputStateAndRef)
txBuilder.addOutputState(outputState, TokenContract.ID)
txBuilder.verify(serviceHub)
val ptx = serviceHub.signInitialTransaction(txBuilder)
val sessions2 = (inputState.participants.toSet() - ourIdentity).map { initiateFlow(it) }
return subFlow(CollectSignaturesFlow(ptx, sessions2))
}
}
And the responder:
@InitiatedBy(TransferFlowResponder::class)
class UpdateStatusOfTransferFlowResponder(private val session: FlowSession) : FlowLogic<Unit>() {
@Suspendable
override fun call() {
val tokenTransferAgreements = mutableListOf<TokenTransferAgreement>()
var isBuyer = true
var notary = CordaUtility.getNotary(serviceHub) ?: throw FlowException("An notary is expected!")
val signedTransactionFlow = subFlow(object : SignTransactionFlow(session) {
override fun checkTransaction(stx: SignedTransaction) = requireThat {
"There must be one output!" using (stx.tx.outputStates.size == 1)
val tokenTransferAgreement = stx.tx.outputStates.first() as TokenTransferAgreement
tokenTransferAgreements.add(tokenTransferAgreement)
notary = stx.notary ?: throw FlowException("An notary is expected!")
if (ourIdentity == tokenTransferAgreement.issuer) {
//checks go here
}
})
}
}
Я полагаю, что в какой-то момент я должен добавить вызов к потоку ReceiveFinality, однако он принимает в качестве аргумента только 1 сеанс, а не список, как у меня здесь. Должен ли я сделать несколько звонков, по одному для каждой сессии? Я также не уверен, должны ли звонки идти в транспондере или в классе UpdateStatusOfTransferFlow.
Помощь здесь будет оценена.