ブロックチェーンを実装するための 200 行のコード ブロックチェーンの例の詳細な説明
この記事は、ブロックチェーンの知識を実装するための 200 行のコードを主に紹介しています。非常に優れており、必要な友人は参照できます。
ブロックチェーンの概念を理解するのは非常に簡単です (ブロックチェーン、トランザクション チェーン ブロック)。分散型 (つまり、同じマシン上ではなく、異なるネットワーク デバイス上に配置されている) データベースは、増大するレコードのリストのホスティングをサポートします。しかし、ブロックチェーンと私たちが解決しようとしている目標を混同するのも簡単です。現時点では人々の心の中で、この言葉は取引、契約、またはスマート暗号通貨の概念と非常に強く結びついています。
ここでのみ、ブロックチェーンはビットコインと同じものではなく、ブロックチェーンの基本を理解することは、特にブロックチェーンがソースコードに基づいている場合には、思っているよりも簡単です。この記事では、JavaScript の 200 行のコードで構築された単純なモデルを提案します。 NaiveChain と呼ばれるこのプロジェクトのソース コードは、GitHub にあります。パート 1 と 2: その機能をフラッシュする必要がある場合は、チートシートを使用してください。標準の ECMAScript 6 を使用します。
ブロック構造
ステップ 1 - ブロックを含める必要がある要素を特定します。わかりやすくするために、前のブロックのインデックス(インデックス)、タイムスタンプ(タイムスタンプ)、データ(データ)、ハッシュ、およびブロックの構造的整合性を維持するために記録されるハッシュなど、最も必要なものだけを含めます。回路。
class Block { constructor(index, previousHash, timestamp, data, hash) { this.index = index; this.previousHash = previousHash.toString(); this.timestamp = timestamp; this.data = data; this.hash = hash.toString(); } }
ハッシュユニット
ハッシュブロックは、データの整合性を維持するために必要です。この例では、これはアルゴリズム SHA-256 に当てはまります。このタイプのハッシュはマイニングには関係ありません。この場合、パフォーマンスの証明による保護を実装していないからです。
var calculateHash = (index, previousHash, timestamp, data) => { return CryptoJS.SHA256(index + previousHash + timestamp + data).toString(); };
生成ユニット
ブロックを生成するには、構造内の残りの要素がすでに決定されているように、前のブロックのハッシュを知る必要があります。データはエンドユーザーによって提供されます。
var generateNextBlock = (blockData) => { var previousBlock = getLatestBlock(); var nextIndex = previousBlock.index + 1; var nextTimestamp = new Date().getTime() / 1000; var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData); return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash); };
ストレージユニット
ブロックチェーンストレージアレイを使用します。最初のブロックは常にハードコーディングされた「Genesis Block」です。
var getGenesisBlock = () => { return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7"); }; var blockchain = [getGenesisBlock()];
ブロックの整合性の確認
ユニットまたは回路の整合性を常に確認できなければなりません。特に他のユニットから新しいユニットを獲得する場合、それを受け入れるかどうかを決定する必要があります。
var isValidNewBlock = (newBlock, previousBlock) => { if (previousBlock.index + 1 !== newBlock.index) { console.log('invalid index'); return false; } else if (previousBlock.hash !== newBlock.previousHash) { console.log('invalid previoushash'); return false; } else if (calculateHashForBlock(newBlock) !== newBlock.hash) { console.log(typeof (newBlock.hash) + ' ' + typeof calculateHashForBlock(newBlock)); console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); return false; } return true; };
チェーンが最も長いものを選択してください
回路内のブロックの順序は明示的に指定する必要がありますが、競合の場合(例:同じ生成されたノード上で同時に2つのノード)ブロックと同じ数)、より多くのブロックを含む回路を選択します。
var replaceChain = (newBlocks) => { if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) { console.log('Received blockchain is valid. Replacing current blockchain with received blockchain'); blockchain = newBlocks; broadcast(responseLatestMsg()); } else { console.log('Received blockchain invalid'); } };
他のネットワークノードへのメッセージ
ウェブサイトの不可欠な部分 - 他のノードとのデータ交換。ネットワーク同期を維持するには、次のルールが使用されます。
ノードが新しいユニットを生成すると、それをネットワークに報告します。
ローカル マシンが新しいフィートに接続すると、最後に生成されたブロックに関する情報を要求します。 A ブロックに面しており、その中にそれよりも大きいインジケーターがある場合、回路またはリクエストの情報の完全なチェーンにブロックが追加されます。
ピアの自動検索は実行されず、すべてのリンクは手動で追加されます。
ユニットの制御
ユーザーは、HTTP サーバーをソリューションに組み込むことで、何らかの方法でノードを制御できる必要があります。ノードと対話するときは、次の機能があります: すべてのユニットのリストを印刷する;
ユーザーが生成したコンテンツを使用して新しいユニットを作成する;
リストを印刷する、またはフェスティバルを追加する。
最も直接的な対話方法 - Curl 経由:
アーキテクチャ
ユーザー制御のインストール用の HTTP と、ノード間の P2P 接続のインストール用の WebSocket HTTP の 2 つの Web サーバーを指します。 以下は 200 行の js コードです
'use strict';
var CryptoJS = require("crypto-js");
var express = require("express");
var bodyParser = require('body-parser');
var WebSocket = require("ws");
var http_port = process.env.HTTP_PORT || 3001;
var p2p_port = process.env.P2P_PORT || 6001;
var initialPeers = process.env.PEERS ? process.env.PEERS.split(',') : [];
class Block {
constructor(index, previousHash, timestamp, data, hash) {
this.index = index;
this.previousHash = previousHash.toString();
this.timestamp = timestamp;
this.data = data;
this.hash = hash.toString();
}
}
var sockets = [];
var MessageType = {
QUERY_LATEST: 0,
QUERY_ALL: 1,
RESPONSE_BLOCKCHAIN: 2
};
var getGenesisBlock = () => {
return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};
var blockchain = [getGenesisBlock()];
var initHttpServer = () => {
var app = express();
app.use(bodyParser.json());
app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain)));
app.post('/mineBlock', (req, res) => {
var newBlock = generateNextBlock(req.body.data);
addBlock(newBlock);
broadcast(responseLatestMsg());
console.log('block added: ' + JSON.stringify(newBlock));
res.send();
});
app.get('/peers', (req, res) => {
res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort));
});
app.post('/addPeer', (req, res) => {
connectToPeers([req.body.peer]);
res.send();
});
app.listen(http_port, () => console.log('Listening http on port: ' + http_port));
};
var initP2PServer = () => {
var server = new WebSocket.Server({port: p2p_port});
server.on('connection', ws => initConnection(ws));
console.log('listening websocket p2p port on: ' + p2p_port);
};
var initConnection = (ws) => {
sockets.push(ws);
initMessageHandler(ws);
initErrorHandler(ws);
write(ws, queryChainLengthMsg());
};
var initMessageHandler = (ws) => {
ws.on('message', (data) => {
var message = JSON.parse(data);
console.log('Received message' + JSON.stringify(message));
switch (message.type) {
case MessageType.QUERY_LATEST:
write(ws, responseLatestMsg());
break;
case MessageType.QUERY_ALL:
write(ws, responseChainMsg());
break;
case MessageType.RESPONSE_BLOCKCHAIN:
handleBlockchainResponse(message);
break;
}
});
};
var initErrorHandler = (ws) => {
var closeConnection = (ws) => {
console.log('connection failed to peer: ' + ws.url);
sockets.splice(sockets.indexOf(ws), 1);
};
ws.on('close', () => closeConnection(ws));
ws.on('error', () => closeConnection(ws));
};
var generateNextBlock = (blockData) => {
var previousBlock = getLatestBlock();
var nextIndex = previousBlock.index + 1;
var nextTimestamp = new Date().getTime() / 1000;
var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);
return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);
};
var calculateHashForBlock = (block) => {
return calculateHash(block.index, block.previousHash, block.timestamp, block.data);
};
var calculateHash = (index, previousHash, timestamp, data) => {
return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};
var addBlock = (newBlock) => {
if (isValidNewBlock(newBlock, getLatestBlock())) {
blockchain.push(newBlock);
}
};
var isValidNewBlock = (newBlock, previousBlock) => {
if (previousBlock.index + 1 !== newBlock.index) {
console.log('invalid index');
return false;
} else if (previousBlock.hash !== newBlock.previousHash) {
console.log('invalid previoushash');
return false;
} else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
console.log(typeof (newBlock.hash) + ' ' + typeof calculateHashForBlock(newBlock));
console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
return false;
}
return true;
};
var connectToPeers = (newPeers) => {
newPeers.forEach((peer) => {
var ws = new WebSocket(peer);
ws.on('open', () => initConnection(ws));
ws.on('error', () => {
console.log('connection failed')
});
});
};
var handleBlockchainResponse = (message) => {
var receivedBlocks = JSON.parse(message.data).sort((b1, b2) => (b1.index - b2.index));
var latestBlockReceived = receivedBlocks[receivedBlocks.length - 1];
var latestBlockHeld = getLatestBlock();
if (latestBlockReceived.index > latestBlockHeld.index) {
console.log('blockchain possibly behind. We got: ' + latestBlockHeld.index + ' Peer got: ' + latestBlockReceived.index);
if (latestBlockHeld.hash === latestBlockReceived.previousHash) {
console.log("We can append the received block to our chain");
blockchain.push(latestBlockReceived);
broadcast(responseLatestMsg());
} else if (receivedBlocks.length === 1) {
console.log("We have to query the chain from our peer");
broadcast(queryAllMsg());
} else {
console.log("Received blockchain is longer than current blockchain");
replaceChain(receivedBlocks);
}
} else {
console.log('received blockchain is not longer than received blockchain. Do nothing');
}
};
var replaceChain = (newBlocks) => {
if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {
console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');
blockchain = newBlocks;
broadcast(responseLatestMsg());
} else {
console.log('Received blockchain invalid');
}
};
var isValidChain = (blockchainToValidate) => {
if (JSON.stringify(blockchainToValidate[0]) !== JSON.stringify(getGenesisBlock())) {
return false;
}
var tempBlocks = [blockchainToValidate[0]];
for (var i = 1; i < blockchainToValidate.length; i++) {
if (isValidNewBlock(blockchainToValidate[i], tempBlocks[i - 1])) {
tempBlocks.push(blockchainToValidate[i]);
} else {
return false;
}
}
return true;
};
var getLatestBlock = () => blockchain[blockchain.length - 1];
var queryChainLengthMsg = () => ({'type': MessageType.QUERY_LATEST});
var queryAllMsg = () => ({'type': MessageType.QUERY_ALL});
var responseChainMsg = () =>({
'type': MessageType.RESPONSE_BLOCKCHAIN, 'data': JSON.stringify(blockchain)
});
var responseLatestMsg = () => ({
'type': MessageType.RESPONSE_BLOCKCHAIN,
'data': JSON.stringify([getLatestBlock()])
});
var write = (ws, message) => ws.send(JSON.stringify(message));
var broadcast = (message) => sockets.forEach(socket => write(socket, message));
connectToPeers(initialPeers);
initHttpServer();
initP2PServer();
NodeJSの親プロセスと子プロセスのリソース共有の原理と実装方法
Vueの携帯電話番号、メール定期認証と60代での認証コード送信例
以上がブロックチェーンを実装するための 200 行のコード ブロックチェーンの例の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Stead は、東南アジアに拠点を置く RWA プロジェクトです。これは、漁船や輸送船、生け簀、水上住宅などの水上インフラのための分散型資金調達プラットフォームとして機能します。

新世代のフロントエンド フレームワークが出現し続ける中、VUE3 は高速で柔軟、そして使いやすいフロントエンド フレームワークとして愛されています。次に、VUE3 の基本を学び、簡単なビデオ プレーヤーを作成しましょう。 1. VUE3 をインストールする まず、VUE3 をローカルにインストールする必要があります。コマンド ライン ツールを開き、次のコマンドを実行します。 npminstallvue@next 次に、新しい HTML ファイルを作成し、VUE3 を導入します。 <!doctypehtml>

Golang は、さまざまなアプリケーションやサービスの開発に使用できる強力で効率的なプログラミング言語です。 Golang では、ポインタは非常に重要な概念であり、データをより柔軟かつ効率的に操作するのに役立ちます。ポインタ変換とは、異なる型間のポインタ操作のプロセスを指します。この記事では、具体的な例を使用して、Golang におけるポインタ変換のベスト プラクティスを学びます。 1. 基本概念 Golang では、各変数にはアドレスがあり、アドレスはメモリ内の変数の位置です。

Oracle インスタンスの数とデータベースのパフォーマンスの関係 Oracle データベースは、業界でよく知られたリレーショナル データベース管理システムの 1 つであり、エンタープライズ レベルのデータ ストレージと管理で広く使用されています。 Oracle データベースでは、インスタンスは非常に重要な概念です。インスタンスとは、メモリー内のOracleデータベースの実行環境を指します。各インスタンスには独立したメモリー構造とバックグラウンド・プロセスがあり、ユーザー・リクエストの処理とデータベース操作の管理に使用されます。インスタンスの数は、Oracle データベースのパフォーマンスと安定性に重要な影響を与えます。

インターネットの急速な発展に伴い、データは今日の情報化時代において最も重要なリソースの 1 つになりました。 Webクローラは、ネットワークデータを自動的に取得・処理する技術として、ますます注目と応用が進んでいます。この記事では、PHPを使って簡単なWebクローラーを開発し、ネットワークデータを自動取得する機能を実現する方法を紹介します。 1. Web クローラーの概要 Web クローラーとは、ネットワーク リソースを自動的に取得して処理する技術であり、主な動作プロセスはブラウザーの動作をシミュレートし、指定された URL アドレスに自動的にアクセスし、すべての情報を抽出することです。

インターネットの普及に伴い、ログイン、登録、パスワードの取得などの操作に確認コードが必要なプロセスになりました。 Ginフレームワークでは、認証コード機能の実装が非常に簡単になりました。この記事では、サードパーティのライブラリを使用して、Gin フレームワークに検証コード機能を実装する方法を紹介し、読者の参考となるサンプル コードを提供します。 1. 依存ライブラリをインストールする 検証コードを使用する前に、サードパーティ ライブラリ goCaptcha をインストールする必要があります。 goCaptcha をインストールするには、goget コマンド $goget-agithub を使用できます。

Django フレームワークをすぐに使い始めましょう: 詳細なチュートリアルと例 はじめに: Django は、MTV (Model-Template-View) アーキテクチャによって駆動される効率的で柔軟な Python Web 開発フレームワークです。シンプルで明確な構文と強力な機能を備えており、開発者が信頼性が高く保守が容易な Web アプリケーションを迅速に構築するのに役立ちます。この記事では、Django の使用法を詳しく紹介し、読者が Django フレームワークをすぐに使い始めるのに役立つ具体的な例とコード サンプルを提供します。 1.Dをインストールする

Oracle データベースは、強力な機能と柔軟性を備えた世界有数のリレーショナル データベース管理システムの 1 つであり、エンタープライズ レベルのシステムで広く使用されています。 Oracle データベースでは、インスタンスは非常に重要な概念であり、データベースの実行環境とメモリ構造を伝達し、ユーザーとの接続と SQL 操作の実行の鍵となります。 Oracle データベース インスタンスとは何ですか? Oracle データベース インスタンスは、データベースの起動時に作成されるプロセスの集合であり、データベース インスタンスのメモリ構造やバックグラウンド プロセスも含まれます。例と
