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

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

Related

DeclarationError: Identifier not found or not unique. --> project:/contracts/"".sol:26:23: | 26 | function initialize() initializer public

When running npx truffle compile, i get the above error message.
I am trying to transition an NFT smart contract into upgradeable form and have imported the relevant source codes. It deploys to testnet fine, but when replacing the constructor with "function Initialize() initializer pubic {" i get the above error message.
Can someone help?
I also get an "Identifier not found or not unique" by my "mapping(address=>bool) private _operatorEnabled;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
function initialize() initializer public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digest(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}
I tried to change the initializer function around a bit, inline with onlyInitializing functionality https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v4.4.1
But that also returned a similar error regarding identifier not found or not unique
There were a few problems with the code:
there needs to be a constructor function that sets the token name and symbol (inherited from ERC721 contract)
the initialize function should not also have the word "initializer" in the function declaration
The code will work if with just the above, but there are warnings regarding the overlapping of your function named "digest" with the name "digest" of various input parameters and variables defined within a few functions. Easiest way to solve this is to change the function name
updated code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
constructor() ERC721("BasicNFT", "BNFT") {}
function initialize() public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digestDifferentName(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}
As a general rule of thumb, upgradeable contracts cannot contain Constructors.
See https://docs.openzeppelin.com/learn/upgrading-smart-contracts
I have added "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
and inherited from this in the contract declaration, which now doesn't return the initial error message.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/security/Pausable.sol";
import "#openzeppelin/contracts/access/AccessControl.sol";
import "#openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
abstract contract ERC721CarbonAsset is ERC721URIStorage, Pausable, AccessControl, Initializable {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Base URI
string private _baseUri;
address _forwarder;
mapping(uint256 => string) private _digests;
mapping(uint256 => string) private _infoRoots;
// Addresses under operator control
mapping(address => bool) private _operatorEnabled;
function initialize() initializer public {
// constructor() public ERC721("", "") Pausable() {
_baseUri = "";
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(PAUSER_ROLE, msg.sender);
_setupRole(MINTER_ROLE, msg.sender);
_setupRole(BURNER_ROLE, msg.sender);
_setupRole(OPERATOR_ROLE, msg.sender);
}
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* #dev See {ERC20-_beforeTokenTransfer}.
* Taken from ERC20Pausable
*
* Requirements:
*
* - the contract must not be paused.
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {
super._beforeTokenTransfer(from, to, amount);
require(!paused(), "ERC721Pausable: token transfer while paused");
}
function mint(address to, uint256 tokenId, string memory tokenUri, string memory digest) public onlyRole(MINTER_ROLE) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenUri);
_digests[tokenId] = digest;
}
function burn(uint256 tokenId) public onlyRole(BURNER_ROLE) {
_burn(tokenId);
}
function setBaseURI(string memory uri) external onlyRole(OPERATOR_ROLE) {
_baseUri = uri;
}
/**
* #dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overriden in child contracts.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseUri;
}
function infoRoot(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _infoRoot = _infoRoots[tokenId];
// If there is no infoRoot set, return an empty string.
if (bytes(_infoRoot).length == 0) {
return "";
}
return _infoRoot;
}
function setInfoRoot(uint256 tokenId, string memory _infoRoot) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_infoRoots[tokenId] = _infoRoot;
}
function digest(uint256 tokenId) external view virtual returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory digest = _digests[tokenId];
// If there is no digest set, return an empty string.
if (bytes(digest).length == 0) {
return "";
}
return digest;
}
function setDigest(uint256 tokenId, string memory digest) external onlyRole(OPERATOR_ROLE) whenNotPaused() {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_digests[tokenId] = digest;
}
// Operator initiatiated token transfer
function operatorTransfer(address recipient, uint256 tokenId) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
address owner = ownerOf(tokenId);
require(isOperatorControlled(owner), "ERC721: sender not under operator control");
// Reset appoval
_approve(msg.sender, tokenId);
transferFrom(owner, recipient, tokenId);
return true;
}
// Address owner can enable their address for operator control
// Default state is operator disabled
function enableOperatorControl() external whenNotPaused() returns (bool) {
require(msgSender() != address(0), "ERC20: owner is a zero address");
require(!isOperatorControlled(msgSender()), "ERC20: owner already under operator control");
_operatorEnabled[msgSender()] = true;
return true;
}
// Operator role can remove operator control from an address
function disableOperatorControl(address owner) external onlyRole(OPERATOR_ROLE) whenNotPaused() returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
require(isOperatorControlled(owner), "ERC721: owner not under operator control");
_operatorEnabled[owner] = false;
return true;
}
function isOperatorControlled(address owner) public view returns (bool) {
require(owner != address(0), "ERC721: owner is a zero address");
return _operatorEnabled[owner];
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
function msgSender() internal view returns(address sender) {
if(msg.sender == _forwarder) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
}
} else {
sender = msg.sender;
}
return sender;
}
function setForwarder(address forwarder) external onlyRole(OPERATOR_ROLE) returns (bool) {
_forwarder = forwarder;
return true;
}
function getForwarder() external view returns (address) {
return _forwarder;
}
}

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 =((

Contract "Coin" should be marked as abstract

i want to create a token on ERC-20 network.
i want to inheritance from interface in my contract .
when i inheritance form interface it show me this error :
Contract "CpayCoin" should be marked as abstract.
solc version in truffle :
compilers: {
solc: {
version: "0.8.10", // Fetch exact version from solc-bin (default: truffle's version)
docker: false, // Use "0.5.1" you've installed locally with docker (default: false)
settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: false,
runs: 200
},
evmVersion: "byzantium"
}
}
},
whats the problem ? how can i solve this problem ???
this is my interface :
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
interface IERC20 {
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount)
external
returns (bool);
function allowance(address owner, address spender)
external
view
returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
contract :
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
import "./IERC-20.sol";
contract CpayCoin is IERC20 {
//mapping
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
//Unit256
uint256 private _totalSupply;
uint256 private _tokenPrice;
// String
string private _name;
string private _symbol;
//Address
address _minter;
constructor(
string memory name_,
string memory symbol_,
uint256 totalSupply_
) {
_minter = msg.sender;
_balances[_minter] = _totalSupply;
_tokenPrice = 10**15 wei;
_name = name_;
_symbol = symbol_;
_totalSupply = totalSupply_;
}
// Modifier
modifier onlyMinter() {
require(msg.sender == _minter, "Only Minter can Mint!");
_;
}
modifier enoughBalance(address adr, uint256 amount) {
require(_balances[adr] >= amount, "Not enough Balance!");
_;
}
modifier enoughValue(uint256 amount) {
require(msg.value == amount * _tokenPrice, "Not enough Value!");
_;
}
modifier checkZeroAddress(address adr) {
require(adr != address(0), "ERC20: mint to the zero address");
_;
}
// Functions
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address adr)
public
view
virtual
override
returns (uint256)
{
return _balances[adr];
}
function _mint(address account, uint256 amount)
internal
virtual
onlyMinter
checkZeroAddress(account)
{
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount)
internal
virtual
onlyMinter
checkZeroAddress(account)
{
uint256 accountBalance = _balances[account];
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply += amount;
emit Transfer(account, address(0), amount);
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
uint256 senderBalance = _balances[sender];
require(
senderBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
unchecked {
_balances[sender] = senderBalance - amount;
}
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
}
Solidity currently (v0.8) doesn't have a way to tell that a class (a contract) implements an interface. Instead, the is keyword is used to mark an inheritance, as "derives from".
So the CpayCoin is IERC20 expression marks the CpayCoin as a child and IERC20 as a parent - not as an interface.
The IERC20 (parent) defines few functions (e.g. decimals() and transfer()) that the CpayCoin (child) doesn't implement, which makes the CpayCoin an abstract class.
Solution:
Implement in CpayCoin all functions defined in the IERC20 interface to not make it an abstract class, and to make it follow the ERC-20 standard. Then you're free to remove the inheritance as it becomes redundant.
Or just remove the inheritance to not have any unimplemented function definitions (but then the contract won't follow the ERC-20 standard).
Mind that in your current code, the _transfer() internal function is unreachable. I'd recommend to implement a transfer() external function that invokes this internal _transfer().
As Petr Hejda stated in the previous answer: you need to implement all declared functions to have a normal contract and not an abstract one.
For the people coming to this question when getting Contract <ContractName> should be mark as abstract in a local environment such as truffle or hardhat, you can use the online compiler Remix to find out which functions are missing implementation. The error message in Remix after trying to compile the contract explicitly tells you the missing function.

Factory error The called function should be payable

I am using the Opensea Creatures repository (https://github.com/ProjectOpenSea/opensea-creatures.git) to make a Factory and create my ERC721 tokens. I have added the function _setTokenURI (newTokenId, metadataURI); in ERC721Tradable.sol to add the URI when doing mint but it gives me the following error:
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
Debug the transaction to get more information.
the files involved are these:
CreatureFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "./IFactoryERC721.sol";
import "./Creature.sol";
contract CreatureFactory is FactoryERC721, Ownable {
using Strings for string;
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
address public proxyRegistryAddress;
address public nftAddress;
address public lootBoxNftAddress;
string public baseURI = "https://terrorverso.herokuapp.com/api/token/";
/*
* Enforce the existence of only 100 OpenSea creatures.
*/
uint256 CREATURE_SUPPLY = 100;
/*
* Three different options for minting Creatures (basic, premium, and gold).
*/
uint256 NUM_OPTIONS = 3;
uint256 SINGLE_CREATURE_OPTION = 0;
uint256 MULTIPLE_CREATURE_OPTION = 1;
uint256 LOOTBOX_OPTION = 2;
uint256 NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION = 4;
constructor(address _proxyRegistryAddress, address _nftAddress) {
proxyRegistryAddress = _proxyRegistryAddress;
nftAddress = _nftAddress;
fireTransferEvents(address(0), owner());
}
function name() override external pure returns (string memory) {
return "Factory";
}
function symbol() override external pure returns (string memory) {
return "FACT";
}
function supportsFactoryInterface() override public pure returns (bool) {
return true;
}
function numOptions() override public view returns (uint256) {
return NUM_OPTIONS;
}
function transferOwnership(address newOwner) override public onlyOwner {
address _prevOwner = owner();
super.transferOwnership(newOwner);
fireTransferEvents(_prevOwner, newOwner);
}
function fireTransferEvents(address _from, address _to) private {
for (uint256 i = 0; i < NUM_OPTIONS; i++) {
emit Transfer(_from, _to, i);
}
}
function mint(uint256 _optionId, address _toAddress, string memory metadataURI) override public {
// Must be sent from the owner proxy or owner.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
assert( address(proxyRegistry.proxies(owner())) == _msgSender() || owner() == _msgSender() || _msgSender() == lootBoxNftAddress );
require(canMint(_optionId));
Creature openSeaCreature = Creature(nftAddress);
if (_optionId == SINGLE_CREATURE_OPTION) {
openSeaCreature.mintTo(_toAddress,metadataURI);
} else if (_optionId == MULTIPLE_CREATURE_OPTION) {
for (
uint256 i = 0;
i < NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION;
i++
) {
openSeaCreature.mintTo(_toAddress,metadataURI);
}
}
}
function canMint(uint256 _optionId) override public view returns (bool) {
if (_optionId >= NUM_OPTIONS) {
return false;
}
Creature openSeaCreature = Creature(nftAddress);
uint256 creatureSupply = openSeaCreature.totalSupply();
uint256 numItemsAllocated = 0;
if (_optionId == SINGLE_CREATURE_OPTION) {
numItemsAllocated = 1;
} else if (_optionId == MULTIPLE_CREATURE_OPTION) {
numItemsAllocated = NUM_CREATURES_IN_MULTIPLE_CREATURE_OPTION;
}
return creatureSupply < (CREATURE_SUPPLY - numItemsAllocated);
}
function tokenURI(uint256 _optionId) override external view returns (string memory) {
return string(abi.encodePacked(baseURI, Strings.toString(_optionId)));
}
/**
* Hack to get things to work automatically on OpenSea.
* Use transferFrom so the frontend doesn't have to worry about different method names.
*/
function transferFrom(
address _from,
address _to,
uint256 _tokenId,
string memory metadataURI
) public {
mint(_tokenId, _to, metadataURI);
}
/**
* Hack to get things to work automatically on OpenSea.
* Use isApprovedForAll so the frontend doesn't have to worry about different method names.
*/
function isApprovedForAll(address _owner, address _operator)
public
view
returns (bool)
{
if (owner() == _owner && _owner == _operator) {
return true;
}
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (
owner() == _owner &&
address(proxyRegistry.proxies(_owner)) == _operator
) {
return true;
}
return false;
}
/**
* Hack to get things to work automatically on OpenSea.
* Use isApprovedForAll so the frontend doesn't have to worry about different method names.
*/
function ownerOf(uint256 _tokenId) public view returns (address _owner) {
return owner();
}
}
ERC721Tradable.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "openzeppelin-solidity/contracts/token/ERC721/ERC721.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "./common/meta-transactions/ContentMixin.sol";
import "./common/meta-transactions/NativeMetaTransaction.sol";
contract OwnableDelegateProxy {}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
/**
* #title ERC721Tradable
* ERC721Tradable - ERC721 contract that whitelists a trading address, and has minting functionality.
*/
abstract contract ERC721Tradable is ContextMixin, ERC721Enumerable, NativeMetaTransaction, Ownable, ERC721URIStorage {
using SafeMath for uint256;
address proxyRegistryAddress;
uint256 private _currentTokenId = 0;
constructor(
string memory _name,
string memory _symbol,
address _proxyRegistryAddress
) ERC721(_name, _symbol) {
proxyRegistryAddress = _proxyRegistryAddress;
_initializeEIP712(_name);
}
/**
* #dev Mints a token to an address with a tokenURI.
* #param _to address of the future owner of the token
*/
function mintTo(address _to, string memory metadataURI) public onlyOwner {
uint256 newTokenId = _getNextTokenId();
_mint(_to, newTokenId);
_setTokenURI(newTokenId, metadataURI);
_incrementTokenId();
}
/**
* #dev calculates the next token ID based on value of _currentTokenId
* #return uint256 for the next token ID
*/
function _getNextTokenId() private view returns (uint256) {
return _currentTokenId.add(1);
}
/**
* #dev increments the value of _currentTokenId
*/
function _incrementTokenId() private {
_currentTokenId++;
}
function baseTokenURI() virtual public pure returns (string memory);
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {
super._burn(tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721, ERC721URIStorage)
returns (string memory)
{
return super.tokenURI(tokenId);
}
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);
}
/**
* Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.
*/
function isApprovedForAll(address owner, address operator)
override
public
view
returns (bool)
{
// Whitelist OpenSea proxy contract for easy trading.
ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
if (address(proxyRegistry.proxies(owner)) == operator) {
return true;
}
return super.isApprovedForAll(owner, operator);
}
/**
* This is used instead of msg.sender as transactions won't be sent by the original token owner, but by OpenSea.
*/
function _msgSender()
internal
override
view
returns (address sender)
{
return ContextMixin.msgSender();
}
}
and Creature.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC721Tradable.sol";
/**
* #title Creature
* Creature - a contract for my non-fungible creatures.
*/
contract Creature is ERC721Tradable{
constructor(address _proxyRegistryAddress)
ERC721Tradable("ExampleNFT", "EXA", _proxyRegistryAddress)
{}
function baseTokenURI() override public pure returns (string memory) {
return "https://example.com/api/token/";
}
function contractURI() public pure returns (string memory) {
return "https://creatures-api.opensea.io/contract/opensea-creatures";
}
}

What does LINK_TOKEN_POINTER do

I am trying to get chainlink to work on harmony one block chain, I am trying to deploy a testing contract extending chainlinkclient.sol to test out the setup but for some reason it won't deploy. I am wondering if it's because of the LINK_TOKEN_POINTER hardcoded to 0xC89bD4E1632D3A43CB03AAAd5262cbe4038Bc571. Does anyone know what that address is? Is it the same for all the ETH testnets (rinkeby, kovan, etc) and other chains as well?
I am trying to deploy the TestConsumer.sol contract onto the Harmony One chain but am getting an error. I was able to get it to work on Kovan.
I suspect it might be due to the LINK_TOKEN_POINTER. Does anyone know how I can get this to work?
pragma solidity 0.4.24;
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.4/ChainlinkClient.sol";
import "https://github.com/smartcontractkit/chainlink/evm-contracts/src/v0.4/vendor/Ownable.sol";
contract ATestnetConsumer is ChainlinkClient, Ownable {
uint256 constant private ORACLE_PAYMENT = 1 * LINK;
uint256 public currentPrice;
int256 public changeDay;
bytes32 public lastMarket;
event RequestEthereumPriceFulfilled(
bytes32 indexed requestId,
uint256 indexed price
);
event RequestEthereumChangeFulfilled(
bytes32 indexed requestId,
int256 indexed change
);
event RequestEthereumLastMarket(
bytes32 indexed requestId,
bytes32 indexed market
);
constructor() public Ownable() {
setPublicChainlinkToken();
}
function requestEthereumPrice(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumPrice.selector);
req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");
req.add("path", "USD");
req.addInt("times", 100);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumChange(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumChange.selector);
req.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
req.add("path", "RAW.ETH.USD.CHANGEPCTDAY");
req.addInt("times", 1000000000);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function requestEthereumLastMarket(address _oracle, string _jobId)
public
onlyOwner
{
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumLastMarket.selector);
req.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
string[] memory path = new string[](4);
path[0] = "RAW";
path[1] = "ETH";
path[2] = "USD";
path[3] = "LASTMARKET";
req.addStringArray("path", path);
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
}
function fulfillEthereumPrice(bytes32 _requestId, uint256 _price)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumPriceFulfilled(_requestId, _price);
currentPrice = _price;
}
function fulfillEthereumChange(bytes32 _requestId, int256 _change)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumChangeFulfilled(_requestId, _change);
changeDay = _change;
}
function fulfillEthereumLastMarket(bytes32 _requestId, bytes32 _market)
public
recordChainlinkFulfillment(_requestId)
{
emit RequestEthereumLastMarket(_requestId, _market);
lastMarket = _market;
}
function getChainlinkToken() public view returns (address) {
return chainlinkTokenAddress();
}
function withdrawLink() public onlyOwner {
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
}
function cancelRequest(
bytes32 _requestId,
uint256 _payment,
bytes4 _callbackFunctionId,
uint256 _expiration
)
public
onlyOwner
{
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
}
function stringToBytes32(string memory source) private pure returns (bytes32 result) {
bytes memory tempEmptyStringTest = bytes(source);
if (tempEmptyStringTest.length == 0) {
return 0x0;
}
assembly { // solhint-disable-line no-inline-assembly
result := mload(add(source, 32))
}
}
}
The LINK_TOKEN_POINTER is a contract that is hard-coded with pointers to the LINK token on various chains. This is so that the contract knows which LINK token to use.
For a chain like harmony, the LINK token pointer probably has not been added for that chain.
To get around this, you'll want to manually set the LINK token, like so:
constructor(address _link) public {
if (_link == address(0)) {
setPublicChainlinkToken();
} else {
setChainlinkToken(_link);
}
It looks like there isn't a LINK token on the Harmony chain yet, so you could deploy a dummy LINK token and point the address to that.