LCOV - code coverage report
Current view: top level - src/primitives - transaction.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 88 88 100.0 %
Date: 2026-06-25 07:23:43 Functions: 227 227 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
       7             : #define BITCOIN_PRIMITIVES_TRANSACTION_H
       8             : 
       9             : #include <attributes.h>
      10             : #include <consensus/amount.h>
      11             : #include <script/script.h>
      12             : #include <serialize.h>
      13             : #include <uint256.h>
      14             : 
      15             : #include <algorithm>
      16             : #include <cstdint>
      17             : #include <iterator>
      18             : #include <limits>
      19             : #include <memory>
      20             : #include <string>
      21             : #include <utility>
      22             : #include <vector>
      23             : 
      24             : /** Transaction types */
      25             : enum {
      26             :     TRANSACTION_NORMAL = 0,
      27             :     TRANSACTION_PROVIDER_REGISTER = 1,
      28             :     TRANSACTION_PROVIDER_UPDATE_SERVICE = 2,
      29             :     TRANSACTION_PROVIDER_UPDATE_REGISTRAR = 3,
      30             :     TRANSACTION_PROVIDER_UPDATE_REVOKE = 4,
      31             :     TRANSACTION_COINBASE = 5,
      32             :     TRANSACTION_QUORUM_COMMITMENT = 6,
      33             :     TRANSACTION_MNHF_SIGNAL = 7,
      34             :     TRANSACTION_ASSET_LOCK = 8,
      35             :     TRANSACTION_ASSET_UNLOCK = 9,
      36             : };
      37             : 
      38             : /** An outpoint - a combination of a transaction hash and an index n into its vout */
      39             : class COutPoint
      40             : {
      41             : public:
      42             :     uint256 hash;
      43             :     uint32_t n;
      44             : 
      45             :     static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();
      46             : 
      47     7673600 :     COutPoint(): n(NULL_INDEX) { }
      48    60891769 :     COutPoint(const uint256& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
      49             : 
      50    78026083 :     SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
      51             : 
      52       89378 :     void SetNull() { hash.SetNull(); n = NULL_INDEX; }
      53    25422445 :     bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
      54             : 
      55   359189674 :     friend bool operator<(const COutPoint& a, const COutPoint& b)
      56             :     {
      57   359189674 :         int cmp = a.hash.Compare(b.hash);
      58   359189674 :         return cmp < 0 || (cmp == 0 && a.n < b.n);
      59             :     }
      60             : 
      61    48936665 :     friend bool operator==(const COutPoint& a, const COutPoint& b)
      62             :     {
      63    48936665 :         return (a.hash == b.hash && a.n == b.n);
      64             :     }
      65             : 
      66       18394 :     friend bool operator!=(const COutPoint& a, const COutPoint& b)
      67             :     {
      68       18394 :         return !(a == b);
      69             :     }
      70             : 
      71             :     std::string ToString() const;
      72             :     std::string ToStringShort() const;
      73             : };
      74             : 
      75             : /** An input of a transaction.  It contains the location of the previous
      76             :  * transaction's output that it claims and a signature that matches the
      77             :  * output's public key.
      78             :  */
      79             : class CTxIn
      80             : {
      81             : public:
      82             :     COutPoint prevout;
      83             :     CScript scriptSig;
      84             :     uint32_t nSequence;
      85             : 
      86             :     /**
      87             :      * Setting nSequence to this value for every input in a transaction
      88             :      * disables nLockTime/IsFinalTx().
      89             :      * It fails OP_CHECKLOCKTIMEVERIFY/CheckLockTime() for any input that has
      90             :      * it set (BIP 65).
      91             :      * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
      92             :      */
      93             :     static const uint32_t SEQUENCE_FINAL = 0xffffffff;
      94             :     /**
      95             :      * This is the maximum sequence number that enables both nLockTime and
      96             :      * OP_CHECKLOCKTIMEVERIFY (BIP 65).
      97             :      * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
      98             :      */
      99             :     static const uint32_t MAX_SEQUENCE_NONFINAL{SEQUENCE_FINAL - 1};
     100             : 
     101             :     // Below flags apply in the context of BIP 68. BIP 68 requires the tx
     102             :     // version to be set to 2, or higher.
     103             :     /**
     104             :      * If this flag is set, CTxIn::nSequence is NOT interpreted as a
     105             :      * relative lock-time.
     106             :      * It skips SequenceLocks() for any input that has it set (BIP 68).
     107             :      * It fails OP_CHECKSEQUENCEVERIFY/CheckSequence() for any input that has
     108             :      * it set (BIP 112).
     109             :      */
     110             :     static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
     111             : 
     112             :     /**
     113             :      * If CTxIn::nSequence encodes a relative lock-time and this flag
     114             :      * is set, the relative lock-time has units of 512 seconds,
     115             :      * otherwise it specifies blocks with a granularity of 1. */
     116             :     static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
     117             : 
     118             :     /**
     119             :      * If CTxIn::nSequence encodes a relative lock-time, this mask is
     120             :      * applied to extract that lock-time from the sequence field. */
     121             :     static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
     122             : 
     123             :     /**
     124             :      * In order to use the same number of bits to encode roughly the
     125             :      * same wall-clock duration, and because blocks are naturally
     126             :      * limited to occur every 600s on average, the minimum granularity
     127             :      * for time-based relative lock-time is fixed at 512 seconds.
     128             :      * Converting from CTxIn::nSequence to seconds is performed by
     129             :      * multiplying by 512 = 2^9, or equivalently shifting up by
     130             :      * 9 bits. */
     131             :     static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
     132             : 
     133     3632388 :     CTxIn()
     134     1816199 :     {
     135     1816189 :         nSequence = SEQUENCE_FINAL;
     136     3632388 :     }
     137             : 
     138             :     explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
     139             :     CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
     140             : 
     141    31645930 :     SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
     142             : 
     143          28 :     friend bool operator==(const CTxIn& a, const CTxIn& b)
     144             :     {
     145          32 :         return (a.prevout   == b.prevout &&
     146           4 :                 a.scriptSig == b.scriptSig &&
     147           4 :                 a.nSequence == b.nSequence);
     148             :     }
     149             : 
     150             :     friend bool operator!=(const CTxIn& a, const CTxIn& b)
     151             :     {
     152             :         return !(a == b);
     153             :     }
     154             : 
     155             :     friend bool operator<(const CTxIn& a, const CTxIn& b)
     156             :     {
     157             :         return a.prevout<b.prevout;
     158             :     }
     159             : 
     160             :     std::string ToString() const;
     161             : };
     162             : 
     163             : /** An output of a transaction.  It contains the public key that the next input
     164             :  * must be able to sign with to claim it.
     165             :  */
     166             : class CTxOut
     167             : {
     168             : public:
     169             :     CAmount nValue;
     170             :     CScript scriptPubKey;
     171             : 
     172   194867784 :     CTxOut()
     173    97433889 :     {
     174    97433895 :         SetNull();
     175   194867784 :     }
     176             : 
     177             :     CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
     178             : 
     179    78937798 :     SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
     180             : 
     181   108738719 :     void SetNull()
     182             :     {
     183   108738719 :         nValue = -1;
     184   108738719 :         scriptPubKey.clear();
     185   108738719 :     }
     186             : 
     187   124726190 :     bool IsNull() const
     188             :     {
     189   124726190 :         return (nValue == -1);
     190             :     }
     191             : 
     192     1424797 :     friend bool operator==(const CTxOut& a, const CTxOut& b)
     193             :     {
     194     2259892 :         return (a.nValue       == b.nValue &&
     195      835095 :                 a.scriptPubKey == b.scriptPubKey);
     196             :     }
     197             : 
     198       86334 :     friend bool operator!=(const CTxOut& a, const CTxOut& b)
     199             :     {
     200       86334 :         return !(a == b);
     201             :     }
     202             : 
     203             :     std::string ToString() const;
     204             : };
     205             : 
     206             : struct CMutableTransaction;
     207             : 
     208             : /** The basic transaction that is broadcasted on the network and contained in
     209             :  * blocks.  A transaction can contain multiple inputs and outputs.
     210             :  */
     211      104325 : class CTransaction
     212             : {
     213             : public:
     214             :     // Default transaction version.
     215             :     static const int32_t CURRENT_VERSION=2;
     216             :     // Special transaction version
     217             :     static const int32_t SPECIAL_VERSION = 3;
     218             : 
     219             :     // The local variables are made const to prevent unintended modification
     220             :     // without updating the cached hash value. However, CTransaction is not
     221             :     // actually immutable; deserialization and assignment are implemented,
     222             :     // and bypass the constness. This is safe, as they update the entire
     223             :     // structure, including the hash.
     224             :     const std::vector<CTxIn> vin;
     225             :     const std::vector<CTxOut> vout;
     226             :     const int16_t nVersion;
     227             :     const uint16_t nType;
     228             :     const uint32_t nLockTime;
     229             :     const std::vector<uint8_t> vExtraPayload; // only available for special transaction types
     230             : 
     231             : private:
     232             :     /** Memory only. */
     233             :     const uint256 hash;
     234             : 
     235             :     uint256 ComputeHash() const;
     236             : 
     237             : public:
     238             :     /** Convert a CMutableTransaction into a CTransaction. */
     239             :     explicit CTransaction(const CMutableTransaction& tx);
     240             :     explicit CTransaction(CMutableTransaction&& tx);
     241             : 
     242             :     template <typename Stream>
     243     9885492 :     inline void Serialize(Stream& s) const {
     244     9885492 :         int32_t n32bitVersion = this->nVersion | (this->nType << 16);
     245     9885492 :         s << n32bitVersion;
     246     9885492 :         s << vin;
     247     9885492 :         s << vout;
     248     9885492 :         s << nLockTime;
     249     9885492 :         if (this->HasExtraPayloadField())
     250     5559610 :             s << vExtraPayload;
     251     9885492 :     }
     252             : 
     253             :     /** This deserializing constructor is provided instead of an Unserialize method.
     254             :      *  Unserialize is not possible, since it would require overwriting const fields. */
     255             :     template <typename Stream>
     256     2081702 :     CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
     257             : 
     258       97906 :     bool IsNull() const {
     259       97906 :         return vin.empty() && vout.empty();
     260             :     }
     261             : 
     262   352843131 :     const uint256& GetHash() const LIFETIMEBOUND { return hash; }
     263             : 
     264             :     // Return sum of txouts.
     265             :     CAmount GetValueOut() const;
     266             : 
     267             :     /**
     268             :      * Get the total transaction size in bytes, including witness data.
     269             :      * "Total Size" defined in BIP141 and BIP144.
     270             :      * @return Total transaction size in bytes
     271             :      */
     272             :     unsigned int GetTotalSize() const;
     273             : 
     274    35867818 :     bool IsCoinBase() const
     275             :     {
     276    35867818 :         return (vin.size() == 1 && vin[0].prevout.IsNull());
     277             :     }
     278             : 
     279       88863 :     friend bool operator==(const CTransaction& a, const CTransaction& b)
     280             :     {
     281       88863 :         return a.hash == b.hash;
     282             :     }
     283             : 
     284         183 :     friend bool operator!=(const CTransaction& a, const CTransaction& b)
     285             :     {
     286         183 :         return a.hash != b.hash;
     287             :     }
     288             : 
     289             :     std::string ToString() const;
     290             : 
     291    22234664 :     bool IsSpecialTxVersion() const noexcept
     292             :     {
     293    22234664 :         return nVersion >= SPECIAL_VERSION;
     294             :     }
     295             : 
     296        7158 :     bool IsPlatformTransfer() const noexcept
     297             :     {
     298        7158 :         return IsSpecialTxVersion() && nType == TRANSACTION_ASSET_UNLOCK;
     299             :     }
     300             : 
     301    10815323 :     bool HasExtraPayloadField() const noexcept
     302             :     {
     303    10815323 :         return IsSpecialTxVersion() && nType != TRANSACTION_NORMAL;
     304             :     }
     305             : };
     306             : 
     307             : /** A mutable version of CTransaction. */
     308       38326 : struct CMutableTransaction
     309             : {
     310             :     std::vector<CTxIn> vin;
     311             :     std::vector<CTxOut> vout;
     312             :     int16_t nVersion;
     313             :     uint16_t nType;
     314             :     uint32_t nLockTime;
     315             :     std::vector<uint8_t> vExtraPayload; // only available for special transaction types
     316             : 
     317             :     explicit CMutableTransaction();
     318             :     explicit CMutableTransaction(const CTransaction& tx);
     319             : 
     320     7786996 :     SERIALIZE_METHODS(CMutableTransaction, obj)
     321             :     {
     322             :         int32_t n32bitVersion;
     323     3089180 :         SER_WRITE(obj, n32bitVersion = obj.nVersion | (obj.nType << 16));
     324     2595663 :         READWRITE(n32bitVersion);
     325     4697807 :         SER_READ(obj, obj.nVersion = (int16_t) (n32bitVersion & 0xffff));
     326     4697814 :         SER_READ(obj, obj.nType = (uint16_t) ((n32bitVersion >> 16) & 0xffff));
     327     2595663 :         READWRITE(obj.vin, obj.vout, obj.nLockTime);
     328     2595663 :         if (obj.nVersion >= CTransaction::SPECIAL_VERSION && obj.nType != TRANSACTION_NORMAL) {
     329     1602043 :             READWRITE(obj.vExtraPayload);
     330     1602043 :         }
     331     2595663 :     }
     332             : 
     333             :     template <typename Stream>
     334     4163395 :     CMutableTransaction(deserialize_type, Stream& s) {
     335     2081698 :         Unserialize(s);
     336     4163395 :     }
     337             : 
     338             :     /** Compute the hash of this CMutableTransaction. This is computed on the
     339             :      * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
     340             :      */
     341             :     uint256 GetHash() const;
     342             : 
     343             :     std::string ToString() const;
     344             : };
     345             : 
     346             : typedef std::shared_ptr<const CTransaction> CTransactionRef;
     347      806712 : template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
     348             : 
     349             : /** Implementation of BIP69
     350             :  * https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki
     351             :  */
     352             : struct CompareInputBIP69
     353             : {
     354      209857 :     inline bool operator()(const CTxIn& a, const CTxIn& b) const
     355             :     {
     356      209857 :         if (a.prevout.hash == b.prevout.hash) return a.prevout.n < b.prevout.n;
     357             : 
     358      204257 :         uint256 hasha = a.prevout.hash;
     359      204257 :         uint256 hashb = b.prevout.hash;
     360             : 
     361             :         typedef std::reverse_iterator<const unsigned char*> rev_it;
     362      204257 :         rev_it rita = rev_it(hasha.end());
     363      204257 :         rev_it ritb = rev_it(hashb.end());
     364             : 
     365      204257 :         return std::lexicographical_compare(rita, rita + hasha.size(), ritb, ritb + hashb.size());
     366      209857 :     }
     367             : };
     368             : 
     369             : struct CompareOutputBIP69
     370             : {
     371     3550092 :     inline bool operator()(const CTxOut& a, const CTxOut& b) const
     372             :     {
     373     3550092 :         return a.nValue < b.nValue || (a.nValue == b.nValue && a.scriptPubKey < b.scriptPubKey);
     374             :     }
     375             : };
     376             : 
     377             : #endif // BITCOIN_PRIMITIVES_TRANSACTION_H

Generated by: LCOV version 1.16