/ src / primitives / transaction.cpp
transaction.cpp
  1  // Copyright (c) 2009-2010 Satoshi Nakamoto
  2  // Copyright (c) 2009-present 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  #include <primitives/transaction.h>
  7  
  8  #include <consensus/amount.h>
  9  #include <crypto/hex_base.h>
 10  #include <hash.h>
 11  #include <primitives/transaction_identifier.h>
 12  #include <script/script.h>
 13  #include <serialize.h>
 14  #include <tinyformat.h>
 15  
 16  #include <algorithm>
 17  #include <cassert>
 18  #include <span>
 19  #include <stdexcept>
 20  
 21  std::string COutPoint::ToString() const
 22  {
 23      return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
 24  }
 25  
 26  CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
 27  {
 28      prevout = prevoutIn;
 29      scriptSig = scriptSigIn;
 30      nSequence = nSequenceIn;
 31  }
 32  
 33  CTxIn::CTxIn(Txid hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
 34  {
 35      prevout = COutPoint(hashPrevTx, nOut);
 36      scriptSig = scriptSigIn;
 37      nSequence = nSequenceIn;
 38  }
 39  
 40  std::string CTxIn::ToString() const
 41  {
 42      std::string str;
 43      str += "CTxIn(";
 44      str += prevout.ToString();
 45      if (prevout.IsNull())
 46          str += strprintf(", coinbase %s", HexStr(scriptSig));
 47      else
 48          str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
 49      if (nSequence != SEQUENCE_FINAL)
 50          str += strprintf(", nSequence=%u", nSequence);
 51      str += ")";
 52      return str;
 53  }
 54  
 55  CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
 56  {
 57      nValue = nValueIn;
 58      scriptPubKey = scriptPubKeyIn;
 59  }
 60  
 61  std::string CTxOut::ToString() const
 62  {
 63      return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
 64  }
 65  
 66  CMutableTransaction::CMutableTransaction() : version{CTransaction::CURRENT_VERSION}, nLockTime{0} {}
 67  CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), version{tx.version}, nLockTime{tx.nLockTime} {}
 68  
 69  Txid CMutableTransaction::GetHash() const
 70  {
 71      return Txid::FromUint256((HashWriter{} << TX_NO_WITNESS(*this)).GetHash());
 72  }
 73  
 74  bool CTransaction::ComputeHasWitness() const
 75  {
 76      return std::any_of(vin.begin(), vin.end(), [](const auto& input) {
 77          return !input.scriptWitness.IsNull();
 78      });
 79  }
 80  
 81  Txid CTransaction::ComputeHash() const
 82  {
 83      return Txid::FromUint256((HashWriter{} << TX_NO_WITNESS(*this)).GetHash());
 84  }
 85  
 86  Wtxid CTransaction::ComputeWitnessHash() const
 87  {
 88      if (!HasWitness()) {
 89          return Wtxid::FromUint256(hash.ToUint256());
 90      }
 91  
 92      return Wtxid::FromUint256((HashWriter{} << TX_WITH_WITNESS(*this)).GetHash());
 93  }
 94  
 95  CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), version{tx.version}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
 96  CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), version{tx.version}, nLockTime{tx.nLockTime}, m_has_witness{ComputeHasWitness()}, hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
 97  
 98  CAmount CTransaction::GetValueOut() const
 99  {
100      CAmount nValueOut = 0;
101      for (const auto& tx_out : vout) {
102          if (!MoneyRange(tx_out.nValue) || !MoneyRange(nValueOut + tx_out.nValue))
103              throw std::runtime_error(std::string(__func__) + ": value out of range");
104          nValueOut += tx_out.nValue;
105      }
106      assert(MoneyRange(nValueOut));
107      return nValueOut;
108  }
109  
110  unsigned int CTransaction::ComputeTotalSize() const
111  {
112      return ::GetSerializeSize(TX_WITH_WITNESS(*this));
113  }
114  
115  std::string CTransaction::ToString() const
116  {
117      std::string str;
118      str += strprintf("CTransaction(hash=%s, ver=%u, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
119          GetHash().ToString().substr(0,10),
120          version,
121          vin.size(),
122          vout.size(),
123          nLockTime);
124      for (const auto& tx_in : vin)
125          str += "    " + tx_in.ToString() + "\n";
126      for (const auto& tx_in : vin)
127          str += "    " + tx_in.scriptWitness.ToString() + "\n";
128      for (const auto& tx_out : vout)
129          str += "    " + tx_out.ToString() + "\n";
130      return str;
131  }