public bool TryFinalizeInput(out IList <PSBTError> errors) { errors = null; if (IsFinalized()) { return(true); } var isSane = this.CheckSanity(); if (isSane.Count != 0) { errors = isSane; return(false); } if (witness_utxo == null && non_witness_utxo == null) { errors = new List <PSBTError>() { new PSBTError(Index, "Neither witness_utxo nor non_witness_output is set") }; return(false); } var coin = this.GetSignableCoin(out var getSignableCoinError) ?? this.GetCoin(); // GetCoin can't be null at this stage. TransactionBuilder transactionBuilder = Parent.CreateTransactionBuilder(); transactionBuilder.AddCoins(coin); foreach (var sig in PartialSigs) { transactionBuilder.AddKnownSignature(sig.Key, sig.Value, coin.Outpoint); } Transaction signed = null; try { var signedTx = Parent.Settings.IsSmart ? Parent.GetOriginalTransaction() : Transaction.Clone(); signed = transactionBuilder.SignTransaction(signedTx, SigHash.All); } catch (Exception ex) { errors = new List <PSBTError>() { new PSBTError(Index, $"Error while finalizing the input \"{getSignableCoinError ?? ex.Message}\"") }; return(false); } var indexedInput = signed.Inputs.FindIndexedInput(coin.Outpoint); if (!indexedInput.VerifyScript(coin, out var error)) { errors = new List <PSBTError>() { new PSBTError(Index, $"The finalized input script does not properly validate \"{error}\"") }; return(false); } FinalScriptSig = indexedInput.ScriptSig is Script oo && oo != Script.Empty ? oo : null; FinalScriptWitness = indexedInput.WitScript is WitScript o && o != WitScript.Empty ? o : null; if (transactionBuilder.FindSignableCoin(indexedInput) is ScriptCoin scriptCoin) { if (scriptCoin.IsP2SH) { RedeemScript = scriptCoin.GetP2SHRedeem(); } if (scriptCoin.RedeemType == RedeemType.WitnessV0) { WitnessScript = scriptCoin.Redeem; } } ClearForFinalize(); errors = null; return(true); }