主页 > imtoken在新手机上登录 > 硅谷以太坊区块链学习之NFT智能合约(六)

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

imtoken在新手机上登录 2023-04-29 07:00:28

硅谷以太坊区块链学习之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);
	}

sitehqz.com 以太坊和以太坊贸易的关系_sitebihu.com 以太坊账户体系_以太坊有哪两种账户类型

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) {

sitebihu.com 以太坊账户体系_以太坊有哪两种账户类型_sitehqz.com 以太坊和以太坊贸易的关系

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;

sitehqz.com 以太坊和以太坊贸易的关系_以太坊有哪两种账户类型_sitebihu.com 以太坊账户体系

} 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

sitebihu.com 以太坊账户体系_以太坊有哪两种账户类型_sitehqz.com 以太坊和以太坊贸易的关系

在这里插入图片描述

无需提交交易即可调用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") {

sitebihu.com 以太坊账户体系_以太坊有哪两种账户类型_sitehqz.com 以太坊和以太坊贸易的关系

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

超过