2017年8月1日にビットコインが2つに分裂(BTCとBCC)したというニュースが話題となりました。
日本でもビックカメラ全店舗でビットコイン決済に対応するなど、国内でも暗号通貨(Crypt Currency)の注目度が高まりつつあります。

Web界隈でも、決済機能を簡単に追加することができるWebサービスStripeがビットコイン決済に対応し、一般的なホームページにもビットコイン決済を数分で追加することが可能ですとなりました(※)。

※ Stripeのビットコイン取引の成約では1件につき0.5%の手数料がかかります。

しかし、「ビットコインは得体の知れないもの」だと否定的に考えている人がいるのも事実です。
実際、ビットコインを支える「ブロックチェーン」技術は革新的な技術ですが、理解がなかなか追いつきにくい部分です。

他方で、ビットコインが広く世に広まっていくに従い、ブロックチェーンの技術を他の分野でも応用できるのではないかと考え、金融や流通、あるいは契約(コントラクト)の分野などでもブロックチェーンに注目が集まっています。

今回は、ブロックチェーンの基本概要の解説と、実際に簡易的なブロックチェーンを作るためのプロセスをご紹介します。

ブロックチェーンとは

bitcoin.jpeg
Credit: pexels.com

ブロックチェーンは、ビットコインを支える中核の技術です。

実際のブロックチェーンにはさまざまなタイプがありますが、基本となる考え方は以下の図に集約されます。

figure1.png
著者により作成

AさんとBさんの取引情報を、2者間だけで保有するのではなく、分散データベースに記録します。
分散データベースは、受け取った取引情報を自己のデータベースに書き込みます。

figure2.png
著者により作成

この取引情報の記録一つひとつのことを*「ブロック」と呼び、各ブロックにはタイムスタンプと前のブロックへのリンクが含まれています。
この「ブロック」が連続して鎖(チェーン)のように繋がり、理論上は一度記録するとブロック内のデータを変更することができないことから、
「ブロックチェーン」*と呼ばれています。

現在では「スマートコントラクト」と呼ばれる契約の手段やフィンテックなど、さまざまな分野でブロックチェーンの技術が使われており、基本的な構造が分かれば、一般的なプログラマーでもブロックチェーンの技術を構築することは可能です。

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

それでは、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を返します。

まとめ

ブロックチェーンの基本的な考え方と、その作り方を通して、ブロックチェーンの基本的な仕組みがご理解いただけたのではないでしょうか。
本当であれば、チェーンのコンフリクト(複数のチェーンが乱立してしまうこと)などの処理も行う必要がありますが、基本的な考え方は以上の5ステップになります。

もしあたらしいサービスを立ち上げるのであれば、ブロックチェーンを活用したサービスを使ってみるのも良いでしょう。

参考:
「ブロックチェーン」とは?今さら聞けない基礎知識を解説