Project API
The project
package contains methods for initializing, loading and compiling Brownie projects, and container classes to hold the data.
When Brownie is loaded from within a project folder, that project is automatically loaded and the ContractContainer
objects are added to the __main__
namespace. Unless you are working with more than one project at the same time, there is likely no need to directly interact with the top-level Project
object or any of the methods within this package.
Only the project.main
module contains methods that directly interact with the filesystem.
brownie.project.main
The main
module contains the high-level methods and classes used to create, load, and close projects. All of these methods are available directly from brownie.project
.
Project
- class brownie.project.main.Project
Top level container that holds all objects related to a Brownie project.
Project Methods
- classmethod Project.load()
Collects project source files, compiles new or updated contracts, instantiates
ContractContainer
objects, and populates the namespace.Projects are typically loaded via
project.load
, but if you have aProject
object that was previously closed you can reload it using this method.
- classmethod Project.load_config()
Updates the configuration settings from the
brownie-config.yaml
file within this project’s root folder.
- classmethod Project.close(raises=True)
Removes this object and the related
ContractContainer
objects from the namespace.>>> from brownie.project import TokenProject >>> TokenProject.close() >>> TokenProject NameError: name 'TokenProject' is not defined
- classmethod Project.dict()
Returns a dictionary of
ContractContainer
objects.>>> from brownie.project import TokenProject >>> TokenProject.dict() { 'Token': [], 'SafeMath': [] }
TempProject
- class brownie.project.main.TempProject
Simplified version of
Project
, used to hold contracts that are compiled viaproject.compile_source
. Instances of this class are not included in the list of active projects or automatically placed anywhere within the namespace.
Module Methods
- main.check_for_project(path)
Checks for an existing Brownie project within a folder and it’s parent folders, and returns the base path to the project as a
Path
object. ReturnsNone
if no project is found.Accepts a path as a str or a
Path
object.>>> from brownie import project >>> Path('.').resolve() PosixPath('/my_projects/token/build/contracts') >>> project.check_for_project('.') PosixPath('/my_projects/token')
- main.get_loaded_projects()
Returns a list of currently loaded
Project
objects.>>> from brownie import project >>> project.get_loaded_projects() [<Project object 'TokenProject'>, <Project object 'OtherProject'>]
- main.new(project_path='.', ignore_subfolder=False)
Initializes a new project at the given path. If the folder does not exist, it will be created.
Returns the path to the project as a string.
>>> from brownie import project >>> project.new('/my_projects/new_project') '/my_projects/new_project'
- main.from_brownie_mix(project_name, project_path=None, ignore_subfolder=False)
Initializes a new project via a template. Templates are downloaded from the Brownie Mix github repo.
If no path is given, the project will be initialized in a subfolder of the same name.
Returns the path to the project as a string.
>>> from brownie import project >>> project.from_brownie_mix('token') Downloading from https://github.com/brownie-mix/token-mix/archive/master.zip... 'my_projects/token'
- main.load(project_path=None, name=None)
Loads a Brownie project and instantiates various related objects.
project_path
: Path to the project. IfNone
, attempts to find one usingcheck_for_project('.')
.name
: Name to assign to the project. If None, the name is generated from the name of the project folder.
Returns a
Project
object. The same object is also available from within theproject
module namespce.>>> from brownie import project >>> project.load('/my_projects/token') [<Project object 'TokenProject'>] >>> project.TokenProject <Project object 'TokenProject'> >>> project.TokenProject.Token <ContractContainer object 'Token'>
- main.compile_source(source, solc_version=None, optimize=True, runs=200, evm_version=None)
Compiles the given source code string and returns a
TempProject
object.If Vyper source code is given, the contract name will be
Vyper
.>>> from brownie import compile_source >>> container = compile_source('''pragma solidity 0.4.25; contract SimpleTest { string public name; constructor (string _name) public { name = _name; } }''' >>> >>> container <TempProject object> >>> container.SimpleTest <ContractContainer object 'SimpleTest'>
- main.install_package(package_id)
Install a package.
See the Brownie Package Manager documentation for more information on packages.
package_id
: Package identifier
brownie.project.build
The build
module contains classes and methods used internally by Brownie to interact with files in a project’s build/contracts
folder.
Build
- class brownie.project.build.Build
Container that stores and manipulates build data loaded from the
build/contracts/
files of a specific project. It is instantiated automatically when a project is opened, and available within theProject
object asProject._build
.
>>> from brownie.project import TokenProject
>>> TokenProject._build
<brownie.project.build.Build object at 0x7fb74cb1b2b0>
Build Methods
- classmethod Build.get(contract_name)
Returns build data for the given contract name.
>>> from brownie.project import build >>> build.get('Token') {...}
- classmethod Build.items(path=None)
Provides an list of tuples in the format
('contract_name', build_json)
, similar to callingdict.items
. If a path is given, only contracts derived from that source file are returned.>>> from brownie.project import build >>> for name, data in build.items(): ... print(name) Token SafeMath
- classmethod Build.contains(contract_name)
Checks if a contract with the given name is in the currently loaded build data.
>>> from brownie.project import build >>> build.contains('Token') True
- classmethod Build.get_dependents(contract_name)
Returns a list of contracts that inherit or link to the given contract name. Used by the compiler when determining which contracts to recompile based on a changed source file.
>>> from brownie.project import build >>> build.get_dependents('Token') ['SafeMath']
Build Internal Methods
- classmethod Build._add(build_json)
Adds a contract’s build data to the container.
- classmethod Build._remove(contract_name)
Removes a contract’s build data from the container.
- classmethod Build._generate_revert_map(pcMap)
Adds a contract’s dev revert strings to the revert map and it’s
pcMap
. Called internally when adding a new contract.The revert map is dict of tuples, where each key is a program counter that contains a
REVERT
orINVALID
operation for a contract in the active project. When a transaction reverts, the dev revert string can be determined by looking up the final program counter in this mapping.Each value is a 5 item tuple of:
("path/to/source", (start, stop), "function name", "dev: revert string", self._source)
When two contracts have differing values for the same program counter, the value in the revert map is set to
False
. If a transaction reverts with this pc, the entire trace must be queried to determine which contract reverted and get the dev string from it’spcMap
.
Internal Methods
The following methods exist outside the scope of individually loaded projects.
- build._get_dev_revert(pc)
Given the program counter from a stack trace that caused a transaction to revert, returns the commented dev string (if any). Used by
TransactionReceipt
.>>> from brownie.project import build >>> build.get_dev_revert(1847) "dev: zero value"
- build._get_error_source_from_pc(pc)
Given the program counter from a stack trace that caused a transaction to revert, returns the highlighted relevent source code and the name of the method that reverted.
Used by
TransactionReceipt
when generating aVirtualMachineError
.
brownie.project.compiler
The compiler
module contains methods for compiling contracts, and formatting the compiled data. This module is used internally whenever a Brownie project is loaded.
In most cases you will not need to call methods in this module directly. Instead you should use project.load
to compile your project initially and project.compile_source
for adding individual, temporary contracts. Along with compiling, these methods also add the returned data to Project._build
and return ContractContainer
objects.
Module Methods
- compiler.set_solc_version(version)
Sets the
solc
version. If the requested version is not available it will be installed.>>> from brownie.project import compiler >>> compiler.set_solc_version("0.4.25") Using solc version v0.4.25
- compiler.install_solc(*versions)
Installs one or more versions of
solc
.>>> from brownie.project import compiler >>> compiler.install_solc("0.4.25", "0.5.10")
- compiler.compile_and_format(contract_sources, solc_version=None, optimize=True, runs=200, evm_version=None, silent=True, allow_paths=None)
Given a dict in the format
{'path': "source code"}
, compiles the contracts and returns the formatted build data.contract_sources
:dict
in the format{'path': "source code"}
solc_version
: solc version to compile with. IfNone
, each contract is compiled with the latest installed version that matches the pragma.optimize
: Toggle compiler optimizationruns
: Number of compiler optimization runsevm_version
: EVM version to target. IfNone
the compiler default is used.silent
: Toggle console verbosityallow_paths
: Import path, passed to solc as an additional path that contract files may be imported from
Calling this method is roughly equivalent to the following:
>>> from brownie.project import compiler >>> input_json = compiler.generate_input_json(contract_sources) >>> output_json = compiler.compile_from_input_json(input_json) >>> build_json = compiler.generate_build_json(input_json, output_json)
- compiler.find_solc_versions(contract_sources, install_needed=False, install_latest=False, silent=True)
Analyzes contract pragmas and determines which solc version(s) to use.
contract_sources
:dict
in the format{'path': "source code"}
install_needed
: ifTrue
, solc is installed when no installed version matches a contract pragmainstall_latest
: ifTrue
, solc is installed when a newer version is available than the installed onesilent
: enables verbose reporting
Returns a
dict
of{'version': ["path", "path", ..]}
.
- compiler.find_best_solc_version(contract_sources, install_needed=False, install_latest=False, silent=True)
Analyzes contract pragmas and finds the best version compatible with all sources.
contract_sources
:dict
in the format{'path': "source code"}
install_needed
: ifTrue
, solc is installed when no installed version matches a contract pragmainstall_latest
: ifTrue
, solc is installed when a newer version is available than the installed onesilent
: enables verbose reporting
Returns a
dict
of{'version': ["path", "path", ..]}
.
- compiler.generate_input_json(contract_sources, optimize=True, runs=200, evm_version=None, language='Solidity')
Generates a standard solc input JSON as a dict.
- compiler.compile_from_input_json(input_json, silent=True, allow_paths=None)
Compiles from an input JSON and returns a standard solc output JSON as a dict.
- compiler.generate_build_json(input_json, output_json, compiler_data={}, silent=True)
Formats input and output compiler JSONs and returns a Brownie build JSON dict.
input_json
: Compiler input JSON dictoutput_json
: Computer output JSON dictcompiler_data
: Additional compiler data to includesilent
: Toggles console verbosity
brownie.project.scripts
The scripts
module contains methods for comparing, importing and executing python scripts related to a project.
- scripts.run(script_path, method_name='main', args=None, kwargs=None, project=None)
Imports a project script, runs a method in it and returns the result.
script_path
: path of script to importmethod_name
: name of method in the script to runargs
: method argskwargs
: method kwargsproject
:Project
object that should available for import into the script namespace>>> from brownie import run >>> run('token') Running 'scripts.token.main'... Transaction sent: 0xeb9dfb6d97e8647f824a3031bc22a3e523d03e2b94674c0a8ee9b3ff601f967b Token.constructor confirmed - block: 1 gas used: 627391 (100.00%) Token deployed at: 0x8dc446C44C821F27B333C1357990821E07189E35
Internal Methods
- scripts._get_ast_hash(path)
Returns a hash based on the AST of a script and any scripts that it imports. Used to determine if a project script has been altered since it was last run.
path
: path of the script>>> from brownie.project.scripts import get_ast_hash >>> get_ast_hash('scripts/deploy.py') '12b57e7bb8d88e3f289e27ba29e5cc28eb110e45'
brownie.project.sources
The sources
module contains classes and methods to access project source code files and information about them.
Sources
- class brownie.project.sources.Sources
The
Sources
object provides access to thecontracts/
andinterfaces/
files for a specific project. It is instantiated automatically when a project is loaded, and available within theProject
object asProject._sources
.>>> from brownie.project import TokenProject >>> TokenProject._sources <brownie.project.sources.Sources object at 0x7fb74cb1bb70>
- classmethod Sources.get(name)
Returns the source code file for the given name.
name
can be a path or a contract name.>>> from brownie.project import sources >>> sources.get('SafeMath') "pragma solidity ^0.5.0; ..."
- classmethod Sources.get_path_list()
Returns a sorted list of contract source paths for the project.
>>> from brownie.project import sources >>> sources.get_path_list() ['contracts/SafeMath.sol', 'contracts/Token.sol', 'interfaces/IToken.sol']
- classmethod Sources.get_contract_list()
Returns a sorted list of contract names for the project.
>>> from brownie.project import sources >>> sources.get_contract_list() ['SafeMath', 'Token']
- classmethod Sources.get_interface_list()
Returns a sorted list of interface names for the project.
>>> from brownie.project import sources >>> sources.get_interface_list() ['IToken']
- classmethod Sources.get_interface_hashes()
Returns a dict of interface hashes in the form of
{'interfaceName': "hash"}
- classmethod Sources.get_interface_sources()
Returns a dict of interfaces sources in the form
{'path/to/interface': "source code"}
- classmethod Sources.get_source_path(contract_name)
Returns the path to the file where a contract or interface is located.
>>> from brownie.project import sources >>> sources.get_source_path('Token') 'contracts/Token.sol'
Module Methods
- sources.is_inside_offset(inner, outer)
Returns a boolean indicating if the first offset is contained completely within the second offset.
>>> from brownie.project import sources >>> sources.is_inside_offset([100, 200], [100, 250]) True
- sources.get_contracts(full_source)
Given a Solidity contract source as a string, returns a
dict
of source code for individual contracts.>>> from brownie.project.sources import get_contracts >>> get_contracts(''' ... pragma solidity 0.5.0; ... ... contract Foo { ... function bar() external returns (bool) { ... return true; ... } ... } ... ... library Bar { ... function baz(uint a, uint b) external pure returns (uint) { ... return a + b; ... } ... }''') { 'Foo': 'contract Foo {\n function bar() external returns (bool) {\n return true;\n }\n}', 'Bar': 'library Bar {\n function baz(uint a, uint b) external pure returns (uint) {\n return a + b;\n }\n}' }
- sources.get_pragma_spec(source, path=None)
Returns an NpmSpec object representing the first pragma statement found within a source file.
Raises
PragmaError
on failure. Ifpath
is notNone
, it will be included in the error string.