しかし、ブロックチェーンについて話すとき、多くのことが理解できないままであり、その助けを借りて解決しようとしている多くの問題もあります。 これは、ビットコインやイーサリアムなどの一般的なブロックチェーンプロジェクトに適用されます。 「ブロックチェーン」という用語は、通常、送金、スマート契約、暗号通貨などの概念に強く結び付けられています。
これにより、ブロックチェーンの理解が実際よりも難しくなります。 特にソースコード。 ここでは、NaiveChainと呼ばれるJavaScriptコードの200行のブロックチェーンの非常に単純な実装について説明します。
ブロック構造
最初の論理ステップは、ブロックの構造を決定することです。 すべてをできるだけシンプルにするために、最も必要なものだけを含めました。インデックス、マーク、データ、ハッシュ、前のブロックのハッシュです。
チェーンの整合性を維持するには、ブロック内で前のブロックのハッシュを見つける必要があります
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(); } }
ブロックハッシュ
データの整合性を維持するには、ブロックをハッシュする必要があります。 SHA256は、ブロックのコンテンツを担当します。 問題の解決策である作業の確認がないため、このハッシュは「マイニング」とは関係がないことに注意してください。
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); };
ブロックストレージ
メモリでは、JavaScript配列を使用してブロックチェーンを保存します。 ブロックチェーンの最初のブロックは、常に「ジェネシスブロック」と呼ばれ、次のコードがあります。
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('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash); return false; } return true; };
最も長いチェーンを選択してください
チェーンには、一度に1つの明示的なブロックセットのみが常に存在する必要があります。 競合が発生した場合(たとえば、作成されたブロック番号72のように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'); } };
他のサイトとのコミュニケーション
ノードの重要な機能は、ブロックチェーンと他のノードとの分離と同期です。 ルール-ネットワーク同期の維持に使用:
- ノードが新しいブロックを生成すると、ネットワークにブロードキャストします
- ノードが新しいピアツーピアネットワークに接続するとき、ノードは最後のブロックに依存します
- ノードは、現在の既知のブロックよりも大きいインデックスを持つブロックを検出すると、現在の状態のブロックを独自のチェーンに追加するか、ブロックチェーンを満たすためのサポートを行います。
ノードが説明されたプロトコルに従う場合に従ういくつかの典型的な通信シナリオ
自動相互検出はありません。 パーティーの場所(= URL)は手動で追加する必要があります。
ノード制御
ユーザーは、何らかの方法でノードを制御できる必要があります。 これは、httpサーバーを構成することによって行われます。
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)); };
ご覧のとおり、ユーザーは次の方法でノードと対話できます。
- すべてのブロックのリストを表示する
- ユーザー定義のコンテンツで新しいブロックを作成します
- ピアユーザーを表示または追加する
ノードを制御する最も簡単な方法は、Curlを使用することです。次に例を示します。
#
curl http://localhost:3001/blocks
建築
ノードが実際に2つのWebサーバーを提供することに注意する必要があります:1つはノードを制御するユーザー用(httpサーバー)、もう1つはノード間のピアツーピア通信用です(Websocket httpサーバー)。
NaiveChainの主要コンポーネント
おわりに
NaiveChainは、デモとトレーニングの目的で作成されました。 (PoS of PoW)のマイニングアルゴリズムを使用するまでは、パブリックネットワークで使用できません。 それにもかかわらず、ブロックチェーンを実装するための基本的な機能を実装しています。