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