Allow ERC20 token for minting ERC721 NFT - solidity

I'm new in Solidity and trying to allow purchasing using ETH and other token such as USDT but I keep getting this error no matter what I tried.
DeclarationError: Identifier already declared. --> contract-9b5b02c5de.sol:9:1:
|
9 | import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
This is my code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "#openzeppelin/contracts#4.8.0/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts#4.8.0/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts#4.8.0/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts#4.8.0/access/Ownable.sol";
import "#openzeppelin/contracts#4.8.0/utils/Counters.sol";
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract Combat is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
ERC20 public tokenUsdt;
uint256 public ethPrice = 0;
uint256 public usdtPrice = 0;
uint256 public maxSupply; //Maximum amount token
bool public isMintEnabled; //default : false
mapping(address=>uint256) public mintedWallets;
constructor(address _tokenUsdt) ERC721("XXX", "QAZ") {
maxSupply = 100;
tokenUsdt = ERC20(_tokenUsdt);
}
function setToken(address _tokenUsdt) external onlyOwner {
tokenUsdt = _tokenUsdt;
}
function setPrice(uint256 _ethPrice, uint256 _usdtPrice) external onlyOwner {
ethPrice = _ethPrice;
usdtPrice = _usdtPrice;
}
function buyMembershipUsdt() external payable {
require(msg.value >= usdtPrice, "Price Error");
tokenUsdt.safeTransferFrom(msg.sender, owner(), _amount);
mintMembership();
}
function buyMembershipEth() external payable {
require(msg.value >= ethPrice, "Price Error");
mintMembership();
}
function mintMembership() internal {
require(isMintEnabled, "Not For Sale");
require(totalSupply() < maxSupply, "Sold Out");
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(msg.sender, tokenId);
}
function setMintEnabled(bool isMintEnabled_) external onlyOwner {
isMintEnabled = isMintEnabled_;
}
function _baseURI() internal pure override returns (string memory) {
return "ipfs://bafybeiebgbvibloa3p3vge7ecxobwxxnuyg4pdozbcfjigfglhz2ogidq4/";
}
function setMaxSupply(uint256 maxSupply_) external onlyOwner{
maxSupply = maxSupply_;
}
function withdraw() public onlyOwner {
require(address(this).balance > 0, "Balance is 0");
payable(owner()).transfer(address(this).balance);
}
function withdrawToken() external onlyOwner {
uint256 tokenBalance = tokenUsdt.balanceOf(address(this));
require(tokenBalance > 0, "Insufficient balance");
tokenUsdt.safeTransfer(msg.sender, tokenBalance);
}
// The following functions are overrides required by Solidity.
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
}
I seen some guides our there but none seems to help because it uses custom token which I'm not using it. Regardless whether I'm using IERC20 or ERC20, I will keep getting error above I mentioned. Am I missing something or what?

You import should be
import "#openzeppelin/contracts#4.8.0/token/ERC20/ERC20.sol";
instead of
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";

Related

I generated a flattened of my contract using Remix but it gives error: Definition of base has to precede definition of derived contract

I thibk the error is occurring because the contract "ERC721Burnable" is trying to inherit from two other contracts "Context" and "ERC721", but "Context" is not defined in the code you provided. So, the definition of a base contract must precede the definition of a derived contract.
How can I make sure that the definition of the "Context" contract is included before the definition of the "ERC721Burnable" contract. Additionally, How can I make sure that "Context" is defined in the same file or imported from a different file.
Bellow is the code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/common/ERC2981.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/utils/math/SafeMath.sol";
contract AliveNatureNFT is ERC721, ERC721Enumerable, ERC721URIStorage, ERC2981, Pausable, ERC721Burnable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
// percentage split for commission and liquidity pool
uint96 public commissionPercentage;
uint96 public liquidityPercentage;
// address of the commission recipient
address public commissionRecipient;
// address of the liquidity pool
address public liquidityPoolRecipient;
// Owner address
address public ownerNFT;
//Base URI
string private url;
struct ProjectData {
string name;
uint256 projectTokenId;
string methodology;
string region;
string emissionType;
string uri;
address creator;
}
struct RetireData {
uint256 retireTokenId;
address beneficiary;
string retirementMessage;
uint256 timeStamp;
uint256 amount;
}
mapping (uint256 => ProjectData) private _projectData;
mapping (uint256 => RetireData) private _retireData;
modifier onlyOwner(address _sender) {
require(_sender == ownerNFT, "Only the owner can call this function");
_;
}
modifier onlyAdmin (address _sender) {
require(_sender == commissionRecipient, "Only the heir can call this function");
_;
}
constructor(
uint96 _liquidityPercentage, address _liquidityPoolRecipient,
string memory _MyToken, string memory _Symbol, string memory _url, address _ownerNFT
) ERC721(_MyToken, _Symbol) {
commissionPercentage = 100;
liquidityPercentage = _liquidityPercentage;
commissionRecipient = 0xE3506A38C80D8bA1ef219ADF55E31E18FB88EbF4;
liquidityPoolRecipient = _liquidityPoolRecipient;
ownerNFT = _ownerNFT;
_setDefaultRoyalty(commissionRecipient, commissionPercentage);
url = _url;
}
function _baseURI() internal view override returns (string memory) {
return url;
}
function pause(address _sender) external onlyAdmin(_sender) {
_pause();
}
function unpause(address _sender) external onlyAdmin(_sender) {
_unpause();
}
function safeMint(address _to, string memory _uri, string memory _name,
string memory _methodology, string memory _region, string memory _emissionType, address _sender) public whenNotPaused onlyOwner(_sender) {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(_to, tokenId);
_setTokenURI(tokenId, _uri);
// Create a new ProjectData struct and store it in the contract's storage
_projectData[tokenId] = ProjectData({
projectTokenId : tokenId,
uri : _uri,
name : _name,
methodology : _methodology,
region : _region,
emissionType : _emissionType,
creator : _sender
});
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
whenNotPaused
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
if (from != address(0)) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can transfer or burn it");
}
}
function _burn(uint256 tokenId) internal whenNotPaused override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function burnToken(uint256 tokenId, string memory _retirementMessage, uint256 _amount, address _sender) public whenNotPaused onlyOwner(_sender) {
address owner = ownerOf(tokenId);
require(owner == msg.sender, "Only the owner of NFT can burn it");
_burn(tokenId);
// Create a new ProjectData struct and store it in the contract's storage
_retireData[tokenId] = RetireData({
retireTokenId : tokenId,
beneficiary : msg.sender,
retirementMessage : _retirementMessage,
timeStamp : block.timestamp,
amount : _amount
});
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
// The following functions are overrides required by Solidity.
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC2981, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
I'm trying to group everything in a flattened contract to have the complete ABI

OpenZeppelin ERC721URIStorage _setTokenURI

i'm trying to create a smart contract for minting NFT's. When i try to import and use _setTokenUri from OpenZeppelin, there is an error accours in Remix ide says that "Undeclared identifier". I wonder why, so here is my code ;
pragma solidity ^0.8.9;
import '#openzeppelin/contracts/token/ERC721/ERC721.sol';
import '#openzeppelin/contracts/access/Ownable.sol';
import '#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol';
contract MintNft is ERC721, Ownable {
uint256 public mintPrice = 0.005 ether;
uint public totalSupply;
uint public maxSupply;
bool public isMintEnabled;
// Mapping for amount of minted nfts by an address
mapping(address => uint256) public mintedWallets;
constructor() payable ERC721('Pokemon Card', 'POKE') {
maxSupply = 20;
}
function toggleIsMintEnabled() external onlyOwner {
isMintEnabled = !isMintEnabled;
}
function setMaxSupply(uint256 _maxSupply) external onlyOwner {
maxSupply = _maxSupply;
}
function mint(string memory tokenURI) external payable {
require(isMintEnabled,"Minting is not enable");
require(mintedWallets[msg.sender] < 2, 'You have reached maximum mint number');
require(msg.value == mintPrice, "Wrong value");
require(maxSupply > totalSupply, "Sold Out ! ");
mintedWallets[msg.sender]++;
totalSupply++;
uint256 tokenId = totalSupply;
_safeMint(msg.sender, tokenId);
_setTokenURI(tokenId,tokenURI);
}
}
Thanks already.
Okay i figured out that i forget to implement ERC721URIStorage when naming my contract.
i changed it to contract MintNft is ERC721URIStorage, Ownable
Now it works fine.

How do I accept an ERC20 token for Nft mint payment instead of ETH

How do I accept an ERC 20 token for minting NFTS on my smart contract. I’m currently paying for the minting using ETH, and I will like to accept another ERC 20 token.
You can change your mint function in order to accept the preferred token type as payment. And in order to prevent paying gas in eth, you can use biconomy forward.Check out their docs.
https://docs.biconomy.io/products/enable-paying-gas-in-erc20
You need a reference from the NFT contract to your token contract.
Let's say we have these two contracts: NFTContract, TokenContract.
contract NFTContract {
TokenContract tokenContract;
...
mint() {
tokensContract.transfer(msg.sender(), addressReceiver, tokensToSend);
...
}
}
contract TokenContract {
transfer(sender, receiver, balance) {}
}
You can check an example of how I did this in my repo I'm developing for my thesis.
https://github.com/NickVanzo/Contracts_For_Thesis
Maybe it will work for you but be careful you can take errors for solidity versions.
pragma solidity ^0.8.9;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
contract LSTNFT is ERC721, ERC721Burnable, Ownable {
uint256 public cost;
uint256 maxSupply = 20;
uint256 maxMintAmountPerTx = 2;
// address of the ERC-20 contract
address public erc20Contract = "ERC-20 address is here";
// instance of the ERC-20 contract
ERC20 public erc20;
constructor() ERC721("Lestonz NFT", "LSTN") {
erc20 = ERC20(erc20Contract);
}
function _baseURI() internal pure override returns (string memory) {
return "ipfs://your ipfs url";
}
modifier mintPriceCompliance(uint256 _mintAmount) {
if (msg.sender != owner()) {
require(msg.value >= cost * _mintAmount, 'Insufficient funds!');
}
_;
}
function mint(uint256 _mintAmount) public payable mintPriceCompliance(_mintAmount) {
require(erc20.balanceOf(msg.sender) >= msg.value, "Not enough ERC-20 tokens");
_safeMint(_msgSender(), _mintAmount);
}
function setCost(uint256 _cost) public onlyOwner {
cost = _cost;
}
}

Not able to purchase the NFT I've created on Rarible (ropsten testnet)

I have created a nft on Rarible ( ropsten test net) but looks like people are not able to buy it....can anyone help me with why this seems to be happenning ?
rarible NFT : nft-link
solidity contract:
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "./rarible/impl/RoyaltiesV2Impl.sol";
import "./rarible/royalties/contracts/LibPart.sol";
import "./rarible/royalties/contracts/LibRoyaltiesV2.sol";
contract RoyaltyNFT is ERC721, Ownable, RoyaltiesV2Impl {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdTracker;
constructor() ERC721("RoyaltyNFT", "ROYA") {}
function mint(address _to) public onlyOwner {
super._mint(_to, _tokenIdTracker.current());
_tokenIdTracker.increment();
}
function _baseURI() internal view virtual override returns (string memory) {
return "https://gateway.pinata.cloud/ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH";
}
function setRoyalties(uint _tokenId, address payable _royaltiesReceipientAddress, uint96 _percentageBasisPoints) public onlyOwner {
LibPart.Part[] memory _royalties = new LibPart.Part[](1);
_royalties[0].value = _percentageBasisPoints;
_royalties[0].account = _royaltiesReceipientAddress;
_saveRoyalties(_tokenId, _royalties);
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721) returns (bool) {
if(interfaceId == LibRoyaltiesV2._INTERFACE_ID_ROYALTIES) {
return true;
}
return super.supportsInterface(interfaceId);
}
}
I had followed a blog to create rarible NFT and i was able to do so but i was unable to sell it to other people as transfer could not be initiated by others.

Smart Contract NFT how to add price by code to whole items in collection?

Greeting,
Could you tell me how to add price for every item in collection hosted by OpenSea ?
So, I have working code, It created:
1.Collection name (from construct before deploy)
2.NFT symbol (from construct before deploy)
3.URI to ipfs (from construct before deploy ex: ipfs://QmQtP8RNjvcVtKqcPwukgckWF74ojBjzahVzE3qCCnqv4f/
My smart contract example:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Context.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/utils/math/SafeMath.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract NFT is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseURI;
string public baseExtension = ".json";
uint256 public cost = 10000000000000000;
uint256 public maxSupply = 10000;
uint256 public maxMintAmount = 100;
bool public paused = false;
mapping(address => bool) public whitelisted;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
mint(msg.sender, 5); // 5- for test
}
// 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) {
require(msg.value >= cost * _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 getCost() public view returns (uint256) {
return cost;
}
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 withdraw() public onlyOwner {
uint256 balance = address(this).balance;
payable(msg.sender).transfer(balance);
}
}
and my item json file example:
{
"description": "Test Description",
"external_url": "http://testurl.com",
"image": "ipfs://QmSrkLg3UR5AUthhCZfrK9nrX3fxJJ4aCJK7B99rUkCa72/4.png",
"name": "Test Name #4",
"symbol": "TNFT",
"collection": {
"name": "TestNFT123_321",
"family": ""
},
"date": 1643919095,
"attributes": {
"Story": "In Caffe",
"Company": "Test Company",
"Some": "thing else"
}
}
On the OpenSea I have created collection name with items, but, with active price button.
What I made wrong?
Thanks for help.
I investigated this issue, so:
Listing items on OpenSea could be with API endpoints (see OpenSea docs, and here).
OpenSea listing could be on mainnet or Rinkeby network only (as of today no Polygon, BSC ...)
There are a lot of clickers, which emulate add item, name, price on Polygon network.
Waiting for API V2 OpenSea =((