Rental Standard Overview
2018/10/17時点で提案されているERC721の貸借実装についての提案をまとめる
https://gyazo.com/9c906b3601f35f219551d472ad364ec7
簡易まとめ
ERC721を機能拡張して利便性を高めようという流れの1つに貸借機能の実装がある
貸借機能というのは特定のアドレス(アカウント)に対して特定の期間中に特定の制限を与えることとする
貸借機能を汎用的な標準として定めようという提案がERC809
現在ERC809を草案とし、その改善案としてERC1201やERC809 Two Tiered Token Architecutureが提案されている
変遷でいくと、ERC809 => ERC1201 => Two Tiered Token という流れがある
この貸借標準と提案自体はドラフトの段階で、絶賛改善募集中
トークンとは
トークンとは何かを復習したい方は以下の記事を参考に。
レンタル機能
レンタル機能を端的に表すと、"誰が、何を、一定期間、保証される権利を、重複なく"表せれば良い。
機能に落とし込むと以下の
貸し出し
借り入れ
期間チェック
重複チェック
キャンセル
ERC721
お馴染み、Non-fungible Tokenを実現するためのインターフェース定義。
ここでは解説は省きます。詳細は以下を参考に
ERC809
本記事のメイントピック
実提案は以下のリンクを参照
ERC809とは?
ERC721の規格に互換性を持ち、トークンを貸借する機能を実現するインターフェース定義の草案として提案されたのがERC809
ERC809を改善した提案として、以下で紹介するERC1201やERC809 Two Tiered Tokenが出ている。
ERC809の実態はERC721のインターフェースを継承し、ERC809で提案するインターフェースを拡張として実装した形になっている。(以下図が参考)
https://gyazo.com/1c1a30ccd70f22bc30e71128024c8f8f
https://gyazo.com/1b256fbf86d992da20a1e2103f6b6865
ERC809が提案するインターフェース
Functions
reserve
access
settle
checkAvailable
cancelReservation
Events
Reserve
dCancel
Functions & Eventsをより詳解に見ていく
Functions
reserve
code:Solidity
function reserve(uint256 _tokenId, uint256 _start, uint256 _stop) external returns (bool success) public;
tokenId / start / stop を引数に渡して、特定のトークン(tokeId指定)を期間単位(start / stop)で借りる予約(reserve)をする。
予約が成功するには、引数で渡したstartとstopの範囲が後述するcheckAvailable()関数の呼び出しで、事前に予約されていない(つまり、他の予約と被らないか)を確認してから予約処理を実行し、予約処理完了のEventであるReserveを発火する。
access
code: Solidity
function access(uint256 _tokenId) external returns (bool success);
トランザクション実行時点の、tokenIdのレンタル主(借主)であるかどうかを判定する関数。
返り値はbool型
settle
code: Solidity
function settle(uint256 _tokenId, address _renter, uint256 _stop) external returns (bool success);
ホテルのチェックアウト、レンタカーの返却のタイミングで呼び出される関数
now >= _stop の制約を儲けることで早期に資金を戻されるのを防いだりできる
checkAvailable
code: Solidity
function checkAvailable(uint256 _tokenId, uint256 _start, uint256 _stop) public view returns (bool available);
レンタル可能かどうかを判断する処理。requireで呼ばれる
ここのロジックほんとか?と思う部分があるため後時間をとって精査。
やりたいこととしては、tokenIdで指定したトークンを_timeで借りれるかどうかを判断する。
バリデーションロジック(過去データからダブりを排除する)はデータ構造的にも工夫が必要(for文を実行しガスがかかってくるため)。
cancelReservation
code: Solidity
function cancelReservation(uint256 _tokenId, uint256 _start, uint256 _stop) external returns (bool success);
関数名の通り、予約をキャンセルする処理
Events
Reserve
code: Solidity
event Reserve(address indexed _renter, uint256 _tokenId, uint256 _start, uint256 _stop)
予約が完了した時に発火されるEvent
Cancel
code: Solidity
event CancelReservation(address indexed _renter, uint256 _tokenId, uint256 _start, uint256 _stop)
予約キャンセルが完了した時に発火されるEvent
疑問点
期間指定してレンタルした場合、効率の良い重複判定ロジックをどう築くのか
現状いくつかPoC実装を調査したが、あまりよくできているものはない。"よくできているもの"というものはパフォーマンス(ガスコスト低減)も考慮したもの。for文で探索するのがメインアプローチだが、データが肥大がするにつれて探索回数が増えるため問題
赤黒木のアプローチがある...??
ERC1201
ERC809の影響を受け、さらなる改善案として考案されたのがERC1201
ERC1201とは?
ERC1201はERC809に影響を受け、改善案として提案された規格。ERC809はERC721に特定のフィールドと関数を設け、同一コントラクトの機能拡張としてのアプローチ。対してERC1201では、貸借をトークン化することで、利便性を高めることを目指している。ここでの利便性は、トークンにすることで貸借権を他者にtransferすることができるなど、トークンとして流動性を持たせることを指す。
つまり、貸借機能の実現をERC809とは異なる角度からアプローチしているのがERC1201ということ。
ERC1201の提案には2つのトークンが登場する
ERC721 Non-Fungible Token
Rental Token
https://gyazo.com/0660a21f0b45733d108c128b24ce1a06
Tier 2 Rental Token
mintRental
code:Solidity
function mintRental(uint256 tokenId, uint256 start, uint256 end, address renter) external;
レンタルトークンをmintする処理。ERC721でいうmint
setRentalRights
code:Solidity
function setRenterRights(uint256 tokenId, address renter, bool canBurn, bool canTransferToAll, bool canTransferToPreapproved, bool canCopyAcrossRights) public
addPreapprovedRenters
code:Solidity
function addPreapprovedRenters(uint tokenId, address[] preapprovedList) public
removePreapprovedRenters
code:Solidity
function addPreapprovedRenters(uint tokenId, address[] preapprovedList) public
approveRentalTransfer
code:Solidity
function approveRentalTransfer(address approved, uint256 tokenId, uint256 start, uint256 end) public
transferRentalFrom
code:Solidity
function rentalTransferFrom(address from, address to, uint256 tokenId, uint256 start, uint256 end) public
cancelRental
code:Solidity
function cancelRental(address owner, uint256 tokenId, uint256 start, uint256 stop) public returns (bool success)
rentalExists
code:Solidity
function exists(uint256 tokenId, uint256 timeIndex) public view returns (bool)
特定の期間(TIMEINDEX)
ownerOfRental
code:Solidity
function ownerOfRental(uint256 tokenId, uint256 time) public view returns (address)
レンタルトークンのownerをgetする関数
balanceOfRental
code:Solidity
function balanceOfRental(address owner, uint256 tokenId, uint256 start, uint256 end) public view returns (uint256)
balanceOfRentalApproval
code:Solidity
function balanceOfRentalApproval(address approved, uint256 tokenId, uint256 start, uint256 end) public view returns (uint256)
ERC1201が抱える課題
ERC1201の提案にも課題があった。(課題というと大げさだが、改善点があったという感じ)
課題とは、レンタル権トークンを管理するERC1201準拠のコントラクトのインターフェースがERC721の命名と衝突し、独自のインタフェース定義となっているということ。
ERC1201に準拠することで、レンタル権をトークンとして扱える(他者にtransfer可能など)ようになったが、ERC721と命名が衝突しているので、取引所などが既に対応しているtransferFromなどの処理に対応できなくなっている。
既存の標準規格のレールに乗っかれていない(恩恵を受けることができない)という提案になっていた。
この課題とERC809、ERC1201の提案を汲み取り、ERC1201の改善と既存規格との整合性を保てる規格を目指した改善案として提案されたのが次に紹介するERC809 Two Tiered Token
ERC809 Two Tiered Token
現在(2018/10/25時点)、最も先端で議論と提案がされているのがERC809 Two Tiered Token
ERC809 Two Tiered Tokenとは?
ERC1201の提案をさらに改善したものがERC809 Two Tiered Token
ERCとして提案されている訳ではないためERC809 Two Tiered Tokenという呼ばれている
この案が現在最も優れた形式であると個人的に思っている
https://gyazo.com/f256edd92588fe74d7d4ac766616e9e8
https://gyazo.com/2ab8c9edb7701a07df8386b79c77e80d
上記の図がアーキテクチャが端的に表している。
ERC721を継承したERC809 Parent トークン(NFT)とERC809 Child トークン(レンタルトークン)で構成されている。
この構成にすることで。NFTのレンタル権をトークンとして扱うことができ、さらにレンタル権はNFTに準拠(継承)しているため、既存の取引所システムなどでも用いることができる様になる。
ERC809 Two Tiered Tokenを提案している方は以下の様な考え方を示しており、「既存の基準に則ることは新たな標準を考案/提案する上では非常に重要な考え方だ」と説いています。
Software engineering has long recognized the importance of code reuse and open source. Composing token standard not only let us reuse the smart contract implementations but also strengthen the underneath economy and protocol at the same time.
課題
時間重複問題の効率の良い探索
スケジュール選択以外の方法での賃借手段 (回数貸しなど)
実装例
参考記事
PoC