暗号通貨のトランザクションを手作りする (2)

今回のおはなし

みなさんこんにちは。

VIPPOOL でエンジニアをやっています、星月です。

前回はトランザクションとはそもそも何か?というお話をして、
UTXO と残高の関係について説明しました。

そのときに、「UTXO は通常ロックされている」「アンロックする権利こそが所有権の実体」
というお話をしました。

このロック、アンロックは実際どのように実現されているのでしょうか、
というのが今回のテーマです。

scriptPubKey と scriptSig

bitcoin やそこからフォークした各種アルトコインでは、ロック・アンロックは、
共通の「Script」と呼ばれる言語で記述されたプログラムコードで実現されています。

このプログラムは、スタック型のバーチャルマシンで実行されて、
最終的な結果が 1 True となればアンロックに成功して、次のトランザクションの入力に接続できます。

...と説明しても抽象的でわかりづらいですね。
具体例を挙げていきます。

トランザクションの出力には scriptPubKey という名前のプログラムが記述されています。
例えばこんな感じ。

OP_PUSH 0xABCD
OP_EQUAL

OP_PUSH は続く値をスタックにプッシュします。
OP_EQUAL はスタック先頭の2つの値を比較して、
異なる場合にはスタックに 0 False を、一致する場合には 1 True を積みます。

次に接続しようするトランザクションの入力には、scriptSig という名前のプログラムを記述します。
例えばこんな感じ。

OP_PUSH 0xABCD

暗号通貨のコインノードは、この出力と入力を接続しても良いか判断するために、
2つのプログラムを連結して実行します。

OP_PUSH 0xABCD
OP_PUSH 0xABCD
OP_EQUAL

0xABCD を2個積んで比較するので、実行後はスタックトップに 1 True が積まれた状態になります。
これでこの2つのトランザクションは接続しても問題ないと判断され、ブロックチェーンに組み込まれます。

図にするとこんな感じです。

f:id:y-hoshizuki:20181022125730p:plain

まるで、scriptPubKey にアンロックの条件が記述されていて、
scriptSig に対応するプログラムを与えることでアンロックに成功する、
というような解釈ができるのではないでしょうか。

さて、では違う scriptSig だとどうでしょう?

OP_PUSH 0xDEADBEAF

コインノードは2つのプログラムを連結して実行します。

OP_PUSH 0xDEADBEAF
OP_PUSH 0xABCD
OP_EQUAL

スタックには異なる値が載っているので、OP_EQUAL の実行後、スタックトップには 0 False が積まれます。
このような場合は不正なトランザクションとして後続のトランザクション自体を拒絶します。

正しい scriptSig でなければ接続を拒絶する、まさにロックされている状態といえるでしょう?

暗号通貨ではこのような仕組みで、ロック・アンロックを実現しています。

今回は OP_PUSH と OP_EQUAL の2命令だけを使った簡単なプログラムですが、
他にもいろいろな命令が使えます。
bitcoin wiki の Script に命令の一覧があるので、
さらっと眺めてみるのもいいかも知れません。

よく使われる Script プログラム

Script 言語で記述可能な範囲であればどんなアンロック条件でも書くことができますが、
一般的に使われるプログラムは形式が決まっています。

今現在、最もよく使われているのが、P2PKH と呼ばれる形式のプログラムで、
以下の形式で記述されます。

scriptSig:
 PUSH 電子署名
 PUSH 公開鍵
scriptPubKey:
 OP_DUP
 OP_HASH160
 PUSH 公開鍵のハッシュ値
 OP_EQUALVERIFY
 OP_CHECKSIG

プログラムの詳しい説明は今は避けておきますが、名前くらいは覚えていただけると幸いです。

今回はここまで。
ご質問、ご意見等ありましたらお気軽にリプライください。