PIVX Core  5.6.99
P2P Digital Currency
transaction.cpp
Go to the documentation of this file.
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 
8 
9 #include "hash.h"
10 #include "tinyformat.h"
11 #include "utilstrencodings.h"
12 
13 std::string BaseOutPoint::ToStringShort() const
14 {
15  return strprintf("%s-%u", hash.ToString().substr(0,64), n);
16 }
17 
18 std::string COutPoint::ToString() const
19 {
20  return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
21 }
22 
23 std::string SaplingOutPoint::ToString() const
24 {
25  return strprintf("SaplingOutPoint(%s, %u)", hash.ToString().substr(0, 10), n);
26 }
27 
28 
29 CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
30 {
31  prevout = prevoutIn;
32  scriptSig = scriptSigIn;
33  nSequence = nSequenceIn;
34 }
35 
36 CTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)
37 {
38  prevout = COutPoint(hashPrevTx, nOut);
39  scriptSig = scriptSigIn;
40  nSequence = nSequenceIn;
41 }
42 
44 {
46 }
47 
49 {
51 }
52 
53 std::string CTxIn::ToString() const
54 {
55  std::string str;
56  str += "CTxIn(";
57  str += prevout.ToString();
58  if (prevout.IsNull())
59  if(IsZerocoinSpend())
60  str += strprintf(", zerocoinspend %s...", HexStr(scriptSig).substr(0, 25));
61  else
62  str += strprintf(", coinbase %s", HexStr(scriptSig));
63  else
64  str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
65  if (nSequence != std::numeric_limits<unsigned int>::max())
66  str += strprintf(", nSequence=%u", nSequence);
67  str += ")";
68  return str;
69 }
70 
71 CTxOut::CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn)
72 {
73  nValue = nValueIn;
74  scriptPubKey = scriptPubKeyIn;
75  nRounds = -10;
76 }
77 
79 {
80  return SerializeHash(*this);
81 }
82 
84 {
86 }
87 
88 std::string CTxOut::ToString() const
89 {
90  return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0,30));
91 }
92 
93 CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nType(CTransaction::TxType::NORMAL), nLockTime(0) {}
94 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 
97 {
98  return SerializeHash(*this);
99 }
100 
102 {
103  return SerializeHash(*this);
104 }
105 
107 {
108  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 CTransaction::CTransaction() : vin(), vout(), nVersion(CTransaction::CURRENT_VERSION), nType(TxType::NORMAL), nLockTime(0), hash() {}
113 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 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 
117 {
118  for (const CTxIn& txin: vin) {
119  if (txin.IsZerocoinSpend() || txin.IsZerocoinPublicSpend())
120  return true;
121  }
122  return false;
123 }
124 
126 {
127  for(const CTxOut& txout : vout) {
128  if (txout.IsZerocoinMint())
129  return true;
130  }
131  return false;
132 }
133 
135 {
136  if (vin.empty())
137  return false;
138 
139  bool fAllowNull = vin[0].IsZerocoinSpend();
140  if (vin[0].prevout.IsNull() && !fAllowNull)
141  return false;
142 
143  return (vout.size() >= 2 && vout[0].IsEmpty());
144 }
145 
147 {
148  return std::any_of(vout.begin(), vout.end(), [](const auto& txout) { return txout.scriptPubKey.IsPayToExchangeAddress(); });
149 }
150 
152 {
153  for(const CTxOut& txout : vout) {
154  if (txout.scriptPubKey.IsPayToColdStaking())
155  return true;
156  }
157  return false;
158 }
159 
161 {
162  CAmount nValueOut = 0;
163  for (const CTxOut& out : vout) {
164  // PIVX: previously MoneyRange() was called here. This has been replaced with negative check and boundary wrap check.
165  if (out.nValue < 0)
166  throw std::runtime_error("CTransaction::GetValueOut() : value out of range : less than 0");
167 
168  if (nValueOut + out.nValue < nValueOut)
169  throw std::runtime_error("CTransaction::GetValueOut() : value out of range : wraps the int64_t boundary");
170 
171  nValueOut += out.nValue;
172  }
173 
174  // Sapling
175  if (hasSaplingData() && sapData->valueBalance < 0) {
176  // NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
177  nValueOut += -sapData->valueBalance;
178 
179  // Verify Sapling version
180  if (!isSaplingVersion())
181  throw std::runtime_error("GetValueOut(): invalid tx version");
182  }
183 
184  return nValueOut;
185 }
186 
188 {
189  CAmount nValue = 0;
190 
191  if (hasSaplingData() && sapData->valueBalance > 0) {
192  // NB: positive valueBalance "gives" money to the transparent value pool just as inputs do
193  nValue += sapData->valueBalance;
194 
195  // Verify Sapling
196  if (!isSaplingVersion())
197  throw std::runtime_error("GetValueOut(): invalid tx version");
198  }
199 
200  return nValue;
201 }
202 
203 unsigned int CTransaction::GetTotalSize() const
204 {
205  return ::GetSerializeSize(*this, PROTOCOL_VERSION);
206 }
207 
208 std::string CTransaction::ToString() const
209 {
210  std::ostringstream ss;
211  ss << "CTransaction(hash=" << GetHash().ToString().substr(0, 10)
212  << ", ver=" << nVersion
213  << ", type=" << nType
214  << ", vin.size=" << vin.size()
215  << ", vout.size=" << vout.size()
216  << ", nLockTime=" << nLockTime;
217  if (IsShieldedTx()) {
218  ss << ", valueBalance=" << sapData->valueBalance
219  << ", vShieldedSpend.size=" << sapData->vShieldedSpend.size()
220  << ", vShieldedOutput.size=" << sapData->vShieldedOutput.size();
221  }
222  if (IsSpecialTx()) {
223  ss << ", extraPayload.size=" << extraPayload->size();
224  }
225  ss << ")\n";
226  for (const auto& in : vin)
227  ss << " " << in.ToString() << "\n";
228  for (const auto& out : vout)
229  ss << " " << out.ToString() << "\n";
230  return ss.str();
231 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
uint256 hash
Definition: transaction.h:35
bool IsNull() const
Definition: transaction.h:46
std::string ToStringShort() const
Definition: transaction.cpp:13
uint32_t n
Definition: transaction.h:36
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
std::string ToString() const
Definition: transaction.cpp:18
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
bool IsZerocoinSpend() const
Definition: script.cpp:275
bool IsZerocoinPublicSpend() const
Definition: script.cpp:280
bool IsZerocoinMint() const
Definition: script.cpp:270
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
bool HasZerocoinSpendInputs() const
CTransaction()
Construct a CTransaction that qualifies as IsNull()
bool HasExchangeAddr() const
const int16_t nType
Definition: transaction.h:273
std::vector< CTxIn > vin
Definition: transaction.h:270
const uint32_t nLockTime
Definition: transaction.h:274
const int16_t nVersion
Definition: transaction.h:272
bool IsShieldedTx() const
Definition: transaction.h:319
bool HasZerocoinMintOutputs() const
size_t DynamicMemoryUsage() const
uint256 ComputeHash() const
const uint256 & GetHash() const
Definition: transaction.h:301
std::string ToString() const
CAmount GetShieldedValueIn() const
Optional< std::vector< uint8_t > > extraPayload
Definition: transaction.h:276
unsigned int GetTotalSize() const
bool IsSpecialTx() const
Definition: transaction.h:329
CAmount GetValueOut() const
Optional< SaplingTxData > sapData
Definition: transaction.h:275
bool HasP2CSOutputs() const
bool isSaplingVersion() const
Definition: transaction.h:314
TxType
Transaction types.
Definition: transaction.h:254
bool IsCoinStake() const
std::vector< CTxOut > vout
Definition: transaction.h:271
bool hasSaplingData() const
Definition: transaction.h:305
An input of a transaction.
Definition: transaction.h:94
bool IsZerocoinSpend() const
Definition: transaction.cpp:43
uint32_t nSequence
Definition: transaction.h:98
bool IsZerocoinPublicSpend() const
Definition: transaction.cpp:48
std::string ToString() const
Definition: transaction.cpp:53
CScript scriptSig
Definition: transaction.h:97
COutPoint prevout
Definition: transaction.h:96
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
bool IsZerocoinMint() const
Definition: transaction.cpp:83
CAmount nValue
Definition: transaction.h:139
int nRounds
Definition: transaction.h:141
uint256 GetHash() const
Definition: transaction.cpp:78
std::string ToString() const
Definition: transaction.cpp:88
std::string ToString() const
Definition: transaction.cpp:23
std::string ToString() const
Definition: uint256.cpp:65
bool IsNull() const
Definition: uint256.h:36
256-bit opaque blob.
Definition: uint256.h:138
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object's serialization.
Definition: hash.h:289
Definition: uint256.h:212
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
Definition: serialize.h:847
A mutable version of CTransaction.
Definition: transaction.h:409
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:96
#define strprintf
Definition: tinyformat.h:1056
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.