public static AddressType GetAddressType(this NBitcoin.TxOut tx) { var template = tx.ScriptPubKey.FindTemplate(); if (template != null) { switch (template.Type) { case TxOutType.TX_PUBKEY: return(AddressType.PublicKey); case TxOutType.TX_PUBKEYHASH: return(AddressType.PublicKeyHash); case TxOutType.TX_MULTISIG: return(AddressType.MultiplePublicKeyHashes); case TxOutType.TX_SCRIPTHASH: return(AddressType.ScriptHash); } } var scriptAddress = tx.ScriptPubKey.GetScriptAddress(Network.Main); if (scriptAddress != null) { switch (scriptAddress.Type) { case Base58Type.SCRIPT_ADDRESS: return(AddressType.ScriptHash); case Base58Type.PUBKEY_ADDRESS: return(AddressType.PublicKey); } } throw new NotSupportedException("Not supported yet"); }
public Spendable(OutPoint output, TxOut txout) { if(output == null) throw new ArgumentNullException("output"); if(txout == null) throw new ArgumentNullException("txout"); _Out = txout; _OutPoint = output; }
public void ReadWrite(BitcoinStream stream) { stream.ReadWrite(ref _OutPoint); if(stream.Serializing) { TxOutCompressor compressor = new TxOutCompressor(_Out); stream.ReadWrite(ref compressor); } else { TxOutCompressor compressor = new TxOutCompressor(); stream.ReadWrite(ref compressor); _Out = compressor.TxOut; } }
public void ReadWrite(BitcoinStream stream) { if(stream.Serializing) { uint o = (uint)(nHeight * 2 + (fCoinBase ? 1 : 0)); stream.ReadWriteAsCompactVarInt(ref o); if(nHeight > 0) stream.ReadWriteAsCompactVarInt(ref nVersion); TxOutCompressor compressor = new TxOutCompressor(txout); stream.ReadWrite(ref compressor); } else { uint nCode = 0; stream.ReadWriteAsCompactVarInt(ref nCode); nHeight = nCode / 2; fCoinBase = (nCode & 1) != 0; if(nHeight > 0) stream.ReadWriteAsCompactVarInt(ref nVersion); TxOutCompressor compressor = new TxOutCompressor(); stream.ReadWrite(ref compressor); txout = compressor.TxOut; } }
private void ClearUnused(Func<TxOut, bool> belongsToCoins) { for(int i = 0 ; i < vout.Count ; i++) { var o = vout[i]; if(o.ScriptPubKey.IsUnspendable || !belongsToCoins(o)) { vout[i] = new TxOut(); } } Cleanup(); }
internal ScriptCoin(OutPoint fromOutpoint, TxOut fromTxOut, Script redeem) : base(fromOutpoint, fromTxOut) { Redeem = redeem; }
public static ScriptCoin Create(Network network, OutPoint fromOutpoint, TxOut fromTxOut, Script redeem) { return(new ScriptCoin(fromOutpoint, fromTxOut, redeem).AssertCoherent(network)); }
internal PSBTOutput(BitcoinStream stream, PSBT parent, uint index, TxOut txOut) : base(parent) { if (txOut == null) { throw new ArgumentNullException(nameof(txOut)); } if (parent == null) { throw new ArgumentNullException(nameof(parent)); } TxOut = txOut; Index = index; byte[] k = new byte[0]; byte[] v = new byte[0]; try { stream.ReadWriteAsVarString(ref k); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTOutput. Could not read key", e); } while (k.Length != 0) { try { stream.ReadWriteAsVarString(ref v); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTOutput. Could not read value", e); } switch (k.First()) { case PSBTConstants.PSBT_OUT_REDEEMSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for redeem script"); } if (redeem_script != null) { throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script"); } redeem_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_OUT_WITNESSSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTOutput. Unexpected key length for PSBT_OUT_BIP32_DERIVATION"); } if (witness_script != null) { throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script"); } witness_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_OUT_BIP32_DERIVATION: var pubkey2 = new PubKey(k.Skip(1).ToArray()); if (hd_keypaths.ContainsKey(pubkey2)) { throw new FormatException("Invalid PSBTOutput, duplicate key for hd_keypaths"); } KeyPath path = KeyPath.FromBytes(v.Skip(4).ToArray()); hd_keypaths.Add(pubkey2, new RootedKeyPath(new HDFingerprint(v.Take(4).ToArray()), path)); break; case PSBTConstants.PSBT_OUT_TAP_BIP32_DERIVATION: var pubkey3 = new TaprootPubKey(k.Skip(1).ToArray()); if (hd_taprootkeypaths.ContainsKey(pubkey3)) { throw new FormatException("Invalid PSBTOutput, duplicate key for hd_taproot_keypaths"); } var bs = new BitcoinStream(v); List <uint256> hashes = null !; bs.ReadWrite(ref hashes); var pos = (int)bs.Inner.Position; KeyPath path2 = KeyPath.FromBytes(v.Skip(pos + 4).ToArray()); hd_taprootkeypaths.Add(pubkey3, new TaprootKeyPath( new RootedKeyPath(new HDFingerprint(v.Skip(pos).Take(4).ToArray()), path2), hashes.ToArray())); break; case PSBTConstants.PSBT_OUT_TAP_INTERNAL_KEY: if (k.Length != 1) { throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for internal taproot pubkey"); } if (!TaprootInternalPubKey.TryCreate(v, out var tpk)) { throw new FormatException("Invalid PSBTOutput. Contains invalid internal taproot pubkey"); } TaprootInternalKey = tpk; 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); } }
public Coin(uint256 fromTxHash, uint fromOutputIndex, Money amount, Script scriptPubKey) { Outpoint = new OutPoint(fromTxHash, fromOutputIndex); TxOut = new TxOut(amount, scriptPubKey); }
public TxOut AddOutput(TxOut @out) { this.vout.Add(@out); return(@out); }
public ScriptCoin(Transaction fromTx, TxOut fromOutput, Script redeem) : base(fromTx, fromOutput) { Redeem = redeem; AssertCoherent(); }
public void AddOutput(TxOut @out) { this.vout.Add(@out); }
public TxOutCompressor(TxOut txOut) { _TxOut = txOut; }
public ScriptCoin(OutPoint fromOutpoint, TxOut fromTxOut, Script redeem) : base(fromOutpoint, fromTxOut) { this.Redeem = redeem; }
public Coin(OutPoint fromOutpoint, TxOut fromTxOut) { this.Outpoint = fromOutpoint; this.TxOut = fromTxOut; }
/// <summary> /// Return the <see cref="TxOut"/> of the transaction that contains smart contract. /// <para> /// There is only allowed to be 1 per transaction . /// </para> /// </summary> public static TxOut TryGetSmartContractTxOut(this Transaction transaction) { TxOut smartContractTxOut = transaction.Outputs.FirstOrDefault(txOut => txOut.ScriptPubKey.IsSmartContractExec()); return(smartContractTxOut); }
public Coin(Transaction fromTx, TxOut fromOutput) { if (fromTx == null) throw new ArgumentNullException("fromTx"); if (fromOutput == null) throw new ArgumentNullException("fromOutput"); uint outputIndex = (uint)fromTx.Outputs.FindIndex(r => Object.ReferenceEquals(fromOutput, r)); Outpoint = new OutPoint(fromTx, outputIndex); TxOut = fromOutput; }
public ScriptCoin(OutPoint fromOutpoint, TxOut fromTxOut, Script redeem) : base(fromOutpoint, fromTxOut) { Redeem = redeem; AssertCoherent(); }
public void UpdateFromCoin(ICoin coin) { if (coin == null) { throw new ArgumentNullException(nameof(coin)); } if (IsFinalized()) { throw new InvalidOperationException("Impossible to modify the PSBTInput if it has been finalized"); } if (coin.Outpoint != PrevOut) { throw new ArgumentException("This coin does not match the input", nameof(coin)); } if (IsFinalized()) { return; } if (coin is ScriptCoin scriptCoin) { if (scriptCoin.RedeemType == RedeemType.P2SH) { redeem_script = scriptCoin.Redeem; } else if (scriptCoin.RedeemType == RedeemType.WitnessV0) { witness_script = scriptCoin.Redeem; if (scriptCoin.IsP2SH) { redeem_script = witness_script.WitHash.ScriptPubKey; } } } else { if (coin.TxOut.ScriptPubKey.IsScriptType(ScriptType.P2SH) && redeem_script == null) { // Let's try to be smart by finding the redeemScript in the global tx if (Parent.Settings.IsSmart && redeem_script == null) { var redeemScript = PayToScriptHashTemplate.Instance.ExtractScriptSigParameters(originalScriptSig, coin.TxOut.ScriptPubKey)?.RedeemScript; if (redeemScript != null) { redeem_script = redeemScript; } } } if (witness_script == null) { // Let's try to be smart by finding the witness script in the global tx if (Parent.Settings.IsSmart && witness_script == null) { var witScriptId = PayToWitScriptHashTemplate.Instance.ExtractScriptPubKeyParameters(coin.TxOut.ScriptPubKey); if (witScriptId == null && redeem_script != null) { witScriptId = PayToWitScriptHashTemplate.Instance.ExtractScriptPubKeyParameters(redeem_script); } if (witScriptId != null) { var redeemScript = PayToWitScriptHashTemplate.Instance.ExtractWitScriptParameters(originalWitScript, witScriptId); if (redeemScript != null) { witness_script = redeemScript; } } } } } if (Parent.Network.Consensus.NeverNeedPreviousTxForSigning || coin.GetHashVersion() == HashVersion.Witness || witness_script != null) { witness_utxo = coin.TxOut; non_witness_utxo = null; } else { orphanTxOut = coin.TxOut; witness_utxo = null; } }
/// <summary> /// If scriptpubkey is already present, just add the value. /// </summary> public static void AddWithOptimize(this TxOutList me, TxOut txOut) { me.AddWithOptimize(txOut.Value, txOut.ScriptPubKey); }
public SendMessageBuilder(TxOut txout) { _TxOut = txout; }
public WitScriptCoin(Transaction fromTx, TxOut fromOutput, Script witRedeem) : base(fromTx, fromOutput) { SetAll(fromOutput.ScriptPubKey, witRedeem); }
public static bool VerifyScript(Transaction tx, int i, TxOut spentOutput, ScriptVerify scriptVerify, SigHash sigHash, out ScriptError error) { var scriptSig = tx.Inputs[i].ScriptSig; return(VerifyScript(scriptSig, tx, i, spentOutput, scriptVerify, sigHash, out error)); }
public Coin(OutPoint fromOutpoint, TxOut fromTxOut) { Outpoint = fromOutpoint; TxOut = fromTxOut; }
public static bool VerifyScript(Script scriptSig, Transaction tx, int i, TxOut spentOutput, ScriptVerify scriptVerify = ScriptVerify.Standard, SigHash sigHash = SigHash.Undefined) { ScriptError unused; return(VerifyScript(scriptSig, tx, i, spentOutput, scriptVerify, sigHash, out unused)); }
public IssuanceCoin(OutPoint outpoint, TxOut txout) { Bearer = new Coin(outpoint, txout); }
public static bool VerifyScript(Script scriptSig, Transaction tx, int i, TxOut spentOutput, out ScriptError error) { return(VerifyScript(scriptSig, tx, i, spentOutput, ScriptVerify.Standard, SigHash.Undefined, out error)); }
internal ScriptCoin(Transaction fromTx, TxOut fromOutput, Script redeem) : base(fromTx, fromOutput) { Redeem = redeem; }
private void AddTxOut(OutPoint outpoint, TxOut txOut) { _TxOutByOutpoint.Add(outpoint, txOut); }
public static ScriptCoin Create(Network network, Transaction fromTx, TxOut fromOutput, Script redeem) { return(new ScriptCoin(fromTx, fromOutput, redeem).AssertCoherent(network)); }
public bool IsRelevantAndUpdate(Transaction tx) { if (tx == null) { throw new ArgumentNullException(nameof(tx)); } var hash = tx.GetHash(); bool fFound = false; // Match if the filter contains the hash of tx // for finding tx when they appear in a block if (isFull) { return(true); } if (isEmpty) { return(false); } if (Contains(hash)) { fFound = true; } for (uint i = 0; i < tx.Outputs.Count; i++) { TxOut txout = tx.Outputs[(int)i]; // Match if the filter contains any arbitrary script data element in any scriptPubKey in tx // If this matches, also add the specific output that was matched. // This means clients don't have to update the filter themselves when a new relevant tx // is discovered in order to find spending transactions, which avoids round-tripping and race conditions. foreach (Op op in txout.ScriptPubKey.ToOps()) { if (op.PushData != null && op.PushData.Length != 0 && Contains(op.PushData)) { fFound = true; if ((nFlags & (byte)BloomFlags.UPDATE_MASK) == (byte)BloomFlags.UPDATE_ALL) { Insert(new OutPoint(hash, i)); } else if ((nFlags & (byte)BloomFlags.UPDATE_MASK) == (byte)BloomFlags.UPDATE_P2PUBKEY_ONLY) { var template = StandardScripts.GetTemplateFromScriptPubKey(txout.ScriptPubKey); if (template != null && (template.Type == TxOutType.TX_PUBKEY || template.Type == TxOutType.TX_MULTISIG)) { Insert(new OutPoint(hash, i)); } } break; } } } if (fFound) { return(true); } foreach (TxIn txin in tx.Inputs) { // Match if the filter contains an outpoint tx spends if (Contains(txin.PrevOut)) { return(true); } // Match if the filter contains any arbitrary script data element in any scriptSig in tx foreach (Op op in txin.ScriptSig.ToOps()) { if (op.PushData != null && op.PushData.Length != 0 && Contains(op.PushData)) { return(true); } } } return(false); }
public WitScriptCoin(OutPoint fromOutpoint, TxOut fromTxOut, Script witRedeem) : base(fromOutpoint, fromTxOut) { SetAll(fromTxOut.ScriptPubKey, witRedeem); }
public StealthCoin(OutPoint outpoint, TxOut txOut, Script redeem, StealthMetadata stealthMetadata, BitcoinStealthAddress address) : base(outpoint, txOut) { StealthMetadata = stealthMetadata; Address = address; Redeem = redeem; }
internal PSBTOutput(BitcoinStream stream, PSBT parent, uint index, TxOut txOut) : base(parent) { if (txOut == null) { throw new ArgumentNullException(nameof(txOut)); } if (parent == null) { throw new ArgumentNullException(nameof(parent)); } TxOut = txOut; Index = index; byte[] k = new byte[0]; byte[] v = new byte[0]; try { stream.ReadWriteAsVarString(ref k); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTOutput. Could not read key", e); } while (k.Length != 0) { try { stream.ReadWriteAsVarString(ref v); } catch (EndOfStreamException e) { throw new FormatException("Invalid PSBTOutput. Could not read value", e); } switch (k.First()) { case PSBTConstants.PSBT_OUT_REDEEMSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for redeem script"); } if (redeem_script != null) { throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script"); } redeem_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_OUT_WITNESSSCRIPT: if (k.Length != 1) { throw new FormatException("Invalid PSBTOutput. Contains illegal value in key for witness script"); } if (witness_script != null) { throw new FormatException("Invalid PSBTOutput, duplicate key for redeem_script"); } witness_script = Script.FromBytesUnsafe(v); break; case PSBTConstants.PSBT_OUT_BIP32_DERIVATION: var pubkey2 = new PubKey(k.Skip(1).ToArray()); if (hd_keypaths.ContainsKey(pubkey2)) { throw new FormatException("Invalid PSBTOutput, duplicate key for hd_keypaths"); } KeyPath path = KeyPath.FromBytes(v.Skip(4).ToArray()); hd_keypaths.Add(pubkey2, Tuple.Create(new HDFingerprint(v.Take(4).ToArray()), path)); 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); } }
/// <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(); } }
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); } }