PIVX Core  5.6.99
P2P Digital Currency
transaction.h
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 
7 #ifndef PIVX_PRIMITIVES_TRANSACTION_H
8 #define PIVX_PRIMITIVES_TRANSACTION_H
9 
10 #include "amount.h"
11 #include "memusage.h"
12 #include "netaddress.h"
13 #include "optional.h"
14 #include "script/script.h"
15 #include "serialize.h"
16 #include "uint256.h"
17 
19 
20 #include <atomic>
21 #include <list>
22 
23 class CTransaction;
24 
26 {
29 };
30 
33 {
34 public:
36  uint32_t n;
37  bool isTransparent{true};
38 
40  BaseOutPoint(const uint256& hashIn, const uint32_t nIn, bool isTransparentIn = true) :
41  hash(hashIn), n(nIn), isTransparent(isTransparentIn) { }
42 
43  SERIALIZE_METHODS(BaseOutPoint, obj) { READWRITE(obj.hash, obj.n); }
44 
45  void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
46  bool IsNull() const { return (hash.IsNull() && n == (uint32_t) -1); }
47 
48  friend bool operator<(const BaseOutPoint& a, const BaseOutPoint& b)
49  {
50  return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));
51  }
52 
53  friend bool operator==(const BaseOutPoint& a, const BaseOutPoint& b)
54  {
55  return (a.hash == b.hash && a.n == b.n);
56  }
57 
58  friend bool operator!=(const BaseOutPoint& a, const BaseOutPoint& b)
59  {
60  return !(a == b);
61  }
62 
63  std::string ToString() const;
64  std::string ToStringShort() const;
65 
66  size_t DynamicMemoryUsage() const { return 0; }
67 
68 };
69 
71 class COutPoint : public BaseOutPoint
72 {
73 public:
75  COutPoint(const uint256& hashIn, const uint32_t nIn) : BaseOutPoint(hashIn, nIn, true) {};
76  std::string ToString() const;
77 };
78 
82 {
83 public:
85  SaplingOutPoint(const uint256& hashIn, const uint32_t nIn) : BaseOutPoint(hashIn, nIn, false) {};
86  std::string ToString() const;
87 };
88 
93 class CTxIn
94 {
95 public:
98  uint32_t nSequence;
99 
100  /* Setting nSequence to this value for every input in a transaction
101  * disables nLockTime. */
102  static const uint32_t SEQUENCE_FINAL = 0xffffffff;
103 
105  explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
106  CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
107 
108  SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
109 
110  bool IsFinal() const { return nSequence == SEQUENCE_FINAL; }
111  bool IsNull() const { return prevout.IsNull() && scriptSig.empty() && IsFinal(); }
112 
113  bool IsZerocoinSpend() const;
114  bool IsZerocoinPublicSpend() const;
115 
116  friend bool operator==(const CTxIn& a, const CTxIn& b)
117  {
118  return (a.prevout == b.prevout &&
119  a.scriptSig == b.scriptSig &&
120  a.nSequence == b.nSequence);
121  }
122 
123  friend bool operator!=(const CTxIn& a, const CTxIn& b)
124  {
125  return !(a == b);
126  }
127 
128  std::string ToString() const;
129 
130  size_t DynamicMemoryUsage() const { return scriptSig.DynamicMemoryUsage(); }
131 };
132 
136 class CTxOut
137 {
138 public:
141  int nRounds;
142 
144  {
145  SetNull();
146  }
147 
148  CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
149 
150  SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
151 
152  void SetNull()
153  {
154  nValue = -1;
156  nRounds = -10; // an initial value, should be no way to get this by calculations
157  }
158 
159  bool IsNull() const
160  {
161  return (nValue == -1);
162  }
163 
164  void SetEmpty()
165  {
166  nValue = 0;
168  }
169 
170  bool IsEmpty() const
171  {
172  return (nValue == 0 && scriptPubKey.empty());
173  }
174 
175  uint256 GetHash() const;
176 
177  bool IsZerocoinMint() const;
178 
179  friend bool operator==(const CTxOut& a, const CTxOut& b)
180  {
181  return (a.nValue == b.nValue &&
182  a.scriptPubKey == b.scriptPubKey &&
183  a.nRounds == b.nRounds);
184  }
185 
186  friend bool operator!=(const CTxOut& a, const CTxOut& b)
187  {
188  return !(a == b);
189  }
190 
191  std::string ToString() const;
192 
194 };
195 
196 struct CMutableTransaction;
197 
207 template<typename Stream, typename TxType>
208 inline void UnserializeTransaction(TxType& tx, Stream& s) {
209  tx.vin.clear();
210  tx.vout.clear();
211 
212  s >> tx.nVersion;
213  s >> tx.nType;
214  s >> tx.vin;
215  s >> tx.vout;
216  s >> tx.nLockTime;
217  if (tx.isSaplingVersion()) {
218  s >> tx.sapData;
219  if (!tx.IsNormalType()) {
220  s >> tx.extraPayload;
221  }
222  }
223 }
224 
225 template<typename Stream, typename TxType>
226 inline void SerializeTransaction(const TxType& tx, Stream& s) {
227  s << tx.nVersion;
228  s << tx.nType;
229  s << tx.vin;
230  s << tx.vout;
231  s << tx.nLockTime;
232  if (tx.isSaplingVersion()) {
233  s << tx.sapData;
234  if (!tx.IsNormalType()) {
235  s << tx.extraPayload;
236  }
237  }
238 }
239 
244 {
245 public:
247  enum TxVersion: int16_t {
248  LEGACY = 1,
249  SAPLING = 3,
250  TOOHIGH
251  };
252 
254  enum TxType: int16_t {
255  NORMAL = 0,
256  PROREG = 1,
258  PROUPREG = 3,
259  PROUPREV = 4,
260  LLMQCOMM = 5,
261  };
262 
263  static const int16_t CURRENT_VERSION = TxVersion::LEGACY;
264 
265  // The local variables are made const to prevent unintended modification
266  // without updating the cached hash value. However, CTransaction is not
267  // actually immutable; deserialization and assignment are implemented,
268  // and bypass the constness. This is safe, as they update the entire
269  // structure, including the hash.
270  std::vector<CTxIn> vin;
271  std::vector<CTxOut> vout;
272  const int16_t nVersion;
273  const int16_t nType;
274  const uint32_t nLockTime;
275  Optional<SaplingTxData> sapData{SaplingTxData()}; // Future: Don't initialize it by default
276  Optional<std::vector<uint8_t>> extraPayload{nullopt}; // only available for special transaction types
277 
279  CTransaction();
280 
284 
285  CTransaction(const CTransaction& tx) = default;
286 
287  template <typename Stream>
288  inline void Serialize(Stream& s) const {
289  SerializeTransaction(*this, s);
290  }
291 
294  template <typename Stream>
296 
297  bool IsNull() const {
298  return vin.empty() && vout.empty();
299  }
300 
301  const uint256& GetHash() const {
302  return hash;
303  }
304 
305  bool hasSaplingData() const
306  {
307  return sapData != nullopt &&
308  (!sapData->vShieldedOutput.empty() ||
309  !sapData->vShieldedSpend.empty() ||
310  sapData->valueBalance != 0 ||
311  sapData->hasBindingSig());
312  };
313 
314  bool isSaplingVersion() const
315  {
316  return nVersion >= TxVersion::SAPLING;
317  }
318 
319  bool IsShieldedTx() const
320  {
321  return isSaplingVersion() && hasSaplingData();
322  }
323 
324  bool hasExtraPayload() const
325  {
326  return extraPayload != nullopt && !extraPayload->empty();
327  }
328 
329  bool IsSpecialTx() const
330  {
331  return isSaplingVersion() && nType != TxType::NORMAL && hasExtraPayload();
332  }
333 
334  bool IsNormalType() const { return nType == TxType::NORMAL; }
335 
336  bool IsProRegTx() const
337  {
338  return IsSpecialTx() && nType == TxType::PROREG;
339  }
340 
341  bool IsQuorumCommitmentTx() const
342  {
343  return IsSpecialTx() && nType == TxType::LLMQCOMM;
344  }
345 
346  // Ensure that special and sapling fields are signed
348  {
350  }
351 
352  /*
353  * Context for the two methods below:
354  * We can think of the Sapling shielded part of the transaction as an input
355  * or output according to whether valueBalance - the sum of shielded input
356  * values minus the sum of shielded output values - is positive or negative.
357  */
358 
359  // Return sum of txouts.
360  CAmount GetValueOut() const;
361  // GetValueIn() is a method on CCoinsViewCache, because
362  // inputs must be known to compute value in.
363 
364  // Return sum of (positive valueBalance or zero) and JoinSplit vpub_new
365  CAmount GetShieldedValueIn() const;
366 
367  bool HasZerocoinSpendInputs() const;
368 
369  bool HasZerocoinMintOutputs() const;
370 
371  bool ContainsZerocoins() const
372  {
374  }
375 
376  bool IsCoinBase() const
377  {
378  return (vin.size() == 1 && vin[0].prevout.IsNull() && !vin[0].scriptSig.IsZerocoinSpend());
379  }
380 
381  bool IsCoinStake() const;
382  bool HasP2CSOutputs() const;
383  bool HasExchangeAddr() const;
384 
385  friend bool operator==(const CTransaction& a, const CTransaction& b)
386  {
387  return a.hash == b.hash;
388  }
389 
390  friend bool operator!=(const CTransaction& a, const CTransaction& b)
391  {
392  return a.hash != b.hash;
393  }
394 
395  unsigned int GetTotalSize() const;
396 
397  std::string ToString() const;
398 
399  size_t DynamicMemoryUsage() const;
400 
401 private:
403  const uint256 hash;
404  uint256 ComputeHash() const;
405 };
406 
409 {
410  std::vector<CTxIn> vin;
411  std::vector<CTxOut> vout;
412  int16_t nVersion;
413  int16_t nType;
414  uint32_t nLockTime;
415  Optional<SaplingTxData> sapData{SaplingTxData()}; // Future: Don't initialize it by default
417 
420 
421  template <typename Stream>
422  inline void Serialize(Stream& s) const {
423  SerializeTransaction(*this, s);
424  }
425 
426  template <typename Stream>
427  inline void Unserialize(Stream& s) {
428  UnserializeTransaction(*this, s);
429  }
430 
431  template <typename Stream>
433  Unserialize(s);
434  }
435 
437  bool IsNormalType() const { return nType == CTransaction::TxType::NORMAL; }
438 
442  uint256 GetHash() const;
443 
444  bool hasExtraPayload() const
445  {
446  return extraPayload != nullopt && !extraPayload->empty();
447  }
448 
449  // Ensure that special and sapling fields are signed
451  {
453  }
454 };
455 
456 typedef std::shared_ptr<const CTransaction> CTransactionRef;
457 static inline CTransactionRef MakeTransactionRef() { return std::make_shared<const CTransaction>(); }
458 template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
459 static inline CTransactionRef MakeTransactionRef(const CTransactionRef& txIn) { return txIn; }
460 static inline CTransactionRef MakeTransactionRef(CTransactionRef&& txIn) { return std::move(txIn); }
461 
462 /* Special tx payload handling */
463 template <typename T>
464 inline bool GetTxPayload(const std::vector<unsigned char>& payload, T& obj)
465 {
466  CDataStream ds(payload, SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
467  try {
468  ds >> obj;
469  } catch (std::exception& e) {
470  return false;
471  }
472  return ds.empty();
473 }
474 template <typename T>
475 inline bool GetTxPayload(const CMutableTransaction& tx, T& obj)
476 {
477  return tx.hasExtraPayload() && GetTxPayload(*tx.extraPayload, obj);
478 }
479 template <typename T>
480 inline bool GetTxPayload(const CTransaction& tx, T& obj)
481 {
482  return tx.hasExtraPayload() && GetTxPayload(*tx.extraPayload, obj);
483 }
484 
485 template <typename T>
486 void SetTxPayload(CMutableTransaction& tx, const T& payload)
487 {
488  CDataStream ds(SER_NETWORK, PROTOCOL_VERSION | ADDRV2_FORMAT);
489  ds << payload;
490  tx.extraPayload.emplace(ds.begin(), ds.end());
491 }
492 
493 #endif // PIVX_PRIMITIVES_TRANSACTION_H
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
true
Definition: bls_dkg.cpp:153
false
Definition: bls_dkg.cpp:151
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:33
std::string ToString() const
friend bool operator==(const BaseOutPoint &a, const BaseOutPoint &b)
Definition: transaction.h:53
friend bool operator!=(const BaseOutPoint &a, const BaseOutPoint &b)
Definition: transaction.h:58
BaseOutPoint(const uint256 &hashIn, const uint32_t nIn, bool isTransparentIn=true)
Definition: transaction.h:40
uint256 hash
Definition: transaction.h:35
friend bool operator<(const BaseOutPoint &a, const BaseOutPoint &b)
Definition: transaction.h:48
bool isTransparent
Definition: transaction.h:37
bool IsNull() const
Definition: transaction.h:46
std::string ToStringShort() const
Definition: transaction.cpp:13
uint32_t n
Definition: transaction.h:36
SERIALIZE_METHODS(BaseOutPoint, obj)
Definition: transaction.h:43
size_t DynamicMemoryUsage() const
Definition: transaction.h:66
void SetNull()
Definition: transaction.h:45
const_iterator end() const
Definition: streams.h:163
const_iterator begin() const
Definition: streams.h:161
bool empty() const
Definition: streams.h:166
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
COutPoint(const uint256 &hashIn, const uint32_t nIn)
Definition: transaction.h:75
std::string ToString() const
Definition: transaction.cpp:18
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
void clear()
Definition: script.h:659
size_t DynamicMemoryUsage() const
Definition: script.cpp:307
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
friend bool operator==(const CTransaction &a, const CTransaction &b)
Definition: transaction.h:385
bool IsNormalType() const
Definition: transaction.h:334
bool HasZerocoinSpendInputs() const
CTransaction()
Construct a CTransaction that qualifies as IsNull()
bool HasExchangeAddr() const
bool IsQuorumCommitmentTx() const
Definition: transaction.h:341
bool IsNull() const
Definition: transaction.h:297
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
CTransaction(deserialize_type, Stream &s)
This deserializing constructor is provided instead of an Unserialize method.
Definition: transaction.h:295
bool IsShieldedTx() const
Definition: transaction.h:319
bool hasExtraPayload() const
Definition: transaction.h:324
bool HasZerocoinMintOutputs() const
bool ContainsZerocoins() const
Definition: transaction.h:371
SigVersion GetRequiredSigVersion() const
Definition: transaction.h:347
void Serialize(Stream &s) const
Definition: transaction.h:288
size_t DynamicMemoryUsage() const
TxVersion
Transaction Versions.
Definition: transaction.h:247
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 IsCoinBase() const
Definition: transaction.h:376
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
friend bool operator!=(const CTransaction &a, const CTransaction &b)
Definition: transaction.h:390
TxType
Transaction types.
Definition: transaction.h:254
bool IsCoinStake() const
std::vector< CTxOut > vout
Definition: transaction.h:271
static const int16_t CURRENT_VERSION
Definition: transaction.h:263
const uint256 hash
Memory only.
Definition: transaction.h:403
bool IsProRegTx() const
Definition: transaction.h:336
CTransaction(const CTransaction &tx)=default
bool hasSaplingData() const
Definition: transaction.h:305
An input of a transaction.
Definition: transaction.h:94
friend bool operator==(const CTxIn &a, const CTxIn &b)
Definition: transaction.h:116
bool IsNull() const
Definition: transaction.h:111
bool IsZerocoinSpend() const
Definition: transaction.cpp:43
friend bool operator!=(const CTxIn &a, const CTxIn &b)
Definition: transaction.h:123
size_t DynamicMemoryUsage() const
Definition: transaction.h:130
uint32_t nSequence
Definition: transaction.h:98
static const uint32_t SEQUENCE_FINAL
Definition: transaction.h:102
bool IsZerocoinPublicSpend() const
Definition: transaction.cpp:48
std::string ToString() const
Definition: transaction.cpp:53
CScript scriptSig
Definition: transaction.h:97
bool IsFinal() const
Definition: transaction.h:110
COutPoint prevout
Definition: transaction.h:96
SERIALIZE_METHODS(CTxIn, obj)
Definition: transaction.h:108
An output of a transaction.
Definition: transaction.h:137
CScript scriptPubKey
Definition: transaction.h:140
SERIALIZE_METHODS(CTxOut, obj)
Definition: transaction.h:150
friend bool operator==(const CTxOut &a, const CTxOut &b)
Definition: transaction.h:179
bool IsZerocoinMint() const
Definition: transaction.cpp:83
friend bool operator!=(const CTxOut &a, const CTxOut &b)
Definition: transaction.h:186
void SetNull()
Definition: transaction.h:152
CAmount nValue
Definition: transaction.h:139
bool IsNull() const
Definition: transaction.h:159
bool IsEmpty() const
Definition: transaction.h:170
int nRounds
Definition: transaction.h:141
size_t DynamicMemoryUsage() const
Definition: transaction.h:193
void SetEmpty()
Definition: transaction.h:164
uint256 GetHash() const
Definition: transaction.cpp:78
std::string ToString() const
Definition: transaction.cpp:88
An outpoint - a combination of a transaction hash and an index n into its sapling output description ...
Definition: transaction.h:82
SaplingOutPoint(const uint256 &hashIn, const uint32_t nIn)
Definition: transaction.h:85
std::string ToString() const
Definition: transaction.cpp:23
void SetNull()
Definition: uint256.h:44
bool IsNull() const
Definition: uint256.h:36
bool empty() const
Definition: prevector.h:281
256-bit opaque blob.
Definition: uint256.h:138
#define T(expected, seed, data)
@ SAPLING
Definition: logging.h:63
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
@ SER_NETWORK
Definition: serialize.h:174
constexpr deserialize_type deserialize
Definition: serialize.h:57
#define READWRITE(...)
Definition: serialize.h:183
A mutable version of CTransaction.
Definition: transaction.h:409
bool IsNormalType() const
Definition: transaction.h:437
Optional< std::vector< uint8_t > > extraPayload
Definition: transaction.h:416
Optional< SaplingTxData > sapData
Definition: transaction.h:415
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:96
void Unserialize(Stream &s)
Definition: transaction.h:427
bool hasExtraPayload() const
Definition: transaction.h:444
void Serialize(Stream &s) const
Definition: transaction.h:422
SigVersion GetRequiredSigVersion() const
Definition: transaction.h:450
CMutableTransaction(deserialize_type, Stream &s)
Definition: transaction.h:432
std::vector< CTxOut > vout
Definition: transaction.h:411
std::vector< CTxIn > vin
Definition: transaction.h:410
bool isSaplingVersion() const
Definition: transaction.h:436
Dummy data type to identify deserializing constructors.
Definition: serialize.h:56
void UnserializeTransaction(TxType &tx, Stream &s)
Transaction serialization format:
Definition: transaction.h:208
void SetTxPayload(CMutableTransaction &tx, const T &payload)
Definition: transaction.h:486
SigVersion
Definition: transaction.h:26
@ SIGVERSION_SAPLING
Definition: transaction.h:28
@ SIGVERSION_BASE
Definition: transaction.h:27
void SerializeTransaction(const TxType &tx, Stream &s)
Definition: transaction.h:226
bool GetTxPayload(const std::vector< unsigned char > &payload, T &obj)
Definition: transaction.h:464
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:456