PIP: PIP-0033
  Title: DATA operation RPC implementation    
  Type: Backend    
  Impact: None    
  Author: Benjamin Ansbach <benjaminansbach@gmail.com>    
  Comments-URI: https://discord.gg/sJqcgtD (channel #pip-0033)
  Status: Draft    
  Created: 2019-06-12    
## Summary A description of the missing JSON-RPC methods related to DATA operations. ## Motivation DATA Operations (optype = 10) were implemented in PascalCoin V4, but the node is missing the JSON-RPC methods to create and properly search for them. This PIP aims to describe the missing methods that need to be implemented to use this feature at it's full potential. To make use of DATA operation the JSON-RPC API of PascalCoin needs to implement methods to.. 1. create and sign DATA operations 2. find DATA operations based on it's unique properties. ## Specification The following sections describe implementation details of the JSON-RPC methods. ### Payload Splitting PascalCoin, at it's core, understands 2 types of encryption: `AES`, `ECIES (sender or target pubkey)` With DATA operations we are able to split a long message into multiple operations (limited by the payload size of 255 bytes) and combine them later on. DATA operations support 1. a field called `guid` which is a unique value identifying a group of operations. 2. a field called `data_sequence` which identifies the position of a single operation in a group of operations (`guid`). #### Implementation The JSON-RPC API for DATA operations will support splitting large payloads (resulting payload >255 bytes) into multiple DATA operations where the `guid` of a DATA operation could (if not explicitly given) and the `data_sequence` will (if not given) be managed by the requested node. The supported encryption methods will be applied before a split, meaning the payload will be encrypted and the encrypted value will be splitted. This will make single messages unusable as they cannot be decrypted with their accompanied operations grouped by `guid`, but saves valuable space. From the known and established encryption methods we can say the following (255 bytes payload): - `AES` An unencrypted payload of 223 bytes fits in a single operation. - `ECIES` - An unencrypted payload of 191 bytes fits in a single operation when using a p256 key - An unencrypted payload of 159 bytes fits in a single operation when using a p521 key - An unencrypted payload of 175 bytes fits in a single operation when using a p384 key - An unencrypted payload of 191 bytes fits in a single operation when using a t283 key When a JSON-RPC user wants to create a DATA operation, the following payload-related rules will apply: - GUID given? If not, create GUID. - Sequence given? If not, start sequence will be 0. - Split payload according to the splitting rules above and loop. - set `operation[n].data_sequence = sequence` - If `sequence > 0` - `operation[n].amount` will be set to `0` - `operation[n].fee` will be set to min fee (`0.0001`) - If offline signing, increment `last_n_operation` - `operation[n].payload` to `payload.slice(sequence * 255, 255)` - `sequence++` Errors that occur when creating one or more operations will be returned with the `valid` flag set to false, so users can re-send/re-sign them. ## Methods The following JSON-RPC methods are needed to make DATA operations available for everyone. A data type in `[` and `]` is optional, you can leave out the parameter in this case. ### senddata Executes a data operation. ``` Array senddata({ UINT32 sender, [UINT32 target = sender, ] UINT16 data_type, [UINT16 data_sequence = 0, ] [GUID guid = GUID.new, ] [PASCCURRENCY amount = 0, ] [PASCCURRENCY fee = 0, ] [HEXASTRING payload = '', ] [String payload_method = 'none', ] [String pwd = ''] }) ``` #### Parameters - `sender UINT32` The sender of the operation. If the sender is null, the signer will be used. - `target [UINT32] (default = sender or signer)` The account where the DATA operation is send to. If the target is null, the sender or (if null) the signer is used. - `data_type UINT16 (default = 0)` The data type of the operation. If not given, the data_type will be 0. - `data_sequence [UINT16]` The data sequence of the operation. If the data sequence cannot be determined (null or not given), it is 0 by default. - `guid [GUID]` A 16 Bytes GUID in `8-4-4-4-12` format. If null or not given, the node will generate a UUID V4 (random). - `amount [PASCCURRENCY] (defult = 0)` The amount to transfer to `target`, if not given or null the default value is 0. - `fee [PASCCURRENCY] (default = 0)` The fee for the operation, if not given or null the default value is 0. - `payload [HEXASTRING] (default = '')` The payload for the operation. If not given, the value is an empty string. - `payload_method [String] (default = 'none')` The encryption method. Can either be `none`, `dest`, `sender` or `aes`. - `pwd [String] (default = '')` The password when using `payload_method=aes`. Optional. #### Return value A array of all created operations. ### signdata Creates and signs a "DATA" operation for later use. ``` Array signdata({ UINT32 signer, [UINT32 sender = signer, ] [UINT32 target = sender, ] UINT16 data_type, [UINT16 data_sequence = 0, ] [GUID guid = GUID.new, ] [PASCCURRENCY amount = 0, ] [PASCCURRENCY fee = 0, ] [HEXASTRING payload = '', ] [String payload_method = 'none', ] [String pwd = ''] }) ``` #### Parameters - `rawoperations [HEXASTRING] (default = '')` In case this sign operation should be added to other signed operations, you'll need to provide the `rawoperations` HexaString of the previous signing request. If the parameter is not given, it will be set to '' (empty string). - `signer UINT32` The signer of the operation - `sender [UINT32] (default = signer)` The sender of the operation. If the sender is null, the signer will be used. - `target [UINT32] (default = sender or signer)` The account where the DATA operation is send to. If the target is null, the sender or (if null) the signer is used. - `data_type UINT16 (default = 0)` The data type of the operation. If not given, the data_type will be 0. - `data_sequence [UINT16]` The data sequence of the operation. If the data sequence cannot be determined (null or not given), it is 0 by default. - `guid [GUID]` A 16 Bytes GUID in `8-4-4-4-12` format. If null or not given, the node will generate a UUID V4 (random). - `last_n_operation UINT32` Last value of `n_operation` of the signer (or sender or target) - `amount [PASCCURRENCY] (defult = 0)` The amount to transfer to `target`, if not given or null the default value is 0. - `fee [PASCCURRENCY] (default = 0)` The fee for the operation, if not given or null the default value is 0. - `payload [HEXASTRING] (default = '')` The payload for the operation. If not given or null the value is an empty string. - `payload_method [String] (default = 'none')` The encryption method. Can either be `none`, `dest`, `sender` or `aes`. - `pwd [String] (default = '')` The password when using `payload_method` `aes`. Can be left out or null. #### Return value The given `rawoperations` altered by the new operation(s). ### finddataoperations This method will help to retrieve one or more DATA operations. DATA operations are special and will be heavily used, but the `getaccountoperations` method is already overloaded with parameters. Thats why we will introduce a new method that only searches for DATA operations. ``` Array finddataoperations({ [UINT32 sender = null, ] [UINT32 target = null, ] [GUID guid = null, ] [UINT16 data_type = null ,] [UINT16 data_sequence = null ,] [UINT32 start = 0 ,] [UINT16 max = 100 ,] }) ``` #### Parameters - `sender [UINT32] (default = null)` The sender of the data operation. Optional - `target [UINT32] (default = null)` The account that received the DATA operation. Optional. - `guid [GUID] (default = null)` A 16 Bytes GUID in `8-4-4-4-12` format. Optional. - `data_sequence [UINT16]` The data sequence of the operation to search for. Optional. - `data_type [UINT16]` The data type of the operation to search for. - `start [UINT32]` The start index to provide paging. - `max [UINT16]` The maximum returned values. While all parameters are optional, the method cannot handle a call to the method without any parameter. #### Rules - Either `sender` or `target` must be set - If `data_sequence` is set, the `guid` must be provided. - Data is returned in descending order (latest block first). ## Rationale DATA operations play a key role in V5 and adoption, they can be implemented in V4 already but it makes most sense to make them available with the protocol update. ## Backwards Compatibility The changes are backwards compatible. ## Reference Implementation None. ## Links - UUID V4: https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) - PascalCoin JSON RPC documentation: https://github.com/PascalCoin/PascalCoin/wiki/JSON-RPC-API