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