我正在构建一个需要多个 CorDapps 的应用程序;我们就叫他们 LibCorDapp 和 AppCorDapp , 其中 AppCorDapp 取决于 LibCorDapp (就像 CorDapp 可能依赖于 Accounts 或 Tokens SDK)。
LibCorDapp - 合约
这个 CorDapp 的目的是定义一个状态和合约的对象模型,可以开箱即用,但也可以派生出来以创建更明确的状态和合约类型。
build.gradle
cordapp {
targetPlatformVersion cordapp_platform_version
minimumPlatformVersion cordapp_platform_version
contract {
name cordapp_contract_name
vendor cordapp_vendor_name
licence cordapp_license
versionId cordapp_version_id
}
signing {
enabled = cordapp_signing_enabled
}
}
dependencies {
implementation "$kotlin_group:kotlin-stdlib-jdk8:$kotlin_version"
cordaCompile "$corda_group:corda-core:$corda_release_version"
testRuntimeOnly "$junit_group:junit-jupiter-engine:$junit_version"
testImplementation "$junit_group:junit-jupiter-api:$junit_version"
testImplementation "$kotlin_group:kotlin-test:$kotlin_version"
testImplementation "$corda_group:corda-node-driver:$corda_release_version"
}
示例状态 package com.example.libcordapp.contract
@BelongsToContract(ExampleContract::class)
open class ExampleState<T : Any>(
override val participants: List<AbstractParty> = emptyList(),
val value: T
) : ContractState { ... }
示例契约(Contract) package com.example.libcordapp.contract
open class ExampleContract {
final override fun verify(tx: LedgerTransaction) { ... }
protected open fun onVerifyCreate(tx: LedgerTransaction, signers: Set<PublicKey>) = Unit
}
注意ExampleState
之间的关系和 ExampleContract
.他们都是open
, 和 ExampleContract
包含一个可覆盖的函数,允许派生类在创建时指定额外的合约逻辑。LibCorDapp - 工作流程
这个 CorDapp 的目的是定义允许创建、更新和使用示例状态的流程。这些流还应该适用于源自
ExampleState
的状态和契约(Contract)。和 ExampleContract
.build.gradle
cordapp {
targetPlatformVersion cordapp_platform_version
minimumPlatformVersion cordapp_platform_version
workflow {
name cordapp_workflow_name
vendor cordapp_vendor_name
licence cordapp_license
versionId cordapp_version_id
}
signing {
enabled = cordapp_signing_enabled
}
}
dependencies {
implementation "$kotlin_group:kotlin-stdlib-jdk8:$kotlin_version"
cordaCompile "$corda_group:corda-core:$corda_release_version"
cordapp project(":libcordapp-contract")
testRuntimeOnly "$junit_group:junit-jupiter-engine:$junit_version"
testImplementation "$junit_group:junit-jupiter-api:$junit_version"
testImplementation "$kotlin_group:kotlin-test:$kotlin_version"
testImplementation "$corda_group:corda-node-driver:$corda_release_version"
}
示例流程 package com.example.libcordapp.workflow
class ExampleFlow(val state: ExampleState) : FlowLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
val tx = with(TransactionBuilder(notary)) {
addOutputState(state)
addCommand(ExampleContract.Issue, signers)
}
}
}
请注意,我没有明确定义输出状态的合约 ID,因为它应该在运行时为每个合约/状态对确定。AppCorDapp - 合约
这个 CorDapp 的目的是演示一个使用 的应用程序示例。 LibCorDapp ,创建和测试派生状态和契约(Contract)。
build.gradle
cordapp {
targetPlatformVersion cordapp_platform_version
minimumPlatformVersion cordapp_platform_version
contract {
name "Test CorDapp Contract"
vendor cordapp_vendor_name
licence cordapp_license
versionId cordapp_version_id
}
signing {
enabled = cordapp_signing_enabled
}
}
dependencies {
implementation "$kotlin_group:kotlin-stdlib-jdk8:$kotlin_version"
implementation "$corda_group:corda-core:$corda_release_version"
cordapp project(":libcordapp-contract")
testRuntimeOnly "$junit_group:junit-jupiter-engine:$junit_version"
testImplementation "$junit_group:junit-jupiter-api:$junit_version"
testImplementation "$kotlin_group:kotlin-test:$kotlin_version"
testImplementation "$corda_group:corda-node-driver:$corda_release_version"
}
GreetingState package com.example.appcordapp.contract
@BelongsToContract(GreetingContract::class)
class GreetingState(
participants: List<AbstractParty> = emptyList()
value: String = "Hello, World!"
) : ExampleState<String>(participants, value)
问候契约(Contract)package com.example.appcordapp.contract
class GreetingContract : ExampleContract {
override fun onVerifyCreate(tx: LedgerTransaction, signers: Set<PublicKey>) = requireThat { ... }
}
请注意 GreetingContract
扩展 ExampleContract
和 GreetingState
扩展 ExampleState
以及定义GreetingContract
因为它是相关契约(Contract),所以在创建 GreetingState
时使用 ExampleFlow
它应该拿起这份契约(Contract)。中实际上没有定义流。 AppCorDapp - 工作流程 模块,因为我明确想测试我可以使用
ExampleFlow
与我派生的状态/契约(Contract)对。测试与问题
对于我的测试,我定义了以下 cordapps:
cordappsForAllNodes = listOf(
TestCordapp.findCordapp("com.example.libcordapp.contract"),
TestCordapp.findCordapp("com.example.libcordapp.workflow"),
TestCordapp.findCordapp("com.example.appcordapp.contract")
)
在尝试创建 GreetingClaim
使用 ExampleFlow
...ExampleFlow(GreetingClaim(participants = listOf(partyA)))
...我得到以下异常:java.lang.IllegalArgumentException: There is more than one CorDapp containing the package com.example.appcordapp.contract on the classpath [/.../libcordapp-contract-0.1.jar, /.../libcordapp-workflow-0.1.jar]. Specify a package name which is unique to the CorDapp.
我假设这要么归结为 gradle,要么与我使用派生状态和契约(Contract)的事实有关?
最佳答案
阅读有关 dependencies 的官方文档,并阅读 this answer ;建议你改cordapp project(":libcordapp-contract")
里面 build.gradle
的 AppCorDapp - Contract
至cordaCompile project(":libcordapp-contract")
.
在您当前的依赖设置中(即使用 cordapp
),libcordapp-contract
被包含在您的 CorDapp 的 jar 文件中,因此当您运行测试时,可以在 2 个位置找到该包:LibCorDapp - Contract
和 AppCorDapp - Contract
CorDapps;如果将依赖项更改为 cordaCompile
,该包将只包含在LibCorDapp - Contract
的jar文件中CorDapp。
关于kotlin - Corda - 包含该软件包的 CorDapp 不止一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63781659/