From 2fb9e33fa793e47899e70b6abdbc4bafd76ea2ba Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 18:15:06 -0300 Subject: [PATCH 1/7] Proposal for Solid States --- nep-solid.mediawiki | 122 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 nep-solid.mediawiki diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki new file mode 100644 index 00000000..6c55af65 --- /dev/null +++ b/nep-solid.mediawiki @@ -0,0 +1,122 @@ +
+  NEP: XYZ
+  Title: Solid State Transfers
+  Author: Igor Machado Coelho , Vitor Nazário Coelho , Fernando Díaz Toledano , "Who Else? Join Us!" 
+  Type: Standard
+  Status: Draft
+  Created: 2019-07-18
+  Requires: NEP-5
+
+ +==Abstract== + +This document describes the Solid State Transfers (SST) standard, which is a Verification Script +capable of providing public assertions regarding user assets, including minimum and precise balance. +This allows for wallets and explorers to implement extra asset security mechanisms in a straightforward manner. + +==Motivation== + +The Witness system of Neo Blockchain allows up-front verification of user claims, in the format of a Verification Script. +Typically, this is used to provide authentication for NEP-5 contracts, including authorization for NEP-5 asset transfers. +We propose to attach extra Witnesses named Solid State Transfers adding extra claims about the user, +such as precise balance and minimum balance at the moment transaction is put in a block. +This allows, explorers and wallets to easily verify correctness of balance at any moment in time, regardless of any other +storage verification technology. + +The main motivation for this standard is to allow extra security checks during blockchain verification phase, simplifing the development +and tests of diverse Neo clients in different programming languages. +This is complementary to any other proposed state verification technology, and it is valid for both Neo2 and Neo3 protocols. + +==Specification== + +Recall that NEP-5 asset transfers are performed by operation "tranfer": + +
+public static bool transfer(byte[] from, byte[] to, BigInteger amount)
+
+ +Also recall that user balance is obtained by operation "balanceOf": + +
+public static BigInteger balanceOf(byte[] account)
+
+ +We propose two balance verification modes: +- strict mode: witness is only valid if user has *exactly* the informed balance (before asset transfer) +- flexible mode: witness is valid if user has *at least* the informed balance (before asset transfer) + +Strict Mode can be implemented as the following Verification Script (with empty Invocation part): + +``` +PUSH_VALUE exact_balance_amount +execute operation "balanceOf" +EQUALS +ASSERT +``` + +Flexible Mode can be implemented as the following Verification Script (with empty Invocation part): + +``` +PUSH_VALUE minimum_balance_amount +execute operation "balanceOf" +GEQ +ASSERT +``` + +Popular user wallets are *strongly recommended* to adopt Strict Mode, since this prevents poorly implemented nodes +from returning wrong values on user balance. Note that: if Strict Mode is adopted, user transaction will **only be executed +if consensus nodes agree on the precise asset amount at that specific time**. +Also note that Strict Mode **strongly forbids** parallel operations on a specific account, since network will reject the second +transaction as soon as balance has changed (thus requiring operations to be performed one at a time). + +Flexible Mode can be adopted on other scenarios where parallel operations are required, since only minimum balance is required +at the moment of the operation. However, if massive operations are performed on the same account, including situations where balance +may be drastically reduced or increased in short periods of time, it is recommended to **NOT ADOPT** this standard. + +Note that any user **is still able to protect its assets**, by simply transfering assets to itself. + +==Rationale== + +The Strict Mode is able to provide *permanent evidence* that some user posesses a certain amount of NEP-5 tokens, in that moment of time. +Since Verification Scripts have this purpose, and no Verification is allowed to fail in the blockchain, this can be considered a very secure +approach of recording one's balance history in time. + +The same reasoning is valid for Flexible Mode, although one may still not know (in a direct manner) the precise assets in account (only minimum value). +It is important to mention that this standard only helps users to **directly know** the information, without requiring any other complete blockchain processing +method (that typically takes longer to validate). + +We believe that the cost of adding extra bytes as witnesses will not cause any harm to the blockchain, and on the contrary, will give so many other benefits +to both Neo users and software developers, increasing accountability and testing power. + +==Backwards Compatibility== + +This NEP is compatible with any other existing NEP, and can be easily implemented in both Neo2 and Neo3 protocols. + +==Test Cases== + +Examples for Strict Mode: + +- In wallet, load user account balance with 100 tokens +- Perform transfer of 60 tokens and include SST requiring equality to "100" +- Verification Script should return True + +- In wallet, load user account balance with 100 tokens +- Perform transfer of 60 tokens and include SST requiring equality to "0" +- Verification Script should return False + +Examples for Flexible Mode: + +- In wallet, load user account balance with 100 tokens +- Simulataneously, perform transfer of 35 tokens and include SST requiring greater than "60" +- Simulataneously, perform transfer of 40 tokens and include SST requiring greater than "60" +- Verification Script should return True, regardless of execution order + +- In wallet, load user account balance with 100 tokens +- Perform transfer of 40 tokens and include SST requiring greater than "65" +- Perform transfer of 35 tokens and include SST requiring greater than "65" +- Verification Script should return False, if executing in this exact order, and True, otherwise + + +==Implementation== + +Ongoing implementation on Neo: https://github.com/neo-project/neo/pull/2013 \ No newline at end of file From bbadc1dc5032a73402944dcb9c9e66e445a3df8c Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 18:51:09 -0300 Subject: [PATCH 2/7] more info --- nep-solid.mediawiki | 56 +++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki index 6c55af65..e542f5bd 100644 --- a/nep-solid.mediawiki +++ b/nep-solid.mediawiki @@ -42,26 +42,40 @@ public static BigInteger balanceOf(byte[] account) We propose two balance verification modes: -- strict mode: witness is only valid if user has *exactly* the informed balance (before asset transfer) -- flexible mode: witness is valid if user has *at least* the informed balance (before asset transfer) +* strict mode: witness is only valid if user has *exactly* the informed balance (before asset transfer) +* flexible mode: witness is valid if user has *at least* the informed balance (before asset transfer) Strict Mode can be implemented as the following Verification Script (with empty Invocation part): -``` + PUSH_VALUE exact_balance_amount execute operation "balanceOf" EQUALS ASSERT -``` + Flexible Mode can be implemented as the following Verification Script (with empty Invocation part): -``` + PUSH_VALUE minimum_balance_amount execute operation "balanceOf" GEQ ASSERT -``` + + +When limited to *two parallel operations*, 'minimum_balance_amount' can be calculated as: + + +current_balance - maximum of all parallel output transfer values + + +On general, it can be safely calculated as: + + +current_balance - sum of all parallel output transfer values + + +Some notes: Popular user wallets are *strongly recommended* to adopt Strict Mode, since this prevents poorly implemented nodes from returning wrong values on user balance. Note that: if Strict Mode is adopted, user transaction will **only be executed @@ -88,6 +102,8 @@ method (that typically takes longer to validate). We believe that the cost of adding extra bytes as witnesses will not cause any harm to the blockchain, and on the contrary, will give so many other benefits to both Neo users and software developers, increasing accountability and testing power. +This NEP can also be extended for other kinds of tokens/assets, such as NFTs. + ==Backwards Compatibility== This NEP is compatible with any other existing NEP, and can be easily implemented in both Neo2 and Neo3 protocols. @@ -96,25 +112,25 @@ This NEP is compatible with any other existing NEP, and can be easily implemente Examples for Strict Mode: -- In wallet, load user account balance with 100 tokens -- Perform transfer of 60 tokens and include SST requiring equality to "100" -- Verification Script should return True +* In wallet, load user account balance with 100 tokens +* Perform transfer of 60 tokens and include SST requiring equality to "100" +* Verification Script should return True -- In wallet, load user account balance with 100 tokens -- Perform transfer of 60 tokens and include SST requiring equality to "0" -- Verification Script should return False +* In wallet, load user account balance with 100 tokens +* Perform transfer of 60 tokens and include SST requiring equality to "0" +* Verification Script should return False Examples for Flexible Mode: -- In wallet, load user account balance with 100 tokens -- Simulataneously, perform transfer of 35 tokens and include SST requiring greater than "60" -- Simulataneously, perform transfer of 40 tokens and include SST requiring greater than "60" -- Verification Script should return True, regardless of execution order +* In wallet, load user account balance with 100 tokens +* Simulataneously, perform transfer of 35 tokens and include SST requiring greater than "60" +* Simulataneously, perform transfer of 40 tokens and include SST requiring greater than "60" +* Verification Script should return True, regardless of execution order -- In wallet, load user account balance with 100 tokens -- Perform transfer of 40 tokens and include SST requiring greater than "65" -- Perform transfer of 35 tokens and include SST requiring greater than "65" -- Verification Script should return False, if executing in this exact order, and True, otherwise +* In wallet, load user account balance with 100 tokens +* Perform transfer of 40 tokens and include SST requiring greater than "65" +* Perform transfer of 35 tokens and include SST requiring greater than "65" +* Verification Script should return False, if executing in this exact order, and True, otherwise ==Implementation== From 2ce4f8eefc7a1fb29c92ce45deb1118724257be7 Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 18:59:21 -0300 Subject: [PATCH 3/7] fix code and modes --- nep-solid.mediawiki | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki index e542f5bd..587193e0 100644 --- a/nep-solid.mediawiki +++ b/nep-solid.mediawiki @@ -27,9 +27,15 @@ The main motivation for this standard is to allow extra security checks during b and tests of diverse Neo clients in different programming languages. This is complementary to any other proposed state verification technology, and it is valid for both Neo2 and Neo3 protocols. +We propose two SST modes, called Strict and Flexible. +On practice, this means saying: + +* I'm going to transfer you X units of this token, and *I EXACTLY have Y units of this token* (strict) +* I'm going to transfer you X units of this token, and *I have AT LEAST Y units of this token* (flexible) + ==Specification== -Recall that NEP-5 asset transfers are performed by operation "tranfer": +Recall that NEP-5 asset transfers are performed by operation "transfer":
 public static bool transfer(byte[] from, byte[] to, BigInteger amount)
@@ -49,8 +55,11 @@ Strict Mode can be implemented as the following Verification Script (with empty
 
 
 PUSH_VALUE exact_balance_amount
+
 execute operation "balanceOf"
+
 EQUALS
+
 ASSERT
 
 
@@ -58,8 +67,11 @@ Flexible Mode can be implemented as the following Verification Script (with empt
 
 
 PUSH_VALUE minimum_balance_amount
+
 execute operation "balanceOf"
+
 GEQ
+
 ASSERT
 
 

From 6fe90dcf8154b6f285341b41bde03583bfc11bf2 Mon Sep 17 00:00:00 2001
From: Igor Machado 
Date: Thu, 22 Oct 2020 19:05:13 -0300
Subject: [PATCH 4/7] note on self transfer

---
 nep-solid.mediawiki | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki
index 587193e0..b3b8c18e 100644
--- a/nep-solid.mediawiki
+++ b/nep-solid.mediawiki
@@ -54,25 +54,19 @@ We propose two balance verification modes:
 Strict Mode can be implemented as the following Verification Script (with empty Invocation part):
 
 
-PUSH_VALUE exact_balance_amount
-
-execute operation "balanceOf"
-
-EQUALS
-
-ASSERT
+PUSH_VALUE exact_balance_amount
+execute operation "balanceOf"
+EQUALS
+ASSERT
Flexible Mode can be implemented as the following Verification Script (with empty Invocation part): -PUSH_VALUE minimum_balance_amount - -execute operation "balanceOf" - -GEQ - -ASSERT +PUSH_VALUE minimum_balance_amount
+execute operation "balanceOf"
+GEQ
+ASSERT
When limited to *two parallel operations*, 'minimum_balance_amount' can be calculated as: @@ -99,7 +93,7 @@ Flexible Mode can be adopted on other scenarios where parallel operations are re at the moment of the operation. However, if massive operations are performed on the same account, including situations where balance may be drastically reduced or increased in short periods of time, it is recommended to **NOT ADOPT** this standard. -Note that any user **is still able to protect its assets**, by simply transfering assets to itself. +Note that any user **is still able to protect its assets**, by simply **transfering assets to itself** using SST, after receiving them from anywhere. ==Rationale== From a4c6ac6115a94c73af1dc9b0eeb531f47beb569d Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 19:06:38 -0300 Subject: [PATCH 5/7] minimum_balance_amount --- nep-solid.mediawiki | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki index b3b8c18e..45c5adf6 100644 --- a/nep-solid.mediawiki +++ b/nep-solid.mediawiki @@ -72,13 +72,13 @@ ASSERT
When limited to *two parallel operations*, 'minimum_balance_amount' can be calculated as: -current_balance - maximum of all parallel output transfer values +minimum_balance_amount = current_balance - maximum of all parallel output transfer values On general, it can be safely calculated as: -current_balance - sum of all parallel output transfer values +minimum_balance_amount = current_balance - sum of all parallel output transfer values Some notes: From 3dfa8d31c445069ee196a644411cb9be1658e2db Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 20:26:26 -0300 Subject: [PATCH 6/7] prevents double spending --- nep-solid.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki index 45c5adf6..cae70e86 100644 --- a/nep-solid.mediawiki +++ b/nep-solid.mediawiki @@ -88,6 +88,7 @@ from returning wrong values on user balance. Note that: if Strict Mode is adopte if consensus nodes agree on the precise asset amount at that specific time**. Also note that Strict Mode **strongly forbids** parallel operations on a specific account, since network will reject the second transaction as soon as balance has changed (thus requiring operations to be performed one at a time). +Finally, note that this mode also prevents **unintentional double-spending on malfunction/out-of-sync wallets**. Flexible Mode can be adopted on other scenarios where parallel operations are required, since only minimum balance is required at the moment of the operation. However, if massive operations are performed on the same account, including situations where balance From 76e6986a473a6be90a84ad47385aecac7d414d2d Mon Sep 17 00:00:00 2001 From: Igor Machado Date: Thu, 22 Oct 2020 20:28:53 -0300 Subject: [PATCH 7/7] strict vs flexible --- nep-solid.mediawiki | 1 + 1 file changed, 1 insertion(+) diff --git a/nep-solid.mediawiki b/nep-solid.mediawiki index cae70e86..cf284e3a 100644 --- a/nep-solid.mediawiki +++ b/nep-solid.mediawiki @@ -28,6 +28,7 @@ and tests of diverse Neo clients in different programming languages. This is complementary to any other proposed state verification technology, and it is valid for both Neo2 and Neo3 protocols. We propose two SST modes, called Strict and Flexible. +Strict uses "==" operation, while Flexible uses ">=". On practice, this means saying: * I'm going to transfer you X units of this token, and *I EXACTLY have Y units of this token* (strict)