[ERC2520] ENSを異なる分散型ホスティングシステムに同時対応させる仕組みを理解しよう！

# はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、1つのENSドメインに対して複数のcontenthashレコードを保存・取得できるようにし、IPFS・Swarm・Onionなど異なる分散型ホスティングシステムに同時対応可能にする仕組みを提案している**ERC2520**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-2520

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

**ERC2520**は、1つのENS（Ethereum Name Service）ドメインに対して、複数の`contenthash`レコードを登録できるようにする提案です。
現在のENS仕様では、1つのドメインにつき1つの`contenthash`レコードしか保持できませんが、この制限を取り払ってIPFS、Swarm、Onion、ZeroNetなど複数の分散型ホスティングシステムへの対応を可能にします。

# 動機

多くのアプリケーションが、分散型ストレージ上にホスティングされたコンテンツへアクセスするためにENS名を使用しています。
その際、`contenthash`レコードを使ってどの分散型システムを使うか、どのコンテンツにアクセスすべきかを判断しています。

しかし現在のENS仕様では、1つのドメインに対して1つの`contenthash`レコードしか設定できないため、サイトの所有者は1つのホスティング手段しか選べません。
これでは、IPFSやSwarmといった既存の選択肢だけでなく、今後登場するであろう新しい分散型ホスティング方式への対応が困難になります。

そのため、複数の`contenthash`レコードをサポートすることで、1つのENS名で複数のホスティング方法を指定できるようにし、より柔軟で拡張性のある運用を可能にすることが重要です。

# 仕様

**ERC2520**は、**EIP1577**の`contenthash`レコードの取り扱いを拡張し、1つのENSドメインに複数の`contenthash`レコードを保存・取得できるようにする提案です。

## インターフェースの互換性

既存の**EIP1577**と互換性を保ちつつ、新たなインターフェースを追加します。
つまり、**EIP1577**の形式を維持しながら、プロトコル指定（`proto`）による保存・取得が可能になります。

:::note info
**EIP1577**については以下の記事を参考にしてください、
:::

https://qiita.com/cardene/items/4b0a25d33edd2f894259

## 保存関数（`setContenthash`）

```js
function setContenthash(bytes32 node, bytes calldata proto, bytes calldata hash) external authorised(node);
```

指定されたプロトコルごとに`contenthash`レコードを保存する関数。

* `node`
    * 対象のENSノード（ドメイン名に対応）
* `proto`
    * 使用するプロトコル（例: IPFS、Swarm）をバイト列で指定
* `hash`
    * 保存したいコンテンツハッシュ

`proto`が指定されていない場合は、デフォルトレコードとして保存されます。

## 取得関数（`contenthash`）

```js
function contenthash(bytes32 node, bytes calldata proto) external view returns (bytes memory);
```

指定されたプロトコルに対応する`contenthash`を返す関数。

* `node`
    * 対象のENSノード
* `proto`
    * 取得したいプロトコルを指定（未指定の場合はデフォルトレコード）

`proto`が指定されていない場合は、デフォルトのレコードを返します。

## インターフェース識別子

複数の`contenthash`レコードに対応したリゾルバは、`supportsInterface`関数において以下のインターフェースIDに対して`true`を返す必要があります。

```
0x6de03e07
```

## アプリケーション側の取り扱い方

* **単一のホスティングシステムしか対応していないアプリケーション**（例: IPFSゲートウェイ）
  → 特定のプロトコルを指定して`contenthash`を取得すべき。

* **複数のホスティングシステムに対応しているアプリケーション**（例: MetaMask）
  → プロトコルを指定せずにデフォルトの`contenthash`を取得すべき。

このように、アプリケーションの性質に応じてプロトコル指定の有無を切り替えることで、柔軟な対応が可能になります。

# 補足

**ERC2520**の実装は、できるだけシンプルでありながら、必要とされる主要な機能をすべてサポートできる点を重視して選ばれました。
そのため、同じプロトコルタイプ（たとえばIPFSなど）に対して複数の`contenthash`レコードを保存したり、優先順位を付けたりする機能は含まれていません。

これは、そうした機能を追加しても大きな利点がなく、かえって実装が複雑になるためです。
シンプルさと実用性のバランスをとった設計が意図されています。

# 互換性

**ERC2520**は、既存の**EIP1577**との互換性を保っています。
新しく追加されるのは関数のオーバーロード（引数の追加）だけであり、既存の関数の動作には影響しません。

そのため、古いアプリケーションも引き続き動作可能です。
これらのアプリケーションは、従来どおりデフォルトの`contenthash`レコードを取得でき、特別な変更を必要としません。
新しい機能を利用したい場合にのみ、新しいインターフェースを使えばよい設計となっています。

# 参考実装

```js
contract ContentHashResolver {
    bytes4 constant private MULTI_CONTENT_HASH_INTERFACE_ID = 0x6de03e07;
    mapping(bytes32=>mapping(bytes=>bytes)) hashes;

    function setContenthash(bytes32 node, bytes calldata proto, bytes calldata hash) external {
        hashes[node][proto] = hash;
        emit ContenthashChanged(node, hash);
    }

    function contenthash(bytes32 node, bytes calldata proto) external view returns (bytes memory) {
        return hashes[node][proto];
    }

    function supportsInterface(bytes4 interfaceID) public pure returns(bool) {
        return interfaceID == MULTI_CONTENT_HASH_INTERFACE_ID;
    }
}
```

# 引用

Filip Štamcar (@filips123), "ERC-2520: Multiple contenthash records for ENS [DRAFT]," Ethereum Improvement Proposals, no. 2520, February 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2520.

# 最後に

今回は「1つのENSドメインに対して複数のcontenthashレコードを保存・取得できるようにし、IPFS・Swarm・Onionなど異なる分散型ホスティングシステムに同時対応可能にする仕組みを提案している**ERC2520**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4