/*

作 者: itdef

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

*/

书接上文

我们先来看区块的结构

 class Block {
public:
string sPrevHash; //记录上个块的哈希值
Block(uint32_t nIndexIn, const string &sDataIn); //构造函数
string GetHash(); //获取哈希函数
void MineBlock(uint32_t nDifficulty); //挖矿函数
private:
uint32_t _nIndex; //该区块的索引值
int64_t _nNonce; //区块随机数 用于哈希值的产生
string _sData; //区块描述字符
string _sHash; //区块哈希值
time_t _tTime; //创建时间
string _CalculateHash() const; //哈希值计算函数
};

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

我们要创建一个区块就是根据创建时间、描述字符、区块随机数字等数据来计算出一个哈希值(_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 + ];
for (uint32_t i = ; i < DifficultyNum; ++i) {
cstr[i] = '';
}
cstr[DifficultyNum] = '\0';
string str(cstr);
do {
_nNonce++;
_sHash = _CalculateHash();
} while (_sHash.substr(, 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(, "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++化  并讲解代码内容

cpp 区块链模拟示例(二)工程代码解析的更多相关文章

  1. cpp 区块链模拟示例(一)工程建立

    /* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...

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

    /* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...

  3. cpp 区块链模拟示例(四) 区块链工作量证明

    本文主要在之前的区块链原形上添加了工作量证明,并且为后继的交易功能做好准备. 上一个章节我们已经创建了区块链的基本原形,但是区块的哈希计算和加入太过于简单,如果按照这种速度添加区块那么区块链估计一个小 ...

  4. cpp 区块链模拟示例(五) 序列化

    有了区块和区块链的基本结构,有了工作量证明,我们已经可以开始挖矿了.剩下就是最核心的功能-交易,但是在开始实现交易这一重大功能之前,我们还要预先做一些铺垫,比如数据的序列化和启动命令解析. 根据< ...

  5. cpp 区块链模拟示例(六) 交易

    交易(transaction)是比特币的核心所在,而区块链的唯一目的,也正是为了能够安全可靠地存储交易.在区块链中,交易一旦被创建,就没有任何人能够再去修改或是删除它.在今天的文章中,我们会实现交易的 ...

  6. cpp 区块链模拟示例(七) 补充 Merkle树

    Merkle 树 完整的比特币数据库(也就是区块链)需要超过 140 Gb 的磁盘空间.因为比特币的去中心化特性,网络中的每个节点必须是独立,自给自足的,也就是每个节点必须存储一个区块链的完整副本.随 ...

  7. 《区块链DAPP开发入门、代码实现、场景应用》笔记4——Ethereum Wallet中部署合约

    账号创建完成之后,账号余额是0,但是部署合约是需要消耗GAS的,因此需要获取一定的以太币才能够继续本次实现.在测试网中获取以太币可以通过挖矿的方式,在开发菜单中可以选择打开挖矿模式,但是这需要将Syn ...

  8. 《区块链DAPP开发入门、代码实现、场景应用》笔记2——Solidity实现简单的智能合约

    本节仅以一个简单的智能合约示例,介绍智能合约的基本组成元素,本合约定义一个uint类型的变量,以及对应这个变量的读写函数. 01 pragma solidity >=0.4.0 <0.6. ...

  9. 《区块链DAPP开发入门、代码实现、场景应用》笔记5——区块链福利彩票的设计

    笔者一直强调,一定要利用区块链的特点来解决行业存在的问题,并且该问题最好用区块链解决或者说只能用区块链解决.彩票行业就是个例子. 在讲解代码之前,首先讲解一下业务设计,如图6.15所示. 图6.15 ...

随机推荐

  1. multiprocessing还是threading?

    今夜看了一篇分析python中多进程与多线程优劣的文章,文章通过几组性能测试强调了多进程的性能优势,同时也深入分析了为何python中多线程性能较差的原因,GIL就是解释器全局锁,该机制限制每个pyt ...

  2. 实验-12-JSP简单入门

    参考资料 JSP实验参考文件 主要看实验任务书 实验1. 第一个HTML页面与Tomcat 实验内容:任务书中的JSP-实验1. 1.1 EclipseJEE的使用 新建Tomcat Server 新 ...

  3. time&datetime

    关于time模块的代码部分 1 #_*_coding:utf-8_*_ 2 __author__ = 'Alex Li' 3 4 import time 5 6 7 # print(time.cloc ...

  4. Hive环境的安装

    hive是什么:hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能(HQL) hive有什么用 1.通过类SQL语句快速实现简单的Map ...

  5. Reachability实时监控网络变化

    Reachability是一种实时观察网络发生变化控件,如当你的手机处于WiFi情况下,他就会检测环境,当处于GPS的情况下改变环境,当处于无网络的情况下又是一种环境.下面我们看下关于Reachabi ...

  6. python中建模分析零息票收益率曲线--复利和连续复利

    收益率曲线(Yield Curve)是显示一组货币和信贷风险均相同,但期限不同的债券或其他金融工具收益率的图表.纵轴代表收益率,横轴则是距离到期的时间.在此用python建模分析零息票收益率曲线,输出 ...

  7. Java性能调优(一):调优的流程和程序性能分析

     https://blog.csdn.net/Oeljeklaus/article/details/80656732 Java性能调优 随着应用的数据量不断的增加,系统的反应一般会越来越慢,这个时候我 ...

  8. Hive表种map字段的查询取用

    建表可以用 map<string,string> 查询时可以按照 aaa[bbb], aaa 是map字段名,bbb是其中的参数名,就可以取到这个参数的值了 当参数名bbb是string时 ...

  9. 与引导文件系统/vmfs/devices..的备用设备之间的连接已丢失,主机配置更改将不会保存到持久存储中

    Cisco UCS 刀片服务器与NETAPP存储 1.异常问题描述: 2.可能原因:存储链路异常     比如断电恢复.光纤线本身的问题.模块的问题.环境温度的问题.bug之类的都有可能 3.处理: ...

  10. sendmail报错Relaying denied

    配置好sendmail后,使用php的mail()发送邮件,出现 SMTP server response: 550 5.7.1 Relaying denied. IP name lookup fai ...