cpp 區塊鏈模擬示例(二)工程代碼解析

/*c++

做 者: itdef 程序員

歡迎轉帖 請保持文本完整並註明出處 
技術博客 http://www.cnblogs.com/itdef/ 
技術交流羣 羣號碼:432336863
歡迎c c++ windows驅動愛好者 服務器程序員溝通交流
部分老代碼存放地點
http://www.oschina.net/code/list_by_user?id=614253
windows

*/服務器

 

書接上文函數

咱們先來看區塊的結構區塊鏈

 1 class Block {
 2 public:
 3     string sPrevHash;            //記錄上個塊的哈希值
 4     Block(uint32_t nIndexIn, const string &sDataIn);    //構造函數
 5     string GetHash();            //獲取哈希函數
 6     void MineBlock(uint32_t nDifficulty);    //挖礦函數
 7 private:
 8     uint32_t _nIndex;            //該區塊的索引值
 9     int64_t _nNonce;            //區塊隨機數 用於哈希值的產生
10     string _sData;                //區塊描述字符
11     string _sHash;                //區塊哈希值
12     time_t _tTime;                //建立時間
13     string _CalculateHash() const;    //哈希值計算函數
14 };

區塊結構很清晰。 一個區塊就是一個建立時間、描述字符、區塊隨機數字等數據組成。ui

咱們要建立一個區塊就是根據建立時間、描述字符、區塊隨機數字等數據來計算出一個哈希值(_CalculateHash函數的功能)。 spa

inline string Block::_CalculateHash() const {
    stringstream ss;
    ss << _nIndex << _tTime << _sData << _nNonce << sPrevHash;
    return sha256(ss.str());
}

 

因爲_nNonce與建立時間是一值在變化的,_CalculateHash()會產生一個個的哈希。.net

在MineBlock()函數中對這些哈希進行檢測,看看是否符合標準,一旦符合標準,那麼久誕生了一個區塊。code

這裏的MineBlock()函數中,根據設置的DifficultyNum,來檢測哈希數值前DifficultyNum位是否爲零,只有符合標準纔是產生的區塊的可以使用的哈希值

隨即產生的哈希值中,前DifficultyNum位爲零,只在必定機率下才產生。 這也是爲了限制區塊的產生速度,在本次區塊鏈技術模擬中,咱們稱之爲"工做量證實"

void Block::MineBlock(uint32_t nDifficulty) {
    char cstr[DifficultyNum + 1];
    for (uint32_t i = 0; i < DifficultyNum; ++i) {
        cstr[i] = '0';
    }
    cstr[DifficultyNum] = '\0';
    string str(cstr);
    do {
        _nNonce++;
        _sHash = _CalculateHash();
    } while (_sHash.substr(0, nDifficulty) != str);
    cout << "Block mined: " << _sHash << endl;
}


Block
結構體中 sPrevHash就是記錄該區塊的上一個區塊的哈希值。區塊鏈技術中使用一種方法將哈希值與區塊一一對應。

這樣知道一個區塊和區塊中的sPrevHash。經過查找能夠依次遍歷區塊鏈中的每一個區塊。這些有關聯的區塊也正是使用這種方法組成了區塊鏈.

 

 

區塊鏈結構體以下

class Blockchain {
public:
    Blockchain();                    //區塊鏈構造函數
    void AddBlock(Block bNew);        //區塊鏈添加區塊函數
private:
    uint32_t _nDifficulty;            //難度值
    vector<Block> _vChain;            //記錄區塊鏈
    Block _GetLastBlock() const;    //獲取最後一個區塊
};

大體的示意圖以下

咱們的模擬文章中,區塊鏈使用了vector<Block> _vChain來記錄每一個區塊,每一個區塊中都有本身在這個vector中的索引_nIndex,這樣查找起來更簡單快捷。

區塊鏈建立的時候會插入一個索引爲零,描述字符爲" Genesis Block "的區塊,稱之爲創始塊. 創世塊與其餘塊的區別是交易的輸入與輸出,這個在後繼章節再詳細介紹。

AddBlock()與_GetLastBlock()相對比較簡單,_GetLastBlock()就是返回vector<Block> _vChain的最後一個元素。

AddBlock()就是經過挖礦產生一個區塊,放入到記錄vector<Block> _vChain中。固然要記得設置該塊的sPrevHash爲以前區塊鏈中最後一個塊的哈希值.

Blockchain::Blockchain() {
    _vChain.emplace_back(Block(0, "Genesis Block"));
    _nDifficulty = DifficultyNum;
}

void Blockchain::AddBlock(Block bNew) {
    bNew.sPrevHash = _GetLastBlock().GetHash();
    bNew.MineBlock(_nDifficulty);
    _vChain.push_back(bNew);
}

Block Blockchain::_GetLastBlock() const {
    return _vChain.back();
}

 

《build-a-blockchain-with-c》 的講解和VC工程的創建就到此爲止。

相對《用 Go 構建一個區塊鏈》 ,《build-a-blockchain-with-c》代碼量少並且簡單。

下面的章節咱們將進行 《用 Go 構建一個區塊鏈》的c++化  並講解代碼內容

相關文章
相關標籤/搜索