NO IMAGE

(本文使用的是比特幣v0.1.0版本 點選下載原始碼)

比特幣是建立在數字加密基礎上的,接觸過比特幣的朋友應該知道:
(1)購買比特幣最後是通過一個比特幣地址進行的,比特幣地址就像支票中的支付物件(收款方);
(2)而比特幣地址則是通過公鑰單向雜湊生成的;
(3)而公鑰則是通過私鑰使用橢圓曲線演算法生成的,
(4)而私鑰通過作業系統底層生成的256位隨機熵;
比特幣系統的私鑰、公鑰和地址生成是通過OpenSSL庫實現的。
具體流程圖如下所示:

公鑰和私鑰的生成

金鑰的生成

CKey key;
  • key.MakeNewKey();
  • void MakeNewKey()
  • {
  • if (!EC_KEY_generate_key(pkey))
  • throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
  • }
  • 公鑰的獲取

    vector<unsigned char> GetPubKey() const
  • {
  • unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
  • if (!nSize)
  • throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
  • vector<unsigned char> vchPubKey(nSize, 0);
  • unsigned char* pbegin = &vchPubKey[0];
  • if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
  • throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
  • return vchPubKey;
  • }
  • 私鑰的獲取

    CPrivKey GetPrivKey() const
  • {
  • unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
  • if (!nSize)
  • throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
  • CPrivKey vchPrivKey(nSize, 0);
  • unsigned char* pbegin = &vchPrivKey[0];
  • if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
  • throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
  • return vchPrivKey;
  • }
  • 公鑰和私鑰的儲存

    私鑰儲存在mapKeys結構中(鍵為公鑰),公鑰儲存在mapPubKeys結果中(鍵為公鑰HASH)

    mapKeys[key.GetPubKey()] = key.GetPrivKey();
  • mapPubKeys[Hash160(key.GetPubKey())] = key.GetPubKey();
  • 通過公鑰生成公鑰HASH

    公鑰先使用SHA256函式再使用RIPEMD160函式生成公鑰HASH

    inline uint160 Hash160(const vector<unsigned char>& vch)
  • {
  • uint256 hash1;
  • SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
  • uint160 hash2;
  • RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
  • return hash2;
  • }
  • 通過公鑰Hash生成地址

    公鑰HASH字首加上一個位元組的版本號

    inline string Hash160ToAddress(uint160 hash160)
  • {
  • // add 1-byte version number to the front
  • vector<unsigned char> vch(1, ADDRESSVERSION);
  • vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
  • return EncodeBase58Check(vch);
  • }
  • 公鑰HASH字尾加入4位元組的校驗碼

    inline string EncodeBase58Check(const vector<unsigned char>& vchIn)
  • {
  • // add 4-byte hash check to the end
  • vector<unsigned char> vch(vchIn);
  • uint256 hash = Hash(vch.begin(), vch.end());
  • vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash 4);
  • return EncodeBase58(vch);
  • }
  • 通過EncodeBase58編碼生成比特幣地址

    inline string EncodeBase58(const vector<unsigned char>& vch)
  • {
  • return EncodeBase58(&vch[0], &vch[0] vch.size());
  • }
  • 上一篇: 比特幣原始碼解讀之執行緒處理-其他執行緒

    下一篇:比特幣原始碼解讀之創世塊的產生

    版權宣告:B鏈網原創,嚴禁修改。轉載請註明作者和原文連結
    http://www.360bchain.com/article/67.html

    版權宣告:B鏈網原創,嚴禁修改。轉載請註明作者和原文連結

    作者:雨後的蚊子

    原文連結: http://www.360bchain.com/article/67.html