BIP: 347
Layer: Consensus (soft fork)
Title: TapscriptにおけるOP_CAT
Author: Ethan Heilman ethan.r.heilman@gmail.com
Armin Sabouri arminsdev@gmail.com
Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0347
Status: Draft
Type: Standards Track
Created: 2023-12-11
License: BSD-3-Clause
Post-History: 2023-10-21: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-October/022049.html [bitcoin-dev] Proposed BIP for OP_CAT
目的と結論
Bitcoin Tapscriptにスタック上の値を連結する操作(OP_CAT)を導入すべきである。これによって、スタック要素同士の結合がシンプルに行えるようになる。現在の最大スタック要素サイズは520バイトを超えないため、TapscriptでOP_CATを再度有効化してもメモリの過度な使用につながらない。結論として、OP_CATはTapscriptの表現力を強化し、より多様なスクリプト構成を行ううえで重要となる。
背景
2010年にBitcoinの初期コードからOP_CATと他のいくつかのオペコードが無効化された。理由として、スクリプト評価時に指数関数的なメモリ使用が起こり得る懸念があった。しかし最大スタック要素サイズの制限(520バイト)が設けられたTapscriptでは、この問題が発生しない。OP_CATが再び有効化されれば、マークルツリーやハッシュ化データ構造の構築など、多くのユースケースで柔軟性が向上する。
概要
このBIPは、OP_SUCCESS126(10進数126、16進数0x7e)として予約されていたオペコードをOP_CATに再定義し、Tapscriptにおいてスタック上位2つの値を連結する操作を可能にするソフトフォークを提案する。旧来のOP_CATと同じオペコード値(126/0x7e)を使用することで混乱を最小化する。
著作権
この文書はBSD-3-Clauseライセンスで公開する。
仕様
- スタック上に2つ以上の値がない場合、OP_CATは失敗する。
- 連結後のサイズが最大スクリプト要素サイズ(520バイト)を超える場合も失敗する。
- スタック[x1, x2] (x2が最上位の場合)に対して、OP_CATはx1‖x2をスタックにプッシュする。
- tapscriptのOP_SUCCESS126をOP_CATに再定義するソフトフォークにより有効化する。
動機
Tapscriptにはスタック上のデータを組み合わせる汎用手段が不足している。OP_CATが追加されると次のような事例が強化される。
- ビットコイン上でのアトミックスワップや分散型ファイルホスティングシステム等、Bitstreamプロトコルの簡素化
- ツリーシグニチャを用いた大規模マルチシグの実装(最大4,294,967,296個の公開鍵対応)
- ポスト量子暗号的シグネチャ(Lamportシグネチャ)の検討
- 両義性契約やVaultsなどの高度な契約構造
- CheckSigFromStack相当の柔軟なスクリプト支出設計
OP_CATはUnix精神に沿うシンプルでモジュール式な機能を提供し、Tapscript開発者が複雑なハッシュ化データ構造を扱いやすくする。かつてOP_CATはBitcoinに存在していたが、無効化された経歴がある。Tapscriptではスタック要素サイズで安全性が担保されるため、再度の有効化が適切と考える。
理由
tapscriptのOP_SUCCESSxオペコードを活用するアップグレード手段を用いる。かつてのOP_CATと同じ値(OP_SUCCESS126)を再定義することで、余計な混乱を防ぐ。スタック要素サイズを引き上げるかどうかは本提案の範囲外である。提案はOP_CAT単体の再有効化を目的とし、ソフトフォーク実装で行う。
下位互換性
tapscript以外のスクリプトにおいてOP_CATを利用するとSCRIPT_ERR_DISABLED_OPCODEとなる。OP_SUCCESS126をOP_CATに再定義するソフトフォークが成立した後、tapscript上だけでOP_CATが有効となる。
参照実装
case OP_CAT:
{
if (stack.size() < 2)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
valtype& vch1 = stacktop(-2);
valtype& vch2 = stacktop(-1);
if (vch1.size() + vch2.size() > MAX_SCRIPT_ELEMENT_SIZE)
return set_error(serror, SCRIPT_ERR_PUSH_SIZE);
vch1.insert(vch1.end(), vch2.begin(), vch2.end());
stack.pop_back();
}
break;
MAX_SCRIPT_ELEMENT_SIZE
は520である。
この実装は、OP_CATが無効化される前のBitcoinコード(コミット「misc changes」4bd188c)の内容に基づく。Elements実装(13e1103a)でも類似のOP_CATが確認できる。
参照文献
謝辞
Dan Gould、Madars Virza、Jeremy Rubin、Andrew Poelstra、Bob Summerwill、Tim Ruffing、Johan T. Halsethらに感謝する。彼らのフィードバックと評論が本稿に大きく貢献した。