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 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 0 : CKeyID ToKeyID(const PKHash& key_hash) 30 : { 31 0 : return CKeyID{uint160{key_hash}}; 32 : } 33 : 34 0 : CKeyID ToKeyID(const WitnessV0KeyHash& key_hash) 35 : { 36 0 : return CKeyID{uint160{key_hash}}; 37 : } 38 : 39 0 : CScriptID ToScriptID(const ScriptHash& script_hash) 40 : { 41 0 : return CScriptID{uint160{script_hash}}; 42 : } 43 : 44 0 : WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in) 45 : { 46 0 : CSHA256().Write(in.data(), in.size()).Finalize(begin()); 47 0 : } 48 : 49 0 : bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) 50 : { 51 0 : std::vector<valtype> vSolutions; 52 0 : TxoutType whichType = Solver(scriptPubKey, vSolutions); 53 : 54 0 : switch (whichType) { 55 : 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 : } 62 0 : return false; 63 : } 64 : case TxoutType::PUBKEYHASH: { 65 0 : addressRet = PKHash(uint160(vSolutions[0])); 66 0 : return true; 67 : } 68 : case TxoutType::SCRIPTHASH: { 69 0 : addressRet = ScriptHash(uint160(vSolutions[0])); 70 0 : return true; 71 : } 72 : 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 : } 78 : 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 : } 84 : 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 : } 90 : case TxoutType::WITNESS_UNKNOWN: { 91 0 : addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]}; 92 0 : return true; 93 : } 94 : case TxoutType::MULTISIG: 95 : case TxoutType::NULL_DATA: 96 : case TxoutType::NONSTANDARD: 97 0 : addressRet = CNoDestination(scriptPubKey); 98 0 : return false; 99 : } // no default case, so the compiler can warn about missing cases 100 0 : assert(false); 101 0 : } 102 : 103 : namespace { 104 : class CScriptVisitor 105 : { 106 : public: 107 0 : CScript operator()(const CNoDestination& dest) const 108 : { 109 0 : return dest.GetScript(); 110 : } 111 : 112 0 : CScript operator()(const PubKeyDestination& dest) const 113 : { 114 0 : return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG; 115 0 : } 116 : 117 0 : CScript operator()(const PKHash& keyID) const 118 : { 119 0 : return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; 120 0 : } 121 : 122 0 : CScript operator()(const ScriptHash& scriptID) const 123 : { 124 0 : return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; 125 0 : } 126 : 127 0 : CScript operator()(const WitnessV0KeyHash& id) const 128 : { 129 0 : return CScript() << OP_0 << ToByteVector(id); 130 0 : } 131 : 132 0 : CScript operator()(const WitnessV0ScriptHash& id) const 133 : { 134 0 : return CScript() << OP_0 << ToByteVector(id); 135 0 : } 136 : 137 0 : CScript operator()(const WitnessV1Taproot& tap) const 138 : { 139 0 : return CScript() << OP_1 << ToByteVector(tap); 140 0 : } 141 : 142 0 : CScript operator()(const WitnessUnknown& id) const 143 : { 144 0 : return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram(); 145 0 : } 146 : }; 147 : 148 : class ValidDestinationVisitor 149 : { 150 : public: 151 0 : bool operator()(const CNoDestination& dest) const { return false; } 152 0 : bool operator()(const PubKeyDestination& dest) const { return false; } 153 0 : bool operator()(const PKHash& dest) const { return true; } 154 0 : bool operator()(const ScriptHash& dest) const { return true; } 155 0 : bool operator()(const WitnessV0KeyHash& dest) const { return true; } 156 0 : bool operator()(const WitnessV0ScriptHash& dest) const { return true; } 157 0 : bool operator()(const WitnessV1Taproot& dest) const { return true; } 158 0 : bool operator()(const WitnessUnknown& dest) const { return true; } 159 : }; 160 : } // namespace 161 : 162 0 : CScript GetScriptForDestination(const CTxDestination& dest) 163 : { 164 0 : return std::visit(CScriptVisitor(), dest); 165 : } 166 : 167 0 : bool IsValidDestination(const CTxDestination& dest) { 168 0 : return std::visit(ValidDestinationVisitor(), dest); 169 : }