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