はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、ENSにおけるアドレスと名前の対応を、Ethereum全体とEVM互換チェーンにまたがって統一的かつ安全に解決できる仕組みを提案しているENSIP19についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIP・BIP・SLIP・CAIP・ENSIPについてまとめています。
概要
ENSIP19は、すべてのコインタイプに対して「リバース解決」と「プライマリ名解決」を標準化し、さらにその解決プロセスをマルチチェーン化したEthereumエコシステム全体で統一的に動作させる仕組みを定めたものです。 ここでいう「リバース解決」とは、アドレスから人間が読める名前を逆引きする仕組みであり、「プライマリ名解決」はあるアドレスに対応する主要な名前を定義する仕組みを指します。
つまり、Ethereumとその互換チェーン(EVM互換チェーン)において、どのチェーン上であっても一貫して同じ名前を使ってアドレスを識別できるようにするための標準化が目的です。
動機
ENSはもともと「Ethereumアドレスを名前で解決する仕組み」として提案されました(ENSIP1)。
ENSIP1については以下の記事を参考にしてください。
その後、ENSIP9で「コインタイプ」という概念が導入され、Ethereumアドレスにも特定のコインタイプが割り当てられました。
ENSIP9については以下の記事を参考にしてください。
またENSIP11では、チェーンとコインタイプを相互に変換するアルゴリズムが定義されました。
ENSIP11については以下の記事を参考にしてください。
一方で、ENSIP3ではEthereumアドレスに対するリバース解決が提案されましたが、任意のコインタイプに対応する一般化されたリバース解決の仕組みは存在していませんでした。
ENSIP3については以下の記事を参考にしてください。
現在、Ethereumのスケーリング手段としてEVM互換チェーンが広く使われるようになったため、Ethereum全体で共通する「デフォルトの名前」が必要とされています。 これにより、どのチェーンにおいても一貫したアイデンティティ解決が可能となります。 特に、EVM互換チェーンは同じアドレス形式を採用しているため、Ethereum全体で使える「チェーンに依存しないアドレス」が有効です。 外部所有アカウント(Externally Owned Account: EoA)や、特定のアルゴリズムによって決まるデプロイアドレスなどはその代表例です。
さらに、スマートコントラクトアカウント(Smart Contract Account: SCA)が普及し、チェーンごとに異なるアドレス生成方式が存在する状況では、1つのENSアイデンティティに複数のアドレスが紐づくことが一般的になります。 このため、Ethereum全体で共通のリバース解決とプライマリ名解決を整備することが必要になっています。
仕様
ENSIP19では、ENSにおける「プライマリ名解決(Primary name resolution)」を標準化し、Ethereumのマルチチェーン環境に対応できるようにしています。 プライマリ名解決とは、アドレスとコインタイプを入力として、そのアドレスに対応する公式の名前を確認する仕組みです。 最終的に、アドレスが信頼できる方法で特定の名前と結び付けられるかどうかを判断します。
用語の定義
入力となるのは「アドレスのバイト列(addressBytes)」と「コインタイプ(coinType)」です。
アドレスは16進数小文字で表記され、コインタイプはENSIP9で定義された番号です。
Ethereumメインネットは coinType = 60 として扱われ、テストネット(Sepoliaなど)も同じ番号を使います。
ENSIP9については以下の記事を参考にしてください。
ENSIP11により、EVMの chainId(チェーンを区別する識別子)からコインタイプを導出できます。
例えば、 chainId = 2 の場合、coinType = 0x80000002 となります。
ENSIP11については以下の記事を参考にしてください。
コインタイプを元にチェーンを導出する関数 chainFromCoinType() は以下のように定義されています。
chainFromCoinType(coinType)
if coinType == 60 → return 1
if 0x80000000 ≤ coinType ≤ 0xffffffff → return coinType ^ 0x80000000
それ以外 → return 0例として、Ethereumメインネットでは coinType = 60 → chainId = 1、
coinType = 0x80000002 → chainId = 2 となります。
アルゴリズムの流れ
プライマリ名解決は2段階の手続きで行われます。
リバース解決(Reverse Resolution)
まず、アドレスから逆引きして名前を得るプロセスです。 コインタイプに応じて「リバース名(reverseName)」を構築します。
- Ethereum(coinType = 60)の場合
[addressAsHex].addr.reverse - デフォルトチェーン(coinType = 0x80000000)の場合
[addressAsHex].default.reverse - その他のコインタイプの場合
[addressAsHex].[coinTypeAsHex].reverse
このリバース名に対して namehash を計算し、INameResolver.name を呼び出して名前を取得します。
もし名前が登録されていなければ、そのアドレスにはプライマリ名が存在しないと判断します。
さらに、取得した名前が実際に同じアドレスへ解決されるかを確認します。
フォワード解決(Forward Resolution)
次に、リバース解決で得られた名前から再度アドレスを解決し、入力のアドレスと一致するかを確認します。 これにより、リバースとフォワードの両方向で一致した場合のみ、その名前がプライマリ名と認められます。
呼び出しはコインタイプに応じて異なります。
- Ethereumの場合:
IAddrResolver.addr(node) - それ以外の場合:
IAddressResolver.addr(node, coinType)
もし解決結果が入力のアドレスと一致しなければ、プライマリ名は存在しないとみなされます。
マルチチェーン対応
Ethereum本体だけでなく、EVM互換チェーンでも統一的に動作できるよう設計されています。
L1(Ethereumメインネット)には「デフォルトのリバース解決コントラクト(default registrar)」が配置され、すべてのチェーン共通で利用できる「デフォルト名」を管理します。 加えて、各チェーンごとに個別のレジストラが用意される場合があります。 特に、L1へステートを投稿するロールアップチェーンでは、それぞれのチェーン専用のリゾルバが配置されます。
例えば、chainId = 2 のチェーンでは次のように名前が決定されます。
b8c2c29ee19d8307cb7255e1cd9cbde883a267d5.80000002.reverseこれを解決した結果がアドレスと一致すれば、その名前がプライマリ名です。 もしそのチェーンがロールアップでなければ、デフォルトリゾルバが代わりに処理を行い、デフォルト名が適用されます。
デフォルトアドレスの扱い
ENSIP9の互換性ルールに基づき、もし特定の coinType に対するアドレスが登録されていなければ、デフォルトアドレスが返されるようになっています。
具体的には、chainFromCoinType(coinType) > 0 のとき、addr(node, coinType) が存在しない場合は addr(node, 0x80000000) の結果を返すことが求められます。
互換性
ENSIP10との関係
ENSIP19はENSIP10の解決処理自体を修正するものではありません。 すでに確立された名前解決手順には変更がないため、ENSIP10に対応している仕組みはそのまま利用できます。 違いは、新しいレジストラ(名前管理コントラクト)が導入されることです。
ENSIP10については以下の記事を参考にしてください。
ENSIP3リバースレジストラの扱い
ENSIP3では、[addressAsHex].addr.reverse にリゾルバを割り当てる形でリバース解決を行っていました。
しかしENSIP19では、より柔軟でデフォルト対応したリゾルバに置き換えることが推奨されます。
もし古いリゾルバをそのまま使っていると、デフォルト名にフォールバックできません。
そのため、リゾルバを「デフォルト対応版」に更新するか、いったんリゾルバを解除する必要があります。
デフォルトアドレスの扱いと既存リゾルバ
多くの既存リゾルバは「デフォルトアドレス」処理を備えていません。 これを対応させるには、コントラクトを再デプロイする必要があります。 一方で、全てのコインタイプに同じアドレスを手動で登録しておけば、従来の「デフォルト」と同じ振る舞いを再現できます。 これにより古い実装との互換性を保つことが可能です。
リバース名アバター機能の廃止
ENSIP12では、ENS名を持たなくてもリバース名に基づいてアバターを設定できる仕組みが導入されました。
しかし、この仕組みはほとんど利用されていません。
現在はENS名自体を無料で取得できるようになっており、ENS名を持つことのハードルがなくなったため、この仕組みは不要とされています。
そのため、新しいリバースリゾルバは text() 関数をサポートせず、アバター設定も非対応となります。
ENSIP12については以下の記事を参考にしてください。
メインネットを「デフォルト」とする慣習の廃止
これまでENSは「メインネットのアドレスを他のチェーンでもデフォルトとして使う」という暗黙のルールが存在しました。 しかし、これは誤解を生みやすく、特にスマートコントラクトアカウント(SCA)が普及した現在では危険です。 例えば、メインネット上に存在するSCAが、同じアドレスを他のチェーンで必ずしも利用できるわけではありません。 そのため、クライアントは「メインネットをデフォルトとする処理」を完全に取り除く必要があります。
実例でのリスク
実際の例を挙げると、ユーザーAがチェーンCからユーザーBに資産を送付しようとした場合を考えます。 ユーザーBはメインネット上にSCAを持っています。
- ユーザーAはユーザーBのメインネットアドレスを入力します。
- アプリケーションはそのアドレスに紐づくメインネットのプライマリ名を表示し、ユーザーAは安心して送付を実行します。
- しかしSCAはチェーンごとに作成方法が異なり、同じアドレスをチェーンCで利用できる保証はありません。
- 結果として、送付した資産はユーザーBがアクセスできないアドレスに届き、回収不可能となってしまいます。
このような事態を防ぐためにも、メインネットアドレスを他チェーンのデフォルトとみなす習慣は廃止する必要があります。
最後に
今回は「ENSにおけるアドレスと名前の対応を、Ethereum全体とEVM互換チェーンにまたがって統一的かつ安全に解決できる仕組みを提案しているENSIP19」についてまとめてきました! いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!
