当前位置:网站首页>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开发中的合约部分已经完成。
边栏推荐
- Scala language learning-08-abstract classes
- 1015 reversible primes (20 points) prime d-ary
- The Vice Minister of the Ministry of industry and information technology of "APEC industry +" of the national economic and information technology center led a team to Sichuan to investigate the operat
- C intercept string
- 07- [istio] istio destinationrule (purpose rule)
- File upload of DVWA range
- ROS learning (IX): referencing custom message types in header files
- Rust language - receive command line parameter instances
- 链表面试题(图文详解)
- MFC 给列表控件发送左键单击、双击、以及右键单击消息
猜你喜欢
Sharing of source code anti disclosure scheme under burning scenario
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
08- [istio] istio gateway, virtual service and the relationship between them
数字经济时代,如何保障安全?
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
继电反馈PID控制器参数自整定
The Vice Minister of the Ministry of industry and information technology of "APEC industry +" of the national economic and information technology center led a team to Sichuan to investigate the operat
[untitled]
Machine learning - decision tree
Qualitative risk analysis of Oracle project management system
随机推荐
Leecode-c language implementation -15 Sum of three ----- ideas to be improved
[cf gym101196-i] waif until dark network maximum flow
Yu Xia looks at win system kernel -- message mechanism
Games101 Lesson 7 shading 1 Notes
In the era of digital economy, how to ensure security?
[Yugong series] February 2022 U3D full stack class 011 unity section 1 mind map
Oracle time display adjustment
Database addition, deletion, modification and query
Ali's redis interview question is too difficult, isn't it? I was pressed on the ground and rubbed
Common functions for PHP to process strings
数据治理:微服务架构下的数据治理
WebRTC系列-H.264预估码率计算
A Closer Look at How Fine-tuning Changes BERT
Position() function in XPath uses
Iterator Foundation
洛谷P1836 数页码 题解
Simulation of Michelson interferometer based on MATLAB
"Designer universe" Guangdong responds to the opinions of the national development and Reform Commission. Primary school students incarnate as small community designers | national economic and Informa
Data governance: data quality
21. Delete data