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


    尚硅谷以太坊区块链学习之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));
        }
    }
    
    • 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
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    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));
        }
    }
    
    • 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

    这个我还没怎么使用过,有兴趣的小伙伴可以自己进行尝试。
    明天写Java的区块链框架Web3j的使用

    Over

  • 相关阅读:
    IronPDF for .NET 2023.9.8 Crack
    9、Nacos服务注册服务端源码分析(总结篇)
    基于STM32的OLED多级菜单GUI实现(简化版智能手表)
    Linux之安全最佳做法(未完成)
    C++标准模板(STL)- 类型支持 (类型特性,is_union,is_class,is_function)
    【Sklearn学习】Sklearn的数据集介绍
    Android Toast居中显示方法二
    [element] el-menu 收起展开的子菜单
    数学建模——图与网络模型及方法(一)
    ArcGIS实验教程——实验四十八:ArcGIS制图表达入门及案例教程
  • 原文地址:https://blog.csdn.net/m0_54849806/article/details/125402145