55#include < cassert>
66#include < cstdint>
77#include < vector>
8- #include < iostream>
98
109#include " hash.hpp"
1110#include " hexxer.hpp"
@@ -19,10 +18,10 @@ struct TransactionBase {
1918 R data;
2019 R hash;
2120 uint32_t vout;
22- R script;
23- std::vector<R> scriptStack;
21+ R script;
22+ std::vector<R> scriptStack;
2423 uint32_t sequence;
25- uint8_t witnessFlag; // OP_NOWITNESS means not a witness program
24+ uint8_t witnessFlag; // OP_NOWITNESS means not a witness program
2625 };
2726
2827 struct Output {
@@ -32,8 +31,8 @@ struct TransactionBase {
3231 };
3332
3433 struct Witness {
35- R data;
36- std::vector<R> stack;
34+ R data;
35+ std::vector<R> stack;
3736 };
3837
3938 R data;
@@ -113,72 +112,55 @@ namespace {
113112 const auto hash = readRange (data, 32 );
114113 const auto vout = serial::read<uint32_t >(data);
115114
116- const auto scriptLen = readVI (data);
117-
118- __ranger::Range scriptRanger (data.begin (), data.begin () + scriptLen);
119-
120- std::vector<R> scriptStack;
121-
122- std::cerr << " Script bytes: " << scriptRanger.size () << " \n " ;
123-
124- while (scriptRanger.size ()) {
125-
126- auto opcode = serial::read<uint8_t >(scriptRanger);
127-
128- if (!opcode || opcode > OP_PUSHDATA4)
129- continue ;
130-
131- auto size = readPD (opcode, scriptRanger);
132-
133- std::cerr << " Read size: " << size << " \n " ;
134-
135- scriptStack.push_back (readRange (scriptRanger, size));
136-
137- std::cerr << " Remaining script bytes: " << scriptRanger.size () << " \n " ;
138- }
139-
140- const auto script = readRange (data, scriptLen);
141-
142- const auto sequence = serial::read<uint32_t >(data);
143- isave.popBackN (data.size ());
144-
145-
146- // std::vector<uint8_t> scriptData(script.begin(), script.end());
147- // auto scriptItr = range(scriptData);
148- //
149- // while(scriptData.size()) {
150- //
151- // auto size = readVI(scriptItr);
152- //
153- // auto item = readRange(scriptItr, size);
154- //
155- // std::vector<uint8_t> item2(item.begin(), item.end());
156- //
157- // scriptStack.push_back(item2);
158- // }
159-
160- uint8_t witnessFlag = OP_NOWITNESS;
161-
162- if (hasWitnesses) {
163-
164- if (script.size () == 0 ) {
165-
166- witnessFlag = OP_ERROR;
167- }
168- else if (script.size () >= 3 ) {
169-
170- if (script[0 ] > 2 && script[0 ] < 40 && script[1 ] == 0 ) {
171-
172- if (script[2 ] == 0x14 )
173- witnessFlag |= OP_P2WPKH;
174- else if (script[2 ] == 0x20 )
175- witnessFlag |= OP_P2WSH;
176- else
177- witnessFlag = OP_ERROR;
178- }
179- }
180- }
181-
115+ const auto scriptLen = readVI (data);
116+
117+ __ranger::Range scriptRanger (data.begin (), data.begin () + scriptLen);
118+
119+ std::vector<R> scriptStack;
120+
121+ while (scriptRanger.size ()) {
122+
123+ auto opcode = serial::read<uint8_t >(scriptRanger);
124+
125+ if (!opcode || opcode > OP_PUSHDATA4)
126+ continue ;
127+
128+ auto size = readPD (opcode, scriptRanger);
129+
130+ scriptStack.push_back (readRange (scriptRanger, size));
131+ }
132+
133+ const auto script = readRange (data, scriptLen);
134+ const auto sequence = serial::read<uint32_t >(data);
135+ isave.popBackN (data.size ());
136+
137+ uint8_t witnessFlag = OP_NOWITNESS;
138+
139+ if (hasWitnesses) {
140+
141+ if (script.size () == 0 ) {
142+
143+ // In this case we must analyze witness data to determine the witness type.
144+ // We'll check for OP_ERROR during witness data processing and set the type there.
145+
146+ witnessFlag = OP_ERROR;
147+ }
148+ else if (script.size () >= 3 ) {
149+
150+ // As per https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
151+
152+ if (script[0 ] > 2 && script[0 ] < 40 && script[1 ] == 0 ) {
153+
154+ if (script[2 ] == 0x14 )
155+ witnessFlag |= OP_P2WPKH;
156+ else if (script[2 ] == 0x20 )
157+ witnessFlag |= OP_P2WSH;
158+ else
159+ witnessFlag = OP_ERROR;
160+ }
161+ }
162+ }
163+
182164 inputs.emplace_back (typename Transaction::Input{isave, hash, vout, script, scriptStack, sequence, witnessFlag});
183165 }
184166
@@ -203,14 +185,22 @@ namespace {
203185 wsave.popBackN (data.size ());
204186
205187 witnesses.emplace_back (typename Transaction::Witness{wsave, std::move (stack)});
206-
207- if (inputs[i].witnessFlag == OP_ERROR) {
208-
209- if (witnesses.back ().stack .size () == 2 )
210- inputs[i].witnessFlag = OP_P2WPKH;
211- else if (witnesses.back ().stack .size () > 2 )
212- inputs[i].witnessFlag = OP_P2WSH;
213- }
188+
189+ if (inputs[i].witnessFlag == OP_ERROR && !inputs[i].script .size ()) {
190+
191+ // As stated in https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
192+ //
193+ // If the version byte is 0, and the witness program is 20 bytes:
194+ // It is interpreted as a pay-to-witness-public-key-hash (P2WPKH) program.
195+ // The witness must consist of exactly 2 items (≤ 520 bytes each). The first one a signature, and the second one a public key.
196+
197+ // We will check for exactly 2 items in witness stack to conform to above
198+
199+ if (witnesses.back ().stack .size () == 2 )
200+ inputs[i].witnessFlag = OP_P2WPKH;
201+ else if (witnesses.back ().stack .size () > 2 )
202+ inputs[i].witnessFlag = OP_P2WSH;
203+ }
214204 }
215205 }
216206
0 commit comments