【前編】試験に出る!最重要 BIP 10 選

Masahiko Hyuga
GBEC Tech Blog
Published in
8 min readMar 16, 2019

こんにちは。フレセッツ株式会社の日向(ひゅうが)です。

いよいよ花粉が本格的に飛び始め、マスクとティッシュが手放せない日々を過ごしております。これがまだ一ヶ月以上続くと思うとユウウツな気分になりますね。花粉の時期だけ花粉のない沖縄などの地域に移住したいですね(笑)

ビットコイン版の RFC ともいえる BIP (Bitcoin Improvement Proposal) という標準的な仕様提案があるのは皆さんご存知でしょうか?ここにはビットコインが 2009 年に公開された後に新規で追加された機能や仕様の詳細が記載されており、HD (Hierarchical Deterministic) ウォレットや SegWit 周りの仕様を調べようとすると最終的には必ずこの BIP にたどり着きます。しかしながらこの BIP は年々増え続けており、執筆時点では実に 117 個ほどあります。しかも公式にある BIP の中には、提案はされたものの棄却されてしまったものや、実質的にほとんど誰にも利用されていなくて廃れた仕様などが含まれており、まさに玉石混淆といった状況です。そこでこの記事では、BIP の中でも特に重要かつ利用頻度が高いと思われるものを 10 個ほど選抜し、それぞれの BIP の中身を簡単に俯瞰してみようと思います。

BIP 11: M-of-N Standard Transactions

これはいわゆる「マルチシグ」を規定するための BIP となります。ビットコインにはネイティブでマルチシグを実装することのできる OP_CHECKMULTISIG とよばれるオペコードがあり、これを ScriptPubkey に埋め込むことでマルチシグを実装します。具体的には ScriptPubkey には

m {pubkey}...{pubkey} n OP_CHECKMULTISIG

を指定し、ScriptSignature に

OP_0 ...signatures...

を指定すること、と書かれています。ただ実際には後述する Pay-to-Script-Hash (P2SH) 形式を使うことが推奨されていますので、現在主流のマルチシグトランザクションとは少し違っていますので注意が必要です。

BIP 16: Pay to Script Hash

これはマルチシグなどの複雑な送金条件の書かれているアドレスを扱う際に、従来の方法だと送金者にその複雑なスクリプトの内容を渡してあげる必要があり、通常のシングルシグのアドレスを扱うのと比べると長いスクリプトをやり取りする必要があるため不便です。そこで考えられたのがこの Pay-to-Script-Hash (P2SH) であり、これを用いると複雑なスクリプトのハッシュ値だけを渡せば十分なようになります。

具体的には、ScriptPubkey は

OP_HASH160 [20-byte-hash-value] OP_EQUAL

という形になり、この ScriptPubkey を利用するための ScriptSignature は

...signatures... {serialized script}

となります。P2SH に対応するクライアントは、通常のスクリプトの処理に加えて、P2SH 型の ScriptPubkey を見つけた際には ScriptSignature に埋め込まれている “serialized script” をスクリプトとして再解釈して再実行してあげる必要があります。

BIP 21: URI Scheme

ビットコインの送金先を(主に QR コードなどで)指定する際の URI スキームを規定した BIP です。”bitcoin:” から始まる URI であり、送金先のアドレスはもちろん、送金数量、ラベル、メッセージなどを指定することもできます。モバイルウォレットなどで入金用の QR コードを表示した場合にはほぼ確実にこの URI スキームに従ったものになります。

具体的なフォーマットについては下記の ABNF にて規定されています。

bitcoinurn     = "bitcoin:" bitcoinaddress [ "?" bitcoinparams ]
bitcoinaddress = *base58
bitcoinparams = bitcoinparam [ "&" bitcoinparams ]
bitcoinparam = [ amountparam / labelparam / messageparam / otherparam / reqparam ]
amountparam = "amount=" *digit [ "." *digit ]
labelparam = "label=" *qchar
messageparam = "message=" *qchar
otherparam = qchar *qchar [ "=" *qchar ]
reqparam = "req-" qchar *qchar [ "=" *qchar ]

抽象的な説明で少しごちゃごちゃしていますが、これを用いた URI スキームの具体例を見てみると分かりやすいでしょう:

bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=20.3&label=Luke-Jr

BIP32: Hierarchical Deterministic Wallets

よく「HD ウォレット」と略されて言われるヤツです。従来的な方法だと新しいアドレスを作る度に乱数が振られるため、コンピュータがクラッシュしてハードディスクが吹っ飛んでしまうなどの事故から守るためにはアドレス作成時に毎回ウォレットのバックアップを取る必要がありました。HD ウォレットは一つの親となる秘密鍵(マスター拡張秘密鍵)から決定論的(Deterministic)かつ階層的(Hierarchical)に子供のアドレスを作っていくことのできるアルゴリズムとなっております。

拡張鍵には hardened と non-hardened (normal) という二種類が存在し、区別して利用されています。hardened な鍵を表す際には、子鍵のインデックス番号に H または ‘ をつけることになっており、例えば m/0/1’ はマスター拡張鍵の 0 番目の non-hardened 鍵の 1 番目の hardened 鍵、というふうになります。

BIP 39: Mnemonic code for generating deterministic keys

HD ウォレットのマスター鍵は 512 ビットの乱数から作られますが、この乱数を通常通り 16 進数などで表記すると、書き写し間違える可能性が高く、また記憶することもほとんど不可能です。そこで(英)単語のリスト(ニーモニック)を元にマスター鍵の乱数を作るという仕様が考えられました。こうすることで、記憶がしやすく、また書き間違えも 16 進数表記と比べればずっと減ることでしょう。

実際に作られるニーモニックの例は

legal winner thank year wave sausage worth useful legal winner thank yellow

といったもので、セキュリティ強度に応じて 12〜24 個の単語となります。単語は 2,048 個(〜11ビット)の単語リストから選択されるため、実際のセキュリティ強度は(チェックサムを除くと)128〜256ビットの強度となります。

Bitcoin Core、モバイルウォレット、ハードウェアウォレットなどを含む最近のウォレットはほとんどすべてこの仕組みを採用しており、初回起動時にはバックアップとして 12〜24 語のニーモニックを書き留めることを要求されるウォレットが多いです。また鍵の計算は同じ計算方式で行われているため、あるウォレットで用いられていたニーモニックを別のウォレットに読み込ませることで、互換性を保ったままウォレット間を移動できることも特徴の一つと言えるでしょう。

お知らせ

■HashHubでは入居者募集中です!
HashHubは、ブロックチェーン業界で働いている人のためのコワーキングスペースを運営しています。ご利用をご検討の方は、下記のWEBサイトからお問い合わせください。また、最新情報はTwitterで発信中です。

HashHub:https://hashhub.tokyo/
Twitter:https://twitter.com/HashHub_Tokyo

■ブロックチェーンエンジニア集中講座開講中!
HashHubではブロックチェーンエンジニアを育成するための短期集中講座を開講しています。お申込み、詳細は下記のページをご覧ください。

ブロックチェーンエンジニア集中講座:https://www.blockchain-edu.jp/

■HashHubでは下記のポジションを積極採用中です!
・コミュニティマネージャー
・ブロックチェーン技術者・開発者
・ビジネスディベロップメント

詳細は下記Wantedlyのページをご覧ください。

Wantedly:https://www.wantedly.com/companies/hashhub/projects

--

--