Solidity require 语句导致 Remix 估计无限气体?

问题描述 投票:0回答:1

我是 Solidity 新手,我有一个类项目的智能合约代码。

pragma solidity ^0.5.0;

import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC721/ERC721Full.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/math/SafeMath.sol";

contract MemToken is ERC721Full {
    using SafeMath for uint256;

    address public contractOwner;

    struct Trait {
        string name;
        uint256 Price;
        uint256 maxSupply;
        uint256 mintedCount;
    }

    Trait[] public traits;

    constructor() public ERC721Full("MemToken", "WINE") {
        contractOwner = msg.sender;

        // Initialize the traits array in the constructor
        traits.push(Trait({name: "Russian River Valley", Price: 0.2 ether, maxSupply: 100, mintedCount: 0}));
        traits.push(Trait({name: "Napa Valley", Price: 0.6 ether, maxSupply: 100, mintedCount: 0}));
        traits.push(Trait({name: "Oregon", Price: 0.3 ether, maxSupply: 100, mintedCount: 0}));
        traits.push(Trait({name: "Columbia Valley", Price: 0.4 ether, maxSupply: 100, mintedCount: 0}));
        traits.push(Trait({name: "Finger Lakes", Price: 0.5 ether, maxSupply: 100, mintedCount: 0}));
    }

    mapping(uint256 => uint256) public tokenToTrait;

    function generateTokenURI(uint256 tokenId) internal view returns (string memory) {
        require(tokenId < totalSupply(), "Token does not exist");
        uint256 traitIndex = tokenToTrait[tokenId];
        Trait memory trait = traits[traitIndex];
        return string(abi.encodePacked(trait.name, "-", tokenId));
    }

function mintMembership(address owner, uint256 traitIndex)
        public
        payable // Allow receiving payments with the function call
        returns (uint256)
    {
        require(traitIndex < traits.length, "Invalid trait index");
        Trait storage trait = traits[traitIndex];
        
        require(trait.mintedCount < trait.maxSupply, "Trait supply limit reached");
        require(msg.value >= trait.Price, "Insufficient payment"); // Check if payment is sufficient
        
        uint256 tokenId = totalSupply();
        _mint(owner, tokenId);
        
        string memory tokenURI = generateTokenURI(tokenId);
        _setTokenURI(tokenId, tokenURI);
        
        tokenToTrait[tokenId] = traitIndex;
        trait.mintedCount++;
        
        // Transfer the payment to the contract owner
        address payable ownerPayable = address(uint64(contractOwner));
        ownerPayable.transfer(msg.value);
        return tokenId;
    }

    function getMembershipType(uint256 tokenId) public view returns (string memory name, uint256 Price) {
        require(tokenId < totalSupply(), "Token does not exist");
        uint256 traitIndex = tokenToTrait[tokenId];
        Trait memory trait = traits[traitIndex];
        return (trait.name, trait.Price);
    }

    function getMembershipInfo(uint256 traitIndex) public view returns (string memory name, uint256 Price, uint256 maxSupply, uint256 mintedCount) {
        require(traitIndex < traits.length, "Invalid trait index");
        Trait memory trait = traits[traitIndex];
        return (trait.name, trait.Price, trait.maxSupply, trait.mintedCount);
    }

}

我至少有一个问题:在 Remix 中编译和部署合约后,mintMembership 功能不起作用(侧边栏中显示为红色,并且尝试推动交易无论如何都会导致 Gas 估算过高,因此无论如何都会失败) 。我还会注意到,Remix 估计所有函数的无限气体。

事实证明,当我注释掉 mintMembership 函数的这一部分时,我能够运行该函数而不会出现任何错误(尽管 Remix 仍然会估计无限气体)。

     require(msg.value >= trait.Price, "Insufficient payment"); // Check if payment is sufficient

缺点是,traitPrice 不再包含在传输给合约所有者的 msg.value 中(mintMembership 函数结束)。

如有任何建议,我们将不胜感激。

ethereum solidity smartcontracts remix
1个回答
0
投票

您有几个问题。

  1. 您使用的 Solidity 版本太旧。最好至少使用

    0.8.0

  2. require
    设计的失败将使用完整的gas限制(这是您看到的极高的gas估计值)。您可以在交易中为此设置较低的 Gas 限额。

  3. require(msg.value >= trait.Price)
    意味着除非您在交易中发送至少
    trait.Price
    ETH,否则您的智能合约调用将会失败。这就是这里发生的事情。

查看构造函数,这可以在

0.2
-
0.6
ETH 之间。

© www.soinside.com 2019 - 2024. All rights reserved.