ブロックチェーンを要素技術から理解する
この記事は Applibot Advent Calendar 2024 9日目の記事です。前回の記事はコチラです。
はじめに
この記事では、ブロックチェーンの要素技術について解説します。少し今更な感じがあるかもしれませんが、ブロックチェーンに関して表層的で曖昧な理解にとどまっていたため、この記事を執筆することで技術的な理解を深めたいと考えました。
ブロックチェーンとは何かをググると、「ブロックと呼ばれる単位でデータを管理し、それを鎖(チェーン)のように連結して保管する技術や仕組み」といった説明が一般的です。P2Pネットワークや分散型DBといった用語は登場するものの、それらの技術や概念の実現方法や、それぞれの技術の結びつきまで踏み込んだ記事はあまり見かけないため、本記事ではその点について掘り下げていきます。
対象読者
- ブロックチェーンの仕組み、要素技術について、表層的な概念だけでなく技術的に踏み込んで理解したいエンジニア、ビジネスマン
0章 ブロックチェーンとは
「ブロックチェーン」を一言で表すなら、改ざんが事実上不可能な特定のネットワーク上で読み書きが可能なデータベースです。そして重要なのは、DBが記録するのは 「データが生成されたこと」と「データが移動したこと」 のみです。そのDBのデータから現在の状態を計算することができ、例えば仮想通貨の場合は、すべてのユーザーの残高を確認できます。読み込みの仕組み自体は通常のDBと大きな違いはありませんが、書き込みの方法がかなり特殊で、さまざまな技術が用いられると同時にお金が絡むため、この分野が注目される要因になっていると感じしました。
ブロックチェーンは、P2Pネットワーク、暗号、改ざん検証のような技術の組み合わせによって成り立っています。これらにより、ブロックチェーンは不特定多数が参加するP2Pネットワーク上で、全員が合意可能なデータベースを構築することを可能にしています。1章ではその根幹となるP2Pネットワークについて説明し、2章ではP2Pネットワークによる分散DBへ書き込む仕組み、3章ではブロックチェーンがどう使われているかを書いていきます。
1章 ブロックチェーンネットワークの構成技術
まず、ブロックチェーンを支える根幹の技術である、P2Pネットワークについて説明します。ブロックチェーンではP2Pによるデータの送受信採用しています。
1-1 P2Pネットワークとは
P2P(ピアツーピア)ネットワークは、ブロックチェーンの根幹といえる技術で、データの送受信を行うためのネットワーク方式の1つです。従来のサーバー/クライアント型ネットワークと対比して語られることが多いです。
サーバー/クライアント型の仕組み
現在主流のWebサービスでは、サーバー/クライアント型のネットワークが一般的です。例えば、PC_Aがデータを取得したい場合、PC_A(クライアント)はあらかじめ決められたサーバーに対してリクエストを送信し、サーバーはレスポンスを返します。サーバー/クライアント型では、サーバーがデータ管理の中心となり、一元的にデータを提供します。
例えば、最近流行りのポケポケで自分が所有するカード一覧を取得する際、アプリのロジックはDeNAさんが管理するサーバー(ネットワーク)に対してリクエストを送信し、そのサーバーがレスポンスを返す仕組みになっているはずです。
P2Pネットワークの仕組み
一方、P2Pネットワークでは、PC_Aはまず同じプロトコルを実装したソフトウェア(ノードプログラム)を実行している他のPC(ノード)に対して、ブロードキャストを行います。リクエストを受けたノードの中で、目的のデータを保持しているノードがPC_Aに対してデータを送信します。
P2Pネットワークではネットワーク上のPCがクライアントとしてもサーバーとしても動作し、対等な関係でデータの送受信を行います。特定の中央サーバーを持たず、ノード同士が対等な関係で動作するネットワークとなります。
補足
- ブロードキャストを行う際には送信先のIPアドレスが必要になります。ただし、ネットワーク上のすべてのPCに対して無差別にブロードキャストを行うわけではなく、ネットワーク内で接続されている近隣のPC(ピア)のIPアドレスを管理し、その範囲内に限定してブロードキャストを行います。
- 送信するデータは細かく分割されており、配信中のノードが一時的にネットワークから見つけられなくなった場合(電源がオフになるなど)、別のノードからデータの続きを取得できる仕組みが採用されています。
- P2Pネットワークの設計やファイルの保存方法によって、「ピュアP2P」「ハイブリッドP2P」「スーパーノード型P2P」といった分類があります。これらのモデルは、ネットワークの構造や管理の仕組みによって名称が異なります。
- ノードプログラムには以下のような機能が含まれます
- ノード間の接続: ネットワーク内の他のノードを自動的に検出し、ピア(隣接ノード)として接続。
- データの送受信: 受信したリクエストを処理し、必要に応じてデータを返す。また、自身が保持していないデータをリクエストすることも可能。
- ネットワークの同期: 他のノードと連携し、ネットワーク全体のデータの整合性を保つ。
1-2 P2Pネットワークの活用
P2Pネットワーク上ではデータの送受信を1-1で説明した仕組みによって、事実上すべてのPCが見ることができます。これらの履歴をP2Pネットワーク上で記録しているものを台帳と呼び、いわばP2Pネットワーク全体の共有データベースとして機能します。この記録はノードプログラムによって行われます。
これ以降、データ送受信の履歴(台帳)を保有するP2Pネットワークのことをブロックチェーンネットワークと呼びます。
補足
- 説明を簡潔にするために、P2Pネットワークに参加するすべてのノードが台帳をもつと書きましたが、ストレージの限界やブロードキャスト時の通信量が膨大になる問題などがあるため、実際にはありません。現実的にはそれらの問題を解決するようにネットワークが設計されており、すべての情報をもつフルノード、ヘッダーしか持たないライトノードというように、ノードによって持つ情報量が異なります。
- データ量の肥大化に対して、台帳を圧縮や整合性を損なわないように古いデータを削除する(プルーニング)ようなストレージの問題を解決する仕組みが入っています
2章 台帳への書き込み
1章ではP2Pネットワークを活用して、各ノードで台帳が共有される仕組みを確認しました。しかし、書き込みに関しては問題があると勘付きます。台帳をブロードキャストによって同期されるDBと捉えると、書き込むユーザーの制限や書き込み順を制御する仕組みが必要そうです。この書き込みの問題を解決する手段として、暗号技術と検証が使われます。
2-1 台帳への書き込み
各ノードが台帳に対して自由に書き込みを行った場合、台帳がぐっちゃぐちゃになることは容易に想像がつきます。そのため、ブロックチェーンネットワークでは、新しいデータを台帳に書き込む権利を特定のノードに与える仕組みが採用されています。
この仕組みはシンプルで、ある計算問題を最初に解いたノードが書き込める、というものです(小学校で休みが出て給食のデザートのあまりが1つでたとき、最初に給食を食べ終わった人が食べる権利を与えられる、みたいな感じです)。
計算問題もシンプルで、sha256でハッシュ化した時、先頭が1234になるようなyを答えよ、というものです。pythonで関数を書くと以下のようなコードになります。
import hashlib
def find_y_with_hash_prefix(prefix: str, input_data: str):
"""
指定されたプレフィックスを持つSHA-256ハッシュを生成するための値yを探索します。
Args:
prefix (str): ハッシュの先頭部分に一致させたい文字列(例: '1234')
input_data (str): ハッシュ化の基となる固定データ(例: 'blockchain')
Returns:
tuple: 条件を満たす値yとそのハッシュ値
"""
y = 0 # 探索する値
while True:
# 入力データとyを連結してハッシュ化
combined_data = f"{input_data}{y}"
hashed_value = hashlib.sha256(combined_data.encode()).hexdigest()
# ハッシュの先頭が指定されたプレフィックスに一致するか確認
if hashed_value.startswith(prefix):
return y, hashed_value
y += 1 # 次の値を試す
# 条件設定
prefix = "1234" # ハッシュの先頭が1234になるようにする
input_data = "blockchain" # ハッシュ化の基となるデータ
# 探索開始
result_y, result_hash = find_y_with_hash_prefix(prefix, input_data)
print(f"条件を満たすy: {result_y}")
print(f"対応するハッシュ値: {result_hash}")
解であるyを見つけたノードは、yをネットワーク全体にブロードキャストします。ブロードキャストされたノードはyが正しいか検証し、条件を満たしていることを確認できた場合(コンセンサスを得られた場合)、そのノードに書き込み権限が与えられます。このようにして書き込み権限を得られたノードは台帳に対して書き込みを行います。この仕組みにより、ブロックチェーンの台帳は整合性を保ちながら分散的に管理されています。
補足
- 解であるyはナンス(nonce)と呼ばれます。
- 実際には書き込み権限を得られた後に書き込みを行うのではなく、書き込みを行った後に検証が行われます
- 上記で例は Proof of Work アルゴリズムによる書き込み権の決定方式です。ネットワークによって、採用されているアルゴリズム(コンセンサスアルゴリズム)は異なります。
- この計算プロセスはマイニングと呼ばれます。
2-2 書き込むデータ形式
台帳に書き込むデータ形式は、あらかじめフォーマットが定められています。メタデータ(ヘッダー)と内容(トランザクション)に分かれていて、以下のようなデータです。
{
"index": 1,
"timestamp": 1702219200.123456,
"previous_hash": "0000000000abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"hash": "0000a7b5f97b9c6238e77a2ff9c1f23553e9f233c17d6ac69de5c8e90cf9a7b1",
"nonce": 83456,
"transactions": [
{
"sender": "Alice",
"receiver": "Bob",
"amount": 10.0,
"fee": 0.1,
"data": ""
},
{
"sender": "Charlie",
"receiver": "Dave",
"amount": 20.0,
"fee": 0.2,
"data": ""
}
]
}
このデータの塊をブロックと呼びます。書き込み権取得の計算時には、前のブロックが保有するhash値(previous_hash)を使用します。ブロックが前のブロックのハッシュ値に依存していることをブロックがチェーンすると表現し、この台帳のデータ構造をブロックチェーンと呼んでいます。
補足
- データ構造はネットワークにより異なります
-
データ構造の主な要素
- Index: ブロックの通し番号。
- Timestamp: ブロック生成時のタイムスタンプ。
- Previous Hash: 直前のブロックのハッシュ値。これにより、各ブロックが鎖(チェーン)のように連結されます。
- Hash: このブロック自身のハッシュ値。ブロック内のデータから生成されます。
- Nonce: 計算問題の結果として得られる値。PoWで用いられる。
- Transactions: ブロックに記録される取引データのリスト。
2-3 改ざんの困難性
2-2で紹介したデータ構造において、あるノードがブロックの改ざんを試みたとしましょう。
一度記録されたブロックを改ざんすると、そのブロックのハッシュ値が変化します。この変更は、その後に連なるすべてのブロックのprevious_hash
との整合性を崩し、結果としてチェーン全体の整合性が失われます。そのため、あるブロックを改ざんするためには、そのブロック以降のすべてのブロックのハッシュ値を再計算し、さらに新たなチェーンとしてネットワーク全体にブロードキャストして同期させる必要があります。しかし、この過程には膨大な計算リソースが必要となるため、現実的には事実上改ざんは不可能と言えます。
2-4 トランザクションの作成_発行(mint)
2-2 では台帳のデータ構造について確認しました。しかし、transaction は書き込むノードが情報を持っているわけではありません。このトランザクションはどのようにして生成されうのでしょうか。
例えば、あるブロックチェーンネットワークの台帳では、カードデータを管理しているとします。このとき、transaction に入るデータはカードの情報になります。
あるユーザーが新しいカードを作成するケースをみてみます。まず、あらかじめ定められたデータ形式にそって以下のようなデータを作成します。
{
"action": "mint",
"creator": "0xabc123...def456",
"token_id": "10002",
"metadata": {
"name": "Dragon Knight",
"attributes": {
"type": "knight",
"power": 250,
"rarity": "rare"
},
"image": "ipfs://QmTz...filehash"
},
"fee": 0.02
}
このデータがトランザクションとなります。トランザクションは、発行者の秘密鍵を使ってデジタル署名を行い、発行者によって正当に作成されたことを保証します。
ユーザーはトランザクションの作成後、ブロックチェーンネットワークのフルノードに対してトランザクションを送信します。トランザクションを受信したノードは、そのトランザクションをネットワーク全体にブロードキャストします。
各ノードは、受信したトランザクションを検証(署名が正しいか、データ形式が正しいかなど)し、有効であればトランザクションプール(未処理トランザクションの一時保管場所)に保存されます。この後、書き込み権限をもつノードが台帳に対して書き込みを行い、その後、書き込み結果をネットワーク全体に共有します。
このようにして、台帳の書き込みが行われます。
補足
- feeはガス代と呼ばれます。ガス代はが必要な理由として、マイナーへの報酬、スパムの防止、トランザクションの優先順位が挙げられます。
- 書き込むノードはガス代を報酬として得られます
- 新しいカードを作成して台帳に記載するすることを minting といいます
- 上記の例では台帳を管理するノードとトランザクションを生成するノード(ウォレット)が分離していますが、統合されている場合が一般的のようです
2-5 トランザクションの作成_移動(transfer)
2-4では発行の例を見てきました。次は移行の例を見ていきましょう。流れは発行とほとんどかわりません。
{
"action": "transfer",
"token_id": "10001",
"sender": "0xabc123...def456",
"receiver": "0x789abc...def123",
"fee": 0.01
}
transaction の内容が発行と少し異なります。この後は mint と同様に、transaction のフルノードへ送信、P2Pネットワークでの検証、トランザクションプールへの保存、書き込み権限を持つノードによる台帳への書き込みが行われます。
補足
- 特定の条件に基づいてトランザクションを自動的に作成・実行する仕組みとしてスマートコントラクト
2-6 スマートコントラクトによるトランザクションの作成
トランザクションは、ユーザー自身が作成することもありますが、実際にはスマートコントラクトと呼ばれる仕組みにを使ってトランサクションを作成・処理されることが一般的です。
スマートコントラクトは簡単にいうと、P2PネットワークにおけるAPIみたいなものです。スマートコントラクトのコードは、ブロックチェーンネットワーク上の各フルノードに保存されており、どのノードからでも同じ結果を得ることができます。
スマートコントラクトはP2Pネットワークによって使用する言語がことなります。例えば、EthereumではSolidityが使用されます。以下に、カードを発行するスマートコントラクトの例を示します。
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract MyCard is ERC721 {
uint256 public nextCardId; // 次に発行されるカードのID
constructor() ERC721("MyCard", "CARD") {} // コントラクト名とシンボルを変更
// 新しいカードを発行する関数
function mintCard(address to) public {
uint256 cardId = nextCardId; // 現在のカードIDを取得
nextCardId++; // 次回の発行に向けてカードIDを更新
_mint(to, cardId); // カードを指定アドレスに割り当て
}
// カードを転送する関数
function transferCard(address from, address to, uint256 cardId) public {
require(ownerOf(cardId) == from, "Sender is not the owner"); // 所有権の確認
_transfer(from, to, cardId); // カードの所有権を移転
}
}
ユーザーはスマートコントラクトを呼び出すためのトランザクションを作成します。そのトランザクションは以下のようなデータになります。
{
"sender": "0xCaller", // 関数を呼び出すユーザーのアドレス
"receiver": "0xSmartContract", // コントラクトのアドレス
"amount": 0, // スマートコントラクトへの送金額(通常0)
"fee": 0.01, // トランザクションのガス代
"data": "mintCard(address to=0xAlice)" // mintCard関数と引数
}
書き込み権限をもつノードはトランザクションを区別し、適切なスマートコントラクトの呼び出しを行います。トランザクションプールから取得した時点でスマートコントラクトの呼び出しが実行されます。
スマートコントラクトを持つブロックチェーンでは、通常、すべての参加者の状態も保存されています。これにより、台帳への書き込みと同時に状態の更新が行われます。ただし、状態はあくまでスナップショットとしてストレージに保持されるものであり、整合性の確認や改ざん防止は台帳の役割となります。
補足
- 台帳と同時にすべての参加者の状態を保存する設計は、アカウントモデルと呼ばれます
2-7 アセットの保存先
トランザクションに画像のそのものの情報は持たず、アセットの保存先の情報のみ記載します。
画像、動画などのアセットは通常、同じくP2Pネットワークを利用した分散ストレージや単にS3やGCSのようなクラウドストレージに保存されます。分散ストレージの仕組みはざっくり説明すると、画像ファイルを分割した上で、それぞれ復元可能な形でP2Pネットワークの各ノードが保有し、リクエストが来たらデータを保有するノードが送信します。
代表的な分散ストレージとしてIPFS、Arweave があります。これらを利用するためにはそれぞれのネットワークに参加する必要がありますが、その方法としてはノードを自前で構築するか、ノードを提供しているSaaSサービスを利用する(Pinata、Infura)のが一般的なようです。
3章 ブロックチェーンの活用
ここまでの章で、トランザクションデータを作成、トランザクションの検証、トランザクションんプールへ滞留、書き込み権限を持つノードによる台帳への書き込み(状態の更新)、の一連のプロセスがブロックチェーン上のエコシステムと理解できました。最後に、ブロックチェーン活用の具体例をみて終わります。
3-1 ブロックチェーン活用の具体例
いまでは様々なブロックチェーンネットワークが存在し、それぞれのネットワークではコンセンサスアルゴリズムやトランザクションの検証方法、ガス代が異なります。ブロックチェーンを使用したサービスを作成する際には適切にどのネットワークを使用するかを検討する必要があります。
3-2 仮想通貨
Bitcoin
概要
- ビットコイン(Bitcoin)は、最初の仮想通貨であり、分散型P2Pネットワーク上で運用され、中央の管理者を必要とせずに価値の保存や送金を可能にします。
ネットワーク
- 利用ネットワーク: ビットコイン独自のブロックチェーンネットワーク。完全に分散化された公開型(パブリック)ネットワークで、誰でも参加可能です。
- スマートコントラクトの有無:スマートコントラクト機能はありません(送金専用)
- コンセンサスアルゴリズム:Proof of Work(PoW)。膨大な計算リソースを利用し、ブロックの追加を競争する仕組み。
Ethereum
概要
- Ethereumは、スマートコントラクト機能を備えた汎用ブロックチェーンプラットフォームで、仮想通貨や分散型アプリケーションの基盤として機能します。
ネットワーク
- 利用ネットワーク: Ethereumメインネット。Ethereum Virtual Machine(EVM)をベースにした世界最大の汎用ブロックチェーンプラットフォーム。
- スマートコントラクトの有無:あり(スマートコントラクトの実行を主目的とするプラットフォーム)。
- コンセンサスアルゴリズム:Proof of Stake(PoS)(Ethereum 2.0以降)。
3-3 ゲーム
NBA Top Shot
概要
- NBA Top Shotは、試合のハイライト映像をNFTとして売買・コレクションできるデジタルカードゲームです。
ネットワーク
- 利用ネットワーク: Flowブロックチェーン。Dapper Labsが開発したゲームやエンタメ向けのブロックチェーンプラットフォーム。
- スマートコントラクトの有無:あり(NFT発行・取引管理に利用)。
- コンセンサスアルゴリズム:Flowブロックチェーン(Delegated Proof of Stake: DPoS)。
3-4 トレーサビリティ
IBM Food Trust
概要
- 食品の生産から消費者に届くまでの過程をブロックチェーンで記録し、透明性を高める。消費者はQRコードなどで生産履歴を確認可能。
ネットワーク
- 利用ネットワーク: Hyperledger Fabricを基盤とした許可型(プライベート)ネットワーク。
- スマートコントラクトの有無:あり(食品移動や加工履歴を記録)。
- コンセンサスアルゴリズム:PBFT(Hyperledger Fabricの許可型ネットワーク)。
3-5 真贋判定
Aura Blockchain(LVMH)
概要
- 高級ブランドの商品にデジタル証明書を付与し、消費者が真贋を確認できるプラットフォーム。中古市場でも信頼性を保証。
ネットワーク
- 利用ネットワーク: Quorum。Ethereumベースの許可型ブロックチェーンで、プライベートな環境で動作します。
- スマートコントラクトの有無:あり(証明書の発行と所有権管理)。
- コンセンサスアルゴリズム:Quorum(Ethereumベースの許可型ネットワーク)。
おわりに
この記事を書いてブロックチェーンについて理解が進みました。少しでもお役に立てると幸いです...!!
(もう少しわかりやすくするために図を用意しようと思います)
Discussion