ブロックチェーン基礎の基礎

2022.02.25

Introduction

最近は暗号資産(仮想通貨)やNFTに関連する情報をよく耳にするようになりました。
こういったものについては特にセキュリティ(データの破壊や改変)が重要になってきます。
これらを支える技術として使用されているのが、ブロックチェーン(Blockchain)です。  

最近仕事でも、これらの情報にふれる機会があったので、
調査した内容についてまとめました。

本稿ではブロックチェーン(+関連技術)の概要と基本的な仕組みについて解説します。

BlockChain?

BlockChainって何?

データベース技術の1つ。
ブロックという単位でデータを管理し、
それを鎖(チェーン)のように連結してデータを保管する技術です。
データを記録・保存するという点においては従来のデータベース(RDBMSやKVS)と同じですが、
その用途やアーキテクチャがまったく違います。

wikipediaより。

ブロックチェーン(英語: Blockchain)は、暗号技術を使って
リンクされたブロックと呼ばれるレコードの増大するリストである。
各ブロックには、前のブロックの暗号化ハッシュ 、タイムスタンプ、
トランザクションデータ(一般的にはマークルツリーで表される)が含まれている。

ブロックチェーンとは、2008年にsatoshi nakamoto氏の論文「Bitcoin」に
初めて概念が登場した技術です。

ネットワーク内で発生した一定時間における取引をトランザクションとし、
そのトランザクションの履歴をブロックと呼ばれる単位にまとめます。
そのブロックは永続化する際に1つ前のリストに連結され、
不変な記録を作成します。

各ブロックには取引の履歴と前のブロック内容のハッシュも格納されます。
なので過去の履歴を改ざんしようとしても、
変更したブロックから算出されるハッシュ値が変わり、
その後のすべてのブロックのハッシュ値も変更する必要があるので
改ざんが非常に難しくなっています。

どんなことに使われている?

  • 暗号資産での使用

Bitcoinの論文で登場した理論でもある、もっともメジャーな用途です。
暗号資産の取引履歴をブロックチェーンに保存し、高度なセキュリティと
非中央集権化を実現しています。

  • トレーサビリティ目的で使用

ブロックチェーンは履歴の改ざんが難しく、そのトレースが可能という特徴から
サプライチェーンの管理に利用されています。
食品の原材料をどこの誰が生産し、それがどういう経路で店舗まで流通しているのか
といった情報をブロックチェーン管理し、
安全性のチェックやフードロスの回避 などをおこなっています。

実際にIBM Food Trustという
食品の安全性とサプライチェーンの効率向上のためのサービスもあります。

関連技術

  • 契約の自動実行(スマートコントラクト)

スマートコントラクトとは第三者を介さずに契約を自動実行する仕組みです。
それ自体はブロックチェーン上で動作しなくても問題ありません。
実際、スマートコントラクトの例としてよく自動販売機が説明されています。

自動販売機は利用者が硬貨を投入し、自動販売機のルールにしたがって
自動的に取引契約を行います。  

この取引契約とは、「自動販売機の購入ボタンがおされたとき、
商品を購入できるお金が投入されており、その商品が売り切れていなければ
商品を利用者に渡し、お金を売り手に渡す」
というような取引です。  

スマートコントラクトをブロックチェーン上で実行する場合、
ブロックチェーンで規定のルールに従ってトランザクションまたは
外部の情報をトリガーにして任意のプログラムを実行します。
ブロックチェーン上でスマートコントラクトを行う利点は、
契約の透明性です。
また、履歴はP2Pネットワーク上でブロックチェーンに記録されるため、
改ざんの心配もありません。
さらに契約に関連する作業(契約書締結など)が不要になるため、
事務コストなどの削減も可能と言われています。  

2015年にリリースされたEthereum(イーサリアム)では、
パブリックブロックチェーンでスマートコントラクトが
実行可能なプラットフォームを提供しています。

  • NFT

NFTとは、Non-Fungible Tokenの略称であり、日本語だと非代替性トークンと呼ばれています。
「非代替性」とは、「替えが効かない」という意味です。
ここでいう「トークン」は、データや、モノ、証明などを意味しています。
NFTをすごーく簡単にいうと、「他にはないユニークであることの証明ができる技術」です。

最近はデジタルデータ(元々コピーが簡単にできる)を
「他にはない唯一のもの」として証明し、その所有権を取得する、
また希少価値の高いデータについては高額で取引されたりもしています。

技術的な側面からいうと、
NFTとはERC721という規格のスマートコントラクトです。

補足:Ethereum(イーサリアム)
Ethereumは、スマートコントラクト機能を持つ分散型アプリケーションプラットフォーム。
このプラットフォーム内で使用される仮想通貨をEther(イーサ)という。

ERCというのはEthereum Request for Commentsの略、
つまりEthereumのRFCです。
ERC721というのは721番目に提案されたEthereumにおける
スマートコントラクトの規格を指します。

この規格を使用することで、Ethereum上で

  • NFTの所有権
  • NFTの取引履歴

が記録可能になります。
現状NFTはデジタルアート作品やゲームキャラクターなどの
デジタルデータを対象とすることが多いですが、
現実世界の物(スニーカーとか車)を対象とする実例もあります。
参考:日本のNFT事例20選【第二弾】

では次に、ブロックチェーンの特徴について解説していきます。

非中央集権ネットワーク

例えば、銀行などでは取引情報などを自分が管理するコンピュータで保持しています。
管理するコンピュータ(≒データベース)はそれ1つだけなので、
システム全体はそのコンピュータに依存しているといえます。
そのコンピュータがハッキングされたり停止した場合、システム全体が止まります。
これが中央集権型システムです。(オンプレでもクラウドでも関係なし)

対してブロックチェーンの場合、こういった特定のコンピュータに依存せず、
中央集権的な管理者を持ちません。
ユーザーはネットワーク上でノードを実行します。
ノードとはマシンにインストールしてネットワークに接続しているソフトであり、
すべてのノードはピア(peer)です。

これが可能な理由は、
「ブロックチェーン上のすべてのトランザクション履歴がノードにふくまれているから」
です。
※一部のノードにおいては、報酬を受け取るためにブロックの作成にも参加する

このように、ユーザーがそれぞれのデータを共有して管理する方式は
「分散型台帳」とも呼ばれ、ネットワークに送信されたトランザクションは、
基本すぐにすべてのノードに伝搬されます。
(ブロック追加時も同じく)

  

この非中央集権ネットワーク上で分散型台帳を支える技術が、
下記の項目です。  

  • P2Pネットワーク
  • 暗号化
  • コンセンサスアルゴリズム

P2Pネットワーク

↑の図にあるとおり、ブロックチェーンではノード同士が
P2P(peer to peer)ネットワークで接続されています。
(peerとは、同等とか対等という意味)

P2Pネットワークでは、各ノードが同じ役割を持ち、ノード間で通信が行われます。
従来のようにサーバで処理してクライアントで利用する形式ではなく、
すべてのノードがクライアントとサーバ両方の役割を担います。
P2Pは、ブロックチェーンを構成する大事な要素のひとつであり、
P2Pの特徴がそのままブロックチェーンの特徴に繋がります。
その特徴については以下のとおりです。

  • 障害に強い

P2Pネットワークでは各ノードが対等であり、相互に通信しています。
そのため、ネットワークを構成するノードが障害や攻撃を受けて停止したとしても、 
それ以外のノードが無事であればネットワークは継続可能です。
従来のクライアントサーバネットワークでサーバが停止した場合はこうはいきません。  

また、スケーラビリティについてもP2Pネットワークは優れています。
従来のクライアントサーバ形式において、特定のサーバに負荷が集中することはありません。
ノードを追加すればするほどスケールアウト可能です。

  • 高価なシステムは必須ではない

P2Pネットワークではすべてのノードが対等や立場でネットワークが構成されているので、
「負荷が集中するのでハイスペックなサーバを用意する」といったことはないです。
スマートフォンでも昔の低スペックマシンでも(クライアントがあるなら)、
ノードとして参加できます。

ブロックチェーンのデータ構造

ブロックチェーンで使用するデータ構造を理解するには、
いくつか前提となる技術があるので、まずそれについて簡単に説明します。

  • ハッシュ関数

ハッシュ関数とは、任意のデータから別の(多くの場合は短い固定長の)値を得るための操作、   または、その様な値を得るための関数です。
Wikipediaより  

そして以下の特徴があります。

  • 出力値(ハッシュ値)から入力値(元のデータ)を逆算できない
  • 同じデータを入力すると同じハッシュ値を得ることができる

下記のサンプルプログラムでは
SHA-256をつかって文字列をハッシュ化しています。
(Rustで記述)

use sha256::digest; //sha256 crateを使用

fn main() {
    let input1 = "hello";
    let input2 = "hollo";

        //SHA-256でハッシュ化
    let val1_1 = digest(input1);
    let val1_2 = digest(input1);
    let val2 = digest(input2);

    println!("val1_1 : {:?}",val1_1);
    println!("val1_2 : {:?}",val1_2);
    println!("val2   : {:?}",val2);

    // 同じインプットからは同じハッシュ値が出力される
    // val1_1 : "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
    // val1_2 : "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

    // 1文字違うだけでまったく違うハッシュ値が出力される
    // val2   : "641b13af9f451dec5f6fe1abea23a27b01191a41c8cc38434683c3a026eaaec7"
}

同じデータからは同じハッシュが生成されています。
また、1文字違うデータからはまったく異なるハッシュ値が生成されます。
これはハッシュ関数の連続性が低く、ハッシュ値の類推ができないことを意味しています。

ブロックチェーンでは、各ブロックに
「1つ前に生成されたブロック内容を示すハッシュ値」を持っています。  

ちなみに、イーサリアムではKeccak-256というハッシュ関数、
ビットコインでは、SHA-256とRIPEMD-160を
組み合わせて使用しています。

  • 電子署名

電子署名とは、電磁的記録(電子文書)に付与する、電子的な徴証であり、
紙文書における印章やサイン(署名)に相当する役割をはたすものである。
主に本人確認や、改竄検出符号と組み合わせて
偽造・改竄(かいざん)の防止のために用いられる。

Wikipediaより  

ブロックチェーン上にはすべての利用者の取引情報が記録されます。
この情報に支払人、受取人、金額だけが記録される場合、
本当に支払人の意思によるものかわかりません。
そこで「この取引は支払人の意思で作成され、内容も正しいです」というのを証明するために   電子署名を使います。

電子署名では公開鍵暗号方式を使って署名を行います。
署名者は秘密鍵を使ってデータに署名し、電子署名として受信者に送る。
受信者は事前に受け取っている公開鍵を使うことで、
対象データが署名者によって作成されたことを確認できます。

ブロックチェーンにおける電子署名は↓のようなイメージです。

めそコインの名前だけ拝借

支払人は自分の秘密鍵を用いて取引情報のハッシュ値を暗号化し、
その情報と公開鍵もセットでトランザクションに記録します。
こうすることで、検証側(ノード)でトランザクションの正当性を確認することができます。

下記のサンプルプログラムは電子署名をするサンプルです。
(Rustで記述)

//rsa,rsa,randを使用

use rand::rngs::OsRng;
use rsa::{Hash, PaddingScheme, PublicKey, RsaPrivateKey, RsaPublicKey};
use sha2::{Digest, Sha256};

fn main() {

    let mut rng = OsRng;
    let bits = 2048;
    //署名対象のメッセージ
    let message = "hello world";
    let data = message.as_bytes();
    //メッセージダイジェスト
    let digest = Sha256::digest(message.as_bytes()).to_vec();

    //秘密鍵と公開鍵生成
    let pri_key = RsaPrivateKey::new(&mut rng, bits)
        .unwrap_or_else(|res| panic!("failed to generate a key:{}", res));
    let pub_key = RsaPublicKey::from(&pri_key);

    //秘密鍵で署名
    let sign_data = pri_key
        .sign_blinded(
            &mut rng,
            PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)),
            &digest,
        )
        .unwrap();

    assert_ne!(&data[..], &sign_data[..]);

    //検証
    pub_key
        .verify(
            PaddingScheme::new_pkcs1v15_sign(Some(Hash::SHA2_256)),
            &digest,
            &sign_data,
        )
        .unwrap_or_else(|res| panic!("result:{}", res));
}

秘密鍵が漏洩すると他人が好き勝手に自分の取引を作成できるので、
秘密鍵の管理には気をつけましょう。

ブロックチェーンにおける電子署名の説明はこのあたりもご確認ください。

  • ブロックのデータ構造

これらをふまえて、ブロックのデータ構造について説明します。
ブロックのデータ構造は以下のようになっています。

なお、ここではコンセンサスアルゴリズム(後述)が
Proof-of-Workと仮定して解説しています。

一定時間ごとにあたらしいブロックが作成され、
その間発生したトランザクションがすべてそのブロックに記録されます。

各ブロックでは
「1つ前に生成されたブロック内容を示すハッシュ値」を持っています。
また、「そのブロックでの取引記録」と後述する「Nonce(ナンス値)」を加えて、
そのブロックのハッシュ値を算出します。
※ Nonce : Number Used Once  

ここで算出するブロックのハッシュ値は、
なんでもよいというわけではありません。
「ハッシュ値は上位X桁は0であること」などの条件があります。
※ブロックチェーンの仕様によって違う  

仕様にあうハッシュ値を探すためにNonceを変えてハッシュ値を探します。
この仕様に合致するブロックのハッシュ値を探すための作業が「マイニング」です。
マイニングはブロックチェーンに参加しているすべてのノードが実行します。

仕様に合致するNonceが見つかり、対象ブロックの正しいバッシュ値が算出されると、
ブロックにNonceが追加されて前のブロックと結合されます。
その後、新たにブロックが形成されてそのブロックが
対象ブロックのハッシュ値を持つ、という仕組みです。

Nonceを探すのは早い者勝ちです。
いちばん最初に正しいNonceを探しだした人が
報酬(そのブロックチェーン上の暗号通貨)をもらうことができます。  

↑でも少し述べましたが、
「仕様に合致するNonceを早いもの勝ちで探し、
最初に発見した人に報酬を支払う」というのは
Proof-of-Workという方式のコンセンサスアルゴリズムです。

このアルゴリズムはいくつか種類があります。
次にコンセンサスアルゴリズムについて解説します。

コンセンサスアルゴリズム

ブロックチェーンでは一定時間内の取引を1つのブロックにすべて記録し、
暗号化して最後尾のブロックにつなげていきます。
この、「ブロックをつなげるためのコンセンサス(合意)形成を行う方法」です。

コンセンサスアルゴリズムはいくつも種類があります。
ここでは代表的なものを2つ紹介します。

Proof of Work(プルーフ・オブ・ワーク. PoW)

さきほどの解説で出てきたアルゴリズムです。
ビットコインやEthereumなど、
現在最も多くの暗号資産で使われていると思われます。
仕様に合致したブロックのハッシュ値を探し、
そのハッシュ値をつかってブロックを接続、
発見した人に報酬(暗号資産のブロックチェーンならその暗号資産)
を支払うという内容です。  

このコンセンサスアルゴリズムですが、近年はマイニングによる
電力消費が問題化しています。
マイニングで勝つには膨大な計算能力が必要で、
消費電力も大きく、地球にやさしくない方法です。  

Proof of Stake(プルーフ・オブ・ステーク. PoS)

PoWの代替手段として開発され、最近の主流となってきている手法です。
この手法は、任意のルールで「ブロックをブロックチェーンにジョイントする役割」を
特定のノードに与えます。
これはバリデータとよばれる特別なノードです。

※バリデータ(承認者): ブロックチェーンに記録されるデータの内容が正しいか検証するノード

例えばEthereum 2.0の場合、マイニングするノードはバリデータとなり、 
ネットワークに参加するための保証金としてイーサを支払います。
このイーサには利子がつくので、それが報酬となります。  

ルールにより選択されたバリデータ(ランダムだったり暗号資産の保有量/期間など)
がブロックを承認し、ネットワークがブロックチェーンを更新します。

また、仕様によってはバリデータが承認したブロックに対して
他のバリデータがそれを検証し、
一定数以上の信任を得られたらブロックチェーンを更新する、
という仕様もあるみたいです。

PoSの特徴としては下記の点が挙げられます。

  • 処理速度が早い
    PoWの場合、決済(ブロックが承認される)までの速度は
    10分から20分程度必要になっていますが、
    PoSならば数秒で可能となります。

  • 消費電力が少ない
    PoSは、PoWに比べマイニングによる消費電力が少ないです。
    PoWがマイニング能力によって正しいブロックを決定するのに対し、
    PoSは「対象ブロックチェーンの通貨」の保有数により決定します。

  • 暗号資産の流動性が高まらない
    このアルゴリズムでは、多くの暗号資産を長期間保有することが有利になるため、
    暗号資産の流動性が高まりにくい特性があります。  

その他のコンセンサスアルゴリズム

コンセンサスアルゴリズムは紹介したもの以外にも、  

  • PoH(プルーフ・オブ・ヒストリー)
  • PoA(プルーフ・オブ・オーソリティ)
  • PoI(プルーフ・オブ・インポータンス)

などなどいろいろな種類があり、新しいアルゴリズムも考案されています。
詳しくはこちらなどをご確認ください。

Summary

本稿ではブロックチェーンの仕組みやデータ構造など、
基本的な部分について解説しました。

スマートコントラクトやNFTなど、各ブロックチェーンの
開発環境で試すこともできるので、興味があるかたは
実際にうごかしてみてください。

Appendix

この記事をかくまでに調べた用語メモ

Ethereum

2015年にリリースされた、分散型アプリケーション(DApps)やスマート・コントラクト
構築するためのプラットフォーム。

「Ethereum」という単語は仮想通貨そのもの指しているわけではない。
Ethereumプラットフォームで使用する仮想通貨ははEther(イーサ.単位はETH)。

Dapp

分散型アプリケーション(decentralized application)のこと。
trustlessプロトコルによる分散ネットワーク上で
多数のユーザーが利用する。

Gas(ガス)

Ethereumでの取引手数料。
取引のためにトランザクション実行をしたり
スマートコントラクトのプログラム実行で発生する手数料。  

Geth

Ethereumのクライアント。 
参考 : Gethをインストールする

Truffle

EthereumにおけるDapp開発用フレームワーク。
スマートコントラクトのコンパイルやテストなど必要な機能を一通り持っている。
参考 : Truffle  

Truffleと一緒に用いられるツールとして
Ganasche(ローカル開発用のノードを構築)や
drizzle(スマートコントラクトにアクセスするフロントエンドを構築)
などがある。

Solidity

スマートコントラクトを使うためのオブジェクト指向の高級言語。
JavascritとかPythonを参考に開発されている。
参考 : Solidity

Open Zeppelin

OSSのEthereum Solidityライブラリ。
ERC20やERC721のベースを提供してくれる。
参考 : Open Zeppelin

Solana

パブリックブロックチェーンの1つ。
最近日本でも取り扱いが開始された。

参考:Solana

PoH(プルーフ・オブ・ヒストリー)というコンセンサスアルゴリズムを採用しており、
処理速度が速く、コストも安い。  

Token(トークン)

所有権を表す抽象概念。
世間一般的には「ブロックチェーン上で発行された独自コイン」を指す。
EthereumのEtherはトークンとは呼ばない。
Ethereum上で発行されるEther以外のものをトークンと呼ぶ。

ERC20トークン

ERC20はイーサリアムブロックチェーンのトークン規格。
これはイーサリアムブロックチェーンと互換性を持つ暗号資産を作るための規格で、
テザー(USDT)とかチェーンリンク(Chainlink)は
ERC-20規格で作られた「ERC-20トークン。
めそコインもこれ。

この記事を書くため参考にしたサイト