【问题标题】:In a Corda transaction are particular state transitions associated with partcular commands?在 Corda 事务中,特定的状态转换是否与特定命令相关联?
【发布时间】:2018-03-06 20:09:20
【问题描述】:

commands webinar 声明(在 3:10 左右)“输入和输出状态始终按类型分组,并且每个组都需要一个命令。”叙述者似乎暗示,如果一个事务由多个命令组成,那么每个命令将与事务中提出的状态转换的不同子集相关联。

但是,LedgerTransaction 的结构中似乎没有捕捉到这样的观点。它由完全独立的inputsoutputscommands 列表组成。没有任何东西表示特定命令与特定输入或输出状态之间的关联。

在我的合同代码中,我可以按类型对状态进行分组,例如:

override fun verify(tx: LedgerTransaction) {
    val fooStates = tx.inputsOfType<FooState>()
    val barStates = tx.inputsOfType<BarStates>()

但我只是根据选择进行分组 - 我不必这样做,并且没有将这些组与特定命令联系起来。

那么当网络研讨会说“每个组都需要一个命令”时,它指的是什么?

如果命令和状态转换之间的关系如网络研讨会所述那样存在,签名与命令相关联的意义就很清楚了。但实际上,由于LedgerTransaction 类没有捕获此类关系,因此不会在每个命令的基础上签署特定的转换。

section on commands 的关键概念中,有一个优惠券命令和一个支付命令,因此必须在债券状态转换上签字的人可能与需要在债券状态转换上签字的人不同。现金状态转换。但是在代码中,没有任何东西将优惠券命令与与命令关联的签名者在签名时同意的特定状态联系起来。

这个规定要求每个组必须有一个相关联的命令,只是开发人员应该在他们的合约验证逻辑中实现的东西,而不是试图捕获的东西交易结构?

【问题讨论】:

    标签: corda


    【解决方案1】:

    好问题。

    您谈到了合同中的分组,这是正确的,它取决于合同的实施,您只需要进一步扩展它以根据交易中的命令强制执行哪些方需要签名。

    因此,您的验证函数可能类似于以下 Option CorDapp 示例中的合同简化版本:

    覆盖 fun verify(tx: LedgerTransaction) {

        val command = tx.commands.requireSingleCommand<Commands>()
    
        when (command.value) {
            is Commands.Issue -> {
                requireThat {
                    val cashInputs = tx.inputsOfType<Cash.State>()
                    val cashOutputs = tx.outputsOfType<Cash.State>()
                    "Cash.State inputs are consumed" using (cashInputs.isNotEmpty())
                    "Cash.State outputs are created" using (cashOutputs.isNotEmpty())
    
                    val option = tx.outputsOfType<OptionState>().single()
                    "The issue command requires the issuer's signature" using (option.issuer.owningKey in command.signers)
                }
            }
    
            is Commands.Trade -> {
                requireThat {
                    val cashInputs = tx.inputsOfType<Cash.State>()
                    val cashOutputs = tx.outputsOfType<Cash.State>()
                    "Cash.State inputs are consumed" using (cashInputs.isNotEmpty())
                    "Cash.State outputs are created" using (cashOutputs.isNotEmpty())
    
                    val inputOption = tx.inputsOfType<OptionState>().single()
                    val outputOption = tx.outputsOfType<OptionState>().single()
                    "The transfer command requires the old owner's signature" using (inputOption.owner.owningKey in command.signers)
                    "The transfer command requires the new owner's signature" using (outputOption.owner.owningKey in command.signers)
                }
            }
    
            else -> throw IllegalArgumentException("Unknown command.")
        }
    }
    

    我们首先从事务中提取命令(或多个命令),这为我们提供了上下文。

    基于此,我们可以从输入或输出中提取我们感兴趣的状态,例如现金/期权并开始检查我们的限制是否得到满足。

    您可以在https://github.com/CaisR3/cordapp-option 找到上述示例的完整版本,合约代码可以在 base\src\main\kotlin\net\corda\option\base\contract\OptionContract.kt 中找到

    【讨论】:

    • 感谢蔡斯的回复。我感兴趣的案例(文档的关键概念部分的优惠券示例中对此进行了介绍)是一个涉及 multiple 命令的事务。尽管您的代码要求给定事务仅包含一个命令,但我认为它仍然回答了我的问题。 IE。由合约逻辑决定命令和状态之间的任何关系,而不是在交易结构本身中捕获的东西。
    • PS 也许你应该在你的 SO 个人资料中添加你是 R3 的高级助理,只是为了表明你能够对 Corda 做出相当明确的陈述:)
    • 不客气!好点,刚刚将该信息添加到我的个人资料中:)
    猜你喜欢
    • 1970-01-01
    • 2017-01-26
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 2016-04-05
    相关资源
    最近更新 更多