ethereumsoliditysmartcontractsbrownie

Gas estimation failed: 'invalid opcode: INVALID'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually


I adapted the code from this tutorial for my needs. It works fine at rinkeby network, but I am getting an error when I try to run it on Mumbai network.

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 {

    bytes32 internal keyHash;
    uint256 public fee;
    event requestedCollectible(address indexed senderAdd);

    uint256 public tokenCounter;

    struct Remedio { 
      string nome_medicamento;
      uint256 dosagem;
      string farmaceutica;
      string posologia;
   }   


    enum Breed{PUG, SHIBA_INU, ST_BERNARD}
    mapping(uint256 => address) public requestIdToSender;
    mapping(uint256 => Breed) public tokenIdToBreed;
    mapping(uint256 => Remedio) public tokenIdToRemedio;
    mapping(uint256 => uint256) public requestIdToTokenId;

    

    constructor() public
        ERC721("GeradorReceitasMedicas", "Receita")
    {
        
        tokenCounter = 0;
    }

    

    function createCollectible(string memory nomeMedicamento, uint256 dosagem, string memory farmaceutica, string memory posologia) 
    public returns (bytes32) {
        
        uint256 newItemId = tokenCounter;

        tokenCounter = tokenCounter + 1;

        Remedio memory newRemedio = Remedio({
           nome_medicamento: nomeMedicamento,
           dosagem: dosagem,
           farmaceutica: farmaceutica,
           posologia: 'posologia'
        });

        requestIdToSender[newItemId] = msg.sender;
        address receitaOwner = requestIdToSender[newItemId];

        _safeMint(receitaOwner, newItemId);

        tokenIdToRemedio[newItemId] = newRemedio;

        emit requestedCollectible(receitaOwner);

    }
    
    

}

LinkTokenInterface.sol:

pragma solidity ^0.6.6;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);
  function approve(address spender, uint256 value) external returns (bool success);
  function balanceOf(address owner) external view returns (uint256 balance);
  function decimals() external view returns (uint8 decimalPlaces);
  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
  function increaseApproval(address spender, uint256 subtractedValue) external;
  function name() external view returns (string memory tokenName);
  function symbol() external view returns (string memory tokenSymbol);
  function totalSupply() external view returns (uint256 totalTokensIssued);
  function transfer(address to, uint256 value) external returns (bool success);
  function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool success);
  function transferFrom(address from, address to, uint256 value) external returns (bool success);
}

DeployAdvanced.py:

from brownie import AdvancedCollectible, accounts, network, config
from scripts.helpful_scripts import fund_advanced_collectible

def main():
    print(config['wallets']['from_key'])
    dev = accounts.add(config['wallets']['from_key'])
    print(network.show_active())
    #print(config['networks'][network.show_active()]['host'])
    publish_source = False
    print(config['wallets']['from_key'])
    advanced_collectible = AdvancedCollectible.deploy(
        {"from": dev},
        publish_source=publish_source,
    )

    fund_advanced_collectible(advanced_collectible)

    return advanced_collectible

helpful_scripts.py:

from brownie import AdvancedCollectible, accounts, config, interface, network



def fund_advanced_collectible(nft_contract):
    dev = accounts.add(config['wallets']['from_key'])
    link_token = interface.LinkTokenInterface(
        config['networks'][network.show_active()]['link_token']
    )
    link_token.transfer(nft_contract, 1000000000000000000, {"from": dev})

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.1.1
  • OpenZeppelin/openzeppelin-contracts@3.4.0 compiler: solc: remappings:
    • '@chainlink=smartcontractkit/chainlink-brownie-contracts@1.1.1'
    • '@openzeppelin=OpenZeppelin/openzeppelin-contracts@3.4.0'

automatically fetch contract sources from Etherscan autofetch_sources: True dotenv: .env

set a custom mnemonic for the development network networks: default: development kovan:

vrf_coordinator: '0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9'
link_token: '0xa36085F69e2889c224210F603D836748e7dC0088'
keyhash: '0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4'
fee: 100000000000000000
oracle: '0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e'
jobId: '29fa9aa13bf1468788b7cc4a500a45b8'
eth_usd_price_feed: '0x9326BFA02ADD2366b30bacB125260Af641031331'   rinkeby:
vrf_coordinator: '0xb3dCcb4Cf7a26f6cf6B120Cf5A73875B7BBc655B'
link_token: '0x01be23585060835e02b77ef475b0cc51aa1e0709'
keyhash: '0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311'
fee: 100000000000000000
oracle: '0x7AFe1118Ea78C1eae84ca8feE5C65Bc76CcF879e'
jobId: '6d1bfe27e7034b1d87b5270556b17277'
eth_usd_price_feed: '0x8A753747A1Fa494EC906cE90E9f37563A8AF630e'
host: 'https://rinkeby.infura.io/v3/${WEB3_INFURA_PROJECT_ID}'   mumbai:
link_token: '0x326C977E6efc84E512bB9C30f76E30c160eD06FB'
eth_usd_price_feed: '0x0715A7794a1dc8e42615F059dD6e406A6594651A'   polygon-test:
link_token: '0x326C977E6efc84E512bB9C30f76E30c160eD06FB'
eth_usd_price_feed: '0x0715A7794a1dc8e42615F059dD6e406A6594651A'   binance:
# link_token: ??
eth_usd_price_feed: '0x9ef1B8c0E4F7dc8bF5719Ea496883DC6401d5b2e'   binance-fork:
eth_usd_price_feed: '0x9ef1B8c0E4F7dc8bF5719Ea496883DC6401d5b2e'   mainnet-fork:
eth_usd_price_feed: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'   matic-fork:
eth_usd_price_feed: '0xF9680D99D6C9589e2a93a78A04A279e509205945' wallets:   from_key: ${PRIVATE_KEY}   from_mnemonic: ${MNEMONIC}

settings: gas_limit: "100000000000"

When I run it on Rinkeby, I get (run command brownie run .\scripts\advancedCollectible\deploy_advanced.py --network rinkeby):

INFORMAÇÕES: não foi possível localizar arquivos para o(s) padrão(ões) especificado(s). Brownie v1.18.1 - Python development framework for Ethereum

ContratoNftProject is the active project.

Running 'scripts\advancedCollectible\deploy_advanced.py::main'... rinkeby Transaction sent: 0xf3cbcf650ab9b4408f8e795469ffa60a61f5943ab485ec133e3650fece7545db
Gas price: 1.499999222 gwei Gas limit: 2377218 Nonce: 67
AdvancedCollectible deployed at: 0x5D37fc76D54880F878a395755df5101B644B655a

C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\network\contract.py:1180: BrownieCompilerWarning: 0x5D37fc76D54880F878a395755df5101B644B655a: Locally compiled and on-chain bytecode do not match! warnings.warn( Transaction sent: 0x74a64ac1449a597584bbca8dc0947e80a6ad042ca68453da6e550a0dbbfe67da
Gas price: 1.499999221 gwei Gas limit: 56992 Nonce: 68
LinkToken.transfer confirmed Block: 10631644 Gas used: 51811 (90.91%)

When I run it on Mumbai, I get (run command brownie run .\scripts\advancedCollectible\deploy_advanced.py --network polygon-test):

INFORMAÇÕES: não foi possível localizar arquivos para o(s) padrão(ões) especificado(s). Brownie v1.18.1 - Python development framework for Ethereum

ContratoNftProject is the active project.

Running 'scripts\advancedCollectible\deploy_advanced.py::main'... polygon-test Transaction sent: 0x6915605b9dfb985b8ef078e3268a6b6e6e2e0b95d3d25ce8e5912c7a71db84d7
Gas price: 1.759579396 gwei Gas limit: 2377218 Nonce: 13
AdvancedCollectible.constructor confirmed Block: 26234140 Gas used: 2161108 (90.91%) AdvancedCollectible deployed at: 0xdbae4544699a953f2b28AFfBA77008Fd9eb1B4Cf

File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie_cli\run.py", line 51, in main return_value, frame = run( File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\project\scripts.py", line 103, in run return_value = f_locals[method_name](*args, **kwargs) File ".\scripts\advancedCollectible\deploy_advanced.py", line 16, in main fund_advanced_collectible(advanced_collectible) File ".\scripts\helpful_scripts.py", line 10, in fund_advanced_collectible link_token.transfer(nft_contract, 1000000000000000000, {"from": dev}) File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\network\contract.py", line 1710, in call return self.transact(*args) File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\network\contract.py", line 1583, in transact return tx["from"].transfer( File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\network\account.py", line 644, in transfer receipt, exc = self._make_transaction( File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\network\account.py", line 727, in _make_transaction
raise VirtualMachineError(e) from None File "C:\Users\p\AppData\Roaming\Python\Python39\site-packages\brownie\exceptions.py", line 93, in init raise ValueError(str(exc)) from None ValueError: Gas estimation failed: 'invalid opcode: INVALID'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.

Why am I getting this error on Mumbai Network? Is it possible to fix the error above?


Solution

  • Your brownie-config.yaml defines a link_token address on the Mumbai testnet. The fund_advanced_collectible Python function then tries to transfer this token from the dev address.

    From other context of your post, I was able to find that the dev address is 0x7cc6FA028dffa310445af40C3abEea61F8534d97.

    Mind that you shared the private key as part of the debug output, but did not share the dev address directly (which I was still able to derive from the key). I'm not sure whether that was intentional on your part, but if there were crypto with monetary value on the same address on mainnet, anyone could steal it using this private key. So I'd recomend you to consider this address compromised and never use it on mainnet.

    Anyway, the dev address does not own any LINK tokens on Mumbai testnet, which makes this part of the script fail:

    link_token.transfer(nft_contract, 1000000000000000000, {"from": dev})
    

    You can claim testnet LINK tokens from the Chainlink faucet: https://faucets.chain.link/mumbai