-
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
ERC20 Token Standard #610
ERC20 Token Standard #610
Conversation
Thank you @frozeman for bringing this to the new EIP format. Those in the community are welcome to look over and comment on this ERC. To be clear, this is NOT a new version of ERC-20. This PR is simply meant to formally define ERC-20 version 1 since there are slight deviations within the community. Once community consensus on version1 is reached, we will mark this ERC as accepted and it will become official with regards to the EIP repo. |
I want to draw attention to the fact that there are two ways to transfer tokens in the ERC20 standard:
There is no way to handle The most common mistake is sending tokens to token contract itself. At least $16000 are already lost. If there is a possibility of error, there will always be users making an error. If you leave the way to transfer tokens to a contract without handling by the recipient, it will lead to the loss of tokens. I developed ERC #223 , trying to solve this problem. |
I do find this idea very useful, but at the same time we also should get the ERC 20 finalised as many tokens already us it. We can then make an ERC 23 for a new version based on ERC 20 |
Can I also say, we need a Initially stated in the MiniMe token, for reference. |
@Souptacular ERC20 is deployed widely, so backwards-incompatible changes and significant extensions should absolutely be new EIPs. Otherwise, tracking the actual support in a given contract will become near impossible. Take for example HTTP; different HTTP versions are standardised in different RFCs; you can refer to different RFC numbers, of to a specific version of HTTP as standardised in the relevant RFC. |
@SilentCicero Changes to ERC20 are out-of-scope for this PR. Also, the method you're asking for is already available offchain from archive clients, who can call any contract at any time in history. |
|
I can suggest to add |
Yes, if included those properties definitely need to be |
I'd like to discuss an extension of ERC 20 - hope this is the right place.
With the current ERC 20 token, this can't be done in one transaction. But for many reasons it would be desirable to trigger the execution of code with a token transfer. For example, paying for an insurance contract with a token and at the same time applying for the insurance policy with the same transaction. This could be easily accomplished with an extension of the transfer function, giving it an optional third argument (the same applies for the transferFrom function respectivly): |
This is not the correct place. Please comment on #20, open a new issue, or open a PR. |
@christoph2806 @Dexaran takes a different approach in its #223 where he wants the token contract to call a |
@Arachnid I was not commenting on re-opening the EIP, but how the wider public should refer to updates to the ERC-20 standard - either as a new ERC # or ERC 20 version x. Are you saying if any change does not support backwards compatibility it should be a whole new token standard (so ERC 23, 24, 118, etc.)? |
@Souptacular Yes, that's what I'm suggesting. Just like with RFCs, any significant change, including new features, should be a new EIP; tokens can then say they're compliant with EIPs x, y, and z (y and z could say "requires x", in which case it's sufficient to say you're compliant with z. If we want a more 'stable' name, we should give the broader token standard a name independent of its EIP number, such as "token standard". |
EIPS/eip-token-standard.md
Outdated
Title: <EIP title> | ||
Author: Fabian Vogelsteller <[email protected]>, Vitalik Buterin <[email protected]> | ||
Type: Informational | ||
Category ERC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Category" line can be removed
EIPS/eip-token-standard.md
Outdated
|
||
## Abstract | ||
|
||
The following standard allows for people to implement a token standard API withing their smart contracts. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spelling: within
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would also revise this abstract:
"The following standard allows for the implementation of a standard API for tokens within their smart contracts: it primarily provides basic functionality to transfer tokens and allow them to be approved to be spent by another on-chain third party."
EIPS/eip-token-standard.md
Outdated
|
||
The following standard allows for people to implement a token standard API withing their smart contracts. | ||
|
||
This standard provides basic functionality for sending and approving tokens to be spend by a third party. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
grammar: use "spent" instead of spend
EIPS/eip-token-standard.md
Outdated
- https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/token/StandardToken.sol | ||
- https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/StandardToken.sol | ||
|
||
Implentation adding the force 0 before calling approve again: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spelling: implementation
How will it be decided whether |
I would say it's a good idea to standardize |
The original reason that name, decimals & symbol (which is near universal) was not included was that it was considered that these are for mostly for human consumption. We will likely still see tokens that are only really for machine to machine consumption and this won't really be relevant. In other words, no real UI. With that being said, I think if people want to drop them (say an IoT decive wanting to save gas costs when interacting in an only-m2m market), it's fine since UIs won't exist anyway for these tokens. So yeah. I'd say, add this to erc20. Additionally, yip, any extensions should be new issues. I don't think we need to necessarily create a new naming scheme for erc20 extensions. A one I want to add discussion on soon is a standard API for increasing and decreasing supply. |
EIPS/eip-token-standard.md
Outdated
@@ -0,0 +1,129 @@ | |||
This is the suggested template for new EIPs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this preamble also be included?
EIPS/eip-token-standard.md
Outdated
|
||
## Simple Summary | ||
|
||
Token standard interface. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe revise a bit? "A standard interface for tokens." ?
EIPS/eip-token-standard.md
Outdated
|
||
## Motivation | ||
|
||
Following the same standard interface allows those tokens to be used in many wallets and exchanges. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another potential revision:
"A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges."
EIPS/eip-token-standard.md
Outdated
function transfer(address _to, uint256 _value) returns (bool success) | ||
``` | ||
|
||
Send `_value` amount of tokens to address `_to` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use "transfer" vs "Send"?
This is not possible if correct result depends on current time, because constant functions do not have access to current time. |
Obtaining return value of non-constant function is non-trivial, when such function is called directly, i.e. not from other smart contract. |
@mikhail-vladimirov Can you clarify this and/or link to some documentation or code where this is asserted? Constant functions not having access to |
Just my two cents. Functions should be properly scoped in practice regardless of the current system implementation. |
I didn't say they do not have access to |
Hmm, interesting. That sounds like a bug or something that should be well defined. |
In the Solidity docs I couldn't find anything I would interpret that way. It just mentions current block - which in the context of a locally executed function I would interpret as the newest block my node has seen. @mikhail-vladimirov is your statement based on other sources of information or on a different interpretation of that docs? Am I right assuming that you mean different implementations of the Solidity compiler? |
@d10r I believe the issue is that when you do |
@d10r There are no problems with Solidity, it just translates Modern EVMs seem to substitute timestamp of last block as |
I think this is a red herring and besides the point; removing
Is there anything holding up this PR being merged? |
EIPS/eip-20-token-standard.md
Outdated
|
||
Returns the symbol of the token. E.g. "HIX". | ||
|
||
OPTIONAL - This method can be used to improve useability, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
useability> usability
Transfers `_value` amount of tokens to address `_to`, and MUST fire the `Transfer` event. | ||
The function SHOULD `throw` if the `_from` account balance does not have enough tokens to spend. | ||
|
||
A token contract which creates new tokens SHOULD trigger a Transfer event with the `_from` address set to `0x0` when tokens are created. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a recommendation to throw if the sender value is 0, as it's most likely an error. If the token wants to have a explicit burn function it should implement so or it should recommend users to send it to any other invalid address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is fine having explicit burn and mint functions but they should call Transfer events as defined in the standard and monitored on etherscan.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anybody any thoughts on that?
I really want to merge that ASAP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@frozeman The token implementations I've seen so far (e.g. OpenZeppelin's, but also many others) seem to make no check that msg.sender
is not 0x00..00
, or 0xff..ff
, or some other magic number.
Personally, I'd leave this out of the standard's text, instead of adding such provisions retroactively, since it was never widely discussed.
EDIT: That is, instead of adding another possibly contentious point that will keep discussion running ad infinitum, just leave it undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing it is contentious because it's already there and block scanners use it. Whether individual dev teams like it or not, the block scanners need to find the tokens, they find the tokens through transfer events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's changing what the spec requires - eg, introducing backwards incompatibilities or new features - and there's adding advice to implementers, or reflecting defacto standardised behaviour. I think recommending a transfer event on minting falls into the latter category rather than the former.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Arachnid See my argument here: #610 (comment)
TL;DR: Without this being a MUST (which it can't be in this PR), tooling can't leverage it meaningfully without creating bugs elsewhere.
I believe etherscan tries to interpret transfer from 0
as mint
and it results in some tokens having incorrect token allocation charts which leads to significant user confusion. As a SHOULD, I think it encourages other applications to do what etherscan has done (they would be operating under the assumption that most tokens will follow the SHOULD) when in fact I'm unconvinced that most do. So we end up with people building applications/interfaces that are wrong some non-trivial portion of the time with no clear mechanism for resolving that. If this were left out, the theory is that interfaces would stop trying to build against something that isn't widely adopted and therefore they would be less likely to build features that are permanently in a half broken state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MicahZoltu has the important point which is clarity, defining the standard, and closing. Maybe even just you three @frozeman @Arachnid and @MicahZoltu since you are the most reputable with investment in this discussion, decide and close. I say we all agree now to go with that decision rather than try to agree on the decision itself. Anyone that disagrees should present a valid argument against deciding and closing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just about the least reputable person I know. I recommend not including me in any list of "reputable persons". 😄
I'm 👍 on merging this with or without the SHOULD. I just wanted to make sure my arguments against it were clear and well understood before those that make the merge decisions do so. If @Arachnid / @frozeman (or whoever make the final merge decision) believe they understand my arguments but still disagree with them then consider the issue resolved (unless further discussion/clarification is desired, in which case I'll happily oblige).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIR, at the initial submission of #20, the creation (minting) of tokens was not taken into consideration. The proposal aimed to standartise an interface for transfer of tokens.
In retrospect, I'd say considerations for creation of tokens should have been kept out of this standard proposal, seeing how it has caused a lot of uncertainty.
My comment above:
EDIT: That is, instead of adding another possibly contentious point that will keep discussion running ad infinitum, just leave it undefined.
... was meant to highlight this fact: creation of tokens shouldn't have been within scope of this standard's text.
It's still not too late to leave a Minted
event outside the scope of this particular standard.
|
||
Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. | ||
|
||
**NOTE**: To prevent attack vectors like the one [described here](https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/) and discussed [here](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's a pity that approve
sets the approval amount and doesn't add or remove to it, it was implemented without much thought but now became a standard already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change that in another standard, but this one needs to be formalised
Im fine with the current standard and suggest merging. |
Going to merge this. Thank you all for the thoughtful discussion. Now we move on to working on an updated, better token standard now that this is formalized 💸 🤓 |
Regarding |
@Georgi87, |
Personally, I use ALL_CAPS for compile-time constants. Also, although |
@frozeman and all. I suggest adding this optional function because it will allow p2p atomic trading with low fees, it is already implemented in this standard: #875. function trade(uint256 expiryTimeStamp, uint amount, uint8 v, bytes32 r, bytes32 s) public payable A function which allows a user to sell a token without paying for the gas fee (only the buyer has to) with a p2p atomic swap. This is achieved by signing an attestation containing the token to sell, the contract address, an expiry timestamp, the price and a prefix containing the ERC spec name and chain id. A buyer can then pay for the deal in one transaction by attaching the appropriate ether to satisfy the deal. This design is also more efficient as it allows orders to be done offline until settlement as opposed to creating orders in a smart contract and updating them. The expiry timestamp protects the seller against people using old orders. This opens up the gates for a p2p atomic swap but should be optional to this standard as some may not have use for it. Some protections need to be added to the message such as encoding the chain id, contract address and the ERC spec name to prevent replays and spoofing people into signing message that allow a trade. |
The following is moving the ERC 20 token standard from #20 to a PR.
With the small addition of mentioning the attack vector on
approve
function and suggesting to set to 0 before allowing a new value.