Corda 教程-你好,世界!第2部分问题

Corda 教程-你好,世界!第2部分问题,corda,Corda,我试图遵循第二个Hello World教程,但收到了这个错误消息,有什么建议吗 找不到com.template.IOUContractnull的合同附件。看见https://docs.corda.net/api-contract-constraints.html#debugging 查看github中的教程答案,源代码与指令有许多不同之处(可能有bug),指令似乎更有意义 这将编译并部署ok。当我尝试创建一个新的借条时,它没有这样做 提前谢谢 这是我的档案: 流量.kt package com.

我试图遵循第二个Hello World教程,但收到了这个错误消息,有什么建议吗

找不到com.template.IOUContractnull的合同附件。看见https://docs.corda.net/api-contract-constraints.html#debugging

查看github中的教程答案,源代码与指令有许多不同之处(可能有bug),指令似乎更有意义

这将编译并部署ok。当我尝试创建一个新的借条时,它没有这样做

提前谢谢

这是我的档案:

流量.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))
    }
}

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)
}
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))
        }
    }
}
模板合同.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))
    }
}

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)
}
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))
        }
    }
}
package com.template.contracts
导入com.template.states.ioState
导入net.corda.core.contracts.CommandData
导入net.corda.core.contracts.Contract
导入net.corda.core.contracts.requireSingleCommand
导入net.corda.core.transactions.LedgerTransaction
导入net.corda.core.contracts*
// ************
//*合同*
// ************
I类合同:合同{
伴星{
const val ID=“com.template.IOUContract”
}
类Create:CommandData
覆盖验证(tx:LedgertTransaction){
val command=tx.commands.requireSingleCommand()
要求{
使用(tx.inputs.isEmpty())的“发出时无输入”
使用(tx.outputs.size==1)的“IoState类型的一个输出”
val output=tx.outputsOfType().single()
使用(output.value>0)“IOU值必须为非负”
使用(output.lender!=output.border)时“借款人和贷款人不能相同”
val expectedSigners=listOf(output.借入者.owningKey,output.贷款人.owningKey)
使用(command.signers.toSet().size==2)的“必须是两个签名者”
使用(command.signers.containsAll(expectedSigners))
}
}
}

我认为您的节点的
cordapps
文件夹中没有
contracts
jar文件。
我假设您正在本地运行教程(即
deployNodes
然后
runNodes
);确保您的节点(在task
deployNodes
下的根
build.gradle
文件中定义)具有
contracts
模块依赖关系(即
cordapp项目(“:contracts”)

顺便说一句,我不知道您示例中的
合同
模块的确切名称;确保正确(如果不正确,gradle会给您一个错误)。

发现问题

我认为这是说明中的一个错误:

指定:
const val ID=“com.template.IOUContract”

它应该在哪里:
const val ID=“com.template.contracts.IOUContract”

:(


R3至少应该对他们的教程做出正确的说明

感谢您的帮助。-这不是很有帮助-我的部署节点有:
节点{name“O=PartyA,L=London,C=GB”p2pPort 10005 rpcSettings{address(“localhost:10006”)adminAddress(“localhost:10046”)}rpcUsers=[[用户:“用户1”、“密码”:“测试”、“权限”:[“所有”]]}
节点故障{projectCordapp{deploy=false}cordapp项目(':contracts')cordapp项目(':workflows')}
-我相信其中包括合同。在
/build/nodes/PartyA/cordapps
中,我有
合同-0.1.jar