教程-世界,您好!第2页

时间:2019-11-29 00:52:46

标签: corda

我试图按照第二个Hello World教程进行操作,并收到此错误消息,有什么建议吗?

Cannot find contract attachments for com.template.IOUContractnull. See https://docs.corda.net/api-contract-constraints.html#debugging

看看github中的教程答案,源代码与说明有很多差异(可能的错误),而且说明似乎更有意义。

这可以编译和部署。当我尝试创建新的IOU时,它没有这样做。

预先感谢

这是我的文件:

Flow.kt

package com.template.flows

import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.Command
import net.corda.core.flows.*
import net.corda.core.identity.Party
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker

import com.template.states.IOUState
import com.template.contracts.IOUContract
import net.corda.core.contracts.requireThat
import net.corda.core.transactions.SignedTransaction

// *********
// * Flows *
// *********
@InitiatingFlow
@StartableByRPC
class IOUFlow(val iouValue: Int,
              val otherParty: Party) : FlowLogic<Unit>() {
    override val progressTracker = ProgressTracker()

    @Suspendable
    override fun call() {
        val notary = serviceHub.networkMapCache.notaryIdentities[0]

        val outputState = IOUState(iouValue, ourIdentity, otherParty)
        val command = Command(IOUContract.Create(), listOf(ourIdentity.owningKey, otherParty.owningKey))

        val txBuilder = TransactionBuilder(notary = notary)
                .addOutputState(outputState, IOUContract.ID)
                .addCommand(command)

        txBuilder.verify(serviceHub)

        val signedTx = serviceHub.signInitialTransaction(txBuilder)

        val otherPartySession = initiateFlow(otherParty)

        val fullySignedTx = subFlow(CollectSignaturesFlow(signedTx, listOf(otherPartySession), CollectSignaturesFlow.tracker()))

        subFlow(FinalityFlow(fullySignedTx, otherPartySession))
    }
}

@InitiatedBy(IOUFlow::class)
class IOUFlowResponder(private val otherPartySession: FlowSession) : FlowLogic<Unit>() {
    @Suspendable
    override fun call() {
        var signTransactionFlow = object : SignTransactionFlow(otherPartySession) {
            override fun checkTransaction(stx: SignedTransaction) = requireThat {
                val output = stx.tx.outputs.single().data
                "This must be an IOU transaction" using (output is IOUState)
                val iou = output as IOUState
                "IOU value can't be too high" using (iou.value < 100)

            }
        }
        val expectedTxId = subFlow(signTransactionFlow).id
        subFlow(ReceiveFinalityFlow(otherPartySession, expectedTxId))
    }
}

TemplateState.kt

package com.template.states

import com.template.contracts.IOUContract
import net.corda.core.contracts.BelongsToContract
import net.corda.core.contracts.ContractState
import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party

// *********
// * State *
// *********
@BelongsToContract(IOUContract::class)

class IOUState(val value: Int,
               val lender: Party,
               val borrower: Party) : ContractState {
    override val participants get() = listOf(lender, borrower)
}

TemplateContract.kt

package com.template.contracts

import com.template.states.IOUState
import net.corda.core.contracts.CommandData
import net.corda.core.contracts.Contract
import net.corda.core.contracts.requireSingleCommand
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.contracts.*

// ************
// * Contract *
// ************

class IOUContract : Contract {
    companion object {
        const val ID = "com.template.IOUContract"
    }

    class Create : CommandData

    override fun verify(tx: LedgerTransaction) {
        val command = tx.commands.requireSingleCommand<Create>()

        requireThat {
            "No input when issue" using (tx.inputs.isEmpty())
            "One output of type IOUState" using (tx.outputs.size == 1)

            val output = tx.outputsOfType<IOUState>().single()
            "IOU's value must be non-negative" using (output.value > 0)
            "Borrower and lender can't be the same" using (output.lender != output.borrower)

            val expectedSigners = listOf(output.borrower.owningKey, output.lender.owningKey)
            "must be two signers" using (command.signers.toSet().size == 2)
            "both must be signers" using (command.signers.containsAll(expectedSigners))
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我认为您的节​​点的contracts文件夹中没有cordapps jar文件。
我假设您正在本地运行本教程(即先运行deployNodes,然后运行runNodes);确保您的节点(在任务build.gradle下的根deployNodes文件中定义)具有contracts模块依赖性(即cordapp project(":contracts"))。
顺便说一句,在您的示例中,我不知道contracts模块的确切名称;确保您设置正确(如果不正确,渐变会给您一个错误)。

答案 1 :(得分:0)

发现了问题!

我认为这是说明中的错误: https://docs.corda.net/tut-two-party-contract.html

指定:const val ID = "com.template.IOUContract"

应位于的位置:const val ID = "com.template.contracts.IOUContract"

:(

R3至少应正确指导其教程