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 0 : CNoDestination() = default; 22 0 : CNoDestination(const CScript& script) : m_script(script) {} 23 : 24 0 : const CScript& GetScript() const { return m_script; } 25 : 26 0 : friend bool operator==(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() == b.GetScript(); } 27 0 : 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 0 : PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {} 36 : 37 0 : 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 0 : 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 0 : 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 0 : WitnessV0ScriptHash() : BaseHash() {} 71 0 : explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {} 72 : explicit WitnessV0ScriptHash(const CScript& script); 73 : }; 74 : 75 : struct WitnessV0KeyHash : public BaseHash<uint160> 76 : { 77 0 : WitnessV0KeyHash() : BaseHash() {} 78 0 : 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 0 : WitnessV1Taproot() : XOnlyPubKey() {} 87 0 : 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 0 : WitnessUnknown(unsigned int version, const std::vector<unsigned char>& program) : m_version(version), m_program(program) {} 99 0 : WitnessUnknown(int version, const std::vector<unsigned char>& program) : m_version(static_cast<unsigned int>(version)), m_program(program) {} 100 : 101 0 : unsigned int GetWitnessVersion() const { return m_version; } 102 0 : const std::vector<unsigned char>& GetWitnessProgram() const LIFETIMEBOUND { return m_program; } 103 : 104 0 : friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) { 105 0 : if (w1.GetWitnessVersion() != w2.GetWitnessVersion()) return false; 106 0 : return w1.GetWitnessProgram() == w2.GetWitnessProgram(); 107 0 : } 108 : 109 0 : friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) { 110 0 : if (w1.GetWitnessVersion() < w2.GetWitnessVersion()) return true; 111 0 : if (w1.GetWitnessVersion() > w2.GetWitnessVersion()) return false; 112 0 : return w1.GetWitnessProgram() < w2.GetWitnessProgram(); 113 0 : } 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