transaction.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka 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 LIMENKA_PRIMITIVES_TRANSACTION_H
   7  #define LIMENKA_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  #include <util/transaction_identifier.h> // IWYU pragma: export
  15  
  16  #include <cstddef>
  17  #include <cstdint>
  18  #include <ios>
  19  #include <limits>
  20  #include <memory>
  21  #include <numeric>
  22  #include <string>
  23  #include <tuple>
  24  #include <utility>
  25  #include <vector>
  26  
  27  /** An outpoint - a combination of a transaction hash and an index n into its vout */
  28  class COutPoint
  29  {
  30  public:
  31      Txid hash;
  32      uint32_t n;
  33  
  34      static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();
  35  
  36      COutPoint(): n(NULL_INDEX) { }
  37      COutPoint(const Txid& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
  38  
  39      SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
  40  
  41      void SetNull() { hash.SetNull(); n = NULL_INDEX; }
  42      bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
  43  
  44      friend bool operator<(const COutPoint& a, const COutPoint& b)
  45      {
  46          return std::tie(a.hash, a.n) < std::tie(b.hash, b.n);
  47      }
  48  
  49      friend bool operator==(const COutPoint& a, const COutPoint& b)
  50      {
  51          return (a.hash == b.hash && a.n == b.n);
  52      }
  53  
  54      friend bool operator!=(const COutPoint& a, const COutPoint& b)
  55      {
  56          return !(a == b);
  57      }
  58  
  59      std::string ToString() const;
  60  };
  61  
  62  /** An input of a transaction.  It contains the location of the previous
  63   * transaction's output that it claims and a signature that matches the
  64   * output's public key.
  65   */
  66  class CTxIn
  67  {
  68  public:
  69      COutPoint prevout;
  70      CScript scriptSig;
  71      uint32_t nSequence;
  72      CScriptWitness scriptWitness; //!< Only serialized through CTransaction
  73  
  74      /**
  75       * Setting nSequence to this value for every input in a transaction
  76       * disables nLockTime/IsFinalTx().
  77       * It fails OP_CHECKLOCKTIMEVERIFY/CheckLockTime() for any input that has
  78       * it set (BIP 65).
  79       * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
  80       */
  81      static const uint32_t SEQUENCE_FINAL = 0xffffffff;
  82      /**
  83       * This is the maximum sequence number that enables both nLockTime and
  84       * OP_CHECKLOCKTIMEVERIFY (BIP 65).
  85       * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
  86       */
  87      static const uint32_t MAX_SEQUENCE_NONFINAL{SEQUENCE_FINAL - 1};
  88  
  89      // Below flags apply in the context of BIP 68. BIP 68 requires the tx
  90      // version to be set to 2, or higher.
  91      /**
  92       * If this flag is set, CTxIn::nSequence is NOT interpreted as a
  93       * relative lock-time.
  94       * It skips SequenceLocks() for any input that has it set (BIP 68).
  95       * It fails OP_CHECKSEQUENCEVERIFY/CheckSequence() for any input that has
  96       * it set (BIP 112).
  97       */
  98      static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
  99  
 100      /**
 101       * If CTxIn::nSequence encodes a relative lock-time and this flag
 102       * is set, the relative lock-time has units of 512 seconds,
 103       * otherwise it specifies blocks with a granularity of 1. */
 104      static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
 105  
 106      /**
 107       * If CTxIn::nSequence encodes a relative lock-time, this mask is
 108       * applied to extract that lock-time from the sequence field. */
 109      static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
 110  
 111      /**
 112       * In order to use the same number of bits to encode roughly the
 113       * same wall-clock duration, and because blocks are naturally
 114       * limited to occur every 600s on average, the minimum granularity
 115       * for time-based relative lock-time is fixed at 512 seconds.
 116       * Converting from CTxIn::nSequence to seconds is performed by
 117       * multiplying by 512 = 2^9, or equivalently shifting up by
 118       * 9 bits. */
 119      static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
 120  
 121      CTxIn()
 122      {
 123          nSequence = SEQUENCE_FINAL;
 124      }
 125  
 126      explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
 127      CTxIn(Txid hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
 128  
 129      SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
 130  
 131      friend bool operator==(const CTxIn& a, const CTxIn& b)
 132      {
 133          return (a.prevout   == b.prevout &&
 134                  a.scriptSig == b.scriptSig &&
 135                  a.nSequence == b.nSequence);
 136      }
 137  
 138      friend bool operator!=(const CTxIn& a, const CTxIn& b)
 139      {
 140          return !(a == b);
 141      }
 142  
 143      std::string ToString() const;
 144  };
 145  
 146  /** An output of a transaction.  It contains the public key that the next input
 147   * must be able to sign with to claim it.
 148   */
 149  class CTxOut
 150  {
 151  public:
 152      CAmount nValue;
 153      CScript scriptPubKey;
 154  
 155      CTxOut()
 156      {
 157          SetNull();
 158      }
 159  
 160      CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
 161  
 162      SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
 163  
 164      void SetNull()
 165      {
 166          nValue = -1;
 167          scriptPubKey.clear();
 168      }
 169  
 170      bool IsNull() const
 171      {
 172          return (nValue == -1);
 173      }
 174  
 175      friend bool operator==(const CTxOut& a, const CTxOut& b)
 176      {
 177          return (a.nValue       == b.nValue &&
 178                  a.scriptPubKey == b.scriptPubKey);
 179      }
 180  
 181      friend bool operator!=(const CTxOut& a, const CTxOut& b)
 182      {
 183          return !(a == b);
 184      }
 185  
 186      std::string ToString() const;
 187  };
 188  
 189  struct CMutableTransaction;
 190  
 191  struct TransactionSerParams {
 192      const bool allow_witness;
 193      SER_PARAMS_OPFUNC
 194  };
 195  static constexpr TransactionSerParams TX_WITH_WITNESS{.allow_witness = true};
 196  static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false};
 197  
 198  /**
 199   * Basic transaction serialization format:
 200   * - uint32_t version
 201   * - std::vector<CTxIn> vin
 202   * - std::vector<CTxOut> vout
 203   * - uint32_t nLockTime
 204   *
 205   * Extended transaction serialization format:
 206   * - uint32_t version
 207   * - unsigned char dummy = 0x00
 208   * - unsigned char flags (!= 0)
 209   * - std::vector<CTxIn> vin
 210   * - std::vector<CTxOut> vout
 211   * - if (flags & 1):
 212   *   - CScriptWitness scriptWitness; (deserialized into CTxIn)
 213   * - uint32_t nLockTime
 214   */
 215  template<typename Stream, typename TxType>
 216  void UnserializeTransaction(TxType& tx, Stream& s, const TransactionSerParams& params)
 217  {
 218      const bool fAllowWitness = params.allow_witness;
 219  
 220      s >> tx.version;
 221      unsigned char flags = 0;
 222      tx.vin.clear();
 223      tx.vout.clear();
 224      /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
 225      s >> tx.vin;
 226      if (tx.vin.size() == 0 && fAllowWitness) {
 227          /* We read a dummy or an empty vin. */
 228          s >> flags;
 229          if (flags != 0) {
 230              s >> tx.vin;
 231              s >> tx.vout;
 232          }
 233      } else {
 234          /* We read a non-empty vin. Assume a normal vout follows. */
 235          s >> tx.vout;
 236      }
 237      if ((flags & 1) && fAllowWitness) {
 238          /* The witness flag is present, and we support witnesses. */
 239          flags ^= 1;
 240          for (size_t i = 0; i < tx.vin.size(); i++) {
 241              s >> tx.vin[i].scriptWitness.stack;
 242          }
 243          if (!tx.HasWitness()) {
 244              /* It's illegal to encode witnesses when all witness stacks are empty. */
 245              throw std::ios_base::failure("Superfluous witness record");
 246          }
 247      }
 248      if (flags) {
 249          /* Unknown flag in the serialization */
 250          throw std::ios_base::failure("Unknown transaction optional data");
 251      }
 252      s >> tx.nLockTime;
 253  }
 254  
 255  template<typename Stream, typename TxType>
 256  void SerializeTransaction(const TxType& tx, Stream& s, const TransactionSerParams& params)
 257  {
 258      const bool fAllowWitness = params.allow_witness;
 259  
 260      s << tx.version;
 261      unsigned char flags = 0;
 262      // Consistency check
 263      if (fAllowWitness) {
 264          /* Check whether witnesses need to be serialized. */
 265          if (tx.HasWitness()) {
 266              flags |= 1;
 267          }
 268      }
 269      if (flags) {
 270          /* Use extended format in case witnesses are to be serialized. */
 271          std::vector<CTxIn> vinDummy;
 272          s << vinDummy;
 273          s << flags;
 274      }
 275      s << tx.vin;
 276      s << tx.vout;
 277      if (flags & 1) {
 278          for (size_t i = 0; i < tx.vin.size(); i++) {
 279              s << tx.vin[i].scriptWitness.stack;
 280          }
 281      }
 282      s << tx.nLockTime;
 283  }
 284  
 285  template<typename TxType>
 286  inline CAmount CalculateOutputValue(const TxType& tx)
 287  {
 288      return std::accumulate(tx.vout.cbegin(), tx.vout.cend(), CAmount{0}, [](CAmount sum, const auto& txout) { return sum + txout.nValue; });
 289  }
 290  
 291  
 292  /** The basic transaction that is broadcasted on the network and contained in
 293   * blocks.  A transaction can contain multiple inputs and outputs.
 294   */
 295  class CTransaction
 296  {
 297  public:
 298      // Default transaction version.
 299      static const uint32_t CURRENT_VERSION{2};
 300  
 301      // The local variables are made const to prevent unintended modification
 302      // without updating the cached hash value. However, CTransaction is not
 303      // actually immutable; deserialization and assignment are implemented,
 304      // and bypass the constness. This is safe, as they update the entire
 305      // structure, including the hash.
 306      const std::vector<CTxIn> vin;
 307      const std::vector<CTxOut> vout;
 308      const uint32_t version;
 309      const uint32_t nLockTime;
 310  
 311  private:
 312      /** Memory only. */
 313      const bool m_has_witness;
 314      const Txid hash;
 315      const Wtxid m_witness_hash;
 316  
 317      Txid ComputeHash() const;
 318      Wtxid ComputeWitnessHash() const;
 319  
 320      bool ComputeHasWitness() const;
 321  
 322  public:
 323      /** Convert a CMutableTransaction into a CTransaction. */
 324      explicit CTransaction(const CMutableTransaction& tx);
 325      explicit CTransaction(CMutableTransaction&& tx);
 326  
 327      template <typename Stream>
 328      inline void Serialize(Stream& s) const {
 329          SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
 330      }
 331  
 332      /** This deserializing constructor is provided instead of an Unserialize method.
 333       *  Unserialize is not possible, since it would require overwriting const fields. */
 334      template <typename Stream>
 335      CTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) : CTransaction(CMutableTransaction(deserialize, params, s)) {}
 336      template <typename Stream>
 337      CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
 338  
 339      bool IsNull() const {
 340          return vin.empty() && vout.empty();
 341      }
 342  
 343      const Txid& GetHash() const LIFETIMEBOUND { return hash; }
 344      const Wtxid& GetWitnessHash() const LIFETIMEBOUND { return m_witness_hash; };
 345  
 346      // Return sum of txouts.
 347      CAmount GetValueOut() const;
 348  
 349      /**
 350       * Get the total transaction size in bytes, including witness data.
 351       * "Total Size" defined in BIP141 and BIP144.
 352       * @return Total transaction size in bytes
 353       */
 354      unsigned int GetTotalSize() const;
 355  
 356      bool IsCoinBase() const
 357      {
 358          return (vin.size() == 1 && vin[0].prevout.IsNull());
 359      }
 360  
 361      friend bool operator==(const CTransaction& a, const CTransaction& b)
 362      {
 363          return a.hash == b.hash;
 364      }
 365  
 366      friend bool operator!=(const CTransaction& a, const CTransaction& b)
 367      {
 368          return a.hash != b.hash;
 369      }
 370  
 371      std::string ToString() const;
 372  
 373      bool HasWitness() const { return m_has_witness; }
 374  };
 375  
 376  /** A mutable version of CTransaction. */
 377  struct CMutableTransaction
 378  {
 379      std::vector<CTxIn> vin;
 380      std::vector<CTxOut> vout;
 381      uint32_t version;
 382      uint32_t nLockTime;
 383  
 384      explicit CMutableTransaction();
 385      explicit CMutableTransaction(const CTransaction& tx);
 386  
 387      template <typename Stream>
 388      inline void Serialize(Stream& s) const {
 389          SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
 390      }
 391  
 392      template <typename Stream>
 393      inline void Unserialize(Stream& s) {
 394          UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
 395      }
 396  
 397      template <typename Stream>
 398      CMutableTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) {
 399          UnserializeTransaction(*this, s, params);
 400      }
 401  
 402      template <typename Stream>
 403      CMutableTransaction(deserialize_type, Stream& s) {
 404          Unserialize(s);
 405      }
 406  
 407      /** Compute the hash of this CMutableTransaction. This is computed on the
 408       * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
 409       */
 410      Txid GetHash() const;
 411  
 412      bool HasWitness() const
 413      {
 414          for (size_t i = 0; i < vin.size(); i++) {
 415              if (!vin[i].scriptWitness.IsNull()) {
 416                  return true;
 417              }
 418          }
 419          return false;
 420      }
 421  };
 422  
 423  typedef std::shared_ptr<const CTransaction> CTransactionRef;
 424  template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
 425  
 426  /** A generic txid reference (txid or wtxid). */
 427  class GenTxid
 428  {
 429      bool m_is_wtxid;
 430      uint256 m_hash;
 431      GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
 432  
 433  public:
 434      static GenTxid Txid(const uint256& hash) { return GenTxid{false, hash}; }
 435      static GenTxid Wtxid(const uint256& hash) { return GenTxid{true, hash}; }
 436      bool IsWtxid() const { return m_is_wtxid; }
 437      const uint256& GetHash() const LIFETIMEBOUND { return m_hash; }
 438      friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; }
 439      friend bool operator<(const GenTxid& a, const GenTxid& b) { return std::tie(a.m_is_wtxid, a.m_hash) < std::tie(b.m_is_wtxid, b.m_hash); }
 440  };
 441  
 442  #endif // LIMENKA_PRIMITIVES_TRANSACTION_H
 443