Develop with pleasure!

福岡でCloudとかBlockchainとか。

ブロックチェーンに埋め込まれているBitcoinのホワイトペーパーをデコードしてみる

CWSによる著作権の訴えで最近話題になってるBitcoinのホワイトペーパーについて、Bitcoin Optechのニュースレターで取り上げられてたStackExchangeの記事↓

bitcoin.stackexchange.com

が面白かったので、Bitcoinブロックチェーンに埋め込まれているBitcoinのホワイトペーパーをデコードしてみる。

Bitcoinのホワイトペーパーのデータが記載されているトランザクションは、2013-04-07のブロック230009に格納された54e48e5f5c656b26c3bca14a8c95aa583d07ebe84dde3b7dd4a78f4e4186e713。サイズが400KB弱とBitcoinトランザクションとしては巨大なトランザクションだ。

このトランザクションは1つのインプットと948個のアウトプットを持っている。このアウトプットの内、945個が以下のような1 of 3のrawマルチシグのアウトプットで(↓は最初のアウトプット)、

1 e4cf0200067daf13255044462d312e340a25c3a4c3bcc3b6c39f0a322030206f626a0a3c3c2f4c656e6774682033203020522f46696c7465722f466c6174654465 636f64653e3e0a73747265616d0a789cad5c4b8b24b911becfafa8b3a1da292925654253d0d55373f06d61c007e39bbd061f0cde8bffbe25c55b5266f61ab3905d 9ba54728e28bb76a963777fbcfb77fdf96db7d291f93f3e599f7fafcedefb73fffe1f6aff665fdefb77f7c7bfefce6c2fa166e695bdfd6dbcfbfddfef8c3dd5cf9 3 OP_CHECKMULTISIG

そして946個めが1つだけ1 of 1のrawマルチシグ。残り2つはP2PKHアウトプット。

なお、PDFのデータは%PDF-で始まり、これをhex値にすると255044462d。↑の3 of 3のマルチシグの最初の公開鍵

e4cf0200067daf13255044462d312e340a25c3a4c3bcc3b6c39f0a322030206f626a0a3c3c2f4c656e6774682033203020522f46696c7465722f466c6174654465

にこのデータが含まれているのが分かる。この255044462dを起点として、すべてのマルチシグスクリプトの公開鍵を連結するとBitcoinのホワイトペーパーが生成できる!

bitcoinrbを使ってデコード処理を書くと以下のようになる(トランザクションのhexデータを同じディレクトリの54e48e5f5c656b26c3bca14a8c95aa583d07ebe84dde3b7dd4a78f4e4186e713というファイルに保存してる前提)。

require 'bitcoin'

tx = Bitcoin::Tx.parse_from_payload(File.read(File.join(File.dirname(__FILE__), '54e48e5f5c656b26c3bca14a8c95aa583d07ebe84dde3b7dd4a78f4e4186e713')).htb)

File.open('bitcoin.pdf', mode = 'w') do |f|
  tx.outputs[0...-2].map.with_index do |o, i|
    data = o.script_pubkey.get_multisig_pubkeys.map.with_index do |p, j|
      if i == 0 && j ==0
        p[(p.index("%PDF-"))..-1]
      elsif i == 945
        p[0...-8]
      else
        p
      end
    end.join
    f.write data
  end
end

実行すると同じディレクトbitcoin.pdfが生成される。

最後のマルチシグの公開鍵はサイズを合わせるため8バイト分0が埋まってるので、それを取り除いたデータサイズは184292バイトになる。ちなみに、最初の公開鍵の255044462dの前にあった先頭8バイトe4cf0200067daf13の内、先頭4バイトe4cf0200は、このサイズをリトルエンディアンで表したもので、後半4バイト067daf13は生成したPDFのCRC32の値をリトルエンディアンで表したものになる。

もともとBitcoinのホワイトペーパー自体はそんなに長いペーパーではなかったけど、1トランザクションに埋め込めるものなのね。

ちなみに、StackExchangeの回答にはフルノードのRPCを実行して、これを1行で行うコマンドが掲載されてる