Bitcoinホワイトペーパーをブロックチェーンから抽出する
先週はLuke Dash Jr氏が運営する新興マイニングプールがOrdinals Inscriptionsを検閲していることが話題になっていましたが、今週も引き続きLuke Dash Jr氏がビットコインをデータ置き場に使うユースケースに対する反発を行動に移しており、Bitcoin Coreのトランザクションリレーポリシー (ノードが隣のノードから受け取ったトランザクションを他のノードに転送する際の条件) のうちトランザクションに関係ないデータ量を判定するコードがInscriptionsのデータサイズを見落としているのはバグだと指摘し、修正案を提出するなどしています。
先週の記事↓
この「バグFIX」に関してツイッター上の日本語Ordinalsファン界隈 (そんなものがあるようです) で誤解が広まりつつあったので、この機会にSpotlightに説明記事を投稿させていただきましたので、ぜひそちらもご覧ください。

さて、ビットコイン上に通貨と無関係なデータを記録したのはOrdinals Inscriptionsが初めてではありません。ジェネシスブロックにはかの有名な"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."という文章が埋め込まれ、10年前には1つのトランザクションでビットコインのホワイトペーパーのPDFが埋め込まれているケースもありました。
今日は忘年会で披露する豆知識として使える、ビットコイントランザクションにいかにホワイトペーパーが埋め込まれたか、そしてどのように復元できるかを見ていきましょう。
・データの様々な埋め込み方とInscriptionsの元祖
・マルチシグを使って埋め込まれたPDFの読み取り方
・おまけ:ジェネシスブロックの文章はどう埋め込まれている?
データの様々な埋め込み方とInscriptionsの元祖
個人レベルでオンチェーンで行われてきた様々な実験はどこかにまとめられて発表されているわけでもなく、各フルノードがもつブロックチェーンデータの海を漂っています。
この歴史を掘り起こしている「オンチェーン考古学者」とでも呼ぶべきユーザーがときどきツイッターに発見したものを共有してくれています。例えば以下の画像は米イリノイ州のオーガスタナ・カレッジという大学の雪景色で、2017年7月に非常に大きなトランザクションによって埋め込まれています。(埋め込むトランザクションのOP_Returnに復元方法も簡潔にメモされています)
Found this (new to me) transaction while exploring nulldata outputs in the blockchain.
— ottosch (@ottosch_) December 14, 2023
Pre-segwit, it inscribes a 72KB JPEG using 48 P2SH inputs (no signatures).
Paid 780K sats at 10 sat/vb.
Msg: "Augustana College Old-Main.jpg Reconstruct with data preceding redeemscripts". pic.twitter.com/L0OtDfwkhc
この画像はP2SHと呼ばれるスクリプトによってロックされたコインを消費するときにそのスクリプトを公開することを逆手に取って、スクリプト自体にデータを埋め込んでいます。そういう意味ではOrdinals Inscriptionsに非常によく似た発想です。
他にもいくつか方法があります:
・"P2FKH" ― Segwit以前の従来のビットコインアドレス宛の送金をP2PKH (Pay-to-Public-Key-Hash)と呼びますが、任意のデータを埋め込んだでたらめなビットコインアドレスに対して送金してデータを埋め込むことをP2FKH (Pay-to-Fake-Key-Hash)と呼ぶようです。対応する秘密鍵が未知であり永遠にUTXOセットを肥大させてしまうため忌避されますが、近年でも時折スパムトランザクションで見かける種類です。
・"P2FK" ― "P2PK"版のP2FKHで、今ではほとんど使われることのない送金方法である点以外はほぼ同じです。要するに、送金先の公開鍵を指定すべきところにデータを記録してしまう方法ですね。
・OP_Return ― データ保存の定番ですが、ノードのポリシールールによって80バイトまで、1トランザクションにつき1つまでに制限されています。ネットミームとして有名な某曲の歌詞を埋め込んだ2013年のこのトランザクションのように、マイナーに直接提出すれば大きなデータも含めることができます。フルノードからすれば消しても良いデータだと判断できるため一番助かる方法です。
・”P2FMS" ― 公開鍵を直接指定する古いタイプのマルチシグUTXOに向けて送金するタイプのP2FKHと考えてよいです。ちなみに2016年にLuke Dash JrとP2FMSを使ってデータ記録している人たちがスパム対策の設定についてGitHubで揉めているのを発見しました。ずーっと同じようなことが繰り返されています(笑)
・P2SHやP2WSH内のスクリプトにデータを埋め込む ― これがInscriptionsが採用した方式です。Taproot以前からあるP2SHでも同じテクニックを問題なく使えます。これまでのものとの一番大きな違いは最初の送金時 (スクリプトでロックされたUTXOへの送金時)ではなく、次回の送金時 (スクリプトでロックされたUTXOからの送金時)にデータを記録するため、2回のトランザクションが必要になる点です。
これらの方法とその効率性について比較した論文が上記画像のオーガスタナ・カレッジの研究者数人によって2018年に公開されているので、興味のある方はぜひ読んでみてください。(PDFリンク)
マルチシグを使って埋め込まれたPDFの読み取り方
さて、本題のホワイトペーパーが埋め込まれているトランザクションはこちらです。見ての通り大量の旧式マルチシグ(65バイトの公開鍵を送金時に指定する方式)に対して送金しており、上記の分類ではP2FMSに分類されます。
以下のように指定したUTXOを900個以上送金先にしています:
OP_PUSHNUM_1 OP_PUSHBYTES_65 e4cf0200067daf13255044462d312e340a25c3a4c3bcc3b6c39f0a322030206f626a0a3c3c2f4c656e6774682033203020522f46696c7465722f466c6174654465 OP_PUSHBYTES_65 636f64653e3e0a73747265616d0a789cad5c4b8b24b911becfafa8b3a1da292925654253d0d55373f06d61c007e39bbd061f0cde8bffbe25c55b5266f61ab3905d OP_PUSHBYTES_65 9ba54728e28bb76a963777fbcfb77fdf96db7d291f93f3e599f7fafcedefb73fffe1f6aff665fdefb77f7c7bfefce6c2fa166e695bdfd6dbcfbfddfef8c3dd5cf9 OP_PUSHNUM_3 OP_CHECKMULTISIGここから情報を復元するのは比較的シンプルで、このトランザクションのすべての出力から「フェイク公開鍵」の部分だけを抽出してつなぐことでホワイトペーパーのPDFを復元することができます。
好きな言語で勉強がてら実装できるレベルの簡単な問題ですね。ちなみにコマンドライン1行で書いちゃう人もいるようです:出典
bitcoin-cli getblock 00000000000000ecbbff6bafb7efa2f7df05b227d5c73dca8f2635af32a2e949 0 | tail -c+92167 | for ((o=0;o<946;++o)) ; do read -rN420 x ; echo -n ${x::130}${x:132:130}${x:264:130} ; done | xxd -r -p | tail -c+9 | head -c184292 > bitcoin.pdfおまけ:ジェネシスブロックの文章はどう埋め込まれている?
さて、かの有名な"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."という文章はジェネシスブロックに存在します。つまり、消費する既存のUTXOなどが存在しない状況でどのようにして記録されているのでしょうか?
答えは単純で、Coinbaseトランザクション (採掘時に新規発行+手数料分をマイナーのアドレスに送る、ブロック内で一番最初のトランザクション)の入力には最大100バイトまでの任意のデータが含められるため、そこに記録されているのです。現在はマイニングプールの名前などが記録されることが多く、マイニングプールごとのハッシュレートの分布が推定できるのもこのためです。
ジェネシスブロックのCoinbaseトランザクションを見てみると、ScriptSig (HEX)欄は以下のようになっています:
04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73これをASCII文字列に変換すると以下の文章が得られます:
ÿÿEThe Times 03/Jan/2009 Chancellor on brink of second bailout for banks次の記事
読者になる
一緒に新しい世界を探求していきましょう。


ディスカッション