How to Deploy a Smart Contract to Polygon in Brownie

Rate this post

This article will look at deploying a smart contract to Polygon using Brownie. 

What is Polygon?

Polygon is “a protocol and a framework for building and connecting Ethereum-compatible blockchain networks” (https://polygon.technology/).

It started as Matic Network in 2017 to solve Ethereum’s scalability and user experience issues by using an ​off/side chain scaling solution.

In 2021, it changed the name to Polygon and now focuses on building a full-fledged blockchain platform, where developers can build scalable Ethereum-compatible blockchains.

Its popularity has rapidly grown as more and more users experience Ethereum’s slow transaction speed and high gas fees and see Polygon as a much cheaper and faster alternative to Ethereum. Many dApps have already been deployed to Polygon with Uniswap being one of the recent notable examples.

Polygon Popularity Google Trends

For more details about Polygon, you can check the Polygon website.

Network Setup

In this article, we will connect to the Polygon testnet (Mumbai) using the API provider Infura

Connecting to Polygon is very straightforward if you already know how to connect to the Ethereum network in Brownie. If you’re not familiar with it, you might also want to check my article below:

Set up a Brownie project

Before setting up the network, let’s start by creating an empty Brownie project. On a terminal window, run the command brownie init in a new directory.

[~]$ mkdir polygon_test
[~]$ cd polygon_test
[~/polygon_test]$ brownie init
Brownie v1.17.1 - Python development framework for Ethereum

SUCCESS: A new Brownie project has been initialized at /Users/mikio/polygon_test

Set up Infura

We will use Infura to connect to the Polygon testnet. Let’s go to https://infura.io/ and log on to the website. If you don’t have an account, click on the SIGN UP button in the top right-hand corner instead and follow the instructions to create a free account.

After logging in, click on the CREATE NEW PROJECT button on the main screen.

Select Ethereum from the PRODUCT drop-down menu and fill in the project name (any name we like).

On the next page, we can find the KEYS section. Copy the project ID. 

Set up the environment variable in Brownie

Go back to the Brownie project. Create a file called .env in the project root directory and add the following line (replace the project ID value with your ID):

.env

WEB3_INFURA_PROJECT_ID=691a20ed16eb439f8006a2b3edb45cdf

Create another file called brownie-config.yaml in the project root directory and add the following line:

dotenv: .env 

Ensure that the .gitignore file contains the entry .env to avoid accidentally committing the .env file to the Git repository

Brownie network configuration

We can find the network settings in Brownie by running the brownie networks list command on the terminal.

[~/polygon_test]$ brownie networks list
Brownie v1.17.1 - Python development framework for Ethereum

The following networks are declared:

Ethereum
  ├─Mainnet (Infura): mainnet
  ├─Ropsten (Infura): ropsten
  ├─Rinkeby (Infura): rinkeby
  ├─Goerli (Infura): goerli
  └─Kovan (Infura): kovan

Ethereum Classic
  ├─Mainnet: etc
  └─Kotti: kotti

Arbitrum
  └─Mainnet: arbitrum-main

Binance Smart Chain
  ├─Testnet: bsc-test
  └─Mainnet: bsc-main

Fantom Opera
  ├─Testnet: ftm-test
  └─Mainnet: ftm-main

Polygon
  ├─Mainnet (Infura): polygon-main
  └─Mumbai Testnet (Infura): polygon-test

XDai
  ├─Mainnet: xdai-main
  └─Testnet: xdai-test

Development
  ├─Ganache-CLI: development
  ├─Geth Dev: geth-dev
  ├─Hardhat: hardhat
  ├─Hardhat (Mainnet Fork): hardhat-fork
  ├─Ganache-CLI (Mainnet Fork): mainnet-fork
  ├─Ganache-CLI (BSC-Mainnet Fork): bsc-main-fork
  ├─Ganache-CLI (FTM-Mainnet Fork): ftm-main-fork
  ├─Ganache-CLI (Polygon-Mainnet Fork): polygon-main-fork
  └─Ganache-CLI (XDai-Mainnet Fork): xdai-main-fork

As we can see, Brownie comes with the network settings for Polygon using Infura by default. 

Polygon
  ├─Mainnet (Infura): polygon-main
  └─Mumbai Testnet (Infura): polygon-test

Let’s connect to the Polygon Mumbai testnet from the Brownie console. Run the brownie console command with the --network polygon-test option as shown below. 

[~/polygon_test]$ brownie console --network polygon-test
Brownie v1.17.1 - Python development framework for Ethereum

PolygonTestProject is the active project.
Brownie environment is ready.
>>> network.is_connected()
True
>>> network.show_active()
'polygon-test'

Now, the network configuration in Brownie is complete.

How to Deploy a Smart Contract

To deploy a smart contract, we need an account on the network, so let’s create one. 

Create a Deployment Account

First, let’s check if there are any local accounts. Run the brownie accounts list command.

[~/polygon_test]$ brownie accounts list                     
Brownie v1.17.1 - Python development framework for Ethereum

Found 0 accounts:

In this case, there is no account. Let’s create a new one called deployment_account. When prompted, type a new password. Be sure to remember it because we will need it later.

[~/polygon_test]$ brownie accounts generate deployment_account
Brownie v1.17.1 - Python development framework for Ethereum

Generating a new private key...
mnemonic: 'xxxxx xxxx xxxx xxxxx xxxx xxxx xxxxx xxxxx xxxxxx xxxx xxxxxx xxxxxx'
Enter the password to encrypt this account with: 
SUCCESS: A new account '0x30e4E6290941A35d6988B52451B32badE7C7CbAC' has been generated with the id 'deployment_account'

The hex-decimal number (0x30e4E6290941A35d6988B52451B32badE7C7CbAC) is the account address. 

We can check that the account has been created by running the brownie accounts list command again.

[~/polygon_test]$ brownie accounts list
Brownie v1.17.1 - Python development framework for Ethereum

Found 1 account:
 └─deployment_account: 0x30e4E6290941A35d6988B52451B32badE7C7CbAC

Get test MATIC token from Polygon Faucet

We need to pay gas when deploying a smart contract because deployment is a transaction. While we use ether (ETH) on Ethereum, we need Polygon’s native token MATIC to pay gas on Polygon. So, let’s get some test MATIC. 

The easiest way to get a test token is to request some on the Polygon Faucet website. Select “Mumbai” and “MATIC Token” and copy and paste the account address in the Wallet Address field.

Press the “Submit” button.

As long as the Faucet is working, we should get some MATIC after a few minutes. 

[~/polygon_test]$ brownie console --network polygon-test
Brownie v1.17.1 - Python development framework for Ethereum

PolygonTestProject is the active project.
Brownie environment is ready.
>>> account = accounts.load('deployment_account')
Enter password for "deployment_account": 
>>> web3.fromWei(account.balance(), 'ether')
Decimal('0.5')

Deploy a smart contract

This article will use the SimpleStorage smart contract, which I took from the Solidity documentation.

Save the content below as contracts/storage.sol.

contracts/storage.sol

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

Then, create a deployment script. In the scripts directory, create a file called deploy.py with the following content.

from brownie import SimpleStorage, accounts

def main():
    account = accounts.load('deployment_account')
    SimpleStorage.deploy({'from': account})

Now, open a terminal window and run the command brownie run deploy.py --network polygon-test as shown below.

When prompted, type the account password.

[~/polygon_test]$ brownie run deploy.py --network polygon-test
Brownie v1.17.1 - Python development framework for Ethereum

New compatible solc version available: 0.8.10
Compiling contracts...
  Solc version: 0.8.10
  Optimizer: Enabled  Runs: 200
  EVM Version: Istanbul
Generating build data...
 - SimpleStorage

PolygonTestProject is the active project.

Running 'scripts/deploy.py::main'...
Enter password for "deployment_account": 
Transaction sent: 0x818386e241114d7c1c893416cfc154b5bb602571e8f1860305e1772c11db4d9f
  Gas price: 2.0 gwei   Gas limit: 99606   Nonce: 0
  SimpleStorage.constructor confirmed   Block: 23917582   Gas used: 90551 (90.91%)
  SimpleStorage deployed at: 0x68612eDF8f534eB752DD1Ea1aa931C7808CF75D1

We can check our smart contract on Polygon PoS Chain Testnet Explorer.

Copy our smart contract address (0x68612eDF8f534eB752DD1Ea1aa931C7808CF75D1 in the example above) and paste it into the search box.

It should find our smart contract.

Interact with the smart contract

We can interact with the smart contract using the Brownie console.

Let’s start the console and connect to the Mumbai testnet.

[~/polygon_test]$ brownie console --network polygon-test      
Brownie v1.17.1 - Python development framework for Ethereum

PolygonTestProject is the active project.
Brownie environment is ready.

Load the smart contract by specifying the address. We can find the address in the output of the deployment script. Alternatively, we can see the address in the JSON file name in the build/deployments/80001 directory (80001 is the network ID of the Polygon Mumbai testnet). 

>>> simple_storage = SimpleStorage.at('0x68612eDF8f534eB752DD1Ea1aa931C7808CF75D1')

Then, we can run the function get(), which should return the value 0 because we haven’t set a value yet.

>>> simple_storage.get()
0

To update the value, we need to send a transaction. Let’s load the deployment_account account.

When prompted, type the account password. 

>>> account = accounts.load('deployment_account')
Enter password for "deployment_account": 

Then, run the function set() with the parameter value 5 and the address of deployment_account. It should return a transaction object after a few seconds.

>>> simple_storage.set(5, {'from': account})
Transaction sent: 0x73cf90c4c884e13a6dea961c9fcc80bb07d52c69752992a5e4e9279f3be00a82
  Gas price: 1.999999998 gwei   Gas limit: 47843   Nonce: 1
  SimpleStorage.set confirmed   Block: 23917709   Gas used: 43494 (90.91%)

<Transaction '0x73cf90c4c884e13a6dea961c9fcc80bb07d52c69752992a5e4e9279f3be00a82'>

We can check the value by running the get() function again, which should now show 5.

>>> simple_storage.get()
5

We can also find the transaction on Polygonscan (Mumbai) by searching the transaction hash value, which shows the input value 5.

Summary

This article looked at how to deploy a smart contract to the Polygon testnet in Brownie

The steps are the same as deploying a smart contract to Ethereum. Brownie already has the network settings to connect to Polygon using Infura by default, so all we need to do is to select the correct network (for example, polygon-test).

Polygon is compatible with Ethereum Virtual Machine.

In this article, we deployed a very simple smart contract for Ethereum to Polygon without any modification.

We then used the Brownie console to interact with the smart contract and checked the transaction information on Polygonscan.

I hope this article has been helpful to understand how to deploy a smart contract to Polygon in Brownie. You can find more in the following resources:


Learn Solidity Course

Solidity is the programming language of the future.

It gives you the rare and sought-after superpower to program against the “Internet Computer”, i.e., against decentralized Blockchains such as Ethereum, Binance Smart Chain, Ethereum Classic, Tron, and Avalanche – to mention just a few Blockchain infrastructures that support Solidity.

In particular, Solidity allows you to create smart contracts, i.e., pieces of code that automatically execute on specific conditions in a completely decentralized environment. For example, smart contracts empower you to create your own decentralized autonomous organizations (DAOs) that run on Blockchains without being subject to centralized control.

NFTs, DeFi, DAOs, and Blockchain-based games are all based on smart contracts.

This course is a simple, low-friction introduction to creating your first smart contract using the Remix IDE on the Ethereum testnet – without fluff, significant upfront costs to purchase ETH, or unnecessary complexity.