cpp 区块链模拟示例(一)工程建立
/*
作 者: itdef
欢迎转帖 请保持文本完整并注明出处
技术博客 http://www.cnblogs.com/itdef/
技术交流群 群号码:432336863
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
部分老代码存放地点
http://www.oschina.net/code/list_by_user?id=614253
*/
今天,我将开启一个使用c++模拟区块链的系列,记录自己学习区块链与实践的心得体会.
文章将参考《一步步教小白使用C++构建区块链》(c++语言)
《用 Go 构建一个区块链 ---- Part 1: 基本原型》 (go语言) 等博客文,
通过使用c++编写和讲解一个简单的区块链代码,来加深自己对区块链原理的理解。
区块链中大量使用哈希算法。
算法将参与需要计算的整体内容全部作为元素添加至哈希计算中,最后得出一个独一无二的计算结果。
他的好处在于,可以用来验证一个文件没有被任何人更改。如果同时拥有待验证内容和哈希计算的结果,那么你可以很快验证自己的待验证内容是否正确。同时,正确内容遭到刻意的修改而计算出正确的哈希结果这种事情几乎不存在。
在这个示例中 我们使用来自Zedwood的C++ sha256函数提供我们需要的哈希计算,该链接中有sha256.h,sha256.cpp和LICENSE.txt文件,我们将它们保存在项目文件夹中。
前言少叙,开始建立工程。使用工具为vs2017,环境为windows操作系统.
创建一个窗口程序,名字叫做MyBlockChainCppSample.如图
建成后,MyBlockChainCppSample.cpp就是main文件包含main入口函数,暂时不必管它.如图
我们接下来创建区块和区块链的结构说明和实现。
区块的结构放在Block.h,由Block.cpp实现。
区块链的结构放在Blockchain.h,由Blockchain.cpp实现.
还有刚才提到的sha256.h,sha256.cpp和LICENSE.txt也要添加进工程中.
#pragma once #include <cstdint>
#include <iostream> using namespace std; #define DifficultyNum 4 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; //哈希值计算函数
};
Block.h
#include "Block.h"
#include "sha256.h"
#include <time.h>
#include <sstream> Block::Block(uint32_t nIndexIn, const string &sDataIn) : _nIndex(nIndexIn), _sData(sDataIn) {
_nNonce = -;
_tTime = time(nullptr);
} string Block::GetHash() {
return _sHash;
} 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;
} inline string Block::_CalculateHash() const {
stringstream ss;
ss << _nIndex << _tTime << _sData << _nNonce << sPrevHash;
return sha256(ss.str());
}
Block.cpp
#pragma once #include <cstdint>
#include <vector>
#include "Block.h" using namespace std; class Blockchain {
public:
Blockchain(); //区块链构造函数
void AddBlock(Block bNew); //区块链添加区块函数
private:
uint32_t _nDifficulty; //难度值
vector<Block> _vChain; //记录区块链
Block _GetLastBlock() const; //获取最后一个区块
};
Blockchain.h
#include "Blockchain.h" 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();
}
Blockchain.cpp
最后的工程结构如图
在MyBlockChainCppSample.cpp中添加以下代码
#include "Blockchain.h"
int main() {
Blockchain bChain = Blockchain();
cout << "Mining block 1..." << endl;
bChain.AddBlock(Block(1, "Block 1 Data"));
cout << "Mining block 2..." << endl;
bChain.AddBlock(Block(2, "Block 2 Data"));
cout << "Mining block 3..." << endl;
bChain.AddBlock(Block(3, "Block 3 Data"));
return 0;
}
到此代码添加结束 但是VC中编译代码可能会遇到以下问题
1 提示 stdafx.h未添加 这是VC默认要添加预编译头 我们可以设置不需要预编译头来解决这个问题(也可以在每个cpp文件中添加stdafx.h)
解决方式如图
2 会提示sprintf函数 不能使用。这是因为该函数时候早期使用的,在字符串处理上可能存在潜在处理错误。我们可以定义一个宏来告知编译器我们知道此类错误并愿意使用
定义如图
最后编译结果如图
这是设置 #define DifficultyNum 6 , 难度为6的计算结果
Mining block 1...
Block mined: 000000182cfdfadfd84a0578f64d68a1c38bbaf4cbcf18027b0be00ee9a37e18
Mining block 2...
Block mined: 0000002f57459a48244bbf39d089a2b6e7b9aac8dca7ef8b7e71ef6a24753522
Mining block 3...
Block mined: 000000a2eaf0c37a192b182e038e4b20146bfdadb5fffb3bb836d8a7af89c16d
请按任意键继续. . .
这是设置 #define DifficultyNum 4 , 难度为4的计算结果
Mining block 1...
Block mined: 0000dcdb20156ad2777f685bab10bde456b756c40ac7c1a70ab5015ccf207309
Mining block 2...
Block mined: 0000350fb47c51201df28dd8e5b0baf517bcf6175dad8df29feba87b5eaadfbe
Mining block 3...
Block mined: 0000aede11083363a82c9ec43346b1895d818ecde528a171e837e5577478cd78
请按任意键继续. . .
下篇进行代码解析
cpp 区块链模拟示例(一)工程建立的更多相关文章
- cpp 区块链模拟示例(二)工程代码解析
/* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...
- cpp 区块链模拟示例(三)新基本原形工程的建立
/* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...
- cpp 区块链模拟示例(四) 区块链工作量证明
本文主要在之前的区块链原形上添加了工作量证明,并且为后继的交易功能做好准备. 上一个章节我们已经创建了区块链的基本原形,但是区块的哈希计算和加入太过于简单,如果按照这种速度添加区块那么区块链估计一个小 ...
- cpp 区块链模拟示例(五) 序列化
有了区块和区块链的基本结构,有了工作量证明,我们已经可以开始挖矿了.剩下就是最核心的功能-交易,但是在开始实现交易这一重大功能之前,我们还要预先做一些铺垫,比如数据的序列化和启动命令解析. 根据< ...
- cpp 区块链模拟示例(六) 交易
交易(transaction)是比特币的核心所在,而区块链的唯一目的,也正是为了能够安全可靠地存储交易.在区块链中,交易一旦被创建,就没有任何人能够再去修改或是删除它.在今天的文章中,我们会实现交易的 ...
- cpp 区块链模拟示例(七) 补充 Merkle树
Merkle 树 完整的比特币数据库(也就是区块链)需要超过 140 Gb 的磁盘空间.因为比特币的去中心化特性,网络中的每个节点必须是独立,自给自足的,也就是每个节点必须存储一个区块链的完整副本.随 ...
- 区块链共识机制之工作量证明(POW)
像比特币.以太坊.NXT.Bitshares等这些区块链系统,其本质上是一种加密经济组织,它建立在点对点网络上,是去中心化.无管辖的,由密码学.经济学和社会共识来共同维护.这些加密网络因各种原因有着多 ...
- 使用Geth 构建以太坊区块链并模拟挖矿过程
使用Geth 构建以太坊区块链并模拟挖矿过程 Go-ethereum 是以太坊官方的一个Golang 实现,我们可以使用Geth 工具来创建创世区块并启动区块链,使用Clef 实现以太坊钱包的功能,以 ...
- 用Java为Hyperledger Fabric(超级账本)开发区块链智能合约链代码之部署与运行示例代码
部署并运行 Java 链代码示例 您已经定义并启动了本地区块链网络,而且已构建 Java shim 客户端 JAR 并安装到本地 Maven 存储库中,现在已准备好在之前下载的 Hyperledger ...
随机推荐
- 一次Windows 安装问题
在 thinpad x250上安装 windows 10时,提示"安装程序无法创建新的系统分区,也无法定位现有系统分区". x250 的主板上自带一个16G的闪存且标识为 主分区, ...
- windows copy 和xcopy
#将文件夹下文件拷贝到指定目录 将d盘下1文件夹内所有内容拷贝到测试目录下copy d:\1\ Z:\chenkai\测试目录\ /yxcopy D:\soft\svn工具 Z:\chenkai\测试 ...
- PP.io的三个阶段,“强中心”——“弱中心”——“去中心”
什么是PP.io? PP.io是我和Bill发起的存储项目,目的在于为开发者提供一个去中心化的存储和分发平台,能做到更便宜,更高速,更隐私. 当然做去中心化存储的项目也有好几个,FileCoin,Si ...
- Java面试知识点
(1) 关于finalize的问题:因为不可预测性,以及对垃圾回收性能的影响,Object.finalize()方法不推荐使用,并且在Java9中已经被废弃.Java 平台目前在逐步使用 java.l ...
- sweetalert弹窗的使用
之前接触到layer弹出层,今天又发现了一个非常实用的弹出层插件,它的名字叫做sweetalert. 官网地址:http://t4t5.github.io/sweetalert/ npm下载方式:np ...
- python——eval()函数
eval()函数用来执行一个字符串表达式,并返回表达式的值. 语法:eval(expression[, globals[, locals]]) x = 4 print(eval('3 * x'))12 ...
- Redux-persist使用
redux-persist作用是将store中的数据缓存到浏览器中,减少数据请求,每当白名单中的数据发生变化,才会进行一次更新缓存的操作,并且这个数据缓存是存在localStorage中的,不是会话级 ...
- 1 CRM
一.crm介绍 CRM,客户关系管理系统(Customer Relationship Management).企业用CRM技术来管理与客户之间的关系,以求提升企业成功的管理方式,其目的是协助企业管理销 ...
- 编织织物的knit course direction and knit wale direction
来自:http://www.definetextile.com/2013/04/course-wale.html
- 在阿里云Ubuntu 14.04 Linux服务器上安装docker
参考 How To Install and Use Docker: Getting Started 这篇最靠谱的文档在阿里云 Ubuntu 14.04 服务器上成功安装 docker . ---- ...