I'm having an odd problem working with some ERC20 token contracts I've written:

When I specify a decimal value, let's say 4 here for simplicity, the values show up differently in Mist vs etherscan.

For example, if I create a token with a supply of 1 with decimals of 4, the tokens show up as a value of 0.0001 in Mist but the value shows up as 1 in etherscan; however, if I click on the ERC20 icon in etherscan to view details on the token, there it agrees with Mist and states that the token supply is 0.0001.

So, I understand that the contract is going to be working with the smallest unit of the token, as set by the decimals value in the constructor; but I'm not quite sure how to get the value of the token itself, rather than the smaller units, to display in Mist and etherscan. Let me know if that doesn't make sense.


2 Answers 2


The way I think about this is that the number of tokens is:

tokenSupply = tokensIActuallyWant * (10 ** decimals)

If I want 1 token with the ability to subdivide it with a precision of 2 decimal places, I represent that as 100.

Similarly if I want 1 token with the ability to subdivide that to 18 decimal places, I need to represent that as 1000000000000000000 (1 with 18 zeros).

Hope that helps.

  • To help clarify, using the terms in ERC-20: totalSupply = tokensIActuallyWant * (10 ^ decimals)
    – eth
    Oct 8, 2017 at 20:14
  • 3
    so if I do not want my tokens to be divisible at all, i.e the smallest token unit is 1 token, then I ought to specify decimals = 0?
    – Dave Sag
    Feb 22, 2018 at 7:19
  • Dave Sag: Yes. Exactly. Apr 27, 2018 at 8:03
  • 4
    Beware that caret ^ in Solidity is a bitwise operator and has nothing to do with exponentiation, which syntax is e.g. ´uint32 tenThousand = 10**4;`
    – blackscale
    Jul 11, 2019 at 10:13

Like many words in crypto (e.g. wallet), the term token has several distinct definitions, mostly depending on context.

Token: usually short for ERC20 token on the Ethereum mainnet.

Token (or replaced by token name or symbol): unit used by smart contracts for accounting (smart contracts work on integers, so there can't be any decimals). Think of it as the smallest possible unit, comparable to wei for Ether.

Token (or replaced by token name or symbol): unit used for display to users (in any UI, from wallets to exchanges or any Dapp). This is comparable to Ether, which uses 18 decimals for display. When showing 1080250000000000000000 for an 18 decimals token, it is much more user-friendly to display it as 1'080.25 instead.

To maintain precision, make sure you use big integers in your JS, and convert to/from float right after/before you sanitize user input. And in your smart contract, you only reason in integers [see notes below], and that's the only kind of numbers it expects to receive as transaction data.

Be extra careful if you use less than 18 decimals, and even more so with zero. Divisions will exhibit stepwise behaviour when applied to small (or not so small, you'd be surprised) quantities of tokens and your smart contract might behave weirdly. It may even hinder the token's ability to be efficiently traded, or even listed on exchanges.

[notes] Solidity can handle fractions and high precision calculations, but when it comes to storing the result, it can only store integer values. Using the most common and optimal type, uint256, you will be able to store numbers as large as 10**77.

If your ERC20 token uses 18 decimals, your "display token" maximum total supply is around 10**59. There is no gain in using a smaller type (e.g. uint192) due to how the EVM works, and at 18 decimals there is already ample space in both directions (total supply, and division precision). Keep the default 18 decimals unless you really know what you are doing, why, and with which consequences.

Not the answer you're looking for? Browse other questions tagged or ask your own question.