internal TxOut orphanTxOut = null; // When this input is not segwit, but we don't have the previous tx internal PSBTInput(PSBT parent, uint index, TxIn input) : base(parent) { TxIn = input; Index = index; originalScriptSig = TxIn.ScriptSig ?? Script.Empty; originalWitScript = TxIn.WitScript ?? WitScript.Empty; }
/// <summary> /// Adds a witness stack to the list of elements that will be used for building the filter. /// </summary> /// <param name="witScript">The witScript.</param> /// <returns>The updated filter builder instance.</returns> public void AddWitness(WitScript witScript) { if (witScript == null) { throw new ArgumentNullException(nameof(witScript)); } AddEntries(witScript.Pushes); }
public override bool Equals(object obj) { WitScript item = obj as WitScript; if (item == null) { return(false); } return(EqualsCore(item)); }
public PayToWitPubkeyHashScriptSigParameters?ExtractWitScriptParameters(WitScript witScript) { if (!CheckWitScriptCore(witScript)) { return(null); } if (PubKey.TryCreatePubKey(witScript[1], out var pk)) { return(new PayToWitPubkeyHashScriptSigParameters((witScript[0].Length == 0) ? null : new TransactionSignature(witScript[0]), pk)); } return(null); }
private bool EqualsCore(WitScript item) { if (_Pushes.Length != item._Pushes.Length) { return(false); } for (int i = 0; i < _Pushes.Length; i++) { if (!Utils.ArrayEqual(_Pushes[i], item._Pushes[i])) { return(false); } } return(true); }
/// <summary> /// Extract witness redeem from WitScript /// </summary> /// <param name="witScript">Witscript to extract information from</param> /// <param name="expectedScriptId">Expected redeem hash</param> /// <returns>The witness redeem</returns> public Script ExtractWitScriptParameters(WitScript witScript, WitScriptId expectedScriptId) { if (witScript.PushCount == 0) { return(null); } var last = witScript.GetUnsafePush(witScript.PushCount - 1); Script redeem = new Script(last); if (expectedScriptId != null) { if (expectedScriptId != redeem.WitHash) { return(null); } } return(redeem); }
public PayToWitPubkeyHashScriptSigParameters ExtractWitScriptParameters(WitScript witScript) { if (!CheckWitScriptCore(witScript)) { return(null); } try { return(new PayToWitPubkeyHashScriptSigParameters() { TransactionSignature = (witScript[0].Length == 1 && witScript[0][0] == 0) ? null : new TransactionSignature(witScript[0]), PublicKey = new PubKey(witScript[1], true), }); } catch (FormatException) { return(null); } }
internal void Combine(PSBTInput other) { if (this.IsFinalized()) { return; } foreach (var uk in other.unknown) { unknown.TryAdd(uk.Key, uk.Value); } if (other.final_script_sig != null) { final_script_sig = other.final_script_sig; } if (other.final_script_witness != null) { final_script_witness = other.final_script_witness; } if (IsFinalized()) { ClearForFinalize(); return; } if (non_witness_utxo == null && other.non_witness_utxo != null) { non_witness_utxo = other.non_witness_utxo; } if (witness_utxo == null && other.witness_utxo != null) { non_witness_utxo = other.non_witness_utxo; } if (sighash_type == 0 && other.sighash_type > 0) { sighash_type = other.sighash_type; } if (redeem_script == null && other.redeem_script != null) { redeem_script = other.redeem_script; } if (witness_script == null && other.witness_script != null) { witness_script = other.witness_script; } foreach (var sig in other.partial_sigs) { partial_sigs.TryAdd(sig.Key, sig.Value); } foreach (var keyPath in other.hd_keypaths) { hd_keypaths.TryAdd(keyPath.Key, keyPath.Value); } }
internal PSBTInput(BitcoinStream stream, PSBT parent, uint index, TxIn input) : base(parent) { TxIn = input; Index = index; originalScriptSig = TxIn.ScriptSig ?? Script.Empty; originalWitScript = TxIn.WitScript ?? WitScript.Empty; byte[] k = new byte[0]; byte[] v = new byte[0]; try { stream.ReadWriteAsVarString(ref k); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTInput. Failed to Parse key.", e); } while (k.Length != 0) { try { stream.ReadWriteAsVarString(ref v); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTInput. Failed to parse key.", e); } switch (k.First()) { case PSBTConstants.PSBT_IN_NON_WITNESS_UTXO: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for NonWitnessUTXO"); } if (non_witness_utxo != null) { throw new FormatException("Invalid PSBTInput. Duplicate non_witness_utxo"); } non_witness_utxo = this.GetConsensusFactory().CreateTransaction(); non_witness_utxo.FromBytes(v); break; case PSBTConstants.PSBT_IN_WITNESS_UTXO: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for WitnessUTXO"); } if (witness_utxo != null) { throw new FormatException("Invalid PSBTInput. Duplicate witness_utxo"); } if (this.GetConsensusFactory().TryCreateNew <TxOut>(out var txout)) { witness_utxo = txout; } else { witness_utxo = new TxOut(); } witness_utxo.FromBytes(v); break; case PSBTConstants.PSBT_IN_PARTIAL_SIG: var pubkey = new PubKey(k.Skip(1).ToArray()); if (partial_sigs.ContainsKey(pubkey)) { throw new FormatException("Invalid PSBTInput. Duplicate key for partial_sigs"); } partial_sigs.Add(pubkey, new TransactionSignature(v)); break; case PSBTConstants.PSBT_IN_SIGHASH: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for SigHash type"); } if (!(sighash_type is null)) { throw new FormatException("Invalid PSBTInput. Duplicate key for sighash_type"); } if (v.Length != 4) { throw new FormatException("Invalid PSBTInput. SigHash Type is not 4 byte"); } var value = Utils.ToUInt32(v, 0, true); if (!Enum.IsDefined(typeof(SigHash), value)) { throw new FormatException($"Invalid PSBTInput Unknown SigHash Type {value}"); } sighash_type = (SigHash)value; break; case PSBTConstants.PSBT_IN_REDEEMSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for redeem script"); } if (redeem_script != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for redeem_script"); } redeem_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_WITNESSSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for witness script"); } if (witness_script != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for redeem_script"); } witness_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_BIP32_DERIVATION: var pubkey2 = new PubKey(k.Skip(1).ToArray()); if (hd_keypaths.ContainsKey(pubkey2)) { throw new FormatException("Invalid PSBTInput. Duplicate key for hd_keypaths"); } var masterFingerPrint = new HDFingerprint(v.Take(4).ToArray()); KeyPath path = KeyPath.FromBytes(v.Skip(4).ToArray()); hd_keypaths.Add(pubkey2, new RootedKeyPath(masterFingerPrint, path)); break; case PSBTConstants.PSBT_IN_SCRIPTSIG: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for final scriptsig"); } if (final_script_sig != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for final_script_sig"); } final_script_sig = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_IN_SCRIPTWITNESS: if (k.Length != 1) { throw new FormatException("Invalid PSBTInput. Contains illegal value in key for final script witness"); } if (final_script_witness != null) { throw new FormatException("Invalid PSBTInput. Duplicate key for final_script_witness"); } final_script_witness = new WitScript(v); break; default: if (unknown.ContainsKey(k)) { throw new FormatException("Invalid PSBTInput. Duplicate key for unknown value"); } unknown.Add(k, v); break; } stream.ReadWriteAsVarString(ref k); } }
private bool CheckWitScriptCore(WitScript witScript) { return(witScript.PushCount == 2 && ((witScript[0].Length == 1 && witScript[0][0] == 0) || (TransactionSignature.IsValid(witScript[0], ScriptVerify.None))) && PubKey.Check(witScript[1], false)); }
/// <summary> /// Import informations contained by <paramref name="other"/> into this instance. /// </summary> /// <param name="other"></param> public void UpdateFrom(PSBTInput other) { if (other == null) { throw new ArgumentNullException(nameof(other)); } foreach (var uk in other.unknown) { unknown.TryAdd(uk.Key, uk.Value); } if (other.final_script_sig != null) { final_script_sig = other.final_script_sig; } if (other.final_script_witness != null) { final_script_witness = other.final_script_witness; } if (non_witness_utxo == null && other.non_witness_utxo != null) { non_witness_utxo = other.non_witness_utxo; } if (witness_utxo == null && other.witness_utxo != null) { witness_utxo = other.witness_utxo; } if (sighash_type == 0 && other.sighash_type > 0) { sighash_type = other.sighash_type; } if (redeem_script == null && other.redeem_script != null) { redeem_script = other.redeem_script; } if (witness_script == null && other.witness_script != null) { witness_script = other.witness_script; } foreach (var sig in other.partial_sigs) { partial_sigs.TryAdd(sig.Key, sig.Value); } foreach (var keyPath in other.hd_keypaths) { hd_keypaths.TryAdd(keyPath.Key, keyPath.Value); } if (IsFinalized()) { ClearForFinalize(); } }