/ src / addresstype.h
addresstype.h
  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  class CNoDestination
 19  {
 20  private:
 21      CScript m_script;
 22  
 23  public:
 24      CNoDestination() = default;
 25      explicit CNoDestination(const CScript& script) : m_script(script) {}
 26  
 27      const CScript& GetScript() const LIFETIMEBOUND { return m_script; }
 28  
 29      friend bool operator==(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() == b.GetScript(); }
 30      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      explicit PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {}
 39  
 40      const CPubKey& GetPubKey() const LIFETIMEBOUND { return m_pubkey; }
 41  
 42      friend bool operator==(const PubKeyDestination& a, const PubKeyDestination& b) { return a.GetPubKey() == b.GetPubKey(); }
 43      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      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      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      WitnessV0ScriptHash() : BaseHash() {}
 74      explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {}
 75      explicit WitnessV0ScriptHash(const CScript& script);
 76  };
 77  
 78  struct WitnessV0KeyHash : public BaseHash<uint160>
 79  {
 80      WitnessV0KeyHash() : BaseHash() {}
 81      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      WitnessV1Taproot() : XOnlyPubKey() {}
 90      explicit WitnessV1Taproot(const XOnlyPubKey& xpk) : XOnlyPubKey(xpk) {}
 91  };
 92  
 93  //! CTxDestination subtype to encode any future Witness version
 94  struct WitnessUnknown
 95  {
 96  private:
 97      unsigned int m_version;
 98      std::vector<unsigned char> m_program;
 99  
100  public:
101      WitnessUnknown(unsigned int version, const std::vector<unsigned char>& program) : m_version(version), m_program(program) {}
102      WitnessUnknown(int version, const std::vector<unsigned char>& program) : m_version(static_cast<unsigned int>(version)), m_program(program) {}
103  
104      unsigned int GetWitnessVersion() const { return m_version; }
105      const std::vector<unsigned char>& GetWitnessProgram() const LIFETIMEBOUND { return m_program; }
106  
107      friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) {
108          if (w1.GetWitnessVersion() != w2.GetWitnessVersion()) return false;
109          return w1.GetWitnessProgram() == w2.GetWitnessProgram();
110      }
111  
112      friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) {
113          if (w1.GetWitnessVersion() < w2.GetWitnessVersion()) return true;
114          if (w1.GetWitnessVersion() > w2.GetWitnessVersion()) return false;
115          return w1.GetWitnessProgram() < w2.GetWitnessProgram();
116      }
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