debugging DynamicSvgNft合约的问题:getHighSVG()和getLowSVG()函数返回错误值

wsxa1bj1  于 2023-08-06  发布在  其他
关注(0)|答案(1)|浏览(82)

Stack Overflow社区!
我目前正在做一个项目,涉及一个名为DynamicSvgNft的NFT合同。该合约旨在根据Chainlink的价格提要更改NFT的SVG图像URI。然而,我面临着一个问题,即getHighSVG()getLowSVG()函数返回的值是混淆的。
以下是合同的相关代码:
// DynamicSvgNft.sol

contract DynamicSvgNft is ERC721, Ownable {
 uint256 private s_tokenCounter;
 string private s_lowImageURI;
 string private s_highImageURI;
 AggregatorV3Interface internal immutable i_priceFeed;

 mapping (uint256 => int256) private s_tokenToHighValue;

 event CreatedNft(uint256 indexed tokenId, int256 highValue);

 constructor(address priceFeedAddress, string memory lowSvg, string memory highSvg) ERC721("Dynamic SVG NFT", "DSN") {
     s_tokenCounter = 0;
     i_priceFeed = AggregatorV3Interface(priceFeedAddress);
     s_lowImageURI = svgToImageUri(lowSvg);
     s_highImageURI = svgToImageUri(highSvg);

 }

 // functionalities
 
 function mintNft(int256 highValue) public {
     _safeMint(msg.sender, s_tokenCounter);
     s_tokenToHighValue[s_tokenCounter] = highValue;
      s_tokenCounter = s_tokenCounter + 1;
     emit CreatedNft(s_tokenCounter, highValue);
 }

 function svgToImageUri(string memory svg) public pure returns (string memory) {
     // convert the svgs to image uris and store them in variables for later use
     string memory baseURL = "data:image/svg+xml;base64,";
     string memory svgBase64Encoded = Base64.encode(bytes(string(abi.encodePacked(svg))));
     return string(abi.encodePacked(baseURL, svgBase64Encoded));
 }

 function _baseURI() internal pure override returns (string memory) {
     return "data:application/json;base64,";
 }

 function tokenURI(uint256 tokenId) public view override returns (string memory) {
     if(!_exists(tokenId)) {
         revert ERC721Metadata__URI_QueryFor_NonExistentToken();
     } 

     (, int256 price, , , ) = i_priceFeed.latestRoundData();

     string memory imageURI;
     if (price >= s_tokenToHighValue[tokenId]) {
           imageURI = s_highImageURI;
     } else {
          imageURI = s_lowImageURI;
     }
     return
         string(
         abi.encodePacked(
             _baseURI(),
             Base64.encode(
                 bytes(
                     abi.encodePacked(
                         '{"name":"',
                         name(),
                         '", "description":"An NFT that changes based on the chainlink feed",',
                         '"attributes": [{"trait_type": "coolness", "value": 100}], "image":"',
                         imageURI,
                         '"}'
                     )
                 )
             )
         )
         );
 }
 function getLowSVG()  public view returns (string memory) {
     return s_lowImageURI;
 }
   function getHighSVG()  public view returns (string memory) {
     return s_highImageURI;
 }
 function getTokenCounter() public view returns (uint256 ) {
     return s_tokenCounter;
 }
 function getPriceFeed() public view returns (AggregatorV3Interface) {
     return i_priceFeed;
 }
}

字符串
下面是观察到问题的测试代码:
//DynamicSvgNft.test.js

const highSVGImageUri = "data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgd2lkdGg9IjQwMCIgIGhlaWdodD0iNDAwIiB4bWxucz0";
    const lowSVGImageUri = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/...";

describe("Constructor", () => {
    it("sets the initial values correctly", async () => {
        const highSVG = await dynamicSvgNft.getHighSVG(); // Returns lowSVGImageUri instead of the highSVGImageUri
        const lowSVG = await dynamicSvgNft.getLowSVG();   // Returns the highSVGImageUri instead of the lowSVGImageUri
          // ... (assertions)
           console.log(`highSVG is => ${highSVG}`)
            assert.equal(highSVG, highSVGImageUri)
            console.log(`lowSVG is => ${lowSVG}`)
            assert.equal(lowSVG, lowSVGImageUri)
            assert.equal(tokenCounter.toString(), "0")
            assert.equal(priceFeed, MockV3Aggregator.address)
    });
});

// ... (other test code)


DynamicSvgNft.deploy.js

const { network } = require("hardhat");
    const { developmentChains, networkConfig } = require("../helper-hardhat-config");
    const { verify } = require("../utils/verify");
    const fs = require("fs")
    
    module.exports = async ({getNamedAccounts, deployments}) => {
        const {deploy, log} = deployments
        const {deployer} = await  getNamedAccounts()
    
        const chainId = network.config.chainId
        let ethUsdPriceFeedAddress
    
        if(developmentChains.includes(network.name)) {
            const EthUsdAggregator = await deployments.get("MockV3Aggregator")
            ethUsdPriceFeedAddress  = EthUsdAggregator.address
        } else {
            ethUsdPriceFeedAddress = networkConfig[chainId].ethUsdPriceFeed
        }
    
        log("#####################################");
    
        // read the nft images
        const lowSVG =  fs.readFileSync("images/dynamicNft/frown.svg", {encoding: "utf8"})
        const highSVG =  fs.readFileSync("images/dynamicNft/happy.svg", {encoding: "utf8"})
        args = [ethUsdPriceFeedAddress, highSVG, lowSVG]
    
        const dynamicSvgNft = await deploy("DynamicSvgNft", {
            from: deployer,
            args:args,
            log: true,
            waitConfirmations: network.config.blockConfirmations || 1
        })
    
        if(!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
            log("verifying.....")
            await verify(dynamicSvgNft.address, args)
            log("verified!")
    
            log("#########################################")
        }
    
    }
    module.exports.tags = ["all", "dynamicsvg", "main"]


问题是getHighSVG()函数返回s_lowImageURI的值,反之亦然,导致在测试期间返回不正确的值
我已经彻底检查了合同和测试代码,但我无法确定问题的根本原因。我怀疑合约部署或合约中使用的svgToImageUri函数可能存在问题。
任何关于如何调试和修复此问题的见解或建议都将受到高度赞赏!如果需要,我还可以提供合同和测试文件的完整代码。
提前感谢您的帮助!

6kkfgxo0

6kkfgxo01#

我遇到了一个DynamicSvgNft合约的问题,其中getHighSVG()getLowSVG()函数返回了不正确的图像URI。该合约旨在根据Chainlink oracle中的price feed值设置不同的SVG图像。
经过调查,我发现问题出在部署过程中向契约构造函数传递参数的方式上。构造函数需要价格提要地址,然后是低SVG和高SVG,按此顺序。但是,我错误地以错误的顺序传递了参数,导致在合约中存储了不正确的图像URI。

const { network } = require("hardhat");
    const { developmentChains, networkConfig } = require("../helper-hardhat-config");
    const { verify } = require("../utils/verify");
    const fs = require("fs")
    
    module.exports = async ({getNamedAccounts, deployments}) => {
        const {deploy, log} = deployments
        const {deployer} = await  getNamedAccounts()
    
        const chainId = network.config.chainId
        let ethUsdPriceFeedAddress
    
        if(chainId == 31337) {
            const EthUsdAggregator = await deployments.get("MockV3Aggregator")
            ethUsdPriceFeedAddress  = EthUsdAggregator.address
        } else {
            ethUsdPriceFeedAddress = networkConfig[chainId].ethUsdPriceFeed
        }
    
        log("#####################################");
    
        // read the nft images
        const lowSVG =  fs.readFileSync("images/dynamicNft/frown.svg", {encoding: "utf8"})
        const highSVG =  fs.readFileSync("images/dynamicNft/happy.svg", {encoding: "utf8"})
        args = [ethUsdPriceFeedAddress, highSVG, lowSVG]
    
        const dynamicSvgNft = await deploy("DynamicSvgNft", {
            from: deployer,
            args:args,
            log: true,
            waitConfirmations: network.config.blockConfirmations || 1
        })
    
        if(!developmentChains.includes(network.name) && process.env.ETHERSCAN_API_KEY) {
            log("verifying.....")
            await verify(dynamicSvgNft.address, args)
            log("verified!")
    
            log("#########################################")
        }
    
    }
    
    module.exports.tags = ["all", "dynamicsvg", "main"]

字符串
为了解决这个问题,我更正了参数顺序:

args = [ethUsdPriceFeedAddress, highSVG, lowSVG]


致:

args = [ethUsdPriceFeedAddress, lowSVG, highSVG]


通过以正确的顺序传递参数,合约现在可以根据提供的SVG正确地设置图像URI。getHighSVG()getLowSVG()函数现在返回预期的图像URI,并且测试按预期通过。
我希望这些信息可以帮助其他任何在DynamicSvgNft合同中遇到类似问题的人。请记住,在部署具有多个参数的合约时,始终要验证参数的顺序,以避免此类问题。
干杯

相关问题