[ERC5604] NFTに担保権を設定するインターフェースの仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、NFTに対する担保権（リーン）を設定し、管理するためのインターフェースを提案している**ERC5604**についてまとめていきます！

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

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

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

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

# 概要

**リーン（Lien）** とは、負債の回収や他の義務の履行を保証するために、財産項目に対して設定される担保権の一形態です。
不動産や車両など、具体的な資産に対してよく用いられます。

このERCは、NFTに対してリーン（担保権）を設定し、管理するためのインターフェースを提案しています。

- **リーンの設置**
    - NFTの所有権に対するリーン（担保権）を設置する機能。
    - これにより、NFTがある負債や義務の保証として機能することができます。
- **リーンの解除**
    - 負債や義務が履行された後、NFTに設置されたリーンを解除する機能。
- **イベント**
    - リーンの設置や解除が行われた時に、それを外部に通知するためのイベントログを発行します。

### 実装のポイント

- **インターフェースの定義**
    - この標準は、リーンの設置と解除のための明確なインターフェースを定義します。
    - これにより、他のスマートコントラクトやアプリケーションがこの機能を簡単に統合し、利用することが可能になります。
- **透明性と信頼性の向上**
    - リーンの設置と解除がブロックチェーン上で透明に行われることで、NFTの取引や担保に関する信頼性が向上します。
- **法的枠組みとの連携**
    - 実世界の担保権と同様に、NFTに対するリーンもまた、負債の保証手段として機能することを意味します。
    - これは、デジタル資産を用いた融資や保証など、新たな金融サービスの展開を可能にします。

:::note info
このERCは、NFTというデジタル資産の新しい用途を提案しています。
担保権の概念をNFTに適用することで、デジタル資産を用いたより安全かつ透明な金融取引が可能になります。
スマートコントラクトを通じて実装されるこの機能は、NFT市場だけでなく、広範な金融業界に影響を与える可能性があります。
:::

:::note info
### リーン

### 車の購入とリーンの設定

あなたが新しい車を購入しようとしているとしますが、全額を一括で支払うのではなく、ローンを利用して支払いたいと考えています。

1. **ローンの申し込み**
    - 車を購入するために、あなたは銀行や金融機関からローンを申し込みます。
2. **リーンの設定**
    - ローンが承認されると、その車に対してリーンが設定されます。
    - これは、あなたがローンを完済するまでの間、銀行が車に対して持つ一種の「**権利**」や「**担保権**」です。
3. **車の使用**
    - リーンが設定されていても、あなたは車を普通に使用することができます。
    - しかし、車を売却したり、他の人に譲渡することは、リーンが解除されるまで基本的にはできません。
4. **ローンの完済**
    - ローンを全額返済すると、リーンは解除され、車の完全な所有権があなたに移ります。
    - これにより、あなたは車を自由に売却したり、他人に譲渡することが可能になります。

### NFTとリーン

この車の購入の例を、NFT（非代替トークン）に適用してみましょう。
あるデジタルアートのNFTを購入する時に、同じようにローンを利用したいと思ったとします。

1. **NFTの購入**
    - あなたは、ある価値あるデジタルアートのNFTを分割払いで購入したいと考えます。
2. **リーンの設定**
    - 資金提供者（例えば、NFTを提供するプラットフォームや金融機関）は、そのNFTにリーンを設定します。
    - これは、あなたがローンを完済するまで、NFTに対する一種の権利を持つことを意味します。
3. **NFTの使用**
    - リーンが設定されている間も、あなたはそのNFTを所有して展示したり、あるいは特定の場合には使用することができますが、売却や譲渡は制限されます。
4. **ローンの完済**
    - ローンを完済すると、リーンは解除され、NFTの完全な所有権があなたに移ります。
    - これにより、自由にNFTを売却したり、他人に譲渡することが可能になります。

このように、リーンは物理的な資産だけでなく、デジタル資産にも適用することができる概念であり、所有権の保護や財産の安全な取引を可能にします。
:::

# 動機

NFT（Non-Fungible Token）リーンに関するERC（Ethereum Request for Comments）の使用例として、「**権利証（deed）**」が挙げられています。
これは、不動産や車両に対するリーン（担保権）と同じように、NFTを使った金融取引において担保としての役割を果たすことを意味します。
ここで、その仕組みや利点を踏まえて、より深く掘り下げてみましょう。

### NFTリーンの概念

NFTリーンとは、特定のNFTに対して設定される担保権です。
これは、貸借契約や義務の履行を保証するために用いられます。
例えば、ある個人が資金を借りる時に、自分が所有する価値あるNFTを担保として提供することができます。

### 権利証（Deed）としての使用例

不動産の所有権を示す権利証は、その不動産を担保としてローンを得る時に重要な役割を果たします。
同様に、NFTを権利証と見なすことにより、デジタルまたは仮想の財産（例えばデジタルアート、仮想不動産など）を担保として利用することが可能になります。

### ERCが提供するインターフェース

このERCは、NFTにリーンを設置し、管理するためのインターフェースを提供します。

- **リーンの設置**
    - 特定のNFTに対してリーンを設置し、そのNFTを担保として指定することができます。
- **リーンの解除**
    - 契約または義務が履行された時に、設置されたリーンを解除し、NFTの自由な取引を可能にします。

### 利点と応用

- **透明性と信頼性**
    - リーンの設置と解除がブロックチェーン上で行われるため、全ての取引が透明かつ不変の記録として残ります。
- **新たな金融サービスの開発**
    - この機能により、NFTを用いた新しい形の融資や投資が可能になります。
    - 例えば、デジタルアートや仮想不動産などの価値あるNFTを担保として、資金を調達することができます。
- **法的枠組みとの整合性**
    - 実世界の担保権と同様に、NFTに対するリーンもまた法的な保護を提供し、契約の履行を保証します。

:::note info
NFTリーンに関するこのERCは、デジタル資産を用いた金融取引における新たな可能性を開きます。
不動産の権利証のように、NFTを担保として使用することで、個人や企業は新しい形の融資や投資にアクセスできるようになります。
この進歩は、デジタル経済のさらなる成長と、ブロックチェーン技術の応用範囲の拡大を示しています。
:::

# 仕様

この規格に準拠するコントラクトは、**ERC721**と**ERC165**を実装しなければいけません。
この規格に準拠するコントラクトは、以下のインタフェースを実装する必要があります。

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

https://qiita.com/cardene/items/541184977a5cba51b759

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

https://chaldene.net/erc721

```ts
interface IERC_LIEN is ERC721, ERC165 {

    /// === Events ===

    /// @notice MUST be emitted when new lien is successfully placed.
    /// @param tokenId the token a lien is placed on.
    /// @param holder the holder of the lien.
    /// @param extraParams of the original request to add the lien.
    event OnLienPlaced(uint256 tokenId, address holder, bytes calldata extraParams);

    /// @notice MUST be emitted when an existing lien is successfully removed.
    /// @param tokenId the token a lien was removed from.
    /// @param holder the holder of the lien.
    /// @param extraParams of the original request to remove the lien.
    event OnLienRemoved(uint256 tokenId, address holder, bytes calldata extraParams);

    /// === CRUD ===

    /// @notice The method to place a lien on a token
    ///         it MUST throw an error if the same holder already has a lien on the same token.
    /// @param tokenId the token a lien is placed on.
    /// @param holder the holder of the lien
    /// @param extraParams extra data for future extension.
    function addLienHolder(uint256 tokenId, address holder, bytes calldata extraParams) public;

    /// @notice The method to remove a lien on a token
    ///         it MUST throw an error if the holder already has a lien.
    /// @param tokenId the token a lien is being removed from.
    /// @param holder the holder of the lien
    /// @param extraParams extra data for future extension.
    function removeLienHolder(uint256 tokenId, address holder, bytes calldata extraParams) public;

    /// @notice The method to query if an active lien exists on a token.
    ///         it MUST throw an error if the tokenId doesn't exist or is not owned.
    /// @param tokenId the token a lien is being queried for
    /// @param holder the holder about whom the method is querying about lien holding.
    /// @param extraParams extra data for future extension.
    function hasLien(uint256 tokenId, address holder, bytes calldata extraParams) public view returns (bool);
}
```

### `addLienHolder`

```javascript
function addLienHolder(uint256 tokenId, address holder, bytes calldata extraParams) public;
```

**概要**

NFTにリーン（担保権）を設置する関数。

**詳細**

この関数は、特定のNFT（`tokenId`で指定）に対して新しいリーンを設置するために使用されます。
リーンは特定のホルダー（`holder`）によって保持されます。
既に同じホルダーによるリーンがそのトークンに設置されている場合、関数はエラーを投げる必要があります。`extraParams`は将来の拡張のために追加データを提供するために使用されます。

**引数**

- `tokenId`
    - リーンを設置するトークンのID。
- `holder`
    - リーンのホルダー（保持者）のアドレス。
- `extraParams`
    - 追加データで、将来の拡張のために用いられる。

---

### `removeLienHolder`

```javascript
function removeLienHolder(uint256 tokenId, address holder, bytes calldata extraParams) public;
```

**概要**

NFTからリーン（担保権）を解除する関数。

**詳細**

特定のNFT（`tokenId`で指定）から既存のリーンを解除するためにこの関数が使用されます。
リーンを解除するには、リーンのホルダー（`holder`）を指定する必要があります。
ホルダーにリーンが存在しない場合、関数はエラーを投げる必要があります。
`extraParams`は将来の拡張のために追加データを提供するために使用されます。

**引数**

- `tokenId`
    - リーンを解除するトークンのID。
- `holder`
    - リーンのホルダー（保持者）のアドレス。
- `extraParams`
    - 追加データで、将来の拡張のために用いられる。

---

### `hasLien`

```javascript
function hasLien(uint256 tokenId, address holder, bytes calldata extraParams) public view returns (bool);
```

**概要**

特定のNFTにアクティブなリーン（担保権）が存在するか確認する関数。

**詳細**

この関数は、特定のトークン（`tokenId`で指定）に対してアクティブなリーンが存在するかどうかを確認するために使用されます。
リーンのホルダー（`holder`）も指定する必要があります。
トークンIDが存在しない、または所有されていない場合、関数はエラーを投げる必要があります。
`extraParams`は将来の拡張のために追加データを提供するために使用されます。

**引数**

- `tokenId`
    - リーンの存在を確認するトークンのID。
- `holder`
    - リーンのホルダー（保持者）に関する確認を行うアドレス。
- `extraParams`
    - 追加データで、将来の拡張のために用いられる。

**戻り値**

- `bool`
    - 指定されたトークンに対して指定されたホルダーによるアクティブなリーンが存在する場合は`true`、そうでない場合は`false`を返します。

---

# 補足

### ERC-721 NFTのみをサポート

#### 理由

シンプルさとガス効率のために、このインターフェースでは**ERC721** NFTのみをサポートしています。
**ERC721**は一意のアセットを表すのに適した標準であり、それぞれのNFTは独自のIDを持っています。
これにより、特定のNFTに対してリーンを設置しやすくなります。

#### 未考慮のERC
**ERC20**（代替可能なトークン）や**ERC1155**（代替可能および非代替可能なトークンの両方をサポートする複合型標準）は考慮されていません。
これらの標準は、将来の拡張で取り扱うことができますが、現時点ではリーンの設置には適していないと判断されました。

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

https://chaldene.net/erc20

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

https://chaldene.net/erc1155

### `addLienHolder` と `removeLienHolder` の分離

リーンの追加と削除は、その性質が大きく異なるため、一つの関数ではなく、`addLienHolder`と`removeLienHolder`として別々に実装されています。
これらのアクションは通常、異なるアクセス制御を必要とします。
例えば、トークンの所有者は他者をリーンホルダーとして追加することができますが、リーンホルダー自身がそのトークンに対するリーンを削除することはできません。

### 債務の金額についての非明記

債務の金額をこのインターフェースに含めていません。
これは、その複雑さと重要性が個別のERCを必要とするほどであると考えられるからです。
債務の金額は、リーンの設置や管理において重要な要素ですが、これを効果的に扱うためにはより詳細な検討が必要です。

### 承認（エンドースメント）の非明記

ホルダーが転送や交換に対する承認を示すためのエンドースメントの適用方法についても明記していません。
これもまた、その複雑さが個別のERCに値すると考えられます。
承認メカニズムは、リーンが設置されたNFTの流動性に影響を与える可能性があり、慎重に設計する必要があります。

:::note info
この設計思想は、NFTリーンを扱うためのインターフェースを効率的かつ実用的に保つことを目指しています。
選択されたアプローチは、現実世界の複雑な法的概念をブロックチェーン技術に適用する時の課題を反映しています。
今後、追加の機能や複雑さを扱うために、新たな標準が提案される可能性があります。
:::

# 互換性

この新しいERCは、既存の**ERC721**標準に基づいて構築されており、**ERC721**に準拠しているコントラクトは、この新しい拡張機能も完全にサポートする必要があります。

# セキュリティ

議論の必要があります。

# 引用

Zainan Victor Zhou (@xinbenlv), Allen Zhou <allen@ubiloan.io>, Alex Qin <alex@ubiloan.io>, "ERC-5604: NFT Lien [DRAFT]," Ethereum Improvement Proposals, no. 5604, September 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5604.

# 最後に

今回は「NFTに対する担保権（リーン）を設定し、管理するためのインターフェースをを提案している**ERC5604**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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