2016.11.29

Bitcoinのスクリプト言語について

Pocket

stones-944145_1280
次世代システム研究室のN.O.です。
Bitcoinのブロックチェーンに記録されたお金の所有権はどのように検証されるのでしょうか?それはBitcoinが独自に持つスクリプト言語によって検証されています。今回はこのスクリプト言語について説明します。また最近Bitcoin coreに取り込まれたSegwitについても少し触れたいと思います。

スクリプト言語

スクリプト言語はForthという言語に似たスタックベースの言語です。スタックの特徴としてプログラムや処理系が小さく済むため、IoTなど組み込み機器にも有利とされています。
スクリプト言語はOP_で始まるOpcode(オペコード)という命令群で構成されます。

スクリプトの場所

スクリプトはどこにあるのでしょうか?
ブロックチェーンは文字通りブロックが連なったものであり、ブロックはブロックヘッダとトランザクションで構成され、トランザクションはinputとoutputで構成されています。このinputとoutputにスクリプトがあります。inputとoutputのフォーマットはBitcoin wikiで見ることができます。

scriptSigとscriptPubkey

inputのスクリプトはscriptSigと呼ばれます。Bitcoinの所有者が、自分の持つ未使用のoutputを使用するためにスクリプトを提示することから、アンロックスクリプトとも呼ばれます。
outputのスクリプトはscriptPubkeyと呼ばれ、ロックスクリプトとも呼ばれます。

Standard Transactions

スクリプトには実に様々なOpcodeがありますが、どのように使われているのでしょうか?Bitcoinには初期の致命的なバグを踏まえてStandard Transactionsというものが追加されました。これに標準的なスクリプトとして5つのスクリプトが定義されています。

To Public Key Hash (P2PKH)

もっともよく使われるタイプです。
scriptPubkey: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
scriptSig: <sig> <pubkey> 

To Script Hash (P2SH)

2番目に使われるタイプです。
scriptPubkey: OP_HASH160 <Hash160(redeemScript)> OP_EQUAL
scriptSig: OP_0 <sig_1> <sig_2> ... <sig_m> <redeemScript>
redeemScript: OP_m <pubkey_1> <pubkey_2> ... <pubkey_n> OP_n OP_CHECKMULTISIG
他にも以下のタイプがありますが、ここでは省略します。
  • Multisig
  • Pubkey
  • Null Data →OP_RETURNの後に80 byteのデータを入れることができる

トランザクション

次にトランザクションに含まれる実際のスクリプトを見ていきたいと思いますが、その前に、トランザクションがどのようにBitcoinを消費するかを説明する必要がありました。
Bitcoin Developer Guideの図が分かりやすいですが、トンランザクションのinputは、前のoutput(かつ未使用のもの、UTXOと呼ばれます。)を参照しています。
tx-overview.svg
これを踏まえてトランザクションに含まれるスクリプトを見ていきます。

ブロックチェーンエクスプローラでスクリプトを確認する

数あるブロックチェーンエクスプローラのサービスのなかには、トランザクションに含まれるスクリプトを見ることができるものがあります。今回はテストネットのトランザクションも見ることができるBlocktrailのブロックチェーンエクスプローラで実際の様子を見てみます。テストネットのwallet作成にはBitPayTestnet Walletを使用しました。

対応するinputとoutputのスクリプトは2つのTransactionにまたがっているため、ここでも2つのトランザクションを見ていきます。まずはinput (Transaction 1)です。
トランザクションの様子 tx1 トランザクションの様子

inputのスクリプトの解説をします。これはP2SHですので、scriptSigに該当するのは以下の部分です。※見やすくするため、スペースを改行に変換しています。
OP_0
30440220116adfa66b7b75ef30dd7d6c359939fb9fb8d16b85c63e66cbda8ff47881b5ea02204a12886f26aea767749e4e2f468777149e6c69b9110d48c932fd4927e54d154b01
3045022100e72e32cacaa3359ead22f95c6215e9a3bc1306e5f591d55a13746572ab1b934b02201390528c741daba5cda04ae71ab320ad083196be898ead466f7162cfaf63568c01
redeemScriptに該当するのは以下の部分となります。
OP_2
0341a8db12929ea97d9efcbdb82cd01c750fff063173143ea910f247a377a53c09
0368ac37f7aad81e2eba1797af3ed44f7780e6fed047883a7d4fdeecc858d3d557
03db9fff614d30c5781daf1edbdf4e8484f5f97b1774bbdbcd568fcdd5dd87c309
OP_3
OP_CHECKMULTISIG
このredeemScriptをtestnetのP2SHアドレスに変換すると
2NAqVJYcxc2mrUW8UBCR2HUuh562Xpqgc2d
となります。

次にこのinputが参照しているoutput(Transaction 0)をみます。
トランザクションの様子 tx0 トランザクションの様子
参照されているoutputスクリプトは以下の部分です。
OP_HASH160 c0f510b2d2bd68694572239e0e38c7b5267daa1f OP_EQUAL
outputのOP_HASH160に続くc0f510b2d2bd68694572239e0e38c7b5267daa1fですが、これはTransaction 1のredeemScriptをhash関数SHA-256にかけた後、RIPEMD-160したものです。このhashにtestnetのP2SHのprefixである0xc4を追加し、Base58check encodeしたものが2NAqVJYcxc2mrUW8UBCR2HUuh562Xpqgc2dとなります。

Segwit

最後に最近話題のSegwitについて触れたいと思います。
SegwitについてはSegregated witness soft forkで説明されていますが、注目したいのはブロックのサイズの増加です。Bitcoinのブロックのサイズは1MBの制限がありますが、SegwitのトランザクションではscriptSigをブロックの制限の対象外となるwitnessという領域に保存します。scriptSigがトランザクションに占める割合が多ければその分トランザクションの領域を節約することができ、より多くのトランザクションをブロックに含めることができるようになります。Segwitにより最大4MBのトランザクションをブロックに入れることが可能ですが、実質的には1.6から2MBとされています。
またこのSegwitは有効になっておらず、ブロック投票でSegwitが支持されることによって利用が開始されます。

終わりに

次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。

皆さんのご応募をお待ちしています。