[ERC5114] NFTとアドレスに紐づいたSBTライクな仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、NFTとアドレスに紐づいたソウルバウンド・バッジ・トークンのインターフェースを提案している規格である**ERC5114**についてまとめていきます！

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

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

:::note warn
**5114**は現在（2023年9月15日）では「**Last Call**」段階です。
:::

# 概要

ソウルバウンド・バッジは、NFT（非代替性トークン）トの一種です。
このバッジは、作成（または発行）された瞬間から、別のNFTと"結びつき"、その後は二つを切り離すことができません。

:::note info
一度ソウルバウンド・バッジが、あるNFTと結びつくとその関係は永遠に続き、他のNFTやアカウントに送ったり、転送したりできない特別なトークンになります。
この結びつきは、まるで魂のように切り離せないため、**A soulbound badge（魂の結びついたバッジ）** と呼ばれています。
:::

# 仕様

```javascript
interface IERC5114 {
	// fired anytime a new instance of this badge is minted
	// this event **MUST NOT** be fired twice for the same `badgeId`
	event Mint(uint256 indexed badgeId, address indexed nftAddress, uint256 indexed nftTokenId);

	// returns the NFT that this badge is bound to.
	// this function **MUST** throw if the badge hasn't been minted yet
	// this function **MUST** always return the same result every time it is called after it has been minted
	// this function **MUST** return the same value as found in the original `Mint` event for the badge
	function ownerOf(uint256 badgeId) external view returns (address nftAddress, uint256 nftTokenId);

	// returns a URI with details about this badge collection
	// the metadata returned by this is merged with the metadata return by `badgeUri(uint256)`
	// the collectionUri **MUST** be immutable (e.g., ipfs:// and not http://)
	// the collectionUri **MUST** be content addressable (e.g., ipfs:// and not http://)
	// data from `badgeUri` takes precedence over data returned by this method
	// any external links referenced by the content at `collectionUri` also **MUST** follow all of the above rules
	function collectionUri() external pure returns (string collectionUri);

	// returns a censorship resistant URI with details about this badge instance
	// the collectionUri **MUST** be immutable (e.g., ipfs:// and not http://)
	// the collectionUri **MUST** be content addressable (e.g., ipfs:// and not http://)
	// data from this takes precedence over data returned by `collectionUri`
	// any external links referenced by the content at `badgeUri` also **MUST** follow all of the above rules
	function badgeUri(uint256 badgeId) external view returns (string badgeUri);

	// returns a string that indicates the format of the `badgeUri` and `collectionUri` results (e.g., 'EIP-ABCD' or 'soulbound-schema-version-4')
	function metadataFormat() external pure returns (string format);
}
```

この規格を使用するコントラクトでは、この規格を使用していることを検出できるようにインターフェースの検出に関する標準の実装をするべきです。

以下は、提供されたインターフェース `IERC5114` の各関数についての説明です：

---

### Mint

```javascript
event Mint(uint256 indexed badgeId, address indexed nftAddress, uint256 indexed nftTokenId);
```

**概要**
このバッジの新しいインスタンスを作成される時に発行されるイベント。

**詳細**
- このイベントは、同じ`badgeId`に対して二度発火してはいけません。

**パラメーター**
- `badgeId`
    - バッジのトークンID。
- `nftAddress`
    - バッジが結びついているNFTのアドレス。
- `nftTokenId`
    - バッジが結びついているNFTのトークンID。

**戻り値**
- なし

---

### ownerOf

```javascript
function ownerOf(uint256 badgeId) external view returns (address nftAddress, uint256 nftTokenId);
```

**概要**
バッジが結びついているNFTの情報を返す関数。

**詳細**
- バッジがまだ作成されていない場合、この関数は例外をスローしなければなりません。
- バッジが一度作成された後、この関数を呼び出すたびに常に同じ結果を返さなければなりません。
- この関数は、バッジに関連する元の`Mint`イベントで見つかる値と同じ値を返さなければなりません。

**引数**
- `badgeId`
    - バッジのトークンID。

**戻り値**
- `nftAddress` 
    - バッジが結びついているNFTのアドレス。
- `nftTokenId`
    - バッジが結びついているNFTのトークンID。

---

### collectionUri

```javascript
function collectionUri() external pure returns (string collectionUri);
```

**概要**
バッジコレクションに関する情報が含まれたURIを返す関数。

**詳細**
- 返されるメタデータは、`badgeUri(uint256)`で返されるメタデータと統合されます。
- `collectionUri`は変更できない（例: `ipfs://` であり、`http://` ではない）必要があります。
- `collectionUri`は内容をアドレス可能なものである必要があります（例: `ipfs://` であり、`http://` ではない）。

**戻り値**
- `collectionUri`
    - バッジコレクションに関する情報が含まれたURI。

---

### badgeUri

```javascript
function badgeUri(uint256 badgeId) external view returns (string badgeUri);
```

**概要**
特定のバッジインスタンスに関する情報が含まれたURIを返す関数。

**詳細**
- `collectionUri`で返されるメタデータよりも、この関数が返すデータが優先されます。
- `badgeUri`の内容に含まれる外部リンクも、上記のルールに従わなければなりません。

**引数**
- `badgeId`
    - バッジのトークンID。

**戻り値**
- `badgeUri`
    - バッジに関する情報が含まれたURI。

---

### metadataFormat

```javascript
function metadataFormat() external pure returns (string format);
```

**概要**
`badgeUri`および`collectionUri`の結果のフォーマットを示す文字列を返す関数（例: **EIP-ABCD**または **soulbound-schema-version-4**）。

**戻り値**
- `format`
    - 結果のフォーマットを示す文字列。

---

# 補足


## 不変性
ソウルバウンド・バッジは一度特定のNFTに紐づけられると、それ以降絶対に移動や変更ができないことを意味します。
このルールにより、複数のソウルバウンド・バッジが同じNFTに結びついている場合でも、それらを切り離したり統合したりすることができず、同時にユーザーは結果をキャッシュ（一時的に保存）して高速にアクセスすることができます。

## コンテンツアドレス可能なURIが必要
特定のコンテンツやデータを一意に識別するためのアドレスです。
ソウルバウンド・バッジは、個人に紐づいた永続的なバッジや指標であり、ユーザーはこのバッジの所有権を譲渡できないだけでなく、発行者も所有権を取り戻すことや他人に渡すことができません。
また、特定のユーザーを検閲したり操作したりするために、リモートコンテンツを変更または削除することも許されていません。

## badgeUriデータフォーマットの仕様がない
`collectionUri()`や`badgeUri(uint256)`で指し示されるデータのフォーマットと、それらをどのように統合するかについての詳細は、将来において改善できるように、この標準から意図的に省かれています。
不変性の制約だけが、このバッジのコアコンセプトが保たれると定義されており、データフォーマットの詳細にかかわらず確実に達成します。
`metadataFormat`関数は、呼び出し元に対して、データの形式やバージョンなどの情報を提供し、呼び出し元がデータを簡単に解析できるようにします。

# 後方互換性

これは新しいトークンタイプであり、既存の「有効なソウル」（[アドレス、ID]で識別できる任意のアセット）以外の既存のトークンとは後方互換性を持たせる意図はありません。

言い換えると、この新しいトークンは、既存のトークンとは異なるものであり、既存の「**有効なソウル**」と呼ばれる特定のアセット（[アドレス、ID]で特定できるもの）との互換性を持たせることを意図していますが、他の既存のトークンとは互換性を持たせないです。

# セキュリティ考慮事項

バッジを実装しようとするユーザーは、実際にそのバッジが要件を満たしているかどうかを確認するときに慎重でなければなりません。
なぜなら、バッジの制作者は、最初にAPIを調べたときに、バッジが規則に従っているように見せかけることができ、実際にはそうでないことがあるからです。
たとえば、コントラクトが一定のメカニズムを介して転送を許可しているにもかかわらず、最初はその機能を使用しないかもしれません。

また、ソウルバウンド・バッジは人間に結びついているのではなく、個々の『ペルソナ（仮想的な個体）』に結びついています。
ペルソナは、時間の経過とともに複数のソウルバウンド・バッジを収集してバッジのコレクションを構築する一種のアクターです（これは一人の人間か、複数の人間から成るグループである可能性があります）。
このペルソナは他の人間に譲渡されることも、別のグループに移譲されることもあり、ペルソナとやり取りする人々は、そのペルソナの背後に1人だけがいると想定すべきではありません。

また、ソウルバウンド・バッジは別のソウルバウンド・バッジに結びつくことも可能です。
理論的には、そのようなバッジの連鎖が同時に作成された場合、ループを形成する可能性があります。
このような連鎖をたどろうとするソフトウェアは、ループが検出された場合にどのように処理するかについて検討する必要があります。

# 引用

Micah Zoltu (@MicahZoltu), "ERC-5114: Soulbound Badge [DRAFT]," Ethereum Improvement Proposals, no. 5114, May 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5114.

# 最後に

今回は「NFTとアドレスに紐づいたソウルバウンド・バッジ・トークンのインターフェースを提案している規格である**ERC5114**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58