20

Smart Contract 智能合約玩轉 NFT 盲盒模式

 3 years ago
source link: https://www.frank.hk/blog/smart-contract-mystery-box/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Smart Contract 智能合約玩轉 NFT 盲盒模式

最近有留意一些 NFT 的項目專案,發現絕大多數都是採用了「盲盒模式」來玩,即購買的時候並不知道裡面是什麼,等到了一定的時間後,盲盒會開啟,才會知道你買的 NFT 具體的屬性,是否稀有等。

screen-20211010180814%402x.png
MekaVerse 盲盒

這裏我們不討論 Marketing 的做法,純粹從技術角度探討一下「盲盒模式」要怎麼做到。

之前寫過一篇文章講怎樣輕鬆編寫 ERC 721 智能合約,裡面有說過 NFT 在 OpenSea 等市場中顯示的名稱,圖像,屬性等資料,完全是由 NFT 的 metadata 決定,而 metadata 則是靠調用 NFT 智能合約中的 tokenURI function 而得到。因此,這個 metadata 並不是像大家想像的一樣不可更改,只要能夠讓智能合約返回不同的 tokenURI, 則在市場中顯示的圖像以及屬性就會隨之更改。

聰明的你可能想到,如果 tokenURI 是一個 http 連接,即 metadata 是存放在傳統伺服器中,則非常容易做到這個效果。只要修改伺服器程式,返回完全不同的 metadata 即可。沒錯,但如果 tokenURI 是一條 IPFS 連結,那要如何處理? IPFS 不是不可更改嗎? 哈哈,是的 IPFS 連結是不能更改,但是 tokenURI 可以呀。只要對智能合約的代碼做一點更改,便可以輕鬆做到效果。

我們的大概思路是,有一個開關參數控制盲盒開啟與否,如果 true,則 tokenURI 將返回一條盲盒專用的 metadata IPFS 連結,裡面的 name,image 等都是固定的名稱和圖像。另外我們還需要有兩個 function ,供授權的地址調用,一個用以改變上述開關參數的狀態,另一個用以設定盲盒開啟後新的 baseURI。等到開啟盲盒的神聖日子來臨,被授權的地址調用這兩個 function,即可揭開盲盒的神秘面紗。

(當然,聰明的你也應該想到,不使用開關參數,完全依靠更改baseURI 也是可以的。只是我覺得有個開關更容易操作一些)

以下是參考的代碼:

1abstract contract BaseERC721BlindBox is BaseERC721 {
2 using Strings for uint256;
3 bool private _blindBoxOpened = false;
4 string private _blindTokenURI =
5 "ipfs://QmexqcLDvoP6HCTtSGumG3yzhZdH8guvV3z3kReCvf2QKn";
7 function _isBlindBoxOpened() internal view returns (bool) {
8 return _blindBoxOpened;
11 function setBlindBoxOpened(bool _status) public {
12 require(
13 hasRole(DEFAULT_ADMIN_ROLE, _msgSender()),
14 "BaseERC721BlindBox: only admin can do this action"
16 _blindBoxOpened = _status;
19 // this function controls how the token URI is constructed
20 function tokenURI(uint256 tokenId)
21 public
22 view
23 virtual
24 override
25 returns (string memory)
27 require(
28 _exists(tokenId),
29 "ERC721Metadata: URI query for nonexistent token"
32 if (_blindBoxOpened) {
33 string memory baseURI = _baseURI();
34 return
35 bytes(baseURI).length > 0
36 ? string(
37 abi.encodePacked(baseURI, tokenId.toString(), ".json")
39 : "";
40 } else {
41 return _blindTokenURI;

當盲盒沒有開啟時,進入 OpenSea 看到的會是這樣

screen 20211010183332 2x

當盲盒開啟後,進入 OpenSea 看到的會是這樣

screen 20211010184258 2x
技術交流,其他諮詢等,請按此聯絡

訂閱我的網站,接收更新以及其他有趣的消息 ? 。 訂閱不收費,走過路過別錯過。
Subscribe to my website, I will email you if any new posts or interesting stuff available.

如果你喜歡我的內容,請考慮用一杯咖啡支持我一下吧,非常感謝 ? 。
If you like my contents, please support me via BuyMeCoffee, Thanks a lot.

其它相關文章


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK