用語集 / 開発者向けリファレンス
内部バイト順
- 内部バイト順とは?
- 内部バイト順とは、ビットコインがシリアライズされた構造の内部で用いる配置のことです。整数は最下位バイトを先頭に書かれ、ハッシュ値はSHA-256が生成した順序のまま書かれます。
1つの名称の下に2つの慣習があります。トランザクションやブロックヘッダーの整数フィールドはすべてリトルエンディアンなので、バージョン番号2は02000000と書かれ、32バイトのハッシュはすべて、ハッシュ関数が出力したとおりの形で生データの中にあります。人間向けのツールは、表示する前にこれらのハッシュを反転します。手書きのパーサーがブロックエクスプローラーと食い違う最も一般的な理由はこれです。
仕組み
内部バイト順は、80バイトのジェネシスブロックのヘッダーを分解して学ぶのが最善です。その中のすべてのフィールドは、目視で確認できるほど小さいからです。
冒頭は01000000で、バージョン番号1を4バイトのリトルエンディアンで表したものです。続いて32バイトのゼロが並びます。最初のブロックには親がないためです。続いてマークルルートが、3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4aとして格納されます。これは、すべてのエクスプローラーが4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33bと表示するダイジェストを、1バイトずつ逆順にしたものです。続いて29ab5f49、タイムスタンプ1231006505、つまり2009年1月3日の18:15:05 UTCを意味します。続いてffff001d、論理値が0x1d00ffffである難易度フィールドです。続いて1dac2b7c、ナンス2083236893です。
金額も同じ規則に従います。1ビットコインは100,000,000サトシであり、ちょうどその額を支払うアウトプットは8バイトの00e1f50500000000を伴います。
理由は歴史的なもので、かなり平凡です。ビットコインは、整数を最下位バイト先頭で保持するx86マシン向けに書かれ、初期のコードはプロセッサがすでに持っていた並びのまま構造を書き出していました。ハッシュはまったく反転されませんでした。変わったのは表示の側です。Bitcoin Coreはダイジェストを1つの巨大な数として扱うクラスに格納し、数は最上位の部分を左に置いて表示するからです。
どこで目にするか
内部バイト順は、ツールが整形された回答ではなく生のバイトを返すときはいつでも得られるものです。
getrawtransactionをverboseフラグなしで実行してトランザクションを取得するか、getblockheaderでverboseをfalseに設定してヘッダーを取得すると、内部のすべてがこの順序で届きます。ハードウェアウォレットがエクスポートしたPSBT、エクスプローラーの生データタブの背後にある16進数、ノードのblocksディレクトリにあるブロックファイルについても同じことが当てはまります。
人をつまずかせるフィールドは、すべてのインプットの先頭にあるアウトポイントです。これは使用されるトランザクションを、エクスプローラーが表示した識別子の逆順として読める32バイトで指し示します。これらの2つの文字列が一致しなくても、何も壊れていません。片方を反転すれば一致します。
内部バイト順vs RPCバイト順
内部バイト順とRPCバイト順は、逆方向に流れる同じ32バイトを表しており、両者を変換する規則には1つの重要な例外があります。ハッシュ値は人間へ出力する際に反転され、入力する際に再び反転されます。整数はそうではありません。ブロック高、タイムスタンプ、サトシ単位の金額はいずれも通常の10進数として提示され、それらのいずれかを入力時または出力時に反転すると、別の書き方になるのではなく、単に誤った値になります。ハッシュだけを反転し、それ以外は何もしなければ、大半のバイト順のバグは消えます。