3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Bitcoin Coreを触りながらBitcoinについて理解する - その2(BTCの送受について)

Posted at

前回
Bitcoin Coreを触りながらBitcoinについて理解する - その1(構築~アドレス生成まで)
からの続きです。

7.UTXOとトランザクションスクリプト

7-1.『BTCを送付する』ということ

前回、ビットコインアドレスを指定してBTCを送付することができるという概念について学んだ。今回はそれを具体的にどのようにブロックチェーン上で実現しているのか見ていきたい。

実際にトランザクションをウォッチしながら考えてみた。
適当にトランザクションを一つ取り出してみる。下記に表示しているのはblock height=123456ブロックのindex=1(上から2番目)のトランザクションだ。(適当に選んだだけなので他意はない)

height=123456,index=1のトランザクション
$ ./gettx.sh e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4
{
  "txid": "e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4",
  "hash": "e3d0425ab346dd5b76f44c222a4bb5d16640a4247050ef82462ab17e229c83b4",
  "version": 1,
  "size": 258,
  "vsize": 258,
  "weight": 1032,
  "locktime": 0,
  "vin": [
    {
      "txid": "4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54",
      "vout": 1,
      "scriptSig": {
        "asm": "3045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c[ALL] 0449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e",
        "hex": "483045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c01410449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 43.61000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 6c8de651f8b92f87ff43fb9732babec784bdb6f5 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9146c8de651f8b92f87ff43fb9732babec784bdb6f588ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1Atyy5h4SSdqWRuS8pzxgTb4bMe7ZpdunP"
        ]
      }
    },
    {
      "value": 6.39000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 4f006767feebf6438aaf51ef86ae4286a1c571b9 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9144f006767feebf6438aaf51ef86ae4286a1c571b988ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "18CisDmjM1MmM1MjtqUHPgmoLhZcSJJTKD"
        ]
      }
    }
  ]
}

このトランザクションを作成した人をBob(ボブ)だとする。
アウトプット情報voutによるとBob
は下記2つのアドレスにそれぞれBTCを送付しているようだ。それぞれのアドレスの持ち主を便宜的にCarol(キャロル)とCharlie(チャーリー)と命名する。
 1Atyy5h4SSdqWRuS8pzxgTb4bMe7ZpdunP=Carolに43.61BTC

 18CisDmjM1MmM1MjtqUHPgmoLhZcSJJTKD=Charlie6.39BTC
以上からこのトランザクションの合計送金額は43.61+6.39=50BTCとなる。
送金するというからには当然ながらBob50BTC以上の原資を持っていなければならない。
それを何らかの形で証明しているのが、インプット情報vinに記載されている内容だ。

vin(再掲)
  "vin": [
    {
      "txid": "4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54",
      "vout": 1,
      "scriptSig": {
        "asm": "3045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c[ALL] 0449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e",
        "hex": "483045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c01410449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e"
      },
      "sequence": 4294967295
    }
  ],

ここの記述内容を一言で表現すると『過去の取引においてBobがアクセス権を有する口座番号にBTCが入金されているので、この口座から支払いを行います』という意味になる。

ビットコインはあくまで取引を主体に考えるので、出金元情報がインプットであり、送金先情報がアウトプットになることに注意。

具体的にはそれぞれのパラメータとして以下が対応している。

 ①過去の取引 →トランザクションIDとインデックス番号
   txid=4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54
   vout=1 (2番目のvoutを意味する)
 ②Bobがアクセス権を有する →デジタル署名
3045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c[ALL]
 ③口座番号 →公開鍵0449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e

asmはアセンブリ言語、hexはそれを機械語(バイナリー)に変換したもの。意味は変わらないので、特に注釈ないときはasmを基準とする。

では実際に①で指定されているトランザクションID
4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54を追跡してみよう。

①のトランザクション
$ ./gettx.sh 4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54
{
  "txid": "4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54",
  "hash": "4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54",
  "version": 1,
  "size": 192,
  "vsize": 192,
  "weight": 768,
  "locktime": 0,
  "vin": [
    {
      "txid": "aed03b8fbb969f45054472aee613c6b115320e8c1ceeb3c2f92c52f8dbc67078",
      "vout": 0,
      "scriptSig": {
        "asm": "3045022043df36465eb8854649a62b36e8d9a402bce012267ac8f4857ef3b5ca2f3396b7022100ae120cbba78942b82304c98efecbabc8745be7b8f6358f089344a2c5efe942dc[ALL]",
        "hex": "483045022043df36465eb8854649a62b36e8d9a402bce012267ac8f4857ef3b5ca2f3396b7022100ae120cbba78942b82304c98efecbabc8745be7b8f6358f089344a2c5efe942dc01"
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.08000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 a9730a07ea5626f14f7fa304c1309602b10a0553 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914a9730a07ea5626f14f7fa304c1309602b10a055388ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1GSy1UxBx7fyNaLB55KQ2x3NpovhxsQahN"
        ]
      }
    },
    {
      "value": 50.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 4d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9144d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7S"
        ]
      }
    }
  ]
}

このトランザクションを作成した者をAlice(アリス)とする。
voutの2番目を見ると、確かに50BTC
が、とあるアドレス184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7Sに送金されている。
Bobはこのアドレスが自身のものであると主張しているわけだ。このアドレスがBobのものであることをBobが証明でき、かつ誰もがそれを検証可能であるならば、BobAliceがアドレス184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7Sに送った50BTCを使用する権利があると認められる。とまあこういうロジックなわけだ。

そしてこれは容易に証明可能だ。
ビットコインアドレス公開鍵ハッシュが形を変えたものであることを既に学んだ。

公開鍵ハッシュ → (Base58Checkエンコード) → ビットコインアドレス
公開鍵ハッシュ ← (Base58Checkデコード)  ← ビットコインアドレス

公開鍵ハッシュ公開鍵をハッシュ化したものであるため、公開鍵を知る者しか作成することができない。

公開鍵 → (Hash160) → 公開鍵ハッシュ

Bobは③(公開鍵)を提示しているので、③からアドレス184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7Sが生成できれば、この③(公開鍵)は正しいものであることが証明される。
https://bc-2.jp/tools/txeditor2.htmlの計算ツールを使って実際に検証してみると公開鍵③が本物であることがわかるだろう。

02-01.png

ただし公開鍵③は一度開示されてしまえばそれまでなので、例えばマイナーによって送金先を書き換えられてしまうとどうしようもないし、同じアドレスを再利用することも出来なくなる。公開鍵③が間違いなくBobのものであることを証明するためにはどうすればいいのだろうか。
それがデジタル署名である。デジタル署名は秘密鍵から作成し、公開鍵によって検証することを可能にするアルゴリズムである。

秘密鍵 → (ECDSA) → デジタル署名を作成
公開鍵 → (ECDSA) → デジタル署名を検証

この関係からBobは自身の秘密鍵でトランザクションにデジタル署名を付加し、他のノードが公開鍵を用いてその正当性を検証することを可能にする。
仮に正しい秘密鍵を持たない者が偽の秘密鍵で署名を作成しトランザクションを偽造したとしても、公開鍵での検証結果がNGとなり不正と判断されるので、そのようなトランザクションは間違いなくリジェクトされる。これはトランザクションを改竄から保護するということでもある。トランザクションの内容を後から他人が勝手に改竄できてしまえばオープンネットワークとしての決済システムは成り立たないので、非常に重要なポイントとなる。
以上を整理すると下図のイメージとなる。

02-02.png

そしてAliceのトランザクションもまた同じく、もっと過去の取引を参照している。追跡すれば、誰かからBTCを受け取っていることが確認できるはずだ。ブロックチェーンが過去のブロックへの参照の連鎖(チェーン)で出来上がっているのと同じように、トランザクションもまた過去へ過去へと遡る取引のチェーンにより成り立っているのである。

UTXO

ここで一つ大切な用語の確認をしておく。
 UTXO (Unspent Transaction Output)=未使用のトランザクションアウトプット
という概念である。これは全てのトランザクションアウトプットのうち、現時点でまだ未使用のものを指している。図で言うならトランザクションID(Bob)Vout0,Vout1が該当する。いずれCarolCharlieがこれを参照するトランザクションを生成するまでこれらは永久的にUTXOであり続ける(=ロックされた状態)。一方でトランザクションID(Alice)Vout1Bobによって参照されたため既にUTXOではなくなっている。
一般化すると、トランザクションが新規作成されたとき、アウトプットから新たなUTXOが生み出されるが、それと同時にインプットが参照した過去のUTXOはその時点でUTXOではなくなる。言い換えればBTCの最新の所在を示すものだ。もっと分かりやすく言うと、UTXOがBTCの実体そのものと言っていい。現金であれば製造年や製造番号といった個体識別IDがあるが、BTCはそれ自体に色が付いているわけではない。その代わり、現金は個体の追跡ができないが、BTCは全ての取引がオープンになっており、今どこにどれだけのBTCが存在しているかがわかる。だからUTXOの始祖をずっと辿っていくとやがてどこかのcoinbaseトランザクションまで遡るだろう。これに例外はない。coinbase以外にBTCを生み出す源泉はないからだ。もちろん途中で途切れることはないし、失われたりもしない。coinbaseからひとたび誕生したUTXOは、形を変えながら途絶えることなく連鎖を続けていき、ビットコインネットワークのエコシステムを形作っていく。トランザクションという経済活動がもたらすこの点波源のような存在であるUTXOこそがビットコインの本質なのだ。

お釣りの回収

UTXOの特徴の一つに分割できないという規定がある。例えば50BTC入っているUTXOの中から10BTCだけ出金して残りの40BTCは残すということはできない。言い換えれば参照は一度きりしかできない仕様ということである。

そこでお釣りをどう処理するかというと下記の2パターンが考えられる。

 1.元のアドレスを再利用してお釣りを振り込み、元のアドレスのまま新たなUTXOを作る。
 2.お釣り用に新規アドレスを作成して振り込み、元のアドレスは使い捨てとする。

1の場合は、公開鍵がオープンになってしまっている以上、どうしてもセキュリティは下がってしまうだろう。ただしQRコードを動的に生成できない場合(紙に印刷したQRコードで広く支払いを募る場合など)は注意しながら運用していく必要がありそうである。実際のユースケースでは圧倒的に2による実装・運用がされていると思うが、いくらアドレスが作成し放題とはいえ、有限の資源であることは間違いないので将来的にはアドレス拡張を行ったりすることになるのかもしれない。

取引手数料

上記はトランザクションのインプットの総額とアウトプットの総額が同量であることを前提に話をしていたが、ではインプットとアウトプットに差がある場合はどうなるのだろうか。

アウトプットはインプットよりも多くすることはできないが、逆にアウトプットをインプットより少なく設定することはプロトコルに違反しない。この場合、アウトプットで出金されなかった差額のBTCの所有権は失うことになる。このBTCはどこに行ってしまうかというと、取引手数料の名目でcoinbaseトランザクションのアウトプットに全て加算されるように実装されている。つまり差額は採掘者へのチップとなるわけだ。

参考までに最近の手数料収入の総額はいかほどなのか、確認してみた。
下記はblock height=615758(2020年2月3日頃)のcoinbaseトランザクションの内容である。

マイナーの手数料収入はどのくらい?
./gettx.sh 1d0733ad91d14a492c6336a787787c9a6baf07c45968ac3a110755d389d04f6f
{
  "txid": "1d0733ad91d14a492c6336a787787c9a6baf07c45968ac3a110755d389d04f6f",
  "hash": "55e4336c1fb8820d372ca5308343b86bef1eed38555536bdd5847000b632441e",
  "version": 2,
  "size": 296,
  "vsize": 269,
  "weight": 1076,
  "locktime": 0,
  "vin": [
    {
      "coinbase": "034e65090471b3375e636430312f62797465706f6f6c2e636f6d2ffabe6d6d98e87c876f78c12807d86ac245d937241c411c25beeecba559f9c7ad9742b4b0020000004204cb9a0b8c96405ceb120000000000",
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 12.54122895,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 5885ab54ce79c9384af724709edb2eb08bfa8ff7 OP_EQUAL",
        "hex": "a9145885ab54ce79c9384af724709edb2eb08bfa8ff787",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "39m5Wvn9ZqyhYmCYpsyHuGMt5YYw4Vmh1Z"
        ]
      }
    },
(以下略)

12.54122895BTCが採掘者のUTXOに入金されている。
現在の採掘報酬は12.5BTCなので、差し引きすると手数料収入は0.04122895BTC=約41,228円(1BTC=1,000,000円)となる。採掘報酬と比べるとその比率は**0.32%**と僅かなものである。手数料収入が採掘報酬を上回る日が来るのはまだ当分先のようだ。

##7-2.トランザクションスクリプト

さて、ここからようやく今回の本題。
トランザクションスクリプトを理解することが当面の俄ビットコイナーの目標となるはずなので頑張っていきたい。

トランザクションスクリプトとは、前項(7-1.『ビットコインを送付する』ということ)で見てきたような概念を実際に計算機が実行できるようにするためにビットコインソフトウェアに内蔵されているプログラム言語だ。

【プログラム言語としての特徴】
 ・Bitcoinのために開発された専用の言語
 ・軽量、簡易
 ・Forth言語に似ている
 ・チューリング不完全(条件分岐、繰り返しなどの高度な処理ができない)
 ・スタックマシン
 ・逆ポーランド記法(演算子を後ろに配置する)

トランザクションスクリプトは全てのノードに評価(実行)されることを前提としており、その結果が正しい場合にトランザクションが正規のものであると認められブロックに取り込まれる。
コードはScriptPubKeyおよびScriptSigの2か所に分散しており、評価する際は結合させて使用する。
順を追って確認してみよう。

ScriptPubKey

ScriptPubKeyは"Public Key Script"(公開鍵スクリプト)の略で、別名Locking Scriptとも呼ばれる。
つまり『UTXOをロックするためのスクリプト』という意味だ。
先ほどのAliceBobに50BTCを送付するVout部分に着目してみる。

Aliceのトランザクションからvoutを再掲
  "vout": [
  (省略)
    {
      "value": 50.00000000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 4d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9144d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f88ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7S"
        ]
      }
    }

ここから分かるように、ScriptPubKey
OP_DUP OP_HASH160 4d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f OP_EQUALVERIFY OP_CHECKSIG
というプログラムコードになっている。
分解するとこんな感じ。
OP_DUP
OP_HASH160
4d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f ←(以降<公開鍵ハッシュ>とする)
OP_EQUALVERIFY
OP_CHECKSIG
説明は後ほど。

たまに誤解している記事があるが、オリジナルのブロックチェーンに載っている送金先情報はこれが全てだ。
"addresses" : 184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7S
の部分はビットコインソフトウェアが人間のために補完してくれているだけであり、あくまでも記述されているのは公開鍵ハッシュ(4d63a4b3b4ae384c44ff5d112a9b87c4c49ff36f)の方だ。
実際にはビットコインアドレスなるものはブロックチェーン上にもどこにも存在しないのである。

ScriptSig

ScriptSigは"Signature Script"(署名スクリプト)の略でUnlocking Scriptとも呼ばれる
『UTXOをアンロックするためのスクリプト』という意味だ。
BobAliceから受け取った50BTCをインプットするVinに着目してみる。

Bobのトランザクションからvinを再掲
  "vin": [
    {
      "txid": "4600bf5f3d49660a546c1b9acd3e6b85479ab227115f741cf12e50506ab24b54",
      "vout": 1,
      "scriptSig": {
        "asm": "3045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c[ALL] 0449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e",
        "hex": "483045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c01410449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e"
      },
      "sequence": 4294967295
    }
  ],

ScriptSig
3045022100c9e35aa55af5ac98cb67c4db7cf3d3f128753c4698f5d25ca0cdc3decd0c46be02204d6dfe89bd3fe88a32d47a44c0ab3ab60d87b27b90106f1b2f9f67c9c60cc80c[ALL]
0449b8d933f97a8c4fe6ce962ee2abff8a81d8cfc5e0870a50cea76c50d04addf2df09331c4a47cdc3bc27a628e766ef5d01f28ee147ed21723b5ff3a62ed8da3e
の部分。長いのでここでは
<デジタル署名>
<公開鍵>
の順に並んでいると理解すればOK。

スクリプトの評価

上記2つのスクリプトは対の存在になっている。
ScriptPubKeyが問題文ならば、
ScriptSigは答案といえる。

ScriptPubKeyによってロックされたUTXOをScriptSigが正しくアンロックできるか?』

という問題と答案の組み合わせによって構成されているわけだ。

02-04.png

そしてスクリプトを採点(評価)するのはマイニングノードやその他のフルノードの役割となる。

具体的な処理の順序としては、ScriptSigの後ろにScriptPubKeyを結合して、スタックマシンで計算を行う。
下表の実行順1から2がScriptSig、3から7がScriptPubKeyのものだ。

|実行順|Script|処理内容|記述箇所|
|---|---|---|---|---|
|1|<デジタル署名>|データプッシュ|ScriptSig|
|2|<公開鍵>|データプッシュ|ScriptSig|
|3|OP_DUP|スタックの先頭を複製してプッシュ|ScriptPubKey|
|4|OP_HASH160|スタックの先頭をHASH160化|ScriptPubKey|
|5|<公開鍵ハッシュ>|データプッシュ|ScriptPubKey|
|6|OP_EQUALVERIFY|スタックの先頭2要素をポップし、等しければtrue|ScriptPubKey|
|7|OP_CHECKSIG|スタックの先頭2要素をポップし、順に<公開鍵>,<デジタル署名>として、署名検証。メッセージダイジェストはトランザクションのSHA260dから導出。成功ならtrue|ScriptPubKey|

03-02.png

最終的に評価結果がtrueとなるとき、UTXOアンロックは成功ということになる。
結局のところ、
 1.Bobは正しい公開鍵を持っているか?
 2.Bobは正しい秘密鍵(によって作られたデジタル署名)を持っているか?
の2点を間接的にチェックしているということだ。
ブロックチェーンを保持する全員が同じ計算方法でチェックして、『取引を承認する』というコンセンサスがネットワーク内で醸成される。

UTXOはそれ単体ではただただオープンなメモリ上に延々と放置され続けるだけの存在でしかない。誰しもが平等にアンロックを試みる機会が無制限に与えられているということだ。そこには何人の規制も介入しない。トラストレスな世界において、公衆の面前に留め置かれ常に攻撃のリスクに晒されながらも、誰一人として不正にそれを利用することができないという仕組みは非常に面白くないだろうか。

以上が最も一般的なP2PKHを用いた支払い方法だ。

#8.様々な支払い方法

理屈だけで言えばトランザクションスクリプトは当事者間で自由に記述することができる。極論すればどんなスクリプトあっても、AliceLocking Script(問題文)とBobUnlocking Script(答案)さえ整合すれば、それは正しい取引なのであって、BTCの送受は可能であるわけだが、万人が安心して使用できる決済プラットフォームとするためには一定のルールの存在が欠かせない。安全性や利便性を追求していく中で、これまで幾つかの支払い方法が編み出されてきた。ここではビットコインが辿ってきた歴史に沿いつつ、順に整理してみることとする。

##8-1. P2PK (Pay to Public Key)

最初期に用いられていた支払い方法。公開鍵でロックしデジタル署名でアンロックする。
公開鍵暗号のベーシックな使用例といえるが、公開鍵が最初からオープンになっている点がデメリット。

支払い方法 ScriptPubKeyの要素 ScriptSigの要素
P2PK 公開鍵 デジタル署名

ビットコインの発明当初はこのままの内容で実装されたため、ScriptPubKeyScriptSigという名称になったものと考えられる。
Locking ScriptUnlocking Scriptという呼び方が今となっては圧倒的に意味が通りやすい。とはいえこれも歴史の産物だと考えると味わい深い。のだろうか?

Script 書式
ScriptPubKey <公開鍵> OP_CHECKSIG
ScriptSig <デジタル署名>

スクリプト評価フロー

実行順 Script 処理 記述箇所
1 <デジタル署名> データプッシュ ScriptSig
2 <公開鍵> データプッシュ ScriptPubKey
3 OP_CHECKSIG スタックの先頭2要素をポップし、順に<公開鍵>,<デジタル署名>として、署名検証。メッセージダイジェストはトランザクションのSHA256dから導出。成功ならtrue ScriptPubKey

03-01.png

事例サンプル

height=50000のcoinbaseトランザクション
$ ./gettx.sh 27f1d66f8a1ee5280f4e92508dcb647e954d53004905d08a75574daee4988360
{
  "txid": "27f1d66f8a1ee5280f4e92508dcb647e954d53004905d08a75574daee4988360",
  "hash": "27f1d66f8a1ee5280f4e92508dcb647e954d53004905d08a75574daee4988360",
  "version": 1,
  "size": 135,
  "vsize": 135,
  "weight": 540,
  "locktime": 0,
  "vin": [
    {
      "coinbase": "0415112a1c02c100",
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 50.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "04a9d6840fdd1497b3067b8066db783acf90bf42071a38fe2cf6d2d8a04835d0b5c45716d8d6012ab5d56c7824c39718f7bc7486d389cd0047f53785f9a63c0c9d OP_CHECKSIG",
        "hex": "4104a9d6840fdd1497b3067b8066db783acf90bf42071a38fe2cf6d2d8a04835d0b5c45716d8d6012ab5d56c7824c39718f7bc7486d389cd0047f53785f9a63c0c9dac",
        "type": "pubkey"
      }
    }
  ]
}
上記ScriptPubKeyに対応するScriptSigの入ったトランザクションVin抜粋
$ ./gettx.sh 2d22e9ef36692d9f9a383523442fe6cd0439b9e8c0498f6b972845517d6d3045
 (Vin抜粋)
    {
      "txid": "27f1d66f8a1ee5280f4e92508dcb647e954d53004905d08a75574daee4988360",
      "vout": 0,
      "scriptSig": {
        "asm": "3045022100c68e6d5fc26175800bd3094fcd00d5b049aaaba5e47f9a276fbb18a50a2d623502200d7fc6a72cb8a6b2a9e4276a8b76e602692d36d199e45d4beaf1b2dbd3aed0ef[ALL]",
        "hex": "483045022100c68e6d5fc26175800bd3094fcd00d5b049aaaba5e47f9a276fbb18a50a2d623502200d7fc6a72cb8a6b2a9e4276a8b76e602692d36d199e45d4beaf1b2dbd3aed0ef01"
      },
      "sequence": 4294967295
    }

公開鍵がそのまま埋め込まれるので、どうしても長くなってしまう。スクリプト長が長いということはそれだけトランザクションの容量が増えるということであり、オーバーヘッドの増加につながる。

##8-2. P2PKH (Pay to Public Key Hash)

遅くとも2010年前半には既に登場していた。
ビットコインアドレス(公開鍵ハッシュ)の概念が採用されて利便性と安全性向上に寄与。
内容は散々やったので前項参照。

支払い方法 ScriptPubKeyの要素 ScriptSigの要素
P2PKH 公開鍵ハッシュ デジタル署名, 公開鍵
Script 書式
ScriptPubKey OP_DUP OP_HASH160 <公開鍵ハッシュ> OP_EQUALVERIFY OP_CHECKSIG
ScriptSig <デジタル署名> <公開鍵>

スクリプト評価フロー

|実行順|Script|処理内容|記述箇所|
|---|---|---|---|---|
|1|<デジタル署名>|データプッシュ|ScriptSig|
|2|<公開鍵>|データプッシュ|ScriptSig|
|3|OP_DUP|スタックの先頭を複製してプッシュ|ScriptPubKey|
|4|OP_HASH160|スタックの先頭をHASH160化|ScriptPubKey|
|5|<公開鍵ハッシュ>|データプッシュ|ScriptPubKey|
|6|OP_EQUALVERIFY|スタックの先頭2要素をポップし、等しければtrue|ScriptPubKey|
|7|OP_CHECKSIG|スタックの先頭2要素をポップし、順に<公開鍵>,<デジタル署名>として、署名検証。メッセージダイジェストはトランザクションのSHA260dから導出。成功ならtrue|ScriptPubKey|

03-02.png

##8-3. Multi-Signature (BIP-011 / M-of-N Standard Transactions)

通称、マルチシグ。
N個の公開鍵でロックしM個の署名でアンロックする仕組み。
アンロックに複数の署名が必要となるため、従来の支払い方法に比べてセキュリティが高い。

支払い方法 ScriptPubKeyの要素 ScriptSigの要素
Multi-Sig N個の公開鍵 M個のデジタル署名
Script 書式
ScriptPubKey M 公開鍵1 ~ 公開鍵n N OP_CHECKMULTISIG
ScriptSig OP_0 デジタル署名1 ~ デジタル署名M

スクリプト評価フロー(2 of 3 MultiSigの場合)

実行順 Script 処理 記述箇所
1 OP_0 データプッシュ(バグ対策のWA) ScriptSig
2 デジタル署名1 データプッシュ ScriptSig
3 デジタル署名2 データプッシュ ScriptSig
4 2 データプッシュ ScriptPubKey
5 公開鍵1 データプッシュ ScriptPubKey
6 公開鍵2 データプッシュ ScriptPubKey
7 公開鍵3 データプッシュ ScriptPubKey
8 3 データプッシュ ScriptPubKey
9 OP_CHECKMULTISIG N個の公開鍵でM個の署名を検証し、全ての署名が検証可能であればtrue。 ScriptPubKey

03-03.png

2of3の場合は、3人の公開鍵で多重ロックをかけ、そのうち2人分の署名が揃えばアンロックできる。
3者間を通じたエスクロー取引などユースケースが拡大する。

##8-4. P2SH (BIP-016 / Pay to Script Hash)

2012年頃に実装され定着している。
これもマルチシグの一種だが、BIP-011よりも以下の点でメリットがある。
 ・送金側のスクリプト実行コスト(取引手数料)が安い
 ・送金先情報を、公開鍵ハッシュ同様に、ビットコインアドレスとして表現できる。

支払い方法 ScriptPubKeyの要素 ScriptSigの要素
P2SH redeem_scriptのハッシュ M個のデジタル署名,redeem_script

Redeem scriptっていうのはMultiSigのアンロック部分をserializeしたもので、
BIP-011でいうScriptPubKeyの内容に相当する。

Script 書式
ScriptPubKey OP_HASH160 redeem_script_hash OP_EQUAL
ScriptSig OP_0 デジタル署名1 ~ デジタル署名M redeem_script
redeem_script M 公開鍵1 ~ 公開鍵n N OP_CHECKMULTISIG

スクリプト評価フロー(2 of 3の場合)
P2SHは

実行順 Script 処理 記述箇所
1 OP_0 データプッシュ(バグ対策のWA) ScriptSig
2 デジタル署名1 データプッシュ ScriptSig
3 デジタル署名2 データプッシュ ScriptSig
4 redeem_script データプッシュ ScriptSig
5 スタックの状態保存
6 OP_HASH160 スタックの先頭をHASH160化 ScriptPubKey
7 redeem_script_hash データプッシュ ScriptPubKey
8 OP_EQUAL スタックの先頭2要素をポップし、等しければtrue ScriptPubKey
9 スタックを5に状態復元
10 スタックの先頭をポップし、スクリプトとして実行
10a 2 データプッシュ redeem_script
10b 公開鍵1 データプッシュ redeem_script
10c 公開鍵2 データプッシュ redeem_script
10d 公開鍵3 データプッシュ redeem_script
10e 3 データプッシュ redeem_script
10f OP_CHECKMULTISIG N個の公開鍵でM個の署名を検証し、全ての署名が検証可能であればtrue。 redeem_script

03-04a.png

03-04b.png

見比べてみると、実際のところ、署名検証にかかる手順とコストはBIP-011と全く同じであることがわかる。
大きな違いは、本来のロックするための鍵(scriptPubKey)を外部スクリプト(Redeem script)としてscriptSig側に記述させている点である。こうすることで送金側に発生していた負担コストをまるっと受け取り側に転嫁させているわけだ。

事例サンプル

height=400000のindex=x番目のトランザクション(適当に見つけた)
$ ./gettx.sh 5ef31625bee220e0293441b84596fcdaae9bc2a7027365175ec67d4e705f7ce6
{
  "txid": "5ef31625bee220e0293441b84596fcdaae9bc2a7027365175ec67d4e705f7ce6",
  "hash": "5ef31625bee220e0293441b84596fcdaae9bc2a7027365175ec67d4e705f7ce6",
  "version": 1,
  "size": 851,
  "vsize": 851,
  "weight": 3404,
  "locktime": 0,

  <snip>

  "vout": [
    {
      "value": 1.00000000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_HASH160 4581f8c5233637c780c40b42ac066b5e4f8255da OP_EQUAL",
        "hex": "a9144581f8c5233637c780c40b42ac066b5e4f8255da87",
        "reqSigs": 1,
        "type": "scripthash",
        "addresses": [
          "382YFNmXQj3WBsK4UyUc7HfEW1vbb6jrbj"
        ]
      }
  <snip>
上記ScriptPubKeyに対応するScriptSigの入った、受け取り側のトランザクションVin抜粋
$ ./gettx.sh 28b8a27c0f252876c3942d7ab1d8917e418c65253543c73daef41bfb50ac8029
(vin抜粋)
  "vin": [
    {
      "txid": "5ef31625bee220e0293441b84596fcdaae9bc2a7027365175ec67d4e705f7ce6",
      "vout": 0,
      "scriptSig": {
        "asm": "0 3045022100c98449c7088714f7c0e503183d6a6d3c36a4811a4b99ba2112886c691c79e28a02207a136717461ed5ed68cf4ad80f2bdc083686ffc871f4d0c4d1bbd2f3f124980b[ALL] 304402207681b4c691a1ca7e4bc9150beb7cf7add6a335361794a699e49bbb63720d2c7502204a7a814a3d3b5835d0177603008ba88be193b0d51ba5ba7c23aa1b3dda900b33[ALL] 522103cfa4a57c9c016ec854187f9be5c407e4cd960b5c11bc4b87de0b77d28699273421036173cc77f927af38f0f70557833c6babdb614fdd7797135e79519203ae65d85a21026380f34fbbd8d798af3a9a63b473fac966bb78ec354b4aaef1a559baf8b15c8453ae",
        "hex": "00483045022100c98449c7088714f7c0e503183d6a6d3c36a4811a4b99ba2112886c691c79e28a02207a136717461ed5ed68cf4ad80f2bdc083686ffc871f4d0c4d1bbd2f3f124980b0147304402207681b4c691a1ca7e4bc9150beb7cf7add6a335361794a699e49bbb63720d2c7502204a7a814a3d3b5835d0177603008ba88be193b0d51ba5ba7c23aa1b3dda900b33014c69522103cfa4a57c9c016ec854187f9be5c407e4cd960b5c11bc4b87de0b77d28699273421036173cc77f927af38f0f70557833c6babdb614fdd7797135e79519203ae65d85a21026380f34fbbd8d798af3a9a63b473fac966bb78ec354b4aaef1a559baf8b15c8453ae"
      },
      "sequence": 4294967295
    },

scriptPubKeyとscriptSigの長さを見比べてみると、送金側と受け取り側のコスト差がどれほどあるか感覚的によくわかるだろう。

ちなみに、scriptPubKeyに記述されている通り、P2SHではビットコインアドレス体系は3始まりとなる。
"addresses" : 382YFNmXQj3WBsK4UyUc7HfEW1vbb6jrbj
(P2PKHでは1始まり)

scriptSigを見ると、
0 <デジタル署名1> <デジタル署名2> redeem_script
の並びで記述されていることがわかる。
さらにredeem_scriptdecodescriptコマンドでデコードすることができる。

redeem_scriptのデコード
$ bitcoin-cli decodescript 522103cfa4a57c9c016ec854187f9be5c407e4cd960b5c11bc4b87de0b77d28699273421036173cc77f927af38f0f70557833c6babdb614fdd7797135e79519203ae65d85a21026380f34fbbd8d798af3a9a63b473fac966bb78ec354b4aaef1a559baf8b15c8453ae
{
  "asm": "2 03cfa4a57c9c016ec854187f9be5c407e4cd960b5c11bc4b87de0b77d286992734 036173cc77f927af38f0f70557833c6babdb614fdd7797135e79519203ae65d85a 026380f34fbbd8d798af3a9a63b473fac966bb78ec354b4aaef1a559baf8b15c84 3 OP_CHECKMULTISIG",
  "reqSigs": 2,
  "type": "multisig",
  "addresses": [
    "1Lf1Jb4NeF5VrLQ58Wp4drgbEbnrfHDu1A",
    "1P3hp6wCYx26yfDatXdqSHJ1RqLzpPCqEV",
    "152jxcp4a6bL9WViZ6v4r8ch2pENHUZM1b"
  ],
  "p2sh": "382YFNmXQj3WBsK4UyUc7HfEW1vbb6jrbj",

  <snip>
}

redeem_scriptの中身は
2 <公開鍵1> <公開鍵2> <公開鍵3> 3 OP_CHECKMULTISIG
という並びとなっている。
以上からこのscriptSigは2of3-MultiSigを実現する書式に従っていることが確認できる。

今回はここまで。
次回はSegwitに関して取り上げたい。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?