こんにちは、CTOの森下です。

Bitcoin CashのアドレスはBitcoinのアドレスと混同されないように独自の仕様があります。 今回は、その仕様を日本語に翻訳しました。

要旨

 この文書では、Bitcoin Cashで使用されるアドレス形式について説明する。 これは、base32でエンコードされ、BCH符号[1]をチェックサムとし、リンクやQRコードで直接使用できる形式である。

 この形式はBech32[2]の仕様を再利用しており、似ている点はあるが、改良されている。

仕様

 このアドレスは以下で構成されている。

  1. 正しいアドレスのネットワークを示す接頭辞
  2. 区切り文字は :
  3. チェックサムを含む宛先を示すbech32でエンコードされたペイロード

接頭辞

 この接頭辞はこのアドレスが有効なネットワーク示す。 これは、Bitcoin Cash mainnetでは bitcoincash、Bitcoin Cash testnetでは bchtest、Bitcoin Cash regtestでは bchregが設定される。

 この接頭辞の後には区切り文字の : が続く。

 この接頭辞はチェックサム計算の一部で省略されるかもしれないが、チェックサムは明示的に接頭辞がなくても、異なるネットワークのアドレスに互換性がないことを保証する。

ペイロード

 ペイロードはbase32でエンコードされたデータ列である。

0 1 2 3 4 5 6 7
+0 q p z r y 9 x 8
+8 g f 2 t v d w 0
+16 s 3 j n 5 4 k h
+24 c e 6 m u a 7 l

ペイロードは以下の3要素で構成される。

  1. アドレスの形式を示すバージョンバイト
  2. ハッシュ
  3. 40ビットのチェックサム

バージョンバイト

 バージョンバイトの最上位ビットは予約されており、0でなければならない。 次の4ビットはアドレスの形式と示し、残された下位3ビットはハッシュサイズを示す。

サイズビット ハッシュサイズ
0 160
1 192
2 224
3 256
4 320
5 384
6 448
7 512

バージョンフィールドにハッシュサイズをエンコードすることでアドレスの長さが正しいかどうかを確認することができる。

タイプビット 意味 バージョンバイトの値
0 P2KH 0
1 P2SH 8

さらに、新しい機能が追加されるとタイプが追加される。

ハッシュ

 ハッシュパートはバージョンフィールドに依存しているのであまり説明はしない。 このハッシュとは、公開鍵のハッシュ (P2KH) やスクリプトのハッシュ (P2SH) である。

チェックサム

 チェックサムは GF(2^5) で定義された40ビットのBCH符号である。 これは、8回連続でアドレスのエラーを最大6個検出することができる。 長さのチェックと組み合わせることで、エラーに対する非常に強い保証が得られる。 チェックサム計算のコードを以下に示す。

uint64_t PolyMod(const data &v) {
    uint64_t c = 1;
    for (uint8_t d : v) {
        uint8_t c0 = c >> 35;
        c = ((c & 0x07ffffffff) << 5) ^ d;
        
        if (c0 & 0x01) c ^= 0x98f2bc8e61;
        if (c0 & 0x02) c ^= 0x79b76d99e2;
        if (c0 & 0x04) c ^= 0xf33e5fb3c4;
        if (c0 & 0x08) c ^= 0xae2eabe2a8;
        if (c0 & 0x10) c ^= 0x1e4f43e470;
    }
    
    return c ^ 1;
}

 チェックサムは以下のデータ (範囲0-31の整数列) によって計算される。

  1. 接頭辞の各文字の下位5ビット。 例: bit...2,9,20,... となる
  2. 区切りとしての5ビットの0
  3. 5ビットでひとかたまりのペイロード。5ビットに満たないチャンクの場合は、右に0埋めをする。
  4. チェックサムのテンプレートとしての8個の0

 ペイロードとチェックサムはbase32の文字表に従ってエンコードされる。 base32形式のアドレスを検証するには、コロン : で接頭辞とペイロードに分ける。

PolyModの入力データ (整数列) は以下のパーツで組み立てられる。

  1. 接頭辞の各文字の下位5ビット
  2. 区切りとしての5ビットの0
  3. base32の文字に対応したペイロードの数字。もし、PolyModが0以外を返した場合、そのアドレスは無効なものである。

 以下のアドレスはチェックサム計算のテストベクトルとして使うことができる。

  • prefix:x64nx6hz
  • p:gpf8m4h7
  • bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn
  • bchtest:testnetaddress4d6njnut
  • bchreg:555555555555555555555555555555555555555555555udxmlmrz

注意: これらのアドレスは有効なペイロードではない。

誤り訂正

 BCH符号は誤り訂正が可能である。 ただし、 誤って実行された場合、資金が取り戻せなくなる可能性があるため、自動的には行わないことを強く勧める。 だが、ユーザにエラーを伝えるために使用されることもある。

大文字 / 小文字

 キャッシュアドレスでは小文字が好ましいが、大文字も許容する。大文字と小文字の混合の場合は拒否されなければならない。 大文字を使用すると、Alphanumeric モード[3] を使用したQRコードで効率的にアドレスをエンコードできる。

二重接頭辞

 支払いに関するURLやQRコードなどにおいては、bitcoincash: の接頭辞が付く。 ここでは、二重の接頭辞があってはならない。

アドレス変換の例

 以下にレガシーアドレスからキャッシュアドレスへの変換例を示す。

レガシーアドレス キャッシュアドレス
1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a
1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy
16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r
3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq
3LDsS579y7sruadqu11beEJoTjdFiFCdX4 bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e
31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37

参考文献