币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】

  • A+
所属分类:NFT
摘要

NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法


chatGPT账号

一、说明

目前直接在支持BSC链的NFT平台上发行NFT作品是最为简单的方法,但是该处理方法存在一个问题,即发行的NFT作品无法在tp钱包显示图片,导致在tp钱包展示NFT 集合时比较混乱,无法正常显示NFT。

nft2022113003

出现该问题的原因,主要是NFT图片的存储形式导致的。无论是nft图片存储到铸造平台的去中心化链上还是存储到ipfs等主流公链上都会存在链上数据与tp钱包之间的数据通信问题。主要考虑是NFT图片数据的访问链路或者接口与钱包直接的数据互信问题,导致无法在TP钱包展示NFT图片。如果此时可以正常在metamask等钱包展示NFT图片,但是无法在TP显示图片,进一步印证了该问题。

二、处理方案

解决该问题的处理方案,只能是脱离现有的NFT铸造平台,通过自部署NFT合约,设置NFT图片的存储方式以允许TP钱包访问,然后通过接口直接铸造NFT作品。

带有tokenURI的NFT合约源代码如下:
1、IERC721接口文件如下:

pragma solidity ^0.5.5;

import "./ITRC165.sol";

/**
 * @dev Required interface of an TRC721 compliant contract.
 */
contract ITRC721 is ITRC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of NFTs in `owner`'s account.
     */
    function balanceOf(address owner) public view returns (uint256 balance);

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApprovalForAll}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApprovalForAll}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

2、ITRC721Metadata 元数据接口合约源代码如下:

pragma solidity ^0.5.5;

import "./ITRC721.sol";

/**
 * @title TRC-721 Non-Fungible Token Standard, optional metadata extension
 */
contract ITRC721Metadata is ITRC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

3、TRC721Metadata 元数据实现类合约源代码如下

pragma solidity ^0.5.5;

import "./Counters.sol";
import "./TRC165.sol";
import "./TRC721.sol";
import "./ITRC721Metadata.sol";

contract TRC721Metadata is Context, TRC165, TRC721, ITRC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Base URI
    string private _baseURI;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_TRC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to TRC721 via TRC165
        _registerInterface(_INTERFACE_ID_TRC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the URI for a given token ID. May return an empty string.
     *
     * If the token's URI is non-empty and a base URI was set (via
     * {_setBaseURI}), it will be added to the token ID's URI as a prefix.
     *
     * Reverts if the token ID does not exist.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "TRC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];

        // Even if there is a base URI, it is only appended to non-empty token-specific URIs
        if (bytes(_tokenURI).length == 0) {
            return "";
        } else {
            // abi.encodePacked is being used to concatenate strings
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     *
     * Reverts if the token ID does not exist.
     *
     * TIP: if all token IDs share a prefix (e.g. if your URIs look like
     * `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
     * it and save gas.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "TRC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI}.
     *
     * _Available since v2.5.0._
     */
    function _setBaseURI(string memory baseURI) internal {
        _baseURI = baseURI;
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a preffix in {tokenURI} to each token's URI, when
    * they are non-empty.
    *
    * _Available since v2.5.0._
    */
    function baseURI() external view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

4、MinterRole NFT铸造者权限角色实现类合约源代码

pragma solidity ^0.5.5;

import "./Context.sol";
import "./Roles.sol";

contract MinterRole is Context {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private _minters;

    constructor () internal {
        _addMinter(_msgSender());
    }

    modifier onlyMinter() {
        require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role");
        _;
    }

    function isMinter(address account) public view returns (bool) {
        return _minters.has(account);
    }

    function addMinter(address account) public onlyMinter {
        _addMinter(account);
    }

    function renounceMinter() public {
        _removeMinter(_msgSender());
    }

    function _addMinter(address account) internal {
        _minters.add(account);
        emit MinterAdded(account);
    }

    function _removeMinter(address account) internal {
        _minters.remove(account);
        emit MinterRemoved(account);
    }
}

5、NFT主合约核心代码如下:

pragma solidity ^0.5.5;

import "./TRC721.sol";
import "./TRC721Enumerable.sol";
import "./TRC721MetadataMintable.sol";

contract NFT is TRC721, TRC721Enumerable, TRC721MetadataMintable {
    constructor() public TRC721Metadata("NFT", "NFT") {

    }
}

test

通过自部署合约铸造NFT作品,即可将NFT图片存储到指定数据对象路径,即可解决TP无法显示NFT图片问题。

至此,完成NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法。

pdf+视频(BSC币安链+TRX波场链)NFT发行教程及合约源代码下载:

币安智能链BSC+波场链TRX NFT发行(合约部署、开源、参数配置、开发、故障处理、工具使用)教程下载:

币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】

币安智能链BSC+波场链TRX NFT发行合约源代码下载

币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】

pdf+视频(BSC币安链+TRX波场链)NFT发行教程及合约源代码下载地址:

此处为隐藏的内容!
登录后才能查看!

添加VX或者telegram获取全程线上免费指导

币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】
免责声明

免责声明:

本文不代表知点网立场,且不构成投资建议,请谨慎对待。用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点网不对网站所发布内容的准确性,真实性等任何方面做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网对项目的真实性,准确性等任何方面均不做任何形式的承诺和保障;

网站内所有涉及到的区块链(衍生)项目,知点网不对其构成任何投资建议,用户由此造成的损失由用户自行承担,与知点网没有任何关系;

知点区块链研究院声明:知点区块链研究院内容由知点网发布,部分来源于互联网和行业分析师投稿收录,内容为知点区块链研究院加盟专职分析师独立观点,不代表知点网立场。

本文是全系列中第5 / 17篇:NFT发行

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的电报
  • 这是我的电报扫一扫
  • weinxin
chatGPT账号

发表评论

您必须登录才能发表评论!