已在 Openzeppelin 中为 Context.sol 声明标识符

问题描述

我正在处理一个 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;
    }
    
}

解决方法

我找到了答案。无论您使用@O​​penZeppilin 合约进行何种工作,都将面临这个问题。每个子文件夹中都有一个 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;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...