I am following Patrick Alphas tutorial using brownie https://youtu.be/M576WGiDBdQ

. I have a fund_and_withdrawl script that has been compiled . With that, I am trying to deploy a fundme contract on a local ganache… Whenever I deploy a script, I get a value error telling me I don’t have enough ETH.[![enter image description here][1]][1]

Are there any settings I should change. How high should my gas settings be ?

This is the FundMe.sol:

// SPDX-License-Identifier: MIT

// Smart contract that lets anyone deposit ETH into the contract
// Only the owner of the contract can withdraw the ETH
pragma solidity ^0.6.6;

// Get the latest ETH/USD price from chainlink price feed
import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
import "@chainlink/contracts/src/v0.6/vendor/SafeMathChainlink.sol";

contract FundMe {
    // safe math library check uint256 for integer overflows
    using SafeMathChainlink for uint256;
    //mapping to store which address depositeded how much ETH
    mapping(address => uint256) public addressToAmountFunded;
    // array of addresses who deposited
    address[] public funders;
    //address of the owner (who deployed the contract)
    address public owner;
    AggregatorV3Interface public priceFeed;
    // the first person to deploy the contract is
    // the owner
    constructor (address _priceFeed) public {  //#whatever parameter used will be our global price feed address
        priceFeed = AggregatorV3Interface(_priceFeed);
        owner = msg.sender;
    function fund() public payable {
        // 18 digit number to be compared with donated amount 
        uint256 minimumUSD = 50 * 10 ** 18;
        //is the donated amount less than 50USD?
        require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH!");
        //if not, add to mapping and funders array
        addressToAmountFunded[msg.sender] += msg.value;
    //function to get the version of the chainlink pricefeed
    function getVersion() public view returns (uint256){
        //AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
       return priceFeed.version();  // above ...<-- we don't need this....we are doing it with a global address
    function getPrice() public view returns(uint256){
        //AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
        (,int256 answer,,,) = priceFeed.latestRoundData();
         // ETH/USD rate in 18 digit 
         return uint256(answer * 10000000000);
    // 1000000000
    function getConversionRate(uint256 ethAmount) public view returns (uint256){
        uint256 ethPrice = getPrice();
        uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
        // the actual ETH/USD conversation rate, after adjusting the extra 0s.
        return ethAmountInUsd;
    function getEntranceFee() public view returns(uint256) {
        //minimu usd
        uint256 minimumUSD = 50 * 10**18;
        uint256 price = getPrice();
        uint256 precision = 1 *10*18 ;
        return (minimumUSD * precision) / price; 
    //modifier: https://medium.com/coinmonks/solidity-tutorial-all-about-modifiers-a86cf81c14cb
    modifier onlyOwner {
        //is the message sender owner of the contract?
        require(msg.sender == owner);
    // onlyOwner modifer will first check the condition inside it 
    // and 
    // if true, withdraw function will be executed 
    function withdraw() payable onlyOwner public {
        // If you are using version eight (v0.8) of chainlink aggregator interface,
    // you will need to change the code below to
    // payable(msg.sender).transfer(address(this).balance);

        //iterate through all the mappings and make them 0
        //since all the deposited amount has been withdrawn
        for (uint256 funderIndex=0; funderIndex < funders.length; funderIndex++){
            address funder = funders[funderIndex];
            addressToAmountFunded[funder] = 0;
        //funders array will be initialized to 0
        funders = new address[](0);

#/#/Here is 
brownie config:/#/

  # - <organization/repo>@<version>
  - smartcontractkit/chainlink-brownie-contracts@1.1.1
      - "@chainlink=smartcontractkit/chainlink-brownie-contracts@1.1.1"
dotenv: .env
    eth_usd_price_feed: "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e"
    verify: True
    verify: False
    verify: False 
  from_key: ${PRIVATE_KEY}

And here is fund_and_withdrawl.py:

from brownie import FundMe
from scripts.helpful_scripts import get_account 

def fund ():
    fund_me = FundMe[-1]
    account = get_account()
    entrance_fee = fund_me.getEntranceFee() 
    print(f"The current entry fee is {entrance_fee}")
    fund_me.fund({"from": account, "value": entrance_fee})
    #always compile any edits to your solidity code  ...
    #need a main function always..
def main():

And here is the .env file:


export PRIVATE_KEY=0x1bb...............
export WEB3_INFURA_PROJECT_ID=76fc7f4e41ec4b398b9b590c000b2d87

I got my helpful_scripts.py:

````from brownie import network, config, accounts, MockV3Aggregator
from web3 import Web3

LOCAL_BLOCKCHAIN_ENVIRONMENTS = [ "development", "ganache-local"]

STARTING_PRICE = 200000000000

def get_account():
    if network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        return accounts[0]
        return accounts.add(config["wallets"]["from_key"])
def deploy_mocks():
    print(f"The active  network is { network.show_active() }")
    print("Deploying Mocks.....")
    if len(MockV3Aggregator) <= 0: #list of all v3 aggregators we've deployed
        MockV3Aggregator.deploy(DECIMALS , Web3.toWei(STARTING_PRICE,"ether"), {"from": get_account()})
    print("Mocks Deployed") #use tge most recently deployed mock agregator

and lastly, the MockAgreggator.sol file:


// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV2V3Interface.sol";

 * @title MockV3Aggregator
 * @notice Based on the FluxAggregator contract
 * @notice Use this contract when you need to test
 * other contract's ability to read data from an
 * aggregator contract, but how the aggregator got
 * its answer is unimportant
contract MockV3Aggregator is AggregatorV2V3Interface {
  uint256 constant public override version = 0;

  uint8 public override decimals;
  int256 public override latestAnswer;
  uint256 public override latestTimestamp;
  uint256 public override latestRound;

  mapping(uint256 => int256) public override getAnswer;
  mapping(uint256 => uint256) public override getTimestamp;
  mapping(uint256 => uint256) private getStartedAt;

    uint8 _decimals,
    int256 _initialAnswer
  ) public {
    decimals = _decimals;

  function updateAnswer(
    int256 _answer
  ) public {
    latestAnswer = _answer;
    latestTimestamp = block.timestamp;
    getAnswer[latestRound] = _answer;
    getTimestamp[latestRound] = block.timestamp;
    getStartedAt[latestRound] = block.timestamp;

  function updateRoundData(
    uint80 _roundId,
    int256 _answer,
    uint256 _timestamp,
    uint256 _startedAt
  ) public {
    latestRound = _roundId;
    latestAnswer = _answer;
    latestTimestamp = _timestamp;
    getAnswer[latestRound] = _answer;
    getTimestamp[latestRound] = _timestamp;
    getStartedAt[latestRound] = _startedAt;

  function getRoundData(uint80 _roundId)
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    return (

  function latestRoundData()
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    return (

  function description()
    returns (string memory)
    return "v0.6/tests/MockV3Aggregator.sol";

// MockOracle
// Function signatures, event signatures, log topics
  • Could you please copy-paste the code as opposed to using a screenshot? This is hard to debug in it's current state. Jun 1 at 12:44
  • Hi @Patrick Collins. I just copied and pasted my entire code from all of my 6 files so far ...the formatting isn't the best, but I have left off at 5:40 on your video tutorial. I am learning as I go... Jun 2 at 2:35
  • Hi @PatrickCollins . Is it also possible to change the gas parameters in brownie.ganache like in the remix tutorial ? Maybe there is, but I haven't gotten far in your video,,,, Jun 3 at 1:30
  • Hi Patrick. I got what I wanted : BrownieFundMeProject is the active project. Running 'scripts/fund_and_withdrawl.py::main'... 25000000000000001 The current entry fee is 25000000000000001 Funding Transaction sent: 0x05639dc31cda3273d2c810e7124d855260f7ff8f0389063488cc9820179af36a Gas price: 2.0 gwei Gas limit: 99258 Nonce: 5 FundMe.fund confirmed Block: 6 Gas used: 90235 (90.91%) Jun 4 at 20:08
  • I am scratching my head. I am not too sure what I had input incorrectly...I guess my ganache accounts might not have had enough gas.... Jun 4 at 20:09

1 Answer 1


Somehow, I reset my ganache and restarted the contract calls. I also forgot to add this correction MockV3Aggregator.deploy(DECIMALS, STARTING_PRICE, {"from": get_account()}) ....

And I got what I wanted...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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