我对 Solidity 很陌生,最近一直在努力学习。作为参考,在完成了基本的加密僵尸教程系列之后,我一直使用此视频 ( https://www.youtube.com/watch?v=tBMk1iZa85Y ) 中的代码作为入门。
我一直在尝试调整此视频中提供的 Solidity 合约代码(我运行得很好!),以要求在铸造 NFT 作为自己的练习之前烧掉指定数量的 ERC-20 代币。我认为我应该是一个有效的实现,它在 Remix 中编译,然后部署到 Rinkeby。部署到 Rinkeby 后,我在 Remix 中调用了 allowAccess 函数,并且成功了。但是,当我使用两个参数调用 mint 函数时,我得到:“gas 估计错误,出现以下消息(见下文)。交易执行可能会失败。你想强制发送吗?执行已恢复。”
如果我仍然发送交易,元掩码会产生“交易 xx 失败!交易遇到错误。”。
我很肯定它与“require(paymentToken.transfer(burnwallet,amounttopay),”transfer Failed“);”有关,尽管我不确定出了什么问题。下面是我的整个合约代码。我目前只是与 Rinkeby 上的 Chainlink 合约进行交互,因为它们有一个方便的代币水龙头。
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Counters.sol";
contract myNFTwithBurn is ERC721, Ownable {
address externalTokenAddress = 0x01BE23585060835E02B77ef475b0Cc51aA1e0709; //Token Type to burn on minting
uint256 amounttopay = 5; //number of these tokens to burn
IERC20 paymentToken = IERC20(externalTokenAddress); //my code: create an interface of the external token
address burnwallet = 0x000000000000000000000000000000000000dEaD; //burn wallet
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
using Strings for uint256;
// Optional mapping for token URIs
mapping (uint256 => string) private _tokenURIs;
// Base URI
string private _baseURIextended;
constructor() ERC721("NFTsWithBurn","NWB") {
}
function setBaseURI(string memory baseURI_) external onlyOwner() {
_baseURIextended = baseURI_;
}
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseURIextended;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(base, tokenId.toString()));
}
function allowAccess() public
{
paymentToken.approve(address(this), 5000000); //This is my attempt to allow the contract access to the user's external tokens, in this case Chainlink (paymentToken)
}
function mintItem(address to, string memory tokenURI)
public
onlyOwner
returns (uint256)
{
require(paymentToken.transfer(burnwallet, amounttopay),"transfer Failed"); //Try to transfer 5 chainlink to the burn wallet
_tokenIds.increment();
uint256 id = _tokenIds.current();
_mint(to, id);
_setTokenURI(id, tokenURI);
return id;
}
}
如果有人至少可以指出我在添加的代码中做错了什么,请这样做!蒂亚!