主页 > imtoken在新手机上登录 > 硅谷以太坊区块链学习之NFT智能合约(六)
硅谷以太坊区块链学习之NFT智能合约(六)
硅谷以太坊区块链学习之NFT智能合约(六)前言
提示:服务外包区块链学习
5被ban了,不知道怎么改才能pass以太坊有哪两种账户类型,没关系,以后可以看看,不知道这篇文章能不能过审
说明:从这篇博客来看,我写区块链的时候没有用Ubuntu,而是用Windows,因为需要链接前面写的NFT系统的后台以太坊有哪两种账户类型,而后台在Windows主机上,即使端口映射用VMware设置,宿主机的MataMask还是连接不上虚拟机,所以切换到Windows感觉一样,甚至Windows更简单。
仅记录操作
上硅谷以太坊区块链直连
一、NFT智能合约 1、智能合约代码
直接上代码,需要详细了解的可以自行百度,因为我不是很懂
反正原理是NFT的详细实体是不能上传到区块链上的,完全上传会消耗太多的gas。
因此实体只能保存在系统后台,将NFT文件URI上传到区块链,形成NFT
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract NFTMarket is ERC721, ERC721Enumerable, ERC721URIStorage {
using Strings for uint256;
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
address private owner;
mapping (uint256 => string) private _tokenURIs;
string private _baseURIextended;
constructor () ERC721("NFTMarket", "NFTMKT") {
owner = msg.sender;
//currToken = IERC20(_currTokenAddress);
}
function setBaseURI(string memory baseURI_) external {
_baseURIextended = baseURI_;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual
override(ERC721URIStorage){
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function tokenURI(uint256 tokenId) public view virtual override(ERC721, ERC721URIStorage) returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
if (bytes(base).length == 0) {
return _tokenURI;
}
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return string(abi.encodePacked(base, tokenId.toString()));
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
return super.supportsInterface(interfaceId);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function burnNFT(uint256 tokenId) public returns (uint256) {
require(msg.sender == ownerOf(tokenId),"Only the owner of this Token could Burn It!");
_burn(tokenId);
return tokenId;
}
function mintNFT(address _to,string memory tokenURI_) public returns (uint256){
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(_to, newItemId);
_setTokenURI(newItemId, tokenURI_);
return newItemId;
}
function transNFT(address _from,address _to,uint256 tokenId) public returns (uint256) {
require(msg.sender == ownerOf(tokenId),"Only the owner of this Token could transfer It!");
transferFrom(_from,_to,tokenId);
return tokenId;
}
function destroy() virtual public {
require(msg.sender == owner,"Only the owner of this Contract could destroy It!");
selfdestruct(payable(owner));
}
}
2. 智能合约推送
因为使用了其他合约中的方法,所以必须选择具体要推送的合约
最好用一个文档记住每个成功推送的合约的地址和使用的命令,方便后续使用
3.具体调用
简单说说一些方法的使用:
mintNFT(铸造的 NFT)
burnNFT(销毁NFT)
safeTransferFrom(发送NFT到指定账户)
transNFT(交易NFT)
balanceOf(查看指定用户有多少个 NFT)
ownerOf(检查指定tokenId的所有者)
tokenByIndex(查看指定索引的NFT)
tokenOfOwner(查看指定地址指定索引的NFT)
totalSupply(查看NFT总数)
2、具体用途
新建两个账号,然后使用MataMask导入账号
矿业!
成功!
看看你有多少 NFT
无需提交交易即可调用call方法,无需挖矿
NFT 总数
我刚刚铸造的NFT在我的账户中是第二个,所以它的索引是1(从0公顷开始)
这时候返回的是NFT的tokenId。 有了tokenId,可以查看NFT的tokenURI
使用结束!
3. NFT商户智能合约
NFT 商户智能合约代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.1;
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract NFTStore is Context, ERC20 {
address private owner;
struct Mints {
address minter;
uint256 amount;
}
mapping(uint256 => Mints) public tokenToMint;
mapping(uint256 => uint256) private tokenAmounts;
/**
* @dev Constructor that gives _msgSender() all of existing tokens.
*/
constructor (uint256 tokenNum) ERC20("NFTStore", "NFC") {
owner = msg.sender;
_mint(_msgSender(), tokenNum * (10 ** uint256(decimals())));
}
function mint(address _to,uint256 amount,uint256 tokenId) public {
require(msg.sender == owner,"Only the owner of this Contract could mint!"); // 本文添加,否则函数 mint 会有逻辑错误
_mint( _to, amount) ; // 如果没有添加上一句 require,此处会有逻辑错误,任何人都可以免费获得NFC
tokenAmounts[tokenId] = amount;
Mints memory mintted = Mints({
minter: _to,
amount: amount
});
tokenToMint[tokenId]=mintted;
}
function getTokenAmount (uint256 tokenId) public view returns (uint256) {
return tokenAmounts[tokenId];
}
function gettokenMints(uint256 tokenId) public view returns ( address, uint256){
Mints memory mintted = tokenToMint[tokenId];
return (mintted.minter,mintted.amount);
}
function destroy() virtual public {
require(msg.sender == owner,"Only the owner of this Contract could destroy It!");
selfdestruct(payable(owner));
}
}
这个我还没怎么用过,有兴趣的朋友可以自己试试。
明天写Java的区块链框架Web3j的使用
超过