Bitcoin ABC 0.30.5
P2P Digital Currency
key_io.cpp
Go to the documentation of this file.
1// Copyright (c) 2014-2016 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <key_io.h>
6
7#include <base58.h>
8#include <cashaddrenc.h>
9#include <chainparams.h>
10#include <config.h>
11#include <util/strencodings.h>
12
13#include <algorithm>
14#include <cassert>
15#include <cstring>
16
17namespace {
18class DestinationEncoder {
19private:
21
22public:
23 explicit DestinationEncoder(const CChainParams &params)
24 : m_params(params) {}
25
26 std::string operator()(const PKHash &id) const {
27 std::vector<uint8_t> data =
29 data.insert(data.end(), id.begin(), id.end());
30 return EncodeBase58Check(data);
31 }
32
33 std::string operator()(const ScriptHash &id) const {
34 std::vector<uint8_t> data =
36 data.insert(data.end(), id.begin(), id.end());
37 return EncodeBase58Check(data);
38 }
39
40 std::string operator()(const CNoDestination &no) const { return {}; }
41};
42
43CTxDestination DecodeLegacyDestination(const std::string &str,
44 const CChainParams &params) {
45 std::vector<uint8_t> data;
46 uint160 hash;
47 if (!DecodeBase58Check(str, data, 21)) {
48 return CNoDestination();
49 }
50 // base58-encoded Bitcoin addresses.
51 // Public-key-hash-addresses have version 0 (or 111 testnet).
52 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is
53 // the serialized public key.
54 const std::vector<uint8_t> &pubkey_prefix =
56 if (data.size() == hash.size() + pubkey_prefix.size() &&
57 std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
58 std::copy(data.begin() + pubkey_prefix.size(), data.end(),
59 hash.begin());
60 return PKHash(hash);
61 }
62 // Script-hash-addresses have version 5 (or 196 testnet).
63 // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is
64 // the serialized redemption script.
65 const std::vector<uint8_t> &script_prefix =
67 if (data.size() == hash.size() + script_prefix.size() &&
68 std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
69 std::copy(data.begin() + script_prefix.size(), data.end(),
70 hash.begin());
71 return ScriptHash(hash);
72 }
73 return CNoDestination();
74}
75} // namespace
76
77CKey DecodeSecret(const std::string &str) {
78 return DecodeSecret(str, Params());
79}
80
81CKey DecodeSecret(const std::string &str, const CChainParams &params) {
82 CKey key;
83 std::vector<uint8_t> data;
84 if (DecodeBase58Check(str, data, 34)) {
85 const std::vector<uint8_t> &privkey_prefix =
87 if ((data.size() == 32 + privkey_prefix.size() ||
88 (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
89 std::equal(privkey_prefix.begin(), privkey_prefix.end(),
90 data.begin())) {
91 bool compressed = data.size() == 33 + privkey_prefix.size();
92 key.Set(data.begin() + privkey_prefix.size(),
93 data.begin() + privkey_prefix.size() + 32, compressed);
94 }
95 }
96 if (!data.empty()) {
97 memory_cleanse(data.data(), data.size());
98 }
99 return key;
100}
101
102std::string EncodeSecret(const CKey &key) {
103 return EncodeSecret(key, Params());
104}
105
106std::string EncodeSecret(const CKey &key, const CChainParams &params) {
107 assert(key.IsValid());
108 std::vector<uint8_t> data = params.Base58Prefix(CChainParams::SECRET_KEY);
109 data.insert(data.end(), key.begin(), key.end());
110 if (key.IsCompressed()) {
111 data.push_back(1);
112 }
113 std::string ret = EncodeBase58Check(data);
114 memory_cleanse(data.data(), data.size());
115 return ret;
116}
117
118CExtPubKey DecodeExtPubKey(const std::string &str) {
119 CExtPubKey key;
120 std::vector<uint8_t> data;
121 if (DecodeBase58Check(str, data, 78)) {
122 const std::vector<uint8_t> &prefix =
124 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() &&
125 std::equal(prefix.begin(), prefix.end(), data.begin())) {
126 key.Decode(data.data() + prefix.size());
127 }
128 }
129 return key;
130}
131
132std::string EncodeExtPubKey(const CExtPubKey &key) {
133 std::vector<uint8_t> data =
135 size_t size = data.size();
136 data.resize(size + BIP32_EXTKEY_SIZE);
137 key.Encode(data.data() + size);
138 std::string ret = EncodeBase58Check(data);
139 return ret;
140}
141
142CExtKey DecodeExtKey(const std::string &str) {
143 CExtKey key;
144 std::vector<uint8_t> data;
145 if (DecodeBase58Check(str, data, 78)) {
146 const std::vector<uint8_t> &prefix =
148 if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() &&
149 std::equal(prefix.begin(), prefix.end(), data.begin())) {
150 key.Decode(data.data() + prefix.size());
151 }
152 }
153 return key;
154}
155
156std::string EncodeExtKey(const CExtKey &key) {
157 std::vector<uint8_t> data =
159 size_t size = data.size();
160 data.resize(size + BIP32_EXTKEY_SIZE);
161 key.Encode(data.data() + size);
162 std::string ret = EncodeBase58Check(data);
163 memory_cleanse(data.data(), data.size());
164 return ret;
165}
166
167std::string EncodeDestination(const CTxDestination &dest,
168 const Config &config) {
169 const CChainParams &params = config.GetChainParams();
170 return config.UseCashAddrEncoding() ? EncodeCashAddr(dest, params)
171 : EncodeLegacyAddr(dest, params);
172}
173
174CTxDestination DecodeDestination(const std::string &addr,
175 const CChainParams &params) {
176 CTxDestination dst = DecodeCashAddr(addr, params);
177 if (IsValidDestination(dst)) {
178 return dst;
179 }
180 return DecodeLegacyAddr(addr, params);
181}
182
183bool IsValidDestinationString(const std::string &str,
184 const CChainParams &params) {
185 return IsValidDestination(DecodeDestination(str, params));
186}
187
188std::string EncodeLegacyAddr(const CTxDestination &dest,
189 const CChainParams &params) {
190 return std::visit(DestinationEncoder(params), dest);
191}
192
193CTxDestination DecodeLegacyAddr(const std::string &str,
194 const CChainParams &params) {
195 return DecodeLegacyDestination(str, params);
196}
std::string EncodeBase58Check(Span< const uint8_t > input)
Encode a byte span into a base58-encoded string, including checksum.
Definition: base58.cpp:152
static bool DecodeBase58Check(const char *psz, std::vector< uint8_t > &vchRet, int max_ret_len)
Definition: base58.cpp:160
std::string EncodeCashAddr(const CTxDestination &dst, const CChainParams &params)
Definition: cashaddrenc.cpp:90
CTxDestination DecodeCashAddr(const std::string &addr, const CChainParams &params)
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:19
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:80
const std::vector< uint8_t > & Base58Prefix(Base58Type type) const
Return the list of hostnames to look up for DNS seeds.
Definition: chainparams.h:129
An encapsulated secp256k1 private key.
Definition: key.h:28
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:97
const uint8_t * begin() const
Definition: key.h:93
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:101
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:76
const uint8_t * end() const
Definition: key.h:94
Definition: config.h:19
virtual bool UseCashAddrEncoding() const =0
virtual const CChainParams & GetChainParams() const =0
unsigned int size() const
Definition: uint256.h:93
uint8_t * begin()
Definition: uint256.h:85
160-bit opaque blob.
Definition: uint256.h:117
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition: cleanse.cpp:14
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
Definition: key_io.cpp:167
bool IsValidDestinationString(const std::string &str, const CChainParams &params)
Definition: key_io.cpp:183
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:156
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:118
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:102
CTxDestination DecodeDestination(const std::string &addr, const CChainParams &params)
Definition: key_io.cpp:174
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:77
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:132
CTxDestination DecodeLegacyAddr(const std::string &str, const CChainParams &params)
Definition: key_io.cpp:193
std::string EncodeLegacyAddr(const CTxDestination &dest, const CChainParams &params)
Definition: key_io.cpp:188
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:142
const CChainParams & m_params
Definition: interfaces.cpp:786
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
const char * prefix
Definition: rest.cpp:817
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:260
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:85
Definition: key.h:167
void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const
Definition: key.cpp:406
void Decode(const uint8_t code[BIP32_EXTKEY_SIZE])
Definition: key.cpp:419
void Encode(uint8_t code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:313
void Decode(const uint8_t code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:325
assert(!tx.IsCoinBase())