尚硅谷以太坊区块链学习之NFT智能合约(6)


前言

提示:服务外包区块链学习

5被ban了,也不知道怎么改能过,无所谓了,我以后能看的见就行,不知道这篇能不能过审

说明:从这篇博客开始就不用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总数)

二、具体使用

新建两个账号,再用MataMask导入账号

在这里插入图片描述
挖矿!

在这里插入图片描述
成功!

看自己有几个NFT了
在这里插入图片描述

call方法都是不用提交交易就可以调用的,所以不需要挖矿

NFT总数
在这里插入图片描述
刚刚铸造的NFT在我的账号里是第二个,所以它的索引是1(从0开始哈)

在这里插入图片描述
这个时候返回的就是这个NFT的tokenId了,有了tokenId既可以看这个NFT的tokenURI了

在这里插入图片描述

使用结束!

三、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的使用

Over

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>