kotlin - Corda - 包含该软件包的 CorDapp 不止一个

标签 kotlin corda

我正在构建一个需要多个 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扩展 ExampleContractGreetingState扩展 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.gradleAppCorDapp - ContractcordaCompile project(":libcordapp-contract") .
在您当前的依赖设置中(即使用 cordapp ),libcordapp-contract被包含在您的 CorDapp 的 jar 文件中,因此当您运行测试时,可以在 2 个位置找到该包:LibCorDapp - ContractAppCorDapp - Contract CorDapps;如果将依赖项更改为 cordaCompile ,该包将只包含在LibCorDapp - Contract的jar文件中CorDapp。

关于kotlin - Corda - 包含该软件包的 CorDapp 不止一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63781659/

相关文章:

enterprise - 如何运营 corda 企业

android - 已弃用 API 29 的 "getBitmap"。任何替代代码?

android - 通过ForegroundService获取位置时应用崩溃

Corda - 自 Corda 4 升级以来测试接受器流程失败

gradle - 使用 gradle 构建 cordapp 示例

kotlin - 发行人赎回另一方持有的可替代代币

kotlin - 使用 Quarkus/Kotlin 上传多部分文件

Kotlin 通用接口(interface)解析器

nullpointerexception - Android Things:在Raspberry PI 3上通过USB UART接收数据时出现NullPointerException

corda - CollectSignaturesFlow 中的流异常