# Introduction

ethPM is the immutable package manager to consume, distribute, or manage any EVM smart contract system.&#x20;

An ethPM package represents the ***idea*** of a smart contract; from a single smart contract file, to a deployed contract instance, to a complex system of smart contracts, and everything in between.

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](http://ethpm.github.io/ethpm-spec/) 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.

ethPM has similar goals to most package managers found in any given programming language.&#x20;

1. Easily import and build upon core ideas written by others.
2. Distribute the ideas that you've written and/or deployed, making them easily consumable for tooling and the community at large.

## ethPM  Architecture

![](/files/-LioALJPiV9IYq-poNyU)

#### ethPM Registry

A registry is an on-chain datastore containing the data for released ethPM packages. Unlike traditional package managers which maintain a single, centralized package registry (eg. NPM, pypi) ethPM uses a federated model where everybody is required to deploy and maintain their own, permissioned package registry (or registries).&#x20;

In a world of trustless computation, trust is critical when it comes to consuming smart contract packages. A single line of malicious code in a `wallet` package could be the difference between a successful dapp or a successful hack. That is why you should ***NEVER*** import a package from a registry with an unknown or untrusted owner.&#x20;

That last sentence is important, it's worth repeating.

`ONLY USE PACKAGES FROM TRUSTED REGISTRIES!`

#### ethPM Package

An ethPM package is a combination of 3 elements that represent an immutable smart contract idea.&#x20;

* Package name
* Package version
* [Content-Addressed URI](/uris#content-addressed-uris)

These three elements are stored on-chain in an ethPM registry. [ERC1319](http://eips.ethereum.org/EIPS/eip-1319), which defines the registry API, enforces that once a package is released, it can never be re-released. The immutability of the blockchain and content-addressed URIs provide absolute certainty that once you interact with a `<wallet==1.2.0>` package from a certain registry, there is 100% certainty that it can never be modified.

#### ethPM Manifest

A manifest is the actual JSON file that contains the JSON object which defines an ethPM package. The JSON file is stored at the content-addressed URI defined in each package release.&#x20;

The bare minimum ethPM manifest defines three fields.&#x20;

```bash
{
    "name": "myPackage",
    "version": "1.0.0",
    "manifest": "ethpm/3"
}
```

Of course, this manifest does not represent a very useful package, so it is up to the creator of each manifest to include whatever `contractTypes`, `sources`, `deployments`, `compilers`, `meta` (data) or `buildDependencies` that are necessary to compose the desired smart contract idea.

Manifests may live on disk, but are intended to be produced and consumed programmatically and uploaded directly to a content-addressable storage network (e.g. [IPFS](https://ipfs.io/)).

#### ethPM's history

ethPM started out as the brainchild of Tim Coulter and Piper Merriam. Since its inception, it has undergone a breaking update from v1 to v2 in 2018, and another breaking update from v2 to v3 in 2020. The goals of these updates were to improve the specification to facilitate better cross-compatibility and advanced use-cases for ethPM packages. Currently, v3 tooling and support across libraries is still under development. If you would like to help contribute to and develop the ethPM ecosystem, [read here](/ethpm-developer-guide/ethpm-questions-and-support#whats-the-best-way-to-contribute).


# ethPM Specification

The [ethPM-Spec](http://ethpm.github.io/ethpm-spec/package-spec.html) defines the JSON schema for an ethPM manifest. ethPM manifests are only valid if they are tightly packed, with alphabetically sorted keys, and no trailing whitespaces. Since ethPM relies heavily upon content-addressed URIs, it's crucial that ethPM manifests are properly formatted, since the smallest edit will completely change the content's hash and integrity.

The formal definition of the ethPM-Spec can be found at its [documentation](http://ethpm.github.io/ethpm-spec/). Below is a brief overview of the different fields you can define in an ethPM manifest to capture the idea of your smart contract(s).

## "name"

The name of your ethPM package. Must conform to regex: `^[a-z][-a-z0-9]{0,255}$`

* Valid package names
  * `wallet`
  * `token-20`
  * `dao-123`
* Invalid package names
  * `1token`
  * `_mypackage`
  * `wallet.123`

## "version"

The version of your ethPM package. ethPM does not enforce a specific versioning scheme, but using [semver](https://semver.org/) is strongly encouraged.

* `"1.0.0"`
* `"2.0.0b3"`
* `"09.07.2019"`

## "manifest" (required)

The ethPM version of your manifest.

* `"ethpm/3"`

## "meta"

JSON object containing metadata for your package. Possible options include..

* `"authors": ["Alice", "Bob"]`
* `"license": "MIT"`
* `"description": "My awesome package."`
* `"keywords": ["solidity", "ethPM", "wallet"]`
* `"links": {"documentation": "readthedocs.com", "repository": "github.com", "website": "wallet.com"}`

## "contractTypes"

A field containing all of the contract types defined in a manifest. A contract type is the fundamental unit of an ethPM package, and maps 1-to-1 every defined contract in Solidity (`contract ContractName {}`).  Two contracts are of the same contract type if they have the same bytecode. For each contract type in `"contractTypes"` ,  packages have the option to include the following properties

* `"contractName"`
* `"sourceId"`
* `"deploymentBytecode"`
* `"runtimeBytecode"`
* `"abi"`
* `"devdoc"`
* `"userdoc"`

## "compilers"

An array of compiler information objects, describing the various compilers, their versions and settings, that were used to generate contract assets found in this package.

## "sources"

This field contains content-addressed URIs for smart contracts composing the contract types defined in a manifest. Sources can be included in a package as either the entire source contract, inlined as a single string **or** a content-addressed URI where the source contract can be found.

While the `sources` field must contain all smart contracts necessary to compile the defined `contractTypes` in the manifest, the `sources` field is not limited to just smart contracts, and can contain deployment scripts or other files that would be useful to interact with the package's smart contract idea.

## "deployments"

This field contains the deployment data for instances of deployed contract types. This field can contain references to contract deployments on different blockchains. [Blockchain URIs](/uris#blockchain-uris) are used to distinguish between the different blockchain networks. For each deployment, the following fields are available.

* `"contractType"` (required)
* `"address"` (required)
* `"transaction"`
* `"block"`
* `"runtimeBytecode"`
* `"compiler"`

## "buildDependencies"

Content-addressed URIs for any ethPM packages that a manifest depends upon.


# ERC1319: Package Registry Standard

An ethPM registry is an on-chain datastore for package releases. For each package release, three pieces of information are committed to storage:

* a package name
* a package version
* the content-addressed URI associated with the package's manifest.

[ERC1319](http://eips.ethereum.org/EIPS/eip-1319) was written to define the API for an on-chain ethPM registry. It is the minimum feasible API for a registry to interoperate with various ethPM tooling. It is encouraged for people to build their own registry implementations that extend upon the standard to support any kind of specialized behavior.

#### Reference Registry Implementations

There are a couple different implementations of ERC1319 available.&#x20;

* [Escape-Truffle](https://github.com/ethpm/escape-truffle/)
  * Solidity implementation with release deletion (but prevents re-releasing the same package version)
* [Simple Registry](https://github.com/ethpm/solidity-registry)
  * Solidity implementation without release deletion
* Vyper (experimental)
  * [with release deletion](https://github.com/ethereum/web3.py/blob/master/ethpm/assets/vyper_registry/registry_with_delete.vy)
  * [without release deletion](https://github.com/ethereum/web3.py/blob/master/ethpm/assets/vyper_registry/registry.vy)

#### Deploying your own registry.

ethPM-CLI provides [a simple command](/ethpm-developer-guide/install-a-package#deploying-a-registry) deploy the Simple Registry to any blockchain.

Escape-Truffle provides [this script](https://github.com/ethpm/escape-truffle/blob/master/scripts/deploy.sh) to assist with deploying its series of smart contracts.

#### Package Naming and Versioning

As of ethPM V3, the `name` and `version` field of a manifest are no longer strictly required. Best practice is that every package **should** define these in their manifest. Some tooling may even go as far as requiring these fields are defined before cutting a release. When a package is released on a registry, users must provide an official `name` and `version` under which to identify a release on the blockchain. The following table defines how a package should be identified, considering the various cases when manifest defines / omits the `name` and `version`, and whether or not the manifest is stored on an on-chain registry.

|                           | Manifest contains name and version                               | Manifest omits name and version              |
| ------------------------- | ---------------------------------------------------------------- | -------------------------------------------- |
| Sourced from registry     | Manifest `name, version` **must** match registry `name, version` | Registry `name, version` is valid identifier |
| Not sourced from registry | Manifest `name, version` is the valid identifier                 | Ambiguous, user must define `name, version`  |


# URIs

ethPM uses a variety of URI schemes to help identify specific resources.

#### Content-Addressed URIs

Content-addressed URIs are used to ensure the immutability of each package release. A content-addressed URI is any URI that contains a cryptographic hash ensuring the identity of its contents and that the contents have not been modified. For example...

* [IPFS](https://ipfs.io/)
  * `ipfs://Qme4otpS88NV8yQi8TfTP89EsQC5bko3F5N1yhRoi6cwGV`
* [Swarm](https://swarm-guide.readthedocs.io/en/latest/introduction.html)
  * `bzz://2477cc8584cc61091b5cc084cdcdb45bf3c6210c263b0143f030cf7d750e894d`
* [Git Blobs](https://developer.github.com/v3/git/blobs/)
  * `https://api.github.com/repos/:owner/:repo/git/blobs/:file_sha`

#### Registry URIs

A registry URI is used to specify an on-chain registry or a specific release on a registry. Registry URIs may use the scheme `ethpm` or `erc1319`. All versions in a Registry URI must  properly escape all URL reserved characters. `CHAIN_ID` is optional - and if not included, defaults to `1` (eg. mainnet).

`ethpm://[CONTRACT_ADDRESS]:[CHAIN_ID]`

* ex: `ethpm://0x6b5DA3cA4286Baa7fBaf64EEEE1834C7d430B729:1`

`ethpm://[CONTRACT_ADDRESS]:[CHAIN_ID]/[PACKAGE_NAME]@[PACKAGE_VERSION]`

* ex:`ethpm://0x6b5DA3cA4286Baa7fBaf64EEEE1834C7d430B729:1/owned@1.0.0`

#### Blockchain URIs

A blockchain URI is used to specify the blockchain on which a deployed contract instance lives. This definition originates from [BIP122 URI](https://github.com/bitcoin/bips/blob/master/bip-0122.mediawiki).

* `blockchain://[CHAIN_ID]/block/[BLOCK_HASH]`
  * `CHAIN_ID` is the unprefixed hexadecimal representation of the genesis hash for the chain.
  * `BLOCK_HASH` is the unprefixed hexadecimal representation of the hash of a block on the chain.

#### Etherscan URIs

`ethPM CLI` uses this URI scheme to automatically generate packages for any of Etherscan's verified contracts. The provided contract address and chain ID **must** correspond to a contract address that has been verified (hint. look for the green checkmark in the `Contract` tab).

`etherscan://[CONTRACT_ADDRESS]:[CHAIN_ID]`

* ex: `etherscan://0xdAC17F958D2ee523a2206206994597C13D831ec7:1`


# ethPM Registry Directory

## `ONLY USE PACKAGES FROM TRUSTED REGISTRIES`

| Description      | Registry URI                    | Maintainer |
| ---------------- | ------------------------------- | ---------- |
| sample libraries | `ethpm://libraries.ethpm.eth:3` | ethpm      |

If you maintain a registry and would like to list it here for the community to use, feel free to open a pr - or drop us a note on the [ethPM Gitter channel](https://gitter.im/ethpm/Lobby) and we'll add it for you.


# ethPM & Remix IDE

How to get the most out of ethPM's plugin for Remix.

## What can I do with the ethPM Remix plugin?

* Generate an ethPM package from smart contracts in your Remix editor
* Publish generated ethPM packages to IPFS or download them locally
* Import smart contract source files from ethPM packages directly into the Remix editor
* Import deployed contract instances from ethPM packages, and interact with them directly in Remix

## How to create a package?

1. Compile the contract you want to package up with the `Solidity Compiler` plugin.
   * &#x20;Currently, the Vyper compiler plugin is **not** supported.
2. Select the contract types you would like to include in the package.
3. Enter your package name and version (both are required to generate a valid ethPM package).
4. Enter any metadata you would like to include in your package.
5. Click `Generate Manifest`.
6. Wait a bit while the plugin generates your manifests, and publishes it to IPFS (via the Infura gateway).
7. Click `Manifest Preview` to view the manifest in the ethPM explorer&#x20;
   * Note. this does not mean that your manifest has been published to a registry - it's simply a pretty view of your beautiful manifest json.
8. Click `Download Raw Manifest` to save a local copy of the generated manifest json.
   * Note - when downloaded, the json file has escaped characters which means it's an invalid ethPM manifest. To make this a valid ethPM manifest, you must remove the escape characters. Sorry for the inconvenience, we're working to eliminate this hurdle asap.

#### Next steps?

* Use the ethPM CLI to [deploy your own ethPM  registry](/ethpm-developer-guide/install-a-package#deploying-a-registry).
* Use the ethPM CLI to [release your newly created package](/ethpm-developer-guide/install-a-package#releasing-a-package), using the generated IPFS url.

## How to import a manifest?

* Click on `Import a Package`
* Enter the IPFS url associated with the desired package.
* Wait a second while the plugin fetches the manifest from IPFS.
* Click on `Import` to import any source file found in the manifest to Remix's in-browser filesystem.
* Click on `Import ABI` to import the ABI for any contract deployment found in the manifest to Remix's in-browser filesystem.

## How to interact a deployment?

* Follow the steps in `How to import a manifest?` (above)&#x20;
* Click on `Import ABI` for whatever contract deployment you want to interact with.&#x20;
* Activate the `Deploy and Run Transactions` plugin in Remix.
* Select `Injected Web3` in the `Environment` dropdown.&#x20;
* Make sure Metamask is connected to whatever chain your target deployment is located on.
* Copy and paste the address of the target deployment into `At Address`.
* Voila, now you can interact with the target deployment right in the Remix editor.


# Getting Started with ethPM CLI

There are multiple options that allow you to start interacting with the ethPM ecosystem, but the easiest place to start is the [ethPM CLI](https://ethpm-cli.readthedocs.io/en/latest/). Full API documentation of these commands can be found [here](https://ethpm-cli.readthedocs.io/en/latest/commands.html).

## Setup

### Installing ethPM CLI

#### Homebrew (recommended)

* `brew update`
* `brew upgrade`
* `brew tap ethpm/ethpm-cli`
* `brew install ethpm-cli`

#### pypi

* Create your virtual environment
* Install the latest version from [pypi](https://pypi.org/project/ethpm-cli/) with `pip install ethpm-cli==x.x.x`

#### Docker

* `docker pull ethpm/ethpm:latest`
* `docker run ethpm/ethpm:latest`

### Setting up your environment vars

Before you can use ethPM CLI, you **must** provide an API key to interact with Infura. If you don't have an API key, you can sign up for one [here](https://infura.io). Then set your environment variable with&#x20;

```
export WEB3_INFURA_PROJECT_ID="INSERT_KEY_HERE"
```

If you plan to [generate packages from Etherscan verified contracts](/ethpm-developer-guide/ethpm-and-etherscan-verified-contracts), you must also provide an API key for Etherscan.

```
export ETHPM_CLI_ETHERSCAN_API_KEY="INSERT_KEY_HERE"
```

If you're using Docker to run ethPM CLI, you must pass Docker the environment variables and mount volumes, like so...

```
docker run -i -e WEB3_INFURA_PROJECT_ID="INSERT_KEY_HERE" -v '/absolute/path/to/ethpm-cli/:/absolute/path/to/ethpm-cli/' -v '/$HOME/.local/share/ethpmcli/:/root/.local/share/ethpmcli/' ethpm/ethpm:latest list
```

### Setting up your private key

If you plan to use the CLI to send any transactions over an Ethereum network (eg. deploying a new registry, releasing a package to a registry), you must link a encrypted keyfile to sign these transactions. ethPM CLI uses [eth-keyfile](https://github.com/ethereum/eth-keyfile) to handle private keys. Follow the steps in the README to generate your encrypted keyfile. Make sure you don't lose the password, as you'll need to provide it for any tx-signing commands. Once you have your encrypted keyfile, you can link it to the ethPM CLI with the following command.

```
ethpm auth --keyfile-path KEYFILE_PATH
```

## Commands

### Deploying a Registry

This will deploy a new instance of the [ERC1319 Solidity Registry](https://github.com/ethpm/solidity-registry) to the specified chain. The address signing the transaction will automatically be set as the `owner` address on the registry. The newly deployed registry will be set as the active registry. You can provide an alias, if you want to store a simple reference to the registry.

```
ethpm registry deploy [-h] --chain-id CHAIN_ID 
                           --keyfile-password KEYFILE_PASSWORD 
                           [--alias ALIAS] 
```

### Generating an ethPM manifest

Thorough steps on how to generate a manifest for a local project can be found [here](https://ethpm-cli.readthedocs.io/en/latest/create.html).

To start a manifest wizard CLI prompt that will guide you through provided options allowed by the ethPM Specification.

```
ethpm create manifest-wizard [-h] --project-dir PROJECT_DIR
```

To quickly generate a bare-bones manifest in one step, without any additional fields.

```
ethpm create basic-manifest [-h] --package-name PACKAGE_NAME
                                 --package-version PACKAGE_VERSION
                                 --project-dir PROJECT_DIR
```

### Releasing a package

This will release a package version on the active registry.

```
ethpm release [-h] --package-name PACKAGE_NAME
                   --package-version PACKAGE_VERSION
                   --manifest-uri MANIFEST_URI
                   --keyfile-password KEYFILE_PASSWORD
```

### Installing a package

This will install a package and its assets to a local `_ethpm_packages/` directory. You can provide a specific ethPM directory, otherwise the CLI will default to the ethPM directory under the current working directory. You can provide an alias for the package if you want a simple reference to the package.

```
ethpm install [-h] manifest-uri [--alias ALIAS] [--ethpm-dir ETHPM_DIR]
```


# ethPM & Etherscan Verified Contracts

Interact with the top 20 erc20 tokens right from your terminal.

In this guide, we'll use [ethPM](https://web3py.readthedocs.io/en/stable/web3.pm.html) & [web3.py](https://github.com/ethereum/web3.py/) to instantly interact with any of the [top 20 erc20 ](https://etherscan.io/tokens?sortcmd=remove\&sort=marketcap\&order=desc)tokens with a couple lines of code from your terminal, **without** copy/pasting a single ABI!! In this example we'll be using the [DAI token](https://etherscan.io/token/0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359), but all top 20 tokens are available as ethPM packages on the [erc20 package registry](/public-registry-directory). All you will need for this tutorial is an Infura API key, if you don't already have one, you can get one [here](https://infura.io).

### tl;dr

```python
> from web3.auto.infura import w3
> w3.pm.set_registry('erc20.snakecharmers.eth')
> dai_pkg = w3.pm.get_package("dai-dai")
> dai = dai_pkg.deployments.get_instance("DSToken")

# Now you can interact with dai like any erc20 tokens.
> dai.functions.totalSupply().call()
78512091351850936215202968
```

### Step by Step

#### Install Python

For this tutorial, you must have Python 3.6+ installed on your machine. Check out [this tutorial](https://realpython.com/installing-python/) for more info.

#### Create your directory & virtual environment

Virtual environments are best practice in Python world, so let's follow suit.

```bash
> mkdir ethpm-tutorial && cd ethpm-tutorial
> python -m venv venv
> export WEB3_INFURA_PROJECT_ID="YOUR_INFURA_API_KEY"
> source venv/bin/activate
```

#### Install web3.py & iPython

```bash
> pip install web3==5.0.1
> pip install ipython
> ipython
```

#### web3.py Setup

Some setup is required in `web3.py` before we can play with our Dai. The `enable_unstable_package_management_api` flag is a temporary security measure. While `web3.pm` is  in alpha, we want to be extra sure that users understand the API might change in the future. This precaution will be removed once the `web3.pm` API stabilizes in the next `web3.py` release.

```python
> from web3.auto.infura import w3
> w3.enable_unstable_package_management_api()
```

#### Set the active registry

We'll be using the erc20 registry located on the Ethereum mainnet at under the ENS name `erc20.snakecharmers.eth` which resolves to the address `0x16763EaE3709e47eE6140507Ff84A61c23B0098A` . You can explore the various erc20 tokens available on this registry on the [ethPM explorer](http://explorer.ethpm.com/browse/mainnet/erc20.snakecharmers.eth). Since our `w3` instance is already connected to mainnet, all we have to do is set the registry.&#x20;

```python
> w3.pm.set_registry('erc20.snakecharmers.eth')
```

#### Grab the Dai package

```python
> dai_package = w3.pm.get_package('dai-dai', '1.0.0')
```

#### Grab the Dai contract instance

Since the contract instance data is contained within the `dai-dai` package, it's quite simple to grab a [contract instance class](https://web3py.readthedocs.io/en/stable/contracts.html#) representing the Dai token contract. We will use the contract type `DSToken` to grab the Dai instance.&#x20;

```python
> dai = dai_package.deployments.get_instance("DSToken")
```

Sidenote: `dai_package` is an instance of `py-ethpm`'s [`Package` class](https://web3py.readthedocs.io/en/stable/ethpm.html#package). This class automatically filters available deployments that live on the connected `w3` instance. To access a package's deployments that live on a different blockchain, you can pass a new `w3` instance to `Package.update_w3()`.

#### Play with your Dai!

Now we have a contract instance representing the Dai contract. We can interact with any of its available functions. Of course, to send Dai, you must first own Dai!&#x20;

```python
> dai.functions.totalSupply().call()
78512091351850936215202968

> dai.functions.send("me.eth").transact()
```

You can follow these steps to interact with any of the erc20 token packages available in the connected registry.

## Generate your own Etherscan verified contract package

Each package in the above erc20 registry was created using the [`ethPM CLI`'s `create`](/ethpm-developer-guide/install-a-package#creating-a-package) command in combination with its corresponding [Etherscan URI](/uris#etherscan-uris). If you're the curious type, and want to re-generate the package locally, these steps can be used to package up any of Etherscan's verified contracts on any blockchain.&#x20;

To generate an Etherscan verified contract package, we'll use ethPM CLI. So you'll need to have that installed on your machine. Steps for how to get setup can be found [here](/ethpm-developer-guide/install-a-package).

Next, you'll need an Etherscan API key. If you don't already have an Etherscan API key, you can grab one [here](https://etherscan.io/register). Then set it as the following environment variable.

`export ETHPM_CLI_ETHERSCAN_API_KEY="YOUR_ETHERSCAN_KEY_HERE"`

ethPM CLI uses [Etherscan URIs](/uris#etherscan-uris) to identify the target verified contract. Once you have the address and chain ID of your verified contract, the URI simply follows this scheme.

`etherscan://[CONTRACT_ADDRESS]:[CHAIN_ID]`

i.e.

`etherscan://0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359:1`

Then, all you need to do is execute the following command, and the CLI will package up the verified contract, and write it to your local `_ethpm_packages/` directory. You can use any package name or package version that makes sense.

`ethpm install etherscan://0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359:1 --package-name my-package --package-version 1.0.0`

By default, this command will write the generated manifest to an `_ethpm_packages/` directory in the current working directory. If no such directory is found, it will automatically generate one. You can also pass the command an `--ethpm-dir` flag to target a specific directory.&#x20;

You can check out your newly created package by exploring the `_ethpm_packages/` directory, and you will also see it listed by calling `ethpm list`.


# Compound Finance & ethPM

Earn interest on your DAI with ethPM and the Compound Protocol

If you're like me, you have a hard time turning down free money. So why just let your crypto sit around and gather dust instead of putting it to work?

This guide will show you how to earn interest on your DAI with only a few lines of code in your terminal. You'll instantly start accumulating interest on your DAI by supplying it to the Compound protocol for others to borrow. We won't go deep into the Compound protocol, but you can learn more about it [here](https://compound.finance/developers#getting-started).

### Overview

* Use the DAI & Compound ethPM packages
* Approve the cDAI contract to transfer your DAI
* Exchange your DAI for cDAI (aka supply your DAI to the Compound liquidity pool)

### Prerequisites

* The private key for an account that owns DAI
* [`ethpm-cli` installed](/ethpm-developer-guide/install-a-package#installing-ethpm-cli) & [environment setup](/ethpm-developer-guide/install-a-package#setting-up-your-environment-vars)
* General understanding of [web3.py contract API](https://web3py.readthedocs.io/en/stable/contracts.html)

### Setup

First, let's get the two packages we'll need to supply our DAI to the Compound protocol.

1. [DAI](http://explorer.ethpm.com/manifest/QmTFxJbaJvpgASxxdqFPSvYr1XLWgXR9fv241jLXsELiXP)
   * package name: `dai-dai`
   * version: `1.0.0`
   * located on: [`erc20.snakecharmers.eth`](http://explorer.ethpm.com/browse/mainnet/erc20.snakecharmers.eth)
2. [Compound](http://explorer.ethpm.com/manifest/QmYvsyuxjj9mKmCvn3jrdfnaHYwFsyHXUu7kETrN4dBhE6)&#x20;
   * package name: `compound`
   * version: `1.0.0`
   * located on: [`defi.snakecharmers.eth`](http://explorer.ethpm.com/browse/mainnet/defi.snakecharmers.eth)

```python
from ethpm_cli.config import setup_w3

# `setup_w3(chain_id, private_key)` is a helper method from ethpm-cli
# that automatically connects to the designated chain via Infura and 
# authenticates your account to automatically sign all transactions
w3 = setup_w3(1, 'PRIVATE_KEY')

# Temporary security measure until PM api stabilizes
w3.enable_unstable_package_management_api()

# Grab the dai package from the snakecharmers erc20 registry
w3.pm.set_registry('erc20.snakecharmers.eth')
dai_pkg = w3.pm.get_package('dai-dai', '1.0.0')
dai = dai_pkg.deployments.get_instance('DSToken')

# Verify that everything's working
dai.functions.name().call()
> b'Dai Stablecoin v1.0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

# Grab the compound package from the snakecharmers defi registry
w3.pm.set_registry('defi.snakecharmers.eth')
compound_pkg = w3.pm.get_package('compound', '1.0.0')
cDai = compound_pkg.deployments.get_instance('cDAI')

# Verify that everything's working
cDai.functions.name().call()
> 'Compound Dai'
```

### Approve

Before we can supply our DAI to the Compound protocol, we have to approve the cDAI contract to transfer our DAI tokens and convert them into cDAI. This is a [standard procedure](https://medium.com/ethex-market/erc20-approve-allow-explained-88d6de921ce9) with many erc20-based systems. We'll use our `cDAI` contract instance for the address.

```python
# approve(spender: address, value: uint256)
dai.functions.approve(cDai.address, w3.toWei(100, 'ether').transact()
> 0x123...
```

### Supply

In the Compound v2 protocol, "minting" is analogous for supplying your DAI to the liquidity pool. Here we'll specify how many DAI we want to supply, and we start earning interest on the very next block after this tx is mined. Neato!

```python
# mint(value: uint256)
cDai.functions.mint(w3.toWei(1, 'ether')).transact()
> 0xabc...
```

### Check your stacks!

Give this a couple blocks before you accrue interest. But check daily to see the accumulated rewards of your DAI's hard work!

```python
cDai.functions.balanceOfUnderlying(w3.eth.defaultAccount).call()
> 1000000000000000001 # User's balance in DAI
```

Verify your supply & interest accrued with the [Compound dapp](https://app.compound.finance/).  You can also use these ethPM packages and your newly created contract instances to borrow DAI or any other supported feature of the [cToken API](https://compound.finance/developers/ctokens#ctokens). The `compound` package we use here also contains deployment information for all the other [mainnet cTokens](https://compound.finance/developers), so you can use the same package to lend/borrow REP, ETH, BAT, etc...


# ethPM Library Support

#### [ethPM-CLI](https://github.com/ethpm/ethpm-cli/)

A command line tool to make it easy to interact with the ethPM ecosystem.&#x20;

* Deploy an ethPM registry
* Release packages on a registry
* Package up smart contracts
* Install ethPM packages
* Scrape blockchains for ethPM assets

#### [web3.pm](https://web3py.readthedocs.io/en/stable/ethpm.html)

A module in web3.py that provides useful methods for interacting with ethPM registries, generating `web3.contract` instances and factories for the contract types defined in a package.

#### [explorer.ethpm.com](http://explorer.ethpm.com/)

An explorer to visually examine the registries and packages available in the ethPM ecosystem.&#x20;

#### ethPM Core Libraries

These libraries are all in different stages of development. If you feel the call to enhance any features in a particular library, we would be thrilled for any and all contributions.&#x20;

* [ethpm.js](https://github.com/ethpm/ethpm.js)
* [py-ethpm](https://web3py.readthedocs.io/en/stable/ethpm.html)
* [ethpm-go](https://github.com/ethpm/ethpm-go)
* [ethpm-rs](https://github.com/ethpm/ethpm-rs)

#### Coming soon...

* ethPM v2 support in Truffle
* ethPM v2 support in Brownie
* ethPM plugin for Remix


# FAQs

#### Why should I care about ethPM?

Nick Gnidan from Truffle wrote a beautiful [blog](https://medium.com/coinmonks/ethpm-smart-contract-packages-for-developers-81c77481c491) which answers this.&#x20;

#### Why isn't there one central registry?

While having a single, centralized registry can be convenient for discovering new packages, there are some downsides, such as a limited feature set and maintenance overhead. ethPM v3 uses a federated registry model to overcome these limitations. In a world where code controls large amounts of money, malicious packages pose a serious threat. Forcing package authors to deploy and maintain their own authorized registry minimizes the chance that a malicious release finds its way into a popular package. Furthermore, the overhead of maintaining a central registry is significant, and more sustainable if distributed amongst package authors. Finally, defining a standard which can be extended allows devs to write custom logic into their package registry to achieve whatever goal they have in mind allows for new ideas to be experimented with and bloom.

#### What about ethPM v1 or v2 packages?

ethPM v3 made breaking changes from ethPM v2, so unfortunately ethPM v1 and v2 packages are no longer supported by the majority of ethPM tooling. However, upgrading a v1 or v2 package to v3 is simple with the ethpm-cli.

#### What about my IPFS assets?

While package authors should take their own measures to ensure IPFS assets maintain availability, the Ethereum Foundation sponsors a server that will automatically scrape, back-up, and persist IPFS assets published to any ERC1319 compliant ethPM registry.&#x20;

#### What's the best way to contribute?

Glad you asked! The easiest way to contribute is to package up your smart contracts, and make them available to the community by releasing them on your registry. Otherwise, pull requests to any of the existing libraries or integration into new frameworks would be massive - and earn the eternal love & appreciation of the ethPM community.&#x20;

#### Have another question? Ask it on our [Gitter channel](https://gitter.im/ethpm/Lobby).

#### Additional Reading

* [**Getting started with web3.py and EthPM**](https://snake-charmers.ethereum.org/2019/01/24/ethpm.html)


