Python

導入 Chainlink 和 Openzeppelin 的問題

  • February 1, 2022

高級收藏契約

布朗尼配置

布朗尼執行腳本/advanced_collectible/deploy_advanced.py

目前嘗試執行腳本並在嘗試導入 chainlink 和 openzeppelin 合約時不斷遇到錯誤。不知道為什麼,我查看了 brownie pm list 以確保我也安裝了正確的版本。

任何意見,將不勝感激。謝謝!

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);
   }
}

來自 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/chainlink-brownie-contracts@1.0.2
 - OpenZeppelin/openzeppelin-contracts@3.4.0
compiler:
 solc:
   remappings:
     - '@chainlink=smartcontractkit/chainlink-brownie-contracts@1.0.2'
     - '@openzeppelin=OpenZeppelin/openzeppelin-contracts@3.4.0'

錯誤:

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";
^-----------------------------------------------------------^

更新

解決方案:將 AdvancedCollectible.sol 中的導入更正為以下內容:

pragma solidity 0.6.6;

import "OpenZeppelin/openzeppelin-contracts@3.4.0/contracts/token/ERC721/ERC721.sol";
import "smartcontractkit/chainlink-brownie-contracts@1.0.2/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);
   }
}

在您的 .sol 中brownie.config.yaml,您正在導入OpenZeppelin/openzeppelin-contracts@3.4.0,但在 .sol 中,您正在導入@oppenzeppelin/contracts/etc...。您應該按照配置中的說明導入依賴項。import "OpenZeppelin/openzeppelin-contracts@3.4.0/contracts/token/ERC721/ERC721.sol

OP 問題很清楚,他不能使用@openzeppelinimport 的原因是brownie.config.yaml文件名不正確。

編輯:根據文件:配置文件必須保存為brownie-config.yaml https://eth-brownie.readthedocs.io/en/stable/config.html

引用自:https://ethereum.stackexchange.com/questions/98289