2017-11-30 12 views
0

私は現金の契約確認が失敗した収集署名の流れ中に問題が発生しています - エラーメッセージ現金契約確認

契約の検証を提供する失敗:失敗要件:参照のための[01]発行者Cには、米国を= 、L =ニューヨーク、O = PartyB量のバランス:300000から0 = 0、契約:[email protected]

事実による表示されます入力された現金の金額は出力+元帳を出る金額と同じではありません。しかし、私は単純にCash.generateSpend()関数を使用していますので、私はこのエラーが原因で何ができるかを確認していないトランザクション内の現金の状態を生成する

"for reference ${issuer.reference} at issuer ${issuer.party} the amounts balance: ${inputAmount.quantity} - ${amountExitingLedger.quantity} != ${outputAmount.quantity}" using 
          (inputAmount == outputAmount + amountExitingLedger) 

。使用されている現金はシミュレーション開始時に自己発行され、この問題の原因となるフローが呼び出される前にノード間を移動している可能性があります。

入力されている現金状態の正確な値はわかりませんが、2つの状態があることがわかります。現金のアウトプットは、費やされた金額(3102ドル)と党に戻ってきた2つの州に加えて、310万ドルを費やし、残りは97991898ドルと9799万ドルの価値があります。パーティーはもともとシミュレーションの開始時に$ 98000000が発行されていたので、この第3の出力状態を$ 97995000とすることは非常に奇妙なようです。 2つの入力状態は$ 97991898 + $ 3102 = $ 97995000から$ 97995000になり、このパーティーは既に別のフローで$ 5000を費やしていると思われます - この3番目の現金生産額は$ 97995000です。

この問題は、Cash.generateSpend()で何か問題が発生している可能性がありますか?私は現金の他の入力または出力状態を追加していません(私は以下のフローを添付しました)。この問題は、5000ドルの支出が発生した場合(すなわち、パーティAがB $ 5000を支払って元帳に記録し、別のフローでBに別の支払いをしようとした場合)にのみ発生します。

//STEP 4: Build the transaction 
val notary = serviceHub.networkMapCache.notaryIdentities.first() 
val builder = TransactionBuilder(notary) 
val builder2 = TermDeposit().generateRedeem(builder, TermDeposit) 
//Add our required cash 
val (tx, cashKeys) = Cash.generateSpend(serviceHub, builder2, Amount((TermDeposit.state.data.depositAmount.quantity * (100+TermDeposit.state.data.interestPercent)/100).toLong(), USD), flow.counterparty) 
println("Redeem added cash ${Amount((TermDeposit.state.data.depositAmount.quantity * (100+TermDeposit.state.data.interestPercent)/100).toLong(), USD)}") 

//STEP 5: Get the client to sign the transaction 
println("Inputs ${tx.inputStates()}") 
println("Outputs ${tx.outputStates()}") 
val partSignedTxn = serviceHub.signInitialTransaction(tx, cashKeys) 
println("Before collect sigs") 
val otherPartySig = subFlow(CollectSignaturesFlow(partSignedTxn, listOf(flow), CollectSignaturesFlow.tracker())) 
println("after collect sigs") 

//STEP 6: Merge all signatures and commit this to the ledger 
val twiceSignedTx = partSignedTxn.plus(otherPartySig.sigs) 
println("Redeem before finality flow") 
return subFlow(FinalityFlow(twiceSignedTx)) 

私はこの質問は非常にオープンである知っているが終わったが、私は間違って行くことができた領域上の任意のポインタをいただければ幸いです。

答えて

0

はここCash.verify()の関連部分です:

val groups = tx.groupStates { it: Cash.State -> it.amount.token } 

for ((inputs, outputs, key) in groups) { 
    val issuer = key.issuer 
    val currency = key.product 

    val inputAmount = inputs.sumCashOrNull() ?: throw IllegalArgumentException("there is at least one cash input for this group") 
    val outputAmount = outputs.sumCashOrZero(Issued(issuer, currency)) 

    val exitKeys = inputs.flatMap { it.exitKeys }.toSet() 
    val exitCommand = tx.commands.select<Commands.Exit>(parties = null, signers = exitKeys).filter { it.value.amount.token == key }.singleOrNull() 
    val amountExitingLedger = exitCommand?.value?.amount ?: Amount(0, Issued(issuer, currency)) 

    requireThat { 
     "for reference ${issuer.reference} at issuer ${issuer.party} the amounts balance: " + 
      "${inputAmount.quantity} - ${amountExitingLedger.quantity} != ${outputAmount.quantity}" using 
      (inputAmount == outputAmount + amountExitingLedger) 
    } 
} 

groupStatesは、リスト - リストの各リストは、与えられたIssuer<Currency>に対応する入力と出力が含まれて、返します。

異なるIssuer<Currency>に関連付けられた現金状態は代替できません。換言すれば、取引は、それが取る(出口を無視して)ごとに多くの現金をIssuer<Currency>に出力しなければならない。

ここで最も問題となるのは、現金を入力して別のIssuer<Currency>で出力することです。フローをデバッグし、トランザクションが検証される前にトランザクションの内容を調べる場合は、これが当てはまるかどうかを判断できるはずです。

1

この問題や同様の現金確認の問題を抱えている人には、中央の現金発行会社として機能するノードを作成し、シミュレーション開始時に自己発行の現金ではなく、 CashIssueAndPaymentフローを使用して、各ノードに一定額の現金を送付します。

この問題がフロー内の何かによって生じたのか、あるいは単一の当事者が現金状態の発行者および受信者であったという事実が原因であるかどうかはまだ分かりません。

関連する問題