Brownie Package Manager¶
Brownie allows you to install other projects as packages. Some benefits of packages include:
- Easily importing and building upon code ideas written by others
- Reducing duplicated code between projects
- Writing unit tests that verify interactions between your project and another project
The Brownie package manager is available from the commandline:
$ brownie pm
Installing a Package¶
Brownie supports package installation from ethPM and Github.
Installing from Github¶
The easiest way to install a package is from a Github repository. Brownie considers a Github repository to be a package if meets the following criteria:
- The repository must have one or more tagged versions.
- The repository must include a
contracts/folder containing one or more Solidity or Vyper source files.
A repository does not have to implement Brownie in order to function as a package. Many popular projects using frameworks such as Truffle or Embark can be added as Brownie packages.
To install a package from Github you must use a package ID. A package ID is comprised of the name of an organization, a repository, and a version tag. Package IDs are not not case sensitive.
Installing from ethPM¶
The Ethereum Package Manager (ethPM) is a decentralized package manager used to distribute EVM smart contracts and projects.
At its core, an ethPM package is a JSON object containing the ABI, source code, bytecode, deployment data and any other information that combines together to compose the smart contract idea. The ethPM specification defines a schema to store all of this data in a structured JSON format, enabling quick and efficient transportation of smart contract ideas between tools and frameworks which support the specification.
To obtain an ethPM package, you must know both the package name and the address of the registry where it is available. This information is communicated through a registry URI. Registry URIs use the following format:
The Snake Charmers maintain an ethPM registry explorer where you can obtain registry URIs.
$ brownie pm install ethpm://zeppelin.snakecharmers.eth:firstname.lastname@example.org
$ brownie pm install ethpm://defi.snakecharmers.eth:email@example.com
Working with Packages¶
Viewing Installed Packages¶
brownie pm list to view currently installed packages. After installing all of the examples given above, the output looks something like this:
$ brownie pm list Brownie - Python development framework for Ethereum The following packages are currently installed: OpenZeppelin └─OpenZeppelinfirstname.lastname@example.org aragon └─aragon/aragonOS@4.0.0 zeppelin.snakecharmers.eth └─email@example.com defi.snakecharmers.eth └─firstname.lastname@example.org
Cloning a Package¶
brownie pm clone [path] to copy the contents of a package into another folder. The package will be cloned to the current directory if [path] is ommited. This is useful for exploring the filestructure of a package, or when you wish to build a project on top of an existing package.
To copy the Aragon package to the current folder:
$ brownie pm export aragon/aragonOS@4.0.0
Using Packages in your Project¶
Importing Sources from a Package¶
You can import sources from an installed package in the same way that you would a source within your project. The root path is based on the name of the package and can be obtained via
brownie pm list.
For example, to import
SafeMath from OpenZeppelin contracts:
You can modify the import path with the
remappings field in your project configuration file. See Remapping Installed Packages for more information.
Using Packages in Tests¶
pm fixture provides access to installed packages during testing. It returns a
Project object when called with a project ID:
def test_with_compound_token(pm): compound = pm('email@example.com').CToken
See the unit test documentation for more detailed information.
Declaring Project Dependencies¶
Dependencies are declared by adding a
dependencies field to your project configuration file:
dependencies: - aragon/aragonOS@4.0.0 - firstname.lastname@example.org
Brownie attempts to install any listed dependencies prior to compiling a project. This is useful when your project may be used outside of your local environment.