-
Notifications
You must be signed in to change notification settings - Fork 113
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
NEP: Token Standard #4
Conversation
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.
Looks good, able to execute on the testnet. Fully working NEP5 template.
Do we really need the methods (transferFrom, approve, allowance) from ERC20? |
They allow you to transfer funds on behalf of someone else which can be pretty valuable. Use case: Ability for people to set up 'joint' accounts where two users share access to the tokens in the contract while retaining their own distinct accounts. Use case: It could also be used as an interface mechanism for systems to interact with the tokens on behalf of someone else. A user would 'allow' an application to access their tokens/data. |
Very pretty document! I have 3 suggestions and you can consider about.
finally, @erikzhang , i think we also need |
@luodanwg
|
another suggestion. |
Maybe we can mark some methods as "optional". |
Optional method and Runtime.notify() have been added to all 'authenticated' methods. |
What is the use of "NotifyOriginator"? Why don't we just add a "transferred" event? |
nep-5.mediawiki
Outdated
|
||
==Motivation== | ||
|
||
As the NEO blockchain scales, Smart Contract deployment and invocation will become increasingly important. Without a standard interaction method, systems will be required to maintain a unique API for each contract, regardless of their similarity to other contracts. Tokenized contracts present themselves as a prime example of this need because their basic operating mechanism is the same. A standard method for interacting with these tokens relieves the entire ecosystem from maintaining a definition for basic operations that a required by every Smart Contract that employs a token. |
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
A standard method for interacting with these tokens relieves the entire ecosystem from maintaining a definition for basic operations that a required by every Smart Contract that employs a token.
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.
Can you edit it?
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.
No problem, PR submitted to lllwvlvwll's repo.
can we approve and Merge this? |
We still need more tests for its implementations. |
I wonder on usage of the wording "account" rather than "address" when referring to transferring funds in this document. Account implies a higher level Object than what is actually being used, and I think is a point of confusion for many developers when they begin to mix the concept of an address with the concept of an account. In blockchain projects I would typically think of an account as the combination of all relevant public and private keys (WIF, pubkey, privkey, address). In summary think it would be more clear to refer to the byte array parameters in this document as addresses rather than accounts (which I argue is a more true representation of what they actually are). Thoughts? |
Token Standard ABI: {
"functions": [
{
"name": "totalSupply",
"parameters": [],
"returntype": "Integer"
},
{
"name": "name",
"parameters": [],
"returntype": "String"
},
{
"name": "symbol",
"parameters": [],
"returntype": "String"
},
{
"name": "decimals",
"parameters": [],
"returntype": "Integer"
},
{
"name": "balanceOf",
"parameters": [
{
"name": "account",
"type": "Hash160"
}
],
"returntype": "Integer"
},
{
"name": "transfer",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "to",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
}
],
"returntype": "Boolean"
}
],
"events": [
{
"name": "transfer",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "to",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
}
]
}
]
} |
It would be nice if we also had a standard set of functionality for ICOs (at least an ABI). https://github.com/neo-project/examples-csharp/blob/master/ICO_Template/ICO_Template.cs is a good start, but it'd be good if it could expose things like ico_start_time and ico_end_time. Not part of this proposal of course, but this seemed the most relevant so commenting here. |
@erikzhang we should also consider a 'listMethods' method which returns the definition for each supported method in the contract. |
@Dexaran @erikzhang removing can you explain more? perhaps I am missing something either way, the |
Alright, I'll try to give a brief explanation. How it works with Ether. Fallback function and payable modifier.As for Ethereum contracts and solidity, there is a fallback function that is executed whenever the call transaction does not provide a signature that matches any of the signatures of the functions implemented in this contract. Read solidity docs for more detailed description. There is a special If you want to create an Ethereum contract that will accept Ether deposits, you must explicitly declare a deposit function or a fallback function and use the contract Receiver_of_Ether
{
function() payable
{
// fallback function allows to deposit Ether to this contract.
// payable modifier is required.
}
} This is specially done to prevent the accidentally sent Ethers being stuck inside contracts. If the contract is not explicitly allowed to receive funds then any attempt of depositing Ether will fail and the funds will not be transferred to the contract (the funds will remain at user's balance). Rationale. Preventing user mistakes and losses of money.We should keep in mind that not all users are technically advanced and some of them will try to send Ether into contracts by mistake. This is a reasonable protection from the most common user mistakes that could lead to disasterous consequences and millions of dollars lost. How it works with ERC223 tokens.I followed this approach when developing the ERC223 standard. I think the contract should explicitly declare that it is specifically designed to receive tokens if it is going to receive tokens. Otherwise, it must reject token deposits by default. This is analogue of how it works with Ether. As for Ether, contract must implement a fallback function with contract Receiver_of_Tokens
{
function tokenFallback(address,uint256,bytes)
{
// tokenFallback function allows to deposit tokens to this contract.
// no payable modifier, we do not allow user to deposit ETH, but only tokens.
}
} It must not be possible to transfer tokens to a contract that is not designed to receive them (that does not implement a special Mistakes of ERC-20 standard and why a contract MUST explicitly declare that it is designed to receive funds.Unlike ERC-223 transfers or Ether transactions, ERC-20 transfer function does not require a receiver to implement a special function for it. A user can just send ERC-20 tokens to any address he wants. As a result, contracts that are not specifically designed to work with tokens (for example, ENS contracts and token contracts themselves) constantly receive tokens that are accidentally sent. These tokens become stuck inside contracts without any possibility to recover them. In other words, users lose their tokens (money) this way. Event handling is a common practice in programming. Transaction should be considered an event and it should be properly handled. ERC-20 lacks this transaction handling mechanism at all and this is a known problem of ERC20 standard. It already results in lost money (you can read about it here, here and here ). The last time I checked it, there were about $400,000 lost in stuck ERC-20 tokens. It was a long time ago, and I believe that we are talking about millions of dollars lost at the moment. |
Thanks @Drexan! This does not address the limitations of NEO I mentioned.
My concern above is that ERC223 cannot be implemented currently in NEO
given lack of dynamic SC calls
And if I am wrong and can be implemented, it at least has not been
described correctly in the current NEP-5 specification
…On Fri, Oct 27, 2017 at 12:52 PM Dexaran ***@***.***> wrote:
Alright, I'll try to give a brief explanation.
How it works with Ether. Fallback function and payable modifier.
As for Ethereum contracts and solidity, there is a fallback function that
is executed whenever the call transaction does not provide a signature that
matches any of the signatures of the functions implemented in this
contract. Read solidity docs
<http://solidity.readthedocs.io/en/develop/contracts.html> for more
detailed description. There is a special payable modifier that allows a
function of a contract to receive funds (Ether). You can not deposit any
Ether into contract that is not specially designed to receive Ether. The
transaction will always fail if the function that is executed is not marked
as payable.
If you want to create an Ethereum contract that will accept Ether
deposits, you must explicitly declare a deposit function or a fallback
function and use the payable modifier. Example:
contract Receiver_of_Ether
{
function() payable
{
// fallback function allows to deposit Ether to this contract.
// payable modifier is required.
}
}
This is specially done to prevent the accidentally sent Ethers being stuck
inside contracts. If the contract is not explicitly allowed to receive
funds then any attempt of depositing Ether will fail and the funds will not
be transferred to the contract (the funds will remain at user's balance).
Rationale. Preventing user mistakes and losses of money.
We should keep in mind that not all users are technically advanced and
some of them will try to send Ether into contracts by mistake. This is a
reasonable protection from the most common user mistakes that could lead to
disasterous consequences and millions of dollars lost.
How it works with ERC223 tokens.
I followed this approach when developing the ERC223 standard. I think the
contract *should* explicitly declare that it is specifically designed to
receive tokens if it is going to receive tokens. Otherwise, it *must*
reject token deposits by default. This is analogue of how it works with
Ether.
As for Ether, contract must implement a fallback function with payable
modifier to receive Ether.
As for tokens, contract must implement a tokenFallback function to
receive tokens. If the contract does not implement it, then any attempt to
deposit (Ether or tokens) must fail.
contract Receiver_of_Tokens
{
function tokenFallback(address,uint256,bytes)
{
// tokenFallback function allows to deposit tokens to this contract.
// no payable modifier, we do not allow user to deposit ETH, but only tokens.
}
}
It must not be possible to transfer tokens to a contract that is not
designed to receive them (that does not implement a special tokenFallback
function or any other function that you agree to use as token transfer
handler. The function name does not seem to be essential here).
Mistakes of ERC-20 standard and why a contract MUST explicitly declare
that it is designed to receive funds.
Unlike ERC-223 transfers or Ether transactions, ERC-20
<ethereum/EIPs#20> transfer function does not
require a receiver to implement a special function for it. A user can just
send ERC-20 tokens to any address he wants. As a result, contracts that are
not specifically designed to work with tokens (for example, ENS contracts
and token contracts themselves) constantly receive tokens that are
accidentally sent.
These tokens become stuck inside contracts without any possibility to
recover them. In other words, users lose their tokens (money) this way.
Event handling <https://en.wikipedia.org/wiki/Event_(computing)> is a
common practice in programming. Transaction should be considered an event
and it should be properly handled. ERC-20 lacks this transaction handling
mechanism at all and this is a known problem of ERC20 standard
***@***.***/erc20-token-standard-critical-problems-3c10fd48657b>
.
*It already results in lost money* (you can read about it here
<https://www.reddit.com/r/ethereum/comments/6e8y9o/the_ens_contract_becomes_token_holder_erc20/>,
here
<https://www.reddit.com/r/storj/comments/6t2czj/5000_are_lost_storj_erc20_tokens_are_vulnerable/>
and here
<https://www.reddit.com/r/storj/comments/6ajjo3/attention_issues_of_the_upcoming_storj_migration/>
). The last time I checked it, there were about $400,000 lost in stuck
ERC-20 tokens. It was a long time ago, and I believe that we are talking
about millions of dollars lost at the moment.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#4 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAFeEiSIhku9zsKEVse2rqmp5ooCUW64ks5swjRfgaJpZM4O0SdA>
.
|
I'm not really familiar with NEO. I can only describe how it works on Ethereum and why.
As for |
thanks for taking the time @Dexaran! i do agree with your critique of ERC20 my point in raising this comment is that NEP5 is not following ERC223 in its current state, and possibly, can't follow it right now given differences between NEO and ETH. my understanding is that NEO smart contracts require that any calls between SCs to be declared statically within the contract that will do the calling. this has potential scalability benefits but may prevent a direct reimplementation of ERC223. maybe @erikzhang can look at the above and comment further |
@erikzhang an update on this: @localhuman has confirmed with me that dynamic SC calls (calls between SCs that are not statically declared) are not allowed on the NEO VM. this means that ERC223 is currently not possible (a token needs to do a dynamic call on the receiver contract) it is very important that NEP-5 tokens are powerful enough to support the behaviors specified by either ERC20 or ERC223. among the many other applications, decentralized exchanges will not work without these features. as it stands, unless a token implements the optional methods in this NEP-5, it is impossible to send it to another SC and have that SC do meaningful work on your behalf we would recommend: (1) enabling dynamic SC calls: this would be a simple change in the VM, there is a lot of other low hanging fruit for performance before we get to sharding VM resources. there could also be something like a (2) more critically, make NEP-5 fully compliant with either ERC20 or ERC223. the tokens are not powerful enough for basic functionality right now in summary, (1) is important but (2) is absolutely necessary. it will be very bad if the ecosystem grows using the current version of NEP-5 |
@luodanwg can you bring this issue to Zhengwen attention ? I think @Ejhfast will do a PR for NEP5 Amendment with (2) making it fully compliant with ERC-20. Rgds. |
An important difference between Ethereum and NEO is that: in NEO, you can combine multiple invocations into one transaction, and ensure transaction consistency. |
@erikzhang if that is possible, it needs to be specified in the protocol, otherwise for all practical purposes NEP5 tokens are broken and will not be able to interact with SCs in interesting ways (lacking equivalent functionality to ERC223) also, in terms of whether it is possible, some of this logic needs to be conditional. for example, transfers should happen conditionally on the existence of |
No description provided.