【问题标题】:Back tracking OwnableState in Corda在 Corda 中回溯 OwnableState
【发布时间】:2018-09-02 04:23:07
【问题描述】:

在浏览 Corda 文档时,我在link 遇到了以下 sn-p。

默认的保险库实现根据以下规则做出决定:

如果状态是 OwnableState,如果节点是 状态的所有者,保险库将存储状态 否则,如果它是参与者之一,保险库将存储状态

在我的流程中,

  1. 我正在使用实现 OwnableState 的状态类从节点 A 向节点 B 发放/发送现金。
  2. 我将节点 B 设为所有者。
  3. 我用节点 A 和节点 B 都填充了参与者字段

我能够在节点 B 中看到新状态但在节点 A 中看不到。 我尝试查询终端上的状态(它只显示未使用的状态)以及通过添加标准为status = vault.StateStatus.ALL 来使用保险库查询API。

这是否意味着,我永远也做不到

  • 跟踪现金从哪里进入节点 B ?
  • 跟踪节点 A 中的现金去向?

代码示例如下: 状态类:

package com.shailesh

import net.corda.core.contracts.CommandAndState
import net.corda.core.contracts.OwnableState
import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable
import net.corda.finance.contracts.asset.Cash

@CordaSerializable
data class MyPersistentState(val amount: Int, val sender : AbstractParty, val receiver : AbstractParty) : OwnableState {

    override val owner: AbstractParty
        get() = receiver

    override val participants: List<AbstractParty> = listOf(sender, receiver)
}

流类:

package com.shailesh

import co.paralleluniverse.fibers.Suspendable
import com.shailesh.PersistenceDemoContract.Companion.id
import net.corda.core.contracts.Contract
import net.corda.core.flows.FinalityFlow
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatingFlow
import net.corda.core.flows.StartableByRPC
import net.corda.core.identity.Party
import net.corda.core.node.services.Vault
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker
import net.corda.finance.DOLLARS
import net.corda.finance.contracts.asset.CASH
import net.corda.finance.contracts.asset.Cash

@InitiatingFlow
@StartableByRPC
class PersistenceDemoFlow(val amount: Int, val receiver : Party) : FlowLogic<Unit>() {

    override val progressTracker: ProgressTracker = ProgressTracker()

    @Suspendable
    override fun call() {
        val notary = serviceHub.networkMapCache.notaryIdentities.first()

        val qc = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL)

        // I expect that result should show me the states in Node A when A issues state to B
        val result: Vault.Page<MyPersistentState> = serviceHub.vaultService.queryBy(contractStateType = MyPersistentState::class.java, criteria = qc)

        val outputState = MyPersistentState(amount, ourIdentity, receiver)
        val tx = TransactionBuilder(notary).addOutputState(outputState, id).addCommand(Cash.Commands.Issue(), listOf(ourIdentity.owningKey))
        tx.verify(serviceHub)
        val signedTx = serviceHub.signInitialTransaction(tx)
        subFlow(FinalityFlow(signedTx))
    }
}

@CordaSerializable
class PersistenceDemoContract: Contract {
    companion object {
        val id = "com.shailesh.PersistenceDemoContract"
    }
    override fun verify(tx: LedgerTransaction) {

    }
}

查询和发出状态的命令:

// Check states
run vaultQuery contractStateType: com.shailesh.MyPersistentState
// Start the issue flow on Node A
flow start com.shailesh.PersistenceDemoFlow amount: 100, receiver: "O=PartyB,L=New York,C=US"

【问题讨论】:

    标签: corda


    【解决方案1】:

    您的流程直接向接收者发出一个状态,其中没有inputs 和一个output - 这是将记录在接收者(所有者)的保险库中的唯一未使用状态。

    状态是凭空产生的,并被插入到接收器的保险库中。首先没有消耗任何东西来创建这种状态。因此,尽管在发送方对已消费/未消费进行查询,但它什么也没返回。

    如果您想跟踪它的发行来源,请通过将发行者设为初始所有者来对状态进行self-issue。然后通过在输入上消耗状态并将其重新分配给具有未消耗状态的输出并重新分配新所有者,将其发送给接收器。

    【讨论】:

    • 感谢您的回复。这是否意味着,当我们使用 OwnableState 时,参与者字段没有我引用的文档中所述的角色。因为,如果我使用具有相同流和参与者内容的 LinearState 而不是 OwnableState,节点 A 和节点 B 都能够看到它们的保险库中的状态。
    • 这并不意味着完全没有角色,您可以在OwnableState的参与者字段中添加参与方,以强制某些参与方需要签署此交易以便状态转移所有权signers == participants
    【解决方案2】:

    扩展 Adrian 的回答,原始问题询问是否对于 OwnableState

    我永远做不到

    跟踪节点 B 的现金来自哪里?

    跟踪节点 A 中的现金去哪儿了?

    此外,在 cmets 中,会询问 participants 字段对于 OwnableState 的重要性。

    participants 字段的重要性在于,所有participants 都将接收并记录创建新状态的事务副本作为FinalityFlow 的一部分。正是这种交易,而不是状态本身,才允许随着时间的推移建立一连串的现金流动。

    在 Corda 中区分谁记录事务(所有participants)和谁记录状态(owner 用于OwnableState,否则所有participants)是很重要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 2018-07-07
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      相关资源
      最近更新 更多