Lesson 11: ImportError: cannot import name 'LinkToken' from 'brownie' #1357
-
|
I was doing the Patrick Collins tutorial link and got this error I have tried to uninstall and reinstall brownie but that didn't work. My code: AdvancedCollectible.sol // An NFT Contract
// Where the tokenURI can be one of 3 different dogs
// Randomly selected
// SPDX-License-Identifier: MIT
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;
bytes32 public keyhash;
uint256 public fee;
enum Breed {
PUG,
SHIBA_INU,
ST_BERNARD
}
mapping(uint256 => Breed) public tokenIdToBreed;
mapping(bytes32 => address) public requestIdToSender;
event requestedCollectible(bytes32 indexed requestId, address requester);
event breedAssigned(uint256 indexed tokenId, Breed breed);
constructor(
address _vrfCoordinator,
address _linkToken,
bytes32 _keyhash,
uint256 _fee
)
public
VRFConsumerBase(_vrfCoordinator, _linkToken)
ERC721("Dogie", "DOG")
{
tokenCounter = 0;
keyhash = _keyhash;
fee = _fee;
}
function createCollectible() public returns (bytes32) {
bytes32 requestId = requestRandomness(keyhash, fee);
requestIdToSender[requestId] = msg.sender;
emit requestedCollectible(requestId, msg.sender);
}
function fulfillRandomness(bytes32 requestId, uint256 randomNumber)
internal
override
{
Breed breed = Breed(randomNumber % 3);
uint256 newTokenId = tokenCounter;
tokenIdToBreed[newTokenId] = breed;
emit breedAssigned(newTokenId, breed);
address owner = requestIdToSender[requestId];
_safeMint(owner, newTokenId);
tokenCounter = tokenCounter + 1;
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
// pug, shiba inu, st bernard
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: caller is not owner no approved"
);
_setTokenURI(tokenId, _tokenURI);
}
}
deploy_and_create.py from scripts.helpful_scripts import (
get_account,
OPENSEA_URL,
get_contract,
fund_with_link,
)
from brownie import AdvancedCollectible, network, config
def deploy_and_create():
account = get_account()
# We want to be able to use the deployed contracts if we are on a testnet
# Otherwise, we want to deploy some mocks and use those
# Rinkeby
advanced_collectible = AdvancedCollectible.deploy(
get_contract("vrf_coordinator"),
get_contract("link_token"),
config["networks"][network.show_active()]["keyhash"],
config["networks"][network.show_active()]["fee"],
{"from": account},
)
fund_with_link(advanced_collectible.address)
creating_tx = advanced_collectible.createCollectible({"from": account})
creating_tx.wait(1)
print("New token has been created!")
return advanced_collectible, creating_tx
def main():
deploy_and_create()
helpful_scripts.py from brownie import accounts, network, config, LinkToken, VRFCoordinatorMock, Contract
from web3 import Web3
LOCAL_BLOCKCHAIN_ENVIRONMENTS = ["hardhat", "development", "ganache", "mainnet-fork"]
OPENSEA_URL = "https://testnets.opensea.io/assets/{}/{}"
BREED_MAPPING = {0: "PUG", 1: "SHIBA_INU", 2: "ST_BERNARD"}
def get_breed(breed_number):
return BREED_MAPPING[breed_number]
def get_account(index=None, id=None):
if index:
return accounts[index]
if network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
return accounts[0]
if id:
return accounts.load(id)
return accounts.add(config["wallets"]["from_key"])
contract_to_mock = {"link_token": LinkToken, "vrf_coordinator": VRFCoordinatorMock}
def get_contract(contract_name):
"""
This function will either:
- Get an address from the config
- Or deploy a Mock to use for a network that doesn't have the contract
Args:
contract_name (string): This is the name of the contract that we will get
from the config or deploy
Returns:
brownie.network.contract.ProjectContract: This is the most recently deployed
Contract of the type specified by a dictionary. This could either be a mock
or a 'real' contract on a live network.
"""
# link_token
# LinkToken
contract_type = contract_to_mock[contract_name]
if network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
if len(contract_type) <= 0:
deploy_mocks()
contract = contract_type[-1]
else:
contract_address = config["networks"][network.show_active()][contract_name]
contract = Contract.from_abi(
contract_type._name, contract_address, contract_type.abi
)
return contract
def deploy_mocks():
"""
Use this script if you want to deploy mocks to a testnet
"""
print(f"The active network is {network.show_active()}")
print("Deploying mocks...")
account = get_account()
print("Deploying Mock LinkToken...")
link_token = LinkToken.deploy({"from": account})
print(f"Link Token deployed to {link_token.address}")
print("Deploying Mock VRF Coordinator...")
vrf_coordinator = VRFCoordinatorMock.deploy(link_token.address, {"from": account})
print(f"VRFCoordinator deployed to {vrf_coordinator.address}")
print("All done!")
def fund_with_link(
contract_address, account=None, link_token=None, amount=Web3.toWei(0.3, "ether")
):
account = account if account else get_account()
link_token = link_token if link_token else get_contract("link_token")
funding_tx = link_token.transfer(contract_address, amount, {"from": account})
funding_tx.wait(1)
print(f"Funded {contract_address}")
return funding_txbrownie-config.yaml dependencies:
- OpenZeppelin/openzeppelin-contracts@3.4.0
- smartcontractkit/chainlink-brownie-contracts@1.1.1
compiler:
solc:
remappings:
- '@openzeppelin=OpenZeppelin/openzeppelin-contracts@3.4.0'
- '@chainlink=smartcontractkit/chainlink-brownie-contracts@1.1.1'
dotenv: .env
wallets:
from_key: ${PRIVATE_KEY}
networks:
development:
keyhash: '0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311'
fee: 100000000000000000
rinkeby:
vrf_coordinator: '0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B'
link_token: '0x01BE23585060835E02B77ef475b0Cc51aA1e0709'
keyhash: '0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311'
fee: 100000000000000000 # 0.1
I also have a .env file. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
Hello @BrysonHall If you already did this and still does not work, I have two extra suggestions:
|
Beta Was this translation helpful? Give feedback.
Hello @BrysonHall
I've reviewed your code and by far it's seems everything is ok on it, so as the error is about an import error did you copy and paste the
LinkToken.solinto contracts/test folder?https://github.com/PatrickAlphaC/nft-demo/blob/main/contracts/test/LinkToken.sol
After copying it you should also run
brownie compilein order to have it on you build folder.If you already did this and still does not work, I have two extra suggestions:
brownie compile..browniefolder and try again.