当前位置: 首页 > 知识库问答 >
问题:

Corda将代币从一个帐户移动到另一个方(帐户托管在不同方)

刘曾琪
2023-03-14

除公证人外,我们的Corda网络还有3个节点。图中显示了每个节点应执行的操作。

只有在这种情况下,我们才会遇到“需要将令牌从帐户持有人转移到乙方”的麻烦

流程代码:


    class TransferETokenDiffNodeFlow(val actualHolder: AbstractParty,
                                     val newHolder: AbstractParty,
                                     val numEtokens: Double,
                                     val observables: MutableList = mutableListOf()) :
            FlowLogic() {
    
        private fun notary() = serviceHub.networkMapCache.notaryIdentities.first()
    @Suspendable
    override fun call(): SignedTransaction {
    
        progressTracker.currentStep = INITIALIZING
        val txBuilder = TransactionBuilder(notary())
    
        val actualHolderStateRef = accountService.accountInfo(actualHolder.owningKey)
                ?: throw AccountNotFoundException("Account not found exception.")
        val actualHolderInfo = actualHolderStateRef.state.data
    
        val actualHolderSession = initiateFlow(actualHolderInfo.host)
    
        actualHolderSession.send(numEtokens)
        actualHolderSession.send(actualHolder)
        actualHolderSession.send(newHolder)
    
        val inputs = subFlow(ReceiveStateAndRefFlow(actualHolderSession))
        val tokens: List = actualHolderSession.receive>().unwrap { it -> it}
    
        progressTracker.currentStep = BUILDING
        addMoveTokens(txBuilder, inputs, tokens)
    
        progressTracker.currentStep = SIGNING
        val initialSignedTrnx = serviceHub.signInitialTransaction(txBuilder)
    
        progressTracker.currentStep = GATHERING_SIGS
        val fulySignedTx= subFlow(CollectSignaturesFlow(initialSignedTrnx, listOf(actualHolderSession)))
    
        progressTracker.currentStep = FINALISING_CREATE
        val stx = subFlow(FinalityFlow(fulySignedTx, listOf(actualHolderSession)))
    
        progressTracker.currentStep = FINALISING
        val statesTx = stx.tx.outRefsOfType()
        statesTx.forEach { state ->
            observables.forEach { observable ->
                subFlow(ShareStateAndSyncAccounts(state, observable))
            }
        }
    
        return stx
    }
    }
    
    
    //ResponderFlow code:
    class TransferETokenDiffNodeFlowResponder(val counterpartySession: FlowSession) : FlowLogic() {
    @Suspendable
    override fun call(): SignedTransaction {
    
        val numEtokens = counterpartySession.receive().unwrap { it }
        val actualHolder = counterpartySession.receive().unwrap { it }
        val newHolder = counterpartySession.receive().unwrap { it }
    
        val partyAndAmount = PartyAndAmount(newHolder, numEtokens of EnergyTokenType.getInstance("ENERGY"))
    
        val actualHolderStateRef = accountService.accountInfo(actualHolder.owningKey)
                ?: throw AccountNotFoundException("Account not found exception.")
        val actualHolderInfo = actualHolderStateRef.state.data
        val criteria = QueryCriteria.VaultQueryCriteria(externalIds = listOf(actualHolderInfo.identifier.id),
                status = Vault.StateStatus.UNCONSUMED)
    
        val selector = DatabaseTokenSelection(serviceHub)
    
        val (inputs, outputs) = selector.generateMove(listOf(partyAndAmount).toPairs(),
                actualHolder, TokenQueryBy(queryCriteria = criteria), runId.uuid)
    
        subFlow(SendStateAndRefFlow(counterpartySession, inputs))
    
        counterpartySession.send(outputs)
    
        subFlow(object : SignTransactionFlow(counterpartySession) {
            @Throws(FlowException::class)
            override fun checkTransaction(stx: SignedTransaction) {
            }
        })
    
        return subFlow(ReceiveFinalityFlow(counterpartySession))
    }
    }

我们需要在C方执行流程,实际持有人是账户持有人,新持有人是乙方。

使用此代码,将返回一个错误:net.corda.core.CordaRuntime 异常:java.lang.非法描述异常:未为以下事务参与者提供流会话:[O = B 方,L = 库里蒂巴,C = BR]

但是如果我更改代码并添加乙方会话,它会返回错误:java.lang.IllegalArgumentException:CollectSignaturesFlow的启动器必须准确传入签署交易所需的会话。

问题是,为什么添加移动令牌不将新持有者作为必需的签名者?我该如何解决这个问题?

共有1个答案

漆雕誉
2023-03-14

在你的代码中有很多要点需要讨论;让我们从错误开始:

  1. When you move tokens, the only required signer is the current holder; so in your case you should pass only one FlowSession which is the session with PartyA (since it's the holder of the tokens); so you should only have:
    CollectSignaturesFlow(initialSignedTrnx, listOf(actualHolderSession))
    
    FinalityFlow(fulySignedTx, listOf(actualHolderSession, partyB))
    

    现在转到其他主题:

    >

  2. 我不建议一方移动另一方持有的代币。想象一下,你在自己的账户中拥有资金,我从你的账户中取出这些资金。应该是持有启动移动的令牌的节点。实际上,这就是SDK就绪流的操作方式。

    如果您查看AbstractMoveTokensFlow,您会看到他们仅通过依赖ObserverAware FinalityFlow在本地签署交易(参见此处);为了确认这一点,您可以看到在ObserverAware FinalityFlow内部没有CollectSignaturesFlow(即它不请求其他节点的签名),仅在本地签署(参见此处)。

    这一切意味着,如果您使用SDK的就绪流来移动由不同于调用移动流的节点的节点持有的令牌;你会得到一个错误,因为需要持有者的签名,但是就绪流不从其他节点收集签名,只从调用移动流的节点收集签名,而不是令牌的持有者。

    我建议遵循SDK的方法,因为只有代币的持有者才能移动他们的代币。

    帐户库留档提到的另一件事是不要混合使用帐户和非帐户(即只从一个帐户移动到另一个帐户或从一方移动到另一方);建议为您的节点创建一个“默认”帐户(例如,创建一个名称与您的节点的X500名称匹配的帐户),请在此处阅读。

 类似资料:
  • 我在AWS云服务中设置了一个项目。在那里我使用了EC2实例、AMI、弹性IP、互联网门路、NACL、路由表、安全组、自定义VPC、私有和公共子网、弹性负载平衡、自动伸缩、启动配置、KMS-key、Lambda、RDS Aurora实例、S3桶、简单电子邮件服务、简单队列服务、简单通知服务、云观察日志。现在我的客户要求将所有服务从现有的AWS帐户迁移到新的AWS帐户。

  • 在 Corda 帐户库中,为了将帐户的主机“所有权”从一个节点更改为另一个节点,需要将处于 AccountInfo 状态的更改为新主机(节点),并共享与此帐户相关的所有保管库状态。 AccountInfo没有更新命令(AccountInfos命令),这意味着您无法在创建主机后更改主机。 < li >此功能是否因任何原因被排除?是否有计划引入更新命令(以及支持流)? < li >移动/转移(主机所有

  • 我有两个帐户和两个线程。1个线程将钱从1个帐户转到2个帐户,2个线程将钱从2个帐户转到1个帐户,当然前提是有足够的钱。我需要了解死锁情况,并解决死锁情况以确认安全转移。以下是我目前的想法: 账户.java 主类 传输线程.java 为了安全转移,我决定将存款和取款两种方法同步。但怀疑用方法运行实现。我有正确的实现吗?如果不是,解释和纠正将不胜感激。

  • 我们不允许寻求书籍、工具、软件库等推荐的问题。你可以编辑这个问题,以便用事实和引用来回答。 有没有任何API可以让我们自动将钱转入其他银行账户?我只发现我无法使用PayPal API完成。 我在一个银行帐户上有用户资金,在应用程序中执行一些操作后,我需要将此资金转移到其他用户银行帐户。 总结一下,一步一步: > 用户1向申请银行账户汇款。 几个小时后,用户1通过单击按钮确认应用程序的某些操作。 在

  • 我使用Corda token sdk和Corda帐户。(Corda_version = 4.1,tokens_version = 1.0,accounts_version = 1.0-rc04) 我刚刚构建了一个简单的场景: Flow_1.PartyA节点创建帐户“lisa” Flow_2。PartA-节点向自身颁发令牌 Flow_3。部分节点将令牌移动到“lisa” 但是,当我启动Flow_3时