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