Skip to content

Commit

Permalink
Draft NEP 26 and Draft NEP 27: New NEPs describing onNEPXXPayment cal…
Browse files Browse the repository at this point in the history
…lbacks (#169)

* *: new NEPs describing onNEPXXPayment callbacks

Fixes #168.

Signed-off-by: Roman Khimov <roman@nspcc.ru>

* nep-Z: add bNEO example

Signed-off-by: Roman Khimov <roman@nspcc.ru>

* nep*: mention ASSERT as well

bNEO uses it and we can't say it's wrong.

Signed-off-by: Roman Khimov <roman@nspcc.ru>

* nep*: fix formatting

Mediawiki is not Markdown.

Signed-off-by: Roman Khimov <roman@nspcc.ru>

* Update nep-Y.mediawiki

Co-authored-by: Jimmy <jinghui@wayne.edu>

* Update nep-Y.mediawiki

Co-authored-by: Jimmy <jinghui@wayne.edu>

* Rename nep-Y.mediawiki to nep-25.mediawiki

* Update and rename nep-Z.mediawiki to nep-26.mediawiki

* Update nep-25.mediawiki

Co-authored-by: Jimmy <jinghui@wayne.edu>

* Update nep-26.mediawiki

Co-authored-by: Jimmy <jinghui@wayne.edu>

* Update and rename nep-26.mediawiki to nep-27.mediawiki

* Update and rename nep-25.mediawiki to nep-26.mediawiki

* nep-26/27: clarify failure mode for unimplemented onNEPXXPayment

Add a bit more details, signify the need for script hash check.

Signed-off-by: Roman Khimov <roman@nspcc.ru>

---------

Signed-off-by: Roman Khimov <roman@nspcc.ru>
Co-authored-by: Shargon <shargon@gmail.com>
Co-authored-by: Jimmy <jinghui@wayne.edu>
  • Loading branch information
3 people authored Jun 5, 2024
1 parent 69ccc34 commit c0e1fd5
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 0 deletions.
104 changes: 104 additions & 0 deletions nep-26.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<pre>
NEP: 26
Title: Smart contract transfer callback for non-fungible tokens
Author: Erik Zhang <erik@neo.org>, Roman Khimov <roman@nspcc.ru>, Jaime Kindelan <jaime@red4sec.com>, Jimmy Liao <jimmy@r3e.network>
Type: Informational
Status: Accepted
Created: 2024-03-03
Requires: 11
</pre>

==Abstract==

This proposal describes the callback method used by Neo smart contracts to
process transfers of non-fungible [[nep-11.mediawiki|NEP-11]] tokens to their addresses.

==Motivation==

While the original [[nep-11.mediawiki|NEP-11]] already defines this method, it
lacks some details relevant specifically to the receiver contract and it doesn't
allow for easy reference. This standard can be used in <code>supportedstandards</code>
section of [[nep-15.mediawiki|NEP-15 manifest]] or in any other situation to
refer to contracts able to receive [[nep-11.mediawiki|NEP-11]] tokens (but not
necessarily being [[nep-11.mediawiki|NEP-11]] themselves). Typical use cases
for this functionality are: depositing/staking (with contract locking and
managing tokens according to some rules) or exchange/minting (contract accepting
transfer to itself, but returning some different token to the sender).

==Specification==

Smart contracts that need to receive and own [[nep-11.mediawiki|NEP-11]] tokens
MUST implement <code>onNEP11Payment</code> method with the following signature:

<pre>
{
"name": "onNEP11Payment",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
},
{
"name": "tokenId",
"type": "ByteString"
},
{
"name": "data",
"type": "Any"
}
],
"returntype": "Void"
}
</pre>

A contract that doesn't implement this method will not be able to receive
[[nep-11.mediawiki|NEP-11]] tokens (standard requires this method to be called
unconditionally which will fail at the system call level if it's not implemented
which then leads to a complete transaction failure). This method is called by
[[nep-11.mediawiki|NEP-11]] contracts which tokens are being transferred. A
particular token can be obtained via the <code>System.Runtime.GetCallingScriptHash</code>
system call. Notice that technically this method MAY be called by entry scripts or
non-[[nep-11.mediawiki|NEP-11]] contracts as well, so contracts SHOULD check for
caller script hash to match their expectations like allowed/accepted tokens.
Processing this call means that contract trusts the caller to implement
[[nep-11.mediawiki|NEP-11]] correctly.

<code>from</code> parameter specifies the sender of tokens and can be <code>null</code>
for minted tokens.

<code>amount</code> is the amount of tokens transferred to the contract. It's
always 1 for non-divisible [[nep-11.mediawiki|NEP-11]] tokens.

<code>tokenId</code> is the transferred token ID.

<code>data</code> is the same <code>data</code>parameter that was given to the
[[nep-11.mediawiki|NEP-11]] <code>transfer</code> call. Contract can interpret
it in any application-specific way including imposing any restrictions on
accepted <code>data</code> contents.

If the contract implementing this NEP can't accept the transfer (for reasons like
unexpected token, wrong amount, forbidden sender, wrong <code>data</code>
parameter or any other) it MUST call <code>ABORT</code> or <code>ABORTMSG</code>
VM opcode to fail the transaction. This is the only way to ensure contract
won't own transferred tokens, because the method doesn't return any value
and exceptions can be handled by calling contract. Contact MAY also check for
various conditions with <code>ASSERT</code> or <code>ASSERTMSG</code> opcodes.

==Rationale==

This NEP just follows and explains [[nep-11.mediawiki|NEP-11]] semantics, no
design decisions made here.

==Backwards Compatibility==

This NEP is completely compatible with [[nep-11.mediawiki|NEP-11]], there are
just two extensions to it:
* addition of <code>ABORTMSG</code> opcode that didn't exist at the time of [[nep-11.mediawiki|NEP-11]] creation, but it's the same thing as <code>ABORT</code> semantically.
* explicit <code>ASSERT</code> and <code>ASSERTMSG</code> opcode allowance that was not a part of [[nep-11.mediawiki|NEP-11]], but also has the same function as <code>ABORT</code> for failed conditions.
==Implementation==

100 changes: 100 additions & 0 deletions nep-27.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<pre>
NEP: 27
Title: Smart contract transfer callback for fungible tokens
Author: Erik Zhang <erik@neo.org>, Roman Khimov <roman@nspcc.ru>, Jaime Kindelan <jaime@red4sec.com>, Jimmy Liao <jimmy@r3e.network>
Type: Informational
Status: Accepted
Created: 2024-03-03
Requires: 17
</pre>

==Abstract==

This proposal describes the callback method used by Neo smart contracts to
process transfers of fungible [[nep-17.mediawiki|NEP-17]] tokens to their addresses.

==Motivation==

While the original [[nep-17.mediawiki|NEP-17]] already defines this method, it
lacks some details relevant specifically to the receiver contract and it doesn't
allow for easy reference. This standard can be used in <code>supportedstandards</code>
section of [[nep-15.mediawiki|NEP-15 manifest]] or in any other situation to
refer to contracts able to receive [[nep-17.mediawiki|NEP-17]] tokens (but not
necessarily being [[nep-17.mediawiki|NEP-17]] themselves). Typical use cases
for this functionality are: depositing/staking (with contract locking and
managing tokens according to some rules) or exchange/minting (contract accepting
transfer to itself, but returning some different token to the sender).

==Specification==

Smart contracts that need to receive and own [[nep-17.mediawiki|NEP-17]] tokens
MUST implement <code>onNEP17Payment</code> method with the following signature:

<pre>
{
"name": "onNEP17Payment",
"parameters": [
{
"name": "from",
"type": "Hash160"
},
{
"name": "amount",
"type": "Integer"
},
{
"name": "data",
"type": "Any"
}
],
"returntype": "Void"
}
</pre>

A contract that doesn't implement this method will not be able to receive
[[nep-17.mediawiki|NEP-17]] tokens standard requires this method to be called
unconditionally which will fail at the system call level if it's not implemented
which then leads to a complete transaction failure). This method is called by
[[nep-17.mediawiki|NEP-17]] contracts which tokens are being transferred. A
particular token can be obtained via the <code>System.Runtime.GetCallingScriptHash</code>
system call. Notice that technically this method MAY be called by entry scripts or
non-[[nep-17.mediawiki|NEP-17]] contracts as well, so contracts SHOULD check for
caller script hash to match their expectations like allowed/accepted tokens.
Processing this call means that contract trusts the caller to implement
[[nep-17.mediawiki|NEP-17]] correctly.

<code>from</code> parameter specifies the sender of tokens and can be <code>null</code>
for minted tokens.

<code>amount</code> is the amount of tokens transferred to the contract.

<code>data</code> is the same <code>data</code>parameter that was given to the
[[nep-17.mediawiki|NEP-17]] <code>transfer</code> call. Contract can interpret
it in any application-specific way including imposing any restrictions on
accepted <code>data</code> contents.

If the contract implementing this NEP can't accept the transfer (for reasons like
unexpected token, wrong amount, forbidden sender, wrong <code>data</code>
parameter or any other) it MUST call <code>ABORT</code> or <code>ABORTMSG</code>
VM opcode to fail the transaction. This is the only way to ensure contract
won't own transferred tokens, because the method doesn't return any value
and exceptions can be handled by calling contract. Contact MAY also check for
various conditions with <code>ASSERT</code> or <code>ASSERTMSG</code> opcodes.

==Rationale==

This NEP just follows and explains [[nep-17.mediawiki|NEP-17]] semantics, no
design decisions made here.

==Backwards Compatibility==

This NEP is completely compatible with [[nep-17.mediawiki|NEP-17]], there are
just two extensions to it:
* addition of <code>ABORTMSG</code> opcode that didn't exist at the time of [[nep-17.mediawiki|NEP-17]] creation, but it's the same thing as <code>ABORT</code> semantically.
* explicit <code>ASSERT</code> and <code>ASSERTMSG</code> opcode allowance that was not a part of [[nep-17.mediawiki|NEP-17]], but also has the same function as <code>ABORT</code> for failed conditions.
==Implementation==

* https://github.com/nspcc-dev/neo-go/blob/8d67f17943553740fe4caa31c3e9efcf7921aba2/examples/nft-nd/nft.go#L213
* https://github.com/nspcc-dev/neofs-contract/blob/91962f2c5625d8aab42adde138f2411c52393382/contracts/neofs/contract.go#L237
* https://github.com/neoburger/code/blob/beb433288bd7b0da9d2245e2a0ae5af5309da7ed/BurgerNEO.cs#L42

0 comments on commit c0e1fd5

Please sign in to comment.