diff --git a/nep-26.mediawiki b/nep-26.mediawiki new file mode 100644 index 00000000..87e9e015 --- /dev/null +++ b/nep-26.mediawiki @@ -0,0 +1,104 @@ +
+  NEP: 26
+  Title: Smart contract transfer callback for non-fungible tokens
+  Author: Erik Zhang , Roman Khimov , Jaime Kindelan , Jimmy Liao 
+  Type: Informational
+  Status: Accepted
+  Created: 2024-03-03
+  Requires: 11
+
+ +==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 supportedstandards +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 onNEP11Payment method with the following signature: + +
+{
+  "name": "onNEP11Payment",
+  "parameters": [
+    {
+      "name": "from",
+      "type": "Hash160"
+    },
+    {
+      "name": "amount",
+      "type": "Integer"
+    },
+    {
+      "name": "tokenId",
+      "type": "ByteString"
+    },
+    {
+      "name": "data",
+      "type": "Any"
+    }
+  ],
+  "returntype": "Void"
+}
+
+ +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 System.Runtime.GetCallingScriptHash +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. + +from parameter specifies the sender of tokens and can be null +for minted tokens. + +amount is the amount of tokens transferred to the contract. It's +always 1 for non-divisible [[nep-11.mediawiki|NEP-11]] tokens. + +tokenId is the transferred token ID. + +data is the same dataparameter that was given to the +[[nep-11.mediawiki|NEP-11]] transfer call. Contract can interpret +it in any application-specific way including imposing any restrictions on +accepted data contents. + +If the contract implementing this NEP can't accept the transfer (for reasons like +unexpected token, wrong amount, forbidden sender, wrong data +parameter or any other) it MUST call ABORT or ABORTMSG +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 ASSERT or ASSERTMSG 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 ABORTMSG opcode that didn't exist at the time of [[nep-11.mediawiki|NEP-11]] creation, but it's the same thing as ABORT semantically. +* explicit ASSERT and ASSERTMSG opcode allowance that was not a part of [[nep-11.mediawiki|NEP-11]], but also has the same function as ABORT for failed conditions. + +==Implementation== + diff --git a/nep-27.mediawiki b/nep-27.mediawiki new file mode 100644 index 00000000..bb7b5d77 --- /dev/null +++ b/nep-27.mediawiki @@ -0,0 +1,100 @@ +
+  NEP: 27
+  Title: Smart contract transfer callback for fungible tokens
+  Author: Erik Zhang , Roman Khimov , Jaime Kindelan , Jimmy Liao 
+  Type: Informational
+  Status: Accepted
+  Created: 2024-03-03
+  Requires: 17
+
+ +==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 supportedstandards +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 onNEP17Payment method with the following signature: + +
+{
+  "name": "onNEP17Payment",
+  "parameters": [
+    {
+      "name": "from",
+      "type": "Hash160"
+    },
+    {
+      "name": "amount",
+      "type": "Integer"
+    },
+    {
+      "name": "data",
+      "type": "Any"
+    }
+  ],
+  "returntype": "Void"
+}
+
+ +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 System.Runtime.GetCallingScriptHash +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. + +from parameter specifies the sender of tokens and can be null +for minted tokens. + +amount is the amount of tokens transferred to the contract. + +data is the same dataparameter that was given to the +[[nep-17.mediawiki|NEP-17]] transfer call. Contract can interpret +it in any application-specific way including imposing any restrictions on +accepted data contents. + +If the contract implementing this NEP can't accept the transfer (for reasons like +unexpected token, wrong amount, forbidden sender, wrong data +parameter or any other) it MUST call ABORT or ABORTMSG +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 ASSERT or ASSERTMSG 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 ABORTMSG opcode that didn't exist at the time of [[nep-17.mediawiki|NEP-17]] creation, but it's the same thing as ABORT semantically. +* explicit ASSERT and ASSERTMSG opcode allowance that was not a part of [[nep-17.mediawiki|NEP-17]], but also has the same function as ABORT 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