问题描述
我正在处理一个 NFT 项目。我的合同文件夹中有我的 NFT 文件,要从中导入 nodemodules 中的 openzeppelin 文件。但是,编译器似乎建议 Context.sol 已在我的文件中声明。我检查了 Context.sol 文件,在给定的文件夹中似乎有很多,我该如何解决。
Error: DeclarationError: Identifier already declared.
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
^-------------------------------------------------------^
@openzeppelin/contracts/utils/Context.sol:15:2: The prevIoUs declaration is here
:
contract Context {
^ (Relevant source part starts here and spans across multiple lines)
NFT.sol
pragma solidity ^0.5.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract NFT is ERC721,Ownable {
address payable public _owner;
mapping (uint => bool) public sold;
mapping (uint => uint) public price;
event Purchase(address owner,uint price,uint id,string uri);
constructor() ERC721("Dapp University","DAPPU") public{
_owner = msg.sender;
}
function mint(string memory _tokenURI,uint _price) public onlyOwner returns (bool) {
uint _tokenId = totalSupply() + 1;
price[_tokenId] = _price;
_mint(address(this),_tokenId);
_setTokenURI(_tokenId,_tokenURI);
return true;
}
function buy(uint _id) external payable {
_validate(_id); //check req. for Trade
_Trade(_id); //swap nft for eth
emit Purchase(msg.sender,price[_id],_id,tokenURI(_id));
}
function _validate(uint _id) internal {
require(_exists(_id),"Error,wrong Token id"); //not exists
require(!sold[_id],Token is sold"); //already sold
require(msg.value >= price[_id],Token costs more"); //costs more
}
function _Trade(uint _id) internal {
_transfer(address(this),msg.sender,_id); //nft to user
_owner.transfer(msg.value); //eth to owner
sold[_id] = true; //nft is sold
}
}
Context.sol
pragma solidity ^0.5.0;
contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
解决方法
我找到了答案。无论您使用@OpenZeppilin 合约进行何种工作,都将面临这个问题。每个子文件夹中都有一个 Context.sol 文件来帮助独立的项目。但是,如此大量的 Context.sol 文件相互冲突,从而导致编译器出错。从抛出的错误中可以看出,我不得不追溯导入并意识到 Context.sol 正在被跟踪并从 GSN 文件夹而不是 Utils 文件夹导入,因此我重新更改了导入以从 utils 文件夹中获取它作为在这里看到。如果您使用的是
pragma solidity ^0.5.0;
import "@openzeppelin/contracts/utils/Context.sol";
// Change to utils folder instead of GSN folder and possibly for all clashing
// Context.sol files
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../../drafts/Counters.sol";
import "../../introspection/ERC165.sol";
contract ERC721 is Context,ERC165,IERC721 {
using SafeMath for uint256;
using Address for address;
using Counters for Counters.Counter;
// Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
// which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;