PIVX Core  5.6.99
P2P Digital Currency
key_io.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2019 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 "script/script.h"
9 #include <boost/variant/apply_visitor.hpp>
10 #include <boost/variant/static_visitor.hpp>
11 
12 #include <assert.h>
13 #include <string.h>
14 #include <algorithm>
15 
16 namespace
17 {
18  class DestinationEncoder : public boost::static_visitor<std::string>
19  {
20  private:
21  const CChainParams& m_params;
22  const CChainParams::Base58Type m_addrType;
23 
24  public:
25  explicit DestinationEncoder(const CChainParams& params, const CChainParams::Base58Type _addrType = CChainParams::PUBKEY_ADDRESS) : m_params(params), m_addrType(_addrType) {}
26 
27  std::string operator()(const CKeyID& id) const
28  {
29  std::vector<unsigned char> data = m_params.Base58Prefix(m_addrType);
30  data.insert(data.end(), id.begin(), id.end());
31  return EncodeBase58Check(data);
32  }
33 
34  std::string operator()(const CExchangeKeyID& id) const
35  {
36  std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::EXCHANGE_ADDRESS);
37  data.insert(data.end(), id.begin(), id.end());
38  return EncodeBase58Check(data);
39  }
40 
41  std::string operator()(const CScriptID& id) const
42  {
43  std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
44  data.insert(data.end(), id.begin(), id.end());
45  return EncodeBase58Check(data);
46  }
47 
48  std::string operator()(const CNoDestination& no) const { return ""; }
49  };
50 
51  CTxDestination DecodeDestination(const std::string& str, const CChainParams& params, bool& isStaking, bool& isExchange)
52  {
53  std::vector<unsigned char> data;
54  uint160 hash;
55  if (DecodeBase58Check(str, data, 23)) {
56  // base58-encoded PIVX addresses.
57  // Public-key-hash-addresses have version 30 (or 139 testnet).
58  // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key.
59  const std::vector<unsigned char>& pubkey_prefix = params.Base58Prefix(CChainParams::PUBKEY_ADDRESS);
60  if (data.size() == hash.size() + pubkey_prefix.size() && std::equal(pubkey_prefix.begin(), pubkey_prefix.end(), data.begin())) {
61  std::copy(data.begin() + pubkey_prefix.size(), data.end(), hash.begin());
62  return CKeyID(hash);
63  }
64  // Exchange Transparent addresses have version 31
65  const std::vector<unsigned char>& exchange_pubkey_prefix = params.Base58Prefix(CChainParams::EXCHANGE_ADDRESS);
66  if (data.size() == hash.size() + exchange_pubkey_prefix.size() && std::equal(exchange_pubkey_prefix.begin(), exchange_pubkey_prefix.end(), data.begin())) {
67  isExchange = true;
68  std::copy(data.begin() + exchange_pubkey_prefix.size(), data.end(), hash.begin());
69  return CExchangeKeyID(hash);
70  }
71  // Public-key-hash-coldstaking-addresses have version 63 (or 73 testnet).
72  const std::vector<unsigned char>& staking_prefix = params.Base58Prefix(CChainParams::STAKING_ADDRESS);
73  if (data.size() == hash.size() + staking_prefix.size() && std::equal(staking_prefix.begin(), staking_prefix.end(), data.begin())) {
74  isStaking = true;
75  std::copy(data.begin() + staking_prefix.size(), data.end(), hash.begin());
76  return CKeyID(hash);
77  }
78  // Script-hash-addresses have version 13 (or 19 testnet).
79  // The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
80  const std::vector<unsigned char>& script_prefix = params.Base58Prefix(CChainParams::SCRIPT_ADDRESS);
81  if (data.size() == hash.size() + script_prefix.size() && std::equal(script_prefix.begin(), script_prefix.end(), data.begin())) {
82  std::copy(data.begin() + script_prefix.size(), data.end(), hash.begin());
83  return CScriptID(hash);
84  }
85  }
86  return CNoDestination();
87  }
88 
89 } // anon namespace
90 
91 std::string EncodeDestination(const CTxDestination& dest, bool isStaking, bool isExchange)
92 {
94 }
95 
96 std::string EncodeDestination(const CTxDestination& dest, const CChainParams::Base58Type addrType)
97 {
98  return boost::apply_visitor(DestinationEncoder(Params(), addrType), dest);
99 }
100 
101 CTxDestination DecodeDestination(const std::string& str)
102 {
103  bool isStaking;
104  bool isExchange;
105  return DecodeDestination(str, Params(), isStaking, isExchange);
106 }
107 
108 CTxDestination DecodeDestination(const std::string& str, bool& isStaking, bool& isExchange)
109 {
110  return DecodeDestination(str, Params(), isStaking, isExchange);
111 }
112 
113 bool IsValidDestinationString(const std::string& str, bool fStaking, const CChainParams& params)
114 {
115  bool isStaking = false;
116  bool isExchange = false;
117  return IsValidDestination(DecodeDestination(str, params, isStaking, isExchange)) && (isStaking == fStaking);
118 }
119 
120 bool IsValidDestinationString(const std::string& str, bool isStaking)
121 {
122  return IsValidDestinationString(str, isStaking, Params());
123 }
124 
125 namespace KeyIO {
126 
127  CKey DecodeSecret(const std::string &str) {
128  CKey key;
129  std::vector<unsigned char> data;
130  if (DecodeBase58Check(str, data, 34)) {
131  const std::vector<unsigned char> &privkey_prefix = Params().Base58Prefix(CChainParams::SECRET_KEY);
132  if ((data.size() == 32 + privkey_prefix.size() ||
133  (data.size() == 33 + privkey_prefix.size() && data.back() == 1)) &&
134  std::equal(privkey_prefix.begin(), privkey_prefix.end(), data.begin())) {
135  bool compressed = data.size() == 33 + privkey_prefix.size();
136  key.Set(data.begin() + privkey_prefix.size(), data.begin() + privkey_prefix.size() + 32, compressed);
137  }
138  }
139  if (!data.empty()) {
140  memory_cleanse(data.data(), data.size());
141  }
142  return key;
143  }
144 
145  std::string EncodeSecret(const CKey &key) {
146  assert(key.IsValid());
147  std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::SECRET_KEY);
148  data.insert(data.end(), key.begin(), key.end());
149  if (key.IsCompressed()) {
150  data.push_back(1);
151  }
152  std::string ret = EncodeBase58Check(data);
153  memory_cleanse(data.data(), data.size());
154  return ret;
155  }
156 
157  CExtKey DecodeExtKey(const std::string &str) {
158  CExtKey key;
159  std::vector<unsigned char> data;
160  if (DecodeBase58Check(str, data, 78)) {
161  const std::vector<unsigned char> &prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
162  if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() &&
163  std::equal(prefix.begin(), prefix.end(), data.begin())) {
164  key.Decode(data.data() + prefix.size());
165  }
166  }
167  return key;
168  }
169 
170  std::string EncodeExtKey(const CExtKey &key) {
171  std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
172  size_t size = data.size();
173  data.resize(size + BIP32_EXTKEY_SIZE);
174  key.Encode(data.data() + size);
175  std::string ret = EncodeBase58Check(data);
176  memory_cleanse(data.data(), data.size());
177  return ret;
178  }
179 
180  CExtPubKey DecodeExtPubKey(const std::string& str)
181  {
182  CExtPubKey key;
183  std::vector<unsigned char> data;
184  if (DecodeBase58Check(str, data, 78)) {
185  const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
186  if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
187  key.Decode(data.data() + prefix.size());
188  }
189  }
190  return key;
191  }
192 
193  std::string EncodeExtPubKey(const CExtPubKey& key)
194  {
195  std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_PUBLIC_KEY);
196  size_t size = data.size();
197  data.resize(size + BIP32_EXTKEY_SIZE);
198  key.Encode(data.data() + size);
199  std::string ret = EncodeBase58Check(data);
200  return ret;
201  }
202 
203 }// namespace
bool DecodeBase58Check(const char *psz, std::vector< unsigned char > &vchRet, int max_ret_len)
Decode a base58-encoded string (psz) that includes a checksum into a byte vector (vchRet),...
Definition: base58.cpp:135
std::string EncodeBase58Check(const std::vector< unsigned char > &vchIn)
Encode a byte vector into a base58-encoded string, including checksum.
Definition: base58.cpp:126
const CChainParams & Params()
Return the currently selected parameters.
CChainParams defines various tweakable parameters of a given instance of the PIVX system.
Definition: chainparams.h:43
const std::vector< unsigned char > & Base58Prefix(Base58Type type) const
Definition: chainparams.h:93
A reference to a CKey: the Hash160 of its serialized public key, special case for exchange key.
Definition: pubkey.h:30
An encapsulated private key.
Definition: key.h:30
const unsigned char * end() const
Definition: key.h:92
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:95
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:98
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:76
const unsigned char * begin() const
Definition: key.h:91
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:24
unsigned int size() const
Definition: uint256.h:83
unsigned char * begin()
Definition: uint256.h:63
160-bit opaque blob.
Definition: uint256.h:127
void memory_cleanse(void *ptr, size_t len)
Definition: cleanse.cpp:27
bool IsValidDestinationString(const std::string &str, bool fStaking, const CChainParams &params)
Definition: key_io.cpp:113
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:101
std::string EncodeDestination(const CTxDestination &dest, bool isStaking, bool isExchange)
Definition: key_io.cpp:91
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:145
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:127
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:193
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:170
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:180
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:157
bool IsValidDestination(const CWDestination &address)
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:17
const char * prefix
Definition: rest.cpp:564
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:72
Definition: key.h:148
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: key.cpp:327
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: key.cpp:313
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:258
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:269