How to create your own token with Solidity and Python
Published: 2022-02-11 12:02:11

In this tutorial, you will learn how to create a simple **ERC20 token** with Solidity and deploy it onto a testnet with Python.

### What is an ERC20 token?
ERC20 is a token standard that resides in a smart contract. What makes it different from other standards is that it is **interchangeable**, which means one ERC20 token will always be equal to another of the same kind. The thing that makes ERC20 a token and not a coin is the fact that smart contracts that control ERC20 tokens live on the Ethereum and other EVM compatible blockchains such as Avalanche, meanwhile coins have their own native blockchains.

## Requirements
You will need **Python 3.6 or greater** and **pip**.
You will also need **npm**.
We will be accomplishing things like tests and deployment using the Python package named **Brownie**, so you will need to install it from pip.
```
> pip install eth-brownie
```
You will also need **ganache-cli**, so that brownie can locally deploy/test the contracts.
```
> npm install ganache-cli
```

## Project setup
Open a folder, launch a command line window inside of it and run the following command, which will initialize the basic files of your brownie project for you.

```
> brownie init
```
You will see that these files have been created.
```
├───build
│   ├───contracts
│   ├───deployments
│   └───interfaces
├───contracts
├───interfaces
├───reports
├───scripts
└───tests
```
The only folders we will focus on this tutorial are `contracts` and `scripts`. The contracts folder will hold our smart contracts and the scripts folder is going to be the one where we write our deployment scripts.

## Configuration
In this tutorial, we are going to use the **OpenZeppelin** library. This library provides a lot of utilities and standards which can be easily imported and used in your project. To get OpenZeppelin for our project and add more settings further in the project, in the **base directory** we need to create a `brownie-config.yaml` file where we are going to configure our dependencies.
After you create the file, add these so that the library gets installed when we compile our contract.
```yaml
dependencies:
  - OpenZeppelin/openzeppelin-contracts@4.2.0

compiler:
  solc:
    remappings:
      - "@openzeppelin=OpenZeppelin/openzeppelin-contracts@4.2.0"
```
In the `dependencies` section, we add the github repository of our target library and specify the version to be downloaded.
In the `remappings` section, we specify a remapping for the library path so that we do not have to type longer imports.

## Writing the contract
A **smart contract** is basically code that resides on the Ethereum blockchain and is available to run functions, emit events and such. Create your smart contract code by creating a new file `MyToken.sol` in the contracts folder.
```solidity
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {

    constructor(uint256 initialSupply) ERC20("MyToken","TKN"){
        _mint(msg.sender, initialSupply);
    }
}
```
**What does this code do?**
The `pragma` keyword lets us specify which versions our code will be compatible with. This means that our code will be compatible with versions of 0.8.0, which means our contract can run in 0.8.0, 0.8.5 and such, but can not run in 0.7.0 or 0.9.0.

In the import statement, we reached to the **ERC20.sol** file from the OpenZeppelin library so that we can use it in our contract.

After we declared our contract, we added `is ERC20`, which basically **inherits** the functions of ERC20.sol, which technically makes our smart contract an ERC20.

The constructor allows us to initialize our smart contract. We added `ERC20("MyToken", "TKN")` to declare the name and symbol. The `initialSupply` is the amount which will be **minted** to the deployer of the contract.

## Compiling the contract
After you have written the contract, you will have to **compile** the contract. To compile the contract to see if you have any errors, run the following command in the base directory.
```
> brownie compile
```
If you have no errors, now it is time to deploy it to the local ganache!

## Local deployment
Create `deploy.py` in the `scripts` folder.
```python
from brownie import MyToken, accounts
from web3 import Web3

initial_supply = 1000000

def main():
    account = accounts[0]
    my_token = MyToken.deploy(initial_supply, {'from': account})
    print(my_token.name())
```
The accounts that we imported from brownie are local accounts created by ganache. These make it easier for us to do operations like deployment, tests, etc.
By getting a local account and our contract MyToken from brownie, we are able to deploy the contract and use the deploy function. `{'from': account}` is the parameter we give to the function which allows it to be transacted by the account.
At the end, we print the use the inherited `name()` function to get the name we had entered in the ERC20 constructor of our contract.

After you finish coding, open your command line window in the base directory, and type the following command, which will run the script and show information about the transactions.
```
> brownie run scripts/deploy.py
```
If this runs without any problems and you get the output of the tokens name at the end, it means that you've made it!

This is the end of this part of the tutorial. If you have seen any mistakes in this tutorial, or if you have any questions, feel free to comment about it. If you want to accomplish more and deploy your token onto a testnet, follow along the series. I hope this tutorial will be your starting point to Web3!