これは ビットバンク株式会社 Advent Calendar 2020 の 20 日目の記事です。
各コインの新しいアドレスについて
bitcoinがbech32を採用したことをきっかけに各コインがインスパイアされ独自のアドレスを採用しはじめました。
独自アドレスを採用した理由はそれぞれですが、ここでは日本で取り扱われている代表的なコインについて解説したいと思います。
bitcoin
動機
bitcoinはsegwitに対応をした際、最初はアドレスが無く既存のbase58を利用したbip-142で規定されたフォーマットが予定されていました。
ところがそれを使わずにbase32に識別子とチェックサムを付けたbech32(bip-173)と呼ばれる方式を開発しました。
いままでの方式と互換性がなく対応したウォレットでないとbech32のアドレスへ送金ができません。
互換性を犠牲にしてなぜ新たに開発したかというと旧来方式であるbase58checkで以下の問題点があるからです。
- base58のデコードが比較的遅い
- エラー検出に使われるHASH256(sha256を2回かける)の処理時間がとても遅く、間違いをかならず検出できる保証もない
- base58は大文字と小文字が混在していて人間に扱いにくい
- base58は英数字モードが使えないためqrコードのデータが大きくなりやすい
bech32は上記問題の改善に加え下記のような特徴があります
- 人が認識しやすい(コインごとのアドレス認識が容易)
base32の特徴
https://tools.ietf.org/html/rfc4648.html
base32はRFC4648で定義されていて標準化された仕様です
特徴は32文字のアルファベットA~Zと数字2~7を使いエンコードされます。
大文字/小文字を使えるが同時には使えません。(大文字・小文字同じ情報になります)
人が見るときには小文字でqrコードでは大文字表記など使い分けできます。
特にqrコードでは大文字にすると英数字モードが使えるので通常にくらべデータが半分近くコンパクトになります。
bech32の特徴
https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
エンコードはbase32の仕様を使っていますが、文字テーブルを変更していて以下の32文字を使います。
qpzry9x8gf2tvdw0s3jn54khce6mua7l
アドレスフォーマットは以下のようになっています
bech32アドレス:[Human Readable Part(bc/ltc/monaなど) | Separator(1固定) | base32 data(witness version + witness program + checksum)]
実際のbech32アドレスは以下のような形式となります
ビットコイン
bc1q0y9s9439wzslcekgze98wr7lhjy4fneagjw2cn
ライトコイン
ltc1q7hhfaxjkf8dn0k7xyglsju4fnt0q9j3s6m39zh
モナコイン
mona1q0n3nf53yqpsk6wmnussq8des5vywwaeme9tsv0
識別子が人が読めるようになっていて bc / ltc / mona などアドレスに通貨名が入っていて一目でなんの通貨のアドレスか分かるようになっています。
この識別子もアドレスの一部のため別のコインの識別子に書き換えてもエラーになります。
そのため同じ識別子が現れない限り、別のコインのアドレスに送ってしまう誤送金がまず起きないでしょう。
実際にbase58形式のアドレスではMから始まるコインが多く誤送金が問題になります。
チェックサムにはBCH符号を使います
この方式では数文字間違えてもエラー訂正ができるが非推奨になっています
仕様の不具合
https://github.com/sipa/bech32/issues/51
強力なエラー検出を持つbech32ですが以下の場合、それが働かないようです。
- アドレスの末尾がpで終わっている場合にpの前に何個 q を追加してもエラーにならない。(アドレスの長さを意図的に長くできる)
- アドレスの末尾がqpで終わっている場合にqを削除してもエラーにならない。
人が入力する場合は写し間違えて抜けたり追加されたりする可能性があるので人の間違いに対してのエラー検知は完璧とは言えないようです。
あくまでデータ化けに強いということのようです。
bitcoincash
動機
bitcoincashはビットコインからハードフォークをして生まれたコインなのでビットコインと同じアドレスです。
同じアドレスを持っているのでBCHをビットコインのアドレスへ送ってしまうなどの問題を抱えていました。
bitcoinがbech32を発表後、bitcoincashはこれに触発されcashアドレスを開発しました。
cashアドレスの特徴
https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
bech32を参考に作られたためbech32と仕様は良く似ている
bech32と違い以前から使われていたスクリプトのエンコード方式を置き換えただけなのでbase58のアドレスと相互変換でき互換性があります。
エンコードはbase32の仕様を使っていますが、文字テーブルを変更していて以下の32文字を使います。(bech32と同じ)
qpzry9x8gf2tvdw0s3jn54khce6mua7l
アドレスフォーマットは以下のようになっています
cashaddress:[Human Readable Part(bitcoincash、bchtestなど) | Separator(:固定) | base32 data(version + scripthash + checksum)]
実際のcashアドレスは以下のような形式となります
ビットコインキャッシュ
bitcoincash:qrpkvnk4pw0c7f4wxj0g3j540u5qas7ntgltxeavcz
ビットコインキャッシュでは短縮表記も認められているようで
bitcoincash:を除いたbase32データのみが使われる場合もある。
チェックサムにはBCH符号を使います
bech32同樣にこの方式では数文字間違えてもエラー訂正ができるが非推奨になっています
その他
bitcoincashは、BSV / BCHN / BCHABC と 分裂したがこのアドレス形式を有効に使ってはいないようです。
XRP
動機
XRPのアドレスは他のコインとアドレスが被るなどは現状はないようですが
送金時に取引所などへの送金で宛先タグをつけ忘れる、間違えるという問題があります。
これは送金アドレスと宛先タグという送金に関する項目が2つに分かれていることに起因しています。
そこでXRPのコミュニティはこの問題を改善する仕様改善をしました。
https://github.com/xrp-community/standards-drafts/issues/6
アドレスに宛先タグ情報を含めて一つのアドレスにしてしまうというものです。
xrp-communityはこれをX-Addressと呼び仕様化しました。
これは互換性がある方式でいままでのアドレスと相互変換できます。
つまり受け取り側は変更の必要がありません。
X-Addressの特徴
Xから始まるアドレスに宛先タグが内包されています。
エンコード方式は今までと同じbase58checkを採用していて以下のようなフォーマット形式になります。
base58checkを採用した理由は依存ライブラリを増やしたくなかったようだ。
アドレスフォーマットは以下のようになっています
通常のアドレス:[← 1 byte prefix →|← 160 bits of account ID →]
タグ付きアドレス:[← 2 byte prefix →|← 160 bits of account ID →|← 8 bits of flags →|← 64 bits of tag →]
以前のアドレスフォーマットとの変更点は以下の3つ
- プレフィックスを2byteに拡張
- タグの中身を表すフラグが追加
- 宛先タグが追加
タグ付きアドレスの仕様では宛先タグは64bitまで対応しているが現状のrippleで扱えるのは32bitだけ。
アカウントIDが公開鍵のハッシュ値でこの部分はそのまま使われているので互換性が保たれている。
実際のアドレスは以下のようになります
エンコード前
アドレス:rPEPPER7kfTD9w2To4CQk6UCfuHM9c6GDY
宛先タグ:12345
エンコード後
タグ付きアドレス:XV5sbjUmgPpvXv4ixFWZ5ptAYZ6PD28Sq49uo34VyjnmK5H
その他
仕様は良さそうに思えるが実際にはアドレスフォーマットに対応したウォレット、取引所が増えないと効果が出てこないので普及状況が気になるところ。
最後に
EthereumやEthereumClassicなどEthereum互換アドレスはたくさんあり、アドレスにコインの種別は全く含まれないのでそのあたりがどうなっていくか個人的に興味があります。