2

Advanced Collectible Contract

Brownie Config

brownie run scripts/advanced_collectible/deploy_advanced.py

Currently trying to run a script and keep running into an error when trying to import chainlink and openzeppelin contracts. Not sure why, I looked at brownie pm list to make sure I have the correct versions install as well.

Any advice would be appreciated. Thanks!

Code from AdvancedCollectible.sol:

pragma solidity 0.6.6;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";

contract AdvancedCollectible is ERC721, VRFConsumerBase{
    uint256 public tokenCounter;
    enum Breed{PUG, SHIBA_INU, ST_BERNARD}
    //add other things
    mapping(bytes32 => address) public requestIdToSender;
    mapping(bytes32 => string) public requestIdToTokenURI;
    mapping(uint256 => Breed) public tokenIdToBreed;
    mapping(bytes32 => uint256) public requestIdToTokenId;
    event requestedCollectible(bytes32 indexed requestId); 

    bytes32 internal keyHash;
    uint256 public fee;

    constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
    public
    VRFConsumerBase(_VRFCoordinator, _LinkToken)
    ERC721("Dogges", "DOGGE")
    {
        keyHash = _keyhash;
        fee = 0.1 * 10 ** 18; //0.1 LINK
    }
    function createCollectable(uint256 userProvidedSeed, string memory tokenURI) public returns (bytes32){
        bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
        requestIdToSender[requestId] = msg.sender;
        requestIdToTokenURI[requestId] = tokenURI;
        emit requestedCollectible(requestId);
    }
    function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override{
        address dogOwner = requestIdToSender[requestId];
        string memory tokenURI = requestIdToTokenURI[requestId];
        uint256 newItemId = tokenCounter;
        _safeMint(dogOwner, newItemId);
        _setTokenURI(newItemId, tokenURI);
        Breed dogBreed = Breed(randomNumber % 3); 
        tokenIdToBreed[newItemId] = dogBreed;
        requestIdToTokenId[requestId] = newItemId;
        tokenCounter = tokenCounter + 1;
    }
    function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _setTokenURI(tokenId, _tokenURI);
    }
}

Code from brownie.config.yaml

# exclude SafeMath when calculating test coverage
# https://eth-brownie.readthedocs.io/en/v1.10.3/config.html#exclude_paths
reports:
  exclude_contracts:
    - SafeMath
dependencies:
  - smartcontractkit/[email protected]
  - OpenZeppelin/[email protected]
compiler:
  solc:
    remappings:
      - '@chainlink=smartcontractkit/[email protected]'
      - '@openzeppelin=OpenZeppelin/[email protected]'

Error:

Brownie v1.14.3 - Python development framework for Ethereum

Compiling contracts...
  Solc version: 0.6.6
  Optimizer: Enabled  Runs: 200
  EVM Version: Istanbul
CompilerError: solc returned the following errors:

contracts/AdvancedCollectible.sol:3:1: ParserError: Source "@openzeppelin/contracts/token/ERC721/ERC721.sol" not found: File outside of allowed directories.
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
^--------------------------------------------------------^

contracts/AdvancedCollectible.sol:4:1: ParserError: Source "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol" not found: File outside of allowed directories.
import ""@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
^-----------------------------------------------------------^

Update

Solution: corrected imports in AdvancedCollectible.sol to the following:

pragma solidity 0.6.6;

import "OpenZeppelin/[email protected]/contracts/token/ERC721/ERC721.sol";
import "smartcontractkit/[email protected]/contracts/src/v0.6/VRFConsumerBase.sol";

contract AdvancedCollectible is ERC721, VRFConsumerBase{
    uint256 public tokenCounter;
    enum Breed{PUG, SHIBA_INU, ST_BERNARD}
    //add other things
    mapping(bytes32 => address) public requestIdToSender;
    mapping(bytes32 => string) public requestIdToTokenURI;
    mapping(uint256 => Breed) public tokenIdToBreed;
    mapping(bytes32 => uint256) public requestIdToTokenId;
    event requestedCollectible(bytes32 indexed requestId); 

    bytes32 internal keyHash;
    uint256 public fee;

    constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
    public
    VRFConsumerBase(_VRFCoordinator, _LinkToken)
    ERC721("Dogges", "DOGGE")
    {
        keyHash = _keyhash;
        fee = 0.1 * 10 ** 18; //0.1 LINK
    }
    function createCollectable(uint256 userProvidedSeed, string memory tokenURI) public returns (bytes32){
        bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
        requestIdToSender[requestId] = msg.sender;
        requestIdToTokenURI[requestId] = tokenURI;
        emit requestedCollectible(requestId);
    }
    function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override{
        address dogOwner = requestIdToSender[requestId];
        string memory tokenURI = requestIdToTokenURI[requestId];
        uint256 newItemId = tokenCounter;
        _safeMint(dogOwner, newItemId);
        _setTokenURI(newItemId, tokenURI);
        Breed dogBreed = Breed(randomNumber % 3); 
        tokenIdToBreed[newItemId] = dogBreed;
        requestIdToTokenId[requestId] = newItemId;
        tokenCounter = tokenCounter + 1;
    }
    function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721: transfer caller is not owner nor approved"
        );
        _setTokenURI(tokenId, _tokenURI);
    }
}
2
  • 1
    Could you paste your code and not pictures? Images aren't discoverable by search engines very well May 4, 2021 at 21:30
  • 1
    @patrickcollins just updated it - good idea, I'll keep that in mind for my future posts as well.
    – rizonpoint
    May 5, 2021 at 4:30

3 Answers 3

1

In your brownie.config.yaml, you are importing OpenZeppelin/[email protected], but in your .sol you are importing @oppenzeppelin/contracts/etc.... You should import the dependency as it says in your config. import "OpenZeppelin/[email protected]/contracts/token/ERC721/ERC721.sol

1

The OP issue is clear and the reason he can't use @openzeppelin import is the incorrect name of brownie.config.yaml file.

Edit: As per the documentation: The configuration file must be saved as brownie-config.yaml https://eth-brownie.readthedocs.io/en/stable/config.html

0

You can solve this without changing the code/import in the smart contract. (As changing that will fix Brownie, but will in turn wreck Truffle.)

Better to do remapping in brownie-config.yaml (And as stated in one of the answers, you had actually done this, but you named the brownie(-)config.ymal --> brownie(.)config.yaml

What was likely causing you error.

Example:

   compiler:
      solc:
        remappings:
          - "@openzeppelin=OpenZeppelin/[email protected]"

Note: the Openzeppelin version may vary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.