-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOutput.h
More file actions
101 lines (92 loc) · 3.76 KB
/
Copy pathOutput.h
File metadata and controls
101 lines (92 loc) · 3.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma once
#include <cstdint>
#include "BitcoinStream.h"
#include "opcodes.h"
#include "common.h"
struct Output {
uint64_t value;
bool isRipeMD160;
bool isBech32;
int bech32_len;
uint8_t ripeMD_version;
const uint8_t *publicKey;
void read(BitcoinStream& stream) {
value = stream.readU64();
uint32_t challengeScriptLength = stream.readVarint();
uint8_t* challengeScript = static_cast<uint8_t *>(stream.pointer);
stream.advance(challengeScriptLength);
decodeScript(challengeScriptLength, challengeScript);
}
void decodeScript(uint32_t challengeScriptLength, uint8_t* challengeScript) {
publicKey = nullptr;
ripeMD_version = 0;
isBech32 = false;
isRipeMD160 = false;
if (challengeScriptLength == 67 && challengeScript[0] == 65 &&
challengeScript[66] == OP_CHECKSIG) { // is_pubkey
publicKey = challengeScript + 1;
} else if (challengeScriptLength == 66 && challengeScript[65] == OP_CHECKSIG) {
publicKey = challengeScript;
} else if (challengeScriptLength >= 25 && // is_pubkeyhash
challengeScript[0] == OP_DUP &&
challengeScript[1] == OP_HASH160 &&
challengeScript[2] == 20) {
publicKey = challengeScript + 3;
isRipeMD160 = true;
} else if (challengeScriptLength == 5 &&
challengeScript[0] == OP_DUP &&
challengeScript[1] == OP_HASH160 &&
challengeScript[2] == OP_0 &&
challengeScript[3] == OP_EQUALVERIFY &&
challengeScript[4] == OP_CHECKSIG) {
WARN("Unexpected output script");
} else if (challengeScriptLength == 23 &&
challengeScript[0] == OP_HASH160 &&
challengeScript[1] == 0x14 &&
challengeScript[22] == OP_EQUAL) { // is_p2sh
publicKey = challengeScript + 2;
isRipeMD160 = true;
ripeMD_version = 5;
} else if (challengeScriptLength == 22 &&
challengeScript[0] == 0x00 &&
challengeScript[1] == 0x14) { // is_p2wpkh
publicKey = challengeScript + 2;
isBech32 = true;
bech32_len = 20;
} else if (challengeScriptLength == 34 &&
challengeScript[0] == 0x00 &&
challengeScript[1] == 0x20) { // is_p2wsh
publicKey = challengeScript + 2;
isBech32 = true;
bech32_len = 32;
} else if (challengeScript[0] == OP_RETURN) { // is_return
return;
} else {
// Ok..we are going to scan for this pattern.. OP_DUP, OP_HASH160, 0x14 then exactly 20 bytes after 0x88,0xAC
// 25...
if (challengeScriptLength > 25) {
uint32_t endIndex = challengeScriptLength - 25;
for (uint32_t i = 0; i < endIndex; i++) {
const uint8_t *scan = &challengeScript[i];
if (scan[0] == OP_DUP &&
scan[1] == OP_HASH160 &&
scan[2] == 20 &&
scan[23] == OP_EQUALVERIFY &&
scan[24] == OP_CHECKSIG) {
publicKey = &(scan[3]);
isRipeMD160 = true;
WARN("Unexpected output script(2)")
break;
}
}
}
if (!publicKey) {
if (challengeScriptLength >= 66 &&
challengeScript[challengeScriptLength - 1] == OP_CHECKSIG) {
WARN("Unexpected output script(3)")
}
// std::cout << "undecoded output script" << endl;
}
}
}
};