# Brownie

## Using Brownie to Deploy To Phron <a href="#using-brownie-to-deploy-to-phron" id="using-brownie-to-deploy-to-phron"></a>

### Introduction <a href="#introduction" id="introduction"></a>

[Brownie](https://eth-brownie.readthedocs.io/) is an Ethereum development environment that helps Python developers manage and automate the recurring tasks inherent to building smart contracts and DApps. Brownie can directly interact with Phron's Ethereum API so it can also be used to deploy smart contracts on Phron.

This guide will cover how to use Brownie to compile, deploy, and interact with Ethereum smart contracts on the Phron TestNet.

**Please note that Brownie is no longer actively maintained.** You can check out [Ape](https://docs.apeworx.io/ape/stable) as an alternative Python Ethereum development environment.

### Checking Prerequisites <a href="#checking-prerequisites" id="checking-prerequisites"></a>

To get started, you will need the following:

* Have MetaMask installed and connected to Phron
* Have an account with funds. You can get DEV tokens for testing on Phron once every 24 hours from the [Phron Faucet](https://faucet.phron.ai/).
* To test out the examples in this guide on Phron, you will need to have your own endpoint and API key, which you can get from one of the supported Endpoint Providers

For this guide, Python version 3.9.10, pip version 22.0.3, and pipx version 1.0.0 were used.

### Creating a Brownie Project <a href="#creating-a-brownie-project" id="creating-a-brownie-project"></a>

You will need to install Brownie and create a Brownie project if you don't already have one. You can choose to either create an empty project or use a [Brownie mix](https://eth-brownie.readthedocs.io/en/stable/init.html?highlight=brownie%20mix#creating-a-project-from-a-template), which is essentially a template to build your project on. For this example, you can create an empty project. You can get started by completing the following steps:

1. Create a directory for your project

   ```bash
   mkdir brownie && cd brownie
   ```
2. If you don't already have `pipx` installed, go ahead and install it

   ```bash
   python3 -m pip install --user pipx
   python3 -m pipx ensurepath
   ```
3. [Install Brownie using `pipx`](https://eth-brownie.readthedocs.io/en/stable/install.html), which is used to run executables installed locally in your project. Brownie will be installed into a virtual environment and be available directly from the command line

   ```bash
   pipx install eth-brownie
   ```

> ### Note
>
> A common error while installing Brownie on Ubuntu is:

```bash
pip seemed to fail to build package:
    pyyaml==5.4.1

Some possibly relevant errors from pip install:
    error: subprocess-exited-with-error
    AttributeError: cython_sources

Error installing eth-brownie.
```

This can be resolved by using the following command:

```bash
pip3 install wheel && \
pip3 install --no-build-isolation "Cython<3" "pyyaml==5.4.1" && \
pip3 install --upgrade --no-cache-dir eth-brownie
```

1. Create a project

   ```bash
   brownie init
   ```

<pre class="language-bash"><code class="lang-bash"><strong>phron@ubuntu:~$ brownie init
</strong>Brownie v1.19.1 - Python development framework for Ethereum

SUCCESS: A new Brownie project has been initialized at /home/moonbeam/brownie

phron@ubuntu:~$ ls
build contracts interfaces reports scripts tests
</code></pre>

Your Brownie project should contain the following empty directories:

* **build** - for project data such as contract artifacts from compilation
* **contracts** - to store the smart contract files
* **interfaces** - for smart contract interfaces that are required for your project
* **reports** - for JSON report files for use in the [Brownie GUI](https://eth-brownie.readthedocs.io/en/stable/gui.html)
* **scripts** - where Python scripts used for deploying contracts or other automated tasks will live
* **tests** - to store Python scripts for testing your project. Brownie uses the `pytest` framework for unit testing

Another important file to note that is not included in an empty project is the `brownie-config.yaml` configuration file. The configuration file is optional and comes in handy when customizing specific settings such as a default network, compiler version and settings, and more.

### Network Configuration <a href="#network-configuration" id="network-configuration"></a>

To deploy to a Phron network, you'll need to add and configure the network. Network configurations in Brownie are added from the command line. Brownie can be used with both development and live environments.

Phron are supported out of the box with Brownie as of version 1.19.3. To view the complete list of supported networks, you can run the following command:

```bash
brownie networks list
```

```bash
brownie networks list
Phron ├─Mainnet: Phron
```

If you're looking to deploy a contract to a Phron development node you'll need to add the network configurations. Under the hood, Brownie uses Ganache for development environments. However, since a Phron development node acts as your own personal development environment, Ganache isn't needed. Therefore, you can configure a development node as a "live" network.

To add Phron development node configurations, you can run the following command:

{% code overflow="wrap" %}

```bash
brownie networks add Phron phron-dev host=http://127.0.0.1:9944 name=Development chainid=7744
```

{% endcode %}

If you successfully added the network, you'll see a success message along with the network details in the terminal.

To deploy to a Phron network, or run tests on a specific network, you can specify the network by appending the following to the given command:

```bash
--network phron-main
```

If you would like to set a default network, you can do so by adding the following snippet to the `brownie-config.yaml` configuration file:

```bash
networks:
    default: phron-main
```

> ### Note
>
> Keep in mind that the `brownie-config.yaml` file isn't automatically created, you can optionally create it yourself.

#### Setting your Networks RPC URLs <a href="#setting-your-networks-rpc-urls" id="setting-your-networks-rpc-urls"></a>

It is recommended that you override the default Brownie RPC URLs to your own RPC endpoint or the public Phron network endpoints. You can override the default Brownie RPC URL for each network as follows:

```bash
brownie networks modify phron-main host=INSERT_RPC_API_ENDPOINT
```

{% code overflow="wrap" %}

```bash
brownie networks modify phron-main host=https://testnet.phron.ai
SUCCESS: Network 'Mainnet' has been modified └─Mainnet ├─id: phron-main ├─chainid: 7744 ├─explorer: https://testnet.phronscan.io/ ├─host: https://testnet.phronscan └─multicall2: 0x1337BedC9D22ecbe766dF105c9623922A27963EC
```

{% endcode %}

### Account Configuration <a href="#account-configuration" id="account-configuration"></a>

Before you can deploy a contract, you'll need to configure your account, which is also done from the command line. To add a new account you can run:

```bash
brownie accounts new INSERT_ACCOUNT_NAME
```

Make sure to replace `INSERT_ACCOUNT_NAME` with your name of choice. For this example, `alice` will be used as the account name.

You'll be prompted to enter in your private key and a password to encrypt the account with. If the account was successfully configured, you'll see your account address printed to the terminal.

{% code overflow="wrap" %}

```bash
brownie accounts new aliceBrownie v1.19.1 - Python development framework for Ethereum
Enter the private key you wish to add: 0x5b92d6e98884f76de468fa3f6278f880748bebc13595d45af5bdc4da702133Enter the password to encrypt this account with: SUCCESS: A new account 'Oxf24FF3a9CF04c71Dbc94D06566f7A27B94566cac' has been generated with the id 'alice'
```

{% endcode %}

### The Contract File <a href="#the-contract-file" id="the-contract-file"></a>

Next you can create a contract inside of the `contracts` directory. The smart contract that you'll deploy as an example will be called `Box`, it will let you store a value that can be retrieved later. You can create a `Box.sol` contract by running the following command:

```bash
cd contracts && touch Box.sol
```

Open the file and add the following contract to it:

```solidity
// contracts/Box.sol
pragma solidity ^0.8.1;

contract Box {
    uint256 private value;

    // Emitted when the stored value changes
    event ValueChanged(uint256 newValue);

    // Stores a new value in the contract
    function store(uint256 newValue) public {
        value = newValue;
        emit ValueChanged(newValue);
    }

    // Reads the last stored value
    function retrieve() public view returns (uint256) {
        return value;
    }
}
```

### Compiling Solidity <a href="#compiling-solidity" id="compiling-solidity"></a>

To compile the contract you can simply run:

```bash
brownie compile
```

{% code overflow="wrap" %}

```bash
brownie compileBrownie v1.19.1 - Python development framework for Ethereum
New compatible solc version available: 0.8.4Compiling contracts... Solc version: 0.8.4 Optimizer: Enabled Runs: 200 EVM Version: IstanbulGenerating build data... - BoxProject has been compiled. Build artifacts saved at /home/phron/brownie/build/contracts
```

{% endcode %}

> ### Note
>
> The first time you compile your contracts it may take longer than usual while the `solc` binary is installed.

After compilation, you'll find the build artifacts in the `build/contracts` directory. The artifacts contain the bytecode and metadata of the contract, which are `.json` files. The `build` directory should already be in the `.gitignore` file but if it's not, it’s a good idea to add it there.

If you want to specify the compiler version or compilation settings, you can do so in the `brownie-config.yaml` file. Please note that if you haven't already created this file, you will need to do so. Then you can specify the compiler like so:

```javascript
compiler:
  evm_version: null
  solc:
    version: 0.8.13
    optimizer:
      enabled: true
      runs: 200
```

> ### Note
>
> You can view the list of [EVM versions supported by Brownie](https://github.com/eth-brownie/brownie/blob/master/docs/compile.rst#the-evm-version) in their documentation.

Your contracts will only be compiled again if Brownie notices that a change has been made. To force a new compilation, you can run:

```bash
brownie compile --all
```

### Deploying the Contract <a href="#deploying-the-contract" id="deploying-the-contract"></a>

In order to deploy the `Box.sol` smart contract, you will need to write a simple deployment script. You can create a new file under the `scripts` directory and name it `deploy.py`:

```bash
cd scripts && touch deploy.py
```

Next, you need to write your deployment script. To get started start, take the following steps:

1. Import the `Box` contract and the `accounts` module from `brownie`
2. Load your account using `accounts.load()` which decrypts a keystore file and returns the account information for the given account name
3. Use the `deploy` method that exists within this instance to instantiate the smart contract specifying the `from` account and the `gas_limit`

```python
# scripts/deploy.py
from brownie import Box, accounts


def main():
    account = accounts.load("alice")
    return Box.deploy({"from": account, "gas_limit": "200000"})
```

You can now deploy the `Box.sol` contract using the `run` command and specifying the network:

```bash
brownie run scripts/deploy.py --network phron-main
```

After a few seconds, the contract is deployed, and you should see the address in the terminal.

{% code overflow="wrap" %}

```bash
brownie run scripts/deploy.py --network phron-testnetBrownie v1.19.1 - Python development framework for Ethereum
BrownieProject is the active project.
Running 'scripts/deploy.py: :mainEnter password for "alice":Transaction sent: Oxf091d0415d1a4614ccd76a5f5f985fdf6abbd68d7481647fb3144dfecffb333Gas price: 1.0 gwei Gas limit: 200000 Nonce: 15298Box.constructor confirmed Block: 1901367 Gas used: 103095 (51.55%)Box deployed at: OxccA4aDdD51Af1E76beZaBE5FD04A82EB6063C65
```

{% endcode %}

Congratulations, your contract is live! Save the address, as you will use it to interact with this contract instance in the next step.

### Interacting with the Contract <a href="#interacting-with-the-contract" id="interacting-with-the-contract"></a>

You can interact with contracts using the Brownie console for quick debugging and testing or you can also write a script to interact.

#### Using Brownie Console <a href="#using-brownie-console" id="using-brownie-console"></a>

To interact with your newly deployed contract, you can launch the Brownie `console` by running:

```bash
brownie console --network phron-main
```

The contract instance will automatically be accessible from the console. It will be wrapped in a `ContractContainer` which also enables you to deploy new contract instances. To access the deployed contract you can use `Box[0]`. To call the `store` method and set the value to `5`, you can take the following steps:

1. Create a variable for the contract

   ```bash
   box = Box[0]
   ```
2. Call the `store` method using your account and set the value to `5`

   ```bash
   box.store(5, {'from': accounts.load('alice'), 'gas_limit': '50000'})
   ```
3. Enter the password for your account

The transaction will be signed by your account and broadcasted to the network. Now, you can retrieve the value by taking these steps:

1. Call the `retrieve` method

   ```bash
   box.retrieve({'from': accounts.load('alice')})
   ```
2. Enter your password

You should see `5` or the value you have stored initially.

{% code overflow="wrap" %}

```bash
brownie console --network phron-testnetBrownie v1.19.1 - Python development framework for Ethereum
BrownieProject is the active project.Brownie environment is ready.box = Box[0]
box. store(5, {'from': accounts. load('alice"), 'gas-limit: "50000").Enter password for "alice":Transaction sent: 0x2418038735934917861dfa77068fe6dadd0b3c7e4362d6f73c1712aaf6a89aGas price: 1.0 gwei Box.store confirmed Gas limit: 50000 Nonce: 15299Box.store confirmed Block: 1901372 Gas used: 44593 (89.19%)
Transaction '0×24180387359349178b1dfa770e68fe6dadd0b3c7e4362d6f73c1712aaf6a89a'box.retrieve ({'from': accounts. load('alice")})Enter password for "alice":5
```

{% endcode %}

#### Using a Script <a href="#using-a-script" id="using-a-script"></a>

You can also write a script to interact with your newly deployed contract. To get started, you can create a new file in the `scripts` directory:

```bash
cd scripts && touch store-and-retrieve.py
```

Next, you need to write your script that will store and then retrieve a value. To get started, take the following steps:

1. Import the `Box` contract and the `accounts` module from `brownie`
2. Load your account using `accounts.load()` which decrypts a keystore file and returns the account information for the given account name
3. Create a variable for the `Box` contract
4. Use the `store` and `retrieve` functions to store a value and then retrieve it and print it to the console

```python
# scripts/store-and-retrieve.py
from brownie import Box, accounts


def main():
    account = accounts.load("alice")
    box = Box[0]
    store = box.store(5, {"from": accounts.load("alice"), "gas_limit": "50000"})
    retrieve = box.retrieve({"from": accounts.load("alice")})

    print("Transaction hash for updating the stored value: " + store)
    print("Stored value: " + retrieve)
```

To run the script, you can use the following command:

```bash
brownie run scripts/store-and-retrieve.py --network phron-main
```

You'll need to enter the password for Alice to send the transaction to update the stored value. Once the transaction goes through, you should see a transaction hash and a value of `5` printed to the console.

Congratulations, you have successfully deployed and interacted with a contract using Brownie!

This tutorial is for educational purposes only. As such, any contracts or code created in this tutorial should not be used in production.The information presented herein has been provided by third parties and is made available solely for general information purposes. Phron does not endorse any project listed and described on the Phron Doc Website (<https://docs.Phron.ai/>). Phron does not warrant the accuracy, completeness or usefulness of this information. Any reliance you place on such information is strictly at your own risk. Phron disclaims all liability and responsibility arising from any reliance placed on this information by you or by anyone who may be informed of any of its contents. All statements and/or opinions expressed in these materials are solely the responsibility of the person or entity providing those materials and do not necessarily represent the opinion of Phron. The information should not be construed as professional or financial advice of any kind. Advice from a suitably qualified professional should always be sought in relation to any particular matter or circumstance. The information herein may link to or integrate with other websites operated or content provided by third parties, and such other websites may link to this website. Phron has no control over any such other websites or their content and will have no liability arising out of or related to such websites or their content. The existence of any such link does not constitute an endorsement of such websites, the content of the websites, or the operators of the websites. These links are being provided to you only as a convenience and you release and hold Phron harmless from any and all liability arising from your use of this information or the information provided by any third-party website or service.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.phron.ai/developers/build-with-phronai/smart-contracts-development/solidity-contracts/phron-toolkit/dev-environments/brownie.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
