Bitcoin ABC 0.34.2
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 <hash.h>
8#include <pubkey.h>
9#include <script/script.h>
10#include <script/solver.h>
11#include <uint256.h>
12#include <util/hash_type.h>
13
14#include <vector>
15
16typedef std::vector<uint8_t> valtype;
17
20 : BaseHash(static_cast<uint160>(in)) {}
21
22CScriptID ToScriptID(const ScriptHash &script_hash) {
23 return CScriptID{static_cast<uint160>(script_hash)};
24}
25
26PKHash::PKHash(const CPubKey &pubkey) : BaseHash(pubkey.GetID()) {}
27PKHash::PKHash(const CKeyID &pubkey_id) : BaseHash(pubkey_id) {}
28
29CKeyID ToKeyID(const PKHash &key_hash) {
30 return CKeyID{static_cast<uint160>(key_hash)};
31}
32
33bool ExtractDestination(const CScript &scriptPubKey,
34 CTxDestination &addressRet) {
35 std::vector<valtype> vSolutions;
36 TxoutType whichType = Solver(scriptPubKey, vSolutions);
37
38 if (whichType == TxoutType::PUBKEY) {
39 CPubKey pubKey(vSolutions[0]);
40 if (!pubKey.IsValid()) {
41 return false;
42 }
43
44 addressRet = PKHash(pubKey);
45 return true;
46 }
47 if (whichType == TxoutType::PUBKEYHASH) {
48 addressRet = PKHash(uint160(vSolutions[0]));
49 return true;
50 }
51 if (whichType == TxoutType::SCRIPTHASH) {
52 addressRet = ScriptHash(uint160(vSolutions[0]));
53 return true;
54 }
55 // Multisig txns have more than one address...
56 return false;
57}
58
59bool ExtractDestinations(const CScript &scriptPubKey, TxoutType &typeRet,
60 std::vector<CTxDestination> &addressRet,
61 int &nRequiredRet) {
62 addressRet.clear();
63 std::vector<valtype> vSolutions;
64 typeRet = Solver(scriptPubKey, vSolutions);
65 if (typeRet == TxoutType::NONSTANDARD) {
66 return false;
67 } else if (typeRet == TxoutType::NULL_DATA) {
68 // This is data, not addresses
69 return false;
70 }
71
72 if (typeRet == TxoutType::MULTISIG) {
73 nRequiredRet = vSolutions.front()[0];
74 for (size_t i = 1; i < vSolutions.size() - 1; i++) {
75 CPubKey pubKey(vSolutions[i]);
76 if (!pubKey.IsValid()) {
77 continue;
78 }
79
80 CTxDestination address = PKHash(pubKey);
81 addressRet.push_back(address);
82 }
83
84 if (addressRet.empty()) {
85 return false;
86 }
87 } else {
88 nRequiredRet = 1;
89 CTxDestination address;
90 if (!ExtractDestination(scriptPubKey, address)) {
91 return false;
92 }
93 addressRet.push_back(address);
94 }
95
96 return true;
97}
98
99namespace {
100class CScriptVisitor {
101public:
102 CScript operator()(const CNoDestination &dest) const { return CScript(); }
103
104 CScript operator()(const PKHash &keyID) const {
105 return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID)
107 }
108
109 CScript operator()(const ScriptHash &scriptID) const {
110 return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
111 }
112};
113} // namespace
114
116 return std::visit(CScriptVisitor(), dest);
117}
118
120 return dest.index() != 0;
121}
CScriptID ToScriptID(const ScriptHash &script_hash)
Definition: addresstype.cpp:22
std::vector< uint8_t > valtype
Definition: addresstype.cpp:16
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: addresstype.cpp:33
bool ExtractDestinations(const CScript &scriptPubKey, TxoutType &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
Definition: addresstype.cpp:59
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
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, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: addresstype.h:54
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:22
An encapsulated public key.
Definition: pubkey.h:31
bool IsValid() const
Definition: pubkey.h:147
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:434
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:564
160-bit opaque blob.
Definition: uint256.h:184
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
@ OP_CHECKSIG
Definition: script.h:169
@ OP_EQUAL
Definition: script.h:125
@ OP_DUP
Definition: script.h:104
@ OP_HASH160
Definition: script.h:166
@ OP_EQUALVERIFY
Definition: script.h:126
std::vector< uint8_t > ToByteVector(const T &in)
Definition: script.h:48
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< uint8_t > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:93
TxoutType
Definition: solver.h:15
PKHash()
Definition: addresstype.h:28