Bitcoinのスクリプト言語について
次世代システム研究室の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と呼ばれます。)を参照しています。
これを踏まえてトランザクションに含まれるスクリプトを見ていきます。
ブロックチェーンエクスプローラでスクリプトを確認する
数あるブロックチェーンエクスプローラのサービスのなかには、トランザクションに含まれるスクリプトを見ることができるものがあります。今回はテストネットのトランザクションも見ることができるBlocktrailのブロックチェーンエクスプローラで実際の様子を見てみます。テストネットのwallet作成にはBitPayとTestnet Walletを使用しました。対応するinputとoutputのスクリプトは2つのTransactionにまたがっているため、ここでも2つのトランザクションを見ていきます。まずはinput (Transaction 1)です。

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

参照されているoutputスクリプトは以下の部分です。
OP_HASH160 c0f510b2d2bd68694572239e0e38c7b5267daa1f OP_EQUALoutputの
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が支持されることによって利用が開始されます。
終わりに
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ 募集職種一覧 からご応募をお願いします。皆さんのご応募をお待ちしています。