【问题标题】:Corda with token and accounts带有令牌和帐户的 Corda
【发布时间】:2020-06-02 23:21:24
【问题描述】:

我们正在使用 Kotlin 在 Corda 处理令牌和帐户。我将详细说明该场景以进行澄清。 我们有一个 node1 和一个 node2。 我们创建了一个从 TokenType 扩展而来的“OurTokenType”。 我们在 node1 上创建了两个账户(卖家和买家)并与 node2 共享。 根据应用程序的业务规则,node2 是发行代币(FungibleToken)的人,并且发行正常。最后,node1 和 node2 可以访问 FungibleStates 以进行发行交易。 我们的问题在于这些代币的转移。当我们尝试将代币从账户卖家转移给买家时。 在我们的场景中,令牌的转移可以发生在节点 1 或节点 2 上。 当我们通过作为账户主机的 node1 进行转账时,我们可以使用有效的 MoveFungibleTokensFlow 类,并将 node1 上的 FungibleStates 更新为正确的值。但是,当我们在observerSessions 参数中添加node2 作为观察者时,node2 上的FungibleStates 没有正确更新。 而当我们通过不是账户主机的node2进行转账时,使用MoveFungibleTokensFlow类,它不起作用,它会生成一个com.r3.corda.lib.tokens.selection.InsufficientBalanceException: Insufficient spendable的异常已识别的状态,即使是平衡的。

我的问题是,我可以使用 MoveFungibleTokensFlow 类在帐户之间转移,即使它们在另一台主机上? 而当我们在托管账户的节点上运行时,在使用observerSessions 时更新FungibleStates 的问题是什么? 或者如果我必须按照链接https://github.com/corda/samples-kotlin/tree/master/Accounts/worldcupticketbooking 的示例进行操作?

【问题讨论】:

    标签: corda


    【解决方案1】:
    • MoveFungibleTokensFlow 没有指定谁是移动令牌的来源的输入参数,这是因为它将流的发起者视为令牌的来源。
    class MoveFungibleTokensFlow
    @JvmOverloads
    constructor(
            val partiesAndAmounts: List<PartyAndAmount<TokenType>>,
            override val participantSessions: List<FlowSession>,
            override val observerSessions: List<FlowSession> = emptyList(),
            val queryCriteria: QueryCriteria? = null,
            val changeHolder: AbstractParty? = null
    ) : AbstractMoveTokensFlow() {
    
    • 你说的“node1 和 node2 都看到已发行的代币”是不正确的,在FungibleToken 中唯一的参与者是代币的holder,所以当代币发行到卖家和买家账户时,唯一的参与者是托管这些帐户的节点(即 node1)。

    • 回到我的第一点,因为只有 node1 有颁发的令牌,并且您在 node2 上运行移动流程(流程将 node2 视为令牌的来源,但 node2 没有它们);这就是您收到余额不足错误的原因。

    • 即使您在向买方和卖方发行代币时添加了 node2 作为观察者(即 node1 和 node2 都有生成的代币);如果你深入研究MoveFungibleTokensflow 的代码,它继承自AbstractMoveTokensFlow,它依赖ObserverAwareFinalityFlow 来签署交易,你会在ObserverAwareFinalityFlow 内部看到它不调用CollectSignatures 流,它只签名本地交易(见here);意味着只有持有账户私钥的节点才能签署移动命令,因为node1是买卖双方的host;那么 node1 是私钥/公钥的所有者,只有 node1 可以代表买卖双方签名。因此,即使您与 node2 共享买家和卖家账户;只有 node1 可以签名,并且由于您从 node2 调用MoveFungibleTokensFlow(您的第二种情况),当它到达需要代表卖方签名的部分(移动其令牌)时它将失败,因为 node2 没有t 拥有该帐户的私钥。
    • 附带说明,当您从 node1 调用 MoveFungibleTokesnFlow 以将卖方的代币转移到买方时;确保为queryCriteria 提供一个值,以仅选择属于卖方的代币;如果您不提供值;然后流程将选择节点 1 上托管的任何令牌,因此您最终可能会移动属于其他帐户的令牌。
    • 还要确保为changeHolder 提供一个值,这样如果您将其保留为空,则更改会返回给卖家;任何产生的更改都将分配给启动节点(即 node1)而不是帐户。
    • 您可以在 Tokens SDK 的my article 中找到许多有用的提示。
    • 另外,R3 最近发布了免费的 Corda 课程;它在 Tokens SDK 上有一个great section
    • 为了让您能够使用节点 1 或节点 2 将代币从卖方转移到买方,您必须依赖实用函数 addMoveTokens() 而不是现成流(即 MoveFungibleTokensFlow)(由于上述原因)。所以你必须自己创建交易,然后使用addMoveTokens()添加要移动的令牌,然后你必须使用CollectSignatures流收集(卖家的)签名(卖家将在响应者流中签名);您还必须负责完成交易。
    • 只是为了澄清上面的流程,你的流程应该检查它是否是卖家的主机;然后它可以在本地签名,如果它不是主机;那么您必须使用该帐户的主机创建一个FlowSession,以便您可以收集其签名(即它批准移动其持有的令牌)。
    • 示例 repo 具有使用 addMoveTokens()some examples;我建议花一些时间来探索它们。

    【讨论】:

    • 我们设法解决了这个问题。我们制作了两个流程,一个在执行节点是帐户主机时调用,另一个在执行节点与帐户主机不同时调用。在第一种情况下,我们使用辅助流 addMoveFungibleTokens 并通过 ShareStateAndSyncAccounts 与节点共享 FungibleToken (transaction.tx.outRefsOfType ())。继续...
    • 在第二种情况下,我们检索令牌的当前持有者会话,并通过响应流我们使用 DatabaseTokenSelection :: generateMove 检索令牌。在主流中,我们使用 addMoveTokens。我们以与第一种情况相同的方式与节点共享令牌。非常感谢您的澄清。
    【解决方案2】:

    让我把你的问题分成两部分:

    1. 观察者会话不会自动更新: 以下是我们如何触发观察者会话更新的示例:https://github.com/corda/samples-kotlin/blob/master/Tokens/stockpaydividend/workflows/src/main/kotlin/net/corda/samples/stockpaydividend/flows/AnnounceDividend.kt#L37 这将确保在维护者进行更新时更新观察者的令牌状态。 (注意:只有维护者才能进行更新,而不是所有者)

    2. 两方之间的可替代代币转移:是的。这是可行的。这行代码是 worldcupticketbooking 示例中 FungibleToken transfer 的开头:https://github.com/corda/samples-kotlin/blob/master/Accounts/worldcupticketbooking/workflows/src/main/kotlin/com/t20worldcup/flows/DVPAccountsHostedOnDifferentNodes.kt#L102 它肯定有效。

    我看到你提到你在InsufficientBalanceException 上有一条错误消息,如果我是你,我会从那里开始挖掘,看看正在查询哪个令牌。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      • 2016-01-10
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多