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¶
The Project class is the top level container that holds all objects related to a Brownie project.
Project Methods¶
-
classmethod
Project.load() → None¶ Compiles the project source codes, instantiates
ContractContainerobjects, and populates the namespace.Projects are typically loaded via
brownie.project.load(), but if you have aProjectobject that was previously closed you can reload it using this method.
-
classmethod
Project.load_config() → None¶ Updates the configuration settings from the
brownie-config.yamlfile within this project’s root folder.
-
classmethod
Project.close(raises: bool = True) → None¶ Removes this object and the related
ContractContainerobjects from the namespace.>>> from brownie.project import TokenProject >>> TokenProject.close() >>> TokenProject NameError: name 'TokenProject' is not defined
-
classmethod
Project.dict()¶ Returns a dictionary of
ContractContainerobjects.>>> from brownie.project import TokenProject >>> TokenProject.dict() { 'Token': [], 'SafeMath': [] }
TempProject¶
TempProject is a simplified version of Project, used to hold contracts that are compiled via main.compile_sources. 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: Union[str, 'Path']) → Optional[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
Pathobject. ReturnsNoneif no project is found.Accepts a path as a str or a
Pathobject.>>> from brownie import project >>> Path('.').resolve() PosixPath('/my_projects/token/build/contracts') >>> project.check_for_project('.') PosixPath('/my_projects/token')
-
main.get_loaded_projects() → List¶ Returns a list of currently loaded
Projectobjects.>>> 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.from_ethpm(uri): Generates a
TempProjectfrom an ethPM package.uri: ethPM manifest URI. Format can be ERC1319 or IPFS.
-
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
Projectobject. The same object is also available from within theprojectmodule 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 Solidity source code string and returns a
TempProjectobject.>>> 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'>
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¶
The Build object is a 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 the Project object as Project._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']
-
classmethod
Build.expand_build_offsets(build_json)¶ Given a build json as a dict, expands the minified offsets to match the original source code.
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
REVERTorINVALIDoperation 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
TransactionReceiptwhen 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
solcversion. 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, minify=False, 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:dictin 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. IfNonethe compiler default is used.minify: Should contract sources be minified?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:dictin 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
dictof{'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:dictin 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
dictof{'version': ["path", "path", ..]}.
-
compiler.generate_input_json(contract_sources, optimize=True, runs=200, evm_version=None, minify=False)¶ 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
Internal Methods¶
-
compiler._format_link_references(evm)¶ Standardizes formatting for unlinked library placeholders within bytecode. Used internally to ensure that unlinked libraries are represented uniformly regardless of the compiler version used.
evm: The'evm'object from a compiler output JSON.
-
compiler._get_bytecode_hash(bytecode)¶ Removes the final metadata from a bytecode hex string and returns a hash of the result. Used to check if a contract has changed when the source code is modified.
-
compiler._expand_source_map(source_map)¶ Returns an uncompressed source mapping as a list of lists where no values are omitted.
>>> from brownie.project.compiler import expand_source_map >>> expand_source_map("1:2:1:-;:9;2:1:2;;;") [[1, 2, 1, '-'], [1, 9, 1, '-'], [2, 1, 2, '-'], [2, 1, 2, '-'], [2, 1, 2, '-'], [2, 1, 2, '-']]
-
compiler._generate_coverage_data(source_map_str, opcodes_str, contract_node, stmt_nodes, branch_nodes, has_fallback)¶ Generates the program counter and coverage maps that are used by Brownie for debugging and test coverage evaluation.
Takes the following arguments:
source_map_str: deployed source mapping as given by the compileropcodes_str: deployed bytecode opcodes string as given by the compilercontract_node: py-solc-ast contract node objectstmt_nodes: list of statement node objects fromcompiler.get_statment_nodesbranch_nodes: list of branch node objects fromcompiler.get_branch_nodeshas_fallback: Bool, does this contract contain a fallback method?
Returns:
pc_list: program counter mapstatement_map: statement coverage mapbranch_map: branch coverage map
-
compiler._get_statement_nodes(source_nodes)¶ Given a list of AST source node objects from py-solc-ast, returns a list of statement nodes. Used to generate the statement coverage map.
-
compiler._get_branch_nodes(source_nodes)¶ Given a list of AST source node objects from py-solc-ast, returns a list of branch nodes. Used to generate the branch coverage map.
brownie.project.ethpm¶
The ethpm module contains methods for interacting with ethPM manifests and registries. See The Ethereum Package Manager for more detailed information on how to access this functionality.
Module Methods¶
-
ethpm.get_manifest(uri)¶ Fetches an ethPM manifest and processes it for use with Brownie. A local copy is also stored if the given URI follows the ERC1319 spec.
uri: URI location of the manifest. Can be IPFS or ERC1319.
-
ethpm.process_manifest(manifest, uri)¶ Processes a manifest for use with Brownie.
manifest: ethPM manifesturi: IPFS uri of the package
-
ethpm.get_deployment_addresses(manifest, contract_name, genesis_hash)¶ Parses a manifest and returns a list of deployment addresses for the given contract and chain.
manifest: ethPM manifestcontract_name: Name of the contractgenesis_block: Genesis block hash for the chain to return deployments on. IfNone, the currently active chain will be used.
-
ethpm.get_installed_packages(project_path)¶ Returns information on installed ethPM packages within a project.
project_path: Path to the root folder of the project
Returns:
[(project name, version), ..]of installed packages[(project name, version), ..]of installed-but-modified packages
-
ethpm.install_package(project_path, uri, replace_existing)¶ Installs an ethPM package within the project.
project_path: Path to the root folder of the projecturi: manifest URI, can be erc1319 or ipfsreplace_existing: if True, existing files will be overwritten when installing the package
Returns the package name as a string.
-
ethpm.remove_package(project_path, package_name, delete_files)¶ Removes an ethPM package from a project.
project_path: Path to the root folder of the projectpackage_name: name of the packagedelete_files: ifTrue, source files related to the package are deleted. Files that are still required by other installed packages will not be deleted.
Returns a boolean indicating if the package was installed.
-
ethpm.create_manifest(project_path, package_config, pin_assets=False, silent=True)¶ Creates a manifest from a project, and optionally pins it to IPFS.
project_path: Path to the root folder of the projectpackage_config: Configuration settings for the manifestpin_assets: ifTrue, all source files and the manifest will be uploaded onto IPFS via Infura.
Returns:
(generated manifest, ipfs uri of manifest)
-
ethpm.verify_manifest(package_name, version, uri)¶ Verifies the validity of a package at a given IPFS URI.
package_name: Package nameversion: Package versionuri: IPFS uri
Raises
InvalidManifestif the manifest is not valid.
-
ethpm.release_package(registry_address, account, package_name, version, uri)¶ Creates a new release of a package at an ERC1319 registry.
registry_address: Address of the registryaccount:Accountobject used to broadcast the transaction to the registrypackage_name: Name of the packageversion: Package versionuri: IPFS uri of the package
Returns the
TransactionReceiptof the registry call to release the package.
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:Projectobject 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¶
The Sources object provides access to the contracts/ files for a specific project. It is instantiated automatically when a project is opened, and available within the Project object as Project._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.
namecan 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 list of contract source paths for the active project.
>>> from brownie.project import sources >>> sources.get_path_list() ['contracts/Token.sol', 'contracts/SafeMath.sol']
-
classmethod
Sources.get_contract_list()¶ Returns a list of contract names for the active project.
>>> from brownie.project import sources >>> sources.get_contract_list() ['Token', 'SafeMath']
-
classmethod
Sources.get_source_path(contract_name)¶ Returns the path to the file where a contract is located.
>>> from brownie.project import sources >>> sources.get_source_path('Token') 'contracts/Token.sol'
-
classmethod
Sources.expand_offset(contract_name, offset)¶ Converts a minified offset to one that matches the current source code.
>>> from brownie.project import sources >>> sources.expand_offset("Token", [1258, 1466]) (2344, 2839)
Module Methods¶
-
sources.minify(source)¶ Given contract source as a string, returns a minified version and an offset map used internally to translate minified offsets to the original ones.
>>> from brownie.project import sources >>> token_source = sources.get('Token') >>> source.minify(token_source) "pragma solidity^0.5.0;\nimport"./SafeMath.sol";\ncontract Token{\nusing SafeMath for uint256; ..."
-
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_hash(source, contract_name, minified)¶ Returns a sha1 hash generated from a contract’s source code.