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

前回
[Bitcoin Coreを触りながらBitcoinについて理解する - その１(構築～アドレス生成まで)](https://qiita.com/mahiroaug/items/ad42e3bde303bb094b4a)
からの続きです。

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

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

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

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

```bash: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**は下記２つのアドレスにそれぞれBTCを送付しているようだ。それぞれのアドレスの持ち主を便宜的に**Carol(キャロル)**と**Charlie(チャーリー)**と命名する。
　`1Atyy5h4SSdqWRuS8pzxgTb4bMe7ZpdunP`=**Carol**に**43.61BTC**
　`18CisDmjM1MmM1MjtqUHPgmoLhZcSJJTKD`=**Charlie**に**6.39BTC**
以上からこのトランザクションの合計送金額は**43.61+6.39=50BTC**となる。
送金するというからには当然ながら**Bob**は**50BTC**以上の原資を持っていなければならない。
それを何らかの形で証明しているのが、インプット情報`vin`に記載されている内容だ。

```bash: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`を追跡してみよう。

```bash:①のトランザクション
$ ./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**が証明でき、かつ誰もがそれを検証可能であるならば、**Bob**は**Alice**がアドレス`184CQ7agrApMYpnKTzWnsMjV9Wx3raHw7S`に送った**50BTC**を使用する権利があると認められる。とまあこういうロジックなわけだ。

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

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

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

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

![02-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/8db83319-6786-a1f6-0d4d-92f6b4fd61e4.png)

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

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

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

![02-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/13a026d2-3eed-e7a2-d5c3-edef472cb1e0.png)

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


### UTXO

ここで一つ大切な用語の確認をしておく。
　**UTXO** (Unspent Transaction Output)=未使用のトランザクションアウトプット
という概念である。これは全てのトランザクションアウトプットのうち、現時点でまだ未使用のものを指している。図で言うなら`トランザクションID(Bob)`の`Vout0`,`Vout1`が該当する。いずれ**Carol**や**Charlie**がこれを参照するトランザクションを生成するまでこれらは永久的に**UTXO**であり続ける（＝ロックされた状態）。一方で`トランザクションID(Alice)`の`Vout1`は**Bob**によって参照されたため既に**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トランザクション`の内容である。

```none:マイナーの手数料収入はどのくらい？
./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をロックするためのスクリプト』という意味だ。
先ほどの**Alice**が**Bob**に50BTCを送付するVout部分に着目してみる。

```bash: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をアンロックするためのスクリプト』という意味だ。
**Bob**が**Alice**から受け取った**50BTC**をインプットする`Vin`に着目してみる。

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

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

### スクリプトの評価

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

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

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

![02-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/f59c9ea8-ee54-3fb0-345d-e81efcb49d69.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|スタックの先頭２要素をポップし、等しければtrue|ScriptPubKey|
|7|OP_CHECKSIG|スタックの先頭２要素をポップし、順に<公開鍵>,<デジタル署名>として、署名検証。メッセージダイジェストはトランザクションのSHA260dから導出。成功ならtrue|ScriptPubKey|

![03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/b4799779-1836-2fb5-5136-4c60c41fe35e.png)



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

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

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

#8.様々な支払い方法

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

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

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

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

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

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

スクリプト評価フロー

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

![03-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/b8914ad1-4fca-72f2-eafd-411227c0cde3.png)

事例サンプル

```bash: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"
      }
    }
  ]
}
```


```bash:上記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|スタックの先頭２要素をポップし、等しければtrue|ScriptPubKey|
|7|OP_CHECKSIG|スタックの先頭２要素をポップし、順に<公開鍵>,<デジタル署名>として、署名検証。メッセージダイジェストはトランザクションのSHA260dから導出。成功ならtrue|ScriptPubKey|

![03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/23eaec17-8481-780b-7e48-93b357b7fe28.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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/0ff14e08-99cc-53b0-2513-dd5b65389a23.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|スタックの先頭２要素をポップし、等しければ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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/e466131b-1174-de80-7080-8ae3f1db1b27.png)

![03-04b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484220/608cc1a8-ee05-b34d-d5ba-2eb6040c83d1.png)

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

事例サンプル

```bash: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>
```

```bash:上記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_script`は`decodescript`コマンドでデコードすることができる。

```bash: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に関して取り上げたい。