# [ERC5380] NFTの使用権限を他のアドレスに付与しよう！

> ERC721規格のNFT所有者が、あるアドレスに対してNFTの限定的な使用を許可する新たなインターフェースの提案です。

- URL: https://cardene.dev/articles/96c2923bc1f967ea7a28
- 公開日: 2023-07-10
- 更新日: 2023-07-10
- トピック: Blockchain
- タグ: blockchain, solidity, ブロックチェーン, nft

## はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回はNFTの使用権を他のアドレスに付与できる**ERC5380**について解説していきます！

:::message
以下を参考にまとめていきます！
:::

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

## 要約

**ERC721**規格のNFT所有者が、あるアドレスに対してNFTの限定的な使用を許可する新たなインターフェースの提案です。

## 動機
NFTの所有者が、他のアドレスに限定的な使用を許可を許可したい場面は多くあります。
レンタルNFTが一つの使用例です。
例えばTCG（トレーディングカードゲーム）のカードがNFTの時、実際にそのNFTを購入することなくそのカードをゲームで使用したいとします。
カード（NFT）の所有者は、借り手にTCGでプレイできるという「**プロパティ（使用許可）**」を出すことで借りては使用できるようになります。
このプロパティは一度に一人だけに割り当てられるべきです（誰でも「レンタル」できてしまうため）。

## インターフェースの実装

```javascript
interface ERC5380Entitlement is ERC165 {
    event EntitlementChanged(address indexed user, address indexed contract, uint256 indexed tokenId);

    function entitle(address user, address contract, uint256 tokenId) external;

    function maxEntitlements(address contract, uint256 tokenId) external view (uint256 max);

    function entitlementOf(address user, address contract, uint256 tokenId) external view returns (uint256 amt);
}
```

#### EntitlementChanged

ユーザーの権利量が変更されたときにログに記録する。
もし0アドレスの時は、NFTの所有者は0アドレスと判定される。

#### entitle

所有者がこの関数の実行者（`msg.sender`)の場合、特定のトークンIDのNFTに関連する特定の権限をあるアドレスに付与する関数。
NFTの所有者が関数の実行者（`msg.sender`)でない場合でも、処理を戻すべきではないです。

**引数**
- `user`
    - 権限を付与するアドレス。
- `contract`
    - コントラクトアドレス。
- `tokenId`
    - プロパティを付与するNFTのトークンID。

#### maxEntitlements

特定の権限を受け取ることができるユーザーの最大数を取得する関数。

**引数**
- `contract`
    - 確認するコントラクトアドレス。
- `tokenId`
    - 確認するNFTのトークンID。

#### entitlementOf

指定されたコントラクトと特定のNFTのトークンIDに関連づけられたアドレスを取得する関数。
デフォルトでは、`contract.ownerOf(tokenId)｀に割り当てられた、`maxEntitlements(contract, tokenId)`の値を返す。

**引数**

- `user`
    - 確認するアドレス。
- `contract`
    - 確認するコントラクトアドレス。
- `tokenId`
    - 確認するNFTのトークンID。


#### その他

`supportsInterface`は、`ERC5380Entitlement`のインタフェースIDで呼び出された場合、trueを返す。

## 拡張機能

### 列挙機能

```javascript
interface ERC5380EntitlementEnumerable is ERC5380Entitlement { // Also implicitly supports ERC-165
    function entitlementOfUserByIndex(address user, uint256 index) external view returns (address contract, uint256 tokenId);
}
```

アドレスに割り当てられた権限が1以上のNFTを列挙し、特定インデックスの値を返す関数。

**引数**
- `user`
    - 確認するアドレス。
- `index`
    - 確認するインデックス。


### メタデータ

```javascript
interface ERC5380InteroperabilityMetadata is InteroperabilityMetadata {
    erc5380?: boolean | undefined;
}
```

**ERC5380**トークンのメタデータである場合は`true`を返し、そうでない場合は削除する。

### トークンURI

以下のインターフェースに準拠していなければならない。

```javascript
interface ERC5380TokenMetadata {
    interop: ERC5380InteroperabilityMetadata;
    
    name?: string;
    
    symbol?: string;
    
    description?: string;
    
    images?: string[];
    
    icons?: string[];
}
```

**interop**
異なるタイプのトークンと、それに対応するURIを区別する。

**name**

**ERC5380**トークンの名前。

**symbol**

**ERC5380**トークンのシンボル。

**description**

**ERC5380**トークンの説明（マークアップや改行なしで、１段落で簡潔に記述）。

**images**

1つ以上の画像。
`1.91:1`から`4:5`のアスペクト比を持つようにする。

**icons**

1つ以上の画像。
`1:1`のアスペクト比で背景は透明にする。

## 補足

**ERC20**と**ERC1155**は、所有している・していないの選択よりも所有権を追跡するのが複雑なためサポートされていないです。

## セキュリティ

**ERC721**と**ERC1046**のセキュリティ上の考慮事項が適用される。

## 最後に

今回はNFTの使用権を他のアドレスに付与できる**ERC5380**について解説してきました！
いかがだったでしょうか？
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

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

## 採用強化中！

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

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

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