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

Merged
merged 13 commits into from Sep 11, 2017

Conversation

@frozeman
Member

frozeman commented Apr 24, 2017

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.

frozeman added some commits Apr 24, 2017

@frozeman frozeman referenced this pull request Apr 24, 2017

Closed

ERC: Token standard #20

@frozeman frozeman added the ERC label Apr 24, 2017

@Souptacular

This comment has been minimized.

Show comment
Hide comment
@Souptacular

Souptacular Apr 24, 2017

Member

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.

Member

Souptacular commented Apr 24, 2017

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.

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Apr 24, 2017

I want to draw attention to the fact that there are two ways to transfer tokens in the ERC20 standard:

  1. transfer
  2. approve + transferFrom

There is no way to handle transfer function calls. As a result, choosing the wrong way to transfer tokens will result in a loss of money.

The most common mistake is sending tokens to token contract itself. At least $16000 are already lost.
Stuck GNT inside Golem contract ~ $5600 lost.
Stuck REP inside Augur contract ~ $1500 lost.
Stuck DGD inside DigixDAO contract ~$7000 lost
Stuck 1ST inside FirstBlood contract ~ $2700 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.

Dexaran commented Apr 24, 2017

I want to draw attention to the fact that there are two ways to transfer tokens in the ERC20 standard:

  1. transfer
  2. approve + transferFrom

There is no way to handle transfer function calls. As a result, choosing the wrong way to transfer tokens will result in a loss of money.

The most common mistake is sending tokens to token contract itself. At least $16000 are already lost.
Stuck GNT inside Golem contract ~ $5600 lost.
Stuck REP inside Augur contract ~ $1500 lost.
Stuck DGD inside DigixDAO contract ~$7000 lost
Stuck 1ST inside FirstBlood contract ~ $2700 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.

@frozeman

This comment has been minimized.

Show comment
Hide comment
@frozeman

frozeman Apr 24, 2017

Member

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

Member

frozeman commented Apr 24, 2017

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

@Souptacular

This comment has been minimized.

Show comment
Hide comment
@Souptacular

Souptacular Apr 24, 2017

Member

@frozeman @Dexaran and others.

Should the next version be a whole new ERC# or just ERC20v2? I'm leaning towards versions of ERC20 so there aren't 20 ERC numbers to keep up with.

Member

Souptacular commented Apr 24, 2017

@frozeman @Dexaran and others.

Should the next version be a whole new ERC# or just ERC20v2? I'm leaning towards versions of ERC20 so there aren't 20 ERC numbers to keep up with.

@SilentCicero

This comment has been minimized.

Show comment
Hide comment
@SilentCicero

SilentCicero Apr 25, 2017

Can I also say, we need a balanceOf(address _sender, uint256 _blockNumber) method to be standard. It's extremely useful for voting, transferring and copying tokens.

Initially stated in the MiniMe token, for reference.

Can I also say, we need a balanceOf(address _sender, uint256 _blockNumber) method to be standard. It's extremely useful for voting, transferring and copying tokens.

Initially stated in the MiniMe token, for reference.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 25, 2017

Collaborator

@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.

Collaborator

Arachnid commented Apr 25, 2017

@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.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 25, 2017

Collaborator

@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.

Collaborator

Arachnid commented Apr 25, 2017

@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.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 25, 2017

Collaborator

name, symbol and decimals are used near-universally in conjunction with ERC20, but I haven't seen them clearly documented anywhere. Would it be appropriate to extend the EIP with a description of these, since they're already de-facto standardised?

Collaborator

Arachnid commented Apr 25, 2017

name, symbol and decimals are used near-universally in conjunction with ERC20, but I haven't seen them clearly documented anywhere. Would it be appropriate to extend the EIP with a description of these, since they're already de-facto standardised?

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Apr 25, 2017

I can suggest to add constant returns functions getName / getSymbol / getDecimals if this variables would be standardized. This can be useful in some cases.
For example to access variables directly from Contracts MEW UI.
Also this will allow to calculate decimal units automatically inside contracts. For example token exchange that needs to trade tokens with different decimals can set a dynamic price using decimals difference coefficient:
uint coefficient = token1.getDecimals() / token2.getDecimals();

Dexaran commented Apr 25, 2017

I can suggest to add constant returns functions getName / getSymbol / getDecimals if this variables would be standardized. This can be useful in some cases.
For example to access variables directly from Contracts MEW UI.
Also this will allow to calculate decimal units automatically inside contracts. For example token exchange that needs to trade tokens with different decimals can set a dynamic price using decimals difference coefficient:
uint coefficient = token1.getDecimals() / token2.getDecimals();

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 25, 2017

Collaborator

Yes, if included those properties definitely need to be constant.

Collaborator

Arachnid commented Apr 25, 2017

Yes, if included those properties definitely need to be constant.

@christoph2806

This comment has been minimized.

Show comment
Hide comment
@christoph2806

christoph2806 Apr 26, 2017

I'd like to discuss an extension of ERC 20 - hope this is the right place.
As tokens become ubiquitous, there arises the demand to "pay" with tokens. Paying for something means "transfering a token and getting a service in return". This means basically:

  1. Transfer token to some contract
  2. Trigger execution of a function of that contract.

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):
function transfer(address _to, uint256 _value, bytes _data) returns (bool success)
The third parameter _data would then trigger a call(_data) in the referenced receiving contract.
In case the call fails, the transfer is rolled back.
I'd like to discuss such an extension and possible security issues which could be connected with this; everything under the assumption that a token contract is usually something which is audited anyway and therefore can be "trusted".

christoph2806 commented Apr 26, 2017

I'd like to discuss an extension of ERC 20 - hope this is the right place.
As tokens become ubiquitous, there arises the demand to "pay" with tokens. Paying for something means "transfering a token and getting a service in return". This means basically:

  1. Transfer token to some contract
  2. Trigger execution of a function of that contract.

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):
function transfer(address _to, uint256 _value, bytes _data) returns (bool success)
The third parameter _data would then trigger a call(_data) in the referenced receiving contract.
In case the call fails, the transfer is rolled back.
I'd like to discuss such an extension and possible security issues which could be connected with this; everything under the assumption that a token contract is usually something which is audited anyway and therefore can be "trusted".

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 26, 2017

Collaborator

I'd like to discuss an extension of ERC 20 - hope this is the right place.

This is not the correct place. Please comment on #20, open a new issue, or open a PR.

Collaborator

Arachnid commented Apr 26, 2017

I'd like to discuss an extension of ERC 20 - hope this is the right place.

This is not the correct place. Please comment on #20, open a new issue, or open a PR.

@frozeman

This comment has been minimized.

Show comment
Hide comment
@frozeman

frozeman Apr 26, 2017

Member

@christoph2806 @Dexaran takes a different approach in its #223 where he wants the token contract to call a tokenFallback fund. I think those a re great ideas but need to be in a new standard and discussed, e.g. in his issue.

Member

frozeman commented Apr 26, 2017

@christoph2806 @Dexaran takes a different approach in its #223 where he wants the token contract to call a tokenFallback fund. I think those a re great ideas but need to be in a new standard and discussed, e.g. in his issue.

@Souptacular

This comment has been minimized.

Show comment
Hide comment
@Souptacular

Souptacular Apr 27, 2017

Member

@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.)?

Member

Souptacular commented Apr 27, 2017

@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.)?

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Apr 28, 2017

Collaborator

@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".

Collaborator

Arachnid commented Apr 28, 2017

@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
+ Title: <EIP title>
+ Author: Fabian Vogelsteller <fabian@ethereum.org>, Vitalik Buterin <vitalik.buterin@ethereum.org>
+ Type: Informational
+ Category ERC

This comment has been minimized.

@ethers

ethers Apr 29, 2017

Member

"Category" line can be removed

@ethers

ethers Apr 29, 2017

Member

"Category" line can be removed

EIPS/eip-token-standard.md
+
+## Abstract
+
+The following standard allows for people to implement a token standard API withing their smart contracts.

This comment has been minimized.

@ethers

ethers Apr 29, 2017

Member

spelling: within

@ethers

ethers Apr 29, 2017

Member

spelling: within

This comment has been minimized.

@simondlr

simondlr May 1, 2017

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."

@simondlr

simondlr May 1, 2017

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
+
+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.

This comment has been minimized.

@ethers

ethers Apr 29, 2017

Member

grammar: use "spent" instead of spend

@ethers

ethers Apr 29, 2017

Member

grammar: use "spent" instead of spend

EIPS/eip-token-standard.md
+- 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:

This comment has been minimized.

@ethers

ethers Apr 29, 2017

Member

spelling: implementation

@ethers

ethers Apr 29, 2017

Member

spelling: implementation

@ethers

This comment has been minimized.

Show comment
Hide comment
@ethers

ethers Apr 29, 2017

Member

How will it be decided whether name, symbol and decimals should be added here?

Member

ethers commented Apr 29, 2017

How will it be decided whether name, symbol and decimals should be added here?

@Dexaran

This comment has been minimized.

Show comment
Hide comment
@Dexaran

Dexaran Apr 29, 2017

I would say it's a good idea to standardize name , symbol and decimals .

Dexaran commented Apr 29, 2017

I would say it's a good idea to standardize name , symbol and decimals .

@simondlr

This comment has been minimized.

Show comment
Hide comment
@simondlr

simondlr Apr 30, 2017

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.

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
@@ -0,0 +1,129 @@
+This is the suggested template for new EIPs.

This comment has been minimized.

@simondlr

simondlr May 1, 2017

Should this preamble also be included?

@simondlr

simondlr May 1, 2017

Should this preamble also be included?

EIPS/eip-token-standard.md
+
+## Simple Summary
+
+Token standard interface.

This comment has been minimized.

@simondlr

simondlr May 1, 2017

Maybe revise a bit? "A standard interface for tokens." ?

@simondlr

simondlr May 1, 2017

Maybe revise a bit? "A standard interface for tokens." ?

EIPS/eip-token-standard.md
+
+## Motivation
+
+Following the same standard interface allows those tokens to be used in many wallets and exchanges.

This comment has been minimized.

@simondlr

simondlr May 1, 2017

Another potential revision:

"A standard interface allows any tokens on Ethereum to be re-used by other applications: from wallets to decentralized exchanges."

@simondlr

simondlr May 1, 2017

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
+function transfer(address _to, uint256 _value) returns (bool success)
+```
+
+Send `_value` amount of tokens to address `_to`

This comment has been minimized.

@simondlr

simondlr May 1, 2017

Use "transfer" vs "Send"?

@simondlr

simondlr May 1, 2017

Use "transfer" vs "Send"?

EIPS/eip-token-standard.md
+```
+
+Allow _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.
+To prevent attack vectors like described here: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/

This comment has been minimized.

@simondlr

simondlr May 1, 2017

"like the one described here:"

@simondlr

simondlr May 1, 2017

"like the one described here:"

EIPS/eip-token-standard.md
+
+## Implementation
+
+Different implementations are available at

This comment has been minimized.

@simondlr

simondlr May 1, 2017

I would probably change this to say: "There are already plenty of ERC20-compliant tokens deployed on the Ethereum network and is the most widely used standard. Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. Example implementations include:"

@simondlr

simondlr May 1, 2017

I would probably change this to say: "There are already plenty of ERC20-compliant tokens deployed on the Ethereum network and is the most widely used standard. Different implementations have been written by various teams that have different trade-offs: from gas saving to improved security. Example implementations include:"

@rverbee

This comment has been minimized.

Show comment
Hide comment
@rverbee

rverbee May 2, 2017

@simondlr apropos the human readable names, and in reference to @Arachnid's reference of the RFC flow, would the m2m version be a separate ERC/EIP?

rverbee commented May 2, 2017

@simondlr apropos the human readable names, and in reference to @Arachnid's reference of the RFC flow, would the m2m version be a separate ERC/EIP?

frozeman added some commits May 3, 2017

@frozeman

This comment has been minimized.

Show comment
Hide comment
@frozeman

frozeman May 3, 2017

Member

I fixed the spelling and added name, symbol and decimals. Tho i remember there was a discussion about either adding decimals like 8 or baseUnit like 100000000.

We might want to revise that.

Member

frozeman commented May 3, 2017

I fixed the spelling and added name, symbol and decimals. Tho i remember there was a discussion about either adding decimals like 8 or baseUnit like 100000000.

We might want to revise that.

@frozeman

This comment has been minimized.

Show comment
Hide comment
@frozeman

frozeman May 3, 2017

Member

After merging this i would highly recommend working on #223
As its backwards compatible, but the tokenFallback is a serious improvement over the current standard.

Member

frozeman commented May 3, 2017

After merging this i would highly recommend working on #223
As its backwards compatible, but the tokenFallback is a serious improvement over the current standard.

@ethers

This comment has been minimized.

Show comment
Hide comment
@ethers

ethers May 9, 2017

Member

This standard may be missing some explicitness about the handling of 0 values, for example when 0 tokens are transferred should that return true and fire the Transfer event ? (raised in ConsenSys/Tokens#47)

All APIs should be considered, including approvals.

Member

ethers commented May 9, 2017

This standard may be missing some explicitness about the handling of 0 values, for example when 0 tokens are transferred should that return true and fire the Transfer event ? (raised in ConsenSys/Tokens#47)

All APIs should be considered, including approvals.

@maraoz

This comment has been minimized.

Show comment
Hide comment
@maraoz

maraoz May 9, 2017

What's the status on the throw; vs return false; discussion?

I know many devs would rather see ERC20 spec recommend throw; over return false; (e.g. @simondlr from Consensys, @joeykrug from Augur and others I talked to).

In OpenZeppelin we use throw (see: https://github.com/OpenZeppelin/zeppelin-solidity/blob/7592122e4df1b0632fcef48e8987c0bd90006437/contracts/token/BasicToken.sol#L27) and we'd like to push the industry standard in that direction.

We favor throw; over return false; because it conforms with the rule "Fail as early and loudly as possible", which we think is a good security precaution. Thoughts?

maraoz commented May 9, 2017

What's the status on the throw; vs return false; discussion?

I know many devs would rather see ERC20 spec recommend throw; over return false; (e.g. @simondlr from Consensys, @joeykrug from Augur and others I talked to).

In OpenZeppelin we use throw (see: https://github.com/OpenZeppelin/zeppelin-solidity/blob/7592122e4df1b0632fcef48e8987c0bd90006437/contracts/token/BasicToken.sol#L27) and we'd like to push the industry standard in that direction.

We favor throw; over return false; because it conforms with the rule "Fail as early and loudly as possible", which we think is a good security precaution. Thoughts?

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

Right, I am saying that balanceOf might call a function to check whether the balance needs to be updated and update it before returning the value.

Right, I am saying that balanceOf might call a function to check whether the balance needs to be updated and update it before returning the value.

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

It sounds like someone calling your balanceOf method may end up changing the state of the contract :) Is that right?

It sounds like someone calling your balanceOf method may end up changing the state of the contract :) Is that right?

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@3esmit

This comment has been minimized.

Show comment
Hide comment
@3esmit

3esmit Aug 24, 2017

Is it called ERC23 or ERC223? I call it everywhere ERC223.
Also, what about MiniMeToken feature balanceOfAt, which is really useful for many things.
I believe would be good to have one more standard implementing MiniMe features together with ERC223.
The drawback of MiniMe is a higher gas usage in all functions, but I see it worth as it have many uses, and in 4 years when ethereum gets really cheap to use those increased gas will be more win then lose.

3esmit commented Aug 24, 2017

Is it called ERC23 or ERC223? I call it everywhere ERC223.
Also, what about MiniMeToken feature balanceOfAt, which is really useful for many things.
I believe would be good to have one more standard implementing MiniMe features together with ERC223.
The drawback of MiniMe is a higher gas usage in all functions, but I see it worth as it have many uses, and in 4 years when ethereum gets really cheap to use those increased gas will be more win then lose.

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

@o0ragman0o You are not changing state in your contracts' balanceOf apparently. That doesn't imply it isn't a valid use case for other contracts. I've stated an example use case that conflicts with the meaning of constant on balanceOf. If there's not a way to distribute rewards to every user without running out of gas (which you seem to appreciate) then amortizing that kind of thing seems appropriate. So updating that reward state depends on calls to things like transfer, but transfer may not have been called since the last reward. Therefore the balance you would get calling balanceOf -- unless you update state -- would be incorrect. This is definitely relevant to ERC20, because I'm arguing that constant should be removed from the interface of balanceOf.

@o0ragman0o You are not changing state in your contracts' balanceOf apparently. That doesn't imply it isn't a valid use case for other contracts. I've stated an example use case that conflicts with the meaning of constant on balanceOf. If there's not a way to distribute rewards to every user without running out of gas (which you seem to appreciate) then amortizing that kind of thing seems appropriate. So updating that reward state depends on calls to things like transfer, but transfer may not have been called since the last reward. Therefore the balance you would get calling balanceOf -- unless you update state -- would be incorrect. This is definitely relevant to ERC20, because I'm arguing that constant should be removed from the interface of balanceOf.

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

Yes, I've read it. The standard is an interface that is incorrect for that exact use case. I'm sorry you haven't followed my reasoning.

Yes, I've read it. The standard is an interface that is incorrect for that exact use case. I'm sorry you haven't followed my reasoning.

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

Because constant isn't enforced by the compiler.

Because constant isn't enforced by the compiler.

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

Or, if balanceOf doesn't change state, the balance may be incorrect. One of those two.

Or, if balanceOf doesn't change state, the balance may be incorrect. One of those two.

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

Requiring everyone who implements the interface to either lie about balances or lie about constantness if they want to amortize dividends is a problem for the standard.

Requiring everyone who implements the interface to either lie about balances or lie about constantness if they want to amortize dividends is a problem for the standard.

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

http://solidity.readthedocs.io/en/develop/miscellaneous.html

view/constant for functions: Disallow modification of state - this is not enforced yet.

http://solidity.readthedocs.io/en/develop/miscellaneous.html

view/constant for functions: Disallow modification of state - this is not enforced yet.

@o0ragman0o

This comment has been minimized.

Show comment
Hide comment
@o0ragman0o

o0ragman0o Aug 24, 2017

@JoshCason

This comment has been minimized.

Show comment
Hide comment
@JoshCason

JoshCason Aug 24, 2017

That may be the right answer, but people should somehow know that the balance may be incorrect.

JoshCason commented Aug 24, 2017

That may be the right answer, but people should somehow know that the balance may be incorrect.

@MicahZoltu

This comment has been minimized.

Show comment
Hide comment
@MicahZoltu

MicahZoltu Aug 24, 2017

Contributor

@JoshCason You can have balanceOf be constant, and still return the correct result even when the correct result requires state mutations. All you need to do is make it so balanceOf calculates pending state mutations as part of computing its return value, without actually applying those mutations. For example, if you had some dividends awaiting to be added to your balance the contract could notice that your internal has some pending mutations and, without actually mutating your balance on contract, take them into consideration when returning a value to you. The next time a non-constant function is executed (such as a transfer) the pending mutation would be applied causing state to update.

Contributor

MicahZoltu commented Aug 24, 2017

@JoshCason You can have balanceOf be constant, and still return the correct result even when the correct result requires state mutations. All you need to do is make it so balanceOf calculates pending state mutations as part of computing its return value, without actually applying those mutations. For example, if you had some dividends awaiting to be added to your balance the contract could notice that your internal has some pending mutations and, without actually mutating your balance on contract, take them into consideration when returning a value to you. The next time a non-constant function is executed (such as a transfer) the pending mutation would be applied causing state to update.

@3sGgpQ8H

This comment has been minimized.

Show comment
Hide comment
@3sGgpQ8H

3sGgpQ8H Aug 24, 2017

@MicahZoltu

You can have balanceOf be constant, and still return the correct result even when the correct result requires state mutations. All you need to do is make it so balanceOf calculates pending state mutations as part of computing its return value, without actually applying those mutations.

This is not possible if correct result depends on current time, because constant functions do not have access to current time.

3sGgpQ8H commented Aug 24, 2017

@MicahZoltu

You can have balanceOf be constant, and still return the correct result even when the correct result requires state mutations. All you need to do is make it so balanceOf calculates pending state mutations as part of computing its return value, without actually applying those mutations.

This is not possible if correct result depends on current time, because constant functions do not have access to current time.

@3sGgpQ8H

This comment has been minimized.

Show comment
Hide comment
@3sGgpQ8H

3sGgpQ8H Aug 24, 2017

@JoshCason

I think having balanceOf marked constant is a bad idea

Obtaining return value of non-constant function is non-trivial, when such function is called directly, i.e. not from other smart contract.

3sGgpQ8H commented Aug 24, 2017

@JoshCason

I think having balanceOf marked constant is a bad idea

Obtaining return value of non-constant function is non-trivial, when such function is called directly, i.e. not from other smart contract.

@MicahZoltu

This comment has been minimized.

Show comment
Hide comment
@MicahZoltu

MicahZoltu Aug 24, 2017

Contributor

constant functions do not have access to current time

@mikhail-vladimirov Can you clarify this and/or link to some documentation or code where this is asserted? Constant functions not having access to block.timestamp doesn't make any sense to me and I find it somewhat hard to believe that it is true. Especially since constant right now is not actually enforced in any way.

Contributor

MicahZoltu commented Aug 24, 2017

constant functions do not have access to current time

@mikhail-vladimirov Can you clarify this and/or link to some documentation or code where this is asserted? Constant functions not having access to block.timestamp doesn't make any sense to me and I find it somewhat hard to believe that it is true. Especially since constant right now is not actually enforced in any way.

@Hackdom

This comment has been minimized.

Show comment
Hide comment
@Hackdom

Hackdom Aug 24, 2017

Contributor

Just my two cents. Functions should be properly scoped in practice regardless of the current system implementation. balanceOf is clearly not meant to be a state changing function. It should be on the developer to configure workflow with balanceOf as a constant function. If that's not the case then that should be changed, not the standard.

Contributor

Hackdom commented Aug 24, 2017

Just my two cents. Functions should be properly scoped in practice regardless of the current system implementation. balanceOf is clearly not meant to be a state changing function. It should be on the developer to configure workflow with balanceOf as a constant function. If that's not the case then that should be changed, not the standard.

@3sGgpQ8H

This comment has been minimized.

Show comment
Hide comment
@3sGgpQ8H

3sGgpQ8H Aug 24, 2017

@MicahZoltu

Constant functions not having access to block.timestamp doesn't make any sense to me and I find it somewhat hard to believe that it is true

I didn't say they do not have access to block.timestamp, they actually do. I said they do not have access to current time when called directly. It is not specified what value block.timestamp should have when constant function is being executed locally, so you may not rely on any particular behavior. Different implementations may (and actually do) behave differently.

3sGgpQ8H commented Aug 24, 2017

@MicahZoltu

Constant functions not having access to block.timestamp doesn't make any sense to me and I find it somewhat hard to believe that it is true

I didn't say they do not have access to block.timestamp, they actually do. I said they do not have access to current time when called directly. It is not specified what value block.timestamp should have when constant function is being executed locally, so you may not rely on any particular behavior. Different implementations may (and actually do) behave differently.

@MicahZoltu

This comment has been minimized.

Show comment
Hide comment
@MicahZoltu

MicahZoltu Aug 24, 2017

Contributor

Hmm, interesting. That sounds like a bug or something that should be well defined.

Contributor

MicahZoltu commented Aug 24, 2017

Hmm, interesting. That sounds like a bug or something that should be well defined.

@d10r

This comment has been minimized.

Show comment
Hide comment
@d10r

d10r Sep 5, 2017

It is not specified what value block.timestamp should have when constant function is being executed locally, so you may not rely on any particular behavior.

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.
On EVM level according to my understanding (after taking a look at the Yellow Paper, Appendix H) there's no notion of local (or not) execution.

@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 commented Sep 5, 2017

It is not specified what value block.timestamp should have when constant function is being executed locally, so you may not rely on any particular behavior.

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.
On EVM level according to my understanding (after taking a look at the Yellow Paper, Appendix H) there's no notion of local (or not) execution.

@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?

@MicahZoltu

This comment has been minimized.

Show comment
Hide comment
@MicahZoltu

MicahZoltu Sep 5, 2017

Contributor

@d10r I believe the issue is that when you do eth_call, it is undefined what value the node that executes the contract will use for block.timestamp. For example, Geth may provide 0 while Parity may provide <now>.

Contributor

MicahZoltu commented Sep 5, 2017

@d10r I believe the issue is that when you do eth_call, it is undefined what value the node that executes the contract will use for block.timestamp. For example, Geth may provide 0 while Parity may provide <now>.

@3sGgpQ8H

This comment has been minimized.

Show comment
Hide comment
@3sGgpQ8H

3sGgpQ8H Sep 6, 2017

@d10r There are no problems with Solidity, it just translates block.timestamp into TIMESTAMP opcode. The problem is that this opcode is supposed to return timestamp of the block current transaction is being mined within, but when constant functions is called locally, it is not mined at all, so there is no current transaction nor current block. Using things like block.coinbase, block.difficulty, block.gaslimit, block.number, block.timestamp, tx.gasprice, or tx.origin in constant functions is not a good idea, because it is unspecified what EVM will return, and different implementations, or even different versions of the same implementation, may behave differently. Check this old thread: https://forum.ethereum.org/discussion/2452/block-timestamp-a-k-a-now-in-constant-functions for details.

Modern EVMs seem to substitute timestamp of last block as block.timestamp for constant functions being executed locally, but last block != current block, and timestamp of last block != current time, though for some applications this could be good enough estimate. In my contracts, when I need constant functions to access current time, I always pass current time to the function as an argument.

3sGgpQ8H commented Sep 6, 2017

@d10r There are no problems with Solidity, it just translates block.timestamp into TIMESTAMP opcode. The problem is that this opcode is supposed to return timestamp of the block current transaction is being mined within, but when constant functions is called locally, it is not mined at all, so there is no current transaction nor current block. Using things like block.coinbase, block.difficulty, block.gaslimit, block.number, block.timestamp, tx.gasprice, or tx.origin in constant functions is not a good idea, because it is unspecified what EVM will return, and different implementations, or even different versions of the same implementation, may behave differently. Check this old thread: https://forum.ethereum.org/discussion/2452/block-timestamp-a-k-a-now-in-constant-functions for details.

Modern EVMs seem to substitute timestamp of last block as block.timestamp for constant functions being executed locally, but last block != current block, and timestamp of last block != current time, though for some applications this could be good enough estimate. In my contracts, when I need constant functions to access current time, I always pass current time to the function as an argument.

@Arachnid

This comment has been minimized.

Show comment
Hide comment
@Arachnid

Arachnid Sep 6, 2017

Collaborator

I think this is a red herring and besides the point; removing constant is a nonstarter for several reasons:

  1. It breaks the existing standard, which this PR seeks to formalise.
  2. There's no practical way at present to retrieve the return value of a transaction.
  3. Expecting people to submit a transaction and wait for it to be mined in order to retrieve their balance is crazy.

Is there anything holding up this PR being merged?

Collaborator

Arachnid commented Sep 6, 2017

I think this is a red herring and besides the point; removing constant is a nonstarter for several reasons:

  1. It breaks the existing standard, which this PR seeks to formalise.
  2. There's no practical way at present to retrieve the return value of a transaction.
  3. Expecting people to submit a transaction and wait for it to be mined in order to retrieve their balance is crazy.

Is there anything holding up this PR being merged?

EIPS/eip-20-token-standard.md
+
+Returns the symbol of the token. E.g. "HIX".
+
+OPTIONAL - This method can be used to improve useability,

This comment has been minimized.

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

useability> usability

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

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.

This comment has been minimized.

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

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.

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

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.

This comment has been minimized.

@DaveAppleton

DaveAppleton Sep 6, 2017

It is fine having explicit burn and mint functions but they should call Transfer events as defined in the standard and monitored on etherscan.

@DaveAppleton

DaveAppleton Sep 6, 2017

It is fine having explicit burn and mint functions but they should call Transfer events as defined in the standard and monitored on etherscan.

This comment has been minimized.

@frozeman

frozeman Sep 8, 2017

Member

Anybody any thoughts on that?
I really want to merge that ASAP

@frozeman

frozeman Sep 8, 2017

Member

Anybody any thoughts on that?
I really want to merge that ASAP

This comment has been minimized.

@veox

veox Sep 8, 2017

Contributor

@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.

@veox

veox Sep 8, 2017

Contributor

@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.

This comment has been minimized.

@Hackdom

Hackdom Sep 8, 2017

Contributor

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.

@Hackdom

Hackdom Sep 8, 2017

Contributor

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.

This comment has been minimized.

@Arachnid

Arachnid Sep 8, 2017

Collaborator

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.

@Arachnid

Arachnid Sep 8, 2017

Collaborator

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.

This comment has been minimized.

@MicahZoltu

MicahZoltu Sep 8, 2017

Contributor

@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.

@MicahZoltu

MicahZoltu Sep 8, 2017

Contributor

@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.

This comment has been minimized.

@Hackdom

Hackdom Sep 8, 2017

Contributor

@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.

@Hackdom

Hackdom Sep 8, 2017

Contributor

@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.

This comment has been minimized.

@MicahZoltu

MicahZoltu Sep 8, 2017

Contributor

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).

@MicahZoltu

MicahZoltu Sep 8, 2017

Contributor

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).

This comment has been minimized.

@veox

veox Sep 8, 2017

Contributor

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.

@veox

veox Sep 8, 2017

Contributor

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),

This comment has been minimized.

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

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.

@alexvandesande

alexvandesande Sep 6, 2017

Contributor

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.

This comment has been minimized.

@frozeman

frozeman Sep 8, 2017

Member

We can change that in another standard, but this one needs to be formalised

@frozeman

frozeman Sep 8, 2017

Member

We can change that in another standard, but this one needs to be formalised

@frozeman

This comment has been minimized.

Show comment
Hide comment
@frozeman

frozeman Sep 11, 2017

Member

Im fine with the current standard and suggest merging.

Member

frozeman commented Sep 11, 2017

Im fine with the current standard and suggest merging.

@Souptacular

This comment has been minimized.

Show comment
Hide comment
@Souptacular

Souptacular Sep 11, 2017

Member

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 💸 🤓

Member

Souptacular commented Sep 11, 2017

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 💸 🤓

@Souptacular Souptacular merged commit f90864a into ethereum:master Sep 11, 2017

@3sGgpQ8H 3sGgpQ8H referenced this pull request in OpenZeppelin/openzeppelin-solidity Sep 11, 2017

Closed

Improper use of assert() in BasicToken and other places #435

@Georgi87

This comment has been minimized.

Show comment
Hide comment
@Georgi87

Georgi87 Oct 21, 2017

Regarding name, symbol and decimals: According to the style guide all constants should be capitalized (http://solidity.readthedocs.io/en/latest/style-guide.html#constants). Should they be renamed to NAME, SYMBOL and DECIMALS?

Regarding name, symbol and decimals: According to the style guide all constants should be capitalized (http://solidity.readthedocs.io/en/latest/style-guide.html#constants). Should they be renamed to NAME, SYMBOL and DECIMALS?

@jamesray1

This comment has been minimized.

Show comment
Hide comment
@jamesray1

jamesray1 Nov 11, 2017

Contributor

@Georgi87, name, symbol and decimals are functions as well as input variables to the eponymous function (however, the latter input variables are just placeholders for the actual input variables) that returns a constant, respectively: a name of type string, a symbol of type string, and decimals of type uint8. The convention in programming languages for variables and function names is that the first word in the variable is lower case (separating words can use an underscore e.g. this_variable or Camel case, e.g. thisVariable; variables can also have numbers, but not as the first character). Constant variables use all caps, e.g. ACCELERATION_DUE_TO_GRAVITY_ON_EARTH = 9.8. So, the function names should be kept as they are (name, symbol and decimals). The input variables could be changed to NAME, SYMBOL and DECIMALS and I guess that that they ought to be changed to comply with convention and provide clarity.

Contributor

jamesray1 commented Nov 11, 2017

@Georgi87, name, symbol and decimals are functions as well as input variables to the eponymous function (however, the latter input variables are just placeholders for the actual input variables) that returns a constant, respectively: a name of type string, a symbol of type string, and decimals of type uint8. The convention in programming languages for variables and function names is that the first word in the variable is lower case (separating words can use an underscore e.g. this_variable or Camel case, e.g. thisVariable; variables can also have numbers, but not as the first character). Constant variables use all caps, e.g. ACCELERATION_DUE_TO_GRAVITY_ON_EARTH = 9.8. So, the function names should be kept as they are (name, symbol and decimals). The input variables could be changed to NAME, SYMBOL and DECIMALS and I guess that that they ought to be changed to comply with convention and provide clarity.

@veox

This comment has been minimized.

Show comment
Hide comment
@veox

veox Nov 11, 2017

Contributor

Personally, I use ALL_CAPS for compile-time constants.

Also, although name/symbol/decimals are unlikely to change during the life cycle of a contract, they can be deployment-time parameters, e.g. when used with a token Factory.

Contributor

veox commented Nov 11, 2017

Personally, I use ALL_CAPS for compile-time constants.

Also, although name/symbol/decimals are unlikely to change during the life cycle of a contract, they can be deployment-time parameters, e.g. when used with a token Factory.

@frozeman frozeman deleted the frozeman:erc20 branch Jan 12, 2018

@James-Sangalli

This comment has been minimized.

Show comment
Hide comment
@James-Sangalli

James-Sangalli Feb 21, 2018

@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.

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment