文章目录

好几个月没有更新了相关内容了,之前跟炜哥聊到合约实现各种功能的时候,还催我把 《怎样写出Axie Infinity的合约(一)》 这个系列更完,但是真的是没时间。不过之前也正好聊到盲盒相关的问题了,可能关于上链后更改状态不熟悉区块链的朋友会有疑问,但其实实现起来挺简单的,趁这个机会也更个文章吧。

目前能想到的有两种实现方式,一种比较灵活:直接修改tokenURI,即暴露一个方法给授权地址,在需要的时候可以修改tokenURI;一种比较简洁:设置一个变量作为开关,被授权的地址调用方法来切换不同的tokenURI。

那么有没有既灵活又简洁的方法呢?把两种方式加起来就好了(对不起,抖了个机灵)……即开启盲盒的时候,既改变开关变量(这个是为了在其他相关逻辑中方便的获取到开启状态),同时也要设置tokenURI。

上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// contracts/test.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

contract MyToken is ERC721, ERC721URIStorage, Ownable {
constructor() ERC721("MyToken", "MTK") {}

string private _tokenURIPrefix = "https://some.storage.online/opened/";
string private _tokenURISuffix = ".json";
bool private _mysteryBoxOpened = false;
string private _mysteryTokenURI = "https://some.storage.online/mystery/token.png";

function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}

function isMysteryBoxOpened() public view returns (bool) {
return _mysteryBoxOpened;
}

function setMysteryBoxStatus(bool _status, string memory _baseUrl) external onlyOwner {
_mysteryBoxOpened= _status;
//如果_baseUrl传入空字符串'',则不会改变原有的路径前缀
if(bytes(_baseUrl).length > 0) _tokenURIPrefix = _baseUrl;
}

function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
if (_mysteryBoxOpened) {
return
string(
//最近查阅到有abi.encodePacked的方法可以用,非常方便
//以前参考使用axie的代码,组装起来很复杂
abi.encodePacked(_tokenURIPrefix, Strings.toString(tokenId), _tokenURISuffix)
);
} else {
return _mysteryTokenURI;
}
}
}

就酱紫。

♦ 本文固定连接:http://gsgundam.com/2022-03-08-contract-for-mystery-box-how-to/

♦ 转载请注明:GSGundam 2022年03月08日发布于 GSGUNDAM砍柴工

♦ 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

♦ 原创不易,如果页面上有适合你的广告,不妨点击一下看看,支持作者。(广告来源:Google Adsense)