Corda交易能否引用一个状态作为输入而不消耗它?

3
在Corda中,是否有一种不花费状态的方式来引用交易中的未使用状态?目的是允许合约在verify方法中使用被引用状态中的某些信息。
2个回答

4

1
链接已失效。Master的内容已被删除。 - opticyclic
你可以在这里找到更多信息 -> https://docs.corda.net/design/reference-states/design.html - Priyav Shah

1

目前Corda不支持此模式的内置支持,但将在Corda 4中添加(请参见下面Roger的答案)。目前,您有几个选择:

编写状态合约以允许此行为:

您可以向合约添加一个命令,强制执行要求每个输入都有与之匹配的输出的要求。这确保了交易只引用状态,而不是修改它。以下是一个示例:

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
    }
}

将状态作为输入状态、输出状态或命令中的字段进行引用:

您可以将参考状态作为输入状态、输出状态或命令的字段包含在交易中。命令可能是最合适的选择:

interface Commands : CommandData {
    class Reference(val referenceState: MyState): Commands
}

然后您可以在合约的验证方法中检查此状态的内容。例如:

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.")
}

1
如果状态在我们的保险库中不存在,但它是提议者和其交易对手保险库中存在的参考状态,那么最后一步是否必要?沿着链条行走难道不会本质上保证该状态来自有效的链条吗? - Rickky13
1
如果您的保险库中没有状态,那么这将是一种替代方法 - 沿着状态链进行检查以确保其有效。 - Joel
现在已经添加了参考状态。 - Roger Willis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接