1414
1515#include " statistics.hpp"
1616
17+ // returns 0xff on failure
1718static uint8_t parseHex (uint8_t character);
19+
1820static uint8_t getHex (uint8_t character);
21+
1922static void streamHex (std::ostream &out, uint8_t *ptr, size_t len);
20- static void streamScript (std::ostream &out, uint8_t *ptr, size_t len);
23+
24+ static bool streamScript (std::ostream &out, uint8_t *ptr, size_t len);
2125
2226#define MAX_TRANSACTION_SIZE 1024 * 1024 * 30
2327
@@ -39,13 +43,7 @@ int main (int argc, char** argv) {
3943 return 1 ;
4044 }
4145
42- if (*(uint32_t *)buffer.data () != 0x01000000 && *(uint32_t *)buffer.data () != 0x02000000 ) {
43-
44- if (strncmp ((char *)buffer.data (), " 01000000" , 8 ) && strncmp ((char *)buffer.data (), " 02000000" , 8 )) {
45-
46- std::cerr << " Transaction does not have needed 'version 1 or 2' flag.\n " ;
47- return 1 ;
48- }
46+ if (parseHex (buffer[0 ]) != 0xff && parseHex (buffer[1 ]) != 0xff ) {
4947
5048 // ASCII hex data has been provided -- let's parse it into binary form.
5149
@@ -55,16 +53,24 @@ int main (int argc, char** argv) {
5553 bufSize /= 2 ;
5654 }
5755
56+ if (*(uint32_t *)buffer.data () != 0x00000001 && *(uint32_t *)buffer.data () != 0x00000002 ) {
57+
58+ std::cerr << " Transaction does not have needed 'version 1 or 2' flag.\n " ;
59+ std::cerr << " We will attempt to read it as if it were a script and then abort.\n " ;
60+
61+ streamScript (std::cout, buffer.data (), bufSize);
62+ std::cout << " \n " ;
63+
64+ return 1 ;
65+ }
66+
5867 auto data = ptr_range (buffer).take (bufSize);
5968
6069 auto transaction = readTransaction (data);
6170
6271 std::cout << " \n " ;
6372
64- std::cout << " Transaction version: " << transaction.version << " \n " ;
65- std::cout << " Transaction inputs: " << transaction.inputs .size () << " \n " ;
66- std::cout << " Transaction outputs: " << transaction.outputs .size () << " \n " ;
67- std::cout << " Transaction locktime: " << transaction.locktime << " \n " ;
73+ std::cout << " Transaction version: " << transaction.version << " , locktime: " << transaction.locktime << " \n " ;
6874
6975 std::cout << " \n " ;
7076
@@ -82,16 +88,39 @@ int main (int argc, char** argv) {
8288
8389 std::cout << " \t V-out: " << input.vout << " \n " ;
8490
85- std::cout << " \t Witness flag: " << getOpString (input. witnessFlag ) << " \n " ;
91+ bool outputScript = false ;
8692
87- if (input.script .size ()) {
93+ if (input.scriptStack .size ()) {
8894
8995 std::cout << " \t Script: " ;
90- streamScript (std::cout, input.script . data () , input.script .size ());
96+ outputScript = streamScript (std::cout, input.scriptStack . back (). begin () , input.scriptStack . back () .size ());
9197 std::cout << " \n " ;
98+
99+ if (outputScript && input.scriptStack .size () > 1 ) {
100+
101+ std::cout << " \t Script inputs:\n " ;
102+
103+ for (size_t i = 0 ; i < input.scriptStack .size () - 1 ; i++) {
104+
105+ std::cout << " \t [" ;
106+ streamHex (std::cout, input.scriptStack [i].begin (), input.scriptStack [i].size ());
107+ std::cout << " ]\n " ;
108+ }
109+ }
92110 }
93111
94- std::cout << " \t Sequence: " << input.sequence << " \n " ;
112+ if (!outputScript && input.script .size ()) {
113+
114+ std::cout << " \t Raw script: " ;
115+ streamScript (std::cout, input.script .begin (), input.script .size ());
116+ std::cout << " \n " ;
117+ }
118+
119+ std::cout << " \t Sequence: " << input.sequence << " aka. 0x" ;
120+ streamHex (std::cout, (uint8_t *)&input.sequence , sizeof (input.sequence ));
121+ std::cout << " \n " ;
122+
123+ std::cout << " \t Witness flag: " << getOpString (input.witnessFlag ) << " \n " ;
95124
96125 if (counter - 1 < transaction.witnesses .size ()) {
97126
@@ -105,39 +134,39 @@ int main (int argc, char** argv) {
105134 }
106135 else {
107136
108- std::cout << " \t Witness signature: " ;
109- streamHex (std::cout, witness.stack [0 ]. data (), witness.stack [0 ].size ());
110- std::cout << " \n " ;
137+ std::cout << " \t Witness pubkey: [ " ;
138+ streamHex (std::cout, witness.stack [1 ]. begin (), witness.stack [1 ].size ());
139+ std::cout << " ] \n " ;
111140
112- std::cout << " \t Witness pubkey: " ;
113- streamHex (std::cout, witness.stack [1 ]. data (), witness.stack [1 ].size ());
114- std::cout << " \n " ;
141+ std::cout << " \t Witness signature: [ " ;
142+ streamHex (std::cout, witness.stack [0 ]. begin (), witness.stack [0 ].size ());
143+ std::cout << " ] \n " ;
115144 }
116145 }
117146 else if (input.witnessFlag == OP_P2WSH) {
118147
119- if (transaction. witnesses .size () == 0 ) {
148+ if (witness. stack .size () == 0 ) {
120149
121150 std::cerr << " \t OP_P2WSH script has no witness elements!\n " ;
122151 }
123152 else {
124153
125- std::cout << " \t Witness script input stack:" ;
154+ auto stack = witness.stack ;
155+
156+ std::cout << " \t Witness script: " ;
157+ streamScript (std::cout, stack.back ().begin (), stack.back ().size ());
158+ std::cout << " \n " ;
126159
127160 size_t i = 0 ;
128161
162+ std::cout << " \t Witness script inputs: " ;
163+
129164 for (; i < witness.stack .size () - 1 ; i++) {
130165
131- std::cout << " [ " ;
132- streamHex (std::cout, witness. stack [i].data (), witness. stack [i].size ());
133- std::cout << " ]" ;
166+ std::cout << (i ? " \t [ " : " [ " ) ;
167+ streamHex (std::cout, stack[i].begin (), stack[i].size ());
168+ std::cout << " ]\n " ;
134169 }
135-
136- std::cout << " \n " ;
137-
138- std::cout << " \t Witness script: " ;
139- streamHex (std::cout, witness.stack [i].data (), witness.stack [i].size ());
140- std::cout << " \n " ;
141170 }
142171 }
143172 else if (input.witnessFlag != OP_NOWITNESS) {
@@ -147,7 +176,7 @@ int main (int argc, char** argv) {
147176 for (auto data : transaction.witnesses [counter - 1 ].stack ) {
148177
149178 std::cout << " \t Witness item: " ;
150- streamHex (std::cout, data.data (), data.size ());
179+ streamHex (std::cout, data.begin (), data.size ());
151180 std::cout << " \n " ;
152181 }
153182 }
@@ -166,7 +195,9 @@ int main (int argc, char** argv) {
166195 streamScript (std::cout, output.script .data (), output.script .size ());
167196 std::cout << " \n " ;
168197
169- std::cout << " \t Value: " << double (output.value ) / 100000000 << " \n " ;
198+ std::cout << " \t Value: " << output.value / 100000000 << " ." ;
199+
200+ printf (" %08llu\n " , output.value % 100000000 );
170201 }
171202
172203 std::cout << " \n " ;
@@ -185,7 +216,7 @@ static uint8_t parseHex(uint8_t character)
185216 if (character >= ' A' && character <= ' F' )
186217 return uint8_t (character - ' A' + 10 );
187218
188- return 0 ;
219+ return 0xff ;
189220}
190221
191222static uint8_t getHex (uint8_t character)
@@ -205,7 +236,7 @@ static void streamHex(std::ostream &out, uint8_t *ptr, size_t len)
205236 out << getHex (uint8_t (ptr[i] >> 4 )) << getHex (ptr[i] & 0x0f );
206237}
207238
208- static void streamScript (std::ostream &out, uint8_t *ptr, size_t len)
239+ static bool streamScript (std::ostream &out, uint8_t *ptr, size_t len)
209240{
210241 for (size_t i = 0 ; i < len; i++) {
211242
@@ -237,16 +268,16 @@ static void streamScript(std::ostream &out, uint8_t *ptr, size_t len)
237268 if (dataSize == OP_PUSHDATA1 || dataSize == OP_PUSHDATA2 || dataSize == OP_PUSHDATA4) {
238269
239270 out << " Script encountered invalid OP_PUSHDATA -- aborting parse." ;
240- return ;
271+ return false ;
241272 }
242273
243274 if (dataSize + i > len) {
244275
245276 out << " Script encountered push data larger than script -- aborting parse." ;
246- return ;
277+ return false ;
247278 }
248279
249- out << " PUSH [" ;
280+ out << " PUSH( " << dataSize << " ) [" ;
250281 streamHex (out, ptr + i, dataSize);
251282 out << " ] " ;
252283
@@ -257,4 +288,6 @@ static void streamScript(std::ostream &out, uint8_t *ptr, size_t len)
257288 out << getOpString (ptr[i]) << " " ;
258289 }
259290 }
291+
292+ return true ;
260293}
0 commit comments