The switch to 18 decimal places has some ergonomic consequences for developers.
There’s a total of 231 tokens available, ie 31 bits.
18 decimal places adds another 59.8 bits.
The full currency supply at 18 decimal places needs at least 90.8 bits to correctly represent, which is a challenge considering most platforms are 64 bit.
This means most developers will need to use an external library to do basic math on these values.
Another unusual aspect of the design is the Amount
is a U256
(source) and there are conversions for u64
and u128
(source). This is all fine in rust but I do feel like there are going to be ergonomic issues in other languages.
This is a byproduct of using ethereum, and there seem to be some reasonable explanations for why 18 decimal places was chosen in this question: Why is ether divisible to 18 decimal places.
sn_transfers
crate still uses nanos and u64
.
I think this will all work out in the end but some simplicity has been lost. The topic of decimal places was originally debated a lot on this forum, but I guess eth has settled it for us.
Some common languages calculating at 18 decimal places
Python
Decimal - broken
>>> 20.123456789123456789 + 30.123456789123456789
50.24691357824691
Integer - works
>>> 20123456789123456789 + 30123456789123456789
50246913578246913578
>>> from decimal import Decimal
>>> # wrong way broken
>>> Decimal(20.123456789123456789) + Decimal(30.123456789123456789)
Decimal('50.24691357824691095856906031')
>>> # right way works
>>> frac = Decimal(123456789123456789)/Decimal(1000000000000000000)
>>> Decimal(20) + frac + Decimal(30) + frac
Decimal('50.246913578246913578')
Excel
Decimal (automatically rounded)
20.1234567891235
30.1234567891235
50.2469135782469
Integer (default format)
2.01234567891235E+019
3.01234567891235E+019
5.02469135782469E+019
Integer (integer format)
20123456789123500000
30123456789123500000
50246913578246900000
Javascript
Decimal - broken
20.123456789123456789 + 30.123456789123456789
50.24691357824691
Integer - broken
20123456789123456789 + 30123456789123456789
50246913578246910000
BigInteger - works
20123456789123456789n + 30123456789123456789n
50246913578246913578n