Corda将代币从一个帐户移动到另一方(托管在另一方的帐户)
除了公证人外,我们的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)) } } 类TransferTokenDiffNodeFlow(val-actualHolder:AbstractParty, 瓦尔·纽霍尔德:抽象党, 瓦尔·努梅托肯斯:双倍, val可观测值:MutableList=mutableListOf()): FlowLogic(){ private fun公证人()=serviceHub.networkMapCache.NotaryIdentity.first() @暂停 重写趣味调用():SignedTransaction{ progressTracker.currentStep=正在初始化 val txBuilder=TransactionBuilder(公证人()) val actualHolderStateRef=accountService.accountInfo(actualHolder.owningKey) ?:抛出AccountNotFoundException(“Account not found exception.”) val actualHolderInfo=actualHolderStateRef.state.data val actualHolderSession=initiateFlow(actualHolderInfo.host) 实际HolderSession.send(numEtokens) actualHolderSession.send(actualHolder) 实际持有人会话发送(新持有人) val输入=子流(接收状态和流出(实际HolderSession)) val标记:List=actualHolderSession.receive>()。展开{it->it} progressTracker.currentStep=建筑 addMoveTokens(txBuilder、输入、标记) progressTracker.currentStep=签名 val initialSignedTrnx=serviceHub.signInitialTransaction(txBuilder) progressTracker.currentStep=收集信号 val fulySignedTx=子流(CollectSignaturesFlow(InitializedTnx,listOf(actualHolderSession))) progressTracker.currentStep=完成创建 val stx=子流(最终流(fulySignedTx,listOf(actualHolderSession))) progressTracker.currentStep=最终确定 val statesTx=stx.tx.outRefsOfType() statesTx.forEach{state-> observables.forEach{observables-> 子流(ShareStateAndSyncAccounts(状态,可观察)) } } 返回stx } } //响应流代码: 类TransferTokenDiffNodeFlowResponder(val countpartySession:FlowSession):FlowLogic(){ @暂停 重写趣味调用():SignedTransaction{ val numEtokens=counterpartySession.receive().unwrap{it} val actualHolder=countpartysession.receive().unwrap{it} val newHolder=counterpartySession.receive().unwrap{it} val partyAndAmount=partyAndAmount(newHolder,EnergyTokenType.getInstance(“ENERGY”)的numotekens) val actualHolderStateRef=accountService.accountInfo(actualHolder.owningKey) ?:抛出AccountNotFoundException(“Account not found exception.”) val actualHolderInfo=actualHolderStateRef.state.data val条件=QueryCriteria.VaultQueryCriteria(ExternalId=listOf(actualHolderInfo.identifier.id), 状态=Vault.StateStatus.Unused) val选择器=数据库令牌选择(serviceHub) val(输入,输出)=选择器.generateMove(listOf(partyAndAmount).toPairs(), actualHolder,TokenQueryBy(queryCriteria=criteria),runId.uuid) 子流(SendstateAndReflow(对方会话、输入)) 对方会话发送(输出) 子流(对象:SignTransactionFlow(对方会话){ @抛出(FlowException::类) 覆盖趣味支票交易(stx:SignedTransaction){ } }) 返回子流(接收最终流(对方会话)) } } 我们需要在丙方执行流程,实际持有人为账户持有人,新持有人为乙方 此代码返回一个错误: net.corda.core.CORDARUNTIMEEException:java.lang.IllegalArgumentException:未为以下交易参与者提供流程会话:[O=乙方,L=库里蒂巴,C=BR] 但如果我更改代码并添加乙方会话,它将返回错误: java.lang.IllegalArgumentException:CollectSignaturesFlow的发起人必须准确地传入事务签名所需的会话 问题是,为什么addMoveTokens不将newHolder作为必需的签名者?Corda将代币从一个帐户移动到另一方(托管在另一方的帐户),corda,Corda,除了公证人外,我们的Corda网络还有3个节点。 此图显示了每个节点应执行的操作 只有在这种情况下,我们才有麻烦“需要将代币从账户持有人转移到乙方” 流程代码: class TransferETokenDiffNodeFlow(val actualHolder: AbstractParty, val newHolder: AbstractParty,
我该如何解决这个问题呢?代码中有许多要点需要讨论;让我们从错误开始:
FlowSession
,这是与PartyA
的会话(因为它是令牌的持有者);因此,您应该只有:
CollectSignaturesFlow(initialSignedTrnx,listOf(actualHolderSession))
PartyA
)和新持有人(即PartyB
);因此,你应该:
FinalityFlow(fulySignedTx,listOf(实际股东会话,party))
这就是为什么当您只为两个子流传递actualHolderSession
时;您收到缺少会话的消息(因为finality flow也希望为PartyB
创建会话);当您为两者添加了PartyB
会话时,收集签名流抱怨您正在传递一个额外的会话(PartyB
不需要对move命令进行签名,只有当前持有者是)