You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Corda中含不同参与者集合的多状态交易可行性问询

解答:单笔交易能否包含多状态且各状态参与者不同?

当然可以!这种在一笔交易里发行多个拥有不同参与者集合状态的场景,在类似Corda的区块链平台中是完全支持的,而且也是实际开发中很常见的需求(比如一次性发行多份不同参与方的凭证、资产)。

针对你的示例场景,我来拆解下具体怎么实现:

核心思路

你的需求是:

  • 状态1需要ALICE和BOB签名
  • 状态2需要BOB和CHARLIE签名
  • 把这两个状态放到同一笔交易里发行

关键要保证:交易中包含所有必要的签名者,且合约验证逻辑能正确检查每个状态的签名要求。这里有两种常见实现方式:


方式1:单个Command包含所有签名者

把所有需要签名的参与者(ALICE、BOB、CHARLIE)都加入同一个Command的签名列表,这样交易完成后所有必要的签名都能被覆盖:

val state1 = ExampleState(ALICE, BOB)
val state2 = ExampleState(BOB, CHARLIE)
// 收集所有需要签名的参与者公钥
val requiredSigners = listOf(ALICE, BOB, CHARLIE).map { it.owningKey }
val command = Command(ExampleCommand.Issue(), requiredSigners)

val transaction = TransactionBuilder(NOTARY)
    .addOutputState(state1, EXAMPLE_CONTRACT_ID)
    .addOutputState(state2, EXAMPLE_CONTRACT_ID)
    .addCommand(command)

方式2:为每个状态添加独立的Command

如果希望更清晰地对应每个状态的签名需求,也可以为每个状态单独添加Command,每个Command绑定对应的参与者:

val state1 = ExampleState(ALICE, BOB)
val state2 = ExampleState(BOB, CHARLIE)

// 对应状态1的签名者:ALICE + BOB
val commandForState1 = Command(ExampleCommand.Issue(), listOf(ALICE, BOB).map { it.owningKey })
// 对应状态2的签名者:BOB + CHARLIE
val commandForState2 = Command(ExampleCommand.Issue(), listOf(BOB, CHARLIE).map { it.owningKey })

val transaction = TransactionBuilder(NOTARY)
    .addOutputState(state1, EXAMPLE_CONTRACT_ID)
    .addOutputState(state2, EXAMPLE_CONTRACT_ID)
    .addCommand(commandForState1)
    .addCommand(commandForState2)

合约验证逻辑配合

不管用哪种方式,你的ExampleContract里的verify函数都需要正确检查每个状态的签名是否符合要求。比如用方式1的话,合约可以这么写:

override fun verify(tx: LedgerTransaction) {
    // 获取交易中所有Issue命令的签名者集合
    val allSigners = tx.commandsOfType<ExampleCommand.Issue>()
        .flatMap { it.signers }
        .toSet()

    // 遍历每个输出状态,确保其所有参与者都已签名
    tx.outputsOfType<ExampleState>().forEach { state ->
        require(state.participants.all { allSigners.contains(it.owningKey) }) {
            "状态的所有参与者必须签署此交易"
        }
    }
}

如果用方式2,合约可以更精准地检查每个状态是否有对应的Command签名:

override fun verify(tx: LedgerTransaction) {
    val issueCommands = tx.commandsOfType<ExampleCommand.Issue>()

    tx.outputsOfType<ExampleState>().forEach { state ->
        // 检查是否存在一个Command包含该状态的所有参与者签名
        val hasValidSignature = issueCommands.any { command ->
            state.participants.all { command.signers.contains(it.owningKey) }
        }
        require(hasValidSignature) {
            "状态 ${state} 的参与者未完成必要签名"
        }
    }
}

只要按照上面的方式实现,这笔交易就能正常执行,完全满足你的需求。

内容的提问来源于stack exchange,提问作者Matthew Layton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:43:46