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

          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     1066150 :     COutPoint(): n(NULL_INDEX) { }
      48     1451692 :     COutPoint(const uint256& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
      49             : 
      50     4016256 :     SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
      51             : 
      52       26025 :     void SetNull() { hash.SetNull(); n = NULL_INDEX; }
      53      789937 :     bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
      54             : 
      55   151925212 :     friend bool operator<(const COutPoint& a, const COutPoint& b)
      56             :     {
      57   151925212 :         int cmp = a.hash.Compare(b.hash);
      58   151925212 :         return cmp < 0 || (cmp == 0 && a.n < b.n);
      59             :     }
      60             : 
      61     1251272 :     friend bool operator==(const COutPoint& a, const COutPoint& b)
      62             :     {
      63     1251272 :         return (a.hash == b.hash && a.n == b.n);
      64             :     }
      65             : 
      66           0 :     friend bool operator!=(const COutPoint& a, const COutPoint& b)
      67             :     {
      68           0 :         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      543173 :     CTxIn()
     134      271586 :     {
     135      271587 :         nSequence = SEQUENCE_FINAL;
     136      543173 :     }
     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     3353331 :     SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
     142             : 
     143           0 :     friend bool operator==(const CTxIn& a, const CTxIn& b)
     144             :     {
     145           0 :         return (a.prevout   == b.prevout &&
     146           0 :                 a.scriptSig == b.scriptSig &&
     147           0 :                 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   118604608 :     CTxOut()
     173    59302304 :     {
     174    59302304 :         SetNull();
     175   118604608 :     }
     176             : 
     177             :     CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
     178             : 
     179     6761912 :     SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
     180             : 
     181    59432073 :     void SetNull()
     182             :     {
     183    59432073 :         nValue = -1;
     184    59432073 :         scriptPubKey.clear();
     185    59432073 :     }
     186             : 
     187    28023007 :     bool IsNull() const
     188             :     {
     189    28023007 :         return (nValue == -1);
     190             :     }
     191             : 
     192      389858 :     friend bool operator==(const CTxOut& a, const CTxOut& b)
     193             :     {
     194      754177 :         return (a.nValue       == b.nValue &&
     195      364319 :                 a.scriptPubKey == b.scriptPubKey);
     196             :     }
     197             : 
     198         764 :     friend bool operator!=(const CTxOut& a, const CTxOut& b)
     199             :     {
     200         764 :         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         734 : 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     1289368 :     inline void Serialize(Stream& s) const {
     244     1289368 :         int32_t n32bitVersion = this->nVersion | (this->nType << 16);
     245     1289368 :         s << n32bitVersion;
     246     1289368 :         s << vin;
     247     1289368 :         s << vout;
     248     1289368 :         s << nLockTime;
     249     1289368 :         if (this->HasExtraPayloadField())
     250      496477 :             s << vExtraPayload;
     251     1289368 :     }
     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       99070 :     CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
     257             : 
     258           5 :     bool IsNull() const {
     259           5 :         return vin.empty() && vout.empty();
     260             :     }
     261             : 
     262   143079015 :     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     1060876 :     bool IsCoinBase() const
     275             :     {
     276     1060876 :         return (vin.size() == 1 && vin[0].prevout.IsNull());
     277             :     }
     278             : 
     279          17 :     friend bool operator==(const CTransaction& a, const CTransaction& b)
     280             :     {
     281          17 :         return a.hash == b.hash;
     282             :     }
     283             : 
     284           2 :     friend bool operator!=(const CTransaction& a, const CTransaction& b)
     285             :     {
     286           2 :         return a.hash != b.hash;
     287             :     }
     288             : 
     289             :     std::string ToString() const;
     290             : 
     291     1691640 :     bool IsSpecialTxVersion() const noexcept
     292             :     {
     293     1691640 :         return nVersion >= SPECIAL_VERSION;
     294             :     }
     295             : 
     296           0 :     bool IsPlatformTransfer() const noexcept
     297             :     {
     298           0 :         return IsSpecialTxVersion() && nType == TRANSACTION_ASSET_UNLOCK;
     299             :     }
     300             : 
     301     1350721 :     bool HasExtraPayloadField() const noexcept
     302             :     {
     303     1350721 :         return IsSpecialTxVersion() && nType != TRANSACTION_NORMAL;
     304             :     }
     305             : };
     306             : 
     307             : /** A mutable version of CTransaction. */
     308       37652 : 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     1227453 :     SERIALIZE_METHODS(CMutableTransaction, obj)
     321             :     {
     322             :         int32_t n32bitVersion;
     323      719112 :         SER_WRITE(obj, n32bitVersion = obj.nVersion | (obj.nType << 16));
     324      409151 :         READWRITE(n32bitVersion);
     325      508341 :         SER_READ(obj, obj.nVersion = (int16_t) (n32bitVersion & 0xffff));
     326      508341 :         SER_READ(obj, obj.nType = (uint16_t) ((n32bitVersion >> 16) & 0xffff));
     327      409151 :         READWRITE(obj.vin, obj.vout, obj.nLockTime);
     328      409151 :         if (obj.nVersion >= CTransaction::SPECIAL_VERSION && obj.nType != TRANSACTION_NORMAL) {
     329       94482 :             READWRITE(obj.vExtraPayload);
     330       94482 :         }
     331      409151 :     }
     332             : 
     333             :     template <typename Stream>
     334      198140 :     CMutableTransaction(deserialize_type, Stream& s) {
     335       99070 :         Unserialize(s);
     336      198140 :     }
     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      351415 : 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         551 :     inline bool operator()(const CTxIn& a, const CTxIn& b) const
     355             :     {
     356         551 :         if (a.prevout.hash == b.prevout.hash) return a.prevout.n < b.prevout.n;
     357             : 
     358          38 :         uint256 hasha = a.prevout.hash;
     359          38 :         uint256 hashb = b.prevout.hash;
     360             : 
     361             :         typedef std::reverse_iterator<const unsigned char*> rev_it;
     362          38 :         rev_it rita = rev_it(hasha.end());
     363          38 :         rev_it ritb = rev_it(hashb.end());
     364             : 
     365          38 :         return std::lexicographical_compare(rita, rita + hasha.size(), ritb, ritb + hashb.size());
     366         551 :     }
     367             : };
     368             : 
     369             : struct CompareOutputBIP69
     370             : {
     371      119202 :     inline bool operator()(const CTxOut& a, const CTxOut& b) const
     372             :     {
     373      119202 :         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