[ERC5484] SBTのMint時にBurnできる権限を付与する仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、SBT（ソウル・バウンド・トークン）の`Mint`（発行）に`Burn`（破棄）できる権限を付与できる**ERC5484**について説明していきます！

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

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

SBT（ソウル・バウンド・トークン）とは、`Transfer`（送付）できないNFTのことを指します。

::: note warn
以下からSBT表記になります。
:::

:::note info
NFT（ERC721）については以下を参考にしてください。
:::

https://chaldene.net/erc721

# 要約
このEIPは、**EIP721**を拡張してSBTを作成するインターフェースを定義します。

:::note info
「**そもそもインターフェースって何？**」という方は以下の記事を参考にしてください！
:::

https://chaldene.net/erc721#st-toc-h-5

NFTの`Mint`（発行）前に発行アドレスと受け取りてアドレスの両方が、このトークンを`Burn`（破棄）する権限を持つアドレスの合意が必要になります。
`Burn`（破棄）の権限の決定後、変更は不可能です。
NFTの`Mint`（発行）後、SBTは他アドレスに`Transefer`（送付）はできませんが、`Burn`（破棄）する権限を持っていれば`Burn`（破棄）を実行することはできます。

# 動機
SBTのアイデアは提案されてからかなりの注目を集めています。
ただし、標準的なインターフェースがないため、SBTは互換性がありません。
SBTの実装について標準的なものがないと、SBTを対象とした汎用サービスを開発することは難しいです。

このEIPでは、SBTを特殊なNFTとして位置付け、**資格情報**、**信用記録**、**融資履歴**、**会員資格**などの個人情報などを判別する役割になることを想定しています。
また、柔軟性を提供するために、SBTはアプリケーション固有の`Burn`（破棄）権限を持ち、通常の**EIP721**規格のNFTと区別する方法を持つ必要があります。

# 仕様
提案するは、**EIP721**規格のNFTでは以下のインターフェースを実装する必要があります。

- **ERC165**（`0x01ffc9a7`）。
- **ERC721**（`0x80ac58cd`）。
- `Mint`（発行）前に`burnAuth`を受け取り手アドレスに提示する。
- `Mint`（発行）後は`burnAuth`を変更不可にする。
- `burnAuth`のみでNFTを`Burn`（破棄）できる権限を判別する。
- NFTの発行アドレスは`Mint`（発行）前にNFTのメタデータを受け取り手アドレスに提示し、受け取り手アドレスの署名を取得する。
- `Mint`（発行）後に発行アドレスはNFTのメタデータを変更してはいけない。

# インターフェース

```javascript
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;

interface IERC5484 {
    enum BurnAuth {
        IssuerOnly,
        OwnerOnly,
        Both,
        Neither
    }

    event Issued (
        address indexed from,
        address indexed to,
        uint256 indexed tokenId,
        BurnAuth burnAuth
    );

    function burnAuth(uint256 tokenId) external view returns (BurnAuth);
}
```

## BurnAuth
`Burn`（破棄）権限の種類を列挙した型定義。

- `IssuerOnly`
    - NFTの発行アドレスにのみ`Burn`（破棄）権限がある。
- `OwnerOnly`
    - NFTの所有者アドレスにのみ`Burn`（破棄）権限がある。
- `Both`
    - NFTの発行アドレスと所有者アドレスにのみ`Burn`（破棄）権限がある。
- `Neither`
    - NFTの`Burn`（破棄）権限はどのアドレスにもない。

## Issued

SBTが`Mint`（発行）されたときに発行されるイベント。
**ERC721**規格のNFTの`Transfer`イベントに追加されます。

- `from`
    - NFTの発行者アドレス。
- `to`
    - NFTの受け取り手アドレス。
- `tokenId`
    - 発行されたNFTのトークンID。
- `burnAuth`
    - 発行されたNFTの`Burn`（破棄）権限。

## burnAuth

特定のNFTに`Burn`（破棄）権限を取得する関数。
引数に渡された`tokenId`のNFTに付与されている`Burn`（破棄）権限を確認できます。

＃補足
SBTは、既存の**EIP721**規格のNFTの特殊なサブセットとしての役割を果たします。
この設計の利点は、既存のNFTサービスとのシームレスな互換性です。
サービスプロバイダーはSBTをNFTのように扱い、既存のコードを大幅に変更する必要がありません。

## 非譲渡性
**EIP721**を拡張した現在のSBTを実装する上での1つの問題は、すべての`Transfer`（送付機能）がエラーを投げることです。
より洗練されたアプローチとして、`Transfer`（送付機能）は引き続きエラーを投げるが、事前にコントラクトに対してSBTインターフェースを実装しているかを確認し、`Transfer`（送付機能）を呼び出さないようにすることが挙げられます。

## Burn権限
インターフェースの使用に関しては最大限柔軟にしています。
そのため、事前に定められた`Burn`（破棄）ルールは重要です。
以下は異なる`Burn`（破棄）権限のサンプルシナリオです。

- `IssuerOnly`
    - ローン履歴
- `ReceiverOnly`
    - 有料会員資格
- `Both`
    - 資格情報
- `Neither`
    - 信用履歴

`Burn`（破棄）権限は1つのトークンに関連付けられ、`Mint`（発行）後に変更はできません。
したがって、トークンが`Mint`（発行）される前に、NFTの受け取り手アドレスに通知し、受け取り手アドレスの同意を得ることが重要です。

## Mintイベント
`Mint`（発行）時には、**EIP721**の`Transfer`イベントとともに`Issued`イベントが発行されます。
この設計により、後方互換性が保持される一方で、これがSBTの発行イベントであることを明確に示すことができます。

## キーローテーション
Ethereumのユーザーが抱える懸念は、`Burn`（破棄）可能なSBTを持つことで、キーローテーションを実現できてしまうことです。

:::note info
ここでのキーローテーションとは、NFTの所有者が変更できないことを想定しているのに、変更できてしまうことを指します。
:::

SBTの所有者は、NFTの発行者アドレスに通知し、`Burn`（破棄）権限を持つアドレスがNFTを`Burn`（破棄）し、発行者アドレスが新しい別のアドレスにレプリカを`Mint`（発行）できます。

# 後方互換性
この提案は、**EIP721**と完全に後方互換性があります。

# 最後に

今回は「SBT（ソウル・バウンド・トークン）の`Mint`（発行）に`Burn`（破棄）できる権限を付与できる**ERC5484**」についてまとめてきました！
いかがだったでしょうか？

実装については今後追記していきます。

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

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

# 採用強化中！

CryptoGamesでは一緒に働く仲間を大募集中です。

https://www.wantedly.com/companies/cryptogames

この記事で書いた自分の経験からもわかるように、裁量権を持って働くことができて一気に成長できる環境です。
「ブロックチェーンやWeb3、NFTに興味がある」、「スマートコントラクトの開発に携わりたい」など、少しでも興味を持っている方はまずはお話ししましょう！