ERC721標(biāo)準(zhǔn)是在ERC20標(biāo)準(zhǔn)上建立的代幣標(biāo)準(zhǔn),是針對(duì)不可互換代幣(non-fungible tokens 簡(jiǎn)稱NFTs)做的智能合約標(biāo)準(zhǔn)挎狸。目前為止只是在草稿階段(Draft)忘古,還未最終定稿技竟。什么是不可互換資產(chǎn)呢窿凤,現(xiàn)在正火的加密貓(CryptoKitties)就是一個(gè)典型的應(yīng)用睬捶,每只貓都有一個(gè)唯一的id黔宛。在這個(gè)場(chǎng)景下,不僅需要跟蹤每個(gè)賬戶下的資產(chǎn)數(shù)量擒贸,而且需要跟蹤每個(gè)資產(chǎn)id的轉(zhuǎn)移臀晃。
與ERC20標(biāo)準(zhǔn)相同部分
與ERC20標(biāo)準(zhǔn)兼容部分不做詳細(xì)介紹,想了解ERC20可以看ERC-20代幣標(biāo)準(zhǔn)
function name() constant returns (string name);
function symbol() constant returns (string symbol);
function totalSupply() constant returns (uint256 totalSupply);
function balanceOf(address _owner) constant returns (uint256 balance);
與ERC20標(biāo)準(zhǔn)不同部分
方法
ownerOf
function ownerOf(uint256 _tokenId) constant returns (address owner)
- 本方法必須實(shí)現(xiàn)
- 返回代幣id為
_tokenId
的擁有者賬戶owner
- 如果查詢的
_tokenId
不存在介劫,拋出throw
- 如果是已經(jīng)銷毀的NFS(不可互換代幣)徽惋,拋出
throw
,而不是返回0
approve
function approve(address _to, uint256 _tokenId)
- 本方法必須實(shí)現(xiàn)
- 批準(zhǔn)id為
_tokenId
的NFS轉(zhuǎn)移到新賬戶_to
下 - 如果
msg.sender != ownerOf(_tokenId)
座韵,拋出throw
- 如果
_tokenId
不存在险绘,拋出throw
- 如果
msg.sender != _to
踢京,拋出throw
- 方法成功完成必須發(fā)出一個(gè)Approval事件
- 狀態(tài)變更與事件對(duì)應(yīng)表
動(dòng)作 | 前狀態(tài) | _to 地址 | 新狀態(tài) | 事件 |
---|---|---|---|---|
清除未設(shè)置 | 清除 | 0 | 清除 | 無 |
設(shè)置 | 清除 | X | 設(shè)置為X | Approval(owner,X,tokenID) |
更改 | X | Y | 設(shè)置為Y | Approval(owner,Y,tokenID) |
重復(fù)設(shè)置 | X | X | 設(shè)置為X | Approval(owner,X,tokenID) |
清除 | X | 0 | 清除 | Approval(owner,0,tokenID) |
takeOwnership
function takeOwnership(uint256 _tokenId)
- 本方法必須實(shí)現(xiàn)
- 取得所有權(quán)
- 將id為
_tokenId
的NFT的所有權(quán)分配給msg.sender - 只有在msg.sender已獲取批準(zhǔn)的情況下才能成功執(zhí)行
- msg.sender未獲得
_tokenId
的批準(zhǔn),拋出throw
- 如果
_tokenId
不存在宦棺,拋出throw
- msg.sender 已經(jīng)擁有
_tokenId
瓣距,拋出throw
- 成功轉(zhuǎn)移必須觸發(fā)Transfer事件
tokenOfOwnerByIndex
function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId)
- 可選的(OPTIONAL)
- 建議實(shí)現(xiàn)此方法以提高錢包和交易所的使用體驗(yàn),但是接口或者其它合約不應(yīng)依賴于此方法的存在代咸。
- 返回賬戶
_owner
的第n個(gè)NFT蹈丸,n由_index
參數(shù)指定 - 如果
_index >= balanceOf(_owner)
,拋出throw
- 示例代碼
uint256 ownerBalance = nonFungibleContract.balanceOf(owner);
uint256[] memory ownerTokens = new uint256[](ownerBalance);
for (uint256 i = 0; i < ownerBalance; i++) {
ownerTokens[i] = nonFungibleContract.tokenOfOwnerByIndex(owner, i);
}
NFT 元數(shù)據(jù)
tokenMetadata
function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl)
- 可選的(OPTIONAL)
- 建議實(shí)現(xiàn)此方法以提高錢包和交易所的使用體驗(yàn)呐芥,但是接口或者其它合約不應(yīng)依賴于此方法的存在逻杖。
- 返回一個(gè)引用外部資源包的多地址字符串
- 該外部資源包包含與NFT關(guān)聯(lián)的元數(shù)據(jù)
- 多地址字符串必須是一個(gè)IPFS或HTTP的路徑,包含多個(gè)子路徑
標(biāo)準(zhǔn)子路徑:
- name(必需):包含NFT的名稱(UTF-8編碼)贩耐,每個(gè)NFT都有唯一的name弧腥。不超過50個(gè)字符,可以包含空白潮太,但不能包含換行管搪。name可能是一個(gè)帶數(shù)字的名稱,以區(qū)分一組中的其它NFT铡买。例如:"Happy Token #157"
- image(可選):包含一個(gè)PNG更鲁,JPEG或SVG圖像,每個(gè)維度至少有300個(gè)像素奇钞。圖像寬高比應(yīng)該在16:9(風(fēng)景模式)和2:3(人像模式)之間澡为。圖像應(yīng)該用一個(gè)“安全區(qū)域”來構(gòu)建,這樣將圖像裁剪到一個(gè)最大的中心方塊不會(huì)消除任何關(guān)鍵信息景埃。(要達(dá)到這個(gè)要求媒至,最簡(jiǎn)單的方法就是使用1:1的圖像寬高比。
- description(可選):包含NFT的UTF-8編碼文本描述谷徙。描述可以包含多行拒啰,使用一個(gè)換行符來分隔行,兩個(gè)換行符來分隔段落完慧。描述可以使用Markdown格式谋旦。不超過1500個(gè)字符。
- other metadata(可選):可以選擇包括任意數(shù)量的其它子路徑屈尼。
事件
Transfer
event Transfer(address indexed _from, address indexed _to, uint256 _tokenId)
- 必須實(shí)現(xiàn)
- 當(dāng)NFT所有權(quán)通過任何機(jī)制轉(zhuǎn)移時(shí)册着,必須觸發(fā)此事件。
- 創(chuàng)建新NFT時(shí)必須為每個(gè)新創(chuàng)建的NFT觸發(fā)Transfer事件脾歧,
_from
地址為0甲捏,_to
地址匹配新NFT(可能是智能合約本身)的所有者。 - 刪除(或消耗)NFT時(shí)必須觸發(fā)Transfer事件涨椒,_to地址為0 摊鸡,_from是NFT刪除前的所有者绽媒。
- Transfer事件
_from == _to
是有效的蚕冬。
Approval
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId)
- 必須實(shí)現(xiàn)
- 所有成功調(diào)用
approve(address _spender, uint256 _value)
方法免猾,都必須觸發(fā)此事件
標(biāo)準(zhǔn)創(chuàng)建日期:2017-09-20
參考文檔 https://github.com/ethereum/EIPs/issues/721