Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

hdchain.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2020 The Dash Core developers
2 // Distributed under the MIT software license, see the accompanying
3 
4 #include <base58.h>
5 #include <bip39.h>
6 #include <chainparams.h>
7 #include <hdchain.h>
8 #include <tinyformat.h>
9 #include <util.h>
10 #include <utilstrencodings.h>
11 
13 {
16  id = uint256();
17  fCrypted = false;
18  vchSeed.clear();
19  vchMnemonic.clear();
20  vchMnemonicPassphrase.clear();
21  mapAccounts.clear();
22  // default blank account
23  mapAccounts.insert(std::pair<uint32_t, CHDAccount>(0, CHDAccount()));
24  return IsNull();
25 }
26 
27 bool CHDChain::IsNull() const
28 {
29  return vchSeed.empty() || id == uint256();
30 }
31 
32 void CHDChain::SetCrypted(bool fCryptedIn)
33 {
34  fCrypted = fCryptedIn;
35 }
36 
37 bool CHDChain::IsCrypted() const
38 {
39  return fCrypted;
40 }
41 
42 void CHDChain::Debug(const std::string& strName) const
43 {
44  DBG(
45  std::cout << __func__ << ": ---" << strName << "---" << std::endl;
46  if (fCrypted) {
47  std::cout << "mnemonic: ***CRYPTED***" << std::endl;
48  std::cout << "mnemonicpassphrase: ***CRYPTED***" << std::endl;
49  std::cout << "seed: ***CRYPTED***" << std::endl;
50  } else {
51  std::cout << "mnemonic: " << std::string(vchMnemonic.begin(), vchMnemonic.end()).c_str() << std::endl;
52  std::cout << "mnemonicpassphrase: " << std::string(vchMnemonicPassphrase.begin(), vchMnemonicPassphrase.end()).c_str() << std::endl;
53  std::cout << "seed: " << HexStr(vchSeed).c_str() << std::endl;
54 
55  CExtKey extkey;
56  extkey.SetMaster(vchSeed.data(), vchSeed.size());
57 
58  CBitcoinExtKey b58extkey;
59  b58extkey.SetKey(extkey);
60  std::cout << "extended private masterkey: " << b58extkey.ToString().c_str() << std::endl;
61 
62  CExtPubKey extpubkey;
63  extpubkey = extkey.Neuter();
64 
65  CBitcoinExtPubKey b58extpubkey;
66  b58extpubkey.SetKey(extpubkey);
67  std::cout << "extended public masterkey: " << b58extpubkey.ToString().c_str() << std::endl;
68  }
69  );
70 }
71 
72 bool CHDChain::SetMnemonic(const SecureVector& vchMnemonic, const SecureVector& vchMnemonicPassphrase, bool fUpdateID)
73 {
75 }
76 
77 bool CHDChain::SetMnemonic(const SecureString& ssMnemonic, const SecureString& ssMnemonicPassphrase, bool fUpdateID)
78 {
79  SecureString ssMnemonicTmp = ssMnemonic;
80 
81  if (fUpdateID) {
82  // can't (re)set mnemonic if seed was already set
83  if (!IsNull())
84  return false;
85 
86  // empty mnemonic i.e. "generate a new one"
87  if (ssMnemonic.empty()) {
88  ssMnemonicTmp = CMnemonic::Generate(256);
89  }
90  // NOTE: default mnemonic passphrase is an empty string
91 
92  // printf("mnemonic: %s\n", ssMnemonicTmp.c_str());
93  if (!CMnemonic::Check(ssMnemonicTmp)) {
94  throw std::runtime_error(std::string(__func__) + ": invalid mnemonic: `" + std::string(ssMnemonicTmp.c_str()) + "`");
95  }
96 
97  CMnemonic::ToSeed(ssMnemonicTmp, ssMnemonicPassphrase, vchSeed);
98  id = GetSeedHash();
99  }
100 
101  vchMnemonic = SecureVector(ssMnemonicTmp.begin(), ssMnemonicTmp.end());
102  vchMnemonicPassphrase = SecureVector(ssMnemonicPassphrase.begin(), ssMnemonicPassphrase.end());
103 
104  return !IsNull();
105 }
106 
107 bool CHDChain::GetMnemonic(SecureVector& vchMnemonicRet, SecureVector& vchMnemonicPassphraseRet) const
108 {
109  // mnemonic was not set, fail
110  if (vchMnemonic.empty())
111  return false;
112 
113  vchMnemonicRet = vchMnemonic;
114  vchMnemonicPassphraseRet = vchMnemonicPassphrase;
115  return true;
116 }
117 
118 bool CHDChain::GetMnemonic(SecureString& ssMnemonicRet, SecureString& ssMnemonicPassphraseRet) const
119 {
120  // mnemonic was not set, fail
121  if (vchMnemonic.empty())
122  return false;
123 
124  ssMnemonicRet = SecureString(vchMnemonic.begin(), vchMnemonic.end());
125  ssMnemonicPassphraseRet = SecureString(vchMnemonicPassphrase.begin(), vchMnemonicPassphrase.end());
126 
127  return true;
128 }
129 
130 bool CHDChain::SetSeed(const SecureVector& vchSeedIn, bool fUpdateID)
131 {
132  vchSeed = vchSeedIn;
133 
134  if (fUpdateID) {
135  id = GetSeedHash();
136  }
137 
138  return !IsNull();
139 }
140 
142 {
143  return vchSeed;
144 }
145 
147 {
148  return Hash(vchSeed.begin(), vchSeed.end());
149 }
150 
151 void CHDChain::DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey& extKeyRet)
152 {
153  // Use BIP44 keypath scheme i.e. m / purpose' / coin_type' / account' / change / address_index
154  CExtKey masterKey; //hd master key
155  CExtKey purposeKey; //key at m/purpose'
156  CExtKey cointypeKey; //key at m/purpose'/coin_type'
157  CExtKey accountKey; //key at m/purpose'/coin_type'/account'
158  CExtKey changeKey; //key at m/purpose'/coin_type'/account'/change
159  CExtKey childKey; //key at m/purpose'/coin_type'/account'/change/address_index
160 
161  masterKey.SetMaster(vchSeed.data(), vchSeed.size());
162 
163  // Use hardened derivation for purpose, coin_type and account
164  // (keys >= 0x80000000 are hardened after bip32)
165 
166  // derive m/purpose'
167  masterKey.Derive(purposeKey, 44 | 0x80000000);
168  // derive m/purpose'/coin_type'
169  purposeKey.Derive(cointypeKey, Params().ExtCoinType() | 0x80000000);
170  // derive m/purpose'/coin_type'/account'
171  cointypeKey.Derive(accountKey, nAccountIndex | 0x80000000);
172  // derive m/purpose'/coin_type'/account'/change
173  accountKey.Derive(changeKey, fInternal ? 1 : 0);
174  // derive m/purpose'/coin_type'/account'/change/address_index
175  changeKey.Derive(extKeyRet, nChildIndex);
176 }
177 
179 {
180  LOCK(cs_accounts);
181  mapAccounts.insert(std::pair<uint32_t, CHDAccount>(mapAccounts.size(), CHDAccount()));
182 }
183 
184 bool CHDChain::GetAccount(uint32_t nAccountIndex, CHDAccount& hdAccountRet)
185 {
186  LOCK(cs_accounts);
187  if (nAccountIndex > mapAccounts.size() - 1)
188  return false;
189  hdAccountRet = mapAccounts[nAccountIndex];
190  return true;
191 }
192 
193 bool CHDChain::SetAccount(uint32_t nAccountIndex, const CHDAccount& hdAccount)
194 {
195  LOCK(cs_accounts);
196  // can only replace existing accounts
197  if (nAccountIndex > mapAccounts.size() - 1)
198  return false;
199  mapAccounts[nAccountIndex] = hdAccount;
200  return true;
201 }
202 
204 {
205  LOCK(cs_accounts);
206  return mapAccounts.size();
207 }
208 
209 std::string CHDPubKey::GetKeyPath() const
210 {
211  return strprintf("m/44'/%d'/%d'/%d/%d", Params().ExtCoinType(), nAccountIndex, nChangeIndex, extPubKey.nChild);
212 }
static const int CURRENT_VERSION
Definition: hdchain.h:31
std::map< uint32_t, CHDAccount > mapAccounts
Definition: hdchain.h:42
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:268
#define strprintf
Definition: tinyformat.h:1066
#define DBG(x)
Server/client environment: argument handling, config file parsing, logging, thread wrappers...
Definition: util.h:47
bool fCrypted
Definition: hdchain.h:36
Definition: key.h:141
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
void SetKey(const K &key)
Definition: base58.h:117
void Debug(const std::string &strName) const
Definition: hdchain.cpp:42
uint256 GetSeedHash()
Definition: hdchain.cpp:146
unsigned int nChild
Definition: pubkey.h:203
void AddAccount()
Definition: hdchain.cpp:178
bool SetAccount(uint32_t nAccountIndex, const CHDAccount &hdAccount)
Definition: hdchain.cpp:193
static void ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector &seedRet)
Definition: bip39.cpp:152
std::string ToString() const
Definition: base58.cpp:193
void SetCrypted(bool fCryptedIn)
Definition: hdchain.cpp:32
SecureVector vchMnemonic
Definition: hdchain.h:39
#define LOCK(cs)
Definition: sync.h:178
std::vector< unsigned char, secure_allocator< unsigned char > > SecureVector
Definition: secure.h:59
void DeriveChildExtKey(uint32_t nAccountIndex, bool fInternal, uint32_t nChildIndex, CExtKey &extKeyRet)
Definition: hdchain.cpp:151
SecureVector vchMnemonicPassphrase
Definition: hdchain.h:40
bool IsNull() const
Definition: hdchain.cpp:27
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:84
uint32_t nChangeIndex
Definition: hdchain.h:132
SecureVector vchSeed
Definition: hdchain.h:38
256-bit opaque blob.
Definition: uint256.h:123
bool GetMnemonic(SecureVector &vchMnemonicRet, SecureVector &vchMnemonicPassphraseRet) const
Definition: hdchain.cpp:107
SecureVector GetSeed() const
Definition: hdchain.cpp:141
static SecureString Generate(int strength)
Copyright (c) 2013-2014 Tomas Dzetkulic Copyright (c) 2013-2014 Pavol Rusnak.
Definition: bip39.cpp:34
CExtPubKey Neuter() const
Definition: key.cpp:287
static bool Check(SecureString mnemonic)
Definition: bip39.cpp:80
const CChainParams & Params()
Return the currently selected parameters.
bool GetAccount(uint32_t nAccountIndex, CHDAccount &hdAccountRet)
Definition: hdchain.cpp:184
bool SetMnemonic(const SecureVector &vchMnemonic, const SecureVector &vchMnemonicPassphrase, bool fUpdateID)
Definition: hdchain.cpp:72
void SetMaster(const unsigned char *seed, unsigned int nSeedLen)
Definition: key.cpp:276
bool IsCrypted() const
Definition: hdchain.cpp:37
std::string GetKeyPath() const
Definition: hdchain.cpp:209
bool SetSeed(const SecureVector &vchSeedIn, bool fUpdateID)
Definition: hdchain.cpp:130
bool SetNull()
Definition: hdchain.cpp:12
CCriticalSection cs_accounts
Definition: hdchain.h:44
int nVersion
Definition: hdchain.h:32
CExtPubKey extPubKey
Definition: hdchain.h:129
size_t CountAccounts()
Definition: hdchain.cpp:203
uint32_t nAccountIndex
Definition: hdchain.h:131
Released under the MIT license