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 : : #ifndef BITCOIN_ADDRESSTYPE_H 6 : : #define BITCOIN_ADDRESSTYPE_H 7 : : 8 : : #include <pubkey.h> 9 : : #include <script/script.h> 10 : : #include <uint256.h> 11 : : #include <util/hash_type.h> 12 : : 13 : : #include <variant> 14 : : #include <algorithm> 15 : : 16 : : class CNoDestination { 17 : : private: 18 : : CScript m_script; 19 : : 20 : : public: 21 : 1187161 : CNoDestination() = default; 22 : 921341 : CNoDestination(const CScript& script) : m_script(script) {} 23 : : 24 : 3972 : const CScript& GetScript() const { return m_script; } 25 : : 26 : 1000 : friend bool operator==(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() == b.GetScript(); } 27 : 486 : friend bool operator<(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() < b.GetScript(); } 28 : : }; 29 : : 30 : : struct PubKeyDestination { 31 : : private: 32 : : CPubKey m_pubkey; 33 : : 34 : : public: 35 : 8986 : PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {} 36 : : 37 : 7 : const CPubKey& GetPubKey() const LIFETIMEBOUND { return m_pubkey; } 38 : : 39 : 0 : friend bool operator==(const PubKeyDestination& a, const PubKeyDestination& b) { return a.GetPubKey() == b.GetPubKey(); } 40 : 0 : friend bool operator<(const PubKeyDestination& a, const PubKeyDestination& b) { return a.GetPubKey() < b.GetPubKey(); } 41 : : }; 42 : : 43 : : struct PKHash : public BaseHash<uint160> 44 : : { 45 : : PKHash() : BaseHash() {} 46 : 20900 : explicit PKHash(const uint160& hash) : BaseHash(hash) {} 47 : : explicit PKHash(const CPubKey& pubkey); 48 : : explicit PKHash(const CKeyID& pubkey_id); 49 : : }; 50 : : CKeyID ToKeyID(const PKHash& key_hash); 51 : : 52 : : struct WitnessV0KeyHash; 53 : : 54 : : struct ScriptHash : public BaseHash<uint160> 55 : : { 56 : : ScriptHash() : BaseHash() {} 57 : : // These don't do what you'd expect. 58 : : // Use ScriptHash(GetScriptForDestination(...)) instead. 59 : : explicit ScriptHash(const WitnessV0KeyHash& hash) = delete; 60 : : explicit ScriptHash(const PKHash& hash) = delete; 61 : : 62 : 102113 : explicit ScriptHash(const uint160& hash) : BaseHash(hash) {} 63 : : explicit ScriptHash(const CScript& script); 64 : : explicit ScriptHash(const CScriptID& script); 65 : : }; 66 : : CScriptID ToScriptID(const ScriptHash& script_hash); 67 : : 68 : : struct WitnessV0ScriptHash : public BaseHash<uint256> 69 : : { 70 : 48720 : WitnessV0ScriptHash() : BaseHash() {} 71 : 1300 : explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {} 72 : : explicit WitnessV0ScriptHash(const CScript& script); 73 : : }; 74 : : 75 : : struct WitnessV0KeyHash : public BaseHash<uint160> 76 : : { 77 : 57639 : WitnessV0KeyHash() : BaseHash() {} 78 : 2627 : explicit WitnessV0KeyHash(const uint160& hash) : BaseHash(hash) {} 79 : : explicit WitnessV0KeyHash(const CPubKey& pubkey); 80 : : explicit WitnessV0KeyHash(const PKHash& pubkey_hash); 81 : : }; 82 : : CKeyID ToKeyID(const WitnessV0KeyHash& key_hash); 83 : : 84 : : struct WitnessV1Taproot : public XOnlyPubKey 85 : : { 86 : 5207 : WitnessV1Taproot() : XOnlyPubKey() {} 87 : 288 : explicit WitnessV1Taproot(const XOnlyPubKey& xpk) : XOnlyPubKey(xpk) {} 88 : : }; 89 : : 90 : : //! CTxDestination subtype to encode any future Witness version 91 : : struct WitnessUnknown 92 : : { 93 : : private: 94 : : unsigned int m_version; 95 : : std::vector<unsigned char> m_program; 96 : : 97 : : public: 98 : 562 : WitnessUnknown(unsigned int version, const std::vector<unsigned char>& program) : m_version(version), m_program(program) {} 99 : 16214 : WitnessUnknown(int version, const std::vector<unsigned char>& program) : m_version(static_cast<unsigned int>(version)), m_program(program) {} 100 : : 101 : 58320 : unsigned int GetWitnessVersion() const { return m_version; } 102 : 24872 : const std::vector<unsigned char>& GetWitnessProgram() const LIFETIMEBOUND { return m_program; } 103 : : 104 : 15 : friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) { 105 [ + + ]: 15 : if (w1.GetWitnessVersion() != w2.GetWitnessVersion()) return false; 106 : 13 : return w1.GetWitnessProgram() == w2.GetWitnessProgram(); 107 : 15 : } 108 : : 109 : 5 : friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) { 110 [ + + ]: 5 : if (w1.GetWitnessVersion() < w2.GetWitnessVersion()) return true; 111 [ + + ]: 4 : if (w1.GetWitnessVersion() > w2.GetWitnessVersion()) return false; 112 : 3 : return w1.GetWitnessProgram() < w2.GetWitnessProgram(); 113 : 5 : } 114 : : }; 115 : : 116 : : /** 117 : : * A txout script categorized into standard templates. 118 : : * * CNoDestination: Optionally a script, no corresponding address. 119 : : * * PubKeyDestination: TxoutType::PUBKEY (P2PK), no corresponding address 120 : : * * PKHash: TxoutType::PUBKEYHASH destination (P2PKH address) 121 : : * * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH address) 122 : : * * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH address) 123 : : * * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH address) 124 : : * * WitnessV1Taproot: TxoutType::WITNESS_V1_TAPROOT destination (P2TR address) 125 : : * * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W??? address) 126 : : * A CTxDestination is the internal data type encoded in a bitcoin address 127 : : */ 128 : : using CTxDestination = std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>; 129 : : 130 : : /** Check whether a CTxDestination corresponds to one with an address. */ 131 : : bool IsValidDestination(const CTxDestination& dest); 132 : : 133 : : /** 134 : : * Parse a scriptPubKey for the destination. 135 : : * 136 : : * For standard scripts that have addresses (and P2PK as an exception), a corresponding CTxDestination 137 : : * is assigned to addressRet. 138 : : * For all other scripts. addressRet is assigned as a CNoDestination containing the scriptPubKey. 139 : : * 140 : : * Returns true for standard destinations with addresses - P2PKH, P2SH, P2WPKH, P2WSH, P2TR and P2W??? scripts. 141 : : * Returns false for non-standard destinations and those without addresses - P2PK, bare multisig, null data, and nonstandard scripts. 142 : : */ 143 : : bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); 144 : : 145 : : /** 146 : : * Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH 147 : : * script for a CKeyID destination, a P2SH script for a CScriptID, and an empty 148 : : * script for CNoDestination. 149 : : */ 150 : : CScript GetScriptForDestination(const CTxDestination& dest); 151 : : 152 : : #endif // BITCOIN_ADDRESSTYPE_H