Corda:在一个流中创建和使用相同的状态?

Corda:在一个流中创建和使用相同的状态?,corda,Corda,是否可以在一个流中创建和使用相同的corda状态,或者在不同的子流中创建和使用它? 我得到以下错误: 原因:net.corda.core.flows.NotaryException:无法对事务进行公证BEDE8C3F8F2D7A646A9F7D1948DAF77CDAFC37F3B086E09FC766F0D412F02690:一个或多个输入状态已在另一个事务中使用是的,您可以在单个流中创建和使用相同的corda状态 您需要分两步进行: 创建发出新状态的第一个事务 创建使用新状态的第二个事务 请

是否可以在一个流中创建和使用相同的corda状态,或者在不同的子流中创建和使用它? 我得到以下错误:
原因:net.corda.core.flows.NotaryException:无法对事务进行公证BEDE8C3F8F2D7A646A9F7D1948DAF77CDAFC37F3B086E09FC766F0D412F02690:一个或多个输入状态已在另一个事务中使用

是的,您可以在单个流中创建和使用相同的corda状态

您需要分两步进行:

  • 创建发出新状态的第一个事务
  • 创建使用新状态的第二个事务
  • 请注意,如果您创建第二笔交易,并导致交易对手在完成第一笔交易之前调用该交易的
    ResolutionFlow
    ,这将导致
    TransactionResolutionException
    ,因为您的存储中还没有要分发的第一笔交易。例如,当运行
    CollectSignaturesFlow
    时,可能会发生这种情况

    以下是在同一流程中构建两个事务的示例:

    @InitiatingFlow
    @StartableByRPC
    class TwoTransactionsFlow(val otherParty: Party) : FlowLogic<Unit>() {
        @Suspendable
        override fun call() {
            val otherPartySessions = listOf(initiateFlow(otherParty))
    
            val transactionBuilderOne = TransactionBuilder()
            // TODO: Add notary and transaction components.
            val partSignedTransactionOne = serviceHub.signInitialTransaction(transactionBuilderOne)
            val fullySignedTransactionOne = subFlow(CollectSignaturesFlow(partSignedTransactionOne, otherPartySessions))
            val notarisedTransactionOne = subFlow(FinalityFlow(fullySignedTransactionOne))
    
            val transactionOneFirstOutputRef = StateRef(notarisedTransactionOne.id, 0)
            val transactionOneFirstOutput = serviceHub.toStateAndRef<ContractState>(transactionOneFirstOutputRef)
    
            val transactionBuilderTwo = TransactionBuilder()
                    .addInputState(transactionOneFirstOutput)
            // TODO: Add notary and other transaction components.
            val partSignedTransactionTwo = serviceHub.signInitialTransaction(transactionBuilderTwo)
            val fullySignedTransactionTwo = subFlow(CollectSignaturesFlow(partSignedTransactionTwo, otherPartySessions))
            subFlow(FinalityFlow(fullySignedTransactionTwo))
        }
    }
    
    @InitiatingFlow
    @星表
    类TwoTransactionFlow(val otherParty:Party):FlowLogic(){
    @暂停
    覆盖有趣的调用(){
    val otherPartySessions=listOf(initiateFlow(otherParty))
    val TransactionBuilder=TransactionBuilder()
    //TODO:添加公证和事务组件。
    val partSignedTransactionOne=serviceHub.signInitialTransaction(transactionBuilderOne)
    val fullySignedTransactionOne=子流(CollectSignaturesFlow(partSignedTransactionOne,otherPartySessions))
    val公证事务处理单=子流(最终流(fullySignedTransactionOne))
    val transactionOneFirstOutputRef=StateRef(公证TransactionOne.id,0)
    val transactionOneFirstOutput=serviceHub.toStateAndRef(transactionOneFirstOutputRef)
    val transactionBuilderTwo=TransactionBuilder()
    .addInputState(transactionOneFirstOutput)
    //TODO:添加公证和其他事务组件。
    val partSignedTransactionTwo=serviceHub.signInitialTransaction(transactionBuilderTwo)
    val fullySignedTransactionTwo=子流(CollectSignaturesFlow(partSignedTransactionTwo,其他PartySessions))
    子流(最终流(完全指定的交易二))
    }
    }
    
    还有一些需要考虑的问题

    • 在Corda 4中,当在一个流中创建和使用状态时,相应的响应程序流应调用ReceiveFinalityFlow 2次(对于签名者也应调用SignTransactionFlow),否则将引发错误:-java.util.concurrent.ExecutionException:net.Corda.core.flows.UnexpectedFlowEndException:尝试访问结束的会话SessionId(toLong=1984916257986245538)带空缓冲区
    Java中启动器流的代码段

    。。。
    //签署交易。
    SignedTransaction signedTx=getServiceHub()。signInitialTransaction(txBuilder);
    //正在与另一方创建会话。
    FlowSession otherPartySession=initiateFlow(另一方);
    //获得交易对手的签名。
    SignedTransaction fullySignedTx=子流(新集合签名流(
    signedTx、Arrays.asList(otherPartySession)、collectSignatureFlow.Companion.tracker());
    //公证交易
    SignedTransaction notraizedtransaction=子流(新的最终流(fullySignedTx,otherPartySession));
    //------------------------------------------------------------------------------------------------------------
    //步骤2:
    //因为现在我们有了一个新的未使用的RECORD-ANCHOR,所以我们必须使它被使用(通过使用以前的输出作为输入)
    //
    //------------------------------------------------------------------------------------------------------------
    StateAndRef oldStateref=getServiceHub().toStateAndRef(新StateRef(notraizedtransaction.getId(),0));
    Command storeCommand=new Command(new-AnchorStateContract.Commands.approvercanchorcmd(),requiredSigners);
    TransactionBuilder txBuilder2=新TransactionBuilder(公证人)
    .addInputState(oldStateref)
    .addCommand(storeCommand);
    验证(getServiceHub());
    //签字
    SignedTransaction signedTx2=getServiceHub()。signInitialTransaction(txBuilder2);
    //完成交易。
    SignedTransaction fullySignedTx2=子流(新集合签名流(
    signedTx2,Arrays.asList(otherPartySession),CollectSignaturesFlow.Companion.tracker());
    //公证交易
    返回子流(新的最终流(fullySignedTx2,otherPartySession));
    }
    
    Java中ResponderFlow的代码片段

    @InitiatedBy(Initiator.class)
    公共类响应程序扩展了FlowLogic{
    私人FlowSession其他方会话;
    公共响应者(FlowSession otherPartySession){
    this.otherPartySession=otherPartySession;
    }
    @暂停
    @凌驾
    public SignedTransaction调用()引发流异常
    {
    //此类在调用函数内部使用,以便在该方签名之前进行验证
    类SignTxFlow1扩展了SignTransactionFlow
    {
    私有签名txflow1(FlowSession otherPartySession){
    超级(其他部门);
    }
    @凌驾
    受保护的无效支票交易(SignedTransaction stx){
    requireThat(require->{
    //验证逻辑
    返回null;
    });
    }
    }
    //此类在调用函数内部使用,以便在该方签名之前进行验证
    类SignTxFlow2扩展了SignTransactionFlow
    {
    私有签名txflow2(FlowSession otherPartySession){
    超级(其他部门);
    }