-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposed ERC20 change: make 18 decimal places compulsory #724
Comments
I think this is a very good idea, and strongly support it. |
How would we handle existing erc20s with other choice of decimals?
Recommend a hard fork (move balance to new contract)?
…On Thursday, September 28, 2017, Martin Holst Swende < ***@***.***> wrote:
I think this is a very good idea, and strongly support it.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#724 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ABXf-2G78x19t8XByBCKSzbZ14ShdYwpks5sm1iFgaJpZM4Pm5UT>
.
|
The main issues, IMHO:
My proposal would be:
|
ACK @alexvandesande idea of setting this as a default NACK on removing option to set decimals. Tokens that have real utility may not be arbitrarily divisible to 18 decimal places, and this would create a more confusing user experience for these tokens. Example: consider an API token where 1 unit gives access to a functionality worth $5. Requiring 18 decimals gives you one of two choices: either allow people to hold "partial API credits", which may be confusing to users, or give your token a very high per-unit valuation, which may also be confusing to users. To solve the light client issue, perhaps require tokens to issue an event on genesis with their lite-client-pertinent parameters. |
Could the standard not be updated to be encouraged to define the decimals within their contract through a standardized variable or return function, which could be read by the wallets, otherwise default to 18 unless otherwise specified? I'd agree that we should maintain the option for != 18 decimals but encourage some default and not break backwards compatibility. |
ERC-20 is a finalized community standard (#20). Imo if a standard, such as ERC-20, were to be updated after finalization it should either take on a new ERC number, such as #223, or take on a versioning scheme such as "version 2". For this particular case I suggest that this rule be added to another upcoming token standard, such as #223. This prevents already existing ERC-20 tokens from not being considered "ERC-20 compliant". |
@Souptacular I absolutely agree with this. The IETF RFC process is exactly the same, once an RFC is finalized it's done. Future RFCs can superseded previous RFCs and building on #223 is the way to go. #20 would simply be "updated" to state that it is updated by #223 and no longer best practice once finalized (if accepted and finalized). |
I strongly support a token standard with a fixed number of decimals! With the words of @prusnak (CTO of @satoshilabs) :
Really good for offline-solutions/hardware wallets! |
#223 already defines a decimals() return function so at this point I think the debate is just "Make 18 mandatory?" - My vote is no, too restrictive. |
Introducing decimals was a very bad engineering move in the first place. I support having the fixed value. |
Please discuss further in #223. #20 is finalized and therefore immutable at this point aside from typos and |
My support level for this proposal is over 9000! 🔥 |
Over 40% of the tokens listed at http://etherscan.io/tokens do not use 18 for their decimals value. Retrospectively changing the ERC-20 specification would cause far more harm than good. |
I think the case of non-divisable tokens is a pretty good usecase; where a token represents a non-divisable thing. Such as tokens representing membership or Beertoken (where one wei would be one atto-beer). But I'd rather see the a boolean: And I don't think this necessarily is tied to #223, but I agree not to retroactively change ERC20. This should be a new ERC. |
Can we please focus on the topic itself and not on the format of the ERC? It's clear by now that this is not about ERC20, but a forward looking standard?
Great point, let's go for numbers! Using MyEtherWallet Big list of tokens of 191 popular tokens here are the stats I calculated:
Over 51% use 18 decimals, followed by 21% that uses 8 decimals, followed by 10% using no decimals at all. (no one uses more). Seems the standard is coalescing for 18. For me, even if this proposal is not accepted, is already data enough for Mist to guess the default of 18 for any tokens that do not specify it. |
I believe tokens deployed with the Parity DApp default to 8 decimals. That could explain why so many tokens have 8. But I'm happy to change that to anything that makes sense. |
@alexvandesande my numbers were to highlight how changing the spec retrospectively would be bad rather than any suggestion about values for the future. There are good arguments for the divisibility of tokens at the least being 0 (indivisible) or some high value (e.g. 18 near-continuous). This could be enabled with a flag rather than an int, although then it would still require a query of the blockchain to find out its value and so doesn't help the offline use case. Hard-coding decimals to 18 makes it impossible to have an indivisible token (the token itself can handle indivisibility inside its own contract but what about partial token transfer on exchanges for example?). Losing such functionality seems like a big step. |
I personally don't think indivisible tokens are a big issue. Every use case I can think of can simply take the floor of the number of tokens when counting, eg, memberships, subscriptions, badges, etc. Token contracts can be written to only transfer whole numbers if desired, too, and exchanges wishing to list that token will have to adapt. |
@Arachnid but how would an exchange know that a token is meant to be indivisible? |
mcdee's point is definitely worth considering; we currently have this extra logic for variable decimals, but if we want to also support indivisible tokens via a boolean, we're just adding a different (and more specific) logic to contracts that interact with these new standardized tokens. Perhaps a middle ground: say we have an indivisible token contract with exactly 10 total supply. the contract provides some sort of indicator that they are indivisible (aka have 0 decimal places) via an optional public constant. Then any dapp that interacts with these indivisible tokens either
Regardless, the math is the same (the token is indivisible), and only the presentation is affected. It might be weird handling Additionally, if an indivisible token wanted to be able to be traded on an exchange divisibly (I'm really surprised autocorrect understands that word), but only used indivisibly, it could do the "only whole numbers accepted" logic in its own contracts, isolating the extra logic. |
If I understand it correctly, the proposal is to remove the |
@mcdee That's up to the exchange. They can add a field for it in their database. Nevertheless, I'd like to hear a use-case for an indivisible token that should actually prohibit part-tokens rather than just round them down when counting them for whatever purpose they exist. |
But how does the token owner let the exchange know? The only sane method is to add a field to their contract to allow the exchanges to pick up the value, and we're right back where we started.
As to flooring partial token transfers: let's say that I have a token I want to be indivisible and the code receives a request to transfer 1.510^18 tokens. Rounding it down so that only 110^18 tokens is transferred is bad because the contract hasn't done what was requested of it. Should the contract throw instead? That would confuse users as they could see that their balance was enough to carry out the transfer. As to a use case for indivisible tokens, how about a token that represents 100g of physical gold? The company needs to be able to exchange tokens for physical gold if required, and doesn't want someone turning up with 0.00876543212345678 tokens expecting them to be changed for a sliver of metal. The general point holds for many items where a single token could represent a physical or logical entity and the token holder doesn't want said entity to be partially owned. |
Are you presupposing an exchange that automatically lists tokens? I was thinking of 'traditional' exchanges. Nevertheless, there are always going to be tokens that have weird transfer conditions, etc. Perhaps such tokens simply won't work with some exchanges.
No, it would transfer 1.5e18 base tokens. If you previously had 3 tokens and the recipient had 0, you now both have 1.5 tokens - and for the purpose of counting subscriptions / badges / whatever, you each have 1.
Then the store need merely say "we only accept integer numbers of tokens", and reject all offers to exchange fractional amounts. |
0x (and other distributed exchanges/exchange protocols) allow any ERC-20 token, so yes automatic.
This and the idea of notifying exchanges of divisibility is moving functionality that currently exists in ERC-20 through use of decimals to manual or otherwise off-chain notifications/enforcement. Doesn't feel very "smart contract" to me. Hard-coding decimals to 18 is a reduction in the on-chain functionality that exists today, to the benefit of UIs for offline transaction generation. From Alex's post above just under half of existing tokens made a different choice which must suggest that there is utility in having the option available. |
The simplest solution would be to subclass tokens. Keep the existing, or substantially similar standard, and allow for sub-classification as: |
I agree about divisiblity - but I don't think a store saying they'll only accept integer numbers of tokens is a problem. In fact, the "10g of gold token" you hypothesise seems more useful if it can be subdivided, even if you can only redeem integer quantities. I'm ambivalent about the proposal to hardcode decimals, but I don't think indivisible tokens are a compelling argument against it. |
I agree. A token can be indivisible and still have 18 decimal points that aren't used, and in the implementation, just fail if someone tries to send less than 1. An app that isn't aware of the indivisibility, would just present your balance as 1.000000000000000000 (which any reasonable app would just display 1), and it will fail when sending less than 1. Same things for an exchange: it can allow to sell fractions of the token, it just needs to alert the user that they won't be able to withdrawal floating point amounts. Personally, I decided to go forward and update the ERC20 example on the homepage to have 18 decimals as the strongly suggested default. No change on the ERC at all. |
So, we have two tokens, one to 8 d.p. and one to 18 d.p and both were deliberate calculated decisions that actually make sense to us. It makes no sense for the first to be subdivided to smaller fractions because there is no utility in those smaller numbers - but I would have to add MORE code to ensure that all transfers are rounded to 8 dp? That really makes no sense to me at all. On the other hand, accepting but disregarding the fractions below the 8 dp range also makes no sense because the remainder bits would be worthless yet charged for in an exchange. To summarise, the argument for 18 is because we have a standard that
|
|
The point of decimals is not to establish a minimum, it's to establish a minimum increment. A token can represent a unit of something, and that unit can be divisable only down to a certain amount, for a reason. There seems to be some confusion between unit and precision in this discussion. Depending on what we're measuring, we can have the same SI Unit, but different precision needs. Let's consider the metric weight unit in the SI, for instance:
Well, the point is that more decimal places may not mean anything. If I have a token where only 3 decimals make sense, the UI should be able to use the decimals() field to provide a fixed-size display, and there should be no way to store values that don't make sense. Ultimately, it shouldn't matter much how tokens are stored internally, what matters is how people perceive and interact with value. As we are today, most sane wallets already multiply by As a sidenote, I can't help but feel that JS's lack of native support for infinite precision, led us to go back to the stone age. :) We should be able to use 20.0002 rather than 20000200000000000000 - now that would be something. |
As @o0ragman0o put it 18 decimals only makes sense in trying to find a common ground between human readable ETH and gas prices. For tokens this only forces us to have extra complication. Ideally keeping the bulk of your numbers ahead of the decimal makes things easier to talk about. Look at bitcoin. We are forced to make up units to make talking about 1 hundredth and 1 thousandth easier to talk about. If you can accurately predict the popularity of your token you don't have to make up these units. With USD we have dollars and cents and most things cost more than a penny. What would happen if most things cost less than a penny? What if a pack of gum costs 0.0003 of your token? Now you need a new word. Every popular token will need list of tiny units. The point is if you don't want to keep making up names for every small amount of every token then you will keep your units ahead of the decimal. Just because 18 decimals is good for Ethereum doesn't mean it's good for every token. In fact it's probably worse in almost every other case. For display if you have 18 decimals and you want to accurately display how many tokens someone has you must print down to 0.000000000000000001 for legal purposes. You can't say they have 0.000. That would be incorrect. That is a display nightmare. If your token only has 3 decimals for instance you can legally tell someone they have 0.001 and it is accurate. There are no indivisible tokens such as securities tokens representing 1 stock. This is a very strong case for 0 decimals. It's easy to fit them into the ERC20 standard as-is. We already have all the tools we need in the current ERC20 to handle most cases. Once you add the code to handle the decimals you never have to deal with it again. You will also encourage more bugs. If apps start expecting tokens to have 18 decimals and then one comes along that does not there will be a bug. This means that as long as even 1 popular token uses a different amount of decimals you will need to code for it and since that number is currently 49% the day will never come when you can expect 100% at 18 decimals. In fact with the coming representation of more real world assets it will probably become more likely that some tokens will require a specific divisibility. It seems to me that the status quo is working fine and is very future friendly. I can understand the desire simplify things, but I think if we would have started off at mandatory 18 we would have eventually had to add the optional decimal place as a feature. I think removing it is not progress. I think we will likely have to add more features, not remove them. I think it is very convenient that we have the decimal feature and allows for many use cases while being very explicit in how we handle it in the code. It's mostly for display only so all you have to do is insert the decimal at end for your display. It's a simple modification that handles real world use cases for tokens. Tokens are not the same as Ethereum. |
@nickjuntilla Discussion about decimals should be moved to one of the new token standards, as ERC20 is final and thus immutable aside from grammar/spelling/clarity updates.
If you decide to continue discussing elsewhere, this is the point you are going to have to argue much more strongly for. Predicting the future value of your token is nearly impossible. Even fiat currency which has a guiding hand trying really hard to keep its value fixed still fluctuates with time (a penny/pence/cent used to be meaningful, but it no longer is). |
There are lots of use-cases that require 0 decimals for legal reasons. For example, it is legally impossible to own 13.2 shares of a company. So if you want to properly implement shares on the blockchain, you must be able to enforce decimals = 0 with ERC-20. Otherwise, you cannot use ERC-20 tokens for shares or bonds and many other established financial constructs. |
That can be implemented in the token by having it throw if a user tries to transfer a non-insignificant number of tokens. See ERC-777 for some thoughts on this. |
@MicahZoltu That would result in a horrible user experience. It should not be the responsibility of the user to get the number of significant digits right in a transaction, this should be automatically done by the wallet. Thus, there must be a way to signal to the wallet what the granularity is, which is done with the decimals field in ERC-20. The approach of ERC-777 is inferior in many regards. Also note that the natural interpretation of an integer including uint256 is to say that 1 means 1, and not that 1 means 0.000000000000000001. |
Would propose not making it compulsory, could be default. Here at TrustToken we have some real use cases where less than 18 decimals makes sense. |
I'm very sympathetic to this proposal, but I think it's a bit too late to make it compulsory given how some coins already are (like USDC that uses 6 decimals). However, we really need some kind of name or maybe a separate standard for 18-decimal ERC20 tokens. Building dapps that are supposed to work with multiple ERC20 coins is getting really annoying when most coins are 18 decimals except for a handful that come up and surprise you during development. |
All ERC-20 token amounts are integers, as well as all Ether amounts. This is quite common practice in financial IT, and crypto-financial IT isn't different. When large token amount is to be presented to a user, it could be convenient to render it in larger units, rather than in base units. For ether amounts, common larger units are GWei (10^9), Szabo (10^12), Finney (10^15), and Ether (10^18). Less common units are KWei (10^3), MWei (10^6), KEther (10^21), etc. When rendered in any of such units, ether amount could look like a fractional number, but this is only the rendering artifact, and this doesn't make the amount itself fractional. For ERC-20 token, situation is the same. UI may render large token amount using larger units. For token representing backup storage space, such units could be KB (1024), MB (1048576), GB (1073741824), or TB (1099511627776). For token, representing eggs, such unit could be a dozen (12). Of cause, one token may have several different units, suitable for amounts of different scale. For example, tokenized ether may logically inherit units commonly used for ether, such as GWel, Szbao, Finney, and Ether. The idea, that simple “decimals” property could cover all use cases was initially wrong, as it doesn't cover tokens, whose units are not powers of ten, and it doesn't cover tokens that have multiple larger units. The introduction of “decimals” property, however, led to a great confusion, as people started thinking that ERC-20 token amounts are fractional, which is not the case. Initially, “decimals” property was meant to be used only by off-chain applications, such as wallets, in order to improve user experience. However, smart contracts started using this property for things like exchange rates. Instead of maintaining fractional exchange rate between base units of two tokens, which would be a proper solution, some smart contracts maintain integer exchange rate between “full” token at only side and token base unit at another side. For example, USD/ETH exchange rate is maintained not as 1 Wei = 0.00000000000000024746... cents, but rather as 1 ETH = 24746 cent. In my understanding, such approach is an abuse of “decimals” property, and leads to a number of problems. The main problem is that the precision of calculations starts depending on the value of token base units. This makes it impossible to use such smart contracts with tokens, whose base units have significant value. |
There has been no activity on this issue for two months. It will be closed in a week if no further activity occurs. If you would like to move this EIP forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review. |
This issue was closed due to inactivity. If you are still pursuing it, feel free to reopen it and respond to any feedback or request a review in a comment. |
Rationale:
The text was updated successfully, but these errors were encountered: