您好,登錄后才能下訂單哦!
這篇文章主要講解了“ERC721藏品合約怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“ERC721藏品合約怎么實現”吧!
ERC721約定了一些接口函數,使它在一定程度上符合ERC20代幣標準。這么做是為了讓現有的 錢包更容易顯示代幣的基本信息。這些函數可以讓符合ERC721標準的智能合約像比特幣或者 以太幣這樣普通的數字加密幣一樣,通過智能合約編程的方式定義一些功能讓用戶實現向他人 發送代幣或檢查賬戶余額等操作。
這是一個簡明的ERC721智能合約聲明:
contract ERC721 { //與ERC20兼容的接口 function name() constant returns (string name); function symbol() constant returns (string symbol); function totalSupply() constant returns (uint256 totalSupply); function balanceOf(address _owner) constant returns (uint balance); //所有權相關的接口 function ownerOf(uint256 _tokenId) constant returns (address owner); function approve(address _to, uint256 _tokenId); function takeOwnership(uint256 _tokenId); function transfer(address _to, uint256 _tokenId); function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId); //通證元數據接口 function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl); //事件 event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); }
該函數應當返回通證的名稱。 例如:
contract MyNFT { function name() constant returns(string name){ return "My Non-FungibleToken"; } }
該函數應當返回通證的符號,它有助于提高與ERC20的兼容性。例如:
contract MyNFT { function symbol() constant returns(string symbol){ return "MNFT"; } }
該函數應當返回區塊鏈上供應的通證總數量,該數量不一定是固定不變的。 例如:
contract MyNFT { //想發行多少取決于你 ;) uint256 private totalSupply = 1000000000; function totalSupply() constant returns (uint256supply){ return totalSupply; } }
該函數用于查詢某一地址里的通證余額。例如:
contract MyNFT { mapping(address => uint) privatebalances; function balanceOf(address _owner) constant returns(uint balance){ return balances[_owner]; } }
下面這些函數定義了合約如何處理通證的所有權及如何轉移所有權。其中最重要的兩個函數 是獲取(takeOwnership)和轉賬(transfer),用來實現用戶之間的通證流轉,就像銀行的提款 和匯款功能。
該函數返回通證持有人的地址。因為每一個ERC721通證都是不可替代的,因此可以在區塊鏈上 唯一的地址找到,我們可以用通證的ID來確定其持有人。
contract MyNFT { mapping(uint256 => address) privatetokenOwners; mapping(uint256 => bool) private tokenExists; function ownerOf(uint256 _tokenId) constant returns (address owner) { require(tokenExists[_tokenId]); return tokenOwners[_tokenId]; } }
該函數用來授權給另一主體代表持有人進行通證轉移操作。例如,假設Alice有一個ERC721通證,她可以 調用approve
函數來授權給她的朋友Bob,然后Bob就可以代表Alice行使通證持有人的權利。
contract MyNFT { mapping(address => mapping (address=> uint256)) allowed; function approve(address _to, uint256 _tokenId){ require(msg.sender ==ownerOf(_tokenId)); require(msg.sender != _to); allowed[msg.sender][_to] = _tokenId; Approval(msg.sender, _to, _tokenId); } }
該函數類似于取款功能,一個外部主體通過調用takeOwnership
函數來從另一個用戶的賬戶 中提取ERC721通證。
因此,在一個用戶被(其他人)授權擁有一定數量的通證的情況下,可以通過該功能將這部分 通證從另一個用戶的賬戶中提取出來。
contract MyNFT { function takeOwnership(uint256_tokenId){ require(tokenExists[_tokenId]); address oldOwner = ownerOf(_tokenId); address newOwner = msg.sender; require(newOwner != oldOwner); require(allowed[oldOwner][newOwner] == _tokenId); balances[oldOwner] -= 1; tokenOwners[_tokenId] = newOwner; balances[oldOwner] += 1; Transfer(oldOwner, newOwner,_tokenId); } }
另一種轉移通證的方法時使用transfer
函數。轉賬(transfer)功能可以讓用戶將通證發給另一個用戶, 類似于操作比特幣這樣的加密數字貨幣。然而,只有在匯出賬戶之前授權過匯入賬戶持有其通證的 情況下,才可以進行轉賬。
contract MyNFT { mapping(address => mapping(uint256 => uint256)) private ownerTokens; function removeFromTokenList(address owner, uint256 _tokenId) private { for(uint256 i = 0;ownerTokens[owner][i] != _tokenId;i++){ ownerTokens[owner][i] = 0; } } function transfer(address _to, uint256 _tokenId){ address currentOwner = msg.sender; address newOwner = _to; require(tokenExists[_tokenId]); require(currentOwner == ownerOf(_tokenId)); require(currentOwner != newOwner); require(newOwner != address(0)); removeFromTokenList(_tokenId); balances[oldOwner] -= 1; tokenOwners[_tokenId] = newOwner; balances[newOwner] += 1; Transfer(oldOwner, newOwner, _tokenId); } }
這個函數是可選的,但推薦你實現它。
每一個ERC721通證的持有者可以同時持有不止一個通證,因為每個通證都有唯一的ID,但是,要跟蹤某個用戶持有的 通證可能就會比較困難。為此,合約需要記錄每個用戶持有的每個通證。通過這種方式,用戶可以 通過索引清單檢索其擁有的通證。通證檢索(tokenOfOwnerByIndex)函數可以通過這種方式追溯某一特定的通證。
contract MyNFT { mapping(address => mapping(uint256 => uint256)) private ownerTokens; function tokenOfOwnerByIndex(address _owner, uint256 _index) constant returns (uint tokenId){ return ownerTokens[_owner][_index]; } }
就像我們之前所說的,使物品具有不可替代性的是它們獨一無二的特質。美元和網球卡不可替代, 因為它們的特征不同。但是,在區塊鏈上將這些區分每個通證的特征儲存下來成本很高,也不推薦這么做。 為了解決這個問題,我們可以儲存每個通證的引用(references),例如IPFS哈希或HTTP(S)鏈接,這些 引用,被稱作元數據。元數據是可選的。
tokenMetaData函數應當返回通證的元數據,或者通證數據的鏈接。
contract MyNFT { mapping(uint256 => string) tokenLinks; function tokenMetadata(uint256 _tokenId) constant returns (string infoUrl) { return tokenLinks[_tokenId]; } }
當調用合約方法的時候,事件將會被觸發,并且一旦被觸發就會向監聽系統傳播。外部應用可以監聽區塊鏈 中的事件,一旦接收到區塊鏈中的事件被觸發,監聽系統就可以通過事件中包含的信息執行邏輯程序。 ERC721標準定義了下面兩個事件。
當一個通證的所有權從一個用戶轉移到另一個時,將觸發該事件,事件的信息包括匯出賬戶、匯入賬戶和通證ID。
contract MyNFT { event Transfer(address indexed _from,address indexed _to, uint256 _tokenId); }
當一個用戶允許另一個用戶持有其通證的時候(例如啟用“授權”功能的時候),該事件就會被觸發,事件的信息中 包含這些通證現在的持有賬戶、被授權賬戶以及通證ID。
contract MyNFT { event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); }
感謝各位的閱讀,以上就是“ERC721藏品合約怎么實現”的內容了,經過本文的學習后,相信大家對ERC721藏品合約怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。