1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 <hash.h>
9 #include <script/names.h>
10 #include <tinyformat.h>
11 #include <util/strencodings.h>
12 
13 #include <assert.h>
14 
ToString() const15 std::string COutPoint::ToString() const
16 {
17     return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
18 }
19 
CTxIn(COutPoint prevoutIn,CScript scriptSigIn,uint32_t nSequenceIn)20 CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
21 {
22     prevout = prevoutIn;
23     scriptSig = scriptSigIn;
24     nSequence = nSequenceIn;
25 }
26 
CTxIn(uint256 hashPrevTx,uint32_t nOut,CScript scriptSigIn,uint32_t nSequenceIn)27 CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
28 {
29     prevout = COutPoint(hashPrevTx, nOut);
30     scriptSig = scriptSigIn;
31     nSequence = nSequenceIn;
32 }
33 
ToString() const34 std::string CTxIn::ToString() const
35 {
36     std::string str;
37     str += "CTxIn(";
38     str += prevout.ToString();
39     if (prevout.IsNull())
40         str += strprintf(", coinbase %s", HexStr(scriptSig));
41     else
42         str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
43     if (nSequence != SEQUENCE_FINAL)
44         str += strprintf(", nSequence=%u", nSequence);
45     str += ")";
46     return str;
47 }
48 
CTxOut(const CAmount & nValueIn,CScript scriptPubKeyIn)49 CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
50 {
51     nValue = nValueIn;
52     scriptPubKey = scriptPubKeyIn;
53 }
54 
ToString() const55 std::string CTxOut::ToString() const
56 {
57     return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
58 }
59 
CMutableTransaction()60 CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}
CMutableTransaction(const CTransaction & tx)61 CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime) {}
62 
GetHash() const63 uint256 CMutableTransaction::GetHash() const
64 {
65     return SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS);
66 }
67 
SetNamecoin()68 void CMutableTransaction::SetNamecoin()
69 {
70     assert (nVersion == CTransaction::CURRENT_VERSION);
71     nVersion = CTransaction::NAMECOIN_VERSION;
72 }
73 
ComputeHash() const74 uint256 CTransaction::ComputeHash() const
75 {
76     return SerializeHash(*this, SER_GETHASH, SERIALIZE_TRANSACTION_NO_WITNESS);
77 }
78 
ComputeWitnessHash() const79 uint256 CTransaction::ComputeWitnessHash() const
80 {
81     if (!HasWitness()) {
82         return hash;
83     }
84     return SerializeHash(*this, SER_GETHASH, 0);
85 }
86 
87 /* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */
CTransaction()88 CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION), nLockTime(0), hash{}, m_witness_hash{} {}
CTransaction(const CMutableTransaction & tx)89 CTransaction::CTransaction(const CMutableTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
CTransaction(CMutableTransaction && tx)90 CTransaction::CTransaction(CMutableTransaction&& tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nLockTime(tx.nLockTime), hash{ComputeHash()}, m_witness_hash{ComputeWitnessHash()} {}
91 
GetValueOut(bool fExcludeNames) const92 CAmount CTransaction::GetValueOut(bool fExcludeNames) const
93 {
94     CAmount nValueOut = 0;
95     for (const auto& tx_out : vout) {
96         if (!MoneyRange(tx_out.nValue) || !MoneyRange(nValueOut + tx_out.nValue))
97             throw std::runtime_error(std::string(__func__) + ": value out of range");
98         if (!fExcludeNames || !CNameScript::isNameScript(tx_out.scriptPubKey))
99             nValueOut += tx_out.nValue;
100     }
101     assert(MoneyRange(nValueOut));
102     return nValueOut;
103 }
104 
GetTotalSize() const105 unsigned int CTransaction::GetTotalSize() const
106 {
107     return ::GetSerializeSize(*this, PROTOCOL_VERSION);
108 }
109 
ToString() const110 std::string CTransaction::ToString() const
111 {
112     std::string str;
113     str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\n",
114         GetHash().ToString().substr(0,10),
115         nVersion,
116         vin.size(),
117         vout.size(),
118         nLockTime);
119     for (const auto& tx_in : vin)
120         str += "    " + tx_in.ToString() + "\n";
121     for (const auto& tx_in : vin)
122         str += "    " + tx_in.scriptWitness.ToString() + "\n";
123     for (const auto& tx_out : vout)
124         str += "    " + tx_out.ToString() + "\n";
125     return str;
126 }
127