Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 40 additions & 22 deletions docs/PolkaVM/smart_contract_storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@ The QF PolkaVM Smart contract storage design and requirements.
## Features

- Allows to store on chain data using key-value like API.
- Allows to read/write stored data only by owner (i.e. data belongs to account) of this data.
> Bref:
> Let say Alice runs a smart contract that stored value = 1 by key "K" using storage.set() function;
> then storage key (or real key) = caller_address.str() + contract_address.str() + "K",
> Let say Alice runs a smart contract that stored some value by key "K" using storage.set() function;
> then storage key (or real key) is a composite key (contract_address, version, "K"),
> where `caller_adress` is an address of caller (in this context it's address of Alice)
> `contract_address` is an address of smart contract (`docs/PolkaVM/blob_hashing_addressing.md`).
> For getting value from the storage the same rule is applied.
> `version` is a smart contract version.
> For getting or deleting value from the storage the same rule is applied.
>
> Hence: storage.get(), storage.set(), storage.delete(), storage.purge() and storage.list() are protecting data from reading/writing storated values from different accounts by design, since address of Alice != addres of Bob.
>
- Supports encode/decode complex sturctures [not in the first implmentation]: bool, u{8,16,32,64,128}, i{8,16,32,64,128}, String, tuples, and arrays.

The references:
(1) https://use.ink/docs/v5/basics/storing-values
Expand All @@ -28,55 +25,76 @@ The references:

For getting a non-mutable reference to data.
```
storage.get(X) :: get(String) -> Option<bool | u{8,16,32,64,128} | i{8,16,32,64,128} | String | tuples | arrays>,
storage.get(K) :: storage.get(Vec<u8>) -> Option<Vec<u8>>,
Where:
- X is a key with type String;
- If K = None means no value found by given key;
- K is a key with type Vec<u8>;
- None means no value found by given key;
- the returned data is not a reference and can't be used for mutating a value.
```

### Set a new value or mutate a stored value

For storing a data by given key.
```
storage.set(X, V) :: set(String, bool | u{8,16,32,64,128} | i{8,16,32,64,128} | String | tuples | arrays) -> bool
storage.set(K, V) :: storage.set(Vec<u8>, Vec<u8>) -> bool
Where:
- X is a key with type String;
- K is a key with type Vec<u8>;
- returns true, if value is stored, false if not.
```

### Delete stored value by key
For erasing a data by given key.
```
storage.delete(X) = K -> any_of(true or false)
storage.delete(K) :: storage.delete(Vec<u8>) -> bool
Where:
- X is a key with type String;
- K is a key with type Vec<u8>;
- returns true, if value is removed or not existed, false if error occured.
```

### Purge storage

For purge all caller's storated data in one call.
#### Option #1: For purge all storated data of the current smart contract in one call.

#### Option #2: For purge all storated data of the current smart contract of the current caller in one call.

```
storage.purge() = K -> any_of(true or false)
storage.purge() :: storage.purge() -> u16
Where:
- returns true, if value is stored, false if not.
- returns number of purged tuples.
```

### Count elements
For get number of storated values (i.e. value is a tuple, values are tuples).

#### Option #1: For get number of storated values of the currenct smart contract (i.e. value is a tuple, values are tuples).

#### Option #2: For get number of storated values of the currenct smart contract of the current caller (i.e. value is a tuple, values are tuples).

```
storage.count() = K -> any_of(u16)
storage.count() :: storage.count() -> u16
Where:
- returns number of stored tuples, 0 if no data stored.
```

### List
For list all caller's storated data. All returned values are non-mutable.

#### Option #1: For list storated data of the currenct smart contract. All returned values are non-mutable.

#### Option #2: For list storated data of the currenct smart contract of the current caller. All returned values are non-mutable.

```
storage.list([limit, offset]) = K -> any_of([tuples])
storage.list(limit, offset) :: storage.list(Option<u16>, Option<u16>) -> Vec<(Vec<u8>, Vec<u8>)>
Where:
- limit max possible elements in K
- offset shift from begining of storated tuples
- returns array of storate tuples, array could be empty, if no data storated.
- returns array of storated tuples, array could be empty, if no data storated.
```

There are 2 options of serialization returned data:

1. SCALE

2. Custom binary serialization a-la "Length-Prefix Encoding" or "TLV":

```
key_size;value_size;number_of_items;key1;value1;...;keyN;valueN
```