net.corda.core.contracts.TransactionVerificationException $ ContractRejection: Ошибка проверки контракта: - PullRequest
0 голосов
/ 21 мая 2018

Я получаю исключение при выполнении моего теста потока

net.corda.core.contracts.TransactionVerificationException$ContractRejection: Contract verification failed: Required com.example.contract.InvoiceContract.Commands command, contract: com.example.contract.InvoiceContract

У меня есть txn, который потребляет 4 различных типа линейных состояний, обновляет некоторые поля и добавляет их в выходное состояние.У txn есть одна команда, логика которой определена в вышеуказанных государственных контрактах.Ниже приведен мой код потока:

object SubmitDocuments {

@InitiatingFlow
@StartableByRPC
class SubmitDocumentsToBank(val locState: StateAndRef<LOCState>, val invoiceState: StateAndRef<InvoiceState>, val packingListState: StateAndRef<PackingListState>, val bolState: StateAndRef<BillOfLadingState>, val updatedlocState: LOCState, val bank: Party) : FlowLogic<SignedTransaction>(){

    companion object{
        object CREATING_BUILDER : ProgressTracker.Step("Creating a Transaction builder")
        object ADDING_STATES : ProgressTracker.Step("Adding Purchase order State in the transation output")
        object ADDING_COMMAND : ProgressTracker.Step("Adding a Create Command in the transaction")
        object VERIFIYING_TX : ProgressTracker.Step("Verifying the txn")
        object SIGNING_TX : ProgressTracker.Step("Signing the transaction")
        object SENDING_TX : ProgressTracker.Step("Sending and committing the transaction")

        fun tracker() = ProgressTracker(CREATING_BUILDER, ADDING_STATES, ADDING_COMMAND, SIGNING_TX, VERIFIYING_TX, SENDING_TX  )
    }

    override val progressTracker: ProgressTracker = tracker()

    @Suspendable
    override fun call(): SignedTransaction {

        val notary = serviceHub.networkMapCache.notaryIdentities.first()

        progressTracker.currentStep = CREATING_BUILDER
        val buider = TransactionBuilder(notary)
        buider.setTimeWindow(Instant.now(), Duration.ofSeconds(60))

        progressTracker.currentStep = ADDING_STATES

        val newInvoiceState = invoiceState.state.data.copy(participants = listOf(invoiceState.state.data.seller, bank))
        val newpackingListState = packingListState.state.data.copy(participants = listOf(invoiceState.state.data.seller, bank))
        val newbolState = bolState.state.data.copy(owner = bank, participants = listOf(bank) )

        buider.addInputState(invoiceState)
        buider.addInputState(packingListState)
        buider.addInputState(bolState)
        buider.addInputState(locState)

        buider.addOutputState(newInvoiceState, LOCContract.LOC_CONTRACT_ID)
        buider.addOutputState(newpackingListState, LOCContract.LOC_CONTRACT_ID)
        buider.addOutputState(newbolState, LOCContract.LOC_CONTRACT_ID)
        buider.addOutputState(updatedlocState, LOCContract.LOC_CONTRACT_ID)


        progressTracker.currentStep = ADDING_COMMAND

        val verifyDocHashCommand = Command(LOCContract.Commands.VerifySubmittedDocuments(), listOf(serviceHub.myInfo.legalIdentities.first().owningKey))
        buider.addCommand(verifyDocHashCommand)


        progressTracker.currentStep = VERIFIYING_TX
        buider.verify(serviceHub)

        progressTracker.currentStep = SIGNING_TX
        val stx = serviceHub.signInitialTransaction(buider)

        progressTracker.currentStep = SENDING_TX

        return subFlow(FinalityFlow(stx))

    }

}

}

Ниже приведен код контракта, в котором указана логика для команды:

open class LOCContract: Contract {

companion object {
    @JvmStatic
    val LOC_CONTRACT_ID = "com.example.contract.LOCContract"
}

interface  Commands: CommandData {
    class IssueLoc(val referenceState: String): Commands
    class VerifySubmittedDocuments: Commands
    class EndorseDocuments(val caller: Party): Commands
    class ReleaseDocuments: Commands
}

override fun verify(tx: LedgerTransaction) {

    val time = Instant.now()
    val command = tx.commands.requireSingleCommand<Commands>()
    when (command.value) {


        is LOCContract.Commands.VerifySubmittedDocuments -> {
            val inputInvoiceState = tx.inputsOfType<InvoiceState>().single()
            val inputplistState = tx.inputsOfType<PackingListState>().single()
            val inputbolState = tx.inputsOfType<BillOfLadingState>().single()
            val bolHash = inputbolState.props.billOfLadingAttachment.hash
            val invoiceHash = inputInvoiceState.props.invoiceAttachmentHash.hash
            val packinglistHash = inputplistState.props.packingListAttachment.hash

            val nonContractAttachments:List<Attachment> = tx.attachments.filter { it !is ContractAttachment }

            requireThat {

                "Attachments are empty" using (nonContractAttachments.isNotEmpty())

                var  list: ImmutableList<SecureHash>? = null
                nonContractAttachments.forEach((fun (data){
                    list!!.add(data.id)
                }))

                "transaction should have valid Bill of lading document hash" using (list!!.contains(bolHash))
                "transaction should have valid Invoice document hash" using (list!!.contains(invoiceHash))
                "transaction should have valid Packing List document hash" using (list!!.contains(packinglistHash))
            }

        }

    }
}

}

Почему он жалуется на => Обязательная команда com.example.contract.InvoiceContract.Commands, контракт: com.example.contract.InvoiceContract, транзакция: я что-то пропустил при построении txn в потоке?

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Ошибка действительна: для транзакции требуется ссылка com.example.contract.InvoiceContract.Commands

Внутри класса потока вы обновляете InvoiceState, но transaction не нашла ссылку наcommand из InvoiceContract.

Исправление должно быть:

  1. Состояние вывода должно относиться к InvoiceContract класс контракта buider.addOutputState(newInvoiceState, InvoiceContract.INVOICE_CONTRACT_ID)
  2. Затем создайте и добавьте соответствующий InvoiceContract Command в построитель транзакций.
0 голосов
/ 22 мая 2018

Кажется, что ваш InvoiceContract наследуется от вашего LOCContract, внутри вашего InvoiceContract в tx.commands.requireSingleCommand<Commands>() выдает эту ошибку.

...