ethereumsoliditysmartcontractsnft

How to update a NFT mint price by ethereum price in USD?


I am trying to build a smart contract that would give a fixed price in USD for each NFT to be minted by others, which they will need to pay in ETH. But I found a problem that the price of ETH is always changing, and each update of the NFT price in ETH would need some gas fee, which could cost a lot in long term for maintenance. Is there a way to periodically update ETH price inside the smart contract, or is manual updating the only way to do it?

Or I might have to remove the NFT price limit and completely rely on the frontend to handle the pricing part. But I think that's too risky.


Solution

  • You can use a Chainlink datafeed that returns the price of ETH in USD.

    There are no datafeeds in emulators (e.g. Ganache or the Remix IDE built-in network), so you can test this snippet on your local fork of the Ethereum mainnet.

    pragma solidity 0.8;
    
    import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
    
    contract MyContract {
        AggregatorV3Interface priceFeed;
        // 18 decimals
        uint256 requiredPriceInUsd = 1000 * 1e18;
    
        constructor() {
            // https://etherscan.io/address/0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419#code
            // Chainlink ETH/USD Price Feed for Ethereum Mainnet
            priceFeed = AggregatorV3Interface(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
        }
    
        // returns amount of wei
        function getRequiredPriceInWei() public view returns (uint256) {
            (,int answer,,,) = priceFeed.latestRoundData();
    
            // returned price is 8 decimals, convert to 18 decimals
            uint256 ethUsdPrice = uint256(answer) * 1e10;
    
            // 36 decimals / 18 decimals = 18 decimals
            return (requiredPriceInUsd * 1e18) / ethUsdPrice;
        }
    }
    

    Output from my test: