Branch data Line data Source code
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 : 1105668 : ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
21 : 0 : ScriptHash::ScriptHash(const CScriptID& in) : BaseHash{in} {}
22 : :
23 : 2107 : PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
24 : 416991 : PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
25 : :
26 : 0 : WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
27 : 486 : WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {}
28 : :
29 : 7709 : CKeyID ToKeyID(const PKHash& key_hash)
30 : : {
31 : 7709 : return CKeyID{uint160{key_hash}};
32 : : }
33 : :
34 : 2081 : CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
35 : : {
36 : 2081 : return CKeyID{uint160{key_hash}};
37 : : }
38 : :
39 : 1601 : CScriptID ToScriptID(const ScriptHash& script_hash)
40 : : {
41 : 1601 : return CScriptID{uint160{script_hash}};
42 : : }
43 : :
44 : 7085 : WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
45 : : {
46 [ + + + + ]: 20894 : CSHA256().Write(in.data(), in.size()).Finalize(begin());
47 : 7085 : }
48 : :
49 : 3547852 : bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
50 : : {
51 : 3547852 : std::vector<valtype> vSolutions;
52 [ + - ]: 3547852 : TxoutType whichType = Solver(scriptPubKey, vSolutions);
53 : :
54 [ + + + + : 3547852 : switch (whichType) {
+ + + + +
- ]
55 : 18068 : case TxoutType::PUBKEY: {
56 : 18068 : CPubKey pubKey(vSolutions[0]);
57 [ - + ]: 18068 : if (!pubKey.IsValid()) {
58 : 0 : addressRet = CNoDestination(scriptPubKey);
59 : : } else {
60 : 18068 : addressRet = PubKeyDestination(pubKey);
61 : : }
62 : : return false;
63 : : }
64 : 419128 : case TxoutType::PUBKEYHASH: {
65 : 419128 : addressRet = PKHash(uint160(vSolutions[0]));
66 : 419128 : return true;
67 : : }
68 : 1222728 : case TxoutType::SCRIPTHASH: {
69 : 1222728 : addressRet = ScriptHash(uint160(vSolutions[0]));
70 : 1222728 : return true;
71 : : }
72 : 143616 : case TxoutType::WITNESS_V0_KEYHASH: {
73 : 143616 : WitnessV0KeyHash hash;
74 : 143616 : std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
75 : 143616 : addressRet = hash;
76 : 143616 : return true;
77 : : }
78 : 73450 : case TxoutType::WITNESS_V0_SCRIPTHASH: {
79 : 73450 : WitnessV0ScriptHash hash;
80 : 73450 : std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
81 : 73450 : addressRet = hash;
82 : 73450 : return true;
83 : : }
84 : 339548 : case TxoutType::WITNESS_V1_TAPROOT: {
85 : 339548 : WitnessV1Taproot tap;
86 : 339548 : std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
87 : 339548 : addressRet = tap;
88 : 339548 : return true;
89 : : }
90 : 15 : case TxoutType::ANCHOR: {
91 [ + - ]: 15 : addressRet = PayToAnchor();
92 : 15 : return true;
93 : : }
94 : 32720 : case TxoutType::WITNESS_UNKNOWN: {
95 [ + - ]: 32720 : addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
96 : 32720 : return true;
97 : : }
98 : 1298579 : case TxoutType::MULTISIG:
99 : 1298579 : case TxoutType::NULL_DATA:
100 : 1298579 : case TxoutType::NONSTANDARD:
101 : 1298579 : addressRet = CNoDestination(scriptPubKey);
102 : 1298579 : return false;
103 : : } // no default case, so the compiler can warn about missing cases
104 : 0 : assert(false);
105 : 3547852 : }
106 : :
107 : : namespace {
108 : : class CScriptVisitor
109 : : {
110 : : public:
111 : 3919 : CScript operator()(const CNoDestination& dest) const
112 : : {
113 : 3919 : return dest.GetScript();
114 : : }
115 : :
116 : 36 : CScript operator()(const PubKeyDestination& dest) const
117 : : {
118 [ + - + - ]: 36 : return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG;
119 : : }
120 : :
121 : 1057885 : CScript operator()(const PKHash& keyID) const
122 : : {
123 [ + - + - : 1057885 : return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
+ - + - +
- ]
124 : : }
125 : :
126 : 2394532 : CScript operator()(const ScriptHash& scriptID) const
127 : : {
128 [ + - + - : 2394532 : return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
+ - ]
129 : : }
130 : :
131 : 1306635 : CScript operator()(const WitnessV0KeyHash& id) const
132 : : {
133 [ + - + - ]: 1306635 : return CScript() << OP_0 << ToByteVector(id);
134 : : }
135 : :
136 : 41790 : CScript operator()(const WitnessV0ScriptHash& id) const
137 : : {
138 [ + - + - ]: 41790 : return CScript() << OP_0 << ToByteVector(id);
139 : : }
140 : :
141 : 752383 : CScript operator()(const WitnessV1Taproot& tap) const
142 : : {
143 [ + - + - ]: 752383 : return CScript() << OP_1 << ToByteVector(tap);
144 : : }
145 : :
146 : 16926 : CScript operator()(const WitnessUnknown& id) const
147 : : {
148 [ + - ]: 16926 : return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();
149 : : }
150 : : };
151 : :
152 : : class ValidDestinationVisitor
153 : : {
154 : : public:
155 : : bool operator()(const CNoDestination& dest) const { return false; }
156 : : bool operator()(const PubKeyDestination& dest) const { return false; }
157 : : bool operator()(const PKHash& dest) const { return true; }
158 : : bool operator()(const ScriptHash& dest) const { return true; }
159 : : bool operator()(const WitnessV0KeyHash& dest) const { return true; }
160 : : bool operator()(const WitnessV0ScriptHash& dest) const { return true; }
161 : : bool operator()(const WitnessV1Taproot& dest) const { return true; }
162 : : bool operator()(const WitnessUnknown& dest) const { return true; }
163 : : };
164 : : } // namespace
165 : :
166 : 5574106 : CScript GetScriptForDestination(const CTxDestination& dest)
167 : : {
168 : 5574106 : return std::visit(CScriptVisitor(), dest);
169 : : }
170 : :
171 : 32460 : bool IsValidDestination(const CTxDestination& dest) {
172 : 32460 : return std::visit(ValidDestinationVisitor(), dest);
173 : : }
|