|
| 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 | +public: |
| 18 | + friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } |
| 19 | + friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } |
| 20 | +}; |
| 21 | + |
| 22 | +struct PKHash : public BaseHash<uint160> |
| 23 | +{ |
| 24 | + PKHash() : BaseHash() {} |
| 25 | + explicit PKHash(const uint160& hash) : BaseHash(hash) {} |
| 26 | + explicit PKHash(const CPubKey& pubkey); |
| 27 | + explicit PKHash(const CKeyID& pubkey_id); |
| 28 | +}; |
| 29 | +CKeyID ToKeyID(const PKHash& key_hash); |
| 30 | + |
| 31 | +struct WitnessV0KeyHash; |
| 32 | + |
| 33 | +struct ScriptHash : public BaseHash<uint160> |
| 34 | +{ |
| 35 | + ScriptHash() : BaseHash() {} |
| 36 | + // These don't do what you'd expect. |
| 37 | + // Use ScriptHash(GetScriptForDestination(...)) instead. |
| 38 | + explicit ScriptHash(const WitnessV0KeyHash& hash) = delete; |
| 39 | + explicit ScriptHash(const PKHash& hash) = delete; |
| 40 | + |
| 41 | + explicit ScriptHash(const uint160& hash) : BaseHash(hash) {} |
| 42 | + explicit ScriptHash(const CScript& script); |
| 43 | + explicit ScriptHash(const CScriptID& script); |
| 44 | +}; |
| 45 | +CScriptID ToScriptID(const ScriptHash& script_hash); |
| 46 | + |
| 47 | +struct WitnessV0ScriptHash : public BaseHash<uint256> |
| 48 | +{ |
| 49 | + WitnessV0ScriptHash() : BaseHash() {} |
| 50 | + explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {} |
| 51 | + explicit WitnessV0ScriptHash(const CScript& script); |
| 52 | +}; |
| 53 | + |
| 54 | +struct WitnessV0KeyHash : public BaseHash<uint160> |
| 55 | +{ |
| 56 | + WitnessV0KeyHash() : BaseHash() {} |
| 57 | + explicit WitnessV0KeyHash(const uint160& hash) : BaseHash(hash) {} |
| 58 | + explicit WitnessV0KeyHash(const CPubKey& pubkey); |
| 59 | + explicit WitnessV0KeyHash(const PKHash& pubkey_hash); |
| 60 | +}; |
| 61 | +CKeyID ToKeyID(const WitnessV0KeyHash& key_hash); |
| 62 | + |
| 63 | +struct WitnessV1Taproot : public XOnlyPubKey |
| 64 | +{ |
| 65 | + WitnessV1Taproot() : XOnlyPubKey() {} |
| 66 | + explicit WitnessV1Taproot(const XOnlyPubKey& xpk) : XOnlyPubKey(xpk) {} |
| 67 | +}; |
| 68 | + |
| 69 | +//! CTxDestination subtype to encode any future Witness version |
| 70 | +struct WitnessUnknown |
| 71 | +{ |
| 72 | + unsigned int version; |
| 73 | + unsigned int length; |
| 74 | + unsigned char program[40]; |
| 75 | + |
| 76 | + friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) { |
| 77 | + if (w1.version != w2.version) return false; |
| 78 | + if (w1.length != w2.length) return false; |
| 79 | + return std::equal(w1.program, w1.program + w1.length, w2.program); |
| 80 | + } |
| 81 | + |
| 82 | + friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) { |
| 83 | + if (w1.version < w2.version) return true; |
| 84 | + if (w1.version > w2.version) return false; |
| 85 | + if (w1.length < w2.length) return true; |
| 86 | + if (w1.length > w2.length) return false; |
| 87 | + return std::lexicographical_compare(w1.program, w1.program + w1.length, w2.program, w2.program + w2.length); |
| 88 | + } |
| 89 | +}; |
| 90 | + |
| 91 | +/** |
| 92 | + * A txout script template with a specific destination. It is either: |
| 93 | + * * CNoDestination: no destination set |
| 94 | + * * PKHash: TxoutType::PUBKEYHASH destination (P2PKH) |
| 95 | + * * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH) |
| 96 | + * * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH) |
| 97 | + * * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH) |
| 98 | + * * WitnessV1Taproot: TxoutType::WITNESS_V1_TAPROOT destination (P2TR) |
| 99 | + * * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W???) |
| 100 | + * A CTxDestination is the internal data type encoded in a bitcoin address |
| 101 | + */ |
| 102 | +using CTxDestination = std::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>; |
| 103 | + |
| 104 | +/** Check whether a CTxDestination is a CNoDestination. */ |
| 105 | +bool IsValidDestination(const CTxDestination& dest); |
| 106 | + |
| 107 | +/** |
| 108 | + * Parse a standard scriptPubKey for the destination address. Assigns result to |
| 109 | + * the addressRet parameter and returns true if successful. Currently only works for P2PK, |
| 110 | + * P2PKH, P2SH, P2WPKH, and P2WSH scripts. |
| 111 | + */ |
| 112 | +bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); |
| 113 | + |
| 114 | +/** |
| 115 | + * Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH |
| 116 | + * script for a CKeyID destination, a P2SH script for a CScriptID, and an empty |
| 117 | + * script for CNoDestination. |
| 118 | + */ |
| 119 | +CScript GetScriptForDestination(const CTxDestination& dest); |
| 120 | + |
| 121 | +#endif // BITCOIN_ADDRESSTYPE_H |
0 commit comments