• cpp 区块链模拟示例(三)新基本原形工程的建立


    /*

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

    */

    本章节相比前两节课程,增加了交易等处理,而在工作量证明,挖矿,创建区块,以及区块链的操作也细致了不少。

    工程的具体建立可以参考前两章节内容,这里不再赘述。

    区块Block

    我们在工程中首先创建Block.h和Block.cpp,用来实现block区块的功能

    我们不会实现一个如同比特币技术中使用的区块链,那太复杂。我们实现一个简化版的区块链基本原形,它仅包含了一些创建时间,区块描述以及本身的哈希数值,以及上一个区块的哈希数值。

     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 来存储区块的指针. 

    与go语言不同的是 所有的内存分配,我们需要自行在退出前归还内存。所以在析构函数中依次遍历容器内的指针并且进行删除内存。结构体如下

    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/

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    【iOS系列】-UITableView的使用
    c语言学习-指针探究
    sublime text 3 乱码
    连接sql2008时报错
    android各种菜单使用介绍
    Android使用开源框架加载图片
    Android数据与服务器交互的GET,POST,HTTPGET,HTTPPOST的使用
    Android开发pool解析xml
    github的提交源码到服务器
    Android多线程更新UI的方式
  • 原文地址:https://www.cnblogs.com/itdef/p/9430045.html
Copyright © 2020-2023  润新知