使用 C++ 建立区块链应用程式的贴文首先出现在 Coinpedia 金融科技新闻上

介绍

区块链技术透过提供去中心化、透明和安全的机制来消除对中介机构的需求,从根本上改变了金融和供应链管理。

为什么要建立区块链应用程式?

区块链应用程式提供增强的资料完整性和安全性,并为共享资讯提供无需信任的环境。透过区块链,人们可以实现智慧合约,并创建数位代币,从而打开去中心化金融(DeFi)和代币化资产等新经济模式的大门 

本文用 10 分钟快速介绍了透过 C++ 进行区块链开发的世界。 

区块链基础知识

区块链是由单一安全且防篡改的单元(称为「区块」)组成的数位链。每个区块包含其元资料和交易的指定资讯。到目前为止,我们刚刚创建了单独的区块,对吗?您将如何尝试以有意义的方式在每个区块之间建立连接?答案是借助称为哈希的独特随机加密函数将每个区块连结到其前一个区块。每个区块都有自己的杂凑值,即主键,您可以透过杂凑值按时间顺序将所有区块连结起来,形成一条链,代表网路内交易的整个历史记录。

区块链中的 C++

由于其速度、灵活性和控制力,C++ 是区块链中使用的最强大的语言之一。它在处理复杂系统、游戏开发和金融应用程式时能产生奇迹。毫无疑问,它是最通用的语言!

C++ 在区块链中大放异彩有多种原因。由于其低阶记忆体管理提供精确控制,它允许开发人员建立高效的区块链系统。想像一下它的核心有多复杂,因为它需要处理无数的交易。因此,为了完成这项艰巨的任务,我们选择了 C++。有一些使用 C++ 开发的重要应用程序,例如比特币、Lifecoin、Ripple、Monero 和 EOS。

为什么C++是区块链开发的理想语言?

  • 计算速度更快

  • 高效能

  • 高效率的记忆体管理

  • 面向对象的特点

  • 支援多执行绪

  • 控制系统资源 

无论您是区块链新手还是想要突破可能的极限,C++ 都是建立持久应用程式的可靠选择。

使用 C++ 理解区块链概念

交易:在区块链中,交易是本质,驱动整个系统。各个区块就像安全金库,保存著与参与者一起的著名的交换资讯和交易价值。这些交易是讲述谁、与谁、何时交换什么内容的基本纪录。

您应该了解的区块链支柱

去中心化:去中心化是区块链在整个技术领域中脱颖而出的原因。什么是去中心化?它是区块链的属性,没有任何一个实体可以控制整个资料库。这使得系统对故障具有稳健性并抑制任何类型的偏差。  每个参与者设备(节点)都维护区块链的副本,确保透明度并防止集中故障或操纵。

不变性:一旦将任何资料写入区块链,您就无法在不更改后续区块的情况下更改它。这是在加密哈希的帮助下完成的。因此,一旦完成的所有更改都无法撤消,使其成为不可变的。

共识机制:一组管理区块链所有必需品的协议。网路中的所有节点需要就这些方法达成一致。共识机制用于简化节点并确保网路中的所有节点都在同一页上。

到现在为止,你一定已经了解了区块链的所有基础知识吧?理论已经够多了!现在让我们深入实践部分。准备好动手了吗?

在本节中,我们将引导您完成一个简单的区块链应用程式开发的整个过程。从设定环境到测试和部署。

1.搭建C++开发环境

在开始开发之前,具备所有先决条件至关重要。在本章中,我们将了解如何拥有合适的开发环境。

安装C++编译器

让我们先了解什么是编译器。

 编译器是软体开发中的重要工具,可作为您编写的人类可读程式码与电脑处理器可以理解和执行的机器码之间的桥梁。在使用 C++ 开发区块链应用程式时,第一步是为自己配备可靠的 C++ 编译器。该工具会将您的 C++ 程式码转换为可执行的机器码,使您的区块链应用程式能够在各种系统上高效运行。

因此,要开始开发,请先安装与您的系统相容的 C++ 编译器。以下是您可以选择的流行 C++ 编译器:

GCC(GNU编译器集合):

Linux/MacOS:

打开终端机并分别输入下面给出的命令

a)Ubuntu/Debian:sudo apt updatesudo apt install build-essentialb)Fedora sudo dnf install gcc gcc-c++c)MacOS(命令列工具)xcode-select –install

 Windows:对于 Windows 使用者来说,MinGW-w64 专案是一个很好的选择,因为它提供了 GCC(GNU 编译器集合)的 Windows 端口,在 Windows 环境中提供了 GCC 的强大功能。

安装步骤:

  • 请造访 MinGW-w64 官方网站下载安装程式。

  • 下载后运行安装程序

  • 根据您的需求选择合适的架构

  • 依照向导步骤完成

  • 更新系统(这是可选步骤,但建议)。

  铛:

Linux/MacOS:sudo apt install clang(MacOS 中也已安装 clang)Fedora:sudo dnf install clangWindows:可以使用 MinGW 或透过 LLVM 专案安装程式安装 Clang

MSVC(微软视觉C++): 

MSVC (Microsoft Visual C++) 是 Visual Studio 的一个组成部分,Visual Studio 是 Microsoft 开发的强大的整合开发环境 (IDE)。 Visual Studio 提供了一整套用于开发、测试和部署应用程式的工具,安装它后会自动在您的系统上设定 MSVC。

在终端机或命令提示字元中使用以下命令验证安装:

g++ –version # 对于 GCCclang –version # 对于 Clangcl # 对于 MSVC

选择 IDE

整合开发环境 (IDE) 透过在统一介面中提供程式码完成、侦错和专案管理等工具来提高生产力。以下是一些广泛使用的 C++ 开发 IDE:

Visual Studio:从官方网站下载Visual Studio。

并依照下表所述执行以下步骤:

CLion:安装与设定:

CLion 是一种流行的 IDE,由 JetBrains 提供支持,但需要订阅,但提供免费试用。

提供免费试用。

Visual Studio Code:安装并设定 C++ 开发的扩充功能。

安装所需的库

使用套件管理器安装必要的库,例如用于加密功能的 OpenSSL。以下是不同作业系统及其命令的步骤和各种函式库。

是的,您已经成功设定了开发环境,您可以直接开始在您选择的 IDE 中执行程式码。

2.用C++建构一个简单的区块链

在开始编写程式码之前,让我们先了解块类别的元件。

Blockclass 的组成部分

  • 索引是一个整数,它按时间顺序储存和维护区块的排序顺序。

  • 时间戳:时间戳以字串形式储存区块建立的实例。 

  • 交易:交易储存参与者之间的交换资讯以及当时区块链的状态。

  • 前哈希和哈希:前哈希存储前一个区块的密码哈希,而哈希是一串混乱或哈希的密码资讯。

  • Nonce:工作量证明 (PoW) 共识演算法中使用的整数。随机数对于 PoW 中的挖矿过程至关重要,矿工们竞相寻找一个随机数来产生具有特定数量的前导零的哈希值。

现在让我们用程式码实现所有功能:

类别区块 {public:    int index;    std::字串时间戳记;    std::vector<Transaction> 交易;    std::string previousHash;    std::字串哈希;    整数随机数; // 对于 PoW    // 建构子    Block(int idx, std::string time, std::vector<Transaction> txs, std::string prevHash) {              时间戳=时间;        交易 = 交易;        前一个哈希 = 前一个哈希;        随机数=0;        哈希 = 计算哈希(); // 目前区块的哈希值    }    // 计算区块哈希值的方法    std::stringcalculateHash() {        std::stringstreamss;        ss <<索引<<时间戳<< previousHash <<随机数;        // 将交易资料和任何其他详细资料加入哈希计算        return sha256(ss.str()); // 实际杂凑函数的占位符    }    // 挖掘区块的方法    void mineBlock(intdifficulty) {        std::string target(difficulty, ‘0’); // 建立目标杂凑字串         while (hash.substr(0,difficulty) != target) {            nonce++++;            哈希 = 计算哈希();         }     }};

完成定义区块类别及其属性后,您可以进一步建立创世区块。创世区块是区块链中第一个需要初始化的区块,其索引为零。定义创世区块后,您可以进一步使用 addblock() 方法将新区块新增到您的区块链中。 

区块链类别 {public:    std::vector<Block> 链;    Blockchain() {        chain.push_back(createGenesisBlock());    }    Block createGenesisBlock() {        return Block(0, “01/01/2024”, “创世区块》, “0”);    }    区块 getLatestBlock() {        return chain.back();    }    void addBlock(Block newBlock) {        newBlock.previousHash = getLatestBlock().hash;        newBlock.hash = newBlock.calculateHash();        chain.push_back(newBlock);     }};

建立并验证交易。每笔交易都有自己的 ID、预先定义的建构子、传送者和接收者资讯以及金额。建立交易后,您需要使用 validateTransaction() 方法对其进行验证。

类别交易 {public:    std::string sender;    std::字串接收者;    双倍金额;    std::string 交易ID;    // 建构子    交易(std::string snd, std::string rcp, double amt, std::string txID) {        sender = snd;        收件人= rcp;        金额 = 金额;        交易ID = 交易ID;    }    // 验证交易的方法    bool validateTransaction() {        // 逻辑的实作        return true; // 占位符     }};

3.在C++中实现共识机制

 到目前为止,您已经完成了 25% 的建造过程。现在,您继续前进并为您的区块实施共识机制,这是整个应用程式的支柱。

工作量证明

工作量证明 (PoW) 是一种共识机制,区块链网路成员/矿工必须找到解决困难的计算数学问题的方法,然后才能将新区块添加到链中。 ,称为随机数,它与区块的资料、杂凑值和其他详细资料相结合,产生以一定数量的前导零开头的杂凑值。这使得该过程变得高效并保护网路免受恶意攻击。

在 C++ 中,您可以透过在 Block 类别中新增证明属性和工作证明方法来实现工作量证明。操作方法如下:

#include <iostream>#include <sstream>#include <ctime>#include <string>#include <vector>#include <openssl/sha.h>using namespace std;string sha256(const string str) {   SHA256_DIGEST_LENGTH];    SHA256_CTX sha256;    SHA256_Init(&sha256);    SHA256_Update(&sha256, str.c_str(), str.length());    SHA256_Final(杂凑值, &sha256);    字串流 ss;    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {        ss << hex << setw(2) << setfill(‘0’) << (int)hash[i];    }    return ss.str();}class Block {public:    int index;    字串资料;    字串前一个哈希值;    字串哈希;    长证明;    time_t 时间戳记;    块(int idx,字串d,字串prevHash){        index = idx;        数据=d;        前一个哈希 = 前一个哈希;        时间戳=时间(nullptr);        证明=0;        哈希 = 计算哈希();    }    字串calculateHash() const {        stringstream ss;        ss <<索引<<时间戳<<资料<< previousHash <<证明;        返回 sha256(ss.str());    }    voidproofOfWork(intdifficulty){        string target(difficulty, ‘0’);        做{            证明++;            哈希 = 计算哈希();        while (hash.substr(0, 难度) != 目标);     }};class Blockchain {public:    vector<Block> chain;    难度;    区块链(int diff) {        难度 = diff;        chain.emplace_back(Block(0, “创世区块”, “0”));   }    void addBlock(string data) {        Block newBlock(chain.size(), data, chain.back().hash);        newBlock.proofOfWork(难度);        if (isValidProof(newBlock)) {            chain.push_back(newBlock);         }    }    bool isValidProof(const Block& block) const {        return block.hash.substr(0, 难度) == string(难度, ‘0’);     }};

在上面的程式码片段中,我们可以看到,首先,我们需要向区块添加证明和哈希。然后,确定证明的难度并进行挖掘。之后,您可以验证证明。

4.使用 C++ 创建简单的区块链 API

 API-应用程式介面是一种允许不同软体应用程式相互交互的工具。而无需了解网路的整个底层结构。 API 有助于将区块链与其他平台(例如 Web 或行动应用程式)整合。因此,API 对于实现高效的开发和整合是必要的。

设定API环境

安装并配置使用 C++ 建立 API 所需的工具,如下表所示:

建构 API

#include <cpprest/http_listener.h>#include <cpprest/json.h>#include “blockchain.h”using 命名空间web;using 命名空间http;using 命名空间实用程式;using 命名空间http::experimental:: listener;区块链区块链( 4); // 难度等级 4void handleGet(http_request request) {    json::value response = json::value::array();    整数 i = 0;    for (auto& block : Blockchain.chain) {        json::value block_json;        block_json[U(“index”)] = json::value::number(block.index);        block_json[U(“资料”)] = json::value::string(block.data);        block_json[U(“previousHash”)] = json::value::string(block.previousHash);        block_json[U(“哈希”)] = json::value::string(block.hash);        block_json[U(“proof”)] = json::value::number(block.proof);        block_json[U(“时间戳记”)] = json::value::number(block.timestamp);        回应[i++] = block_json;    }    request.reply(status_codes::OK,response);}void handlePost(http_request request) {    request.extract_json().then([&](jsonvalue requestData) { )].as_string();blockchain.addBlock(data);request.reply(status_codes::OK, U(“区块新增成功”));}).wait();}int main() {http_listener 监听器(U (“http://localhost:8080”));listener.support(methods::GET,handleGet);listener.support(methods::POST,handlePost);尝试{listener.open().wait() ;cout << “监听 http://localhost:8080” << endl;while (true);} catch (exception const& e) {cerr << e.what() << endl;   }返回0;}

handleGet 以 JSON 格式检索整个区块链。

handlePost 使用 POST 请求中的资料向区块链添加一个新区块。

运行和测试应用程式

运行应用程式

在根据软体开发周期完成程式码的核心功能后,您需要跳到编译和测试整个应用程式的最关键和不可避免的步骤。这对于确认应用程式中的元件是否如预期运作最为重要。

编译程式码:g++ -o Blockchain_api Blockchain_api.cpp -lboost_system -lcrypto -lssl -lcpprest执行执行档:./blockchain_api

上面的程式码在 http://localhost:8080 上启动 API 伺服器。

使用邮差测试

  • 使用 Postman 或curl 测试 API 端点:

  • 新增一个区块:

  • 方法:邮寄

  • 网址:http://localhost:8080

  • 正文:JSON 格式

{  「数据」:「这是一个新区块」}

查看区块链:

  • 方法:获取

  • 网址:http://localhost:8080

使用 C++ 创建的 API 新增区块并查看区块链的范例。

void handleGet(http_request request) {    json::value 回应 = json::value::array();    整数 i = 0;    for (auto& block : Blockchain.chain) {        json::value block_json;        block_json[U(“index”)] = json::value::number(block.index);        block_json[U(“资料”)] = json::value::string(block.data);        block_json[U(“previousHash”)] = json::value::string(block.previousHash);        block_json[U(“哈希”)] = json::value::string(block.hash);        block_json[U(“proof”)] = json::value::number(block.proof);        block_json[U(“时间戳记”)] = json::value::number(block.timestamp);        回应[i++] = block_json;    }    request.reply(status_codes::好的,回应); }void handlePost(http_request request) {    request.extract_json().then([&](json::value requestData) {        auto data = requestData[U(“data”)].as_string(plock); ;request.reply(status_codes::OK, U(“阻止新增成功”)) }).wait();}

handlePost 函数透过从 JSON 主体中提取资料并将新区块新增至区块链来处理区块新增。

handleGet 函数检索整个区块链并将其作为 JSON 回应发送回。

6.使用 C++ 建立区块链应用程式的实例

 逐步执行

步骤 1:使用 C++ 语法建立具有必要属性的 Block 类别。

#include <iostream>#include <ctime>#include <string>#include <sstream>#include <vector>#include <openssl/sha.h>using namespace std;class Block {public:    int index;    字串资料;    字串前一个哈希值;    字串哈希;    长证明;    time_t 时间戳记;    区块(int idx,const string&data,const string&prevHash)        :索引(idx),资料(资料),prevHash(prevHash),证明(0),时间戳(时间(nullptr)){     }    字串calculateHash() const {        stringstream ss;        ss <<索引<<时间戳<<资料<< previousHash <<证明;        返回 sha256(ss.str());    }    voidproofOfWork(intdifficulty){        string target(difficulty, ‘0’);        做{            证明++;            哈希 = 计算哈希();        while (hash.substr(0, 难度) != 目标);    }private:    string sha256(const string& input) const {        无符号字元哈希[SHA256_DIGEST_LENGTH];        SHA256_CTX sha256;        SHA256_Init(&sha256);        SHA256_Update(&sha256, input.c_str(), input.size());        SHA256_Final(杂凑值, &sha256); 字串流 ss;        for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {            ss << hex << setw(2) << setfill(‘0’) << (int)hex << setw(2) << setfill(‘0’) << (int)hash[i];        }        return ss.str();     }};

步骤2:实作calculateHash方法。

#include <iostream>#include <sstream>#include <iomanip>#include <openssl/sha.h>class Block {public:    int index;    std::字串资料;    std::string previousHash;    std::字串哈希;    长证明;    time_t 时间戳记;    区块(int idx, const std::string& data, const std::string& prevHash)        : 索引(idx), 资料(资料), previousHash(prevHash), 证明(0), 时间戳(time(nullp) =计算哈希值();    } std::stringcalculateHash() const {        std::stringstream ss;        ss <<索引<<时间戳<<资料<< previousHash <<证明;        返回 sha256(ss.str());    }private:    std::string sha256(const std::string& input) const {        无符号字元哈希[SHA256_DIGEST_LENGTH];        SHA256_CTX sha256;        SHA256_Init(&sha256);        SHA256_Update(&sha256, input.c_str(), input.size());        SHA256_Final(杂凑值, &sha256);        std::stringstream ss;        for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {            ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i] ;        }        return ss.str();     }};

步骤 3:定义区块链类别并使用创世区块进行初始化。

class Blockchain {public:    区块链(int 难度)        : 难度(难度) {            }    void addBlock(const string& data) {        Block newBlock(chain.size(), data, chain.back().hash);        newBlock.proofOfWork(难度);        chain.push_back(newBlock);    }    const Block&latestBlock() const {        return chain.back();    }    vector<Block> chain;private:    int 难度;};

步骤4:实作calculateHash方法。

#include <iostream>#include <sstream>#include <iomanip>#include <openssl/sha.h>class Block {public:    int index;    std::字串资料;    std::string previousHash;    std::字串哈希;    长证明;    time_t 时间戳记;    区块(int idx, const std::string& data, const std::string& prevHash)        : 索引(idx), 资料(资料), previousHash(prevHash), 证明(0), 时间戳(time(nullp) =计算哈希值();    }    std::stringcalculateHash() const {        std::stringstream ss;        ss <<索引<<时间戳<<资料<< previousHash <<证明;        返回 sha256(ss.str());    }private:    std::string sha256(const std::string& input) const {        无符号字元哈希[SHA256_DIGEST_LENGTH];        SHA256_CTX sha256;        SHA256_Init(&sha256);        SHA256_Update(&sha256, input.c_str(), input.size());        SHA256_Final(杂凑值, &sha256);        std::stringstream ss;        for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {            ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i] ;        }        return ss.str();     }};

步骤 5:定义区块链类别并使用创世区块对其进行初始化。

class Blockchain {public:    区块链(int 难度)        : 难度(难度) {            }    void addBlock(const string& data) {        Block newBlock(chain.size(), data, chain.back().hash);        newBlock.proofOfWork(难度);        chain.push_back(newBlock);    }    const Block&latestBlock() const {        return chain.back();    }    vector<Block> chain;private:    int 难度;};

步骤 6:使用适当的 C++ 函式库设定 API 环境来处理请求。

#include <cpprest/http_listener.h>#include <cpprest/json.h>using 命名空间web;using 命名空间web::http;using 命名空间web::http::experimental::listener;class BlockchainAPI {public: BlockchainAPI(const字串&地址,区块链&区块链)     :监听器(http_listener(U(位址))),区块链(区块链) {        listener.support(methods::GET, std:: bind(&BlockchainAPI::handleGet, this, std::placeholders:: _1));listener.support(methods::POST, std::bind(&BlockchainAPI::handlePost, this, std::placeholders::_1)); void start() {listener.open().wait();        cout <<“区块链API正在运行…”<< endl;     }私有:http_listener监听器;    Blockchain& Blockchain;void handleGet(http_request request) {json::value response = json::value::array();int i = 0;for (const auto& block : Blockchain.chain) {json::value block_json;block_json[ U(“index”)] = json::value::number(block.index);block_json[U(“data”)] = json::value::string(block.data);block_json[U(“previousHash ” ”)] = json::value::string(block.previousHash);block_json[U(“hash”)] = json::value::string(block.hash);block_json[U(“proof”)] = json::value::number(block.proof);block_json[U(“timestamp”)] = json::value::number(block.timestamp);response[i++] = block_json; }        request.reply(status_codes::好的,回应);    }void handlePost(http_request request) {request.extract_json().then([&](json::value requestData) {string data = requestData[U(“data”)].as_string();blockchain.addBlock(data) ;request.reply(status_codes::OK, U(“阻止新增成功”));}) .等待 () ; }};

步骤 7:透过挖掘新区块并使用 Postman 或curl 验证区块链来测试应用程式。

Main:int main() {    区块链区块链(4);  // 难度等级    BlockchainAPI api(“http://localhost:8080”, Blockchain);    api.start();    return 0;}测试:curl -X POST http://localhost:8080 -H “Content-Type: application/json” -d ‘{“data”:”这是一个新区块”}’

使用 C++ 进行区块链开发不仅仅是编码;它是关于建立去中心化系统的基本要素,这些系统有可能彻底改变各个产业。

总而言之,我们涵盖了从区块链 C++ 程式设计基础知识到应用程式的部署和测试的所有内容。

完成本模组后,您可以进一步探索优化的概念,例如可扩展性、安全实践、高级共识机制和智能合约。 

保持好奇心,拥抱持续学习,持续编码。