deploy_mocks()

When deploying to local blockchain environments that are not forks (ganache-cli, ganacheUI), we need to deploy mock contracts of external contracts we import .

When deploying to Forked environments, no need for mocks. We will refer to existing deployments via their addresses on the respective chain we are forking.

Iteration 1

from brownie import FundMe
from brownie import network, config
from scripts.helpful_scripts import *
from scripts.helpful_scripts import LOCAL_BLOCKCHAIN_ENV

def deploy_fund_me():
    account = get_account()
    print(f"Deploying on ....{network.show_active()}")
    
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENV:
        price_feed_address = config["networks"][network.show_active()]["eth_usd_price_feed"]

    else: #deploy mock of price feed on internal chain: development
        deploy_mocks()
        price_feed_address = MockV3Aggregator[-1].address 

Here the external contract we need is the chainlink ETH/USD price feed contract to pass into AggregatorV3Interface.

We store chainlink's pricefeed contract's corresponding address for each live chain in brownie-config.yaml, under the variable: eth_usd_price_feed.

If we are deploying to rinkeby, price_feed_address == eth_usd_price_feed == 0x8A753747A1Fa494EC906cE90E9f37563A8AF630e

If deploying to internal chain, like development

deploymocks() is called -> stored in helpful_scripts.py

  • checks if a prior instance exists

  • if there are not prior deployments, it will deploy a fresh mock contract.

  • if a prior deployment exists, nothing is done within deploy_mocks(),

    • execution goes back deploy.py line15: price_feed_address = MockV3Aggregator[-1].address

Iteration 2: get_contract() + deploy_mocks()

from brownie import Lottery
from scripts.helpful_scripts import get_account, get_contract()

def deploy():
    account = get_account()
    Lottery.deploy(
        get_contract("ethusd_pricefeed").address, 
        get_contract("vrf_coordinator").address,
        get_contract("link_token").address,
        config["networks"][network.show_active()]["fee"],
        config["networks"][network.show_active()]["keyhash"],{"from":account}, 
        publish_source = config["networks"][network.show_active()].get("verify", False))
        # get verify key, if it doesnt exist - default to false.
    print(".....Deployed lottery!.....")
    
def main():
    deploy()

deploy_mocks() -> deploys mocks of each type every time its called within get_contracts()

when calling get_contacts(ethusd_pricefeed), in deploy.py

if len(contract_type) < 0: deploy_mocks() contract = contract_type[-1]

ALL mocks are deployed. and again each time we call get_contracts.

Explanation

Create a dictionary contract_to_mock, which stores the actual contract names as values, and our reference names as keys.

  • "eth_usd_price_feed": MockV3Aggregator

  • contract_type = MockV3Aggregator

getcontract takes a parameter, contract_name, which is passed into the dictionary to obtain the true name of the contract.

if deploying to LOCAL_BLOCKCHAIN_ENV

mocks will be required. check if prior mock exists, if it does not, deploy_mocks() is ran.

contract = contract_type[-1] -> contract = MockV3Aggregator[-1]

This creates a Contract container called contract which holds the mock contracts. To access their address: contract.address

Else: no mocks needed

Access deployed contracts via their livenet addresses and abi.

contract address is obtained from brownie-config.yaml contract_address = config["networks"][network.show_active()][contract_name]

Beyond the address, we will need the contract's ABI to know how to interact with it.

Together, we will create a brownie Contract container object:

contract = Contract.from_abi(contract_type.name, contract_address, contract_type.abi)

The ABI is accessed via contract_type.abi -> MockV3Aggregator.abi

The ABI is generated and stored in build/contracts/dependencies as part of our import statement setup.

Once we setup our import statements with the correct references and compile the project, brownie automatically downloads the necessary contracts as part of our dependencies and generates their ABI.

Last updated