找不到合同附件

时间:2019-08-26 10:28:35

标签: kotlin corda

将corda升级到版本4后,我得到了net.corda.core.transactions.MissingContractAttachments:找不到com.template.contract.ServiceContractnull的合同附件。

此流在本地工作,但是在部署到Azure时会抛出错误消息。

我有

  • 检查我所有的cordapps是否都位于/ opt / corda / cordapps -folder

  • 我的合同ID是“ com.template.contract.ServiceContract”

  • 我没有进行任何测试

我试图更改SERVICE_CONTRACT_ID =“ com.template.contract”,但这也不起作用

CreateServiceFlow

@InitiatingFlow
@StartableByRPC
class CreateServiceFlow(val serviceState: ServiceState) : FlowLogic<SignedTransaction>() {
    override val progressTracker = ProgressTracker()
    @Suspendable
    override fun call(): SignedTransaction {

        serviceHub.vaultService.queryBy<ServiceState>().states.forEach{
            if (it.state.data.serviceName == serviceState.serviceName) {
                throw Exception("There can be only one ${serviceState.serviceName} service per service " +
                    "provider")
            }
        }

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

        val serviceCommand = Command(
            ServiceContract.Commands.IssueService(),
            serviceState.participants.map { it.owningKey }
        )

        val builder = TransactionBuilder(notary = notary)
            .addOutputState(serviceState, ServiceContract.SERVICE_CONTRACT_ID,
                constraint = AlwaysAcceptAttachmentConstraint)
            .addCommand(serviceCommand)

        builder.verify(serviceHub)

        val partSignedTx = serviceHub.signInitialTransaction(builder)

        val otherPartySession = initiateFlow(serviceState.accountOperator)

        val fullySignedTx = subFlow(CollectSignaturesFlow(partSignedTx, setOf(otherPartySession)))


        return subFlow(FinalityFlow(fullySignedTx, setOf(otherPartySession)))
    }
}

@InitiatedBy(CreateServiceFlow::class)
class IssueServiceResponder(val otherPartySession: FlowSession) : FlowLogic<SignedTransaction>() {
    @Suspendable
    override fun call(): SignedTransaction {
        val signTransactionFlow = object : SignTransactionFlow(otherPartySession) {
            override fun checkTransaction(stx: SignedTransaction) = requireThat {
                "there should be no inputs" using(stx.inputs.isEmpty())
                "there should be one output" using(stx.tx.outputStates.size == 1)
                "The state should serviceState" using(stx.tx.outputStates.single() is ServiceState)
            }
        }
        val txId = subFlow(signTransactionFlow).id
        return subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId = txId))
    }
}

ServiceContract

package com.template.contract

@LegalProseReference(uri = "<prose_contract_uri>")
class ServiceContract : Contract {
    companion object {
        @JvmStatic
        val SERVICE_CONTRACT_ID = "com.template.contract.ServiceContract"
    }

    val legalContractReference: SecureHash
        get() = SecureHash.randomSHA256()

    interface Commands : CommandData {
        class IssueService : TypeOnlyCommandData(), ServiceContract.Commands
        class AddServiceData : TypeOnlyCommandData(), ServiceContract.Commands
        class AddPartner: TypeOnlyCommandData(), ServiceContract.Commands
        class RemovePartner: TypeOnlyCommandData(), ServiceContract.Commands
        class ExitService : TypeOnlyCommandData(), ServiceContract.Commands
    }

    override fun verify(tx: LedgerTransaction) {....
}

在运行createService流到远程节点Web服务器的POST请求时,它会抛出

net.corda.core.transactions.MissingContractAttachments: Cannot find contract attachments for com.template.contract.ServiceContractnull. See https://docs.corda.net/api-contract-constraints.html#debugging
        at net.corda.core.transactions.TransactionBuilder.selectAttachmentThatSatisfiesConstraints(TransactionBuilder.kt:445) ~[corda-core-4.0.jar:?]...

更新:这是我在本地运行相同流时得到的响应

{
  "wire": {
    "id": "3EDD9204FF70AF2B36D78219690946004C7D5625D347F04EE55980A8600141BF",
    "notary": "O=NetworkMapAndNotary, L=Helsinki, C=FI",
    "inputs": [],
    "outputs": [
      {
        "data": {...},
        "contract": "com.template.contract.ServiceContract",
        "notary": "O=NetworkMapAndNotary, L=Helsinki, C=FI",
        "encumbrance": null,
        "constraint": {
          "@class": "net.corda.core.contracts.AlwaysAcceptAttachmentConstraint"
        }
      }
    ],
    "commands": [
      {
        "value": {
          "@class": "com.template.contract.ServiceContract$Commands$IssueService"
        },
        "signers": [
          "GfHq2tTVk9z4eXgyVMCDbvndZWywoFqaPKbGgxeqVUEVBYgpNTqFTqc7mVqe",
          "GfHq2tTVk9z4eXgyWB97whuGdtsB8c7EByHbsTxkdsNq695JX8PKSwDPq3d9"
        ]
      }
    ],
    "timeWindow": null,
    "attachments": [
      "17B22D590137C675AC1B61B7052CCEF739AA36223865BBFF707E6CB2F933FBF0"
    ],
    "references": [],
    "privacySalt": "0AFC86A1BBF6D897CCC5AA56F0FC0474DE4CD618FF040BAA96293BAA1BCDBCAF",
    "networkParametersHash": "31AF29974115E6BE4418C4080F58DFD77F301E45DC35A05DB855B0D1B25966B2"
  },
  "signatures": [...]
}

1 个答案:

答案 0 :(得分:1)

在Azure部署中,您正在devMode=false中运行node.conf吗?

您的代码可能是由corda dev密钥签名的,而后者只能在开发模式下使用(因为该密钥不安全),这意味着已部署的节点未加载您的CorDapp。

为了测试在Azure部署中是否存在此问题,您可以尝试将此行添加到node.conf

cordappSignerKeyFingerprintBlacklist=[]

默认情况下,Corda dev键在该列表中,列表中的空白将导致您的应用程序被加载。有关更多信息,请参见https://docs.corda.net/corda-configuration-file.html#corda-configuration-file-signer-blacklist

您可以在此处阅读有关签名罐子的更多信息:

https://docs.corda.net/cordapp-build-systems.html?highlight=signed#signing-the-cordapp-jar