我在执行流量测试时遇到异常
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))
}
}
}
}
}
为什么抱怨=&gt;必需的com.example.contract.InvoiceContract.Commands命令,contract:com.example.contract.InvoiceContract,transaction: 我在流程中构建txn时是否遗漏了什么?
答案 0 :(得分:0)
似乎您的InvoiceContract
继承自LOCContract
,InvoiceContract
tx.commands.requireSingleCommand<Commands>()
内的@foreach($group as $key=>$data)
<td>{{$data->value}}</td>
@endforeach
正在抛出此错误。
答案 1 :(得分:0)
错误有效:交易需要参考 com.example.contract.InvoiceContract.Commands
在流程类中,您正在更新InvoiceState
,但transaction
没有找到command
InvoiceContract
的引用。
修复应该是:
InvoiceContract
合同类buider.addOutputState(newInvoiceState, InvoiceContract.INVOICE_CONTRACT_ID)
InvoiceContract
Command
并将其添加到事务构建器。