c++实现区块链的小Demo

首先是Block.h文件

#include<cstdint>
#include<iostream>
using namespace std;

class Block
{
    public:
        string sPrevHash;
        Block(uint32_t nIndexIn,const string &sDataIn);
        string GetHash();
        void MineBlock(uint32_t nDifficulty);//挖矿,其参数nDifficulty表示指定的难度值

    private:
        uint32_t _nIndex;//区块索引值,第几个区块,从0开始计算
        int64_t _nNonce;//区块随机数
        string _sData;//区块描述字符
        string _sHash;//区块Hash值
        time_t _tTime;//区块生成时间
        string _CalculateHash() const;//计算Hash值

};

Block.cpp

#include"Block.h"
#include"sha256.h"
#include"time.h"
#include<sstream>
Block::Block(uint32_t nIndexIn,const string &sDataIn):_nIndex(nIndexIn),_sData(sDataIn)
{
    _nNonce=-1;
    _tTime=time(nullptr);
}
string Block::GetHash()
{
    return _sHash;
}
void Block::MineBlock(uint32_t nDifficulty)
{
    char cstr[nDifficulty+1];
    for(uint32_t i=0;i<nDifficulty;++i)
    {
        cstr[i]='0';
    }
    cstr[nDifficulty]='\0';
    string str(cstr);

    do
        {
            _nNonce++;
            _sHash=_CalculateHash();

        }while(_sHash.substr(0,nDifficulty)!=str);
    cout<<"Block mined:"<<_sHash<<endl;
}
inline string Block::_CalculateHash() const
{
    stringstream ss;
    ss<<_nIndex<<_tTime<<_sData<<_nNonce<<sPrevHash;
    return sha256(ss.str());
}

Blockchain.h

#include"Block.h"
#include<vector>
class Blockchain
{
public:
    Blockchain();
    void AddBlock(Block bNew);
private:
    uint32_t _nDifficulty;
    vector<Block> _vChain;
    Block _GetLastBlock() const;//获取最新的区块,由const关键字,表示输出的内容不可更改
};

Blockchain.cpp

#include"Blockchain.h"
Blockchain::Blockchain()
{
    _vChain.emplace_back(Block(0,"Genesis Block"));
    _nDifficulty=3;
}
void Blockchain::AddBlock(Block bNew)
{
    bNew.sPrevHash=_GetLastBlock().GetHash();
    bNew.MineBlock(_nDifficulty);
    _vChain.push_back(bNew);
}
Block Blockchain::_GetLastBlock() const
{
    return _vChain.back();
}

引用了来自Zedwood的C++ sha256函数

sha256.h

#ifndef SHA256_H
#define SHA256_H
#include <string>

class SHA256
{
protected:
    typedef unsigned char uint8;
    typedef unsigned int uint32;
    typedef unsigned long long uint64;

    const static uint32 sha256_k[];
    static const unsigned int SHA224_256_BLOCK_SIZE = (512/8);
public:
    void init();
    void update(const unsigned char *message, unsigned int len);
    void final(unsigned char *digest);
    static const unsigned int DIGEST_SIZE = ( 256 / 8);

protected:
    void transform(const unsigned char *message, unsigned int block_nb);
    unsigned int m_tot_len;
    unsigned int m_len;
    unsigned char m_block[2*SHA224_256_BLOCK_SIZE];
    uint32 m_h[8];
};

std::string sha256(std::string input);

#define SHA2_SHFR(x, n)    (x >> n)
#define SHA2_ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define SHA2_ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define SHA2_CH(x, y, z)  ((x & y) ^ (~x & z))
#define SHA2_MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define SHA256_F1(x) (SHA2_ROTR(x,  2) ^ SHA2_ROTR(x, 13) ^ SHA2_ROTR(x, 22))
#define SHA256_F2(x) (SHA2_ROTR(x,  6) ^ SHA2_ROTR(x, 11) ^ SHA2_ROTR(x, 25))
#define SHA256_F3(x) (SHA2_ROTR(x,  7) ^ SHA2_ROTR(x, 18) ^ SHA2_SHFR(x,  3))
#define SHA256_F4(x) (SHA2_ROTR(x, 17) ^ SHA2_ROTR(x, 19) ^ SHA2_SHFR(x, 10))
#define SHA2_UNPACK32(x, str)                 \
{                                             \
    *((str) + 3) = (uint8) ((x)      );       \
    *((str) + 2) = (uint8) ((x) >>  8);       \
    *((str) + 1) = (uint8) ((x) >> 16);       \
    *((str) + 0) = (uint8) ((x) >> 24);       \
}
#define SHA2_PACK32(str, x)                   \
{                                             \
    *(x) =   ((uint32) *((str) + 3)      )    \
           | ((uint32) *((str) + 2) <<  8)    \
           | ((uint32) *((str) + 1) << 16)    \
           | ((uint32) *((str) + 0) << 24);   \
}
#endif

sha256.cpp


#include <cstring>
#include <fstream>
#include "sha256.h"

const unsigned int SHA256::sha256_k[64] = //UL = uint32
            {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};

void SHA256::transform(const unsigned char *message, unsigned int block_nb)
{
    uint32 w[64];
    uint32 wv[8];
    uint32 t1, t2;
    const unsigned char *sub_block;
    int i;
    int j;
    for (i = 0; i < (int) block_nb; i++) {
        sub_block = message + (i << 6);
        for (j = 0; j < 16; j++) {
            SHA2_PACK32(&sub_block[j << 2], &w[j]);
        }
        for (j = 16; j < 64; j++) {
            w[j] =  SHA256_F4(w[j -  2]) + w[j -  7] + SHA256_F3(w[j - 15]) + w[j - 16];
        }
        for (j = 0; j < 8; j++) {
            wv[j] = m_h[j];
        }
        for (j = 0; j < 64; j++) {
            t1 = wv[7] + SHA256_F2(wv[4]) + SHA2_CH(wv[4], wv[5], wv[6])
                + sha256_k[j] + w[j];
            t2 = SHA256_F1(wv[0]) + SHA2_MAJ(wv[0], wv[1], wv[2]);
            wv[7] = wv[6];
            wv[6] = wv[5];
            wv[5] = wv[4];
            wv[4] = wv[3] + t1;
            wv[3] = wv[2];
            wv[2] = wv[1];
            wv[1] = wv[0];
            wv[0] = t1 + t2;
        }
        for (j = 0; j < 8; j++) {
            m_h[j] += wv[j];
        }
    }
}

void SHA256::init()
{
    m_h[0] = 0x6a09e667;
    m_h[1] = 0xbb67ae85;
    m_h[2] = 0x3c6ef372;
    m_h[3] = 0xa54ff53a;
    m_h[4] = 0x510e527f;
    m_h[5] = 0x9b05688c;
    m_h[6] = 0x1f83d9ab;
    m_h[7] = 0x5be0cd19;
    m_len = 0;
    m_tot_len = 0;
}

void SHA256::update(const unsigned char *message, unsigned int len)
{
    unsigned int block_nb;
    unsigned int new_len, rem_len, tmp_len;
    const unsigned char *shifted_message;
    tmp_len = SHA224_256_BLOCK_SIZE - m_len;
    rem_len = len < tmp_len ? len : tmp_len;
    memcpy(&m_block[m_len], message, rem_len);
    if (m_len + len < SHA224_256_BLOCK_SIZE) {
        m_len += len;
        return;
    }
    new_len = len - rem_len;
    block_nb = new_len / SHA224_256_BLOCK_SIZE;
    shifted_message = message + rem_len;
    transform(m_block, 1);
    transform(shifted_message, block_nb);
    rem_len = new_len % SHA224_256_BLOCK_SIZE;
    memcpy(m_block, &shifted_message[block_nb << 6], rem_len);
    m_len = rem_len;
    m_tot_len += (block_nb + 1) << 6;
}

void SHA256::final(unsigned char *digest)
{
    unsigned int block_nb;
    unsigned int pm_len;
    unsigned int len_b;
    int i;
    block_nb = (1 + ((SHA224_256_BLOCK_SIZE - 9)
                     < (m_len % SHA224_256_BLOCK_SIZE)));
    len_b = (m_tot_len + m_len) << 3;
    pm_len = block_nb << 6;
    memset(m_block + m_len, 0, pm_len - m_len);
    m_block[m_len] = 0x80;
    SHA2_UNPACK32(len_b, m_block + pm_len - 4);
    transform(m_block, block_nb);
    for (i = 0 ; i < 8; i++) {
        SHA2_UNPACK32(m_h[i], &digest[i << 2]);
    }
}

std::string sha256(std::string input)
{
    unsigned char digest[SHA256::DIGEST_SIZE];
    memset(digest,0,SHA256::DIGEST_SIZE);

    SHA256 ctx = SHA256();
    ctx.init();
    ctx.update( (unsigned char*)input.c_str(), input.length());
    ctx.final(digest);

    char buf[2*SHA256::DIGEST_SIZE+1];
    buf[2*SHA256::DIGEST_SIZE] = 0;
    for (int i = 0; i < SHA256::DIGEST_SIZE; i++)
        sprintf(buf+i*2, "%02x", digest[i]);
    return std::string(buf);
}

main.cpp

#include<iostream>
#include<cstdint>
#include"Blockchain.h"
using namespace std;
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;
}

运行结果

源代码出处:https://blog.csdn.net/tostick/article/details/80247856

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要实现一个WebSocket客户端demo下载,首先需要了解WebSocket是一种在单个TCP连接上进行全双工通信的协议。 1. 首先,你可以在网上搜索WebSocket客户端的库或框架,比如Java中的Java-WebSocket、Python中的websocket-client等。选择一个合适的库。 2. 下载所选库的相关文件并解压。 3. 根据库的文档和示例进一步了解如何使用该库来实现WebSocket客户端。 4. 阅读文档或示例,了解WebSocket客户端的初始化和连接过程。 5. 根据文档或示例代码,编写一个简单的WebSocket客户端demo,其中包括连接至WebSocket服务器、发送消息和接收消息的基本功能。注意在编写代码时要结合所选库的API进行调用。 6. 编译或运行该demo,确保功能正常。 7. 如果有其他需要,可以根据文档或示例进一步完善WebSocket客户端的功能,比如处理WebSocket连接关闭、错误处理等。 8. 将最终的demo代码整理成一个可供下载的压缩文件。 总结:通过选择合适的WebSocket客户端库,阅读文档示例,编写代码并进行调试,最终实现WebSocket客户端demo并提供下载。同时可以根据需要进一步完善功能,比如处理连接关闭和错误。 ### 回答2: 要实现一个WebSocket客户端demo,首先要确保你的开发环境中有相应的工具和库。 1. 安装Node.js:前往Node.js官网(https://nodejs.org/),下载适用于你操作系统的安装包,然后按照指导安装。 2. 创建项目文件夹:在你的电脑上选择一个合适的位置创建一个新的文件夹来存放项目文件。 3. 初始化项目:在命令行中进入到你创建的项目文件夹中,然后执行以下命令初始化一个新的Node.js项目: `npm init -y` 4. 安装WebSocket库:在命令行中执行以下命令安装WebSocket库: `npm install websocket` 5. 创建并编写客户端代码:在项目文件夹中创建一个新的JavaScript文件,例如`client.js`,然后使用编辑器打开这个文件,并编写以下代码: ```javascript const WebSocket = require('websocket').client; const client = new WebSocket(); client.on('connectFailed', (error) => { console.log('连接失败:', error.toString()); }); client.on('connect', (connection) => { console.log('连接成功'); connection.on('error', (error) => { console.log('连接错误:', error.toString()); }); connection.on('close', () => { console.log('连接已关闭'); }); connection.on('message', (message) => { if (message.type === 'utf8') { console.log('收到消息:', message.utf8Data); } }); // 发送消息 connection.send('Hello, WebSocket Server!'); }); // 连接WebSocket服务器 client.connect('ws://localhost:8080/', 'echo-protocol'); ``` 6. 运行客户端程序:在命令行中执行以下命令运行客户端程序: `node client.js` 此时客户端会尝试连接到指定的WebSocket服务器,并发送一条消息。 请注意,以上代码仅为一个简单的示例,你可能需要根据你的实际需求进行修改和扩展。同时,要确保WebSocket服务器已经正确地运行和配置,并监听在`ws://localhost:8080/`地址上。 ### 回答3: 在实现WebSocket客户端Demo之前,我们需要首先了解WebSocket是一种基于TCP协议的全双工通信协议,能够在客户端和服务器之间建立持久连接,实现实时通信。 要实现WebSocket客户端Demo,可以按照以下步骤进行操作: 1. 下载WebSocket客户端库:首先,我们需要下载适用于目标编程语言的WebSocket客户端库。WebSocket客户端库提供了许多用于创建和管理WebSocket连接的API。 2. 导入WebSocket客户端库:将下载的WebSocket客户端库导入到项目中,并确保可以正确引用和调用WebSocket相关的类或函数。 3. 创建WebSocket连接:使用WebSocket客户端库的API,创建一个WebSocket连接对象。连接对象需要指定WebSocket服务器的URL,即服务器的WebSocket端点。 4. 连接到服务器:使用连接对象的方法将WebSocket客户端连接到服务器。这将触发WebSocket连接握手过程,如果成功,将建立一个持久的双向通信通道。 5. 处理WebSocket事件:一旦WebSocket连接建立成功,客户端可以侦听WebSocket事件,例如消息接收、连接关闭等。根据业务需求,编写对应的事件处理逻辑,以处理从服务器发送的数据。 6. 发送数据到服务器:使用连接对象的方法,可以将数据发送到服务器。数据可以是文本字符串、二进制数据或其他形式的数据,具体取决于WebSocket客户端库的API。 7. 关闭连接:在不再需要WebSocket连接时,可以使用连接对象的方法显式地关闭连接。这将从客户端和服务器之间断开持久连接。 需要注意的是,具体实现WebSocket客户端Demo的步骤可能会因所选编程语言和WebSocket客户端库的不同而有所差异。在实际操作中,可能需要参考WebSocket客户端库的文档和示例代码,以确保正确地使用API和处理事件。 一旦WebSocket客户端Demo实现成功,客户端将能够与WebSocket服务器建立双向通信,并实现实时数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值