Corda事务是否可以引用状态作为输入而不使用它?

Corda事务是否可以引用状态作为输入而不使用它?,corda,Corda,在Corda中,有没有一种方法可以引用事务中未使用的状态而不使用它?其目的是允许合同在被称为验证方法的一部分的状态下使用某些信息。目前在Corda中没有对此模式的内置支持,但它将被添加到Corda 4中(参见下面罗杰的回答)。目前,您有几个选择: 编写州合同以允许这种行为: 您可以向契约中添加一个命令,该命令强制要求要引用的状态类型的每个输入都有一个匹配的输出。这保证了事务只引用状态,而不是修改状态。以下是一个例子: class MyContract : Contract { overr

在Corda中,有没有一种方法可以引用事务中未使用的状态而不使用它?其目的是允许合同在被称为
验证
方法的一部分的状态下使用某些信息。

目前在Corda中没有对此模式的内置支持,但它将被添加到Corda 4中(参见下面罗杰的回答)。目前,您有几个选择:

编写州合同以允许这种行为:

您可以向契约中添加一个命令,该命令强制要求要引用的状态类型的每个输入都有一个匹配的输出。这保证了事务只引用状态,而不是修改状态。以下是一个例子:

class MyContract : Contract {
    override fun verify(tx: LedgerTransaction) {
        val command = tx.commands.requireSingleCommand<MyContract.Commands>()
        when (command.value) {
            is Commands.Reference -> requireThat {
                val inputs = tx.inputsOfType<MyState>()
                val outputs = tx.outputsOfType<MyState>()
                // Assuming `MyState.equals` has been overridden appropriately.
                "There must be a matching output state for each input state" using
                        (inputs.toSet() == outputs.toSet())
            }
        }
    }

    interface Commands : CommandData {
        class Reference: Commands
    }
}
然后,可以在合同的verify方法中检查此状态的内容。例如:

class MyContract : Contract {
    override fun verify(tx: LedgerTransaction) {
        val command = tx.commands.requireSingleCommand<MyContract.Commands>()
        when (command.value) {
            is Commands.Reference -> requireThat {
                val commandData = command.value as Commands.Reference
                val referenceState = commandData.referenceStateAndRef.state.data
                val inputs = tx.inputsOfType<MyState>()
                "The input state contents must match the reference data" using
                        (inputs.all { it.contents == referenceState.contents })
            }
        }
    }

    interface Commands : CommandData {
        class Reference(val referenceStateAndRef: StateAndRef<MyState>): Commands
    }
}
val referenceCommand = ledgerTransaction.commandsOfType<Reference>().single()
val referenceStateAndRef = referenceCommand.value.referenceStateAndRef
val actualStateAndRefFromVault = serviceHub.toStateAndRef<MyState>(referenceStateRef)
if (referenceStateAndRef != actualStateAndRefFromVault) {
    throw FlowException("Referenced state does not match state in the vault.")
}
class MyContract:合同{
覆盖验证(tx:LedgertTransaction){
val command=tx.commands.requireSingleCommand()
何时(命令值){
是Commands.Reference->requireThat{
val commandData=command.value作为Commands.Reference
val referenceState=commandData.referenceState和f.state.data
val inputs=tx.inputsOfType()
“输入状态内容必须与参考数据匹配”,使用
(inputs.all{it.contents==referenceState.contents})
}
}
}
接口命令:CommandData{
类引用(val referenceStateAndRef:StateAndRef):命令
}
}
使用这种方法,您还必须在流中检查引用状态是否与分类账上的实际状态相同(即,交易的提议者没有添加虚假的状态对象作为引用)。例如:

class MyContract : Contract {
    override fun verify(tx: LedgerTransaction) {
        val command = tx.commands.requireSingleCommand<MyContract.Commands>()
        when (command.value) {
            is Commands.Reference -> requireThat {
                val commandData = command.value as Commands.Reference
                val referenceState = commandData.referenceStateAndRef.state.data
                val inputs = tx.inputsOfType<MyState>()
                "The input state contents must match the reference data" using
                        (inputs.all { it.contents == referenceState.contents })
            }
        }
    }

    interface Commands : CommandData {
        class Reference(val referenceStateAndRef: StateAndRef<MyState>): Commands
    }
}
val referenceCommand = ledgerTransaction.commandsOfType<Reference>().single()
val referenceStateAndRef = referenceCommand.value.referenceStateAndRef
val actualStateAndRefFromVault = serviceHub.toStateAndRef<MyState>(referenceStateRef)
if (referenceStateAndRef != actualStateAndRefFromVault) {
    throw FlowException("Referenced state does not match state in the vault.")
}
val referenceCommand=ledgerTransaction.commandsOfType().single()
val referenceStateAndRef=referenceCommand.value.referenceStateAndRef
val ActualStateAndRefromVault=serviceHub.toStateAndRef(参考StateRef)
如果(referenceStateAndRef!=实际状态AndRefromVault){
抛出FlowException(“引用的状态与vault中的状态不匹配。”)
}

参考州将添加到Corda版本4中,该版本将于今年晚些时候发布。这就解决了上述问题。见:


如果我们的保险库中不存在该州,但它是投标人及其交易对手保险库中存在的参考州,该怎么办。最后一步有必要吗?遍历链不一定能保证状态来自有效链吗?如果您的vault中还没有该状态,这将是另一种选择-遍历状态链以检查其是否有效。现在已添加引用状态,请参见下面的答案。链接已失效。master的内容已被删除。您可以在此处找到更多信息->