# [ERC7632] NFTのtokenIdと文字列名を結び付ける仕組みを理解しよう！

> ERC7632は、NFTなどのトークンで一般的に使われている uint256 型の tokenId を拡張し、文字列型（string）の tokenName を扱えるようにする仕組みです。

- URL: https://cardene.dev/articles/92729e359491d1a0b203
- 公開日: 2025-12-19
- 更新日: 2025-12-19
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

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

https://amzn.asia/d/gxvJ0Pw

今回は、`tokenId` と `tokenName` を一対一で対応させ、数値IDと文字列名を相互に変換できる仕組みを提案している**ERC7632**についてまとめていきます！

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

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

他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。

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

## 概要

**ERC7632**は、NFTなどのトークンで一般的に使われている `uint256` 型の `tokenId` を拡張し、文字列型（`string`）の `tokenName` を扱えるようにする仕組みです。
同時に、`tokenName` から従来の `tokenId` に戻す（逆変換する）こともできるよう設計されています。

現在の多くのNFT規格では、トークンは数値の `tokenId` によって一意に識別されています。
しかし、数値だけでは人間にとって意味が分かりづらく、トークンの内容や個性を直感的に理解しにくいという問題があります。

**ERC7632**では、この課題に対応するため以下の考え方を採用しています。

* 内部的な識別子としては、これまで通り `uint256` の `tokenI を使用します。
* 表示や操作のために、人が読める `string` 型の `tokenName` を追加で扱います。
* `tokenName` は一方向の別名ではなく、必ず `tokenId` に変換でき、逆に `tokenId` から `tokenName` も取得できる設計です。

これにより、既存のNFTエコシステムとの互換性を保ちながら、人間にとって理解しやすいトークン表現を実現します。

## 動機

**ERC7632**が必要とされる背景には、NFTを扱う多くのサービスに共通する課題があります。

現在、NFTは以下のような場面で利用されています。

* マーケットプレイスでの売買
* ブロックチェーンエクスプローラーでの表示
* ウォレットでの保有資産管理
* DeFiやdAppsでのNFT連携やロジック処理

これらのサービスでは、NFTを単なる数値IDとしてではなく、名前を持つデジタル資産として扱いたいケースが増えています。

しかし、現行の仕様では以下の問題があります。

* `tokenId` が数値のみのため、UI上で何を表しているNFTなのか分かりにくいです。
* NFTごとに名前の付け方や取得方法がコントラクトごとに異なり、実装が統一されていません。
* マーケットプレイスやウォレット側で、独自に名前解決ロジックを実装する必要があり、運用コストが高くなります。

**ERC7632**では、これらの問題に対して以下のような価値を提供します。

* トークンに標準的な名前表現を持たせることで、NFTを直感的に理解できます。
* マーケットプレイスやウォレットは、共通の方法でNFTの名前を取得・表示できます。
* DeFiやdAppsでは、NFTを名前ベースで指定・操作できるため、可読性と保守性が向上します。

結果として、NFTを扱うすべてのレイヤーで、**表示の分かりやすさ**と**実装の一貫性**が向上し、開発者とユーザーの両方にとって使いやすいエコシステムが実現します。

## 仕様

**ERC7632**は、NFTなどのトークンに対して数値の `tokenId` と文字列の `tokenName` を双方向で扱えるようにする標準仕様**です。
従来のERC規格では `tokenId` は `uint256` のみでしたが、**ERC7632**では人が読める名前を正式に扱えるようにし、なおかつ既存の仕組みと互換性を保つことを重視しています。

**ERC7632**では、`tokenName` と `tokenId` の対応関係を必ず一貫させることが最も重要な前提です。
名前があるトークンには必ず対応するIDがあり、その逆も必ず成立します。

#### 準拠コントラクトの必須要件

**ERC7632**に準拠するコントラクトは、`tokenName` と `tokenId` の対応関係を必ずサポートする必要があります。
その実現方法として、仕様では2つの方法（1a と 1b）が定義されています。

### 方法1a：IERC_NamedTokenCore を実装する方法（推奨）

**ERC7632**では、最も標準的な方法として**IERC_NamedTokenCore**インターフェースの実装が推奨されています。

#### IERC_NamedTokenCoreインターフェース

```js
interface IERC_NamedTokenCore {
  function idToName(uint256 _tokenId) external view returns (string);
  function nameToId(string memory _tokenName) external returns (uint256);
}
```

このインターフェースでは、以下の2つの操作を提供します。

* `tokenId` から `tokenName` を取得します。
* `tokenName` から `tokenId` を取得します。

これにより、数値IDと文字列名を双方向に変換できます。

#### 名前追加時のイベント

新しい `tokenName` が導入された場合、以下のイベントを発行することが推奨されています。

```solidity
event newName(uint256 indexed tokenId, string tokenName);
```

このイベントにより、インデクサーやマーケットプレイス、エクスプローラーは「**新しい名前付きトークンが作られた**」ことを効率的に検知できます。

#### `tokenId` と `tokenName` の対応ルール

**ERC7632**では、`tokenId` と `tokenName` は一対一で対応してる必要があります。

満たすべき条件は以下です。

* `tokenId` が存在するなら、必ず `tokenName` も存在します。
* `tokenName` が存在するなら、必ず `tokenId` も存在します。
* 以下の式が常に成り立ちます。

```text
tokenId = nameToId(idToName(tokenId))
tokenName = idToName(nameToId(tokenName))
```

これは、どちらの方向から変換しても必ず元に戻ることを意味します。
部分的な対応や曖昧な名前解決は認められていません。

### 方法1b：デフォルトマッピングルールを使う方法

**IERC_NamedTokenCore**を実装しない場合でも、**ERC7632**に準拠することは可能です。
その場合は、決め打ちの変換ルールを使います。

#### デフォルトの変換ルール

`tokenName` と `tokenId` は、以下の式で対応付けられます。

```js
uint256 tokenId = uint256(keccak256(tokenName));
```

つまり、`tokenName` を `keccak256` でハッシュ化し、その結果を `uint256` として `tokenId` にします。

この方法の特徴は以下です。

* ストレージにマッピングを持たなくてもよいです。
* 常に同じ名前から同じ `tokenId` が生成されます。
* ただし、名前の正規化や重複管理は実装者の責任になります。

### `tokenName` 版メソッドの提供

**ERC7632**では、`tokenId` を使う既存のメソッドに対して、`tokenName` 版のメソッドを用意することが推奨されています。

具体的には以下のルールです。

* 既存のメソッドが `tokenId（uint256）` を引数に取る場合
* 同じ処理内容で、引数を `tokenName（string）` に置き換えたメソッドを用意します
* メソッド名の末尾に `ByName` を付けます

#### 例

```js
function transferFrom(address from, address to, uint256 tokenId) external;

function transferFromByName(address from, address to, string memory tokenName) external;
```

この2つのメソッドは、内部的に同じ挙動をしなければなりません。
指定方法がIDか 名前かの違いだけで、結果は一致する必要があります。

### 追加インターフェース

**ERC7632**では、さらに高度な名前管理を行うための拡張インターフェースが定義されています。
これらは実装しても良いです。

#### IERC_NamedTokenExtensionインターフェース

```js
interface IERC_NamedTokenExtension {
  function isValidTokenName(string memory _tokenName) external view returns (string);
  function normalizeTokenName(string memory _tokenName) external view returns (string memory);
}
```

##### `isValidTokenName`

この関数は、指定された `tokenName` が有効かどうかを判定します。

用途としては以下があります。

* 使用できない文字を含んでいないかの確認
* 長さ制限のチェック
* 予約語や禁止ワードの検証

戻り値が `string` になっているため、単なる真偽値ではなくエラーメッセージを返す実装も想定されています。

##### `normalizeTokenName`

この関数は、`tokenName` を正規化した形に変換します。

例えば以下のような用途です。

* 大文字・小文字の統一
* 不要な空白の除去
* Unicode表記ゆれの吸収

これにより、同じ意味の名前が別トークンとして扱われる問題を防げます。

## 補足

**ERC7632**は、使いやすさと柔軟性の両立を目的として設計されています。
そのため、`tokenId` と `tokenName` の対応付けについて、あえて実装方法を1つに固定していません。

基本的な考え方は以下です。

* すぐに使えるよう、デフォルトの対応ルールを用意します。
* より高度な要件に対応できるよう、コントラクト独自の対応ルールも許可します。

デフォルトでは、`tokenName` を `keccak256` でハッシュ化して `tokenId` を生成する方式が使えます。
この方法は実装が簡単で、ストレージも不要なため、小規模なコントラクトや実験的な用途に向いています。

一方で、以下のようなケースでは独自実装が必要になります。

* 人が決めた連番IDと名前を対応させたい場合
* 既存のID体系と名前体系を結び付けたい場合
* 名前の管理や検証に複雑なルールがある場合

そのため、**ERC7632**では**IERC_NamedTokenCore**というインターフェースを通じて、自由にマッピングロジックを実装できる余地を残しています。
これにより、簡単に使いたい場合も、厳密に制御したい場合も、同じ規格の中で対応できます。

## 互換性

**ERC7632**は、`uint256` 型の `tokenId` を唯一の識別子として使う従来のトークンコントラクトと完全に互換性があります**。

重要な点は、**ERC7632**が以下の前提を変えていないことです。

* トークンの内部識別子はあくまで `uint256` の `tokenId` です。
* `tokenName` は追加情報であり、`tokenId` を置き換えるものではありません。

そのため、既存の**ERC721**や**ERC1155**などのコントラクトは、以下の点で影響を受けません。

* 既存のトークンIDの扱いはそのままです。
* 既存の関数やイベントは変更不要です。
* **ERC7632**を知らない外部コントラクトとも問題なく連携できます。

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

[\[ERC721\] ERC721を1からわかりやすく解説](/articles/0570a8d05bc7c9b9593f)

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

[\[ERC1155\] ERC1155を1からわかりやすく解説](/articles/c3ef92722b057161bebd)

**ERC7632**に対応したコントラクトは、従来の仕組みの上に名前機能を積み上げる形になっています。
これにより、過去の資産やツールを壊さずに、名前付きトークンという表現を追加できます。

## セキュリティ

**ERC7632**では、`tokenId` と `tokenName` がどちらも一意であることを前提としています。
同じ名前や同じIDが複数のトークンに割り当てられることは想定されていません。

#### 一意性の前提

以下の条件が守られていることが前提です。

* 1つの tokenId に対して、対応する tokenName は1つだけです。
* 1つの tokenName に対して、対応する tokenId は1つだけです。

この前提が崩れると、名前からIDを引いた結果が曖昧になり、トークン操作に重大な問題が発生します。

#### 正規化されていない `tokenName` のリスク

`tokenName` を正規化しない場合、見た目がほぼ同じ名前が別物として扱われる可能性があります。

例えば以下のようなケースです。

* 大文字と小文字の違い
  例: `TokenA` と `tokena`
* 全角と半角の違い
* 見た目が同じUnicode文字の違い

これらはユーザーにとって非常に分かりづらく、なりすましや誤操作の原因になります。

#### 正規化を許可する場合の責務

もしコントラクトが正規化されていない `tokenName` や、見た目が似た名前の共存を許可する場合、開発者には明確な責任があります。

**ERC7632**では、そのための仕組みとして**IERC_NamedTokenExtension**が用意されています。

* 正規化ルールを `normalizeTokenName` で明示します。
* `tokenName` の妥当性を `isValidTokenName` で検証します。

これにより、ウォレットやマーケットプレイスは、「**このコントラクトではどのような名前ルールが使われているのか**」を理解した上で表示や警告を行えます。

## 引用

Zainan Victor Zhou (@xinbenlv), "ERC-7632: Interfaces for Named Token [DRAFT]," Ethereum Improvement Proposals, no. 7632, February 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7632.

## 最後に

今回は「`tokenId` と `tokenName` を一対一で対応させ、数値IDと文字列名を相互に変換できる仕組みを提案している**ERC7632**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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