• cpp 区块链模拟示例(二)工程代码解析


    /*

    作 者: itdef 

    欢迎转帖 请保持文本完整并注明出处 
    技术博客 http://www.cnblogs.com/itdef/ 
    技术交流群 群号码:432336863
    欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
    部分老代码存放地点
    http://www.oschina.net/code/list_by_user?id=614253

    */

    书接上文

    我们先来看区块的结构

     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 };

    区块结构很清晰。 一个区块就是一个创建时间、描述字符、区块随机数字等数据组成。

    我们要创建一个区块就是根据创建时间、描述字符、区块随机数字等数据来计算出一个哈希值(_CalculateHash函数的功能)。 

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

    由于_nNonce与创建时间是一值在变化的,_CalculateHash()会产生一个个的哈希。

    在MineBlock()函数中对这些哈希进行检测,看看是否符合标准,一旦符合标准,那么久诞生了一个区块。

    这里的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] = '';
        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++化  并讲解代码内容

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    请简单说一下你了解的端口及对应的服务?
    地址解析协议ARP和逆地址解析协议RARP
    IP地址分类
    OSI分层和五层协议
    对象如何晋升到老年代?
    JVM 垃圾回收机制,何时触发 MinorGC 等操作
    什么是引用?
    类加载机制
    Solaris10怎么创建flash archive
    RPC: program not registered (ZT)
  • 原文地址:https://www.cnblogs.com/itdef/p/9429269.html
Copyright © 2020-2023  润新知