transaction.h raw
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 The Limenka 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 #ifndef LIMENKA_PRIMITIVES_TRANSACTION_H
7 #define LIMENKA_PRIMITIVES_TRANSACTION_H
8
9 #include <attributes.h>
10 #include <consensus/amount.h>
11 #include <script/script.h>
12 #include <serialize.h>
13 #include <uint256.h>
14 #include <util/transaction_identifier.h> // IWYU pragma: export
15
16 #include <cstddef>
17 #include <cstdint>
18 #include <ios>
19 #include <limits>
20 #include <memory>
21 #include <numeric>
22 #include <string>
23 #include <tuple>
24 #include <utility>
25 #include <vector>
26
27 /** An outpoint - a combination of a transaction hash and an index n into its vout */
28 class COutPoint
29 {
30 public:
31 Txid hash;
32 uint32_t n;
33
34 static constexpr uint32_t NULL_INDEX = std::numeric_limits<uint32_t>::max();
35
36 COutPoint(): n(NULL_INDEX) { }
37 COutPoint(const Txid& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
38
39 SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
40
41 void SetNull() { hash.SetNull(); n = NULL_INDEX; }
42 bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
43
44 friend bool operator<(const COutPoint& a, const COutPoint& b)
45 {
46 return std::tie(a.hash, a.n) < std::tie(b.hash, b.n);
47 }
48
49 friend bool operator==(const COutPoint& a, const COutPoint& b)
50 {
51 return (a.hash == b.hash && a.n == b.n);
52 }
53
54 friend bool operator!=(const COutPoint& a, const COutPoint& b)
55 {
56 return !(a == b);
57 }
58
59 std::string ToString() const;
60 };
61
62 /** An input of a transaction. It contains the location of the previous
63 * transaction's output that it claims and a signature that matches the
64 * output's public key.
65 */
66 class CTxIn
67 {
68 public:
69 COutPoint prevout;
70 CScript scriptSig;
71 uint32_t nSequence;
72 CScriptWitness scriptWitness; //!< Only serialized through CTransaction
73
74 /**
75 * Setting nSequence to this value for every input in a transaction
76 * disables nLockTime/IsFinalTx().
77 * It fails OP_CHECKLOCKTIMEVERIFY/CheckLockTime() for any input that has
78 * it set (BIP 65).
79 * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
80 */
81 static const uint32_t SEQUENCE_FINAL = 0xffffffff;
82 /**
83 * This is the maximum sequence number that enables both nLockTime and
84 * OP_CHECKLOCKTIMEVERIFY (BIP 65).
85 * It has SEQUENCE_LOCKTIME_DISABLE_FLAG set (BIP 68/112).
86 */
87 static const uint32_t MAX_SEQUENCE_NONFINAL{SEQUENCE_FINAL - 1};
88
89 // Below flags apply in the context of BIP 68. BIP 68 requires the tx
90 // version to be set to 2, or higher.
91 /**
92 * If this flag is set, CTxIn::nSequence is NOT interpreted as a
93 * relative lock-time.
94 * It skips SequenceLocks() for any input that has it set (BIP 68).
95 * It fails OP_CHECKSEQUENCEVERIFY/CheckSequence() for any input that has
96 * it set (BIP 112).
97 */
98 static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1U << 31);
99
100 /**
101 * If CTxIn::nSequence encodes a relative lock-time and this flag
102 * is set, the relative lock-time has units of 512 seconds,
103 * otherwise it specifies blocks with a granularity of 1. */
104 static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
105
106 /**
107 * If CTxIn::nSequence encodes a relative lock-time, this mask is
108 * applied to extract that lock-time from the sequence field. */
109 static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
110
111 /**
112 * In order to use the same number of bits to encode roughly the
113 * same wall-clock duration, and because blocks are naturally
114 * limited to occur every 600s on average, the minimum granularity
115 * for time-based relative lock-time is fixed at 512 seconds.
116 * Converting from CTxIn::nSequence to seconds is performed by
117 * multiplying by 512 = 2^9, or equivalently shifting up by
118 * 9 bits. */
119 static const int SEQUENCE_LOCKTIME_GRANULARITY = 9;
120
121 CTxIn()
122 {
123 nSequence = SEQUENCE_FINAL;
124 }
125
126 explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
127 CTxIn(Txid hashPrevTx, uint32_t nOut, CScript scriptSigIn=CScript(), uint32_t nSequenceIn=SEQUENCE_FINAL);
128
129 SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
130
131 friend bool operator==(const CTxIn& a, const CTxIn& b)
132 {
133 return (a.prevout == b.prevout &&
134 a.scriptSig == b.scriptSig &&
135 a.nSequence == b.nSequence);
136 }
137
138 friend bool operator!=(const CTxIn& a, const CTxIn& b)
139 {
140 return !(a == b);
141 }
142
143 std::string ToString() const;
144 };
145
146 /** An output of a transaction. It contains the public key that the next input
147 * must be able to sign with to claim it.
148 */
149 class CTxOut
150 {
151 public:
152 CAmount nValue;
153 CScript scriptPubKey;
154
155 CTxOut()
156 {
157 SetNull();
158 }
159
160 CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
161
162 SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
163
164 void SetNull()
165 {
166 nValue = -1;
167 scriptPubKey.clear();
168 }
169
170 bool IsNull() const
171 {
172 return (nValue == -1);
173 }
174
175 friend bool operator==(const CTxOut& a, const CTxOut& b)
176 {
177 return (a.nValue == b.nValue &&
178 a.scriptPubKey == b.scriptPubKey);
179 }
180
181 friend bool operator!=(const CTxOut& a, const CTxOut& b)
182 {
183 return !(a == b);
184 }
185
186 std::string ToString() const;
187 };
188
189 struct CMutableTransaction;
190
191 struct TransactionSerParams {
192 const bool allow_witness;
193 SER_PARAMS_OPFUNC
194 };
195 static constexpr TransactionSerParams TX_WITH_WITNESS{.allow_witness = true};
196 static constexpr TransactionSerParams TX_NO_WITNESS{.allow_witness = false};
197
198 /**
199 * Basic transaction serialization format:
200 * - uint32_t version
201 * - std::vector<CTxIn> vin
202 * - std::vector<CTxOut> vout
203 * - uint32_t nLockTime
204 *
205 * Extended transaction serialization format:
206 * - uint32_t version
207 * - unsigned char dummy = 0x00
208 * - unsigned char flags (!= 0)
209 * - std::vector<CTxIn> vin
210 * - std::vector<CTxOut> vout
211 * - if (flags & 1):
212 * - CScriptWitness scriptWitness; (deserialized into CTxIn)
213 * - uint32_t nLockTime
214 */
215 template<typename Stream, typename TxType>
216 void UnserializeTransaction(TxType& tx, Stream& s, const TransactionSerParams& params)
217 {
218 const bool fAllowWitness = params.allow_witness;
219
220 s >> tx.version;
221 unsigned char flags = 0;
222 tx.vin.clear();
223 tx.vout.clear();
224 /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
225 s >> tx.vin;
226 if (tx.vin.size() == 0 && fAllowWitness) {
227 /* We read a dummy or an empty vin. */
228 s >> flags;
229 if (flags != 0) {
230 s >> tx.vin;
231 s >> tx.vout;
232 }
233 } else {
234 /* We read a non-empty vin. Assume a normal vout follows. */
235 s >> tx.vout;
236 }
237 if ((flags & 1) && fAllowWitness) {
238 /* The witness flag is present, and we support witnesses. */
239 flags ^= 1;
240 for (size_t i = 0; i < tx.vin.size(); i++) {
241 s >> tx.vin[i].scriptWitness.stack;
242 }
243 if (!tx.HasWitness()) {
244 /* It's illegal to encode witnesses when all witness stacks are empty. */
245 throw std::ios_base::failure("Superfluous witness record");
246 }
247 }
248 if (flags) {
249 /* Unknown flag in the serialization */
250 throw std::ios_base::failure("Unknown transaction optional data");
251 }
252 s >> tx.nLockTime;
253 }
254
255 template<typename Stream, typename TxType>
256 void SerializeTransaction(const TxType& tx, Stream& s, const TransactionSerParams& params)
257 {
258 const bool fAllowWitness = params.allow_witness;
259
260 s << tx.version;
261 unsigned char flags = 0;
262 // Consistency check
263 if (fAllowWitness) {
264 /* Check whether witnesses need to be serialized. */
265 if (tx.HasWitness()) {
266 flags |= 1;
267 }
268 }
269 if (flags) {
270 /* Use extended format in case witnesses are to be serialized. */
271 std::vector<CTxIn> vinDummy;
272 s << vinDummy;
273 s << flags;
274 }
275 s << tx.vin;
276 s << tx.vout;
277 if (flags & 1) {
278 for (size_t i = 0; i < tx.vin.size(); i++) {
279 s << tx.vin[i].scriptWitness.stack;
280 }
281 }
282 s << tx.nLockTime;
283 }
284
285 template<typename TxType>
286 inline CAmount CalculateOutputValue(const TxType& tx)
287 {
288 return std::accumulate(tx.vout.cbegin(), tx.vout.cend(), CAmount{0}, [](CAmount sum, const auto& txout) { return sum + txout.nValue; });
289 }
290
291
292 /** The basic transaction that is broadcasted on the network and contained in
293 * blocks. A transaction can contain multiple inputs and outputs.
294 */
295 class CTransaction
296 {
297 public:
298 // Default transaction version.
299 static const uint32_t CURRENT_VERSION{2};
300
301 // The local variables are made const to prevent unintended modification
302 // without updating the cached hash value. However, CTransaction is not
303 // actually immutable; deserialization and assignment are implemented,
304 // and bypass the constness. This is safe, as they update the entire
305 // structure, including the hash.
306 const std::vector<CTxIn> vin;
307 const std::vector<CTxOut> vout;
308 const uint32_t version;
309 const uint32_t nLockTime;
310
311 private:
312 /** Memory only. */
313 const bool m_has_witness;
314 const Txid hash;
315 const Wtxid m_witness_hash;
316
317 Txid ComputeHash() const;
318 Wtxid ComputeWitnessHash() const;
319
320 bool ComputeHasWitness() const;
321
322 public:
323 /** Convert a CMutableTransaction into a CTransaction. */
324 explicit CTransaction(const CMutableTransaction& tx);
325 explicit CTransaction(CMutableTransaction&& tx);
326
327 template <typename Stream>
328 inline void Serialize(Stream& s) const {
329 SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
330 }
331
332 /** This deserializing constructor is provided instead of an Unserialize method.
333 * Unserialize is not possible, since it would require overwriting const fields. */
334 template <typename Stream>
335 CTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) : CTransaction(CMutableTransaction(deserialize, params, s)) {}
336 template <typename Stream>
337 CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
338
339 bool IsNull() const {
340 return vin.empty() && vout.empty();
341 }
342
343 const Txid& GetHash() const LIFETIMEBOUND { return hash; }
344 const Wtxid& GetWitnessHash() const LIFETIMEBOUND { return m_witness_hash; };
345
346 // Return sum of txouts.
347 CAmount GetValueOut() const;
348
349 /**
350 * Get the total transaction size in bytes, including witness data.
351 * "Total Size" defined in BIP141 and BIP144.
352 * @return Total transaction size in bytes
353 */
354 unsigned int GetTotalSize() const;
355
356 bool IsCoinBase() const
357 {
358 return (vin.size() == 1 && vin[0].prevout.IsNull());
359 }
360
361 friend bool operator==(const CTransaction& a, const CTransaction& b)
362 {
363 return a.hash == b.hash;
364 }
365
366 friend bool operator!=(const CTransaction& a, const CTransaction& b)
367 {
368 return a.hash != b.hash;
369 }
370
371 std::string ToString() const;
372
373 bool HasWitness() const { return m_has_witness; }
374 };
375
376 /** A mutable version of CTransaction. */
377 struct CMutableTransaction
378 {
379 std::vector<CTxIn> vin;
380 std::vector<CTxOut> vout;
381 uint32_t version;
382 uint32_t nLockTime;
383
384 explicit CMutableTransaction();
385 explicit CMutableTransaction(const CTransaction& tx);
386
387 template <typename Stream>
388 inline void Serialize(Stream& s) const {
389 SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
390 }
391
392 template <typename Stream>
393 inline void Unserialize(Stream& s) {
394 UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
395 }
396
397 template <typename Stream>
398 CMutableTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) {
399 UnserializeTransaction(*this, s, params);
400 }
401
402 template <typename Stream>
403 CMutableTransaction(deserialize_type, Stream& s) {
404 Unserialize(s);
405 }
406
407 /** Compute the hash of this CMutableTransaction. This is computed on the
408 * fly, as opposed to GetHash() in CTransaction, which uses a cached result.
409 */
410 Txid GetHash() const;
411
412 bool HasWitness() const
413 {
414 for (size_t i = 0; i < vin.size(); i++) {
415 if (!vin[i].scriptWitness.IsNull()) {
416 return true;
417 }
418 }
419 return false;
420 }
421 };
422
423 typedef std::shared_ptr<const CTransaction> CTransactionRef;
424 template <typename Tx> static inline CTransactionRef MakeTransactionRef(Tx&& txIn) { return std::make_shared<const CTransaction>(std::forward<Tx>(txIn)); }
425
426 /** A generic txid reference (txid or wtxid). */
427 class GenTxid
428 {
429 bool m_is_wtxid;
430 uint256 m_hash;
431 GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
432
433 public:
434 static GenTxid Txid(const uint256& hash) { return GenTxid{false, hash}; }
435 static GenTxid Wtxid(const uint256& hash) { return GenTxid{true, hash}; }
436 bool IsWtxid() const { return m_is_wtxid; }
437 const uint256& GetHash() const LIFETIMEBOUND { return m_hash; }
438 friend bool operator==(const GenTxid& a, const GenTxid& b) { return a.m_is_wtxid == b.m_is_wtxid && a.m_hash == b.m_hash; }
439 friend bool operator<(const GenTxid& a, const GenTxid& b) { return std::tie(a.m_is_wtxid, a.m_hash) < std::tie(b.m_is_wtxid, b.m_hash); }
440 };
441
442 #endif // LIMENKA_PRIMITIVES_TRANSACTION_H
443