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

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.

Related

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.

Allow ERC20 token for minting ERC721 NFT

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";

Is there a way to check how many times an ERC721 token has been minted?

I am using the OpenZeppelin's ERC721 Library, is there was a way to get the count of the number of times a token has been minted.
Is there a built-in mapping or function to check that?
You can use the Enumerable extension. The totalSupply() function returns the currently existing amount of tokens (minted minus burned), which in some cases might not the same thing as the total amount of minted tokens.
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
/*
* `totalSupply()` (defined in ERC721Enumerable) returns 1
* even though 2 tokens were minted, but 1 was also burned
*/
contract MyCollection is ERC721Enumerable, ERC721Burnable {
constructor() ERC721("CollectionName", "Symbol") {
_mint(msg.sender, 1);
_burn(1);
_mint(msg.sender, 2);
}
// multiple parents define the same function
// overriding here just to point at the expected parent class
// related to the combination of `Burnable` and `Enumerable` in the same contract - not to `Enumerable` alone
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
return ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);
}
// same reason for overriding as above
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
return ERC721Enumerable.supportsInterface(interfaceId);
}
}
Or you can override the _beforeTokenTransfer() hook and create a custom counter that takes into account only minting and ignores burning.
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
/*
* `mintCounter` returns 2, ignores the burned tokens
*/
contract MyCollection is ERC721Enumerable, ERC721Burnable {
uint256 public mintCounter;
constructor() ERC721("CollectionName", "Symbol") {
_mint(msg.sender, 1);
_burn(1);
_mint(msg.sender, 2);
}
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override(ERC721, ERC721Enumerable) {
if (from == address(0)) {
mintCounter++;
}
return ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) {
return ERC721Enumerable.supportsInterface(interfaceId);
}
}

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;
}
}

Solidity calling contract with elevated permissions

I have two contracts, one for handling staking and one for minting a NFT. The flow I want is for the user to stake in frontend react app which will invoke the staking contract. The user will then be eligible to mint a NFT when staked.
Now the issue I am facing is that because the minting role is called from stakingExample contract, which requires the user to invoke this, but as it has a critical function (mint) of the other contract, it should be protected with permissions such that only StakingExample can call NFTExample contract.
Is there a way to allow the user to run NFTExample with elevated permissions temporary in smart contract?
Example of staking contract:
// SPDX-License-Identifier: unlicensed
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/access/AccessControl.sol";
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "#openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
contract StakingExample is AccessControl {
bytes32 public constant CONTRACT_ROLE = keccak256("CONTRACT_ROLE");
NFTExample public _NFTExample;
...
function someStakingFunction() {
// code that stakes and
// set some variable that tracks if user have minted
}
function claimNFT(uint256 _pid, string memory _tokenURI) public onlyRole(CONTRACT_ROLE) {
// checks if user have unclaimed NFT
if (haveUnclaimed) {
_NFTExample.mintItem(msg.sender, _tokenURI)
}
}
}
Example of NFT contract:
// SPDX-License-Identifier: unlicensed
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/access/AccessControl.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract CMRGachaSeedNFT is ERC721URIStorage, AccessControl, ERC721Enumerable {
bytes32 public constant CONTRACT_ROLE = keccak256("CONTRACT_ROLE");
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
...
// Only Contract Role can call mint item, which mint item and transfers it to user's address
function mintItem(address _address, string memory _tokenURI)
public
onlyRole(CONTRACT_ROLE)
returns (uint256)
{
// Do some checks
// Mint
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(_address, newItemId);
_setTokenURI(newItemId, _tokenURI);
return newItemId;
}
}
You need to add one function in staking contract which shows amount of the staking:
function showStakeAmount() external view returns(uint256){
//I don't know your codes about this but you need a mapping to store
//the stake amount of each user and here you return it but something like this:
return StakingAmountOfUsers(msg.sender);
}
Then you need an interface of the staking contract and its address, also make an modifier in NFT contract (Following changes must be added):
interface StakingInterface{
function showStakeAmount() external view returns(uint256);
}
contract CMRGachaSeedNFT is ERC721URIStorage, AccessControl, ERC721Enumerable {
uint256 AmountThatShouldBeStaked;
StakingInterface StakingContract;
constructor(address STAKING_CONTRACT_ADDRESS){
StakingContract = StakingInterface(STAKING_CONTRACT_ADDRESS);
}
modifier isStaked(){
require(StakingContract.showStakeAmount() > AmountThatShouldBeStaked, "You did not stake enough amount of X token");
_;
}
function mintItem(address _address, string memory _tokenURI)
public
onlyRole(CONTRACT_ROLE)
returns (uint256)
isStaked()
{
//Continue coding...
}
}