From 7e5a4e3917ea4f4e37bf5e8a40ea698f0ba96e9a Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 14 Jun 2019 10:52:20 +0800 Subject: [PATCH 1/4] Add new BEP --- BEP12.md | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 BEP12.md diff --git a/BEP12.md b/BEP12.md new file mode 100644 index 00000000..643f7eac --- /dev/null +++ b/BEP12.md @@ -0,0 +1,118 @@ +# BEP12: Implement Memo Validation +## Summary +This BEP describes a new feature that enables users to customize additional memo validation. +## Abstract +For Bitcoin and Ethereum, exchanges create unique addresses for each clients. It costs them too much effort to manage secret files and collect tokens to cold wallet. So now, for new blockchain platform, exchanges tender to use a single address for client deposit and require clients to input memo to identify client account information. + +However, this user experience change causes a lot of problems for both exchange customer support and clients. Clients may be panic when their tokens are missing and exchange supports have to verify the client deposit transactions manually. This is caused by that many users don’t realize that memo is required or they just forget to do that. What’s worse, sometimes their wallets don’t support transaction memo at all. + +It would be wonderful if binance chain can filter out these transactions which have no valid memo on binance chain. Thus clients will panic for losing money when they make a mistake in filling memo. +## Status +This BEP is WIP. +## Motivation +Currently, only exchanges can benefit from this BEP. However, this BEP proposes an important infrastructure for customized validation functions. In the future, more amazing features will be built on it. +## Specificaion +### Add Verification Flags into AppAccount +``` +type AppAccount struct { + auth.BaseAccount `json:"base"` + Name string `json:"name"` + FrozenCoins sdk.Coins `json:"frozen"` + LockedCoins sdk.Coins `json:"locked"` + Flags uint64 `json:”flags”` +} +``` +We will add new field named “flags” into “AppAccount”. Its data type is 64bit unsigned int. The highest bit represents if there are valiation functions are associated with this account. The rest of each bit can represent a validation function, which means an account can specify at most 63 validation functions. By default, all accounts’ flags are zero. Users can send transactions to update their account flags. +### New Transaction to Update Account Flags +Parameters for Updating Account Flags + +| | Type | Description | +|-------|----------------|-------------| +| From | sdk.AccAddress | Address of target account | +| Flags | uint64 | New account flags | + +For a valid value of flags, it should satisfiy the following requirements: + +- The highest bit should indicate if lower bits are all zero + + ``` + bool isHighestFlagsBitZero = (flags & 0x8000 0000 0000 0000 == 0) + bool isLowerFlagsBitsAllZero = (flags & 0x7FFFF FFFF FFFF FFFF == 0) + isHighestFlagsBitZero == isLowerFlagsBitsAllZero + ``` +- If a bit has no binded validation function, its value must not be 1. + +Users are free to set their account flags to any valid values. The account flags changes will take effect since the next height. + +### Memo validation +Firstly, this validation will check if the following conditions can be met: +The transaction type is send. +The address is the receiving address. +Then the validation function will ensure that the transaction memo is not empty and the memo only contains digital character. +This is the pseudocode: + +``` +func memoValiation(address, tx) error { + if tx.Type != “send” { + return nil + } + if ! isReceiver(tx, account.address) { + return nil + } + if tx.memo.length == 0 { + return err(“tx memo is empty”) + } + if !isAllDigital(tx.memo) { + return err(“tx memo contains non digital character”) + } + return nil +} +``` + +### Validations Entrance +CheckTx is the entrance of all customized validation functions. To minimize the impact to performance, we will check the highest bit of account flags first. If it is zero, no validation function will be called. Otherwise, we will iterate all bits which have binded validation functions. To reduce the cost of function call, we will check account flags before calling validation functions. This is the pseudocode: + +``` +func checkTx(tx) error { + ... + err = customizedValiation(tx) + if err != nil { + return err + } + ... +} +func customizedValiation(tx) error { + for addr in tx.involvedAddress() { + account = getAccount(addr) + if isHighestFlagsBitZero(account.Flags) { + return nil + } + if (account.Flags & MemoCheck ) { // MemoCheck = 0x01 + err := memoValiation(addr, tx) + if err != nil { + return err + } + } + ... + // Other validation functions + ... + } +} +``` +### Impact to Upgrade +For initial version, we just need to make a decision on which height binance chain will support setting account flags. + +In the future, more validation functions will be supported and existing validation functions might need to update, which means we must take scalability into consideration. + +Steps to add a new validation function: + +- Implement new validation functions and call them from **customizedValiation** +- Upgrade account flags validation to allow corresponding bits to be 1 since specified height. + +Steps to update an existing validation functions: + +- Add validation function code. +- Specify since which height the logic will take effect. + +## License +All the content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 77239c043c802d7748f41bc6ea533d8d5a577a70 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Fri, 14 Jun 2019 14:29:59 +0800 Subject: [PATCH 2/4] Update validation entrance --- BEP12.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/BEP12.md b/BEP12.md index 643f7eac..7d044aee 100644 --- a/BEP12.md +++ b/BEP12.md @@ -70,14 +70,16 @@ func memoValiation(address, tx) error { ``` ### Validations Entrance -CheckTx is the entrance of all customized validation functions. To minimize the impact to performance, we will check the highest bit of account flags first. If it is zero, no validation function will be called. Otherwise, we will iterate all bits which have binded validation functions. To reduce the cost of function call, we will check account flags before calling validation functions. This is the pseudocode: +“AnteHandler” is the entrance of all customized validation functions. To minimize the impact to performance, only when the running mode is check mode and the highest bit of account flags is 1, then the validation functions will be called. To reduce the cost of function call, we will check account flags before calling validation functions. This is the pseudocode: ``` -func checkTx(tx) error { - ... - err = customizedValiation(tx) - if err != nil { - return err +func anteHandler(tx) error { + … + if mode == CheckMode { + err = customizedValiation(tx) + if err != nil { + return err + } } ... } @@ -86,18 +88,19 @@ func customizedValiation(tx) error { account = getAccount(addr) if isHighestFlagsBitZero(account.Flags) { return nil - } + } if (account.Flags & MemoCheck ) { // MemoCheck = 0x01 err := memoValiation(addr, tx) if err != nil { return err } } - ... + … // Other validation functions - ... + .... } } + ``` ### Impact to Upgrade For initial version, we just need to make a decision on which height binance chain will support setting account flags. From 392c5fb67b4a9d85c86ca7c9cf213a2886452d10 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Tue, 18 Jun 2019 17:31:39 +0800 Subject: [PATCH 3/4] Improve this BEP according to suggestions --- BEP12.md | 113 +++++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 71 deletions(-) diff --git a/BEP12.md b/BEP12.md index 7d044aee..9e1265a6 100644 --- a/BEP12.md +++ b/BEP12.md @@ -1,12 +1,14 @@ -# BEP12: Implement Memo Validation +# BEP12: Introduce customized validation scripts and transfer memo validation ## Summary -This BEP describes a new feature that enables users to customize additional memo validation. +This BEP describes a new feature that enables users to customize validation scripts, and introduces the first validation script for transaction memo. ## Abstract -For Bitcoin and Ethereum, exchanges create unique addresses for each clients. It costs them too much effort to manage secret files and collect tokens to cold wallet. So now, for new blockchain platform, exchanges tender to use a single address for client deposit and require clients to input memo to identify client account information. +In some circumstance, users may want to specify some additional validations on some transactions. -However, this user experience change causes a lot of problems for both exchange customer support and clients. Clients may be panic when their tokens are missing and exchange supports have to verify the client deposit transactions manually. This is caused by that many users don’t realize that memo is required or they just forget to do that. What’s worse, sometimes their wallets don’t support transaction memo at all. +Taking exchange for example, for Bitcoin and Ethereum, exchanges create unique addresses for each clients. It costs them too much effort to manage secret files and collect tokens to cold wallet. So now, for new blockchain platform, exchanges tend to use a single address for client deposit and require clients to input memo to identify client account information. -It would be wonderful if binance chain can filter out these transactions which have no valid memo on binance chain. Thus clients will panic for losing money when they make a mistake in filling memo. +However, this user experience change causes a lot of problems for both exchange customer support and clients. Clients may be panic if their tokens are missing and exchange supports have to verify the client deposit transactions manually. + +For all transfer transactions which are intend to deposit tokens to enchanges, it would be nice if binance chain can reject these who have no valid memo. Thus clients won’t be panic for losing tokens and exchanges supports won’t suffer from heavy working load. ## Status This BEP is WIP. ## Motivation @@ -22,7 +24,7 @@ type AppAccount struct { Flags uint64 `json:”flags”` } ``` -We will add new field named “flags” into “AppAccount”. Its data type is 64bit unsigned int. The highest bit represents if there are valiation functions are associated with this account. The rest of each bit can represent a validation function, which means an account can specify at most 63 validation functions. By default, all accounts’ flags are zero. Users can send transactions to update their account flags. +We will add new field named “flags” into “AppAccount”. Its data type is 64bit unsigned int. The highest bit represents if there are validation functions are associated with this account. The rest of each bit will represent a validation function, which means an account can specify at most 63 validation functions. By default, all accounts’ flags are zero. Users can send transactions to update their account flags. ### New Transaction to Update Account Flags Parameters for Updating Account Flags @@ -31,91 +33,60 @@ Parameters for Updating Account Flags | From | sdk.AccAddress | Address of target account | | Flags | uint64 | New account flags | -For a valid value of flags, it should satisfiy the following requirements: - -- The highest bit should indicate if lower bits are all zero +For a valid value of flags, it should satisfy the following two requirements: - ``` - bool isHighestFlagsBitZero = (flags & 0x8000 0000 0000 0000 == 0) - bool isLowerFlagsBitsAllZero = (flags & 0x7FFFF FFFF FFFF FFFF == 0) - isHighestFlagsBitZero == isLowerFlagsBitsAllZero - ``` -- If a bit has no binded validation function, its value must not be 1. +- The highest bit can’t be binded to any validation function, it should indicate if lower bits are all zero: +(flags & 0x8000 0000 0000 0000 == 0) == (flags & 0x7FFF FFFF FFFF FFFF == 0) +- If a bit has no binded validation function, its value must be 0. -Users are free to set their account flags to any valid values. The account flags changes will take effect since the next height. +Users are free to set their account flags to any valid values. The account flags changes will take effect since the next height. ### Memo validation -Firstly, this validation will check if the following conditions can be met: -The transaction type is send. -The address is the receiving address. -Then the validation function will ensure that the transaction memo is not empty and the memo only contains digital character. -This is the pseudocode: +“AnteHandler” is the entrance of customized validation functions. To minimize the impact to performance, the following methods will be taken: -``` -func memoValiation(address, tx) error { - if tx.Type != “send” { - return nil - } - if ! isReceiver(tx, account.address) { - return nil - } - if tx.memo.length == 0 { - return err(“tx memo is empty”) - } - if !isAllDigital(tx.memo) { - return err(“tx memo contains non digital character”) - } - return nil -} -``` +- Only in check mode, the validation functions can be called. +- To reduce the cost of function call, account flags will be checked before calling validation functions. ### Validations Entrance -“AnteHandler” is the entrance of all customized validation functions. To minimize the impact to performance, only when the running mode is check mode and the highest bit of account flags is 1, then the validation functions will be called. To reduce the cost of function call, we will check account flags before calling validation functions. This is the pseudocode: +Firstly, this validation will check if the following conditions can be met: + +- The transaction type is send. +- The address is the receiving address. + +Then the validation function will ensure that the transaction memo is not empty and the memo only contains digital character. This is the pseudocode: ``` -func anteHandler(tx) error { - … - if mode == CheckMode { - err = customizedValiation(tx) - if err != nil { - return err - } - } - ... +func memoValiation(addr, tx) error { +if tx.Type != “send” { + return nil } -func customizedValiation(tx) error { - for addr in tx.involvedAddress() { - account = getAccount(addr) - if isHighestFlagsBitZero(account.Flags) { - return nil - } - if (account.Flags & MemoCheck ) { // MemoCheck = 0x01 - err := memoValiation(addr, tx) - if err != nil { - return err - } - } - … - // Other validation functions - .... - } +if ! isReceiver(tx, addr) { + return nil +} +if tx.memo.length == 0 { + return err(“tx memo is empty”) +} +if !isAllDigital(tx.memo) { + return err(“tx memo contains non digital character”) +} +return nil } - ``` + ### Impact to Upgrade -For initial version, we just need to make a decision on which height binance chain will support setting account flags. +For initial version, we just need to make a decision on which height binance chain will support the new transaction to update account flags. In the future, more validation functions will be supported and existing validation functions might need to update, which means we must take scalability into consideration. Steps to add a new validation function: -- Implement new validation functions and call them from **customizedValiation** -- Upgrade account flags validation to allow corresponding bits to be 1 since specified height. +- Implement a new validation functions and call it from entrance +- Update account flags validation to allow corresponding bits to be 1 since specified height. -Steps to update an existing validation functions: +Steps to update an existing validation function: -- Add validation function code. -- Specify since which height the logic will take effect. +- Add updated validation code. +- Specify since which height the new code will take effect. ## License All the content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 300e5a2da798a95eb86ee5c68e78e6fa6abd2893 Mon Sep 17 00:00:00 2001 From: HaoyangLiu Date: Thu, 20 Jun 2019 11:31:40 +0800 Subject: [PATCH 4/4] update according to suggestions --- BEP12.md | 75 +++++++++++++++++++++++--------------------------------- 1 file changed, 31 insertions(+), 44 deletions(-) diff --git a/BEP12.md b/BEP12.md index 9e1265a6..dfc0c0c7 100644 --- a/BEP12.md +++ b/BEP12.md @@ -1,31 +1,36 @@ -# BEP12: Introduce customized validation scripts and transfer memo validation +# BEP12: Introduce customized scripts and transfer memo validation ## Summary -This BEP describes a new feature that enables users to customize validation scripts, and introduces the first validation script for transaction memo. +This BEP describes a new feature that enables addresses to customize scripts, and introduces the a validation script for transfer transaction memo. ## Abstract -In some circumstance, users may want to specify some additional validations on some transactions. +In some circumstances, users may want to specify some additional functions or/and validations on some transactions. -Taking exchange for example, for Bitcoin and Ethereum, exchanges create unique addresses for each clients. It costs them too much effort to manage secret files and collect tokens to cold wallet. So now, for new blockchain platform, exchanges tend to use a single address for client deposit and require clients to input memo to identify client account information. +Taking exchange for example, for Bitcoin and Ethereum, exchanges create unique addresses for each client. It costs them too much effort to manage secret files and collect tokens to cold wallet. So now, for new blockchain platforms, exchanges tend to use a single address for client deposit and require clients to input memo (or call it “tag”) to identify client account information. -However, this user experience change causes a lot of problems for both exchange customer support and clients. Clients may be panic if their tokens are missing and exchange supports have to verify the client deposit transactions manually. +However, this user experience change causes a lot of problems for both exchange customer support and clients. Clients may be panic if they forget to input the correct memo and exchange cannot allocate the fund to their account. The exchange support have to verify the client deposit in other ways. + +For all transfer transactions which are depositing tokens to exchanges, it would be nice if Binance Chain can reject those that have no valid memo. Thus clients won’t be panic for losing tokens and exchanges supports won’t suffer from the heavy working load. + +Here a script model is introduced into Binance Chain. And each address can add new functions by associate itself with one or more predefined scripts. The memo validation is one first type of the scripts to introduce here. -For all transfer transactions which are intend to deposit tokens to enchanges, it would be nice if binance chain can reject these who have no valid memo. Thus clients won’t be panic for losing tokens and exchanges supports won’t suffer from heavy working load. ## Status This BEP is WIP. ## Motivation -Currently, only exchanges can benefit from this BEP. However, this BEP proposes an important infrastructure for customized validation functions. In the future, more amazing features will be built on it. +This memo validation can be used for any membership based deposit/charge business model. + +This BEP also proposes an important infrastructure for customized scripts. In the future, more amazing features will be built on it. ## Specificaion -### Add Verification Flags into AppAccount +### Add Flags into Address Structure ``` -type AppAccount struct { - auth.BaseAccount `json:"base"` - Name string `json:"name"` - FrozenCoins sdk.Coins `json:"frozen"` - LockedCoins sdk.Coins `json:"locked"` - Flags uint64 `json:”flags”` +type Account struct { + auth.BaseAccount `json:"base"` + Name string `json:"name"` + FrozenCoins sdk.Coins `json:"frozen"` + LockedCoins sdk.Coins `json:"locked"` + Flags uint64 `json:”flags”` } ``` -We will add new field named “flags” into “AppAccount”. Its data type is 64bit unsigned int. The highest bit represents if there are validation functions are associated with this account. The rest of each bit will represent a validation function, which means an account can specify at most 63 validation functions. By default, all accounts’ flags are zero. Users can send transactions to update their account flags. -### New Transaction to Update Account Flags +Each address represents an account. The account structure is shown as above. We will add a new field named “flags” into “Account”. Its data type is 64bit unsigned int. Each bit will represent a script, which means an account can specify at most 64 scripts. The flags of all existing accounts are zero. Users can send transactions to update their account flags. +### New Transaction: SetAccountFlags Parameters for Updating Account Flags | | Type | Description | @@ -33,27 +38,21 @@ Parameters for Updating Account Flags | From | sdk.AccAddress | Address of target account | | Flags | uint64 | New account flags | -For a valid value of flags, it should satisfy the following two requirements: +With this transaction, users can set their account flags to any values. But setting a bit which has no bonded script will not have any effect, unless a new script is bonded to it in the future. -- The highest bit can’t be binded to any validation function, it should indicate if lower bits are all zero: -(flags & 0x8000 0000 0000 0000 == 0) == (flags & 0x7FFF FFFF FFFF FFFF == 0) -- If a bit has no binded validation function, its value must be 0. +By default, all accounts’ flags are zero which means no script is specified. Suppose there are two available scripts(marked as A and B), and the lowest bit is bonded to script A and the second lowest bit is bonded to script B. If an address set its account flags to 0x03, then two scripts are enabled. If only script B is expected, then account flags should be set to 0x02. -Users are free to set their account flags to any valid values. The account flags changes will take effect since the next height. +Besides, the account flags changes will take effect since the next transaction. -### Memo validation -“AnteHandler” is the entrance of customized validation functions. To minimize the impact to performance, the following methods will be taken: +### Memo Check Script for Transfer +This script is aimed to ensure the transfer transactions have valid memo if the receivers require this. -- Only in check mode, the validation functions can be called. -- To reduce the cost of function call, account flags will be checked before calling validation functions. - -### Validations Entrance -Firstly, this validation will check if the following conditions can be met: +Firstly, this script will check the following conditions: - The transaction type is send. -- The address is the receiving address. +- The target address is the receiving address. -Then the validation function will ensure that the transaction memo is not empty and the memo only contains digital character. This is the pseudocode: +Then this script will ensure that the transaction memo is not empty and the memo only contains digital letters. This is the pseudocode: ``` func memoValiation(addr, tx) error { @@ -73,20 +72,8 @@ return nil } ``` -### Impact to Upgrade -For initial version, we just need to make a decision on which height binance chain will support the new transaction to update account flags. - -In the future, more validation functions will be supported and existing validation functions might need to update, which means we must take scalability into consideration. - -Steps to add a new validation function: - -- Implement a new validation functions and call it from entrance -- Update account flags validation to allow corresponding bits to be 1 since specified height. - -Steps to update an existing validation function: - -- Add updated validation code. -- Specify since which height the new code will take effect. +### Scalability +In the future, more scripts will be supported and existing scripts might need to be updated, so we must take scalability into consideration in the implementation. ## License All the content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/).