比特币私钥生成
Posted 豆芽的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了比特币私钥生成相关的知识,希望对你有一定的参考价值。
比特币突破4万人民币一个了,于是下了份源码来研究研究。
重点分析下比特币私钥生成的原理,看能否重现私钥的,只要有私钥这个随机数就相当于拥有了整个账户,然而看到了这一句:
根据CPU当前性能来生成:
void RandAddSeed()
{
// Seed with CPU performance counter
int64_t nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
memory_cleanse((void*)&nCounter, sizeof(nCounter));
}
看到这个就不用去想自己能重现私钥了,如果只是时间随机数种子还是有希望的,遍历每毫秒。
实际上生成随机私钥用到了3种随机数:
// First source: OpenSSL\'s RNG
RandAddSeedPerfmon();
GetRandBytes(buf, 32);
hasher.Write(buf, 32);
// Second source: OS RNG
GetOSRand(buf);
hasher.Write(buf, 32);
// Third source: HW RNG, if available.
if (GetHWRand(buf)) {
hasher.Write(buf, 32);
}
基本上来说是真随机了,而不是我们平时生成的伪随机数。至少这个随机数没有办法重现,够狠,这也是比特币赖以生存的原因。
私钥是完全随机的,那么账号就是安全的,可以放心通过私钥生成公钥,地址等,比特币伟大之处在于够随机,随机的范围够广(0到2的256次方),以至于获得这个随机数(私钥)本身需要消耗巨大的成本,当成本无法覆盖收益时,逐利的人就不会选择来破解它。前几周玩了玩比特币交易,对其理解更深刻了一层,伟大的东西希望能发扬光大吧,感觉比特币未来想象空间是无限的
欢迎来我的博客看看 http://www.cnblogs.com/douyamv
个人网站: http://www.douyamv.com/
core的主要方法如下:
1 class CWallet final : public CCryptoKeyStore, public CValidationInterface 2 { 3 private: 4 static std::atomic<bool> fFlushScheduled; 5 std::atomic<bool> fAbortRescan; 6 std::atomic<bool> fScanningWallet; 7 8 /** 9 * Select a set of coins such that nValueRet >= nTargetValue and at least 10 * all coins from coinControl are selected; Never select unconfirmed coins 11 * if they are not ours 12 */ 13 bool SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl *coinControl = nullptr) const; 14 15 CWalletDB *pwalletdbEncryption; 16 17 //! the current wallet version: clients below this version are not able to load the wallet 18 int nWalletVersion; 19 20 //! the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded 21 int nWalletMaxVersion; 22 23 int64_t nNextResend; 24 int64_t nLastResend; 25 bool fBroadcastTransactions; 26 27 /** 28 * Used to keep track of spent outpoints, and 29 * detect and report conflicts (double-spends or 30 * mutated transactions where the mutant gets mined). 31 */ 32 typedef std::multimap<COutPoint, uint256> TxSpends; 33 TxSpends mapTxSpends; 34 void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); 35 void AddToSpends(const uint256& wtxid); 36 37 /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */ 38 void MarkConflicted(const uint256& hashBlock, const uint256& hashTx); 39 40 void SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator>); 41 42 /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected. 43 * Should be called with pindexBlock and posInBlock if this is for a transaction that is included in a block. */ 44 void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0); 45 46 /* the HD chain data model (external chain counters) */ 47 CHDChain hdChain; 48 49 /* HD derive new child key (on internal or external chain) */ 50 void DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKey& secret, bool internal = false); 51 52 std::set<int64_t> setInternalKeyPool; 53 std::set<int64_t> setExternalKeyPool; 54 int64_t m_max_keypool_index; 55 std::map<CKeyID, int64_t> m_pool_key_to_index; 56 57 int64_t nTimeFirstKey; 58 59 /** 60 * Private version of AddWatchOnly method which does not accept a 61 * timestamp, and which will reset the wallet\'s nTimeFirstKey value to 1 if 62 * the watch key did not previously have a timestamp associated with it. 63 * Because this is an inherited virtual method, it is accessible despite 64 * being marked private, but it is marked private anyway to encourage use 65 * of the other AddWatchOnly which accepts a timestamp and sets 66 * nTimeFirstKey more intelligently for more efficient rescans. 67 */ 68 bool AddWatchOnly(const CScript& dest) override; 69 70 std::unique_ptr<CWalletDBWrapper> dbw; 71 72 public: 73 /* 74 * Main wallet lock. 75 * This lock protects all the fields added by CWallet. 76 */ 77 mutable CCriticalSection cs_wallet; 78 79 /** Get database handle used by this wallet. Ideally this function would 80 * not be necessary. 81 */ 82 CWalletDBWrapper& GetDBHandle() 83 { 84 return *dbw; 85 } 86 87 /** Get a name for this wallet for logging/debugging purposes. 88 */ 89 std::string GetName() const 90 { 91 if (dbw) { 92 return dbw->GetName(); 93 } else { 94 return "dummy"; 95 } 96 } 97 98 void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool); 99 100 // Map from Key ID (for regular keys) or Script ID (for watch-only keys) to 101 // key metadata. 102 std::map<CTxDestination, CKeyMetadata> mapKeyMetadata; 103 104 typedef std::map<unsigned int, CMasterKey> MasterKeyMap; 105 MasterKeyMap mapMasterKeys; 106 unsigned int nMasterKeyMaxID; 107 108 // Create wallet with dummy database handle 109 CWallet(): dbw(new CWalletDBWrapper()) 110 { 111 SetNull(); 112 } 113 114 // Create wallet with passed-in database handle 115 explicit CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in)) 116 { 117 SetNull(); 118 } 119 120 ~CWallet() 121 { 122 delete pwalletdbEncryption; 123 pwalletdbEncryption = nullptr; 124 } 125 126 void SetNull() 127 { 128 nWalletVersion = FEATURE_BASE; 129 nWalletMaxVersion = FEATURE_BASE; 130 nMasterKeyMaxID = 0; 131 pwalletdbEncryption = nullptr; 132 nOrderPosNext = 0; 133 nAccountingEntryNumber = 0; 134 nNextResend = 0; 135 nLastResend = 0; 136 m_max_keypool_index = 0; 137 nTimeFirstKey = 0; 138 fBroadcastTransactions = false; 139 nRelockTime = 0; 140 fAbortRescan = false; 141 fScanningWallet = false; 142 } 143 144 std::map<uint256, CWalletTx> mapWallet; 145 std::list<CAccountingEntry> laccentries; 146 147 typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; 148 typedef std::multimap<int64_t, TxPair > TxItems; 149 TxItems wtxOrdered; 150 151 int64_t nOrderPosNext; 152 uint64_t nAccountingEntryNumber; 153 std::map<uint256, int> mapRequestCount; 154 155 std::map<CTxDestination, CAddressBookData> mapAddressBook; 156 157 std::set<COutPoint> setLockedCoins; 158 159 const CWalletTx* GetWalletTx(const uint256& hash) const; 160 161 //! check whether we are allowed to upgrade (or already support) to the named feature 162 bool CanSupportFeature(enum WalletFeature wf) const { AssertLockHeld(cs_wallet); return nWalletMaxVersion >= wf; } 163 164 /** 165 * populate vCoins with vector of available COutputs. 166 */ 167 void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe=true, const CCoinControl *coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t& nMaximumCount = 0, const int& nMinDepth = 0, const int& nMaxDepth = 9999999) const; 168 169 /** 170 * Return list of available coins and locked coins grouped by non-change output address. 171 */ 172 std::map<CTxDestination, std::vector<COutput>> ListCoins() const; 173 174 /** 175 * Find non-change parent output. 176 */ 177 const CTxOut& FindNonChangeParentOutput(const CTransaction& tx, int output) const; 178 179 /** 180 * Shuffle and select coins until nTargetValue is reached while avoiding 181 * small change; This method is stochastic for some inputs and upon 182 * completion the coin set and corresponding actual target value is 183 * assembled 184 */ 185 bool SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector<COutput> vCoins, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet) const; 186 187 bool IsSpent(const uint256& hash, unsigned int n) const; 188 189 bool IsLockedCoin(uint256 hash, unsigned int n) const; 190 void LockCoin(const COutPoint& output); 191 void UnlockCoin(const COutPoint& output); 192 void UnlockAllCoins(); 193 void ListLockedCoins(std::vector<COutPoint>& vOutpts) const; 194 195 /* 196 * Rescan abort properties 197 */ 198 void AbortRescan() { fAbortRescan = true; } 199 bool IsAbortingRescan() { return fAbortRescan; } 200 bool IsScanning() { return fScanningWallet; } 201 202 /** 203 * keystore implementation 204 * Generate a new key 205 */ 206 CPubKey GenerateNewKey(CWalletDB& walletdb, bool internal = false); 207 //! Adds a key to the store, and saves it to disk. 208 bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override; 209 bool AddKeyPubKeyWithDB(CWalletDB &walletdb,const CKey& key, const CPubKey &pubkey); 210 //! Adds a key to the store, without saving it to disk (used by LoadWallet) 211 bool LoadKey(const CKey& key, const CPubKey &pubkey) { return CCryptoKeyStore::AddKeyPubKey(key, pubkey); } 212 //! Load metadata (used by LoadWallet) 213 bool LoadKeyMetadata(const CTxDestination& pubKey, const CKeyMetadata &metadata); 214 215 bool LoadMinVersion(int nVersion) { AssertLockHeld(cs_wallet); nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } 216 void UpdateTimeFirstKey(int64_t nCreateTime); 217 218 //! Adds an encrypted key to the store, and saves it to disk. 219 bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) override; 220 //! Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) 221 bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); 222 bool AddCScript(const CScript& redeemScript) override; 223 bool LoadCScript(const CScript& redeemScript); 224 225 //! Adds a destination data tuple to the store, and saves it to disk 226 bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value); 227 //! Erases a destination data tuple in the store and on disk 228 bool EraseDestData(const CTxDestination &dest, const std::string &key); 229 //! Adds a destination data tuple to the store, without saving it to disk 230 bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value); 231 //! Look up a destination data tuple in the store, return true if found false otherwise 232 bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const; 233 //! Get all destination values matching a prefix. 234 std::vector<std::string> GetDestValues(const std::string& prefix) const; 235 236 //! Adds a watch-only address to the store, and saves it to disk. 237 bool AddWatchOnly(const CScript& dest, int64_t nCreateTime); 238 bool RemoveWatchOnly(const CScript &dest) override; 239 //! Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) 240 bool LoadWatchOnly(const CScript &dest); 241 242 //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock(). 243 int64_t nRelockTime; 244 245 bool Unlock(const SecureString& strWalletPassphrase); 246 bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); 247 bool EncryptWallet(const SecureString& strWalletPassphrase); 248 249 void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const; 250 unsigned int ComputeTimeSmart(const CWalletTx& wtx) const; 251 252 /** 253 * Increment the next transaction order id 254 * @return next transaction order id 255 */ 256 int64_t IncOrderPosNext(CWalletDB *pwalletdb = nullptr); 257 DBErrors ReorderTransactions(); 258 bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment = ""); 259 bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew = false); 260 261 void MarkDirty(); 262 bool AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose=true); 263 bool LoadToWallet(const CWalletTx& wtxIn); 264 void TransactionAddedToMempool(const CTransactionRef& tx) override; 265 void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override; 266 void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override; 267 bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate); 268 int64_t RescanFromTime(int64_t startTime, bool update); 269 CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, CBlockIndex* pindexStop, bool fUpdate = false); 270 void ReacceptWalletTransactions(); 271 void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override; 272 // ResendWalletTransactionsBefore may only be called if fBroadcastTransactions! 273 std::vector<uint256> ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman); 274 CAmount GetBalance() const; 275 CAmount GetUnconfirmedBalance() const; 276 CAmount GetImmatureBalance() const; 277 CAmount GetWatchOnlyBalance() const; 278 CAmount GetUnconfirmedWatchOnlyBalance() const; 279 CAmount GetImmatureWatchOnlyBalance() const; 280 CAmount GetLegacyBalance(const isminefilter& filter, int minDepth, const std::string* account) const; 281 CAmount GetAvailableBalance(const CCoinControl* coinControl = nullptr) const; 282 283 /** 284 * Insert additional inputs into the transaction by 285 * calling CreateTransaction(); 286 */ 287 bool FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl); 288 bool SignTransaction(CMutableTransaction& tx); 289 290 /** 291 * Create a new transaction paying the recipients with a set of coins 292 * selected by SelectCoins(); Also create the change output, when needed 293 * @note passing nChangePosInOut as -1 will result in setting a random position 294 */ 295 bool CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, 296 std::string& strFailReason, const CCoinControl& coin_control, bool sign = true); 297 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state); 298 299 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries); 300 bool AddAccountingEntry(const CAccountingEntry&); 301 bool AddAccountingEntry(const CAccountingEntry&, CWalletDB *pwalletdb); 302 template <typename ContainerType> 303 bool DummySignTx(CMutableTransaction &txNew, const ContainerType &coins) const; 304 305 static CFeeRate minTxFee; 306 static CFeeRate fallbackFee; 307 static CFeeRate m_discard_rate; 308 309 bool NewKeyPool(); 310 size_t KeypoolCountExternalKeys(); 311 bool TopUpKeyPool(unsigned int kpSize = 0); 312 void ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal); 313 void KeepKey(int64_t nIndex); 314 void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey); 315 bool GetKeyFromPool(CPubKey &key, bool internal = false); 316 int64_t GetOldestKeyPoolTime(); 317 /** 318 * Marks all keys in the keypool up to and including reserve_key as used. 319 */ 320 void MarkReserveKeysAsUsed(int64_t keypool_id); 321 const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } 322 323 std::set< std::set<CTxDestination> > GetAddressGroupings(); 324 std::map<CTxDestination, CAmount> GetAddressBalances(); 325 326 std::set<CTxDestination> GetAccountAddresses(const std::string& strAccount) const; 327 328 isminetype IsMine(const CTxIn& txin) const; 329 /** 330 * Returns amount of debit if the input matches the 331 * filter, otherwise returns 0 332 */ 333 CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; 334 isminetype IsMine(const CTxOut& txout) const比特币私钥公钥地址