「ブロックチェーン」の作り方

それでは、JavaScriptを使った、具体的なブロックチェーンの作り方について解説します。

Step1. ブロックの構造を決めよう

最初のステップは、ブロックの構造を決定することです。
最低限の項目は以下の5つです。

・インデックス (index):0から始まる連続した整数値
・タイムスタンプ (timestamp):取引の時刻を格納するunixタイムスタンプ
・データ (data):実際の取引データ
・ハッシュ値 (hash):タイムスタンプなどから生成するユニークな値
・直前のブロックのハッシュ値(previousHash)

直前のブロックのハッシュ値が分かれば、チェーンの連続性が保たれることになります。

これをJava Scriptで表現すると、次のようになります。

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();
  }
}

Step2. ブロックのハッシュ値を生成しよう

ブロックの構造が決まったら、今度はブロックのハッシュ値を生成していきます。
ハッシュの生成には色々な技術がありますが、SHA-256と呼ばれる技術が一般的です。
SHAとはSecured Hash Algorithmの略で、アメリカ国家安全保障局(NSA)によって設計された暗号学的なハッシュ関数です。

以下のコードでは、crypto.jsと呼ばれる暗号化ライブラリを使って、ハッシュを生成するようにしています。

var calculateHash = (index, previousHash, timestamp, data) => {
  return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();
};

Step3. ブロックを作ろう

新しいブロックを作成するために必要なのは、直前のブロックのハッシュ値と、残りの必要項目(インデックス・タイムスタンプ・データ・このブロックのハッシュ値)です。
もちろん、取引内容に当たる
データ
はエンドユーザーによって渡される値になるので、引数として受け取れるようにしておきます。

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);
};

Step4. 起源ブロックを定義しよう

ブロックチェーンは、基本的に前のブロックのハッシュ値を含むブロックの集合体なので、1つのブロックを除いては、連続した配列になるはずです。

しかし、その1つの例外的なブロックである「一番最初の」ブロックは、直前のハッシュ値を保有していないために、物理的に定義を行う必要があります。
このブロックの名前は一般的ではありませんが、プログラマーLauri Hartikka氏の言葉を借りて「起源ブロック」(Genesis Block)と呼ぶことにしましょう。

以下のコードでは、起源ブロックを物理的に定義して生成しています。

var getGenesisBlock = () => {
  return new Block(0, "0", 1465154705, “This is the genesis block!”, "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");
};

var blockchain = [getGenesisBlock()];

Step5. ブロックの連続性を検証しよう

ブロックチェーンにおいて重要なことは、いかなるときでもどんな人でも、あるブロックやチェーンが連続的であることを検証できるようにすることです。
特に、他の人が作ったブロックを受け取って新しいブロックを作る際に、連続していることを確かめるのに重要です。

ここでは、直前のブロックと新しいブロックを引数として、インデックスやハッシュ値を比べていく工程をコードにしてみましょう。

var isValidNewBlock = (previousBlock, newBlock) => {
  if (previousBlock.index + 1 !== newBlock.index) {
    console.log(‘インデックスが無効です’);
    return false;
  } else if (previousBlock.hash !== newBlock.previousHash) {
    console.log(‘直前のブロックのハッシュ値が無効です’);
    return false;
  } else if (calculateHashForBlock(newBlock) !== newBlock.hash) {
    console.log(‘ハッシュ値が無効です:’ + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);
    return false;
  }
  return true;
};

「isValidNewBlock」 を通して、問題がなければtrueを返します。