繁体   English   中英

有没有办法在 ERC-721 上的 Solidity 上检索 JSON?

[英]Is there a way to retrieve JSON on Solidity on ERC-721?

我正在练习 ERC_721 合同,想知道是否有办法将 JSON 数据直接存储在合同上,看看我的方法并给出你的想法:

上传到 IPFS 的variation1.json文件:

{
    "attributes": [
      {
        "trait_type": "Rank",
        "value": "1"
      }
    ],
    "description": "A simple NFT",
    "image": "Qmdasifhw89rv92enfkq128re3",
    "name": "NFT#1"
}

然后我会使用一个像下面这样的object来与将file引用到urlOfTokenURI的合同一起使用

[
  {
    "file": "variation1.json", "urlOfTokenURI": https://gateway.pinata.cloud/ipfs/Qmdasifhw89rv92enfkqeqe23f"
  },
  {
    "file": "variation2.json", "urlOfTokenURI": "https://gateway.pinata.cloud/ipfs/Qmgvfrg34vt4u785ygbmasdsa"
  },
  ...
]

然后获取一个随机数,检索一个随机urlOfTokenURI并将令牌铸造到所需的地址,从可用令牌列表中排除该令牌:

function mintNFT(address recipient, string memory tokenURI)
    public onlyOwner
    returns (uint256)
{
    _tokenIds.increment();
    //retrieve object, get random number and mint with the urlOfTokenURI
    //from random number index
    uint256 newItemId = _tokenIds.current();
    _mint(recipient, newItemId);
    _setTokenURI(newItemId, tokenURI);

    return newItemId;
}

这个工作缺少什么?

有人可以指导我如何进行或对另一种方法有建议吗? 我有点迷路了。

不明白如何铸造一个随机的 NFT 并立即将其展示给用户。

如果这是一个愚蠢的问题,请提前道歉。 我正在学习,顺便说一句。

感谢帮助!

  1. 如果你需要一个真正的随机数fn,你需要寻找oracle服务(例如Chainlink)
  2. 是的,可以在不发布到 IPFS 的情况下生成 uri。 您可以改为生成 base64 数据 uri。 查看巫师和龙游戏及其合同的示例
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/Strings.sol";
...
    using Strings for uint256;
    using Base64 for bytes;
...
    function tokenURI(uint256 id) public view returns (string memory) {

        string memory metadata = string(abi.encodePacked(
            "{\"name\": \"NFT#",
            id.toString(),
            "\", \"description\": \"A simple NFT\", \"attributes\":",
            "[{\"key\":\"trait_type\",\"value\":\"1\"}]",
            "}"
        ));

        return string(abi.encodePacked(
            "data:application/json;base64,",
            bytes(metadata).base64()
        ));
    }

Base64 库

pragma solidity ^0.8.0;

library Base64 {

    string internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    function base64(bytes memory data) internal pure returns (string memory) {
        if (data.length == 0) return "";
        
        // load the table into memory
        string memory table = TABLE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)
            
            // prepare the lookup table
            let tablePtr := add(table, 1)
            
            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))
            
            // result ptr, jump over length
            let resultPtr := add(result, 32)
            
            // run over the input, 3 bytes at a time
            for {} lt(dataPtr, endPtr) {}
            {
                dataPtr := add(dataPtr, 3)
                
                // read 3 bytes
                let input := mload(dataPtr)
                
                // write 4 characters
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(shr( 6, input), 0x3F)))))
                resultPtr := add(resultPtr, 1)
                mstore(resultPtr, shl(248, mload(add(tablePtr, and(        input,  0x3F)))))
                resultPtr := add(resultPtr, 1)
            }
            
            // padding with '='
            switch mod(mload(data), 3)
            case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) }
            case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) }
        }
        
        return result;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM