veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
transaction.hpp
1// Copyright (c) 2019-2022 Xenios SEZC
2// https://www.veriblock.org
3// Distributed under the MIT software license, see the accompanying
4// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef BFI_BITCOIN_TRANSACTION_HPP
7#define BFI_BITCOIN_TRANSACTION_HPP
8
9#include <veriblock/bfi/bitcoin/serialize.hpp>
10#include <veriblock/pop/uint.hpp>
11
12namespace altintegration {
13
14namespace btc {
15
16static const int SERIALIZE_TRANSACTION_NO_WITNESS = 0x40000000;
17
18using Script = std::vector<uint8_t>;
19using ScriptWitness = std::vector<std::vector<uint8_t>>;
21using Amount = int64_t;
22
25struct OutPoint {
26 uint256 hash;
27 uint32_t n;
28
29 ADD_SERIALIZE_METHODS;
30
31 template <typename Stream, typename Operation>
32 inline void SerializationOp(Stream& s, Operation ser_action) {
33 READWRITE(hash);
34 READWRITE(n);
35 }
36
37 friend bool operator==(const OutPoint& a, const OutPoint& b) {
38 return a.hash == b.hash && a.n == b.n;
39 }
40
41 friend bool operator!=(const OutPoint& a, const OutPoint& b) {
42 return !(a == b);
43 }
44};
45
50struct TxIn {
51 OutPoint prevout;
52 Script scriptSig;
53 uint32_t nSequence;
54 ScriptWitness scriptWitness;
55
56 ADD_SERIALIZE_METHODS;
57
58 template <typename Stream, typename Operation>
59 inline void SerializationOp(Stream& s, Operation ser_action) {
60 READWRITE(prevout);
61 READWRITE(scriptSig);
62 READWRITE(nSequence);
63 }
64
65 friend bool operator==(const TxIn& a, const TxIn& b) {
66 return a.prevout == b.prevout && a.scriptSig == b.scriptSig &&
67 a.nSequence == b.nSequence && a.scriptWitness == b.scriptWitness;
68 }
69
70 friend bool operator!=(const TxIn& a, const TxIn& b) { return !(a == b); }
71};
72
76struct TxOut {
77 Amount nValue;
78 Script scriptPubKey;
79
80 ADD_SERIALIZE_METHODS;
81
82 template <typename Stream, typename Operation>
83 inline void SerializationOp(Stream& s, Operation ser_action) {
84 READWRITE(nValue);
85 READWRITE(scriptPubKey);
86 }
87
88 friend bool operator==(const TxOut& a, const TxOut& b) {
89 return a.nValue == b.nValue && a.scriptPubKey == b.scriptPubKey;
90 }
91
92 friend bool operator!=(const TxOut& a, const TxOut& b) { return !(a == b); }
93};
94
99 // The local variables are made const to prevent unintended modification
100 // without updating the cached hash value. However, CTransaction is not
101 // actually immutable; deserialization and assignment are implemented,
102 // and bypass the constness. This is safe, as they update the entire
103 // structure, including the hash.
104 std::vector<TxIn> vin;
105 std::vector<TxOut> vout;
106 int32_t nVersion;
107 uint32_t nLockTime;
108
109 template <typename Stream>
110 inline void Serialize(Stream& s) const {
111 SerializeTransaction(*this, s);
112 }
113
114 template <typename Stream>
115 inline void Unserialize(Stream& s) {
116 UnserializeTransaction(*this, s);
117 }
118
119 friend bool operator==(const Transaction& a, const Transaction& b) {
120 return a.vin == b.vin && a.vout == b.vout && a.nVersion == b.nVersion &&
121 a.nLockTime == b.nLockTime;
122 }
123
124 friend bool operator!=(const Transaction& a, const Transaction& b) {
125 return !(a == b);
126 }
127
128 bool HasWitness() const {
129 for (size_t i = 0; i < vin.size(); i++) {
130 if (!vin[i].scriptWitness.empty()) {
131 return true;
132 }
133 }
134 return false;
135 }
136};
137
138template <typename Stream>
139inline void UnserializeTransaction(Transaction& tx, Stream& s) {
140 const bool fAllowWitness =
141 (s.getVersion() & SERIALIZE_TRANSACTION_NO_WITNESS) == 0;
142
143 Unserialize(s, tx.nVersion);
144 unsigned char flags = 0;
145 tx.vin.clear();
146 tx.vout.clear();
147 /* Try to read the vin. In case the dummy is there, this will be read as an
148 * empty vector. */
149 Unserialize(s, tx.vin);
150 if (tx.vin.size() == 0 && fAllowWitness) {
151 /* We read a dummy or an empty vin. */
152 Unserialize(s, flags);
153 if (flags != 0) {
154 Unserialize(s, tx.vin);
155 Unserialize(s, tx.vout);
156 }
157 } else {
158 /* We read a non-empty vin. Assume a normal vout follows. */
159 Unserialize(s, tx.vout);
160 }
161 if (((flags & 1) != 0) && fAllowWitness) {
162 /* The witness flag is present, and we support witnesses. */
163 flags ^= 1;
164 for (size_t i = 0; i < tx.vin.size(); i++) {
165 Unserialize(s, tx.vin[i].scriptWitness);
166 }
167 if (!tx.HasWitness()) {
168 /* It's illegal to encode witnesses when all witness stacks are empty. */
169 throw std::ios_base::failure("Superfluous witness record");
170 }
171 }
172 if (flags) {
173 /* Unknown flag in the serialization */
174 throw std::ios_base::failure("Unknown transaction optional data");
175 }
176 Unserialize(s, tx.nLockTime);
177}
178
179template <typename Stream>
180inline void SerializeTransaction(const Transaction& tx, Stream& s) {
181 const bool fAllowWitness =
182 (s.getVersion() & SERIALIZE_TRANSACTION_NO_WITNESS) == 0;
183
184 Serialize(s, tx.nVersion);
185 unsigned char flags = 0;
186 // Consistency check
187 if (fAllowWitness) {
188 /* Check whether witnesses need to be serialized. */
189 if (tx.HasWitness()) {
190 flags |= 1;
191 }
192 }
193 if (flags) {
194 /* Use extended format in case witnesses are to be serialized. */
195 std::vector<TxIn> vinDummy;
196 Serialize(s, vinDummy);
197 Serialize(s, flags);
198 }
199 Serialize(s, tx.vin);
200 Serialize(s, tx.vout);
201 if (flags & 1) {
202 for (size_t i = 0; i < tx.vin.size(); i++) {
203 Serialize(s, tx.vin[i].scriptWitness);
204 }
205 }
206 Serialize(s, tx.nLockTime);
207}
208
209} // namespace btc
210
211} // namespace altintegration
212
213#endif
Defines logging helpers.
Definition: block.hpp:14
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.hpp:25
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.hpp:98
An input of a transaction.
Definition: transaction.hpp:50
ScriptWitness scriptWitness
Only serialized through CTransaction.
Definition: transaction.hpp:54
An output of a transaction.
Definition: transaction.hpp:76