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