Hello I am trying to deploy a contract using remix.ethereum.org after linked the metamask account using mumbai network.
I receive this error while making the transaction for the contract
Gas estimation errored with the following message (see below). The
transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error. { "code": -32000, "message": "execution
reverted" }
status false Transaction mined but execution failed
transaction hash 0x7af5f103024420440aa8c2314bd4a136fa3ce20b2cad325c662205308bb96f19
gas 3000000 gas
transaction cost 677934 gas
hash 0x7af5f103024420440aa8c2314bd4a136fa3ce20b2cad325c662205308bb96f19
[
{
"from": "0x0000000000000000000000000000000000001010",
"data": "0x000000000000000000000000000000000000000000000000000605718620be0000000000000000000000000000000000000000000000000006d23f73843bdd2a000000000000000000000000000000000000000000000812986dea162255c6d300000000000000000000000000000000000000000000000006cc3a01fe1b1f2a0000000000000000000000000000000000000000000008129873ef87a87684d3",
"topics": [
"0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
"0x0000000000000000000000000000000000000000000000000000000000001010",
"0x0000000000000000000000002af41d8052ad1dfe56af7ce01beb8918985c94e3",
"0x000000000000000000000000be188d6641e8b680743a4815dfa0f6208038960f"
]
}
]
val 0 wei
Anyone has any idea how to solve it ?
That's the contract :
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "contracts/access/Ownable.sol";
contract Appoles is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.004 ether;
uint256 public presaleCost = 0.004 ether;
uint256 public maxSupply = 10;
uint256 public maxMintAmount = 2;
bool public paused = false;
mapping(address => bool) public whitelisted;
mapping(address => bool) public presaleWallets;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
mint(msg.sender, 20);
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function mint(address _to, uint256 _mintAmount) public payable {
uint256 supply = totalSupply();
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(supply + _mintAmount <= maxSupply);
if (msg.sender != owner()) {
if (whitelisted[msg.sender] != true) {
if (presaleWallets[msg.sender] != true) {
//general public
require(msg.value >= cost * _mintAmount);
} else {
//presale
require(msg.value >= presaleCost * _mintAmount);
}
}
}
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(_to, supply + i);
}
}
function walletOfOwner(address _owner)
public
view
returns (uint256[] memory)
{
uint256 ownerTokenCount = balanceOf(_owner);
uint256[] memory tokenIds = new uint256[](ownerTokenCount);
for (uint256 i; i < ownerTokenCount; i++) {
tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
}
return tokenIds;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return
bytes(currentBaseURI).length > 0
? string(
abi.encodePacked(
currentBaseURI,
tokenId.toString(),
baseExtension
)
)
: "";
}
//only owner
function setCost(uint256 _newCost) public onlyOwner {
cost = _newCost;
}
function setPresaleCost(uint256 _newCost) public onlyOwner {
presaleCost = _newCost;
}
function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
maxMintAmount = _newmaxMintAmount;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension)
public
onlyOwner
{
baseExtension = _newBaseExtension;
}
function pause(bool _state) public onlyOwner {
paused = _state;
}
function whitelistUser(address _user) public onlyOwner {
whitelisted[_user] = true;
}
function removeWhitelistUser(address _user) public onlyOwner {
whitelisted[_user] = false;
}
function addPresaleUser(address _user) public onlyOwner {
presaleWallets[_user] = true;
}
function add100PresaleUsers(address[100] memory _users) public onlyOwner {
for (uint256 i = 0; i < 2; i++) {
presaleWallets[_users[i]] = true;
}
}
function removePresaleUser(address _user) public onlyOwner {
presaleWallets[_user] = false;
}
function withdraw() public payable onlyOwner {
(bool success, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(success);
}
}
Related
I am using ethers.js to interact with my smart contract deployed on polygon testnet. I try to call a function play() from the smart contract but it always fails with the error: Error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ]
I have satisfied all the require statements but it still seems to fail. Is there something wrong with my code?
I have also tried using getRandomNumber() function from of chainlink VRF separately and it works there.
My smart contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "./FutNFTTransfer.sol";
import "./VRFConsumer.sol";
contract FutNFTMatch is FutNFTTransfer, VRFConsumer {
uint256 public levelPercentSuitablePosition;
uint256 public levelPercentNoPosition;
mapping(string => string[]) public formationToPositions;
string[] public formations;
string[] public allPositions;
uint256 public lineupFee = 3 ether;
uint256 public matchFee = 1 ether;
// uint256 public lineupFee = 0.001 ether;
address[] public lineupSet;
modifier playersOwned(uint256[11] memory _playerIds) {
for (uint256 i = 0; i < _playerIds.length; i++) {
require(ownerOf(_playerIds[i]) == msg.sender);
}
_;
}
modifier lineUpSet(address _owner) {
require(lineUps[_owner].isValid, "Linup not set");
_;
}
constructor() {
formations.push("4-3-3");
formationToPositions["4-3-3"] = [
"GK",
"LB",
"CB",
"CB",
"RB",
"CMF",
"CMF",
"CMF",
"LWF",
"ST",
"RWF"
];
formations.push("4-3-3 attack");
formationToPositions["4-3-3 attack"] = [
"GK",
"LB",
"CB",
"CB",
"RB",
"CMF",
"AMF",
"CMF",
"RWF",
"ST",
"LWF"
];
allPositions = [
"LWF",
"ST",
"RWF",
"CF",
"AMF",
"CMF",
"DMF",
"LMF",
"RMF",
"RB",
"LB",
"CB",
"GK"
];
}
function setMatchFee(uint256 _fee) public onlyOwner {
matchFee = _fee;
}
function setLineupFee(uint256 _fee) public onlyOwner {
lineupFee = _fee;
}
function getAllFormations() public view returns (string[] memory) {
return formations;
}
function getLineup(address _owner) public view returns (LineUp memory) {
return lineUps[_owner];
}
function addFormation(string memory formation, string[] memory positions)
public
onlyOwner
{
formationToPositions[formation] = positions;
formations.push(formation);
}
function getPositionsFromFormation(string memory formation)
public
view
returns (string[] memory)
{
return formationToPositions[formation];
}
function getAllPositions() public view returns (string[] memory) {
return allPositions;
}
function setLevelPercentSuitablePosition(uint256 _percent)
public
onlyOwner
{
levelPercentSuitablePosition = _percent;
}
function setLevelPercentNoPosition(uint256 _percent) public onlyOwner {
levelPercentNoPosition = _percent;
}
function setLineUp(
uint256[11] memory _playerIds,
string[11] memory _positions,
string memory _formation
) external payable playersOwned(_playerIds) returns (uint256) {
require(msg.value == lineupFee, "Required fee not sent!");
lineUps[msg.sender] = LineUp(_playerIds, _positions, _formation, true);
lineupSet.push(msg.sender);
return _getTeamRating(msg.sender);
}
function _getTeamRating(address _owner)
internal
view
lineUpSet(_owner)
returns (uint256)
{
LineUp memory lineup = lineUps[_owner];
uint256 sum;
uint256 count;
for (uint256 i = 0; i < lineup.playerIds.length; i++) {
sum += _getPlayerLevel(lineup, i);
count++;
}
return sum / count;
}
function _getPlayerLevel(LineUp memory _lineup, uint256 _arrayPosition)
internal
view
returns (uint256)
{
Player memory player = super.getPlayer(
_lineup.playerIds[_arrayPosition]
);
string memory position = _lineup.positions[_arrayPosition];
uint256 level;
if (
keccak256(abi.encodePacked(player.preferredPosition)) ==
keccak256(abi.encodePacked(position))
) {
level = player.level;
} else {
level = _getPlayerLevelForUnpreferredPosition(player, position);
}
return level;
}
function _getPlayerLevelForUnpreferredPosition(
Player memory _player,
string memory _position
) internal view returns (uint256) {
uint256 level = (_player.level * levelPercentNoPosition) / 100;
for (uint256 k = 0; k < _player.suitablePositions.length; k++) {
if (
keccak256(abi.encodePacked(_player.suitablePositions[k])) ==
keccak256(abi.encodePacked(_position))
) {
level = (_player.level * levelPercentSuitablePosition) / 100;
break;
}
}
return level;
}
function getOpponent() public lineUpSet(msg.sender) returns(address) {
require(lineupSet.length > 1, "Players not available!");
getRandomNumber();
randomResult = (randomResult % lineupSet.length) + 1;
address opponent = lineupSet[randomResult - 1];
if(msg.sender == opponent) {
if(randomResult == lineupSet.length) {
opponent = lineupSet[randomResult - 2];
} else {
opponent = lineupSet[randomResult];
}
}
return opponent;
}
function play()
external
payable
lineUpSet(msg.sender)
{
require(msg.value == matchFee, "Required fee not sent!");
address _opponent = getOpponent();
uint256 teamRating = _getTeamRating(msg.sender);
uint256 opponentTeamRating = _getTeamRating(_opponent);
uint256 winProbability = 50;
if (teamRating > opponentTeamRating) {
winProbability = 50 + ((teamRating - opponentTeamRating) * 3);
} else {
winProbability = 50 - ((opponentTeamRating - teamRating) * 3);
}
getRandomNumber();
randomResult = (randomResult % 100) + 1;
address payable winner;
if (randomResult <= winProbability) {
ownerHistory[msg.sender].winCount++;
ownerHistory[_opponent].lossCount++;
winner = payable(msg.sender);
} else {
ownerHistory[msg.sender].lossCount++;
ownerHistory[_opponent].winCount++;
winner = payable(_opponent);
}
(bool sent, ) = winner.call{
value: /*0.0015*/
4.5 ether
}("");
require(sent, "Could not complete transaction!");
}
}
my frontend code:
const provider = new ethers.providers.Web3Provider(
(window as any).ethereum
);
const signer = provider.getSigner();
const matchFee = await this.props.futNFTMatch.matchFee();
const tx = await this.props.futNFTMatch
.connect(signer)
.play({
value: matchFee,
gasLimit: 1000000,
gasPrice: 30000000000,
});
await tx.wait();
Your transaction was reverted due to insufficient gas:
Warning! Error encountered during contract execution [out of gas]
Try removing gas and gasPrice fields from your call or increasing
I get this error when I try to call play() function from my smart contract using ethers.js:
MetaMask - RPC Error: Internal JSON-RPC error.
{code: -32603, message: 'Internal JSON-RPC error.', data: {…}}
code: -32603
data:
code: 3
data: "0x4e487b710000000000000000000000000000000000000000000000000000000000000032"
message: "execution reverted"
message: "Internal JSON-RPC error."
my smart contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import "./FutNFTTransfer.sol";
import "./VRFConsumer.sol";
contract FutNFTMatch is FutNFTTransfer, VRFConsumer {
uint256 public levelPercentSuitablePosition = 75;
uint256 public levelPercentNoPosition = 50;
mapping(string => string[]) public formationToPositions;
string[] public formations;
string[] public allPositions;
uint256 public lineupFee = 0.2 ether;
uint256 public matchFee = 3 ether;
address[] public lineupSet;
mapping(address => uint256) public ownersToDeposits;
modifier playersOwned(uint256[11] memory _playerIds) {
for (uint256 i = 0; i < _playerIds.length; i++) {
require(ownerOf(_playerIds[i]) == msg.sender, "Players not owned!");
}
_;
}
modifier lineUpSet(address _owner) {
require(lineUps[_owner].isValid, "Linup not set");
_;
}
constructor() {
formations.push("4-3-3");
formationToPositions["4-3-3"] = [
"GK",
"LB",
"CB",
"CB",
"RB",
"CMF",
"CMF",
"CMF",
"LWF",
"ST",
"RWF"
];
formations.push("4-3-3 attack");
formationToPositions["4-3-3 attack"] = [
"GK",
"LB",
"CB",
"CB",
"RB",
"CMF",
"AMF",
"CMF",
"RWF",
"ST",
"LWF"
];
allPositions = [
"LWF",
"ST",
"RWF",
"CF",
"AMF",
"CMF",
"DMF",
"LMF",
"RMF",
"RB",
"LB",
"CB",
"GK"
];
}
function setMatchFee(uint256 _fee) public onlyOwner {
matchFee = _fee;
}
function setLineupFee(uint256 _fee) public onlyOwner {
lineupFee = _fee;
}
function getAllFormations() public view returns (string[] memory) {
return formations;
}
function getLineup(address _owner) public view returns (LineUp memory) {
return lineUps[_owner];
}
function deposit() public payable lineUpSet(msg.sender) {
require(msg.value >= 1 ether, "Not enough funds sent!");
ownersToDeposits[msg.sender] += msg.value;
if (ownersToDeposits[msg.sender] < 2 ether) {
lineupSet.push(msg.sender);
}
}
function _removeFromLineupSet(address _owner) internal {
address[] memory newLineupSet;
uint256 subFromIndex = 0;
for (uint256 i = 0; i < lineupSet.length; i++) {
if (lineupSet[i] != _owner) {
newLineupSet[i - subFromIndex] = lineupSet[i];
} else {
subFromIndex++;
}
}
lineupSet = newLineupSet;
}
function withdrawDeposit(uint256 _price) public payable {
require(
ownersToDeposits[msg.sender] >= _price,
"Enough funds not deposited!"
);
address to = payable(msg.sender);
(bool sent, ) = to.call{value: _price}("");
ownersToDeposits[msg.sender] -= _price;
require(sent, "Could not complete the transaction");
if (ownersToDeposits[msg.sender] < 1 ether) {
_removeFromLineupSet(msg.sender);
}
}
function addFormation(string memory formation, string[] memory positions)
public
onlyOwner
{
formationToPositions[formation] = positions;
formations.push(formation);
}
function getPositionsFromFormation(string memory formation)
public
view
returns (string[] memory)
{
return formationToPositions[formation];
}
function getAllPositions() public view returns (string[] memory) {
return allPositions;
}
function setLevelPercentSuitablePosition(uint256 _percent)
public
onlyOwner
{
levelPercentSuitablePosition = _percent;
}
function setLevelPercentNoPosition(uint256 _percent) public onlyOwner {
levelPercentNoPosition = _percent;
}
function setLineUp(
uint256[11] memory _playerIds,
string[11] memory _positions,
string memory _formation
) external payable playersOwned(_playerIds) returns (uint256) {
require(msg.value == lineupFee, "Required fee not sent!");
lineUps[msg.sender] = LineUp(_playerIds, _positions, _formation, true);
return getTeamRating(msg.sender);
}
function getTeamRating(address _owner)
public
view
lineUpSet(_owner)
returns (uint256)
{
LineUp memory lineup = lineUps[_owner];
uint256 sum;
uint256 count;
for (uint256 i = 0; i < lineup.playerIds.length; i++) {
sum += _getPlayerLevel(lineup, i);
count++;
}
return sum / count;
}
function _getPlayerLevel(LineUp memory _lineup, uint256 _arrayPosition)
internal
view
returns (uint256)
{
Player memory player = super.getPlayer(
_lineup.playerIds[_arrayPosition]
);
string memory position = _lineup.positions[_arrayPosition];
uint256 level;
if (
keccak256(abi.encodePacked(player.preferredPosition)) ==
keccak256(abi.encodePacked(position))
) {
level = player.level;
} else {
level = _getPlayerLevelForUnpreferredPosition(player, position);
}
return level;
}
function _getPlayerLevelForUnpreferredPosition(
Player memory _player,
string memory _position
) internal view returns (uint256) {
uint256 level = (_player.level * levelPercentNoPosition) / 100;
for (uint256 k = 0; k < _player.suitablePositions.length; k++) {
if (
keccak256(abi.encodePacked(_player.suitablePositions[k])) ==
keccak256(abi.encodePacked(_position))
) {
level = (_player.level * levelPercentSuitablePosition) / 100;
break;
}
}
return level;
}
function getOpponent() public lineUpSet(msg.sender) returns (address) {
require(lineupSet.length > 1, "Players not available!");
getRandomNumber();
randomResult = (randomResult % lineupSet.length) + 1;
address opponent = lineupSet[randomResult - 1];
if (msg.sender == opponent) {
if (randomResult == lineupSet.length) {
opponent = lineupSet[randomResult - 2];
} else {
opponent = lineupSet[randomResult];
}
}
return opponent;
}
function play() external payable lineUpSet(msg.sender) {
require(
ownersToDeposits[msg.sender] >= 1 ether,
"Does not have enough funds in deposits!"
);
address _opponent = getOpponent();
uint256 teamRating = getTeamRating(msg.sender);
uint256 opponentTeamRating = getTeamRating(_opponent);
uint256 winProbability = 50;
if (teamRating > opponentTeamRating) {
winProbability = 50 + ((teamRating - opponentTeamRating) * 3);
} else {
winProbability = 50 - ((opponentTeamRating - teamRating) * 3);
}
getRandomNumber();
randomResult = (randomResult % 100) + 1;
if (randomResult <= winProbability) {
ownerHistory[msg.sender].winCount++;
ownerHistory[_opponent].lossCount++;
ownersToDeposits[_opponent] -= 1 ether;
if (ownersToDeposits[_opponent] < 1 ether) {
_removeFromLineupSet(_opponent);
}
ownersToDeposits[msg.sender] += 0.5 ether;
} else {
ownerHistory[msg.sender].lossCount++;
ownerHistory[_opponent].winCount++;
ownersToDeposits[msg.sender] -= 1 ether;
if (ownersToDeposits[msg.sender] < 1 ether) {
_removeFromLineupSet(msg.sender);
}
ownersToDeposits[_opponent] += 0.5 ether;
}
}
}
my ethers.js code:
const provider: ethers.providers.Web3Provider = new ethers.providers.Web3Provider((window as any).ethereum);
const signer = provider.getSigner();
const matchFee = await this.props.futNFTMatch.matchFee();
const tx = await this.props.futNFTMatch.connect(signer).play();
await tx.wait();
I have satisfied all the require statements, but still I get this error. Is something wrong with my code?
Here are all the contracts if you need them: https://github.com/anim7/FutNFT/tree/master/contracts
Try the following suggestion provided by MetaMask.
ensure the network has been added correctly. You can use Chainlist to add custom network/ tokens
ensure you have enough native tokens from that network to pay for gas
ensure you are using the latest version of the app or the extension
I am using ethers.js to call the mint function in my smart contract but it fails with this error:
Error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ].
I am able to call the view functions this error only occurs when I call functions which make transactions. So, I know that I have connected to the same network as the contract.
My smart contract:
pragma solidity ^0.8.12;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract FutNFT is ERC721, ERC721Enumerable, Ownable {
struct Player {
string name;
string preferredPosition;
uint256 id;
uint8 age;
uint8 level;
uint64 lastUpgrade;
string[] suitablePositions;
string imageURI;
}
struct History {
uint256 winCount;
uint256 lossCount;
}
mapping(address => History) ownerHistory;
mapping(uint256 => Player) players;
mapping(uint256 => address) public playerToOwner;
mapping(uint256 => uint256) listedPlayerIndex;
uint256[] public listedPlayers;
event PlayerAdded(uint256 playerId);
modifier owned(uint256 id) {
require(getPlayerExists(id), "Player does not exist");
require(msg.sender == ownerOf(id), "Not the owner!");
_;
}
constructor() ERC721("FutNFT", "FNFT") {}
function getListedPlayers() public view returns (uint256[] memory) {
return listedPlayers;
}
function getPlayer(uint256 _id) public view returns (Player memory) {
return players[_id];
}
function ownerOf(uint256 tokenId)
public
view
override(ERC721, IERC721)
returns (address)
{
return super.ownerOf(tokenId);
}
function getPlayerExists(uint256 _id) public view returns (bool) {
return playerToOwner[_id] != address(0);
}
function mint(Player memory _player) public onlyOwner {
require(playerToOwner[_player.id] == address(0), "Player Exists!");
players[_player.id] = _player;
playerToOwner[_player.id] = msg.sender;
_mint(msg.sender, _player.id);
emit PlayerAdded(_player.id);
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
my frontend code:
const player: PlayerInterface = {
name: "Lionel Messi",
preferredPosition: "RWF",
id: 1,
age: 34,
level: 20,
lastUpgrade: new Date().getTime(),
suitablePositions: ["ST", "CF", "RMF", "CAM"],
imageURI:
"https://bafybeicfhmevzs4aso7rqvx7l5ndb2ly7gudjyj5xjkztvohpwxw2za7iy.ipfs.dweb.link/nft.png",
};
const provider = new ethers.providers.Web3Provider(
(window as any).ethereum
);
const signer = provider.getSigner();
const tx = await futNFT.connect(signer).mint(player, {
gasPrice: 30000000000,
gasLimit: 2000000,
});
await tx.wait();
console.log("minted");
const player1 = await futNFT.getPlayer(1);
console.log(player1);
I am quite new to Solidity. I have deployed a smart contract and doing some testing on it. If no one was added as a whitelisted user - all wallets can mint an NFT. If I add someone and then remove them - no one can mint it until whitelisted (except the owner). My question: is it possible to allow everyone to mint again? Thanks in advance.
contract:
pragma solidity ^0.8.7;
contract test is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.03 ether;
uint256 public presaleCost = 0.03 ether;
uint256 public maxSupply = 10000;
uint256 public maxMintAmount = 10000;
bool public paused = false;
mapping(address => bool) public whitelisted;
mapping(address => bool) public presaleWallets;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
mint(msg.sender, 1);
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function mint(address _to, uint256 _mintAmount) public payable {
uint256 supply = totalSupply();
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(supply + _mintAmount <= maxSupply);
if (msg.sender != owner()) {
if (whitelisted[msg.sender] != true) {
if (presaleWallets[msg.sender] != true) {
//general public
require(msg.value >= cost * _mintAmount);
} else {
//presale
require(msg.value >= presaleCost * _mintAmount);
}
}
}
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(_to, supply + i);
}
}
function walletOfOwner(address _owner)
public
view
returns (uint256[] memory)
{
uint256 ownerTokenCount = balanceOf(_owner);
uint256[] memory tokenIds = new uint256[](ownerTokenCount);
for (uint256 i; i < ownerTokenCount; i++) {
tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
}
return tokenIds;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return
bytes(currentBaseURI).length > 0
? string(
abi.encodePacked(
currentBaseURI,
tokenId.toString(),
baseExtension
)
)
: "";
}
//only owner
function setCost(uint256 _newCost) public onlyOwner {
cost = _newCost;
}
function setPresaleCost(uint256 _newCost) public onlyOwner {
presaleCost = _newCost;
}
function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
maxMintAmount = _newmaxMintAmount;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension)
public
onlyOwner
{
baseExtension = _newBaseExtension;
}
function pause(bool _state) public onlyOwner {
paused = _state;
}
function whitelistUser(address _user) public onlyOwner {
whitelisted[_user] = true;
}
function removeWhitelistUser(address _user) public onlyOwner {
whitelisted[_user] = false;
}
function addPresaleUser(address _user) public onlyOwner {
presaleWallets[_user] = true;
}
function add100PresaleUsers(address[100] memory _users) public onlyOwner {
for (uint256 i = 0; i < 2; i++) {
presaleWallets[_users[i]] = true;
}
}
function removePresaleUser(address _user) public onlyOwner {
presaleWallets[_user] = false;
}
function withdraw() public payable onlyOwner {
(bool success, ) = payable(msg.sender).call{
value: address(this).balance
}("");
require(success);
}
}
In mint function you have added condition for if address is not owner then this user needs to be whitelisted. If you want to mint nft by any address then remove this condition.
if (msg.sender != owner()) {
if (whitelisted[msg.sender] != true) {
if (presaleWallets[msg.sender] != true) {
//general public
require(msg.value >= cost * _mintAmount);
} else {
//presale
require(msg.value >= presaleCost * _mintAmount);
}
}
}
I run my code on rinkeby etherscan network and it works perfectly. But the image and descriptions are not showing on opensea testnet. I run the /validate/ url it shows Valid: "false".
Here is what I found when I force update on opensea, https://testnets-api.opensea.io/api/v1/asset/0x668D179B933af761e4732B084290D32B3235C22b/0/?force_update=true
Here is my code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "./ERC2981ContractWideRoyalties.sol";
import "hardhat/console.sol";
contract SmoothApe is ERC721URIStorage, Ownable, ERC2981ContractWideRoyalties {
using Counters for Counters.Counter;
using Strings for uint256;
Counters.Counter private _tokenIdCounter;
event EmitNFT(address sender, uint256 tokenId);
uint256 public preSaleTokenPrice = 0.01 ether;
uint256 public costPrice = 0.02 ether;
uint256 public maxSupply = 10000;
uint256 public maxMintNft = 10;
string public baseURI;
string public baseExtension = ".json";
string public notRevealedUri;
bool public paused = false;
bool public revealed = true;
bool public presale = false;
// set 0x7350243981aB92E2A3646e377EBbFC28e9DE96C1 as payable admn wallet
address payable public adminWallet = payable(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2);
address payable public communityWallet = payable(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db);
address payable public t1Wallet = payable(0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB);
address payable public t2Wallet = payable(0x617F2E2fD72FD9D5503197092aC168c91465E7f2);
address payable public t3Wallet = payable(0x17F6AD8Ef982297579C203069C1DbfFE4348c372);
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
constructor(string memory _name, string memory _symbol,string memory _initBaseURI, string memory _initNotRevealedUri) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
setNotRevealedUri(_initNotRevealedUri);
}
// inherit and override erc165
function supportsInterface(bytes4 interfaceId) public view virtual override (ERC721, ERC2981Base) returns (bool) {
return super.supportsInterface(interfaceId);
}
// set Royalty value (between 0 and 10000)
function setRoyalties(address recipient, uint256 value) public onlyOwner {
_setRoyalties(recipient, value);
}
function _baseURI() internal view override returns (string memory) {
return baseURI;
}
function mintApe() public payable {
uint256 tokenId = _tokenIdCounter.current();
require(!paused, "Minting is paused");
require(msg.sender != owner(), "You can't mint ape to admin");
// require(_mintAmount > 0, "Mint amount must be greater than 0");
// require(_mintAmount <= maxSupply, "Mint amount must be less than or equal to max supply");
if(presale == true) {
preSaleTokenPrice = costPrice;
}
require(msg.value >= costPrice, string(abi.encodePacked("Must send at least ", costPrice.toString(), " ether to purchase")));
require(balanceOf(msg.sender) < maxMintNft, "You can only own 11 ape at a time");
// require(_mintAmount + balanceOf(msg.sender) <= maxMintNft, "You can only own 10 ape at a time");
// adminWallet.transfer(msg.value);
payable(owner()).transfer(msg.value);
emit EmitNFT(msg.sender, tokenId);
// for(uint256 i = 1; i <= _mintAmount; i++){
_safeMint(msg.sender, tokenId);
// _setTokenURI(tokenId, _baseURI());
_tokenIdCounter.increment();
// }
}
// admin mint ape to wallet
function mintApeTo(address _to, uint256 _mintAmount) public onlyOwner {
require(!paused, "Minting is paused");
require(_mintAmount > 0, "Mint amount must be greater than 0");
require(_mintAmount <= maxSupply, "Mint amount must be less than or equal to max supply");
for(uint256 i = 1; i <= _mintAmount; i++){
uint256 tokenId = _tokenIdCounter.current();
_safeMint(_to, tokenId);
// _setTokenURI(tokenId, _baseURI());
_tokenIdCounter.increment();
}
}
function getCostPrice() public view virtual returns (uint256) {
return costPrice;
}
// function to set cost of ape
function setCost(uint256 _preSaleTokenPrice, uint256 _publicTokenPrice) public onlyOwner {
preSaleTokenPrice = _preSaleTokenPrice;
costPrice = _publicTokenPrice;
}
// set presale to true
function setPresale(bool _presale) public onlyOwner {
presale = _presale;
}
function reveal(bool _reveal) public onlyOwner {
revealed = _reveal;
}
// pause function
function pause() public onlyOwner {
paused = true;
}
// set function for setBaseURI and setNotRevealed function
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setTokenURI(uint256 _tokenId, string memory _tokenURI) public onlyOwner {
_setTokenURI(_tokenId, _tokenURI);
}
// override tokenURI function
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
require(tokenId < _tokenIdCounter.current(), "Token ID must be less than the total supply");
if(!revealed) {
return notRevealedUri;
}
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(
abi.encodePacked(
currentBaseURI,
tokenId.toString(),
baseExtension))
: "";
}
}
Here is a sample of NFT i mint:
https://testnets.opensea.io/assets/0x668D179B933af761e4732B084290D32B3235C22b/0
my ipfs CID:
ipfs://QmaoMZ19zhpC6T4id6jdBP1Qz5dQSmRZMkQZU7Zt8hyFNQ/
as you can see in the right up corner there is a "reload" button, you need to click it to reload the ipfs on opensea
I had the same problem. Turned out that I wasn't uploading the images to ipfs correctly because it was visible only to me on my machine. So try to see if the ipfs metadata are correctly formated and are accesible from different devices.
Also you shouldn't just paste your entire contract in. Tt is really hard to answer your question then. Just write out the important sections of the code.