2018.02.27 (Tue) technology

Segwitのウォレットサポートを実装したBitcoin Core 0.16.0がリリース

Written by 安土 茂亨

2月26日、Bitcoin Coreの新しいメジャーバージョンBitcoin Core 0.16.0がリリースされた。0.16.0では主にウォレット関連の機能が強化されており、そのメインとなるのがウォレットのSegwitサポートだ。その他にもいくつか変更が加わっているので、主な変更点についておさえておこう。

ウォレットのSegwitサポート

Bitcoin Coreは2016年11月にリリースされた0.13.1からフルノードとしてSegwitをサポートしているが、ウォレット機能では長らくSegwitがサポートされない状態が続いた。今回リリースされた0.16.0からBitcoin CoreのウォレットでもSegwitのUTXOの管理および、Segwitの新しいアドレスフォーマットBech32がサポートされるようになった。

Bech32アドレスの生成

Segwitを使用する際のロックスクリプト(scriptPubkey)は従来のP2PKH(公開鍵ハッシュへの支払い)とP2SH(スクリプトハッシュへの支払い)のロックスクリプトと異なり以下のような構成になっている。

  • P2WPKH(P2PKHのSegwit版)
    0 <公開鍵のハッシュ>
  • P2WSH(P2SHのSegwit版)
    0 <スクリプトのSHA256ハッシュ>

従来のロックスクリプトとは構成が異なるので今までのアドレスフォーマット(1から始まるP2PKHや、3から始まるP2SH)とは異なり、別のアドレスフォーマットが必要になり、それがBIP-173で定義されたBech32というアドレスフォーマット(bc1から始まるアドレス)だ。

既存の他のウォレットでもBech32をサポートしているものはまだ少なく、P2WPKHやP2WSHをP2SHでネストして使っているウォレットが主流だが、今回のBitcoin Core 0.16.0からこのBech32のアドレスタイプをサポートするようになる。

CLIでは既存の getnewaddress および addmultisigaddress RPCに以下のアドレスタイプを指定する引数が追加された。

  • legacy
    今までと同様Base58エンコードされたP2PKHアドレスを生成
  • p2sh-segwit (デフォルト)
    P2WPKHをP2SHでネストしたP2SHアドレスを生成
  • bech32
    Bech32のアドレスフォーマットでP2WPKHのアドレスを生成
    (mainnetは”bc1”から始まり、testnetは”tb1”から始まる)

bech32を指定すると以下のようにBech32ベースのアドレスが生成される(””の部分はアカウント)。


$ bitcoin-cli getnewaddress "" bech32
bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

GUI環境であるbitcoin-qtを利用している場合はアドレス作成時にアドレスタイプを選択できないので、bitcoin-qtの起動時に --addresstype オプションで指定する必要がある(例: $ bitcoin-qt --addresstype=bech32)。

また送金トランザクションを作成する際、送金先のアドレスがP2WPKHかP2WSHの場合は、お釣り用のアドレスと送付先のアドレスの区別が付かないようにするため、お釣り用のアドレスもデフォルトでP2WPKHアドレスが使用されるようになる。お釣り用のアドレスを生成する getrawchangeaddress RPCも アドレスタイプを指定する引数が追加されている。

なお、getnewaddress RPCでbech32のアドレスが生成できるようになったため addwitnessaddress RPCは廃止される予定だ。

一部のRPCコマンドではSegwitアドレスを未サポート

signmessage や verifymessage 、 importmulti RPCではまだSegwitアドレスをサポートしておらず、今後のバージョンで引き続き追加される予定だ。

SegwitのUTXOおよび鍵の管理

Bech32のアドレスで受信したコインも listunspent RPCで確認でき、SegwitトランザクションのUTXOも管理できるようになっている。


$ bitcoin-cli -testnet listunspent         
[
  {
    "txid": "a91ddd4d17b1c1cda9bcdb1ebb95ebeb375af3bea974c67b9470d176e850baba",
    "vout": 1,
    "address": "tb1qtr8rf2esn3ej2yxu7j0e9qexttskc7p3yluywq",
    "account": "",
    "scriptPubKey": "001458ce34ab309c732510dcf49f9283265ae16c7831",
    "amount": 0.29999673,
    "confirmations": 2,
    "spendable": true,
    "solvable": true,
    "safe": true
  }
]

dumpwallet RPCでは今まで各アドレスの秘密鍵がエクスポートされていたが、0.16.0からそれに加え、P2SHでネストしたP2WPKHのオリジナルのスクリプト(ネスト対象のP2WPKHのスクリプト)が含まれるようになり、importwalletを実行した際にこれらのスクリプトもインポートされるようになる。

HDウォレットがデフォルトに

Segwitのサポート以外にも0.16以降のウォレットでは、階層的決定性(HD)ウォレットが標準となる。旧バージョンのウォレットのデータファイルが無い場合、デフォルトでHDウォレットが生成される。(※ 0.16以降で生成したウォレットファイルは以前のバージョンでは動作しない。)

ただ、Bitcoin CoreのウォレットがサポートするのはあくまでBIP-32のHDウォレットの仕様で、今のところTREZORや他の多くのウォレットがサポートしている、複数のアカウントをサポートするBIP-44や、復元フレーズを使ったマスターシードの復元をサポートするBIP-39などはサポートしていない。

BIP-44では以下のような階層でHDウォレットの鍵導出をするが


m / purpose' / coin_type' / account' / change / address_index

  • purpose’: 準拠する仕様(BIP-44の場合は44の強化導出)
  • coin_type': コインの種類(各コインの種類はSLIP-44で定義されている)
  • account': アカウントのインデックス
  • change: 外部チェーン=0(コインの受取用アドレス)、内部チェーン=1(お釣り用のアドレス)
  • address_index: アドレスのインデックス

Bitcoin Coreでは以下のようなシンプルな階層になっている。


m / account' / change’ / address_index

GUI環境でRBFがデフォルトに

RBF(Replace by Fee)はBIP-125で定義された仕様で、トランザクションを作成しブロードキャストしたものの、手数料が少なく中々ブロックに入らないといった場合に、そのトランザクションを手数料を上乗せしたトランザクションに置き換える仕組みだ。

RBFを利用するには予めトランザクションインプットのシーケンスに最大値より小さい値をセットすることでRBFのトランザクションであることをマーキングする。インプットのシーケンスの値が最大値の場合、RBFは利用できない。

これまで、 -walletrbf オプションを付与して起動した場合のみRBFが有効になっていたが、GUI環境では -walletrbf オプションに関係なくRBFがデフォルトになり、RBFのマーキングがされたトランザクションがデフォルトで生成される。RBFを使用したくない場合は、送金時に「Replace-By-Feeを有効」のチェックボックスのチェックを外す必要がある。

なお、RPCの方は今まで通り -walletrbf オプションを付与して起動するか、個々のトランザクションを指定する際にreplaceable引数を指定しない限りRBFは使用されない。

最初は低めの手数料を設定しておき、承認されない場合にRBFで手数料を上乗せすることで無駄に高い手数料を払うようなことがないようRBFの仕組みをGUI環境でデフォルトにしたものと考えられる。ただ、RBFによって必ず置換されたトランザクションが早くブロックに入るという保証は無いので、その点は注意が必要だ。

プルーニングノードのシグナリングをサポート

Bitcoin Coreは全てのブロックチェーンデータを保持するフルノードだが、ディスク使用量を抑えたい場合に、UTXOは保持したまま古いRAWデータやUNDOデータを削除しディス使用量を劇的に削減するプルーニング(剪定)モードというのが利用できる。

プルーニングモードを有効にしているノードは、古いブロックチェーンデータを削除しているため、他のノードから古いブロックを要求されても、そのデータを返せない。そのためプルーニングモードが有効になっている場合、他のノードにservice bits ”NODE_NETWORK” を通知しないようになっている(”NODE_NETWORK”は全ブロック要求に応えることができることを相手に通知するためのフラグ)。

ただ、プルーニングノードであっても、古いブロックデータの要求には応えられないが、直近のブロークデータは保持しているため、これらのブロックやヘッダ、トランザクションについてはリレーできるようにしようというBIP-159が提案された。

このためには、まずプルーニングノードであることを接続先のノードに通知する必要があるので、新たなservice bits ”NODE_NETWORK_LIMITED”が定義され、0.16.0からプルーニングノードはこのservice bitsを通知するようになった。

現状はこのシグナリングのみで、ブロックの同期が完了したノードであればプルーニングノードにも接続するようにする機能は今後のバージョンで追加される予定だ。

新しいRPCの追加

0.16.0から以下のRPCが追加されている。

  • rescanblockchain
    ブロックチェーンの再スキャンをするためのRPC。再スキャンの対象ブロック(開始ブロック高と終了ブロック高)を指定でき、マルチウォレット環境で実行時にブロックチェーンを再スキャンするのに使用可能。
  • savemempool
    クラッシュや停電などでメモリプールが失われないよう、メモリプールの内容をディスクに保存するRPC。

セーフモードがデフォルトで無効に

Bitcoin Coreにはセーフモードという、ネットワークで特定の問題が発生すると自動的にウォレットや送信に関するRPCを無効化し、ウォレットデータを保護する機能がある。ただこのチェック機能については、十分な信頼性が無いとみなされ、今回デフォルトで無効化されることになった(有効化するためには起動オプションとして -disablesafemode=0 を指定する必要がある)。
なお、無効化されても getneworkinfo の wargings は引き続き警告が表示され、-alertnotify コマンドも起動する。

この他にも細かい修正が行われており、詳細はリリースノートを参照してほしい。

0.16.0のリリースでは主にウォレットの機能強化が中心で、特に重要なのがウォレットのSegwitのサポートだ。現時点でBitcoinのブロックチェーンのトランザクションデータの内、Segwitトランザクションの割合は15%程度だが、他の多くのウォレットでもBech32アドレスのサポートが広がり、Segwitトランザクションの比率が上がっていくことを期待したい。


無料メールマガジン

BTCNの最新ニュースを毎日お昼ごろお届けします!


まだデータがありません。