Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2014 The Bitcoin developers
3 : // Copyright (c) 2015-2021 The PIVX Core developers
4 : // Distributed under the MIT software license, see the accompanying
5 : // file COPYING or https://www.opensource.org/licenses/mit-license.php.
6 :
7 : #include "primitives/transaction.h"
8 :
9 : #include "hash.h"
10 : #include "tinyformat.h"
11 : #include "utilstrencodings.h"
12 :
13 440 : std::string BaseOutPoint::ToStringShort() const
14 : {
15 1320 : return strprintf("%s-%u", hash.ToString().substr(0,64), n);
16 : }
17 :
18 770 : std::string COutPoint::ToString() const
19 : {
20 2310 : return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
21 : }
22 :
23 0 : std::string SaplingOutPoint::ToString() const
24 : {
25 0 : return strprintf("SaplingOutPoint(%s, %u)", hash.ToString().substr(0, 10), n);
26 : }
27 :
28 :
29 913 : CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
30 : {
31 913 : prevout = prevoutIn;
32 913 : scriptSig = scriptSigIn;
33 913 : nSequence = nSequenceIn;
34 913 : }
35 :
36 7666 : CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
37 : {
38 7666 : prevout = COutPoint(hashPrevTx, nOut);
39 7666 : scriptSig = scriptSigIn;
40 7666 : nSequence = nSequenceIn;
41 7666 : }
42 :
43 27727233 : bool CTxIn::IsZerocoinSpend() const
44 : {
45 55454566 : return prevout.hash.IsNull() && scriptSig.IsZerocoinSpend();
46 : }
47 :
48 18492738 : bool CTxIn::IsZerocoinPublicSpend() const
49 : {
50 18492738 : return scriptSig.IsZerocoinPublicSpend();
51 : }
52 :
53 672 : std::string CTxIn::ToString() const
54 : {
55 672 : std::string str;
56 672 : str += "CTxIn(";
57 1344 : str += prevout.ToString();
58 672 : if (prevout.IsNull())
59 0 : if(IsZerocoinSpend())
60 0 : str += strprintf(", zerocoinspend %s...", HexStr(scriptSig).substr(0, 25));
61 : else
62 0 : str += strprintf(", coinbase %s", HexStr(scriptSig));
63 : else
64 3498 : str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
65 672 : if (nSequence != std::numeric_limits<unsigned int>::max())
66 0 : str += strprintf(", nSequence=%u", nSequence);
67 672 : str += ")";
68 672 : return str;
69 : }
70 :
71 7041 : CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
72 : {
73 7041 : nValue = nValueIn;
74 7041 : scriptPubKey = scriptPubKeyIn;
75 7041 : nRounds = -10;
76 7041 : }
77 :
78 0 : uint256 CTxOut::GetHash() const
79 : {
80 0 : return SerializeHash(*this);
81 : }
82 :
83 8566956 : bool CTxOut::IsZerocoinMint() const
84 : {
85 8566956 : return scriptPubKey.IsZerocoinMint();
86 : }
87 :
88 654 : std::string CTxOut::ToString() const
89 : {
90 2616 : return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0,30));
91 : }
92 :
93 616541 : CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nType(CTransaction::TxType::NORMAL), nLockTime(0) {}
94 139212 : CMutableTransaction::CMutableTransaction(const CTransaction& tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload) {}
95 :
96 73843 : uint256 CMutableTransaction::GetHash() const
97 : {
98 73843 : return SerializeHash(*this);
99 : }
100 :
101 1301547 : uint256 CTransaction::ComputeHash() const
102 : {
103 1301547 : return SerializeHash(*this);
104 : }
105 :
106 114167 : size_t CTransaction::DynamicMemoryUsage() const
107 : {
108 114167 : return memusage::RecursiveDynamicUsage(vin) + memusage::RecursiveDynamicUsage(vout);
109 : }
110 :
111 : /* For backward compatibility, the hash is initialized to 0. TODO: remove the need for this default constructor entirely. */
112 12860 : CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION), nType(TxType::NORMAL), nLockTime(0), hash() {}
113 1046582 : CTransaction::CTransaction(const CMutableTransaction &tx) : vin(tx.vin), vout(tx.vout), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload), hash(ComputeHash()) {}
114 1557960 : CTransaction::CTransaction(CMutableTransaction &&tx) : vin(std::move(tx.vin)), vout(std::move(tx.vout)), nVersion(tx.nVersion), nType(tx.nType), nLockTime(tx.nLockTime), sapData(tx.sapData), extraPayload(tx.extraPayload), hash(ComputeHash()) {}
115 :
116 12935685 : bool CTransaction::HasZerocoinSpendInputs() const
117 : {
118 30675526 : for (const CTxIn& txin: vin) {
119 17739841 : if (txin.IsZerocoinSpend() || txin.IsZerocoinPublicSpend())
120 0 : return true;
121 : }
122 12935685 : return false;
123 : }
124 :
125 106233 : bool CTransaction::HasZerocoinMintOutputs() const
126 : {
127 337983 : for(const CTxOut& txout : vout) {
128 231750 : if (txout.IsZerocoinMint())
129 0 : return true;
130 : }
131 106233 : return false;
132 : }
133 :
134 8791277 : bool CTransaction::IsCoinStake() const
135 : {
136 8791277 : if (vin.empty())
137 : return false;
138 :
139 8780511 : bool fAllowNull = vin[0].IsZerocoinSpend();
140 8824300 : if (vin[0].prevout.IsNull() && !fAllowNull)
141 : return false;
142 :
143 8736722 : return (vout.size() >= 2 && vout[0].IsEmpty());
144 : }
145 :
146 275538 : bool CTransaction::HasExchangeAddr() const
147 : {
148 879705 : return std::any_of(vout.begin(), vout.end(), [](const auto& txout) { return txout.scriptPubKey.IsPayToExchangeAddress(); });
149 : }
150 :
151 10612 : bool CTransaction::HasP2CSOutputs() const
152 : {
153 22979 : for(const CTxOut& txout : vout) {
154 13248 : if (txout.scriptPubKey.IsPayToColdStaking())
155 881 : return true;
156 : }
157 9731 : return false;
158 : }
159 :
160 8234000 : CAmount CTransaction::GetValueOut() const
161 : {
162 8234000 : CAmount nValueOut = 0;
163 23902497 : for (const CTxOut& out : vout) {
164 : // PIVX: previously MoneyRange() was called here. This has been replaced with negative check and boundary wrap check.
165 15668497 : if (out.nValue < 0)
166 0 : throw std::runtime_error("CTransaction::GetValueOut() : value out of range : less than 0");
167 :
168 15668497 : if (nValueOut + out.nValue < nValueOut)
169 : throw std::runtime_error("CTransaction::GetValueOut() : value out of range : wraps the int64_t boundary");
170 :
171 15668497 : nValueOut += out.nValue;
172 : }
173 :
174 : // Sapling
175 8234000 : if (hasSaplingData() && sapData->valueBalance < 0) {
176 : // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
177 949634 : nValueOut += -sapData->valueBalance;
178 :
179 : // Verify Sapling version
180 949634 : if (!isSaplingVersion())
181 0 : throw std::runtime_error("GetValueOut(): invalid tx version");
182 : }
183 :
184 8234000 : return nValueOut;
185 : }
186 :
187 4181713 : CAmount CTransaction::GetShieldedValueIn() const
188 : {
189 4181713 : CAmount nValue = 0;
190 :
191 4181713 : if (hasSaplingData() && sapData->valueBalance > 0) {
192 : // NB: positive valueBalance "gives" money to the transparent value pool just as inputs do
193 724 : nValue += sapData->valueBalance;
194 :
195 : // Verify Sapling
196 724 : if (!isSaplingVersion())
197 0 : throw std::runtime_error("GetValueOut(): invalid tx version");
198 : }
199 :
200 4181713 : return nValue;
201 : }
202 :
203 301987 : unsigned int CTransaction::GetTotalSize() const
204 : {
205 301987 : return ::GetSerializeSize(*this, PROTOCOL_VERSION);
206 : }
207 :
208 364 : std::string CTransaction::ToString() const
209 : {
210 364 : std::ostringstream ss;
211 728 : ss << "CTransaction(hash=" << GetHash().ToString().substr(0, 10)
212 728 : << ", ver=" << nVersion
213 364 : << ", type=" << nType
214 364 : << ", vin.size=" << vin.size()
215 364 : << ", vout.size=" << vout.size()
216 364 : << ", nLockTime=" << nLockTime;
217 364 : if (IsShieldedTx()) {
218 66 : ss << ", valueBalance=" << sapData->valueBalance
219 66 : << ", vShieldedSpend.size=" << sapData->vShieldedSpend.size()
220 66 : << ", vShieldedOutput.size=" << sapData->vShieldedOutput.size();
221 : }
222 364 : if (IsSpecialTx()) {
223 0 : ss << ", extraPayload.size=" << extraPayload->size();
224 : }
225 364 : ss << ")\n";
226 858 : for (const auto& in : vin)
227 1482 : ss << " " << in.ToString() << "\n";
228 1018 : for (const auto& out : vout)
229 1962 : ss << " " << out.ToString() << "\n";
230 364 : return ss.str();
231 : }
|