# [ERC4972] ENSにコントラクトアカウントを紐づける仕組みを理解しよう！

> Ethereum Name Service（ENS）は、Ethereumブロックチェーン上で動作する分散型の名前解決サービスです。

- URL: https://cardene.dev/articles/64bdb724a083550e0903
- 公開日: 2024-03-06
- 更新日: 2024-03-06
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、ENS（Ethereum Name Service）を拡張して、Nameの所有者にスマートコントラクトアカウントを紐付ける仕組みを提案している**ERC4972**についてまとめていきます！

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

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

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

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

## 概要

Ethereum Name Service（ENS）は、Ethereumブロックチェーン上で動作する分散型の名前解決サービスです。
このサービスにより、ユーザーは人間が読めるアドレス（例：`alice.eth`）をEthereumのアドレスにリンクでき、送金やコントラクトの呼び出しなどを容易に行うことができます。
ENSはドメイン名システム（DNS）のブロックチェーン版と考えることができます。

- **人間が読めるアイデンティティとスマートコントラクトの紐付け**
    - 各ENS名（人間が読めるアイデンティティ）を、単一のスマートコントラクトアカウントにリンクする機能を追加する提案です。
    - このスマートコントラクトは、ENS名の所有者が管理・制御することができます。

この拡張の目的は、ENSを使用する時の柔軟性と機能性を高めることにあります。
現在、ENSは主にアドレスのエイリアスとして機能しますが、この提案により、ENS名が直接スマートコントラクトにリンクされるようになるため、より複雑なロジックや機能をENS名に組み込むことが可能になります。

たとえば、ENS名を使用して、特定の条件下でのみ資金を受け取る、あるいは自動的に資金を他のアドレスに転送するといった機能を持つスマートコントラクトを設定することができるようになります。
これにより、個人や組織は、ENS名を介して独自の複雑なトランザクションやコントラクトを簡単に実装し、管理することができます。

この提案が実装されると、ENSの使い方や可能性が大幅に拡大されることになります。
ユーザーは、ただのアドレスのエイリアスとしてではなく、ENS名を通じて独自のデジタルアイデンティティやサービスを展開するための強力なツールとして活用できるようになるでしょう。

## 動機

ここで言及されているのは、各ネームに「**Rich Context**」を与え、名前の所有者に利用可能な追加のスマートコントラクトアカウントを提供することにより、一般的なスマートコントラクトアカウントの採用を促進することを目指しています。
このコンセプトは、ネーム所有者のアカウント（**NOA: Name Owner Account**）として紹介されており、名前ノードに資産や情報を持たせることが可能になります。

#### 名前にRich Contextを与える

現在のネームサービス（例えばENS）では、人間が読める名前は単にEthereumアドレスにマッピングされるだけです。
しかし、この拡張機能により、名前自体がより豊富な情報を持つことが可能になります。
名前にリンクされたスマートコントラクトアカウント（**NOA**）を通じて、名前が単なる識別子ではなく、資産や情報を含むエンティティとして機能するようになります。

#### NOAの概念

NOAは、名前の所有者に割り当てられるスマートコントラクトアカウントです。
このアカウントを介して、ネームノード（人間が読める名前）はEthereum上での資産や情報を直接持つことができるようになります。
これにより、ネームサービスは、名前の登録だけでなく、資産の保有や情報の格納という新たな機能を提供することができます。

#### 新しいユースケースの開放

NOAを導入することで、ネームノードの転送が、名前の所有権だけでなく、そのNOAが持つ資産や情報も含めた転送を可能にします。
これは、例えば、特定のネームノードが特定のデジタルアセットや特権、アクセス権を保持している場合にそのネームノードを別の人に転送することで、それらのアセットや権利も一緒に移転されるというシナリオを可能にします。

#### 一般的なスマートコントラクトアカウントの採用促進

スマートコントラクトアカウントは、その柔軟性と機能性から、様々なデジタルアプリケーションでの利用が期待されています。
NOAを通じて、ユーザーはスマートコントラクトアカウントをより簡単に、そして直感的に利用開始できるようになります。
これにより、スマートコントラクトの概念がより広く受け入れられ、その採用が促進されることが期待されます。

この拡張機能により、名前サービスは単なる名前解決ツールから、資産管理や情報格納のプラットフォームへと進化することになります。
これにより、ブロックチェーン上でのデジタルアイデンティティの概念が拡張され、新たなアプリケーションやサービスの開発が促進されるようになります。

## 仕様

### Name-Owned Account

説明されている「**Name-Owned Account (NOA)**」の概念は、ネームベースのアイデンティティとそれに関連するスマートコントラクトアカウントを結びつけるためのものです。
ここで言及されている**ERC137**は、人間が読める名前をブロックチェーンのアドレスに紐付ける標準を定義しています。

:::message
**ERC137**については以下の記事を参考にしてください。
:::

[\[ERC137\] アドレスに任意の名前を紐付けるENSの仕組みを理解しよう！](/articles/17e6e1a452006f08a197)

#### NOAの主要要素

##### Human Readable Name
人間が読める名前は、**ERC137**によって定義された、ブロックチェーン上で一意の識別子です。
これは通常、ENSを介してEthereumのアドレスにマッピングされるドメイン名（例：`alice.eth`）です。

##### Owned Account (NOA)
NOAは、その名前に基づいてアドレスが導出されるスマートコントラクトアカウントです。
このアカウントは、特定のネームノードに紐付けられ、資産や情報を保持することが可能です。
スマートコントラクトとして、特定のロジックや規則を実装することで、ネームノードの使用方法や資産の管理方法に拡張性を持たせることができます。

##### Name Owner(s)
名前の所有者は、そのネームノードとNOAを管理する権利を持つ個人または複数のエンティティです。
所有者は、NOAに対してデプロイや操作を行うことができ、その使用方法を完全にコントロールすることができます。

#### 関係性の図解

図は、NOA、ネームノード、名前所有者の間の所有権の関係性を表しています。

```
  ┌───────────────┐        ┌───────────┐         ┌───────────────┐
  │ Owned Account ◄──own───┤ Name Node ◄───own───┤   Name Owner  │
  └───────────────┘        └───────────┘         └───────────────┘
```

この図では、名前所有者がネームノードを所有しており、そのネームノードがNOA（所有アカウント）を所有していることを示しています。
これにより、ネームサービスによって保証された所有権の連鎖が確立されます。
名前所有者は、NOAに対して直接コントロールを行うことができ、そのアカウントを通じて、資産の保持や特定のアクションの実行が可能になります。

:::message
NOAの導入により、Ethereumの名前サービスは単なる名前解決の機能を超え、名前に関連したスマートコントラクトアカウントを通じて資産や情報の管理が可能になります。
これは、ブロックチェーン上でのデジタルアイデンティティや資産所有権の管理において新たな可能性を開くものであり、よりセキュアで効率的な方法での資産の移転や情報の管理を実現します。
:::

### インターフェース

#### INameServiceRegistry

ネームサービスに必要なコアインターフェースは以下の通りです。

```ts
interface INameServiceRegistry {
    /// @notice get account address owned by the name node
    /// @params node represents a name node
    /// @return the address of an account
    function ownedAccount(
        bytes32 node
    ) external view returns(address);
}
```

#### `ownedAccount`

```javascript
function ownedAccount(
    bytes32 node
) external view returns(address);
```

**概要**

名前ノードによって所有されるアカウントのアドレスを取得する関数。

**詳細**

この関数は、特定のネームノードに紐付けられた、所有されるアカウント（**NOA: Name-Owned Account**）のアドレスを返します。
これにより、名前ネームがスマートコントラクトアカウントを介してどのアドレスを所有しているかを確認できます。
関数は読み取り専用であり、ブロックチェーンの状態を変更することなく情報を提供します。

**引数**

- `node`
		- 名前ノードを表す`bytes32`型の引数です。これは、特定の名前（例：`alice.eth`）がハッシュ化された形式であり、それに対応するアカウントのアドレスを取得するために使用されます。

**戻り値**

- `address`
		- ネームノードによって所有されるスマートコントラクトアカウントのアドレスを返します。
		- このアドレスは、ネームノードの所有者が管理するコントラクトのアドレスであり、資産や情報を保持することが可能です。

#### INameOwnedAccount

名前所有のアカウントに必要なコア・インターフェースは以下の通りです。

```ts
interface INameOwnedAccount {
    /// @notice get the name node is mapped to this account address
    /// @return return a name node
    function name() external view returns(bytes32);

    /// @notice get the name service contract address where
    /// the name is registered
    /// @return return the name service the name registered at
    function nameService() external view returns(address);
}
```

#### `name`

```javascript
function name() external view returns(bytes32);
```

**概要**

アカウントにマッピングされた名前ノードを取得する関数。

**詳細**

この関数は、スマートコントラクトアカウントに関連付けられた具体的なネームノード（人間が読めるドメイン名に対応するユニークな識別子）を返します。
ネームノードは、Ethereum Name Service（ENS）のようなネームサービスにおいて、ドメイン名を一意に識別するために使用されます。

**戻り値**

- `bytes32`
    - アカウントにマッピングされた名前ノードのユニークな識別子です。

---

#### `nameService`

```javascript
function nameService() external view returns(address);
```

**概要**

名前が登録されている名前サービスのコントラクトアドレスを取得する関数。

**詳細**

この関数は、特定の名前（ドメイン名）が登録されているネームサービスのコントラクトアドレスを返します。
このアドレスを通じて、名前の登録や解決に関連する機能を提供するコントラクトにアクセスすることができます。
例えば、ENSの場合、ENSレジストリコントラクトのアドレスが返されることになります。

**戻り値**

- `address`
    - 名前が登録されているネームサービスのコントラクトアドレス。


## 補足

ネームノード（Name Node）と名前所有アカウント（Name-Owned Account, NOA）の間に一対一のマッピングを実現する方法について言及しています。
具体的には、各NOAのアドレスがネームノードから派生するように設計されており、それぞれのNOAにネームノード情報を含めることで、NOAがそのネームノードの所有権を反映するようになっています。
このプロセスを通じて、NOAはそれが関連付けられている特定のネームノードを明確に識別できます。

#### ネームノードの情報をNOAに含める

各NOAにネームノード情報を含めることは、NOAがそのネームノードの所有権を表す重要な方法です。
これにより、NOAはネームノードに対して一意のアクセスポイントとして機能し、ネームノードとの直接的な関連性を持つことができます。

#### `name()`関数の利用

`name()`関数を使用すると、NOAが保持するネームノードの情報を取得できます。
これにより、NOAからそのネームノードへの逆追跡が可能になり、NOAがどのネームノードに関連付けられているかを明確に識別することができます。
この機能は、NOAとネームノード間の関係性を確認する時に特に役立ちます。

#### `nameService()`関数の利用

`nameService()`関数は、名前が登録されているネームサービスのコントラクトアドレスを取得します。
このアドレスを利用して、名前の登録状況の検証や他の関連行動を実行することが可能です。
例えば、特定のネームノードが有効なネームサービスによって管理されているかどうかのチェックなどが含まれます。

#### 実際の所有者への追跡

これら2つの方法を通じて、NOAは実際の所有者であるネームノードの所有者に追跡する能力を持ちます。
ネームノードの所有者は、NOAを介してその名前に関連する資産や情報を管理することができるため、NOAとネームノードの間のこの関係性は、デジタルアイデンティティと資産管理の透明性と効率性を高めるのに役立ちます。

この仕組みにより、ブロックチェーン上での名前とアカウントの関連付けが強化され、名前サービスを通じたデジタルアセットの管理や所有権の確認がより直接的かつ効率的に行えるようになります。

## 互換性

ネーム登録インターフェイスは**ERC137**と互換性があります。

## 実装

名前所有アカウント（Name-Owned Account, NOA）の作成プロセスに関しての説明です。
ここで説明されているプロセスは、ブロックチェーン上で特定の名前に紐付いたスマートコントラクトアカウントを生成するための方法を提供します。
このプロセスは主に、「**ファクトリー**」コントラクトを通じて行われ、一連の特定の技術的手順に従います。

#### NOAの作成プロセス

1. **ファクトリーコントラクト**
    - NOAは「**ファクトリー**」コントラクトによって生成されます。
    - このファクトリーはネームサービス自体である可能性があり、NOAを生成するためには、`CREATE2`オペコードを使用します（`CREATE`ではありません）。
    - `CREATE2`を使用する理由は、生成されるNOAのアドレスを事前に計算でき、かつ決定的（予測可能）にするためです。

2. **`CREATE2`の使用**
    - Ethereumにはスマートコントラクトをデプロイするための2つのオペコード、`CREATE`と`CREATE2`があります。
    - `CREATE2`を使用する主な利点は、コントラクトのアドレスがコントラクトの作成者（ファクトリーコントラクト）、提供されるソルト、およびコントラクトのバイトコードから決定的に計算されることです。
    - これにより、NOAのアドレスを予測可能にし、再現可能にします。

3. **アドレスの決定的保存**
    - NOAは、同一の初期化コード（`initcode`）とファクトリーコントラクトを使用して生成される必要があります。
    - これにより、NOAのアドレスが決定的に保存されることが保証されます。
    - アドレスが予測可能であることは、ネームノードとその所有アカウントの間の一対一のマッピングを実現する上で重要です。

4. **ネームノードをソルトとして使用**
    - `CREATE2`でNOAを生成する時、ネームノード情報を「**ソルト**」として使用します。
    - このソルトは、ネームノードとNOAの間の一意の対応関係（全単射）を保証するために重要です。
    - ソルトを使用することで、同一のファクトリーコントラクトと初期化コードから、異なるネームノードごとに異なるNOAアドレスを生成することができます。

:::message
NOAの作成プロセスは、ネームノードに紐付いたスマートコントラクトアカウントを生成するための決定的で再現可能な方法を提供します。
ファクトリーコントラクトを使用し、`CREATE2`オペコードを活用することで、NOAのアドレスが予測可能かつ一意になり、ネームノードとの間に一対一の関係が確立されます。
このプロセスは、デジタルアイデンティティや資産の管理に新たな可能性を開きます。
:::

## 引用

Shu Dong (@dongshu2013), Qi Zhou (@qizhou), Zihao Chen (@zihaoccc), "ERC-4972: Name-Owned Account [DRAFT]," Ethereum Improvement Proposals, no. 4972, April 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4972.

## 最後に

今回は「ENS（Ethereum Name Service）を拡張して、Nameの所有者にスマートコントラクトアカウントを紐付ける仕組みを提案している**ERC4972**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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