ScriptPubKeyについて


ScriptPubKeyとは

Bitcoinではトランザクションの有効性を検証するためにScript言語というものを用いています。
Bitcoinのトランザクションにはinputとoutputが含まれますが、inputに用いるものがunlocking script(ScriptSig)で、トランザクションの鍵を解除するためのスクリプトです。
また、outputに用いられるものがlocking script(ScriptPubKey)と言います。
locking scriptはトランザクションのアウトプットに置かれる解除条件で、アウトプットを使用する際に満たさなければいけない条件を指定する、鍵をかけるためのスクリプトです。

Script言語 

script言語は、スタックベースの言語で左から右に向かって実行されます。
ここでいうスタックはデータ構造のスタックと同様のもので、先入れ後出しの形で命令が処理されていきます。
ビットコインのP2PKH(pay to public key hash)を使用したスクリプトでは
ScriptPubKeyは次のようなスクリプトになっています。

OP_DUP OP_HASH160 <PublicKey Hash A>  OP_EQUALVERIFY OP_CHECKSIG

OP_DUPはスタックのトップを複製して1番上に追加します。
OP_HASH160 スタックのトップをSHA-256でハッシュし、次にRIPEMD-160でハッシュします。
OP_EQUALVERIFYは2つの要素が等しければ1を、等しくなければ0を返すOP_EQUALを実行した後、OP_VERIFYを実行します。
OP_VERIFYはスタックのトップが1でなければトランザクションを無効とします。1の場合は何もしません。その後トップの要素が削除されます。
OP_CHECKSIGは署名の妥当性を検証して1(署名成功)または0(失敗)を返します。

一方で、ScriptSigは

<Signature A> <PublicKey A>

となっています。
ScriptSigとScriptPubKeyを組み合わせて以下のスクリプトを検証することでトランザクションに入っているビットコインを使用することができるようになります。

<Signature A> <PublicKey A> OP_DUP OP_HASH160 <PublicKey Hash A> OP_EQUALVERIFY OP_CHECKSIG

P2PKHの流れ

① < Signature A> < PublicKey A>をスタックに積みます

<Signature A> <PublicKey A>

②OP_DUPでスタックのトップにある< PublicKey A>が複製され、追加されます

<Signature A> <PublicKey A> <PublicKey A>

③OP_DUPでトップにある< PublicKey A>のハッシュを計算して< PublicKey Has A>としてスタックに追加します

<Signature A> <PublicKey A> <PublicKey Hash A>

④< PublicKey Hash A>をスタックに追加します。

<Signature A> <PublicKey A> <PublicKey Hash A> <PublicKey Hash A>

⑤OP_EQUALVERIFYで上2つのが等しいか検証し、正しければ1、そうでなければ0を積み、その後OP_VERIFYで1番上の要素を削除する

<Signature A> <PublicKey A>

⑥OP_CHECKSIGで署名をチェックする。1(署名成功)または0(失敗)を返す。
このような流れでトランザクションが検証されます。

参考 

「BIP16 : P2SH の仕組み」https://developers.yenom.tech/entry/2018/08/18/143918

「ブロックチェーン・プログラミング 仮想通貨入門 」http://bookclub.kodansha.co.jp/product?item=0000148221

「Bitcoin wiki Script」https://en.bitcoin.it/wiki/Script