比特币突破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; 335 CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const; 336 bool IsChange(const CTxOut& txout) const; 337 CAmount GetChange(const CTxOut& txout) const; 338 bool IsMine(const CTransaction& tx) const; 339 /** should probably be renamed to IsRelevantToMe */ 340 bool IsFromMe(const CTransaction& tx) const; 341 CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; 342 /** Returns whether all of the inputs match the filter */ 343 bool IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const; 344 CAmount GetCredit(const CTransaction& tx, const isminefilter& filter) const; 345 CAmount GetChange(const CTransaction& tx) const; 346 void SetBestChain(const CBlockLocator& loc) override; 347 348 DBErrors LoadWallet(bool& fFirstRunRet); 349 DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx); 350 DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut); 351 352 bool SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& purpose); 353 354 bool DelAddressBook(const CTxDestination& address); 355 356 const std::string& GetAccountName(const CScript& scriptPubKey) const; 357 358 void Inventory(const uint256 &hash) override 359 { 360 { 361 LOCK(cs_wallet); 362 std::map<uint256, int>::iterator mi = mapRequestCount.find(hash); 363 if (mi != mapRequestCount.end()) 364 (*mi).second++; 365 } 366 } 367 368 void GetScriptForMining(std::shared_ptr<CReserveScript> &script); 369 370 unsigned int GetKeyPoolSize() 371 { 372 AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool 373 return setInternalKeyPool.size() + setExternalKeyPool.size(); 374 } 375 376 //! signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower 377 bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = nullptr, bool fExplicit = false); 378 379 //! change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format) 380 bool SetMaxVersion(int nVersion); 381 382 //! get the current wallet format (the oldest client version guaranteed to understand this wallet) 383 int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } 384 385 //! Get wallet transactions that conflict with given transaction (spend same outputs) 386 std::set<uint256> GetConflicts(const uint256& txid) const; 387 388 //! Check if a given transaction has any of its outputs spent by another transaction in the wallet 389 bool HasWalletSpend(const uint256& txid) const; 390 391 //! Flush wallet (bitdb flush) 392 void Flush(bool shutdown=false); 393 394 /** 395 * Address book entry changed. 396 * @note called with lock cs_wallet held. 397 */ 398 boost::signals2::signal<void (CWallet *wallet, const CTxDestination 399 &address, const std::string &label, bool isMine, 400 const std::string &purpose, 401 ChangeType status)> NotifyAddressBookChanged; 402 403 /** 404 * Wallet transaction added, removed or updated. 405 * @note called with lock cs_wallet held. 406 */ 407 boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, 408 ChangeType status)> NotifyTransactionChanged; 409 410 /** Show progress e.g. for rescan */ 411 boost::signals2::signal<void (const std::string &title, int nProgress)> ShowProgress; 412 413 /** Watch-only address added */ 414 boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged; 415 416 /** Inquire whether this wallet broadcasts transactions. */ 417 bool GetBroadcastTransactions() const { return fBroadcastTransactions; } 418 /** Set whether this wallet broadcasts transactions. */ 419 void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } 420 421 /** Return whether transaction can be abandoned */ 422 bool TransactionCanBeAbandoned(const uint256& hashTx) const; 423 424 /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ 425 bool AbandonTransaction(const uint256& hashTx); 426 427 /** Mark a transaction as replaced by another transaction (e.g., BIP 125). */ 428 bool MarkReplaced(const uint256& originalHash, const uint256& newHash); 429 430 /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ 431 static CWallet* CreateWalletFromFile(const std::string walletFile); 432 433 /** 434 * Wallet post-init setup 435 * Gives the wallet a chance to register repetitive tasks and complete post-init tasks 436 */ 437 void postInitProcess(CScheduler& scheduler); 438 439 bool BackupWallet(const std::string& strDest); 440 441 /* Set the HD chain model (chain child index counters) */ 442 bool SetHDChain(const CHDChain& chain, bool memonly); 443 const CHDChain& GetHDChain() const { return hdChain; } 444 445 /* Returns true if HD is enabled */ 446 bool IsHDEnabled() const; 447 448 /* Generates a new HD master key (will not be activated) */ 449 CPubKey GenerateNewHDMasterKey(); 450 451 /* Set the current HD master key (will reset the chain child index counters) 452 Sets the master key's version based on the current wallet version (so the 453 caller must ensure the current wallet version is correct before calling 454 this function). */ 455 bool SetHDMasterKey(const CPubKey& key); 456 };