比特币私钥生成

比特币突破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 };

 

 
posted on 2017-10-31 15:40  豆芽的博客  阅读(5001)  评论(0编辑  收藏  举报