cpp 區塊鏈模擬示例(三)新基本原形工程的創建

 

/*ios

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

*/程序員

 

 

 

本章節相比前兩節課程,增長了交易等處理,而在工做量證實,挖礦,建立區塊,以及區塊鏈的操做也細緻了很多。windows

工程的具體創建能夠參考前兩章節內容,這裏再也不贅述。服務器

 

區塊Block

咱們在工程中首先建立Block.h和Block.cpp,用來實現block區塊的功能函數

咱們不會實現一個如同比特幣技術中使用的區塊鏈,那太複雜。咱們實現一個簡化版的區塊鏈基本原形,它僅包含了一些建立時間,區塊描述以及自己的哈希數值,以及上一個區塊的哈希數值。post

 1 class Block {
 2 public:
 3     string    _hash;                //當前區塊的哈希
 4     string    _data;                //區塊描述字符
 5     string    _prevHash;            //記錄上個塊的哈希值
 6     Block(const string&    prevHash, const string& dataIn);    //構造函數
 7     void SetHash();                //設置本區塊的哈希
 8 private:
 9     int64_t _nNonce;            //區塊隨機數 用於哈希值的產生
10     time_t    _tTime;                //建立時間
11     
12 };
SetHash()函數就是根據區塊的這些屬性計算出區塊的哈希值。計算出符合標準的區塊哈希值應該是一個複雜困難的過程,即便在高速電腦中,也會人爲的提高閥值,讓區塊的產生不那麼快速。這個在隨後的章節會介紹,這裏只是使用最基本的計算方法。
根據結構體中的區塊描述字符,建立時間以及上個區塊的哈希值等元素計算出哈希值。 區塊描述字符和建立時間是讓哈希的計算有隨機性,而添加上個區塊的哈希值是讓全部區塊都具備關聯性,用來提高篡改區塊信息的難度。
代碼中使用的sha256函數來自來自Zedwood的C++ sha256函數,具體介紹能夠查看前面兩個章節
1 void Block::SetHash() {
2     stringstream ss;
3     ss << _tTime << _data << _prevHash;
4     _hash = sha256(ss.str());
5 }

區塊類的建立函數很簡單就是填寫各種信息,計算該區塊的哈希值區塊鏈

Block::Block( const string& dataIn, const string&    prevHash) {
    _tTime = time(nullptr);
    _nNonce = -1;
    _data = dataIn;    
    _prevHash = prevHash;
    SetHash();
}

 

 

區塊鏈Blockchain

區塊鏈就是一個個區塊的集合。使用vector<Block*> blocks 來存儲區塊的指針. ui

與go語言不一樣的是 全部的內存分配,咱們須要自行在退出前歸還內存。因此在析構函數中依次遍歷容器內的指針而且進行刪除內存。結構體以下spa

class Blockchain {
public:
    Blockchain(Block* p);
    vector<Block*>    blocks;
    void AddBlock(string datain);
    ~Blockchain() {
        for (int i = 0; i < blocks.size(); i++) {
            if (blocks[i] != NULL) {
                delete blocks[i];
                blocks[i] = NULL;
            }
        }
    }
private:

};

區塊鏈建立時候會添加一個Genesis Block創世區塊。 這個區塊與其餘區塊的區別在於該區塊沒有上一個區塊信息,它是第一個區塊。

 

        static Block* NewGenesisBlock() {
        return NewBlock("Genesis Block", "");
    }

    static Blockchain* NewBlockchain() {
        //建立一個創世塊 創世塊沒有prevhash 它是第一個塊
        Block* pblock = NewGenesisBlock();
        Blockchain* p = new Blockchain(pblock);
        return  p;
    }
    static Block* NewBlock(string datain, string prevBlockHash) {
        Block* p = new Block( datain, prevBlockHash);
        return p;
    }    

 

Blockchain::Blockchain(Block* p) {
    blocks.clear();
    blocks.push_back(p);
}

 

下面開始在main函數檢測咱們的函數是否工做正常

 

 

#include "Blockchain.h"
#include "util.h"
#include <vector>
#include <iostream>

using namespace std;

int main()
{
    Blockchain* bc = TOOLS::NewBlockchain();

    bc->AddBlock("Send 1 BTC to Ivan");
    bc->AddBlock("Send 2 more BTC to Ivan");

    for (int i = 0; i < bc->blocks.size(); i++) {
        std::cout << "Prev hash = " << bc->blocks[i]->_prevHash << std::endl;
        std::cout << "data  = " << bc->blocks[i]->_data << std::endl;
        std::cout << "hash  = " << bc->blocks[i]->_hash << std::endl << std::endl;

    }

    //退出以前 刪除
    delete bc;

    return 0;
}

 

運行結果

 

下一個章節介紹工做量證實
本章節代碼存儲在QQ羣文件中 文件名 MyBlockChainCppSample_part1

 

參考博文:

https://blog.csdn.net/simple_the_best/article/details/78073844

https://jeiwan.cc/posts/building-blockchain-in-go-part-1/

相關文章
相關標籤/搜索