简体   繁体   中英

Error compiling OpenZeppelin imported contracts in truffle in vs code

I'm running a truffle project created with truffle init command in CMD. then I create a react app with npx reate-react-app in the same folder. I'm creating a NFT so I have installed OZ contracts in my react app with using npm install @openzeppelin/contracts command.

Now at this point whole project looks like this.

root folder

在此处输入图像描述

Package.json

在此处输入图像描述

and this is the complete truffle-config.js

/**
 * Use this file to configure your truffle project. It's seeded with some
 * common settings for different networks and features like migrations,
 * compilation and testing. Uncomment the ones you need or modify
 * them to suit your project as necessary.
 *
 * More information about configuration can be found at:
 *
 * trufflesuite.com/docs/advanced/configuration
 *
 * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
 * to sign your transactions before they're sent to a remote public node. Infura accounts
 * are available for free at: infura.io/register.
 *
 * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
 * public/private key pairs. If you're publishing your code to GitHub make sure you load this
 * phrase from a file you've .gitignored so it doesn't accidentally become public.
 *
 */

// const HDWalletProvider = require('@truffle/hdwallet-provider');
// const infuraKey = "fj4jll3k.....";
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
const path = require("path");
module.exports = {
  contracts_build_directory: path.join(__dirname, "client/src/contracts"),
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

  networks: {
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
     development: {
      host: "127.0.0.1",     // Localhost (default: none)
      port: 7545,            // Standard Ethereum port (default: none)
      network_id: "*",       // Any network (default: none)
     },
    // Another network with more advanced options...
    // advanced: {
    // port: 8777,             // Custom port
    // network_id: 1342,       // Custom network
    // gas: 8500000,           // Gas sent with each transaction (default: ~6700000)
    // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei)
    // from: <address>,        // Account to send txs from (default: accounts[0])
    // websocket: true        // Enable EventEmitter interface for web3 (default: false)
    // },
    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    // ropsten: {
    // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
    // network_id: 3,       // Ropsten's id
    // gas: 5500000,        // Ropsten has a lower block limit than mainnet
    // confirmations: 2,    // # of confs to wait between deployments. (default: 0)
    // timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
    // skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    // },
    // Useful for private networks
    // private: {
    // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
    // network_id: 2111,   // This network is yours, in the cloud.
    // production: true    // Treats this network as if it was a public net. (default: false)
    // }
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
       version: "0.6.1",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // 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"
      // }
    }
  },

  // Truffle DB is currently disabled by default; to enable it, change enabled: false to enabled: true
  //
  // Note: if you migrated your contracts prior to enabling this field in your Truffle project and want
  // those previously migrated contracts available in the .db directory, you will need to run the following:
  // $ truffle migrate --reset --compile-all

  db: {
    enabled: false
  }
};

in my solidity contract file, path is C:\Dapp\Pet-Shop-IPFS-React\contracts\PetShop.sol , I've imported the installed OZ ERC721 contract PetShop.js

pragma solidity >=0.4.22 <0.9.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

contract PetShop is ERC721 {
    
      uint256 public tokenId;
      uint256 public prevOwnerTokenID;
      address public owner;
      
      mapping(uint256 => uint256) public priceMapping;
      mapping(uint256 => string) tokenIdToOffchainContentHash;
      
      event PetGenerated(address, uint256, uint256, string);
      event BuyPet(uint256, address, address);
      event SuccessfulEtherWithdrawal(uint256, address, bool);
      
       constructor()
        ERC721("ShanBuilders", "SBRS")
        {
            owner = msg.sender;
        }
     
       function generatePet(uint256 _petPrice, string memory contentHash) public returns(bool) {
         
         require(msg.sender != address(0), "Please! Check back! Registeration should not be from zero address");
         require(msg.sender == owner, "Only contract owner can generate more pets");
         
         tokenId++;
         require(tokenId <= 16, "More than 16 pets is not allowed");
         
         priceMapping[tokenId] = _petPrice;
         tokenIdToOffchainContentHash[tokenId] = contentHash;
         _mint(owner, tokenId);
         emit PetGenerated(owner, tokenId, _petPrice, contentHash);
         return true;
       }
       
       function checkPrice(uint256 _tokenId) public view returns(uint256) {
           return priceMapping[_tokenId];
       }
       
       function checkHashForAToken(uint256 _tokenId) public view returns(string memory) {
           return tokenIdToOffchainContentHash[_tokenId];
       }
       
       function buyPet(uint256 _tokenId) public payable returns(bool, string memory) {
           
           prevOwnerTokenID = _tokenId;
           address buyer = msg.sender;
           address _owner = ownerOf(prevOwnerTokenID);
           
           require(buyer != address(0), "Should not be zero address");
           require(_exists(prevOwnerTokenID), "Invalid property Id, not registered");
           require(msg.value == checkPrice(prevOwnerTokenID), "Please Send The Required Value");
           
           withDraw(msg.value);
            _transfer(_owner, buyer, prevOwnerTokenID);
           emit BuyPet(_tokenId, _owner, buyer);
           return (true, "Succesful");
       }
       
       function withDraw(uint256 _amount) internal returns(bool) {
       
        address _owner = ownerOf(prevOwnerTokenID);
        require(_amount > 0, "Amount must be valid");
        
        payable(_owner).transfer(_amount);
        emit SuccessfulEtherWithdrawal(_amount, _owner, true);
        return true;
    }
     
}

this is Migration

const PetShop = artifacts.require("PetShop");

module.exports = function (deployer) {
  deployer.deploy(PetShop);
};

Q is after doing all this something went wrong that I didn't notice. when i run truffle compile it fails the compilation and throws error, 在此处输入图像描述

*** ParserError: Source "@openzeppelin/contracts/token/ERC721/ERC721.sol" not found: File import callback not supported***

How can I work around this issue, It will be great if someone could help me understand what this error says and why this is happening?

I have solved it in the following way,

@openzeppelin library . i installed it in the wrong place, in react, it should have been installed in the root folder, after installing @openzeppelin in root folder, it creates package-lock.json

compiler version as @openzeppelin's contracts using latest solidity version every time, for now it is 0.8.0, and the truffle current version was 5.2.0, and truffle using solidity version 0.5.0 or something between to 0.5.5, what did i do first install npm install solc@0.8.0 in root folder it updates package-lock.json like this

"solc": {
      "version": "0.8.0",
      "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.0.tgz",
      "integrity": "sha512-ypgvqYZhb/i5BM6cw9/5QkSlDJm/rLynsbWGP3kz6HeB6oNxPK6UMiB7jMr+tNVbQbBM/8l47vrI3XaDCHShjQ==",
      "requires": {
        "command-exists": "^1.2.8",
        "commander": "3.0.2",
        "follow-redirects": "^1.12.1",
        "fs-extra": "^0.30.0",
        "js-sha3": "0.8.0",
        "memorystream": "^0.3.1",
        "require-from-string": "^2.0.0",
        "semver": "^5.5.0",
        "tmp": "0.0.33"
      }

then update truffle to 0.5.3 using npm install -g truffle

Last step i did is to update truffle-config.js with the following:

compilers: {
    solc: {
       version: "0.8.0",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // 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"
      // }
    }
  },

that's it then run truffle compile , if it creates a contract folder in react/src and compiled successfully, there will be no error

const path = require("path");
module.exports = {
  contracts_build_directory: path.join(__dirname, "client/src/contracts"),
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM