C++でブロックチェーンアプリケーションを構築するという記事が最初にCoinpedia Fintech Newsに掲載されました。
導入
ブロックチェーン技術は、仲介者の必要性を排除する分散型、透明性、安全性を備えたメカニズムを提供することで、金融とサプライチェーン管理を根本的に変革しました。
なぜブロックチェーンアプリケーションを構築する必要があるのでしょうか?
ブロックチェーンアプリケーションは、強化されたデータの整合性とセキュリティを提供し、情報を共有するための信頼のない環境を提供します。ブロックチェーンを使用すると、スマートコントラクトを実装し、分散型金融(DeFi)やトークン化された資産などの新しい経済モデルへの扉を開くデジタルトークンを作成できます。
この記事は、C++ によるブロックチェーン開発の世界を 10 分で簡単に紹介するものです。
ブロックチェーンの基礎
ブロックチェーンは、ブロックと呼ばれる単一の安全で改ざん不可能なユニットで構成されるデジタル チェーンです。各ブロックには、メタデータとトランザクションの指定情報が含まれています。ここまでは、個々のブロックを作成しただけです。各ブロック間の接続を意味のある方法で確立するにはどうすればよいでしょうか。答えは、ハッシュと呼ばれる独自のランダム暗号化関数を使用して、各ブロックを前のブロックにリンクすることです。各ブロックには、プライマリ キーである独自のハッシュがあり、ハッシュを通じてすべてのブロックを時系列順にリンクして、ネットワーク内のトランザクションの履歴全体を表すチェーンを形成できます。
ブロックチェーンにおける C++
C++ は、そのスピード、柔軟性、制御性により、ブロックチェーンで使用される最も強力な言語の 1 つです。複雑なシステム、ゲーム開発、金融アプリケーションを処理する際に驚異的な効果を発揮します。間違いなく、最も汎用性の高い言語です。
C++ がブロックチェーンで優れている理由は複数あります。C++ は、精密な制御を提供する低レベルのメモリ管理により、開発者が効率的なブロックチェーン システムを構築できるようにします。ビットコイン ネットワークがいかに巨大で安全であるかは、誰もが知っています。無数のトランザクションを処理する必要があるため、そのコアがいかに複雑であるかを想像してみてください。したがって、この困難なタスクを管理するために、C++ が選択されました。ビットコイン、ライフコイン、リップル、モネロ、EOS など、C++ を使用して開発された重要なアプリケーションがいくつかあります。
なぜ 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 (clang は MacOS にも既にインストールされています)Fedora: sudo dnf install clangWindows: Clang は MinGW または LLVM プロジェクト インストーラーを使用してインストールできます
MSVC (Microsoft Visual C++):
MSVC (Microsoft Visual C++) は、Microsoft が開発した強力な統合開発環境 (IDE) である Visual Studio の不可欠なコンポーネントです。Visual Studio は、アプリケーションの開発、テスト、および展開のための包括的なツール スイートを提供しており、これをインストールすると、システムに MSVC が自動的に設定されます。
ターミナルまたはコマンド プロンプトで次のコマンドを使用してインストールを確認します。
g++ –version # GCCclangの場合 –version # Clangclの場合 # MSVCの場合
IDEの選択
統合開発環境 (IDE) は、コード補完、デバッグ、プロジェクト管理などのツールを統一されたインターフェイス内で提供することで生産性を向上させます。以下は、C++ 開発で広く使用されている IDE の一部です。
Visual Studio: 公式 Web サイトから Visual Studio をダウンロードします。
以下の表に記載されている手順に従ってください。
CLion: インストールとセットアップ:
CLion は JetBrains を搭載した人気の IDE ですが、サブスクリプションが必要ですが、無料トライアルも提供されています。
無料トライアルを提供します。
Visual Studio Code: C++ 開発用の拡張機能をインストールして設定します。
必要なライブラリのインストール
パッケージ マネージャーを使用して、暗号化機能用の OpenSSL などの重要なライブラリをインストールします。以下は、さまざまなオペレーティング システムとそのコマンドの手順とさまざまなライブラリです。
やった、開発環境が正常にセットアップされたので、選択した IDE でコードを直接実行できます。
2.C++でシンプルなブロックチェーンを構築する
コードを書く旅を始める前に、ブロック クラスのコンポーネントを理解しましょう。
ブロッククラスのコンポーネント
インデックスは、ブロックのソート順序を時系列で保存および維持する整数です。
タイムスタンプ: タイムスタンプには、ブロックが作成されたインスタンスが文字列の形式で保存されます。
トランザクション: トランザクションには、参加者間の交換情報とその時点でのブロックチェーンの状態が保存されます。
前のハッシュとハッシュ: 前のハッシュには前のブロックの暗号ハッシュが格納されますが、ハッシュは暗号化情報の文字列を混ぜ合わせたもの、つまりハッシュ化したものです。
ノンス: プルーフ オブ ワーク (PoW) コンセンサス アルゴリズムで使用される整数。難易度ターゲットを満たす有効なハッシュを見つけるために増加するカウンターとして機能します。ノンスは PoW のマイニング プロセスにとって非常に重要です。マイナーは、先頭のゼロの数が特定の数であるハッシュを生成するノンスを見つけるために競い合います。
では、すべての機能をコードで実装してみましょう。
class Block {public: int index; std::string timestamp; std::vector<Transaction>transactions; std::string previousHash; std::string hash; int nonce; // For PoW // Constructor Block(int idx, std::string time, std::vector<Transaction> txs, std::string prevHash) { index = idx; timestamp = time; transactions = txs; previousHash = prevHash; nonce = 0; hash = calculateHash(); // 現在のブロックのハッシュ } // ブロックのハッシュを計算するメソッド std::string calculateHash() { std::stringstream ss; ss << index << timestamp << previousHash << nonce; // トランザクション データとその他の詳細をハッシュ計算に追加します return sha256(ss.str()); // 実際のハッシュ関数のプレースホルダー } // ブロックをマイニングするメソッド void mineBlock(int challenges) { std::string target(difficulty, ‘0’); // ターゲット ハッシュの文字列を作成します while (hash.substr(0, challenges) != target) { nonce++; hash = calculateHash(); } }};
ブロッククラスとその属性の定義が完了したら、ジェネシス ブロックを作成できます。ジェネシス ブロックは、ブロックチェーン内で初期化する必要があり、インデックスが 0 である最初のブロックです。ジェネシス ブロックを定義したら、addblock() メソッドを使用してブロックチェーンに新しいブロックを追加できます。以下にコードを示します。
クラス Blockchain {public: std::vector<Block> chain; Blockchain() { chain.push_back(createGenesisBlock()); } Block createGenesisBlock() { return Block(0, “01/01/2024”, “Genesis Block”, “0”); } Block getLatestBlock() { return chain.back(); } void addBlock(Block newBlock) { newBlock.previousHash = getLatestBlock().hash; newBlock.hash = newBlock.calculateHash(); chain.push_back(newBlock); }};
トランザクションを作成して検証します。各トランザクションには独自の ID、定義済みのコンストラクター、送信者と受信者の情報、および金額があります。トランザクションを作成したら、メソッドvalidateTransaction() を使用して検証する必要があります。
class Transaction {public: std::string sender; std::string received; double amount; std::string transactionID; // コンストラクタ Transaction(std::string snd, std::string rcp, double amt, std::string txID) { sender = snd; recipient = rcp; amount = amt; transactionID = txID; } // トランザクションを検証するメソッド bool validTransaction() { // 検証ロジックの実装 return true; // プレースホルダ }};
3.C++ でのコンセンサスメカニズムの実装
これまでに、構築プロセスの 25% が完了しました。次に、アプリケーション全体のバックボーンとなるブロックのコンセンサス メカニズムを実装します。
プルーフ・オブ・ワーク
プルーフ・オブ・ワーク(PoW)は、ブロックチェーンネットワークのメンバー/マイナーが、チェーンに新しいブロックを追加する前に、難しい計算数学的問題の解決策を見つける必要があるコンセンサスメカニズムです。これは基本的に、ブロックのデータ、ハッシュ、およびその他の詳細と組み合わせて、特定の数の先頭のゼロで始まるハッシュ値を生成する、ナンスと呼ばれる特定の番号を見つけるプロセスです。これにより、プロセスが効率化され、ネットワークが悪意のある攻撃から保護されます。
C++ では、Block クラスに proof 属性と proof of work メソッドを追加することで、Proof of Work を実装できます。手順は次のとおりです。
#include <iostream>#include <sstream>#include <ctime>#include <string>#include <vector>#include <openssl/sha.h>using namespace std;string sha256(const string str) { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, str.c_str(), str.length()); SHA256_Final(hash, &sha256); stringstream 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; string data; string previousHash; string hash; long proof; time_t timestamp; Block(int idx, string d, string prevHash) { index = idx; data = d; previousHash = prevHash; timestamp = time(nullptr); proof = 0; hash = calculateHash(); } string calculateHash() const { stringstream ss; ss << index << timestamp << data << previousHash << proof; return sha256(ss.str()); } void proofOfWork(int challenges) { string target(difficulty, ‘0’); do { proof++; hash = calculateHash(); } while (hash.substr(0, challenges) != target); }};class Blockchain {public: vector<Block> chain; int challenges; Blockchain(int diff) { difficulty = diff; chain.emplace_back(Block(0, “Genesis Block”, “0”)); } void addBlock(string data) { Block newBlock(chain.size(), data, chain.back().hash); newBlock.proofOfWork(difficulty); 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 を使用すると、定義済みのブロックチェーン データとのやり取りが容易になるため、開発者はネットワークの基盤となる構造全体を知らなくても、アプリケーションをすばやく構築できます。API は、ブロックチェーンを Web アプリケーションやモバイル アプリケーションなどの他のプラットフォームと統合するのに役立ちます。したがって、効率的な開発と統合を可能にするには API が必要です。
API環境の設定
次の表に示すように、C++ を使用して API を作成するために必要なツールをインストールして構成します。
APIの構築
#include <cpprest/http_listener.h>#include <cpprest/json.h>#include “blockchain.h”using namespace web;using namespace http;using namespace utility;using namespace http::experimental::listener;Blockchain blockchain(4); // 難易度レベル 4void handleGet(http_request request) { json::value response = json::value::array(); int i = 0; for (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::OK, response);}void handlePost(http_request request) { request.extract_json().then([&](json::value requestData) { auto data = requestData[U(“data”)].as_string();blockchain.addBlock(data);request.reply(status_codes::OK, U(“Block added successfully”));}).wait();}int main() {http_listener listener(U(“http://localhost:8080”));listener.support(methods::GET, handleGet);listener.support(methods::POST, handlePost);try {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 によるテスト
Postman または curl を使用して API エンドポイントをテストします。
ブロックを追加する:
メソッド: POST
URL: http://localhost:8080
本文: JSON 形式
{ “data”: “これは新しいブロックです”}
ブロックチェーンを表示:
メソッド: GET
URL: http://localhost:8080
C++ で作成された API を使用してブロックを追加し、ブロックチェーンを表示する例。
void handleGet(http_request request) { json::value response = json::value::array(); int i = 0; for (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::OK, response); }void handlePost(http_request request) { request.extract_json().then([&](json::value requestData) { auto data = requestData[U(“data”)].as_string();blockchain.addBlock(data);request.reply(status_codes::OK, U(“Block added successfully”)) }).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; string data; string previousHash; string hash; long proof; time_t timestamp; Block(int idx, const string& data, const string& prevHash) : index(idx), data(data), previousHash(prevHash), proof(0), timestamp(time(nullptr)) { hash = calculateHash(); } string calculateHash() const { stringstream ss; ss << index << timestamp << data << previousHash << proof; return sha256(ss.str()); } void proofOfWork(int challenges) { string target(difficulty, ‘0’); do { proof++; hash = calculateHash(); } while (hash.substr(0, challenges) != target); }private: string sha256(const string& input) const { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, input.c_str(), input.size()); SHA256_Final(hash, &sha256); stringstream ss; for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { ss << hex << setw(2) << setfill(‘0’) << (int)hash[i]; } ss.str() を返します。 }};
ステップ 2: calculateHash メソッドを実装します。
#include <iostream>#include <sstream>#include <iomanip>#include <openssl/sha.h>class Block {public: int index; std::string data; std::string previousHash; std::string hash; long proof; time_t timestamp; Block(int idx, const std::string& data, const std::string& prevHash) : index(idx), data(data), previousHash(prevHash), proof(0), timestamp(time(nullptr)) { hash = calculateHash(); } std::string calculateHash() const { std::stringstream ss; ss << index << timestamp << data << previousHash << proof; return sha256(ss.str()); }private: std::string sha256(const std::string& input) const { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, input.c_str(), input.size()); SHA256_Final(hash, &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: Blockchain クラスを定義し、ジェネシス ブロックで初期化します。
クラス Blockchain {public: Blockchain(int challenges) : challenges(difficulty) { chain.emplace_back(Block(0, “Genesis Block”, “0”)); } void addBlock(const string& data) { Block newBlock(chain.size(), data, chain.back().hash); newBlock.proofOfWork(difficulty); chain.push_back(newBlock); } const Block& latestBlock() const { return chain.back(); } vector<Block> chain;private: int challenges;};
ステップ 4: calculateHash メソッドを実装します。
#include <iostream>#include <sstream>#include <iomanip>#include <openssl/sha.h>class Block {public: int index; std::string data; std::string previousHash; std::string hash; long proof; time_t timestamp; Block(int idx, const std::string& data, const std::string& prevHash) : index(idx), data(data), previousHash(prevHash), proof(0), timestamp(time(nullptr)) { hash = calculateHash(); } std::string calculateHash() const { std::stringstream ss; ss << index << timestamp << data << previousHash << proof; return sha256(ss.str()); }private: std::string sha256(const std::string& input) const { unsigned char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX sha256; SHA256_Init(&sha256); SHA256_Update(&sha256, input.c_str(), input.size()); SHA256_Final(hash, &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: Blockchain クラスを定義し、ジェネシス ブロックで初期化します。
クラス Blockchain {public: Blockchain(int challenges) : challenges(difficulty) { chain.emplace_back(Block(0, “Genesis Block”, “0”)); } void addBlock(const string& data) { Block newBlock(chain.size(), data, chain.back().hash); newBlock.proofOfWork(difficulty); chain.push_back(newBlock); } const Block& latestBlock() const { return chain.back(); } vector<Block> chain;private: int challenges;};
ステップ 6: 適切な C++ ライブラリを使用してリクエストを処理するための API 環境を設定します。
#include <cpprest/http_listener.h>#include <cpprest/json.h>using namespace web;using namespace web::http;using namespace web::http::experimental::listener;class BlockchainAPI {public: BlockchainAPI(const string& address, Blockchain& blockchain) : listener(http_listener(U(address))), blockchain(blockchain) { 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 << “Blockchain 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::OK, response); }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(“Block added successfully”));}) . wait () ; }} ;
ステップ 7: 新しいブロックをマイニングし、Postman または curl を使用してブロックチェーンを検証して、アプリケーションをテストします。
メイン:int main() { Blockchain blockchain(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++ プログラミングの基礎からアプリケーションの展開とテストまですべてをカバーしました。
このモジュールを完了すると、スケーラビリティ、セキュリティプラクティス、高度なコンセンサスメカニズム、スマートコントラクトなどの最適化の概念をさらに詳しく調べることができます。
好奇心を持ち続け、継続的な学習を受け入れ、コーディングを続けてください。あなたの貢献がテクノロジーの未来を推進しますように。