PreciousChickenToken: A guided example of OpenZeppelin's ERC20 using Ethers, Truffle and React

I’ve asked a fair few questions recently of @abcoathup regards ERC20s, and I appreciate his help.

It is my practice to blog when I’m learning something new, it helps me understand the material better; so here is my attempt to work through some of the basics on ERC20s:

PreciousChickenToken: A guided example of OpenZeppelin’s ERC20 using Ethers, Truffle and React

As I hope I make clear, it is more about working code than best practice; but might be helpful to others. Feedback always appreciated.

3 Likes

Hi @PreciousChicken,

Thanks for sharing your blog post. I think writing a blog post is a great way to learn, I :heart: seeing tutorials from the community.

Sorry for the delay in responding, I was on vacation last week :desert_island:

I had a look through the post and had the following feedback:

I noticed that you installed truffle globally, my personal preference is Installing packages locally rather than globally (npx)

I would keep any non-core functionality separate from the token (such as purchasing). The token should ideally just be the functionality to use the token. If you have purchasing functionality you can put this in a separate contract.

You could also transfer an amount of tokens to the purchasing functionality contract rather than having to set an allowance for the token contract to be able to use some of the deployer of the token contracts tokens.

The pragma could be ^0.6.2 as 0.6.2 is the minimum compiler version that we can use due to dependencies in OpenZeppelin Contracts.

There is a typo in the SPDX license: The Unlicense (MIT is a great license to use).

I know that you are aware that you didn't handle decimals. The token has 18 decimals. You could change this to have 0 decimals.

By default, ERC20 uses a value of 18 for decimals . To use a different value, you will need to call _setupDecimals in your constructor.

The total supply is 1000/(10^18) so in MetaMask when added as a custom token will show as 0.000 PCT
For information on decimals see: https://docs.openzeppelin.com/contracts/3.x/erc20#a-note-on-decimals

Rather than changing the build artifacts to client/src/contracts you could create a soft link. (ln -s ../../build/contracts/ contracts)


Well done on creating a guide that can be followed and a nice demo app.

1 Like

I really appreciate your reply; wasn't expecting you to go into such depth, but it is good of you to take the time. I hope you had a good vacation (and managed to get up to some nice stuff despite the pandemic).

I've altered a fair bit of my post in line with your suggestions, so will give feedback on your feedback :grinning::

I noticed that you installed truffle globally, my personal preference is Installing packages locally rather than globally (npx)

Same here. I prefer local installs, much neater. However the audience for this post is very much beginner - therefore they should follow all the instructions and it should hopefully work first time. However it they've followed the official truffle install guide previously, which is entirely possible; then installing via npx on top of a global install might cause problems. In which case they'd need to uninstall globally before installing again with npx. And that's just too much blurb. On the other hand if they've previously installed globally, and just do it again using my instructions, it should still work.

I would keep any non-core functionality separate from the token (such as purchasing). The token should ideally just be the functionality to use the token. If you have purchasing functionality you can put this in a separate contract.

You could also transfer an amount of tokens to the purchasing functionality contract rather than having to set an allowance for the token contract to be able to use some of the deployer of the token contracts tokens.

This would be a definite improvement. I've copied this advice into the conclusion section and linked to your post, in case people are using my guide as a jumping off point.

The pragma could be ^0.6.2 as 0.6.2 is the minimum compiler version that we can use due to dependencies in OpenZeppelin Contracts.

I think I previously referred to 0.6.0 in some places, and 0.6.1 in others, so I've made them all 0.6.2; thanks for pointing this out.

There is a typo in the SPDX license: The Unlicense (MIT is a great license to use).

Embarrassing - no idea how I achieved this as the compiler would have thrown this out :thinking:. Either way, corrected, thanks for flagging.

I know that you are aware that you didn’t handle decimals. The token has 18 decimals. You could change this to have 0 decimals.

Done, thanks for suggestion.

Rather than changing the build artifacts to client/src/contracts you could create a soft link. ( ln -s ../../build/contracts/ contracts )

You could argue a soft link is more elegant. However the advantage of building it in the client directory is if you deploy anywhere other than locally (e.g. Vercel) you are going to want the build products in the same folder as React. One of the nice things about writing a blog is your code examples serve as templates for you later, and I'm interested in deploying smart contracts other than locally. However I've included the option in the explanation anyway so people can do either.

I also made a fairly major change unrelated to the ERC20; I figured out how to get Metamask to connect to the React app without all the localhost configuration; so it should be more seamless for people following the guide.

Anyway I really do appreciate your guidance, it is very good of you to take the time to offer such great suggestions.

1 Like

Thanks again for writing the guide. Writing content is hard and takes time, so always want to give feedback if I can as a small way of saying thanks.

Also building the knowledge base of the community is so important. We are all learning.

I assumed (incorrectly) that the compiler would check the license text but you have shown any random text will compile.

// SPDX-License-Identifier: RANDOM_TEXT

pragma solidity ^0.6.0;

contract MyContract {

}
$ npx oz compile
✓ Compiled contracts with solc 0.6.11 (commit.5ef660b1)

I must confess I didn't go through your MetaMask instructions.

I use ganache-cli -d so get the same accounts and I have imported some of the private keys.

For connecting to public testnets with truffle, I have the following guide that you could suggest: Connecting to Public Test Networks with Truffle


With regards your forget me not project, if the main concept is proof of existence,
you could be storing IPFS hashes with the content even being encrypted. This would reduce the gas costs.

To reduce the gas costs even more you could just emit events using a Stateless Smart Contract.

1 Like

Random text is my speciality :slightly_smiling_face:.

Yes, exactly, that is what I plan to look at next. Thank you for taking a look at my research.

That's a really interesting read, I hadn't seen this concept before. I can see pros and cons, but certainly worth being aware of.

1 Like