Branch data Line data Source code
1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-2022 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 : : #ifndef BITCOIN_PRIMITIVES_TRANSACTION_H
7 : : #define BITCOIN_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 [ + - + - ]: 545080 : COutPoint(): n(NULL_INDEX) { }
[ + + ]
37 [ + + ]: 655338 : COutPoint(const Txid& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
[ + - + - ]
[ + - + +
+ - ][ + -
+ - + - +
- # # # #
# # # # #
# # # #
# ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - ][ +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ][ + - +
- + - + -
+ - ][ + -
+ - + - +
- + - + -
+ - + - #
# ][ + - +
- + - + -
+ - + - +
- + - + -
+ - + - #
# ][ + - +
- + - + -
+ - + + +
- + - + -
# # # # #
# # # ]
38 : :
39 : 21434837 : SERIALIZE_METHODS(COutPoint, obj) { READWRITE(obj.hash, obj.n); }
40 : :
41 [ + - ][ + - : 17578 : void SetNull() { hash.SetNull(); n = NULL_INDEX; }
+ - + - +
- ]
42 [ + + - + ]: 424718 : bool IsNull() const { return (hash.IsNull() && n == NULL_INDEX); }
43 : :
44 : 89710259 : friend bool operator<(const COutPoint& a, const COutPoint& b)
45 : : {
46 : 89710259 : return std::tie(a.hash, a.n) < std::tie(b.hash, b.n);
47 : : }
48 : :
49 : 17710996 : friend bool operator==(const COutPoint& a, const COutPoint& b)
50 : : {
51 [ + + + + ]: 17710996 : 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 : 888352 : 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 : 223399 : CTxIn()
122 : 223399 : {
123 : 223399 : nSequence = SEQUENCE_FINAL;
124 : 223399 : }
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 : 955151 : SERIALIZE_METHODS(CTxIn, obj) { READWRITE(obj.prevout, obj.scriptSig, obj.nSequence); }
130 : :
131 : 48 : friend bool operator==(const CTxIn& a, const CTxIn& b)
132 : : {
133 [ + - ]: 48 : return (a.prevout == b.prevout &&
134 [ + - ]: 48 : a.scriptSig == b.scriptSig &&
135 [ - + ]: 48 : 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 [ + - ][ + - : 36397539 : class CTxOut
+ + + + ]
[ - - + -
- - - - +
- ][ - - -
- + + -
- ]
[ + + + + ]
[ + - + -
+ - - + -
- + - + -
+ + + - +
- + - + -
+ + ]
150 : : {
151 : : public:
152 : : CAmount nValue;
153 : : CScript scriptPubKey;
154 : :
155 : 30282117 : CTxOut()
156 : 30282117 : {
157 [ + - + + ]: 730743 : SetNull();
[ + + ]
158 : : }
159 : :
160 : : CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);
161 : :
162 : 15362949 : SERIALIZE_METHODS(CTxOut, obj) { READWRITE(obj.nValue, obj.scriptPubKey); }
163 : :
164 : 30411618 : void SetNull()
165 : : {
166 : 30411618 : nValue = -1;
167 : 30411618 : scriptPubKey.clear();
168 : : }
169 : :
170 : 15673666 : bool IsNull() const
171 : : {
172 [ + + + + ]: 14887435 : return (nValue == -1);
[ + + + +
+ + + + +
+ + + + +
+ + + + -
+ + + + +
+ + - - ]
[ - + - -
- - - - -
- - - -
- ][ + + #
# # # # #
# # # # #
# ][ - + +
+ - + ][ -
- - + + -
- + - - ]
[ # # # #
# # # # ]
[ + + - +
+ - + - +
- + + + +
+ + + + +
- + + + +
+ + + + -
+ + + ]
173 : : }
174 : :
175 : 327597 : friend bool operator==(const CTxOut& a, const CTxOut& b)
176 : : {
177 [ + - - + ]: 655194 : return (a.nValue == b.nValue &&
178 : 327597 : a.scriptPubKey == b.scriptPubKey);
179 : : }
180 : :
181 : 798 : friend bool operator!=(const CTxOut& a, const CTxOut& b)
182 : : {
183 : 798 : 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 [ + - # # : 1058806 : 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 : 3063 : void UnserializeTransaction(TxType& tx, Stream& s, const TransactionSerParams& params)
217 : : {
218 : 3063 : const bool fAllowWitness = params.allow_witness;
219 : :
220 : 3063 : s >> tx.version;
221 : 3063 : unsigned char flags = 0;
222 : 3063 : tx.vin.clear();
223 : 3063 : tx.vout.clear();
224 : : /* Try to read the vin. In case the dummy is there, this will be read as an empty vector. */
225 : 3063 : s >> tx.vin;
226 [ + + + + ]: 3060 : if (tx.vin.size() == 0 && fAllowWitness) {
227 : : /* We read a dummy or an empty vin. */
228 : 2057 : s >> flags;
229 [ + + ]: 2057 : if (flags != 0) {
230 : 2052 : s >> tx.vin;
231 : 2052 : s >> tx.vout;
232 : : }
233 : : } else {
234 : : /* We read a non-empty vin. Assume a normal vout follows. */
235 : 1003 : s >> tx.vout;
236 : : }
237 [ + - ]: 2052 : if ((flags & 1) && fAllowWitness) {
238 : : /* The witness flag is present, and we support witnesses. */
239 : 2052 : flags ^= 1;
240 [ + + ]: 8655 : for (size_t i = 0; i < tx.vin.size(); i++) {
241 : 6603 : s >> tx.vin[i].scriptWitness.stack;
242 : : }
243 [ + + ]: 2052 : if (!tx.HasWitness()) {
244 : : /* It's illegal to encode witnesses when all witness stacks are empty. */
245 [ + - ]: 2 : throw std::ios_base::failure("Superfluous witness record");
246 : : }
247 : : }
248 [ - + ]: 3058 : if (flags) {
249 : : /* Unknown flag in the serialization */
250 [ # # ]: 0 : throw std::ios_base::failure("Unknown transaction optional data");
251 : : }
252 : 3058 : s >> tx.nLockTime;
253 : 3058 : }
254 : :
255 : : template<typename Stream, typename TxType>
256 : 1141227 : void SerializeTransaction(const TxType& tx, Stream& s, const TransactionSerParams& params)
257 : : {
258 : 1141227 : const bool fAllowWitness = params.allow_witness;
259 : :
260 : 1141227 : s << tx.version;
261 : 1141227 : unsigned char flags = 0;
262 : : // Consistency check
263 [ + + ]: 1141227 : if (fAllowWitness) {
264 : : /* Check whether witnesses need to be serialized. */
265 [ + + ]: 123824 : if (tx.HasWitness()) {
266 : : flags |= 1;
267 : : }
268 : : }
269 : : if (flags) {
270 : : /* Use extended format in case witnesses are to be serialized. */
271 [ + - ]: 66630 : std::vector<CTxIn> vinDummy;
272 [ + - ]: 66630 : s << vinDummy;
273 : 66630 : s << flags;
274 : 66630 : }
275 : 1141227 : s << tx.vin;
276 : 1141227 : s << tx.vout;
277 [ + + ]: 1141227 : if (flags & 1) {
278 [ + + ]: 142381 : for (size_t i = 0; i < tx.vin.size(); i++) {
279 : 75751 : s << tx.vin[i].scriptWitness.stack;
280 : : }
281 : : }
282 : 1141227 : s << tx.nLockTime;
283 : 1141227 : }
284 : :
285 : : template<typename TxType>
286 : 25 : inline CAmount CalculateOutputValue(const TxType& tx)
287 : : {
288 : 59 : 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 [ + + ]: 567343 : 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 : 856759 : inline void Serialize(Stream& s) const {
329 : 856759 : 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 [ + - ]: 219 : CTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) : CTransaction(CMutableTransaction(deserialize, params, s)) {}
336 : : template <typename Stream>
337 [ + - ]: 2789 : CTransaction(deserialize_type, Stream& s) : CTransaction(CMutableTransaction(deserialize, s)) {}
338 : :
339 : 7 : bool IsNull() const {
340 [ - + - - ]: 7 : return vin.empty() && vout.empty();
341 : : }
342 : :
343 [ + - + - : 56504114 : const Txid& GetHash() const LIFETIMEBOUND { return hash; }
+ - + + ]
[ + + # #
# # # # ]
[ - + + +
# # ][ + -
+ - + - #
# # # #
# ][ + - +
+ + - + -
+ - + - ]
[ + + + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ][ + - +
- + - + -
+ - # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
344 [ # # # # ]: 141925 : 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 : 439262 : bool IsCoinBase() const
357 : : {
358 [ + + + + ]: 439262 : return (vin.size() == 1 && vin[0].prevout.IsNull());
359 : : }
360 : :
361 : 9 : friend bool operator==(const CTransaction& a, const CTransaction& b)
362 : : {
363 [ - + ][ + - : 9 : return a.hash == b.hash;
+ - + - +
- ]
364 : : }
365 : :
366 : 0 : friend bool operator!=(const CTransaction& a, const CTransaction& b)
367 : : {
368 [ # # ]: 0 : return a.hash != b.hash;
369 : : }
370 : :
371 : : std::string ToString() const;
372 : :
373 [ + + + + ]: 742175 : bool HasWitness() const { return m_has_witness; }
[ + + # # ]
[ - - + +
+ + ][ - -
+ + + + -
- + + ]
374 : : };
375 : :
376 : : /** A mutable version of CTransaction. */
377 [ + - ]: 520207 : 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 : 284468 : inline void Serialize(Stream& s) const {
389 : 284468 : SerializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
390 : : }
391 : :
392 : : template <typename Stream>
393 [ + - ]: 2844 : inline void Unserialize(Stream& s) {
394 [ + - ]: 2844 : UnserializeTransaction(*this, s, s.template GetParams<TransactionSerParams>());
395 : 2789 : }
396 : :
397 : : template <typename Stream>
398 [ + - ]: 219 : CMutableTransaction(deserialize_type, const TransactionSerParams& params, Stream& s) {
399 [ + - ]: 219 : UnserializeTransaction(*this, s, params);
400 : 219 : }
401 : :
402 : : template <typename Stream>
403 [ + - ]: 2789 : CMutableTransaction(deserialize_type, Stream& s) {
404 : 2789 : Unserialize(s);
405 : 2789 : }
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 : 2104 : bool HasWitness() const
413 : : {
414 [ + + ]: 2166 : for (size_t i = 0; i < vin.size(); i++) {
415 [ + + ]: 2121 : 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 [ + - + + ]: 399511 : 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 : 18296 : GenTxid(bool is_wtxid, const uint256& hash) : m_is_wtxid(is_wtxid), m_hash(hash) {}
432 : :
433 : : public:
434 [ + - ]: 9546 : static GenTxid Txid(const uint256& hash) { return GenTxid{false, hash}; }
[ + - + - ]
[ + - + -
+ - - - ]
[ # # # #
# # ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
435 [ + - + - : 9070 : static GenTxid Wtxid(const uint256& hash) { return GenTxid{true, hash}; }
+ - + - ]
[ + - ]
436 [ + + ][ - - : 7061 : bool IsWtxid() const { return m_is_wtxid; }
- - + + +
+ - - ][ #
# # # #
# ]
437 [ + - + - ]: 16659 : const uint256& GetHash() const LIFETIMEBOUND { return m_hash; }
[ # # # #
# # # # #
# ][ - - -
- + + - -
- - # # ]
[ + - ][ # #
# # # # #
# # # #
# ]
438 [ + - - + ]: 13187 : 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 : 4160 : 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 // BITCOIN_PRIMITIVES_TRANSACTION_H
|