Как я могу использовать inputStatesAndRef респондента в транзакции Corda? - PullRequest
0 голосов
/ 17 февраля 2020

Я пытаюсь создать приложение Corda для обучения porpuses. В этом приложении мне нужно передать несколько монет новому владельцу, и состояния, в которых хранятся эти монеты, должны быть уникальными, если у вас есть предыдущее состояние монеты, вам нужно будет его развить. Например, если кто-то переводит вам 300 монет, а у вас уже есть 200, вы преобразуете это состояние в 200 монет в новое, равное 500.

Я уже пытался создать другие подпотоки для получения входных данных респондента. до сделки, но это не сработало. Ниже вы, ребята, можете видеть мой поток запросов и ответов, не справляясь с ситуацией, о которой я спрашивал выше. Ребята, можете ли вы представить, как я могу справиться с этой ситуацией?

Большое спасибо вам, ребята, и извините за некоторые проблемы с engli sh, которые могут возникнуть в моем тексте.

    @InitiatingFlow
    @StartableByRPC
    class CoinTransferFlow(var amount: Double, val newOwner: Party) : FlowLogic<SignedTransaction>() {
        companion object {
            object GENERATING_TRANSACTION : ProgressTracker.Step("Generating transaction based on new BrunoCoin.")
            object VERIFYING_TRANSACTION : ProgressTracker.Step("Verifying contract constraints.")
            object SIGNING_TRANSACTION : ProgressTracker.Step("Signing transaction with our private key.")
            object GETTING_OTHER_SIGNATURES : ProgressTracker.Step("Gathering the counterparty's signature.") {
                override fun childProgressTracker() = CollectSignaturesFlow.tracker()
            }

            object FINALISING_TRANSACTION : ProgressTracker.Step("Obtaining notary signature and recording transaction.") {
                override fun childProgressTracker() = FinalityFlow.tracker()
            }

            fun tracker() = ProgressTracker(
                    GENERATING_TRANSACTION,
                    VERIFYING_TRANSACTION,
                    SIGNING_TRANSACTION,
                    GETTING_OTHER_SIGNATURES,
                    FINALISING_TRANSACTION
            )
        }

        override val progressTracker = tracker()

        @Suspendable
        override fun call(): SignedTransaction {
            val listMoneyStateAndRef = serviceHub.vaultService.queryBy(BrunoCoinState::class.java).states

            val notary = serviceHub.networkMapCache.notaryIdentities[0]

            progressTracker.currentStep = GENERATING_TRANSACTION
            var txBuilder = buildTransaction(listMoneyStateAndRef, notary)

            progressTracker.currentStep = VERIFYING_TRANSACTION

            txBuilder.verify(serviceHub)

            progressTracker.currentStep = SIGNING_TRANSACTION

            val signedTransaction = serviceHub.signInitialTransaction(txBuilder)

            progressTracker.currentStep = GETTING_OTHER_SIGNATURES


            progressTracker.currentStep = FINALISING_TRANSACTION

            val otherPartySession = initiateFlow(newOwner)
            otherPartySession.send(signedTransaction)
            return subFlow(FinalityFlow(signedTransaction, setOf(otherPartySession)))
        }
    @InitiatedBy(CoinTransferFlow::class)
    class TransferResponderFlow(val otherPartySession: FlowSession) : FlowLogic<SignedTransaction>() {

        companion object {

            object VERIFYING_TRANSACTION : ProgressTracker.Step("Counterparty verifying contract constraints.")
            object  FINALISING_TRANSACTION :  ProgressTracker.Step("Counterparty finalising the transaction")

            fun tracker() = ProgressTracker(
                    VERIFYING_TRANSACTION,
                    FINALISING_TRANSACTION
            )
        }
        override val progressTracker = tracker()

        @Suspendable
        override fun call(): SignedTransaction {

            fun verifyTx(sgdTx : SignedTransaction) = requireThat {
                "O output precisa ser do tipo BrunoCoinState"  using (sgdTx.tx.outputStates[0] is BrunoCoinState)

                val bCoinState = sgdTx.tx.outputStates[0] as BrunoCoinState

                "O output2 precisa ser do tipo BrunoCoinTransferState" using (sgdTx.tx.outputStates[1] is BrunoCoinTransferState)

                val bCoinTransferState = sgdTx.tx.outputStates[1] as BrunoCoinTransferState

                "Os valores propostos na transação deve ser maior que 0" using (bCoinState.amount > 0
                        && bCoinTransferState.amount > 0)

                "Os valores propostos na transação e o valor enviados devem ser iguais" using (bCoinState.amount == bCoinTransferState.amount)
            }


            val sgdTx = otherPartySession.receive<SignedTransaction>().unwrap{ it }

            progressTracker.currentStep = VERIFYING_TRANSACTION

            verifyTx(sgdTx)

            progressTracker.currentStep = FINALISING_TRANSACTION

            return subFlow(ReceiveFinalityFlow(otherPartySession/*, expectedTxId = txId*/))
        }
    }

1 Ответ

1 голос
/ 07 апреля 2020

addInputState добавляет ссылочный ввод:

/** Adds an input [StateRef] to the transaction. */
open fun addInputState(stateAndRef: StateAndRef<*>) = apply {
    checkNotary(stateAndRef)
    inputs.add(stateAndRef.ref)
    inputsWithTransactionState.add(stateAndRef)
    resolveStatePointers(stateAndRef.state)
    return this
}

См. Пример: https://github.com/corda/samples/blob/release-V4/auction-cordapp/workflows/src/main/java/net/corda/samples/flows/BidFlow.java#L70

...