[ERC5187] ERC1155の所有権と使用権を分離させる仕組みを理解しよう！

# はじめに

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

https://amzn.asia/d/gxvJ0Pw

今回は、**ERC1155**を所有権と使用権を分離し、様々なユースケースに対応させる仕組みを提案している**ERC5187**についてまとめていきます！

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

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

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

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

# 概要

**ERC5187**は、**ERC1155**を拡張し、NFTの「**使用権**」を分離して扱えるようにする提案です。
具体的には、所有者（`owner`）はNFTの所有権を持ち続けたまま、複数のユーザーに対して同時に異なる期間で「**使用権**（NFT-ID）」を貸し出すことができます。

貸し出しが終了すると、使用権はコントラクトによって自動的に回収される仕組みです。
また、NFTの所有者は貸し出し中でも所有権を他の人に譲渡できます。
さらに、借り手同士が使用権を他のユーザーに転貸したり、利用期間を延長したり、
貸し手への早期返却も可能できます。

## 動機

**ERC721**や**ERC1155**は、所有権に重点を置いて設計されてきました。
これはアートやコレクションなど、NFTが「**私有財産**」として利用される場面では理にかなっていました。

しかしNFTの用途は広がりつつあり、ゲーム内アイテムやデジタル空間（メタバース）でのアイテム、ファイナンス領域など、NFTが「**使用される**」ケースが増えています。
例えば、アーティストが自身の作品を一定期間だけメディアに貸し出したい場合や、ゲームギルドが初心者にアイテムを貸して参加のハードルを下げたい場合などです。

現在、NFTを貸す手段としては「**担保の提供**」や「**信頼**」に頼ったもの、あるいは「**中央集権的な管理**」が主流です。
しかし、これではWeb3らしいオープンで自律的な仕組みとは言えず、NFTのレンタル市場の拡大も難しくなります。

そこで提案されているのが、使用期限をもつ「**自動回収型NFT**（expirable NFT）」です。
コントラクトで期限を管理し、信頼や中央管理なしにNFTの貸し出し・回収が可能になります。
これにより、完全にオンチェーンで担保不要なレンタル市場が成立し、NFTの流通や利用方法が広がります。

## 所有権と使用権を分離

**ERC5187**の本質は、NFTの「**所有権**」と「**使用権**」を分離し、それぞれ独立して売買できるようにすることです。

例えば、ある家を貸している最中にオーナーが家を売っても、借り手の権利はそのまま維持されて新しいオーナーが賃料を受け取ることになります。
あるいは、借り手が勝手にその家を他人にまた貸しできるようになり、さらにその人がまた別の人に貸すというように、複数段階のサブリースも可能になります。
そして、最終的な借り手が契約期間を延長することも自由に行えます。

これは従来の不動産市場では難しい仕組みですが、ブロックチェーンを使用することでとらストレスに実現できます。

このようにして、所有権と使用権の市場が独立して形成されると、それぞれの価値も別々に決まるようになります。
所有権は将来的なプロジェクトの成長や期待値に基づいた「**投資商品**」として評価され、使用権は「**今すぐ使うための実用価値**」として、より供給と需要に即した価格がつきやすくなります。

このバランスが取れることで、NFT市場はより持続的で健全な発展が可能になると考えられます。

# 仕様

**ERC5187**は、NFTの**所有権**と**使用権**を分けて扱い、使用権のみを他人に貸し出したり返却したりできるようにするためのインターフェースを提案しています。
**ERC1155**との互換性を前提としており、使用期間の設定、返却、再貸出までを全てコントラクト上で完結できます。

```js:IRental.sol
pragma solidity ^0.8.0;

///  Note: the ERC-165 identifier for this interface is 0x6938e358.
 interface IRental /* is IERC165,IERC1155 */ {
    /**
     * @notice This emits when user rent NFT
     * - `id` The id of the current token
     * - `user` The address to rent the NFT usage rights
     * - `amount` The amount of usage rights
     * - `expire` The specified period of time to rent
     **/
    event Rented(uint256 indexed id,address indexed user,uint256 amount,uint256 expire);

    /**
    * MUST trigger on any successful call to `renew(address user,uint256 id)`
    *  - `id` The id of the current token
    *  - `user` The user of the NFT
    *  - `expire` The new specified period of time to rent
    **/
    event Renew(uint256 indexed id,address indexed user,uint256 expire);

    /**
    *  MUST trigger on any successful call to `renew(address user,uint256 id,uint256 expire)`
    *  - `id` The id of the current token
    *  - `from` The current user of the NFT
    *  - `to` The new user
    **/
    event Sublet(uint256 indexed id,address indexed from,address to);

    /**
     * @notice This emits when the NFT owner takes back the usage rights from the tenant (the `user`)
     * - id The id of the current token
     * - user The address to rent the NFT's usage rights
     * - amount Amount of usage rights
     **/
    event TakeBack(uint256 indexed id, address indexed user, uint256 amount);

    /**
     * @notice Function to rent out usage rights
     * - from The address to approve
     * - to The address to rent the NFT usage rights
     * - id The id of the current token
     * - amount The amount of usage rights
     * - expire The specified period of time to rent
     **/
    function safeRent(address from,address to,uint256 id,uint256 amount,uint256 expire) external;

    /**
     * @notice Function to take back usage rights after the end of the tenancy
     * - user The address to rent the NFT's usage rights
     * - tokenId The id of the current token
     **/
    function takeBack(address user,uint256 tokenId) external;

    /**
    * @notice Return the NFT to the address of the NFT property right owner.
    **/
    function propertyRightOf(uint256 id) external view returns (address);

    /**
    * @notice Return the total supply amount of the current token
    **/
    function totalSupply(uint256 id) external view returns (uint256);

    /**
    * @notice Return expire The specified period of time to rent
    **/
    function expireAt(uint256 id,address user) external view returns(uint256);

    /**
    *   extended rental period
    *  - `id` The id of the current token
    *  - `user` The user of the NFT
    *  - `expire` The new specified period of time to rent
    **/
    function renew(address user,uint256 id,uint256 expire)  external;

    /**
    *  transfer of usage right
    *  - `id` The id of the current token
    *  - `user` The user of the NFT
    *  - `expire` The new specified period of time to rent
    **/
    function sublet(address to,uint256 id) external;
}
```

## イベント

### `Rented`

NFTの使用権をユーザーに貸し出した時に発行されるイベント。

- `id`
    - トークンID。
- `user`
    - 使用権を受け取ったアドレス。
- `amount`
    - 貸し出した使用権の数。  
- `expire`
    - 使用権の期限（タイムスタンプ）。

### `Renew`

既に借りている使用権の期限を延長した時に発行されるイベント。

- `id`
    - トークンID。 
- `user`
    - 使用権を延長したユーザー。 
- `expire`
    - 延長後の期限。

### `Sublet`

借りた使用権を他人に渡した時に発行されるイベント。

- `id`
    - トークンID。  
- `from`
    - 現在の使用者。 
- `to`
    - 使用権を渡したユーザー。

### `TakeBack`

NFTのオーナーが使用期限終了後、使用権を回収した時に発行されるイベント。

- `id`
    - トークンID  
- `user`
    - 回収対象のユーザー。  
- `amount`
    - 回収された使用権の数。

## 関数

### `safeRent`

NFTの使用権を他のユーザーに貸し出す関数。

- `from`
    - 所有者アドレス（NFT保有者）。
- `to`
    - 借り手のアドレス。  
- `id`
    - トークンID。 
- `amount`
    - 貸し出す使用権の数。  
- `expire`
    - 使用期限（タイムスタンプ）。

### `takeBack`

使用期限が切れたNFTの使用権をNFT所有者が回収する関数。

- `user`
    - 使用者のアドレス。  
- `tokenId`
    - トークンID。

### `propertyRightOf`

特定のNFTの所有者アドレスを返す関数。

- `id`
    - トークンID。 
- 戻り値
    - 所有者のアドレス。

### `totalSupply`

トークンIDに対するNFTの総供給量を返す関数。

- `id`
    - トークンID。  
- 戻り値
    - 発行数（数量）。

### `expireAt`

特定ユーザーの使用権の期限を返す関数。

- `id`
    - トークンID。
- `user`
    - 対象ユーザーのアドレス。  
- 戻り値
    - 使用期限のタイムスタンプ。

### `renew`

指定したユーザーのNFT使用権の期限を延長する関数。

- `user`
    - 対象ユーザーのアドレス。  
- `id`
    - トークンID。  
- `expire`
    - 新たな使用期限。

### `sublet`

自身が持つ使用権を他のアドレスに渡す関数。

- `to`
    - 移譲先のアドレス。  
- `id`
    - トークンID。


# 補足

## 複数ユーザーへの同時貸し出しが可能になる

**ERC5187**では、NFTの使用権を複数に分けて扱うことができます。
そのため、NFTの所有者は、`safeRent`関数を使って複数のユーザーに同時に使用権を貸し出すことができます。

使用期間が終了したら、`takeBack` 関数で使用権をコントラクト経由で自動的に回収できます。
これにより、信頼や手作業に頼ることなく複数ユーザーへのレンタルとその管理がスムーズに行えます。

## 使用権のやり取りが柔軟になる

もうひとつの利点は、貸し出した使用権の取り扱いが柔軟になることです。
使用権を受け取ったユーザーは、リース期間中に `sublet` 関数を使って他のユーザーにまたがしすることができます。

また、NFTの所有者に `renew` 関数を実行することで使用期間の延長も可能です。

特に便利なのが、ユーザーが使用権を元の所有者に対して `sublet` することで、途中で使用権を返却することもできるという点です。
これは、借り手の都合で早期に返したい場合などに有効です。

このように、所有権は保持したまま、使う権利だけを複数に分けて貸し出す・返す・譲るというフローが、全てコントラクトで安全に完結するようになります。

# 互換性

**ERC1155**と完全な互換性があります。

# 引用

DerivStudio (@DerivStudio), "ERC-5187: Extend EIP-1155 with rentable usage rights [DRAFT]," Ethereum Improvement Proposals, no. 5187, April 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5187.

# 最後に

今回は「**ERC1155**を所有権と使用権を分離し、様々なユースケースに対応させる仕組みを提案している**ERC5187**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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