Bitcoin Core  27.99.0
P2P Digital Currency
addresstype.cpp
Go to the documentation of this file.
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 #include <addresstype.h>
6 
7 #include <crypto/sha256.h>
8 #include <hash.h>
9 #include <pubkey.h>
10 #include <script/script.h>
11 #include <script/solver.h>
12 #include <uint256.h>
13 #include <util/hash_type.h>
14 
15 #include <cassert>
16 #include <vector>
17 
18 typedef std::vector<unsigned char> valtype;
19 
22 
23 PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
24 PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
25 
26 WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
27 WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {}
28 
29 CKeyID ToKeyID(const PKHash& key_hash)
30 {
31  return CKeyID{uint160{key_hash}};
32 }
33 
35 {
36  return CKeyID{uint160{key_hash}};
37 }
38 
39 CScriptID ToScriptID(const ScriptHash& script_hash)
40 {
41  return CScriptID{uint160{script_hash}};
42 }
43 
45 {
46  CSHA256().Write(in.data(), in.size()).Finalize(begin());
47 }
48 
49 bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
50 {
51  std::vector<valtype> vSolutions;
52  TxoutType whichType = Solver(scriptPubKey, vSolutions);
53 
54  switch (whichType) {
55  case TxoutType::PUBKEY: {
56  CPubKey pubKey(vSolutions[0]);
57  if (!pubKey.IsValid()) {
58  addressRet = CNoDestination(scriptPubKey);
59  } else {
60  addressRet = PubKeyDestination(pubKey);
61  }
62  return false;
63  }
64  case TxoutType::PUBKEYHASH: {
65  addressRet = PKHash(uint160(vSolutions[0]));
66  return true;
67  }
68  case TxoutType::SCRIPTHASH: {
69  addressRet = ScriptHash(uint160(vSolutions[0]));
70  return true;
71  }
73  WitnessV0KeyHash hash;
74  std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
75  addressRet = hash;
76  return true;
77  }
80  std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
81  addressRet = hash;
82  return true;
83  }
85  WitnessV1Taproot tap;
86  std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
87  addressRet = tap;
88  return true;
89  }
91  addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
92  return true;
93  }
97  addressRet = CNoDestination(scriptPubKey);
98  return false;
99  } // no default case, so the compiler can warn about missing cases
100  assert(false);
101 }
102 
103 namespace {
104 class CScriptVisitor
105 {
106 public:
107  CScript operator()(const CNoDestination& dest) const
108  {
109  return dest.GetScript();
110  }
111 
112  CScript operator()(const PubKeyDestination& dest) const
113  {
114  return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG;
115  }
116 
117  CScript operator()(const PKHash& keyID) const
118  {
119  return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
120  }
121 
122  CScript operator()(const ScriptHash& scriptID) const
123  {
124  return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
125  }
126 
127  CScript operator()(const WitnessV0KeyHash& id) const
128  {
129  return CScript() << OP_0 << ToByteVector(id);
130  }
131 
132  CScript operator()(const WitnessV0ScriptHash& id) const
133  {
134  return CScript() << OP_0 << ToByteVector(id);
135  }
136 
137  CScript operator()(const WitnessV1Taproot& tap) const
138  {
139  return CScript() << OP_1 << ToByteVector(tap);
140  }
141 
142  CScript operator()(const WitnessUnknown& id) const
143  {
144  return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();
145  }
146 };
147 
148 class ValidDestinationVisitor
149 {
150 public:
151  bool operator()(const CNoDestination& dest) const { return false; }
152  bool operator()(const PubKeyDestination& dest) const { return false; }
153  bool operator()(const PKHash& dest) const { return true; }
154  bool operator()(const ScriptHash& dest) const { return true; }
155  bool operator()(const WitnessV0KeyHash& dest) const { return true; }
156  bool operator()(const WitnessV0ScriptHash& dest) const { return true; }
157  bool operator()(const WitnessV1Taproot& dest) const { return true; }
158  bool operator()(const WitnessUnknown& dest) const { return true; }
159 };
160 } // namespace
161 
163 {
164  return std::visit(CScriptVisitor(), dest);
165 }
166 
168  return std::visit(ValidDestinationVisitor(), dest);
169 }
CScriptID ToScriptID(const ScriptHash &script_hash)
Definition: addresstype.cpp:39
std::vector< unsigned char > valtype
Definition: addresstype.cpp:18
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
CKeyID ToKeyID(const PKHash &key_hash)
Definition: addresstype.cpp:29
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:131
unsigned char * begin()
Definition: hash_type.h:18
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
const CScript & GetScript() const LIFETIMEBOUND
Definition: addresstype.h:27
An encapsulated public key.
Definition: pubkey.h:34
bool IsValid() const
Definition: pubkey.h:189
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:728
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:702
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:414
static opcodetype EncodeOP_N(int n)
Definition: script.h:513
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:583
const unsigned char * begin() const
Definition: pubkey.h:290
size_type size() const
Definition: prevector.h:296
value_type * data()
Definition: prevector.h:532
160-bit opaque blob.
Definition: uint256.h:95
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:66
@ OP_CHECKSIG
Definition: script.h:189
@ OP_EQUAL
Definition: script.h:145
@ OP_DUP
Definition: script.h:124
@ OP_HASH160
Definition: script.h:186
@ OP_1
Definition: script.h:82
@ OP_0
Definition: script.h:75
@ OP_EQUALVERIFY
Definition: script.h:146
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:140
TxoutType
Definition: solver.h:22
@ WITNESS_V1_TAPROOT
@ WITNESS_UNKNOWN
Only for Witness versions not already defined above.
@ WITNESS_V0_SCRIPTHASH
@ NULL_DATA
unspendable OP_RETURN script that carries data
@ WITNESS_V0_KEYHASH
PKHash()
Definition: addresstype.h:48
const CPubKey & GetPubKey() const LIFETIMEBOUND
Definition: addresstype.h:40
CTxDestination subtype to encode any future Witness version.
Definition: addresstype.h:95
assert(!tx.IsCoinBase())