当前位置:网站首页>Nft智能合约发行,盲盒,公开发售技术实战--合约篇
Nft智能合约发行,盲盒,公开发售技术实战--合约篇
2022-07-06 07:53:00 【NFT践行者】
这篇文章主要是从技术视角来给大家介绍一下nft主流的玩法-发行,盲盒,公开发售等流程步骤,这也是目前市场上大部分项目的玩法。
本次文章nft开发主要分为两部分: 1. 合约部分 2. 拼图部分。
本次Nft开发系列我也准备分为两篇文章进行讲解,今天主要讲解合约部分。
合约部分主要是以下功能:
建立和eth测试网互动的智能合约
Nft要能够被mint
Nft能够设定总量
Nft设定每个地址最大持有量
Nft要能够限定单次的mint的量
Nft要能够设定开关去公开发售
拼图部分主要是以下功能:
如何快速制作多种拼图以及meta资料
如何上传ipfs星际网络系统(测试网)
以上就是本次文章需要讲解的技术点。
开发之前,你需要准备好以下工具和环境。
metamask钱包插件
remix在线编译环境
具体钱包的安装以及remix的使用,就不再这边讲解。
合约部分
首先将本次合约部分的源码直接粘贴在remix中进行编译。源码如下:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
contract NftMeta is ERC721Enumerable, Ownable {
using Strings for uint256;
// 是否准许nft开卖-开关
bool public _isSaleActive = false;
// 初始化盲盒,等到一定时机可以随机开箱,变成true
bool public _revealed = false;
// nft的总数量
uint256 public constant MAX_SUPPLY = 10;
// 铸造Nft的价格
uint256 public mintPrice = 0.3 ether;
// 铸造的钱包最多只能有一个nft数量
uint256 public maxBalance = 1;
// 一次mint的nft的数量
uint256 public maxMint = 1;
// 盲盒开关打开后,需要显示开箱的图片的base地址
string baseURI;
// 盲盒图片的meta,json地址,后文会提到
string public notRevealedUri;
// 默认地址的扩展类型
string public baseExtension = ".json";
mapping(uint256 => string) private _tokenURIs;
// 构造器
constructor(string memory initBaseURI, string memory initNotRevealedUri)
ERC721("Nft Meta", "NM") // 实现了ERC721的父类构造器,是子类继承的一种实现方式
{
setBaseURI(initBaseURI);
setNotRevealedURI(initNotRevealedUri);
}
// 外部地址进行铸造nft的函数调用
function mintNftMeta(uint256 tokenQuantity) public payable {
// 校验总供应量+每次铸造的数量<= nft的总数量
require(
totalSupply() + tokenQuantity <= MAX_SUPPLY,
"Sale would exceed max supply"
);
// 校验是否开启开卖状态
require(_isSaleActive, "Sale must be active to mint NicMetas");
// 校验铸造的钱包地址中的nft的数量 + 本次铸造的数量 <= 该钱包最大拥有的nft的数量
require(
balanceOf(msg.sender) + tokenQuantity <= maxBalance,
"Sale would exceed max balance"
);
// 校验本次铸造的数量*铸造的价格 <= 本次消息附带的eth的数量
require(
tokenQuantity * mintPrice <= msg.value,
"Not enough ether sent"
);
// 校验本次铸造的数量 <= 本次铸造的最大数量
require(tokenQuantity <= maxMint, "Can only mint 1 tokens at a time");
// 以上校验条件满足,进行nft的铸造
_mintNftMeta(tokenQuantity);
}
// 进行铸造
function _mintNftMeta(uint256 tokenQuantity) internal {
for (uint256 i = 0; i < tokenQuantity; i++) {
// mintIndex是铸造nft的序号,按照总供应量从0开始累加
uint256 mintIndex = totalSupply();
if (totalSupply() < MAX_SUPPLY) {
// 调用erc721的安全铸造方法进行调用
_safeMint(msg.sender, mintIndex);
}
}
}
// 返回每个nft地址的Uri,这里包含了nft的整个信息,包括名字,描述,属性等
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
// 盲盒还没开启,那么默认是一张黑色背景图片或者其他图片
if (_revealed == false) {
return notRevealedUri;
}
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return
string(abi.encodePacked(base, tokenId.toString(), baseExtension));
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
//only owner
function flipSaleActive() public onlyOwner {
_isSaleActive = !_isSaleActive;
}
function flipReveal() public onlyOwner {
_revealed = !_revealed;
}
function setMintPrice(uint256 _mintPrice) public onlyOwner {
mintPrice = _mintPrice;
}
function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
notRevealedUri = _notRevealedURI;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension)
public
onlyOwner
{
baseExtension = _newBaseExtension;
}
function setMaxBalance(uint256 _maxBalance) public onlyOwner {
maxBalance = _maxBalance;
}
function setMaxMint(uint256 _maxMint) public onlyOwner {
maxMint = _maxMint;
}
function withdraw(address to) public onlyOwner {
uint256 balance = address(this).balance;
payable(to).transfer(balance);
}
}
以上就是合约源码。
对erc721的扩展部分和权限部分进行引用,同时进行继承,重写erc721的部分方法,下文会提到。
这些状态变量主要是用来对Nft的一些属性进行设置,包括总量,每个地址最多mint的数量等。
上面是铸造方法的实现,先进行铸造前的条件校验,然后调用erc721的_safemint安全方法进行铸造。
将合约代码进行部署,其中有几个注意的点
同时将测试网络切到Rinkeby测试网,同时需要提前通过faucet进行测试币的领取。领取地址:
Faucets | ChainlinkGet testnet LINK for an account on one of the supported blockchain testnets so you can create and test your own oracle and Chainlinked smart contract.https://faucets.chain.link/FaucETHhttps://fauceth.komputing.org/
Rinkeby: Authenticated Faucethttps://faucet.rinkeby.io/部署完成之后,会出现
在我们mint之前,需要进行开启铸造开关(红色框内),点击将状态变量变成true.
红色函数是铸造方法,填入数量1,同时因为我们在合约的状态变量设置了最小Mint的价格是0.3ether,因此我们需要在msg.value中附带ether数量从而完成mint。
因为红色框中是不允许输入小数的,因此,通过ether网站进行费用单位转换
Ethereum Unit Converter | Ether to Gwei, Wei, Finney, Szabo, Shannon etc.https://eth-converter.com/
将0.3ether输入,从而得到Gwei的数量,将该数量赋值到以上红框中进行mint。成功之后,就会在ipfs测试网看到一张编号为0的图片。ipfs测试网地址:
至此,我们nft开发中的合约部分已经完成。
边栏推荐
- 好用的TCP-UDP_debug工具下载和使用
- 2.10transfrom attribute
- Simulation of holographic interferogram and phase reconstruction of Fourier transform based on MATLAB
- C # display the list control, select the file to obtain the file path and filter the file extension, and RichTextBox displays the data
- Oracle time display adjustment
- Linked list interview questions (Graphic explanation)
- Artcube information of "designer universe": Guangzhou implements the community designer system to achieve "great improvement" of urban quality | national economic and Information Center
- 上线APS系统,破除物料采购计划与生产实际脱钩的难题
- MES, APS and ERP are essential to realize fine production
- Apache middleware vulnerability recurrence
猜你喜欢
DataX self check error /datax/plugin/reader/_ drdsreader/plugin. Json] does not exist
Go learning notes (3) basic types and statements (2)
Leetcode question brushing record | 203_ Remove linked list elements
Sanzi chess (C language)
Secure captcha (unsafe verification code) of DVWA range
07- [istio] istio destinationrule (purpose rule)
Inspiration from the recruitment of bioinformatics analysts in the Department of laboratory medicine, Zhujiang Hospital, Southern Medical University
解决方案:智慧工地智能巡檢方案視頻監控系統
leecode-C語言實現-15. 三數之和------思路待改進版
Esrally domestic installation and use pit avoidance Guide - the latest in the whole network
随机推荐
08- [istio] istio gateway, virtual service and the relationship between them
Basics of reptile - Scratch reptile
22. Empty the table
Rust language - receive command line parameter instances
Go learning notes (3) basic types and statements (2)
Simulation of Teman green interferometer based on MATLAB
珠海金山面试复盘
Comparison of usage scenarios and implementations of extensions, equal, and like in TS type Gymnastics
onie支持pice硬盘
Risk planning and identification of Oracle project management system
Binary tree creation & traversal
DataX self check error /datax/plugin/reader/_ drdsreader/plugin. Json] does not exist
【T31ZL智能视频应用处理器资料】
合规、高效,加快药企数字化转型,全新打造药企文档资源中心
[1. Delphi foundation] 1 Introduction to Delphi Programming
A Closer Look at How Fine-tuning Changes BERT
23. Update data
WebRTC系列-H.264预估码率计算
Google可能在春节后回归中国市场。
Mise en œuvre du langage leecode - C - 15. Somme des trois chiffres - - - - - idées à améliorer