Bitcoin Cashの定期ハードフォーク(2020-05-15)の解説

コールドウォレット開発グループの原です。

2020年5月15日にBitcoin Cash (BCH)の定期ハードフォークが行われました。
ここでは、今回のハードフォークの内容を解説します。

変更点の概要

今回のハードフォークで変更されるコンセンサスルールは下記の2点です。

  • 署名検証に関する制限の変更
  • 新しいOP_CODE OP_REVERSEBYTESの追加

推奨されるノードの実装ポリシーの変更は下記の2点です。これらはコンセンサスルールの変更ではありません。

  • mempool内にあるトランザクションの連鎖数の上限を変更
  • 次回のハードフォークに備えた自動リプレイプロテクション

また、今回のハードフォークでは提案されたものの実際には有効化されなかったルールがあります。これについても最後に紹介します。

署名検証に関する制限の変更

BitcoinにはCPUの負荷を抑えるため、トランザクションやブロックに含められる署名検証用OP_CODEの数に制限があります。 しかし、今までの制限はスクリプトの実行前に評価されるため、実際に実行されないOP_CODEもカウントされるなどの問題がありました。 そこで、今までの制限を廃止しSigCheckと呼ばれる新しい制限が導入されました。

以降ではSigCheckで変更されたルールについて説明します。

OP_CODEのカウント方法の変更

スクリプトを実行し、評価したOP_CODEによって下記のルールでカウントします。

OP_CODE 条件 カウント
OP_CHECKSIG / OP_CHECKSIGVERIFY / OP_CHECKDATASIG / OP_CHECKDATASIGVERIFY 署名がNULL +0
署名がNULL以外 +1
M-of-N OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY M個の署名が全てNULL +0
Schnorrモード +M
ECDSAモード +N

マルチシグに関して

  • Schnorrモード
    前回のハードフォークで追加された、マルチシグでシュノア署名を使う場合の検証方法のことです。
    Schnorrモードはcheckbitsを使って署名に対応する公開鍵を明示的に指定するため、署名の検証はM回だけ行います。

  • ECDSAモード
    従来のECDSAによる検証方法のことです。
    ECDSAモードは署名に対応する公開鍵が分からないため成功するまで繰り返し署名の検証を行います。したがって、最大N回署名の検証が発生します。

ブロックの制限

ブロックあたりのカウント <= ブロックサイズの上限 / 141

141という値は、一般的なP2PKHトランザクションのインプットに由来しています。
P2PKHのインプットはシュノア署名を使った場合141バイトになり、1つのOP_CHECKSIGで検証されます。

2020年5月15日時点のブロックサイズの上限は32MBなので226950カウントが上限になります。

トランザクションの制限

トランザクションあたりのカウント <= 3000

これはメインネットのStandard Transactionの制約に由来しています。Standard Transactionの制約はノードがトランザクションを受け入れる際にチェックされるルールのことです。

メインネットのStandard Transactionのルールではトランザクションサイズの上限が100000バイトです。 また、後述するトランザクションのインプットの制限によってscriptSigの上限は1カウントあたり33.5バイトになります。 そのため、1トランザクションに含められるのは100000 / 33.5から約3000カウントが上限になります。

トランザクションのインプットの制限

トランザクションのインプットあたりのカウント <= (scriptSigの長さ + 60) / 43
このルールはコンセンサスルールではなく、Standard Transactionのチェックにのみ適用されます。

この式は今までのStandard Transactionで有効なマルチシグに由来しています。マルチシグは実際のトランザクションに含められるSigCheckのカウントが多いため選ばれています。

有効なマルチシグの中でカウントの多くなる組み合わせとして、ECDSAの1-of-3 P2MSと1-of-15 P2SHマルチシグを考慮します。
SigCheckのカウントをS、scriptSigの長さをLとすると、1-of-3 P2MSは(S=3, L=72.5)、1-of-15 P2SHマルチシグは(S=15, L=589.5)になります。
ここからS = (L + 56.75) / 43.08333が上限となり、値を丸めて上記の式になります。

このルールをscriptSigの長さについてみると
scriptSigの長さ >= 43 * トランザクションのインプットあたりのカウント - 60
となります。
scriptSigの長さが最小になる場合について考えます。
最小になるのはカウントが2のときで、43 * 2 - 60の26バイトです。 このscriptSigをトランザクションのインプットに使う場合、他にTXIDなど41バイト必要なデータを追加して67バイトになります。
したがって、1カウントあたりのサイズは最低でも67 / 2の33.5バイト必要になります。これが前述したトランザクションの制限に影響します。
ただし、26バイトのscriptSigはStandard Transactionでは実現できないため、実質的な最小値はカウントが3でscriptSigが69バイトのときになります。この場合、1カウントあたり(69 + 41) / 3の36.67バイト必要になります。

今までの制限の廃止

今まであった下記の4つの制限は廃止されます。

  • ブロック1MBあたり20000カウント
  • トランザクションあたり20000カウント
  • トランザクションあたり4000カウント (Standard Transactionのチェックのみ)
  • P2SHのインプットあたり15カウント (Standard Transactionのチェックのみ)

新しいOP_CODE OP_REVERSEBYTESの追加

OP_REVERSEBYTESはスタックの先頭にあるバイナリデータの順序を逆順にします。データのエンディアンを変換するために使うことが想定されています。

仕様

<bin> OP_REVERSEBYTES

<bin>の順序を反転してスタックの先頭に追加します。

詳細

Bitcoin Scriptを含め、Bitcoinのプロトコルは原則リトルエンディアンが使われています。 しかし、一般的なプロトコルではビッグエンディアンも広く使われており、そのデータをBitcoin Scriptで扱うには変換が必要です。

今までのBitcoin Scriptでエンディアンを変換するには、OP_SPLITOP_SWAPおよびOP_CATを組み合わせて1バイトずつ反転するという方法がありました。ただし、この方法はスクリプトが複雑なうえに、変換対象のデータサイズが固定長かつ短い場合しか使えないなどの制約があります。 そこでOP_REVERSEBYTESが導入され、よりシンプルで制約の少ない方法で実現できるようになりました。

OP_REVERSEBYTESの期待されるユースケースとしては、BCH上のトークン発行プロトコルであるSimple Ledger Protocol (SLP)があります。 SLPはビッグエンディアンでエンコードされたデータをOP_RETURNでトランザクションに記述するプロトコルです。

SLPの情報をCovenants1などのBitcoin Scriptを使ったコントラクトで扱おうとすると、トークンの送金額などを数値として扱うたびにエンディアンの変換が必要になります。OP_REVERSEBYTESによりそのような操作を簡潔に記述できるようになると、手数料の削減やより高機能なスクリプトを実現できるようになります。

mempool内にあるトランザクションの連鎖数の上限を変更

今まで25だったmempool内にあるトランザクションの連鎖数の上限を50に引き上げます。

この上限は元々、ブロックに含めるトランザクションの選択にかかる時間がトランザクションの連鎖数に依存していたため設けられたものでしたが、トランザクション選択アルゴリズムの改善などにより上限の引き上げが行われました。

短時間で多くのトランザクションを発行する必要のあるアプリケーションはこの変更により制限が緩和されます。

次回のハードフォークに備えた自動リプレイプロテクション

次回(2020年11月15日)に予定されているハードフォークの際に自動でネットワークが分離するためのリプレイプロテクションです。

BCHの場合、定期ハードフォークがある度に同様の処理が行われています。

Infrastructure Funding Plan For Bitcoin Cash (IFP)について

最後に、今回のハードフォークで議論されたものの有効化されなかったIFPという仕様について紹介します。

これは、マイナーが受け取るブロック報酬のうち5%をBCHのノード実装やプロトコル開発などの開発者コミュニティに送金することを強制するルールです。BIP 9の仕組みを利用してマイナーの66%が賛成すれば有効化されることになっていました。

大手マイナーのBTC.TOPのCEOが提案し、ノード実装のひとつであるBitcoin ABCによって実装されましたが、送金対象となる開発者の選び方が不透明であることや仕様が固まらないまま実装されたことなどからBCHのコミュニティで大きな議論となりました。

ここでは、議論の中で生まれた2つのプロジェクトを簡単に紹介します。

Bitcoin Cash Node (BCHN)

Bitcoin Cash Nodeは、IFP反対派によって作られたBitcoin ABCからIFPを取り除いたノード実装です。 Bitcoin ABCやBitcoin Unlimitedなどの既存ノードの開発者も参加しています。

Flipstarter

FlipstarterはBCH上のコントラクトを利用した資金調達の仕組みです。SIGHASH_ANYONECANPAYを利用してトラストレスな仕組みを実現しています。
IFPによる資金調達の代案としてこの仕組みが使われ、下記のノード実装が資金を募集しました。

ノード実装 目標額 結果
Bitcoin Cash Node 978BCH 成功
Bitcoin ABC 1000BCH 失敗
BCHD 360BCH 成功
Bitcoin Verde 241BCH 成功
Knuth 460BCH 成功

おわりに

Bitcoin Cashの定期ハードフォークの内容について解説しました。
今回は主にBitcoin Scriptやトランザクションの制約を緩和する変更が行われました。これによってよりBCHを使うアプリケーションの幅が広がることが期待できます。

また、IFPに関する議論ではコミュニティ主体の開発で必ず問題になる開発資金に焦点があてられました。 結果的にIFPは有効化されませんでしたが、代替案としてBCHNやFlipstarterなどのプロジェクトが生まれコミュニティに受け入れられたのは今後の開発においても大きな成果です。

次回の定期ハードフォークは半年後の2020年11月15日に予定されています。内容はまだ公開されていませんが今後も注目したいと思います。

一緒にCoincheckを盛り上げてくれるメンバーを募集しています!

様々なポジションを募集しておりますので、是非ご興味ある方はご応募ください。まずは話を聞いてみたいという方も大歓迎です。

参考資料


  1. Covenantsは以前の記事で紹介したコントラクトです