はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、ERC721形式のNFTを共有所有する仕組みを提案しているERC1633についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
ERC1633は、ERC20トークン標準を拡張し、ERC721の共有所有権を表現する新しいトークンであるRe-Fungible Token(RFT)を提案しています。
ERC1633では、既存のERC20との互換性を最大限保ちながら、ERC165インターフェース検出を活用することで、RFTがNFTの一部所有権を示していることをコントラクトレベルで確認できるように設計されています。
ERC165については以下の記事を参考にしてください。
動機
共有所有は、多くの業界で実際に行われておりニーズは日々増しています。
特に、ERC721で表現されるデジタル資産や現実世界の資産において、複数人による所有が求められるケースが増えています。
例えば、ARTBLX Inc.は、アート作品(物理・デジタル・概念的)を複数人で共同所有するためのプロトコルを開発しています。
このプロセスによって生成されるERC20トークンは、関連付けられたNFTの価値を表し、価格発見や所有者間での流動性の確保、ローンやステーブルコインといった金融商品への活用も可能になります。
また、RFTとしてのインターフェースを提案することで、別のDappsが識別できるようになります。
例えば、ウォレットがRFTに対応して元となるNFTのメタデータを表示したり、NFTマーケットプレイスがそのRFTの取引所を案内したりすることが可能です。
どこでERC20が使われている場合でも、それがNFTの共有所有を示すかどうかを知ることは有用です。
仕様
他Dappsに必要な機能
Re-Fungible Token(RFT)標準は、以下の2点を他Dappsに実装されていることを前提として設計されています。
- RFTが通常のERC20トークンではなく、NFTの共有所有権を表すトークンであることを識別できること。
- 特定のNFTが、RFTによって所有されているか判別できること。
RFTからの確認方法
pragma solidity ^0.4.20;
/// @dev Note: the ERC-165 identifier for this interface is 0x5755c3f2.
interface RFT /* is ERC20, ERC165 */ {
function parentToken() external view returns(address _parentToken);
function parentTokenId() external view returns(uint256 _parentTokenId);
}
RFTコントラクトには、以下の2つの読み取り関数が実装されます。
-
parentToken()
- 対象となるNFTコントラクトのアドレス(
address
型)を返す。
- 対象となるNFTコントラクトのアドレス(
-
parentTokenId()
- 対象となるNFTのトークンID(
uint256
型)を返す。
- 対象となるNFTのトークンID(
これにより、RFTがどのNFTを表しているかを特定できます。
また、ERC721準拠であることの確認、NFTの所有者がRFTであることの確認も可能です。
オンチェーンでの確認例
pragma solidity ^0.4.20;
import './RFT.sol';
import './ERC721.sol';
contract ConfirmRFT {
function confirmRFT(address _RFT) external view returns(bool) {
address _NFT = RFT(_RFT).parentToken(); // returns address of NFT contract
uint256 _tokenId = RFT(_RFT).parentTokenId(); // returns id of ID of NFT
return
NFT(_NFT).supportsInterface(0x80ac58cd) && // confirm it is ERC-721
NFT(_NFT).ownerOf(_tokenId) == _RFT; // confirm the owner of the NFT is the RFT contract address
}
}
オフチェーン(JavaScript + web3.js)での確認例
async function confirmRFT(web3) {
const ERC721ABI = [...] // abi for ERC721
const RFTABI = [...] // abi for RFT
const RFTAddress = '0x0123456789abcdef0123456789abcdef' // address for the deployed RFT
const RFTContract = new web3.eth.Contract(RFTABI, RFTAddress) // deployed RFT contract instance
const ERC721Address = await RFTcontract.methods.parentToken().call() // returns address of NFT contract
const ERC721TokenId = await RFTcontract.methods.parentTokenId().call() // returns id of ID of NFT
const ERC721Contract = new web3.eth.Contract(ERC721ABI, ERC721Address) // deployed ERC721 (as reported by RFT)
const isERC721 = await ERC721Contract.methods.supportsInterface('0x80ac58cd').call() // confirm it is ERC-721
const ownerOfAddress = await ERC721Contract.methods.ownerOf(ERC721TokenId).call() // get the owner of the NFT
return ERC721Response.toLowerCase() === RFTAddress.toLowerCase() // confirm the owner of the NFT is the RFT contract
}
NFTからの確認方法
特定のNFTトークンの所有者がRFTであるかを判断するには、ERC165インターフェース検出機能を活用します。
-
supportsInterface(bytes4 interfaceID)
が0x01ffc9a7
(ERC-165)および0x5755c3f2
(RFT)に対してtrue
を返す必要があります。 -
0x5755c3f2
はparentToken()
とparentTokenId()
のセレクタをXORした結果で、RFT専用のインターフェースIDです。
function supportsInterface(bytes4 interfaceID) external view returns (bool);
オンチェーンでの確認例
pragma solidity ^0.4.20;
import './RFT.sol';
import './ERC721.sol';
contract ConfirmRFT {
function confirmRFT(address _NFT, uint256 _tokenId) external view returns(bool) {
address _RFT = ERC721(_NFT).ownerOf(_tokenId); // get the owner of the NFT
return
RFT(_RFT).supportsInterface(0x01ffc9a7) && // confirm it supports ERC-165
RFT(_RFT).supportsInterface(0x5755c3f2) // confirm it is RFT
}
}
オフチェーン(JavaScript + web3.js)での確認例
async function confirmRFT(web3) {
const ERC721ABI = [...] // abi for ERC721
const RFTABI = [...] // abi for RFT
const ERC721Address = '0x0123456789abcdef0123456789abcdef' // address for the deployed NFT
const ERC721TokenId = '7' // token Id of the NFT
const ERC721Contract = new web3.eth.Contract(ERC721ABI, ERC721Address) // deployed ERC721
const RFTAddress = await ERC721Contract.methods.ownerOf(ERC721TokenId).call() // owner address of the NFT
const RFTContract = new web3.eth.Contract(RFTABI, RFTAddress) // deployed RFT contract instance
const isERC165 = await RFTContract.methods.supportsInterface('0x01ffc9a7').call() // confirm it is ERC-165
return isERC165 && await RFTContract.methods.supportsInterface('0x5755c3f2').call() // confirm it is RFT
}
補足
ERC1633の設計における基本方針は、できる限り多くのユースケースに対応できるように柔軟性を最大化することです。
そのため、既存のERC20トークン標準との完全な後方互換性を維持しつつ、すでにデプロイ済みまたは将来的に登場するERC721ともシームレスに連携できる設計になっています。
Re-Fungible Token(RFT)を用いる各プロジェクトは、RFTの発行(mint
)、burn
、ガバナンスの仕組みなどを自らのニーズに応じて自由に構築することが可能です。
互換性
RFT標準は、ERC20トークン標準と完全に互換性があります。
引用
Billy Rennekamp (@okwme), Dan Long dan@artblx.com, Kiryl Yermakou kiryl@artblx.com, Nate van der Ende nate@artblx.com, "ERC-1633: Re-Fungible Token Standard (RFT) [DRAFT]," Ethereum Improvement Proposals, no. 1633, November 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-1633.
最後に
今回は「ERC721形式のNFTを共有所有する仕組みを提案しているERC1633」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!