ビットコインの基礎知識(7) - ノード同士の通知と検証

ビットコインのノードは目的別に3種類あります。

1. SPV(Simplified Payment Verification)ノード

SPVノードは、ビットコイン利用者のインターフェースとなるノードです。

スマホやPCにウォレット・アプリを入れることでこのノードになります。

利用者の入力した取引データの正当性検証を行い、これをビットコインネットワークに送信します。

2. マイニング・ノード

マイニング・ノードはその名の通りマイニング報酬を得ることを目的としたノードです。

新規ブロックを効率よく生成するため、GPUやASICといった超高速並列計算が可能なハードウェア上で実行します。

3. フル・ノード

フル・ノードはビットコイン・ネットワークの維持運営で中心的な役割を持つノードです。

原始以来の全てのブロックチェーンを保存しています。

このノードの目的は、全ての取引データの正当性検証と二重払いデータの検証を行うことです。

ノード同士の通知と検証

利用者がウォレット(SPVノード)を使ってビットコインを誰かに送金すると、ビットコイン・ネットワークに取引データがブロードキャストされ、フルノードやマイニング・ノードがこれを受信し、正当性検証を実施します。

PoWが始まりブロックを書き込む権利を得たマイニング・ノードは、自身が生成したブロックをブロードキャストでネットワークに通知し、全ノードがこれを受信します。

ブロックを受信した各ノードは、正当性検証を実施後に自身の台帳にブロックを追記し、chainstate(取引データから生成されたデータベース)内のUTXOを更新します。

ビットコインの基礎知識(6) - 新規ブロックの生成と承認

新規ブロックの生成と承認

マイナーがビットコインからマイニング報酬を得る仕組みがマイニングです。

マイニングは10分ごとに行われ、これに参加したマイナーの中からPoW(Proof of Work)と呼ばれる一種のくじ引きで当たりを引いたノードにマイニング報酬が発行されます。

それと同時に世界中で行われた複数の取引データブロックとして台帳に書き込まれます。

生成と承認の流れ

処理の流れは下記のようになります。

  1. 利用者が送金処理を行う。
  2. 10分経過後、複数の送金履歴からいくつかの取引データをマイナーが選びます。
  3. 取引データのハッシュ値を作成します。
  4. 前のブロック・ヘッダのハッシュ値と3で作成した取引データのハッシュ値にノンスと呼ばれるビットを組み合わせ、ハッシュ関数にかけることでハッシュ値を作成します。
  5. ハッシュの先頭部に決められた数のゼロ並びが現れるまで4を繰り返します。
  6. 2で選択した取引データに自分あてのマイニング報酬と取引データに含まれる手数料を加え、自身の台帳にブロック・ヘッダと取引データからなるブロック情報を書き込みます。
  7. 他ノードに対し、選択した取引データと発見したノンスをブロードキャストします。
  8. 受信したノードは7の情報よりハッシュ値をとることでゼロ並びが出現することを確認し、正しいノンスであると判定すると、ブロックを生成し自身の台帳に追加します。

以上です。

ビットコインの基礎知識(5) - 台帳に登録されるデータの中身

マイニングによって台帳に書きこまれる主なデータは、マイナーによって選択された複数の取引データからなるブロックと、取引データから算出された利用者ごとの残高を示すUTXO(Unspent Transaction Output)です。

ブロックは複数存在し、ビットコインの創生時に作成されたジェネシスブロックから最新のブロックまでを作成順に追記する形で保存されます。

ブロックの中身

個々のブロックは次の要素で構成されています。

フィールド名サイズ(byte)内容
ブロック・ヘッダ80このブロックの内容を示す様々なメタ・データ
ブロック・サイズ4ブロック・サイズ
取引カウンタ1~9(可変)格納されている取引データの数
取引データ可変ビットコインの送受信データ

ブロック・ヘッダの中身

ブロック・ヘッダは次の要素で構成されています。

フィールド名サイズ(byte)内容
バージョン4利用しているビットコインのバージョン数
前のブロックのハッシュ値32前のブロック中のブロック・ヘッダのハッシュ値
マークル・ルート32格納している取引データのハッシュ値
タイムスタンプ4ブロックが生成された大まかな時刻
ディフィカルティ4ブロック生成の難易度
ノンス4PoWの当たりくじ

ブロック・ヘッダには3つの主要なメタデータが格納されています。

  • 前のブロック・ヘッダのハッシュ値
    先頭の文字に連続したゼロが現れます。
    このハッシュ値を通じてブロックチェーンは原始のブロックから最新のブロックまでが数珠つなぎで関係付けが行われます。
  • マークル・ルート(Merkle Root)
    ブロックに格納する取引データを多段階でハッシュしたものとなります。
    このマークル・ルートを通じて取引データとブロック・ヘッダの関係付けが行われます。
  • ノンス(Nonce)
    ノンスはマイニング報酬を得るために行われるPoW(Proof of Works)の当たりくじです。
    これを含めたブロック・ヘッダから、次のブロックのハッシュ値を計算します。

ビットコインの基礎知識(4) - ビットコインの流れ

ブロックチェーン上でビットコインをやり取りする時には次のようなフローになります。

1. トランザクションの生成

ウォレット・アプリを操作することで、受信者のアドレスと送信者の秘密鍵で作成した署名を付与したトランザクションを生成します。

2. ノードに送信

生成したトランザクションを、ブロックチェーン・ネットワークへの参加端末(ノード)に送信します。

3. マイニング開始

トランザクションを受信した参加端末(ノード)は、トランザクションの正常性を検証後、前のブロックを生成後10分経過するとマイニングを開始します。

4. ブロック生成とブロックのブロードキャスト

マイニングで正しいノンスを見つけたノードは、受信したトランザクションと自身へのマイニング報酬を示すトランザクションからブロックを生成し、自身の台帳に追加するとともに全ノードにブロックをブロードキャストで転送します。

5. 分散台帳の登録

各ノードは受信したブロックの正常性を検証後、それぞれが持つ分散元帳の最後に書き込みます。

以上です。

ビットコインの基礎知識(3) - 参加者

参加者

ビットコイン・ネットワークには特定の管理運営者や所有者はいません

世界中の開発者がビットコイン・プログラムを開発し、さまざまな目的を持つ参加者がこのプログラムをコンピュータ上で稼働させてノードとなり、これらをつなげあうことでネットワークが構築されています。

参加者は次のように4分類できます。

  • 利用者
  • 交換所、取引所
  • マイナー(採掘者)
  • コア・プログラムの開発者

マイナーはビットコインをマイニング(採掘)して報酬を得ることを目的としています。(ビットコイン・ネットワークはシステムの維持運営への協力に対する報酬をマイナーに発行します。)

マイナーは報酬として得たビットコインを通貨取引所や交換所を通じて、個人の利用者との間で法定通貨と売買することで流通が行われます。

ビットコインの基礎知識(2) - 発行上限

発行上限は2100万BTC

ビットコインには中央銀行のような管理組織はありません

このためマイニングで無限にビットコインが発行されると、ビットコイン自体の価値が低下するというインフレになります。

コア開発者はこれを防ぐため、2100万BTCを発行上限とし、半減期という仕組みで徐々に発行量を減らすプログラムを組み込みました。

具体的には4年ごとにマイニング報酬額を半分に減らすというもので、2140年頃に発行量はゼロとなるように作られています。

ビットコインの基礎知識(1)

ビットコインの実態は取引データの集合体

ビットコインの取引を行うためには、ウォレット・アプリを自身のパソコン・スマホ・タブレットに導入する必要があります。

このウォレットに誰かからビットコインを送金してもらうと、ウォレット上に自身が所有するビットコインの量(BTC)が表示されるようになります。

取引されたビットコインは、利用者同士のウォレット間で送受信された訳ではありません。

取引データはビットコイン・ネットワークと呼ばれる世界中にある何千台ものノードにブロードキャストされ、各ノードの中にある台帳に書き込まれます。

この台帳に書かれた取引データこそがビットコインの実態です。

全てのノードの台帳は常に同期されているため、ウォレットがどのノードに接続しても同じ取引データを参照でき、送金が行われるとそれを利用者は認識できます。

オープンソースのブロックチェーンを試す(6) - Ethereum(イーサリアム)のアカウント登録とマイニング

前回はUbuntuで、Ethereumの起動テストまでを行いました。

今回はアカウントの登録とマイニングを行います。

アカウントの登録

アカウントを登録するためにはpersonal.newAccountコマンドを使います。

コマンド入力後、パスフレーズを2回入力する必要がありますが、このパスフレーズは絶対に忘れないようにしてください。

パスフレーズを忘れた場合の救済措置は一切ありません

[コマンド]

1
personal.newAccount()

[実行結果]

途中実行ログが表示されてしまって少々見づらいですが、最終行に表示されている文字列がアカウントを表す情報となります。

ちなみに、eth.accountsコマンドを使うと、登録されているアカウントの一覧を表示することができます。

[コマンド]

1
eth.accounts

[実行結果]

マイニング

Ethereumでは何かを行うときに、ether(コイン、報酬)が必要となります。

理由は仲間内のブロックチェーンでも、チェーンがつながるためには複数ノードのよるマイニングが必要で、そのマイニングする動機づけとして報酬が必要だからです。

というわけで、下記コマンドを使ってマイニングを開始します。

[コマンド]

1
minert.start()

[実行結果]

マイニングを開始すると下記のようなログが表示されるようになります。

[実行結果]

  • Commit new mining work
    「新しいマイニング作業をコミットした(始まった)」・・・という意味でしょうか。
  • Successfully sealed new block
    「新しいブロックのシール貼りが成功した」・・・という意味でしょうか。
  • mined potential block
    「潜在的なブロックを採掘した」・・・という意味でしょうか。

マイニングしている雰囲気を感じてもらえたら十分かと思います。🙇‍♀️🙇‍♀️🙇‍♀️

マイニング状況の確認

しばらくマイニングを続けたら、一旦下記コマンドでマイニングを止めます。

[コマンド]

1
miner.stop()

[実行結果]

採掘されたブロック数を確認します。

[コマンド]

1
eth.blockNumber

[実行結果]

次に残高(マイニングして得た報酬)を確認します。

[コマンド]

1
eth.getBalance("アカウント")

[実行結果]

マイニングを行うことで、ブロックが生成され、マイニングを行ったアカウントに対して報酬(ether)を入手できることが確認できました。

オープンソースのブロックチェーンを試す(5) - Ethereum(イーサリアム)の起動2回目

前回はWSL上で、Ethereumの起動テストを行いまして失敗しました。

調べたところWSLだとListen設定ができないとのことで、WindowsにVirtualBoxをインストールし、ゲストOSとしてUbuntu20.04を設定し、再度Ethereumの起動テストを行いました。

さらに、これまでWSL上で実行してきた手順オープンソースのブロックチェーンを試す(1)~(3)をやり直しました。

以下はその続きとなります。

ジェネシス・ブロックの準備

まず、Ethereum起動の前準備としてジェネシス・ブロックを用意します。

[ジェネシス・ブロック genblock.json]

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"config": {
"chainId": 1100
},
"nonce": "0x0000000000000033",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x8000000",
"difficulty": "0x100",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {}
}

環境の初期化

次に下記のコマンドを実行し、環境の初期化を行います。

datadirオプションにはデータを保存するディレクトリを指定します。

initには作成したジェネシス・ブロック(genblock.json)を指定します。

[Ethereum起動コマンド]

1
geth --datadir ./data init ./genblock.json

[実行結果]

Ethereumの起動

初期化が完了したら、いよいよEthereumの起動を行います。

下記コマンドを実行します。

なおnetworkidオプションには、genblock.jsonのchainIdで設定した値と同じものを指定します。

[Ethereum起動コマンド]

1
geth --networkid "1100" --datadir ./data  console

[実行結果]

一部エラーは出ていますが、起動自体はできているようです。

次回は、アカウントの登録とマイニングを行ってみます。

オープンソースのブロックチェーンを試す(4) - Ethereum(イーサリアム)の起動

今回はEthereumの起動を行います。

ジェネシス・ブロックの準備

まずは、Ethereum起動の前準備としてジェネシス・ブロックを用意する必要があります。

[ジェネシス・ブロック genblock.json]

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"config": {
"chainId": 1100
},
"nonce": "0x0000000000000033",
"timestamp": "0x0",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit": "0x8000000",
"difficulty": "0x100",
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"coinbase": "0x3333333333333333333333333333333333333333",
"alloc": {}
}

環境の初期化

次に下記のコマンドを実行し、環境の初期化を行います。

datadirオプションにはデータを保存するディレクトリを指定します。

initには作成したジェネシス・ブロック(genblock.json)を指定します。

[Ethereum初期化コマンド]

1
geth --datadir ./data init ./genblock.json

[実行結果]

Ethereumの起動

初期化が完了したら、いよいよEthereumの起動を行います。

下記コマンドを実行します。

なおnetworkidオプションには、genblock.jsonのchainIdで設定した値と同じものを指定します。

[Ethereum起動コマンド]

1
geth --networkid "1100" --datadir ./data  console

[実行結果]

致命的なエラーとなり、うまく起動できませんでした。

調べたところWSL環境ではソケットのListenができないために、Ethereumが起動できないようです😢

次回は、WSLではなくLinux環境を構築し、再びEthereum環境の起動をトライします。


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×