Skip to content
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

Replace NEP-5 with NEP-17 #126

Merged
merged 20 commits into from
Jul 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.mediawiki
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ First review [[nep-1.mediawiki|NEP-1]]. Then clone the repository and add your N
| Standard
| Accepted
|-
| [https://github.com/neo-project/proposals/pull/126 17]
| [[nep-17.mediawiki|17]]
| Token Standard
| Erik Zhang
| Standard
| Accepted
| Final
|-
|
| Dynamic Sharding
Expand Down
189 changes: 189 additions & 0 deletions nep-17.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<pre>
NEP: 17
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
Title: Token Standard
Author: Erik Zhang <erik@neo.org>
Type: Standard
Status: Final
Created: 2020-11-12
Replaces: 5
</pre>

==Abstract==

This proposal outlines a token standard for the NEO blockchain that will provide systems with a generalized interaction mechanism for tokenized Smart Contracts. This mechanic, along with the justification for each feature are defined. A template and examples are also provided to enable the development community.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be interesting to also invite previous authors of NEP-5 to join this NEP-17 for discussion, or even, authorship (if they agree too).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S.: just noticed you informed that on the TODO list, requiring people to submit Pull Request. That's fine then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ping @lllwvlvwlll to discuss with other authors of NEP-5.


==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 are required by every Smart Contract that employs a token.

==Specification==

In the method definitions below, we provide both the definitions of the functions as they are defined in the contract as well as the invoke parameters.

===Methods===

erikzhang marked this conversation as resolved.
Show resolved Hide resolved
====symbol====

<pre>
{
"name": "symbol",
"safe": true,
"parameters": [],
"returntype": "String"
}
</pre>

Returns a short string representing symbol of the token managed in this contract. e.g. <code>"MYT"</code>. This string MUST be valid ASCII, MUST NOT contain whitespace or control characters, SHOULD be limited to uppercase Latin alphabet (i.e. the 26 letters used in English) and SHOULD be short (3-8 characters is recommended).

This method MUST always return the same value every time it is invoked.

erikzhang marked this conversation as resolved.
Show resolved Hide resolved
====decimals====

<pre>
{
"name": "decimals",
"safe": true,
"parameters": [],
"returntype": "Integer"
}
</pre>

Returns the number of decimals used by the token - e.g. <code>8</code>, means to divide the token amount by <code>100,000,000</code> to get its user representation.
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

This method MUST always return the same value every time it is invoked.

====totalSupply====

<pre>
{
"name": "totalSupply",
"safe": true,
"parameters": [],
"returntype": "Integer"
}
</pre>

Returns the total token supply deployed in the system.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we also need to limit it for the same reasons (at least to int64), and balanceOf as well.


====balanceOf====

<pre>
{
"name": "balanceOf",
"safe": true,
"parameters": [
{
"name": "account",
"type": "Hash160"
}
],
"returntype": "Integer"
}
</pre>

Returns the token balance of the <code>account</code>.

The parameter <code>account</code> MUST be a 20-byte address. If not, this method SHOULD <code>throw</code> an exception.
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

If the <code>account</code> is an unused address, this method MUST return <code>0</code>.

====transfer====

<pre>
{
"name": "transfer",
"safe": false,
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "to",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
},
{
"name": "data",
"type": "Any"
}
],
"returntype": "Boolean"
}
</pre>

Transfers an <code>amount</code> of tokens from the <code>from</code> account to the <code>to</code> account.

The parameters <code>from</code> and <code>to</code> MUST be 20-byte addresses. If not, this method SHOULD <code>throw</code> an exception.

The parameter <code>amount</code> MUST be greater than or equal to <code>0</code>. If not, this method SHOULD <code>throw</code> an exception.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Info about parameter data is missing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the receiver is a deployed contract, the function MUST call onPayment method on receiver contract with the data parameter from transfer AFTER firing the Transfer event. If the receiver doesn't want to receive this transfer it MUST call ABORT.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, whether we need to add a brief description like why we need this parameter, what's the size limitation, etc.


The function MUST return <code>false</code> if the <code>from</code> account balance does not have enough tokens to spend.

If the method succeeds, it MUST fire the <code>Transfer</code> event, and MUST return <code>true</code>, even if the <code>amount</code> is <code>0</code>, or <code>from</code> and <code>to</code> are the same address.

The function SHOULD check whether the <code>from</code> address equals the caller contract hash. If so, the transfer SHOULD be processed; If not, the function SHOULD use the SYSCALL <code>Neo.Runtime.CheckWitness</code> to verify the transfer.
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

If the transfer is not processed, the function MUST return <code>false</code>.

If the receiver is a deployed contract, the function MUST call <code>onNEP17Payment</code> method on receiver contract with the <code>data</code> parameter from <code>transfer</code> AFTER firing the <code>Transfer</code> event. If the receiver doesn't want to receive this transfer it MUST call <code>ABORT</code>.

erikzhang marked this conversation as resolved.
Show resolved Hide resolved
<pre>
{
"name": "onNEP17Payment",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
},
{
"name": "data",
"type": "Any"
}
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
],
"returntype": "Void"
}
</pre>

===Events===

====Transfer====

<pre>
{
"name": "Transfer",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "to",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
}
shargon marked this conversation as resolved.
Show resolved Hide resolved
]
}
</pre>

MUST trigger when tokens are transferred, including zero value transfers and self-transfers.
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

A token contract which creates new tokens MUST trigger a <code>Transfer</code> event with the <code>from</code> address set to <code>null</code> when tokens are created.
erikzhang marked this conversation as resolved.
Show resolved Hide resolved
erikzhang marked this conversation as resolved.
Show resolved Hide resolved

A token contract which burns tokens MUST trigger a <code>Transfer</code> event with the <code>to</code> address set to <code>null</code> when tokens are burned.

==Implementation==

C#: https://github.com/neo-project/neo-devpack-dotnet/blob/master/src/Neo.SmartContract.Framework/Nep17Token.cs

Python: https://github.com/CityOfZion/neo3-boa/blob/development/boa3_test/examples/NEP17.py