javascript Multimint智能合约上的Solidity Mint功能-应付款NFT不起作用

qgzx9mmu  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(208)

我有一个NFT集合的智能合约。关键是我有两种不同的薄荷糖。一个需要灵魂绑定NFT的白名单的造币厂和另一个将是销售集合的造币厂(以MATIC,ETH为成本)。我已经有了灵魂绑定薄荷功能,但我没有得到销售薄荷工作。safeMintNft()函数被触发以铸造此销售集合。

function safeMintNft() public payable whenNotPaused {
    require(
        nftCost > 0, "NFT cost is not set"
    );

    require(
        keccak256(bytes(whitelistedAddresses[msg.sender].discordUser)) !=
            keccak256(""),
        "Address is not whitelisted"
    );

    require(
        keccak256(bytes(whitelistedAddresses[msg.sender].user_type)) == keccak256(bytes("buyer")),
        "Only buyers can mint the NFT"
    );
    uint256 minterBalance = address(msg.sender).balance;
    require(
        minterBalance >= nftCost,
        "not enough tokens to pay for this NFT"
    );

    
    uint256 tokenId = _tokenIdCounter.current();
    _tokenIdCounter.increment();
    tokenIdAddresses[tokenId] = msg.sender;

    address payable contractAddress = payable(address(this));
    contractAddress.transfer(nftCost);

    _safeMint(msg.sender, tokenId);
}

那我就用茶试试。达到这种情况的代码片段如下:

describe("User has enough eth to mint", async function() {
     beforeEach(async function() {
         await this.nft.setNftCost(ethers.utils.parseEther("0.1"));
      });
      it("should be able to mint", async function() {
         const tx = await this.nft.connect(this.normalUser).safeMintNft();
         const waitedTx = await tx.wait();
         expect(waitedTx.status).to.equal(1);
      });
});

当它达到这种情况时,我们将成本设置为0。1个以太币(账户normalUser拥有它,因为它是一个拥有999+以太币的安全帽账户)。当它到达it语句时,我得到这个错误:

Error: Transaction reverted: function call failed to execute
at MelkExp.safeMintNft (contracts/MelkExp.sol:107)

线107是contractAddress.transfer(nftCost);
任何想法?如果任何信息是失踪,我会编辑或在评论中回答

5kgi1eie

5kgi1eie1#

address payable contractAddress = payable(address(this));
contractAddress.transfer(nftCost);

此代码段尝试传输nftCost数量的本机令牌(以太坊上的ETH,Polygon上的MATIC)。..)

  • 从您的合约地址(transfer()函数的调用者)
  • 到相同的合约地址(从address(this)分配的contractAddress的值)。

这可能不是故意的。
如果您要向合约发送本机令牌(无论是从合约还是从用户地址),则接收方合约需要实现receive()或payable fallback()特殊函数。

contract MyContract {
    receive() external payable {
        // the received ETH stays in this contract address
        // so you may want to transfer it to some admin address right away
        // or to implement another function for withdrawal
    }
}

如果您的目标是从用户钱包中提取nftCost数量的原生令牌,则需要将其包含在交易中,然后在合约端进行验证。
这是因为用户首先发送交易-并且只有在一段时间后(通常在公共网络上几秒钟)才会执行合约功能。但是,在已经签署和广播之后,合同不能追溯影响交易的value

// execute `safeMintNft()`, sending along 0.1 ETH
const tx = await this.nft.connect(this.normalUser).safeMintNft({
    value: ethers.utils.parseEther("0.1")
});
function safeMintNft() public payable whenNotPaused {
    // instead of the `transfer()`
    require(msg.value == nftCost);
}

相关问题