ARPABLE
アープらしいエンジニア、それを称賛する言葉・・・アーパボー!
ブロックチェーン

ブロックチェーントランザクションとは(2)

ブロックチェーン・トランザクションとは(1)ではトランザクションに関する基礎知識を説明した上でトランザクションのロジックを直感的にしてもらい、その後実際のトランザクションを作成する過程をイメージするための映像を紹介しました。

今回はそれをもとにブロックチェーントランザクションの山場といえる以下の点に関してそのロジックを直感的にイメージできるよう説明していきたいとおもいます。

  • 各トランザクションがつながりあう仕組み
  • 2重支払防止を実現するための仕組み

(※)前回同様、ここで使用した資料や動画は2020年~2021年に社内で行われたALT(アープライトニングトーク)で使われたものを適宜流用します。

(※)説明は2008年「サトシ・ナカモト」が発表したビットコインに関する論文をベースに説明していきます。

トランザクションはどのように生成されるのか?

前回の稿、トランザクション(1)の最後に1つのトランザクションの作成イメージを映像でご紹介しました。

ここでは1つ目のトランザクションがそれ以降どのようにつながりあっているのかを、図を使用してマンガ風に説明していきます。

UTXO、公開鍵、秘密鍵、電子署名を理解していることを前提にしてますが、よくわからない人はトランザクション(1)に戻って学習して下さい。

ここで用いる画像には以下のアイコンが使用されてます。

作成されたトランザクション図

この図は、虎杖君が五条さんに70BTCを支払うときに作成したトランザクションです。
(※)分かりやすさを優先してここではガス代(手数料)を省略してます。

左上にはUTXOプールがありますが、これはOUTPUTの中で未使用のもの、つまりそこに書かれた額は利用できるということでしたね。

この図では虎杖君が使用できるUTXOのみを記載してます。

五条さんに70BTC支払うわけですから、ガス代も考慮するとそれよりも大きいUTXOを使用する必要がありますね。
おつりが出た時には虎杖君への新しいアドレスが生成され戻ってくることになってました。
この図では、たまたまUTXOプールに100BTCのUTXOがあるので、これをインプットにセットしました。

OUTPUTには五条さんへの支払いを実現する為、「五条さん宛てへ70BTC」のデータユニット(この時点ではUTXO候補)をセットしました。

データユニットとは
ここでデータユニットという聞きなれない言葉が出てきました。
独自に命名したものなので定義を明確にしておきます。
これは「UTXO候補」の事であり、トランザクションの作成からブロックに取り込まれ承認されるまでの期間、つまりトランザクション未承認期間にOUTPUT内に作成された以下の一連のデータのことで、ブロックが承認された後、UTXOになりうるものをここではデータユニットと呼んでます。
{(誰にいくら送金する) + ( ScriptPubkey ) }

※)「誰に」つまりアドレスはScriptPubkeyに記載された公開鍵ハッシュから生成することができます。

そしてお釣りを虎杖君に戻すため、30BTCのデータユニット(この時点ではUTXO候補、以降省略)が生成されてます。

このトランザクションでは1つのINPUTに対してOUTPUTに2つのデータユニットが設定されてます。

それぞれのデータユニットは将来UTXOとして使用されるときの使用許可条件であるロッキングスクリプトを設定する必要がありましたね。
そこでOUTPUT領域の最下部には、「Outputのロック機構」がそれぞれのデータユニット用に2つ設定されてます(図では重なっている状態で表してます)

スクリプトといえば、INPUT領域にもアンロッキングスクリプト(Scriptsig)が設定されることになってました。
その為、虎杖君が自分宛てのUTXO(この図では100BTC)を使用するために自分自身の公開鍵をセットしてます。

更にこのトランザクションの全体からロッキングスクリプトを除いた領域全体に対して、虎杖君の秘密鍵で電子署名を生成したものもセットされてます。

この電子署名により以下の2点が保証されてます。

  1. トランザクションを作成したのは間違いなく虎杖君自身である
  2. 改ざんもされてない

トランザクションの流れをイメージしよう

虎杖君が五条さんに70BTCを支払うためのトランザクションが無事に完成しましたので、ここから更に五条さんが受け取った70BTCを使用してパンダに10BTCを支払い虎杖君も更にパンダに50BTC支払うというトランザクションの流れを見てみましょう。

流れを見るには映像で、ということで弊社で行われたALT(アープライトニングトーク)で使用したものから関連する部分を抜き出しましたのでご覧ください。

 

2重支払防止を実現するための仕組み

さてトランザクションの説明もいよいよ佳境に入ってきました。

以前の稿「トランザクション(1)」で通貨の3条件を説明しましたので詳細はそちらを参考にしてもらいたいのですが、ポイントは以下の3点でした。

  1. 偽造防止
  2. 信頼性の担保
  3. 二重支払防止

これまでの稿で上記❶と❷は説明しておりますのでここから❸を説明したいともいます。

これはSatoshi Nakamotoも論文の中で”double spending problem”を言及しております。

ビットコインのトランザクションにはもともとIDを書き換えられるリスク(トランザクション展性)があり、それがSegWITを導入する一因といわれてますが、この点は別稿に譲りたいと思います。

ここではこれまで説明したトランザクション間の流れに対して2重支払いを防止するためにはどこを守る必要があるのかを明確にしたうえで、どのような仕掛けで実現しているかをトランザクションスクリプトをベースに分かりやすく説明していきます。

2重支払いを防止するために守るべきポイント

この稿では、「トランザクションの流れをイメージしよう」のところでトランザクション間には繋がりがあることが分かりましたね。

その中で二重支払を防止するにはどこを守ればよいのかを明確にしていきましょう。

五条さんがパンダに10BTCを支払うときに虎杖君からもらった70BTCを使う場面がありました。
そしてパンダに送金するためにINPUTに使用する70BTCは、虎杖君から送金を受けたものでした。

つまり、以下の2点が証明できれば2重支払の防止が可能となるわけですね。

❶虎杖君が五条さんに送金するために作成したトランザクション(TxID-1000)のOUTPUTにセットされたデータユニットが五条さんのUTXOになっていること。

❷五条さんがパンダに送金するためのトランザクション(TxID-1001)は本当に五条さんが作成したものであること。

トランザクションスクリプト

これを誰もが検証するための仕組みがトランザクションスクリプトです。

五条さんが使用するのは虎杖君が作成したトランザクションTxID:1000のOUTPUTに記載されている「五条に70」の情報が書いてあるUTXOです。

このUTXOにはScriptPubKeyと呼ばれるスクリプトが記載されており、五条さんだけが使えるようロックされているので別名ロッキングスクリプトと呼ばれます。

また五条さんが作成したトランザクションTxID:1001のINPUTに、先ほどのUTXOをポインタ形式(TxID+インデックス番号)で指定します。
更に、五条さんの公開鍵と電子署名を記載したScriptSigと呼ばれるスクリプトをします。これを、ロックされたUTXOを解除するのでアンロッキングスクリプトと呼ばれます。

これらのスクリプトが実際にどのように機能するかは後ほど動画でご紹介しますが、ここではまずどのように検証するのかのロジックを明確にしておきましょう。

2重支払防止のロジックとは

2重支払の防止のためには以下の2点を証明する必要があることは既に説明しました。

❶虎杖君が五条さんに送金するために作成したトランザクション(TxID-1000)のOUTPUTにセットされたデータユニットが五条さんのUTXOになっていること。

❷五条さんがパンダに送金するためのトランザクション(TxID-1001)は本当に五条さんが作成したものであること。

ブロックチェーンでは、これを3ステップのロジックで証明します。

  1. INPUTに記載するUTXOが実際に存在すること
  2. それが五条さん宛てのものであること(公開鍵が一致すること)
  3. トランザクションは本当に五条さんが作成し改ざんされてないこと

このロジックは映像で見た方が分かりやすいので、弊社で行われたALT(アープライトニングトーク)の1シーンである「五条さんの主張を検証する3ステップ」をご覧ください。

トランザクションスクリプトとは

ようやくここまで来ましたね。
トランザクションスクリプトとは、トランザクションを中央の権威によらず自動的に検証することにより2重支払防止が可能なキーとなるテクノロジーです。

つまりトランザクションに不正がないか検証するためのプログラムで、トランザクションが本当に正しい送信者からのインプットであり、正しい送信先にアウトプットできるのかをチェックすることができるということですね。

このスクリプトはプログラム言語ではありますが非常に軽量で、オペコード(≒機械語)とも呼ばれることもあります。

トランザクションスクリプトの特徴

  • ビットコイン専用の言語
  • シンプルな文法
    チューリング不完全、つまり分岐、ループがない(DoS系攻撃を受けにくい)
  • ステートレス
    状態依存がなく、それぞれのUTXO単独で処理が完結する。
  • スタックマシン上で動作する
  • 逆ポーランド記法(数値が前で演算子は後に表記)

トランザクションスクリプトは全ての参加者が検証することを前提にしており、その結果が正しいトランザクションのみがトランザクションプールに蓄積され、後にマイニングに成功した時にブロックに取り込まれます。

トランザクションスクリプトの種類

ビットコインのトランザクションスクリプトは現在以下の5種類存在しています。

  • P2PKH(Pay to Public Key Hash)
  • P2PK(Pay to Public Key)
  • マルチシグネチャ(Multi-Signature)
  • P2SH(Pay to Script Hash)
  • OP_RETURN(Data Output)

ここでは一般的に使用されているP2PKH(Pay-to-Public-Key-Hash)のロジックをベースに説明を進めます。

トランザクションスクリプトによる検証

スクリプトに注目して実際にトランザクションをどのように検証していくのかを見てみましょう。

トランザクションのOUTPUTにはUTXOの使用をロックするためのロッキングスクリプト(ScriptPubkey)がセットされ、そのUTXOを利用したいトランザクションのINPUTにはScriptSig、すなわち使用者による電子署名と公開鍵を含むアンロッキングスクリプトがセットされている。

上記のスクリプトを実行順に並べたのが以下の表です。
検証するためにはINPUTに記載されているScriptSigと使用したいUTXOに記載されたScriptPubkeyという2種類のスクリプトをスタックマシン上で連続して実行していくことになります。

スタックマシンとは
データをちょうど積み木のように積み上げていくデータ構造をスタックと呼び、それを利用することにより後入れ先出し法(LIFO:Last In First Out)に従い実行していく、つまり積んだのが新しい順に実行する仕組みのことです。
実際の動きは次の映像で確認することができます。

スクリプトの欄にはデータまたはオペコードが、その右には処理内容、最も右にある欄はScriptSig(Sigと略)かScriptPubkey(Pubkeyと略)のどちらにあるかを記載している。

スクリプト 処理内容 場所
デジタル署名 Push Sig
公開鍵 Push Sig
OP_DUP 先頭をpop、複製してPush Pubkey
OP_HASH160 先頭をpop、RIPEMD160(ハッシュ化)してPush Pubkey
公開鍵ハッシュ
(≒アドレス)
Push Pubkey
OP_EQUALVERIFY 2要素をPopし等しければTrue Pubkey
OP_CHECKSIG 2要素をPop、トランザクションをSha256でWハッシュ、
電子署名を公開鍵で復号化して一致したらTrue
Pubkey

これがスタックマシン上でどのように実行されるのかは動画で見た方が分かりやすいので弊社で開催されたALT(アープライトニングトーク)で使用した映像からピンポイントで抜き出したものを紹介しましょう。

 

まとめ

いかがだったでしょうか?

個人的にはブロックチェーン(ビットコインベース)の中で最も分かりにくいところだったのでそのロジックを丁寧に説明してみました。

先ずはどのようにトランザクションを作成するのかを明確にした後、トランザクションどおし繋がりあうことにより、その正当性が検証される流れをイメージしました。

その正当性とは通貨の3条件の一つであり、Satoshi Nakamoto自身も論文の中で”Double Spending Problem”として取り上げている「2重支払防止」に注目し、どのように実現するのかのロジックを明確にしました。

そしてそのロジックを実際に実行する手段としてトランザクションスクリプトがあり、それらがどのような動きで正当性を検証しているのかを直感的にイメージするために映像で確認しました。

Satoshi Nakamotoが提案したブロックチェーンの真髄ともいえるトランザクションスクリプトを理解することは大変大きな意味があると思います。

次の稿では最後の大物であるマイニングについて書いてみたいと思います。

(アーパボー)