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

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

前回の投稿でブロックチェーンの基本9ステップについて簡単に説明しました。
今回はその中の2番目のステップで使われるトランザクションについて、ソフトウエアロジックを中心になるべくわかりやすく説明していきます。

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

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

ブロックチェーン・トランサクションとは

トランザクションとは、参加者間で行われる価値の移転すなわち「取引」を所定のルールで記述したデータです。

通常、1つ以上のインプット(支払元)と1つ以上のアウトプット(支払先)、及びそれらの取引の正当性を自律的に証明するための情報(スクリプト)などから構成されます。

支払元(原資)と支払先(原資の移転先)が記述さている様子が、簿記の借方・貸方と似ている(実際には少し違う)ことから台帳と呼ばれることもあります。
更に、ブロックチェーン全体としてはこれらの全ての取引データが、各ノードに分散して記録されていることから分散型台帳技術、あるいはDLT(Distributed Ledger Technology)と呼ばれることがあります。

トランザクションはブロックチェーンを支える重要な要素技術の一つなので、以前の稿で(※1)で使用した全体図「ブロックチェーンの基本9ステップ」をもとに、そのライフサイクルを直感的に理解しておきましょう。
(※1「ブロックチェーンとは」はこちらから

  1. 口座(アドレス)の作成
  2. お金の支払いを定型化されたトランザクションに記述する
  3. ネットワークに伝播
  4. 審査終了
  5. トランザクションプールに蓄積
  6. マイナーがナンスを発見し
  7. ブロックを生成
  8. 生成したブロックをネットワークに伝播
  9. ブロックチェーン確定

これらの流れは、弊社ライトニングトークALTで説明した時の映像が分かりやすいと思いますので掲載しておきます。

 

トランザクションを理解するための基礎知識

トランザクションを理解せずしてブロックチェーンを理解できず、とよく言われますが、その理由は、トランザクションがブロックチェーンの柱となる技術だからです。

弊社で行われたブロックチェーンのライトニングトークALT(ARP lightning Talk)でも何回かに分けて説明しました(このブログでもその一部のコンテンツを流用します)。

その経験を踏まえて先ずはいくつかの重要な基本的な技術を学んでいきましょう。

UTXOとは

ビットコインなどのブロックチェーンにおいて、トランザクションの仕組みを理解するためには、UTXOという多くの方にとって聞きなれない仕組みを理解する必要があります。
UTXOとは、「Unspent Transaction Output」の略で、日本語では「未使用残高」などと呼ばれています。
結論から言うと、トランザクションのアウトプット領域に記載されている金額が未使用の場合、それがUTXOとなります。
UTXOは全ての参加者により追跡可能であり、UTXOプールという名前のデータベースに保存されています。

ちょっとこれではピンときませんよね。
そこで、一般の銀行の口座管理で使用されている「残高」というものと比較してみましょう。

残高管理の考え方(図)残高管理の考え方

 

一般的な銀行のデータベースでは、トランザクション(振込、送金、引落し等の取引)が実行されるたびに口座ごとの残高が更新されていきます(図の左側)。
これを「アカウントベース方式」と呼んだりしてます。

これに対してビットコインのブロックチェーン(※)では、トランザクションが発生するたびに残高を更新する」という概念はありません。
(※例えばイーサリアムには残高という考え方があります)

ウォレットを利用していると残高が表示されますが、あれはその時点で特定のアドレスに対応するUTXOを探して集計を行っているのです。
つまり、利用者のビットコインは、アドレスごとに残高として記録されているわけではなく、いくつもの取引データの中からUTXOとして散らばっているものをかき集めて残高を計算しているのです。

なぜこのような一見すると面倒な仕組みになっているのでしょうか?
それはブロックチェーンのデータが公開されていることに関係しています。
誰でも取引情報を参照できるため(そこにはそれなりの努力とスキルが必要ですが)、以下の理由があるといわれており、この考え方はブロックチェーンの随所にみられます。

  1. できるだけ匿名性を高くしたい(他人の取引き状況が分かりにくい)
  2. セキュリティ上のリスクを軽減したい(残高の書き換えにくさ)
  3. 二重支払を防止したい(各UTXOにはロック機能(※)をセット)

(※)UTXOには送金された人しか使えないようロッキングスクリプト(ScriptPubkey)と呼ばれるロック機能があるため、第三者には使用できない仕組みが備わってます。

ここで、サトシナカモトの原点と通貨の3条件に関して、弊社ライトニングトークでの1コマをご紹介します。

 

電子署名とは

電子署名とは、電子データが本人が作成したものであること、改ざんされてないことを保証する仕組みです。

技術的には公開鍵/秘密鍵とハッシュ関数により実現しており、eメール送信時、ホームページの参照、e文書など、多くの場面で使用されてます。

大まかな流れは以下の通りです。

送信者は

  1. 原文をハッシュ化する
  2. ハッシュ値を本人の秘密鍵で暗号化して電子署名作成する
  3. 原文と電子署名を同封して送信する

受信者は

  1. 送信者の公開鍵で電子署名を復号化してハッシュ値を取り出す
  2. 送付された原文をハッシュ化する
  3. 復号化したハッシュ値と原文から算出したハッシュ値が一致することを確認する

電子署名に関しては多くのサイトで紹介されていますので、詳細はそちらをご参照ください。
そのいくつかをリストアップしておきます。

トランザクションを直感しよう

さて、基礎知識がついたところで、先ずはトランザクションを直感的にイメージしてみましょう。

トランザクションは資金の移動を記述するための仕組みであり、主に送金元情報であるINPUTと送金先情報であるOUTPUTによって構成されます。
下の図は、七海君が五条さんに300円を支払うケースを想定してます。

フクロウ君
フクロウ君
ここでは正確さより分かりやすさを優先しておる

 

トランザクションのイメージ(図)トランザクションのイメージ

INPUTについて

INPUTには送金するための原資を記載しますが、そこに使われるのはUTXOのみであり、OUTPUTに記載した送金額より大きくなるよう1つ以上選択する必要があります。

つまりINPUTに記載するUTXO(実際にはUTXOに対するポインタ(※))は、自分宛てのOUTPUTの中で未使用のものを選択します。
そういう意味では一連のトランザクションというのは、ネットワークのように連鎖していきます。
(※)ここでいうポインタはトランザクションIDとインデックス番号で構成されます。

更に重要なのが、送金に使用するUTXOが本当に自分あてのものかを証明するために必要な自分自身の公開鍵、およびトランサクションの電子署名を記載します。
この情報をスクリプトと呼ばれる簡易なプログラムで記述するので、アンロッキングスクリプト(ScriptSig)と呼ばれてます。

OUTPUTについて

OUTPUTには送金先の情報が記載されます。
送金先はINPUTに記載したUTXOの総額より小さければ、複数の送金先を記載することができます。

一つの送金先には以下の2つの情報を記載することになってます。

  1. 送金額:satoshiという単位(1億分の1ビットコイン)で記載する
  2. 宛先:実際には送金額を使用することができる条件をスクリプトで記載する

宛先として記載するスクリプトとは、宛先人しか使えないようロックするという意味で、ロッキングスクリプト(ScriptPubKey)と呼ばれます。

OUTPUTに記載されたロッキングスクリプトは、のちにこのOUTPUTがUTXOとして使用されることになる際に、INPUTに併記されるアンロッキングスクリプトで解除で来た時、送金する際の原資として有効になります。このあたりは少しわかりにくいので、別稿にて詳しく説明する予定です。

手数料(ガス代)

ブロックチェーンでは、その信頼性を担保するため(コンセンサスアルゴリズム)、マイニングという作業を行うマイナーがいます。

このマイナーさんにはマイニングに成功した時には高額の報酬が支払われますが、それ以外にもトランザクションごとにマイナーに手数料を支払うことになってます。

その理由は、

  1. マイナーがトランザクションを処理するモチベーションとなる
  2. トランザクションをむやみに作成するSPAM攻撃を抑制できる
  3. 手数料の高いものから優先的に処理される

上記③に関して補足をしていると、これによりトランザクションの作成者にとっては、緊急度により手数料の高さに選択肢ができます。

おつり

トランザクションのINPUTに記載された額は、手数料を含めたOUTPUTの額と同じかそれより高くなるよう設定します。

その結果、おつりが出ることがありますが、その場合、トランザクションの作成者に対して新たに新しいアドレス(実際には公開鍵ハッシュ)を生成して返金する仕組みになってます。

トランザクションのフォーマット(bitcoin)

ビットコインのトランザクションは以下のフォーマットになってます。
(出典は、bitcoin wiki

Field Description Size
Version no currently 1 4 bytes
Flag If present, always 0001, and indicates the presence of witness data optional 2 byte array
In-counter positive integer VI = VarInt 1 – 9 bytes
list of inputs the first input of the first transaction is also called “coinbase” (its content was ignored in earlier versions) <in-counter>-many inputs
Out-counter positive integer VI = VarInt 1 – 9 bytes
list of outputs the outputs of the first transaction spend the mined bitcoins for the block <out-counter>-many outputs
Witnesses A list of witnesses, 1 for each input, omitted if flag above is missing variable, see Segregated_Witness
lock_time if non-zero and sequence numbers are < 0xFFFFFFFF: block height or timestamp when transaction is final 4 bytes

 

トランザクション作成過程をイメージしよう

これまで説明してきたことをベースに実際にトランザクションを作成するときの流れをUTXOの動きを中心にまとめましょう。

  1. INPUTに自分が使えるUTXOのポインタ(トランザクションIDとインデックス)をセットする。
  2. OUTPUTに送金先のアドレス(公開鍵ハッシュ)と送金額をセットする。
  3. マイナーさんへの手数料(ガス代)をセットする。
  4. おつりを返金するためのアドレス(公開鍵ハッシュ)と返金額をセットする。 おつりは、後に送金者が保有するUTXOとなる。
  5. INPUTに、トランザクション(ScriptSigを除く)の電子署名と送金者の公開鍵から構成されるアンロッキングスクリプトをセットする。

いかがでしょうか?
いまいちわかりずらいかもしれませんので、弊社のライトニングトークALTで使用したビデオを紹介します。
このビデオを見てイメージトレーニングをしておいてください。

内容は、冒頭で紹介した虎杖君が五条さんに300円を払う場合のトランザクションの手順です。
※)OUTPUTに記載されるはずのロッキングスクリプトは図が複雑になるため省略してます。

 

 

(アーパボー)