# Create an ERC20 using Truffle, without writing Solidity

**URL:** <https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713>\
**Category:** Guides and Tutorials\
**Created:** [April 23, 2020, 5:52am UTC](https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713 "2020-04-23T05:52:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [April 23, 2020, 5:52am UTC](https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713/1 "2020-04-23T05:52:44Z")

</div>

![cover_forum_create_an_erc20](https://us1.discourse-cdn.com/flex022/uploads/zeppelin/original/2X/2/23e101fd8acee48c32298e75daa21ff406ef4ff3.png)

In this tutorial we will use a [Preset](https://docs.openzeppelin.com/contracts/3.x/api/presets) ERC20 contract in [OpenZeppelin Contracts v3.x](https://docs.openzeppelin.com/contracts/3.x/) to create an ERC20 using [Truffle](https://www.trufflesuite.com/), **without having to write any Solidity code**.

## Setting up the Environment

We begin by creating a new project.

```auto
$ mkdir mytoken && cd mytoken
$ npm init -y

```

Then we install [OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts)

```auto
$ npm i --save-dev @openzeppelin/contracts

```

Next we install a development tool for deployment, for this tutorial we will use [Truffle](https://www.trufflesuite.com/) but we could use any other tools such as [OpenZeppelin CLI](https://forum.openzeppelin.com/t/creating-an-erc20-using-presets-in-openzeppelin-contracts-with-openzeppelin-cli-without-writing-solidity/2698).

```auto
$ npm i truffle

```

## Getting the contract artifacts

We will setup our Solidity project using `truffle init` to create a `contracts` directory and configuration to connect to a network.

```auto
$ npx truffle init

Starting init...
================

> Copying project files to /home/abcoathup/projects/mytoken

Init successful, sweet!

```

We are going to use Preset [`ERC20PresetMinterPauser`](https://docs.openzeppelin.com/contracts/3.x/api/presets#ERC20PresetMinterPauser) which is an ERC20 that is preset so it can be minted, paused and burned.

The Preset contracts have already been compiled, so we only need to copy the artifacts to the `build/contracts` directory.

```auto
$ mkdir -p build/contracts/
$ cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/

```

## Deploy the contract

We will use [`truffle develop`](https://www.trufflesuite.com/docs/truffle/reference/truffle-commands#develop) to open a Truffle console with a development blockchain

```auto
$ npx truffle develop
Truffle Develop started at http://127.0.0.1:9545/

Accounts:
(0) 0x0445c33bdce670d57189158b88c0034b579f37ce
(1) 0x46b68a577f95d02d2732cbe93c1809e9ca25b443
(2) 0xff8ddfd4ae8ed56c4b94738fef931b732f3aaeb5
(3) 0xc28aaeb2c63c3617e6733d786a6d7273871b805f
...

Private Keys:
(0) 11e8321617611610d7561dfdf1fdbf87cee4cc99b97cc73c68f0eb5715fff7cc
(1) b28ee7deb262fbb6cccabb43179406e97bf7ff4c20b66feac3321019373531bd
(2) 44e5ce1f204a63e50faf2f202af1d5653aace83805dd9bc7062033f0625aaaa7
(3) 168e28ad21ede684f8fd3ddc8b88e9474c740884f43bda1d567e968544b53a6e
...

Mnemonic: ridge drop soon clutch empty north car drum maximum obey clinic coin

⚠️ Important ⚠️ : This mnemonic was created for you by Truffle. It is not secure.
Ensure you do not use it on production blockchains, or else you risk losing funds.

truffle(develop)>

```

We can deploy our new token to our development blockchain. Providing a name and a symbol as parameters to the constructor to create a new `ERC20PresetMinterPauser`.

```auto
truffle(develop)> token = await ERC20PresetMinterPauser.new("My Token", "TKN")
undefined

```

## Interact with our Token

The accounts that we can use were displayed when we started `truffle develop`

### Token metadata

We can call the contract to read token metadata such as `name`, `symbol` and `decimals`

```auto
truffle(develop)> await token.name()
'My Token'
truffle(develop)> await token.symbol()
'TKN'
truffle(develop)> (await token.decimals()).toString()
'18'

```

### Mint

We can send a transaction to mint tokens to a given account, from an account with the minter role.  
In our case we are minting from the account which deployed the token, which is given the minter role.

We will mint 1000 tokens (the token has 18 decimals).

```auto
truffle(develop)> await token.mint('0x46b68a577f95d02d2732cbe93c1809e9ca25b443','1000000000000000000000')
{
  tx: '0xf04c4342eadd64e81ba631d7340ca1bec4f402f2775e8a9087c8af06ff34e7c7',
  receipt: {
    transactionHash: '0xf04c4342eadd64e81ba631d7340ca1bec4f402f2775e8a9087c8af06ff34e7c7',
    transactionIndex: 0,
    blockHash: '0x907fc78d3973dc1b3081148c2ab3172857f32ffc73d6102b756033f60431c850',
    blockNumber: 2,
    from: '0x0445c33bdce670d57189158b88c0034b579f37ce',
    to: '0x3797c825cac4a1fa765f6d8cd7787fb195849555',
    gasUsed: 68253,
...

```

We can check the balance

```auto
truffle(develop)> (await token.balanceOf('0x46b68a577f95d02d2732cbe93c1809e9ca25b443')).toString()
'1000000000000000000000'

```

### Burn

We can send a transaction to burn tokens (from the account holder)

```auto
truffle(develop)> await token.burn('10000000000000000000', {from: '0x46b68a577f95d02d2732cbe93c1809e9ca25b443'})
{
  tx: '0x626b3c012f8edb66cbb45b279554c8f0ac9f5db35097e1364a45e9df5e96027e',
  receipt: {
    transactionHash: '0x626b3c012f8edb66cbb45b279554c8f0ac9f5db35097e1364a45e9df5e96027e',
    transactionIndex: 0,
    blockHash: '0x73ec9a1245d2d28cf08aaefb63975542c8c23ee221ef3479a26e00f5fbc7b949',
    blockNumber: 3,
    from: '0x46b68a577f95d02d2732cbe93c1809e9ca25b443',
    to: '0x3797c825cac4a1fa765f6d8cd7787fb195849555',
    gasUsed: 36797,
...

```

We can check the balance after burning

```auto
truffle(develop)> (await token.balanceOf('0x46b68a577f95d02d2732cbe93c1809e9ca25b443')).toString()
'990000000000000000000'

```

### Pause

We can pause our Token by sending a transaction calling the `pause` function, from an account with the pauser role.  
In our case we are pausing from the account which deployed the token, which is given the pauser role.

```auto
truffle(develop)> await token.pause()
{
  tx: '0x93385cbb2d893658878db962cce2fcc520e211cfdc1a9d49660489b8d20b6768',
  receipt: {
    transactionHash: '0x93385cbb2d893658878db962cce2fcc520e211cfdc1a9d49660489b8d20b6768',
    transactionIndex: 0,
    blockHash: '0x84529e46656d47dd642b10ed3606b7306de8020060d7711dc5a963d6cb4f142a',
    blockNumber: 4,
    from: '0x0445c33bdce670d57189158b88c0034b579f37ce',
    to: '0x3797c825cac4a1fa765f6d8cd7787fb195849555',
    gasUsed: 30548,
...

```

Transactions which attempt to transfer (such as `mint`) will revert whilst paused.

```auto
truffle(develop)> await token.mint('0x46b68a577f95d02d2732cbe93c1809e9ca25b443','1000000000000000000000')
Thrown:
Error: Returned error: VM Exception while processing transaction: revert ERC20Pausable: token transfer while paused -- Reason given: ERC20Pausable: token transfer while paused.    
...

```

## Video

I made an asciinema going through all the steps in the tutorial:  
[https://asciinema.org/a/364291](https://asciinema.org/a/364291)

## Next steps

- We could deploy using `truffle migrate` and the following migration script

```auto
// migrations/2_deploy.js

const Token = artifacts.require('@openzeppelin/contracts/ERC20PresetMinterPauser');

module.exports = function(deployer) {
  deployer.deploy(Token, 'My Token', 'MYT');
};

```

- We could deploy to a public test network (see [Connecting to Public Test Networks with Truffle](https://forum.openzeppelin.com/t/connecting-to-public-test-networks-with-truffle/2960))
- We could [extend](https://docs.openzeppelin.com/contracts/3.x/extending-contracts) `ERC20PresetMinterPauser`
- If we write contract code we should [write automated tests](https://docs.openzeppelin.com/learn/writing-automated-tests)
- [Points to consider when creating a fungible token (ERC20, ERC777)](https://forum.openzeppelin.com/t/points-to-consider-when-creating-a-fungible-token-erc20-erc777/2915)

---

<div class="post-metadata">

**Author:** ![abcoathup](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/abcoathup/32/415_2.png) [@abcoathup](https://forum.openzeppelin.com/u/abcoathup)\
**Post date:** [June 12, 2020, 12:57am UTC](https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713/2 "2020-06-12T00:57:13Z")

</div>

A post was split to a new topic: [Are there any DAO based ERC20s?](https://forum.openzeppelin.com/t/are-there-any-dao-based-erc20s/3088)

---

<div class="post-metadata">

**Author:** ![Skyge](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/skyge/32/343_2.png) [@Skyge](https://forum.openzeppelin.com/u/Skyge)\
**Post date:** [May 21, 2021, 11:03am UTC](https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713/3 "2021-05-21T11:03:59Z")

</div>

3 posts were split to a new topic: [Test ERC20 with Truffle](https://forum.openzeppelin.com/t/test-erc20-with-truffle/8888)

---

<div class="post-metadata">

**Author:** ![Censorable](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/censorable/32/13265_2.png) [@Censorable](https://forum.openzeppelin.com/u/Censorable)\
**Post date:** [February 16, 2022, 5:45pm UTC](https://forum.openzeppelin.com/t/create-an-erc20-using-truffle-without-writing-solidity/2713/5 "2022-02-16T17:45:57Z")

</div>

Cannot get this to work any longer.

```auto
npx truffle init

```

Running the command above now ends with 94 packages needing funding, 54 vulnerabilities(1 low, 35 moderate, 16 high, 2 critical). Trying to ignore this and move forward regardless.

```auto
npx truffle development

```

The command above doesn't work and provides the following error

```auto
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:135:10)
    at hash160 (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\node_modules\ethereum-cryptography\vendor\hdkey-without-crypto.js:249:1)
    at HDKey.set (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\node_modules\ethereum-cryptography\vendor\hdkey-without-crypto.js:50:1)
    at Function.HDKey.fromMasterSeed (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\node_modules\ethereum-cryptography\vendor\hdkey-without-crypto.js:194:1)
    at Function.EthereumHDKey.fromMasterSeed (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\node_modules\ethereumjs-wallet\dist\hdkey.js:16:1)
    at Object.getAccountsInfo (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\packages\core\lib\mnemonics\mnemonic.js:45:1)
    at Object.module.exports [as run] (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\packages\core\lib\commands\develop\run.js:30:44)
    at Command.run (C:\Users\SGK\Documents\Ethereum\Token\node_modules\truffle\build\webpack:\packages\core\lib\command.js:189:1)
Truffle v5.4.33 (core: 5.4.33)
Node v17.4.0

```
