/root/bitcoin/src/addresstype.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2023 The Bitcoin Core developers |
2 | | // Distributed under the MIT software license, see the accompanying |
3 | | // file COPYING or https://www.opensource.org/licenses/mit-license.php. |
4 | | |
5 | | #include <addresstype.h> |
6 | | |
7 | | #include <crypto/sha256.h> |
8 | | #include <hash.h> |
9 | | #include <pubkey.h> |
10 | | #include <script/script.h> |
11 | | #include <script/solver.h> |
12 | | #include <uint256.h> |
13 | | #include <util/hash_type.h> |
14 | | |
15 | | #include <cassert> |
16 | | #include <vector> |
17 | | |
18 | | typedef std::vector<unsigned char> valtype; |
19 | | |
20 | 0 | ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {} |
21 | 0 | ScriptHash::ScriptHash(const CScriptID& in) : BaseHash{in} {} |
22 | | |
23 | 0 | PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} |
24 | 0 | PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {} |
25 | | |
26 | 0 | WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} |
27 | 0 | WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {} |
28 | | |
29 | | CKeyID ToKeyID(const PKHash& key_hash) |
30 | 0 | { |
31 | 0 | return CKeyID{uint160{key_hash}}; |
32 | 0 | } |
33 | | |
34 | | CKeyID ToKeyID(const WitnessV0KeyHash& key_hash) |
35 | 0 | { |
36 | 0 | return CKeyID{uint160{key_hash}}; |
37 | 0 | } |
38 | | |
39 | | CScriptID ToScriptID(const ScriptHash& script_hash) |
40 | 0 | { |
41 | 0 | return CScriptID{uint160{script_hash}}; |
42 | 0 | } |
43 | | |
44 | | WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in) |
45 | 0 | { |
46 | 0 | CSHA256().Write(in.data(), in.size()).Finalize(begin()); |
47 | 0 | } |
48 | | |
49 | | bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) |
50 | 0 | { |
51 | 0 | std::vector<valtype> vSolutions; |
52 | 0 | TxoutType whichType = Solver(scriptPubKey, vSolutions); |
53 | |
|
54 | 0 | switch (whichType) { |
55 | 0 | case TxoutType::PUBKEY: { |
56 | 0 | CPubKey pubKey(vSolutions[0]); |
57 | 0 | if (!pubKey.IsValid()) { |
58 | 0 | addressRet = CNoDestination(scriptPubKey); |
59 | 0 | } else { |
60 | 0 | addressRet = PubKeyDestination(pubKey); |
61 | 0 | } |
62 | 0 | return false; |
63 | 0 | } |
64 | 0 | case TxoutType::PUBKEYHASH: { |
65 | 0 | addressRet = PKHash(uint160(vSolutions[0])); |
66 | 0 | return true; |
67 | 0 | } |
68 | 0 | case TxoutType::SCRIPTHASH: { |
69 | 0 | addressRet = ScriptHash(uint160(vSolutions[0])); |
70 | 0 | return true; |
71 | 0 | } |
72 | 0 | case TxoutType::WITNESS_V0_KEYHASH: { |
73 | 0 | WitnessV0KeyHash hash; |
74 | 0 | std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); |
75 | 0 | addressRet = hash; |
76 | 0 | return true; |
77 | 0 | } |
78 | 0 | case TxoutType::WITNESS_V0_SCRIPTHASH: { |
79 | 0 | WitnessV0ScriptHash hash; |
80 | 0 | std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); |
81 | 0 | addressRet = hash; |
82 | 0 | return true; |
83 | 0 | } |
84 | 0 | case TxoutType::WITNESS_V1_TAPROOT: { |
85 | 0 | WitnessV1Taproot tap; |
86 | 0 | std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin()); |
87 | 0 | addressRet = tap; |
88 | 0 | return true; |
89 | 0 | } |
90 | 0 | case TxoutType::ANCHOR: { |
91 | 0 | addressRet = PayToAnchor(); |
92 | 0 | return true; |
93 | 0 | } |
94 | 0 | case TxoutType::WITNESS_UNKNOWN: { |
95 | 0 | addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]}; |
96 | 0 | return true; |
97 | 0 | } |
98 | 0 | case TxoutType::MULTISIG: |
99 | 0 | case TxoutType::NULL_DATA: |
100 | 0 | case TxoutType::NONSTANDARD: |
101 | 0 | addressRet = CNoDestination(scriptPubKey); |
102 | 0 | return false; |
103 | 0 | } // no default case, so the compiler can warn about missing cases |
104 | 0 | assert(false); |
105 | 0 | } |
106 | | |
107 | | namespace { |
108 | | class CScriptVisitor |
109 | | { |
110 | | public: |
111 | | CScript operator()(const CNoDestination& dest) const |
112 | 0 | { |
113 | 0 | return dest.GetScript(); |
114 | 0 | } |
115 | | |
116 | | CScript operator()(const PubKeyDestination& dest) const |
117 | 0 | { |
118 | 0 | return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG; |
119 | 0 | } |
120 | | |
121 | | CScript operator()(const PKHash& keyID) const |
122 | 0 | { |
123 | 0 | return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; |
124 | 0 | } |
125 | | |
126 | | CScript operator()(const ScriptHash& scriptID) const |
127 | 0 | { |
128 | 0 | return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; |
129 | 0 | } |
130 | | |
131 | | CScript operator()(const WitnessV0KeyHash& id) const |
132 | 0 | { |
133 | 0 | return CScript() << OP_0 << ToByteVector(id); |
134 | 0 | } |
135 | | |
136 | | CScript operator()(const WitnessV0ScriptHash& id) const |
137 | 0 | { |
138 | 0 | return CScript() << OP_0 << ToByteVector(id); |
139 | 0 | } |
140 | | |
141 | | CScript operator()(const WitnessV1Taproot& tap) const |
142 | 0 | { |
143 | 0 | return CScript() << OP_1 << ToByteVector(tap); |
144 | 0 | } |
145 | | |
146 | | CScript operator()(const WitnessUnknown& id) const |
147 | 0 | { |
148 | 0 | return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram(); |
149 | 0 | } |
150 | | }; |
151 | | |
152 | | class ValidDestinationVisitor |
153 | | { |
154 | | public: |
155 | 0 | bool operator()(const CNoDestination& dest) const { return false; } |
156 | 0 | bool operator()(const PubKeyDestination& dest) const { return false; } |
157 | 0 | bool operator()(const PKHash& dest) const { return true; } |
158 | 0 | bool operator()(const ScriptHash& dest) const { return true; } |
159 | 0 | bool operator()(const WitnessV0KeyHash& dest) const { return true; } |
160 | 0 | bool operator()(const WitnessV0ScriptHash& dest) const { return true; } |
161 | 0 | bool operator()(const WitnessV1Taproot& dest) const { return true; } |
162 | 0 | bool operator()(const WitnessUnknown& dest) const { return true; } |
163 | | }; |
164 | | } // namespace |
165 | | |
166 | | CScript GetScriptForDestination(const CTxDestination& dest) |
167 | 0 | { |
168 | 0 | return std::visit(CScriptVisitor(), dest); |
169 | 0 | } |
170 | | |
171 | 0 | bool IsValidDestination(const CTxDestination& dest) { |
172 | 0 | return std::visit(ValidDestinationVisitor(), dest); |
173 | 0 | } |