I was recently asked to help create a simple ERC20 token for a fellow meetup organizer, for her to learn more about how Ethereum tokens are created, deployed, and used.

Helping other people learn new things — especially in the crypto ecosystem — is what I love best, so I took this opportunity to put together a nice tight lil repo which makes it as easy as possible for someone to deploy a token, and know exactly what’s going on along the way.

TLDR: https://github.com/decentorganization/simple-token

This is called simple-token for a reason: it’s super simple. It is a base-standard ERC20 token with a fixed supply of tokens, created at token the token’s initialization, and given to the address who deploys the contract. There are no administrative functions in the token (for minting or burning, for example — this contract doesn’t support those functions). It’s very basic, but a good starting point for understanding how a token works and deploying one.

Let’s walk through it.

Prereqs

Install the necessary dependencies, namely git and yarn .

Then clone down the repo with

and install the dependencies with

$ yarn install

Config

The project uses environment variables for configuration options, such as the token’s name, symbol, decimals, and total supply.

We use the dotenv package to manage environment variables (which was installed via yarn install above), which means that we need a .env file in the project. It’s not included by default upon cloning the project down, so use the .env.example file to create one for yourself

$ cp .env.example .env

Open up .env and change the values to whatever you see fit. I recommend keeping the number of decimals at 18 , as this will provide the best experience when interacting with the rest of the Ethereum Token ecosystem.

Code

Start off in ./contracts/SimpleToken.sol . Notice how the contract inherits from ERC20 and ERC20Detailed . These two contracts are provided by the wonderful openzeppelin-solidity project, of which I have copied the relevant files into this project.

The constructor, which is executed one time — upon contract deployment — expect 4 arguments to be passed in: name , symbol , decimals , and totalSupply .

The SimpleToken 's constructor then, in turn, calls the constructor of its inherited ERC20Detailed contract, passing in name , symbol , and decimals . Then the constructor executes the single line of custom code in this project (lol): _mint(msg.sender, _totalSupply) .

That line calls the _mint(address, uint) function which lives in ./contracts/openzeppelin/contracts/token/ERC20/ERC20.sol (it’s from openzeppelin), using msg.sender of the transaction as the recipient of the new tokens, and the passed-in totalSupply as the total number of tokens to create.

I highly encourage the interested reader to start digging into the ERC20 and ERC20Detailed contracts that live in ./contracts/openzeppelin/contracts/tokens/ERC20/ directory, as this is where 100% of the ERC20 spec for SimpleToken.sol is implemented. When dealing with immutable code, it’s best to use code that has been heavily audited and accepted by the community, which is the goal of openzeppelin: to be a source for trusted solidity implementations of common contract patterns.

Deploy

So how do we pass these 4 variables into the contract upon deployment? Simple — we use truffle for that (also installed from yarn install above).

The truffle tooling provides an easy way to deploy contracts to various Ethereum networks, through the truffle migrate command.

Head into ./migrations/2_deploy_simple_token.js and notice how the deployer object has a function called deploy which takes n number of arguments, with argument 1 being a reference to the contract to deploy, and arguments 2 through n being whatever n-1 variables we want to pass in to the contract’s constructor.

As mentioned above, we’re using environment variables for the name , symbol , decimals , and totalSupply , so all we have to do is use dotenv to pull them from our environment and set them in the deploy function. That is as simple as referencing them using the syntax: process.env.ENV_VAR_NAME .

This project is not currently set up for deployment onto any “real” networks, but works very well for deploying onto a local blockchain that can be started using the truffle toolset.

Check out the Local Development section of the README to learn more about how to start a local blockchain, migrate contracts onto it, then connect to it with Metamask to examine the token and interact with it.

Next Steps

When you’re comfortable with the codebase and deploying it locally, the next step would be to deploy this contract onto a real public network, such as Ropsten, Rinkeby, Görli, or (gasp) MAINNET.

Left as an exercise for the reader, you’ll need to modify ./truffle-config.js to “set up” these networks. If you’re not running a node on one of these public networks, you’ll need to connect to an existing node to broadcast your contract transaction, and will need a funded Ethereum account to do so. Getting all of this set up will require changes to the codebase.

Hint —

This will come in handy: https://infura.io/

So will this: https://github.com/trufflesuite/truffle-hdwallet-provider

Disclaimer and P.S.

This is meant to be an educational exercise. Deploy code at your own risk. Yadda yadda.