// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IWhitelist.sol";
{
errors: [
{
component: 'general',
errorCode: '2333',
formattedMessage: 'DeclarationError: Identifier already declared.\n' +
' --> IERC721Enumerable.sol:14:1:\n' +
' |\n' +
'14 | abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {\n' +
' | ^ (Relevant source part starts here and spans across multiple lines).\n' +
'Note: The previous declaration is here:\n' +
' --> IERC721Enumerable.sol:6:1:\n' +
' |\n' +
'6 | import "../ERC721.sol";\n' +
' | ^^^^^^^^^^^^^^^^^^^^^^^\n' +
'\n',
message: 'Identifier already declared.',
secondarySourceLocations: [Array],
severity: 'error',
sourceLocation: [Object],
type: 'DeclarationError'
}
],
sources: {
'@openzeppelin/ERC721.sol': { id: 0 },
'@openzeppelin/IERC721Enumerable.sol': { id: 1 },
'@openzeppelin/contracts/ERC721.sol': { id: 2 },
'@openzeppelin/contracts/IERC721Enumerable.sol': { id: 3 },
'@openzeppelin/contracts/access/IERC721Enumerable.sol': { id: 4 },
'@openzeppelin/contracts/access/Ownable.sol': { id: 5 },
'@openzeppelin/contracts/token/ERC721.sol': { id: 6 },
'@openzeppelin/contracts/token/ERC721/ERC721.sol': { id: 7 },
'@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol': { id: 8 },
'@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol': { id: 9 },
'@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol': { id: 10 },
'@openzeppelin/contracts/token/IERC721Enumerable.sol': { id: 11 },
'CryptoDevs.sol': { id: 12 },
'ERC721.sol': { id: 13 },
'IERC721Enumerable.sol': { id: 14 },
'IWhitelist.sol': { id: 15 }
}
}
Hi, yes I can see that the forum has similar topics but I don't really get it... so everytime I install openzeppelin contracts I should go and edit most of it just to use multiple ones?....
Please share ALL the relevant code (no, the above is insufficient for reproducing the problem).
CryptoDevs.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./IWhitelist.sol";
contract CryptoDevs is ERC721, Ownable {
string _baseTokenURI;
uint256 public _price = 0.01 ether;
bool public _paused;
uint8 public tokenIds;
uint8 _maxTokenIds = 10;
IWhitelist whitelist;
bool public presaleStarted;
uint256 public presaleEnded;
modifier onlyWhenNotPaused{
require(!_paused, "The presale is paused rn");
_;
}
constructor (string memory baseURI, address whitelistContract) ERC721('CryptoDevs', "CD"){
_baseTokenURI = baseURI;
whitelist = IWhitelist(whitelistContract);
}
function startPresale() public onlyOwner {
presaleStarted = true;
presaleEnded = block.timestamp + 5 minutes;
}
function presaleMint() public payable onlyWhenNotPaused{
require(presaleStarted && block.timestamp < presaleEnded, "Presale is not active rn");
require(whitelist.whitelistedAddresses(msg.sender), "You are not whitelisted");
require(msg.value >= _price, "Wrong amount of ether sent");
require(tokenIds < _maxTokenIds, "No NFTs left to mint");
tokenIds += 1;
_safeMint(msg.sender, tokenIds);
}
function mint() public payable onlyWhenNotPaused {
require(presaleStarted && block.timestamp >= presaleEnded, "Presale has not ended yet");
require(tokenIds < _maxTokenIds, "Exceed maximum Crypto Devs supply");
require(msg.value >= _price, "Ether sent is not correct");
tokenIds += 1;
_safeMint(msg.sender, tokenIds);
}
function _baseURI() internal view virtual override returns(string memory) {
return _baseTokenURI;
}
function setPaused(bool val) public onlyOwner{
_paused = val;
}
function withdraw() public onlyOwner {
address _owner = owner();
uint256 amount = address(this).balance;
(bool sent, ) = _owner.call{value: amount}("");
require(sent, "Failed to send Ether");
}
receive() external payable {}
fallback() external payable {}
}
index.ts
import fs from 'fs';
//@ts-ignore
import solc from 'solc';
import { JsonRpcProvider, ContractFactory, Wallet } from 'ethers';
import 'dotenv/config';
import { METADATA_URL, WHITELIST_CONTRACT_ADDRESS } from './config';
(async () => {
const source = fs.readFileSync('./contracts/CryptoDevs.sol', 'utf-8');
const findImports = () => {
const lines = source.split('\n');
for (let line of lines) {
if (/import "/i.test(line)) {
const neededPart = line.split('"')[1];
if (/@/.test(neededPart)) {
return {
contents: fs.readFileSync('./node_modules/' + neededPart, 'utf-8'),
};
} else {
return {
contents: fs.readFileSync('./contracts' + neededPart.slice(1)),
};
}
}
}
};
const input = {
language: 'Solidity',
sources: {
'CryptoDevs.sol': {
content: source,
},
},
settings: {
outputSelection: {
'*': {
'*': ['*'],
},
},
},
};
const contractsData = JSON.parse(solc.compile(JSON.stringify(input), { import: findImports }));
console.log(contractsData);
})();
Thank you
index.ts is in the root folder and
CryptoDevs.sol and IWhitelist.sol are in the ./contracts folder
IWhitelist.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
interface IWhitelist {
function whitelistedAddresses(address) external view returns (bool);
}
Amxx
June 14, 2023, 9:38am
7
Yevhen_Hrytsenko:
sources: {
'@openzeppelin/ERC721.sol': { id: 0 },
'@openzeppelin/IERC721Enumerable.sol': { id: 1 },
'@openzeppelin/contracts/ERC721.sol': { id: 2 },
'@openzeppelin/contracts/IERC721Enumerable.sol': { id: 3 },
'@openzeppelin/contracts/access/IERC721Enumerable.sol': { id: 4 },
'@openzeppelin/contracts/access/Ownable.sol': { id: 5 },
'@openzeppelin/contracts/token/ERC721.sol': { id: 6 },
'@openzeppelin/contracts/token/ERC721/ERC721.sol': { id: 7 },
'@openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol': { id: 8 },
'@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol': { id: 9 },
'@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol': { id: 10 },
'@openzeppelin/contracts/token/IERC721Enumerable.sol': { id: 11 },
'CryptoDevs.sol': { id: 12 },
'ERC721.sol': { id: 13 },
'IERC721Enumerable.sol': { id: 14 },
'IWhitelist.sol': { id: 15 }
}
IERC721Enumerable
is present twice:
once as @openzeppelin/contracts/IERC721Enumerable.sol
once as IERC721Enumerable.sol
You probably should not have that second file in your codebase
yes thank you. But I don't have any files not outside the @openzeppelin folder, I just installed it with npm and imported 2 files
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
but I found a workaround I just compile it with the Juan Blanco extension just by pressing f5 so I don't need any code to compile the contract and it works fine.. still it would be good to understand why such stuff happens but at least I can compile the contract....which is almost all I wanted)