Data Types
Type Categories
In PREDA types could be mainly classified into 2 categories: value type and reference type.
Value types store the data right in the variable, when they are assigned, the data is copied.
bool a = true;
bool b;
b = a; // b get a copy of a's value
b = false; // only b's copy of value is modified, value of a is still "true"
Typical value types are numbers, boolean and enumeration types.
Reference types store a reference to the actual data, when they are assigned, the reference is copied and the data is shared.
struct S{
bool a;
}
S s0;
s0.a = true;
S s1;
s1 = s0; // s1 now holds a reference to the same data as s0's
s1.a = false; // the shared copy of data is modified, hence s0.a is now also "false"
Typical reference types are string, array, map, token and user-defined structures.
Value Types
Built-in Boolean and Integer Types
PREDA has the following built-in boolean and integer types:
type | size in bytes | value range |
---|---|---|
bool | 1 | true / false |
int8 | 1 | [-2^7, 2^7-1] |
int16 | 2 | [-2^15, 2^15-1] |
int32 | 4 | [-2^31, 2^31-1] |
int64 | 8 | [-2^63, 2^63-1] |
int128 | 16 | [-2^127, 2^127-1] |
int256 | 32 | [-2^255, 2^255-1] |
int512 | 64 | [-2^511, 2^511-1] |
uint8 | 1 | [0, 2^8-1] |
uint16 | 2 | [0, 2^16-1] |
uint32 | 4 | [0, 2^32-1] |
uint64 | 8 | [0, 2^64-1] |
uint128 | 16 | [0, 2^128-1] |
uint256 | 32 | [0, 2^256-1] |
uint512 | 64 | [0, 2^512-1] |
bigint | varying | [-2^8128 + 1, 2^8128 - 1] |
Supported operators
type | symbols | bool | int types | uint types | bigint |
---|---|---|---|---|---|
assignment | = | X | X | X | X |
logical | &&, ||, ! | X | |||
equality comparison | ==, != | X | X | X | X |
generic comparison | <, >, <=, >= | X | X | X | |
increment and decrement | ++, -- | X | X | X | |
arithmetic | +, -, *, /, %, +=, -=, *=, /=, %= | X | X | X | |
negation | - | X | X | ||
bitwise | ~, &, ^, |, <<, >>, &=, ^=, |=, <<=, >>= | X |
Note: when uint types are shifted more than its bit-width, result would be 0.
Built-in Floating Point Types
PREDA has three types of build-in floating point types: float256, float512 and float1024, with the corresponding bit-width. They support the following operators
type | symbols | float256 / float512 / float1024 |
---|---|---|
assignment | = | X |
logical | &&, ||, ! | |
equality comparison | ==, != | X |
generic comparison | <, >, <=, >= | X |
increment and decrement | ++, -- | |
arithmetic | +, -, *, /, %, +=, -=, *=, /=, %= | X (except modulo) |
negation | - | X |
bitwise | ~, &, ^, |, <<, >>, &=, ^=, |=, <<=, >>= |
Enumerations
Enumeration types are defined with a list of enumerators which the value is restricted to.
enum MyEnum{
EnumValueA,
EnumValueB,
...
}
MyEnum e = MyEnum.EnumValueA; // enumerators must be accessed through the enumeration type name
An enumeration type cannot have more than 65535 enumerators.
Other Built-in Value Types
In addition to the types above, PREDA also provides the following built-in fundamental types:
type | size in bytes | description |
---|---|---|
blob | 36 | digest of a data block |
hash | 32 | SHA256 hash value |
address | 36 | an address on the chain |
Supported operators
type | symbols | blob | hash | address |
---|---|---|---|---|
assignment | = | X | X | X |
logical | &&, ||, ! | |||
equality comparison | ==, != | X | X | X |
generic comparison | <, >, <=, >= | X | X | X |
increment and decrement | ++, -- | |||
arithmetic | +, -, *, /, %, +=, -=, *=, /=, %= | |||
negation | - | |||
bitwise | ~, &, ^, |, <<, >>, &=, ^=, |=, <<=, >>= |
The type address has the following built-in member functions:
function | return type | arguments | is const | description |
---|---|---|---|---|
is_user | bool | None | Yes | if the address is a user address |
is_delegated | bool | None | Yes | if the address is a delegated address |
is_dapp | bool | None | Yes | if the address is a dapp address |
is_asset | bool | None | Yes | if the address is an asset address |
is_name | bool | None | Yes | if the address is a name address |
is_contract | bool | None | Yes | if the address is a contract address |
is_custom | bool | None | Yes | if the address is a custom address |
Reference Types
Built-in Generic Containers
type | size in bytes | description |
---|---|---|
array | varying | a dynamic array of elements of the same type |
map | varying | a mapping from keys to values |
Supported operators
type | symbols | array | map |
---|---|---|---|
assignment | = | X | X |
logical | &&, ||, ! | ||
equality comparison | ==, != | ||
generic comparison | <, >, <=, >= | ||
increment and decrement | ++, -- | ||
arithmetic | +, -, *, /, %, +=, -=, *=, /=, %= | ||
negation | - | ||
bitwise | ~, &, ^, |, <<, >>, &=, ^=, |=, <<=, >>= |
Dynamic Array : array
An array is an array of dynamic size containing elements of the same type. It supports the bracket operator "[]", the index type must be uint32. The corresponding value type is the first template parameter given at definition, e.g. array\<int64>. array has the following built-in member functions that could be access through the dot operator ".":
function | return type | arguments | is const | description |
---|---|---|---|---|
length | uint32 | None | Yes | returns the number of elements in the array |
set_length | None | uint32 newLength | No | resize the array to newLength. Existing elements are kept. If newLength is larger than current length, elements with default value of valueType are appended. |
push | None | valueType newElement | No | append a new element to the end of the array |
pop | None | None | No | remove the last element from the array |
Key-Value Map: map
A map is a mapping from keys to values. It supports the bracket operator "[]". The key type and value type are the first and second template parameter given at definition, e.g. map\<address, string>. map has the following built-in member functions that could be access through the dot operator ".":
function | return type | arguments | is const | description |
---|---|---|---|---|
has | bool | keyType key | Yes | if the key exists in the map |
erase | None | keyType key | No | remove the element that has the given key, if it exists |
string
string holds an array of characters in UTF-8 format. Besides assignment ("="), it also supports equality comparison ("==", "!=") and generic comparison ("<", ">", "<=", ">=") operators. string has the following built-in member functions that could be access through the dot operator ".":
function | return type | arguments | is const | description |
---|---|---|---|---|
set | None | string str | No | set the content of the string to str. |
append | None | string str | No | append str to the end of the current string |
length | uint16 | None | Yes | get the length of the string |
A string can have up to 65535 characters.
token
token is the built-in type for carrying certain amount of tokens that can be also stored in contracts states or carried around in transactions. It doesn't support any operator besides assignment "=" (to copy the reference, since it's a reference type). It has the following built-in functions
function | return type | arguments | is const | description |
---|---|---|---|---|
get_id | uint64 | None | Yes | returns the id of the token stored in token |
get_amount | bigint | None | Yes | returns the amount of token stored in type |
transfer | bool | token recipient, bigint transfer_amount | No | transfers a certain amount of token to another token |
transfer_all | bool | token recipient | No | transfers all token in the current token to another one |
transfer() and transfer_all() would fail if:
- the token id is 0, or
- the recipient is already holding some token of a different id, or
In addition, transfer() could fail if:
the amount to transfer is negative, or
the token doesn't have sufficient amount to transfer.
Structures
Users can define custom struct types in their code.
A struct is a collection of data grouped together under one name. The members of a struct can be of any built-in type and other user-defined structs.
A struct cannot have member functions.
struct MyStruct{
TypeA memberA;
TypeB memberB;
TypeC memberC;
...
}
The members of a struct can be accessed using the dot operator ".", for example:
// following the definition above
MyStruct myStruct;
myStruct.memberA = ...
A struct cannot have more than 255 members.
Type Conversion
Implicit Conversion
PREDA allows implicit conversion from integers to another integer type with wider range, if both types are signed or unsigned, e.g.
int16 x;
x = 3; // Error: integer literals default to type "int32", which has wider range than int16 . Write x = 3i16 instead.
int8 y;
y = x; // Error: int8 is not a subset of int16. Write y = int16(x) instead.
uint64 v;
int256 u = v; // Error: there is no implicit conversion between signed / unsigned integer types. Write u = int256(v) instead.
uint128 w = v; // Ok: Converting from unsigned 64-bit to unsigned 128-bit, which has a wider range
Explicit Conversion
Explicit type conversion is allowed between
From | To | Explanation |
---|---|---|
any integer type | any integer type | A runtime check will be performed to verify that the source value is inside range of the target type. Otherwise a runtime error will be generated and execution ends immediately |
any integer / float type | string | Convert the number to a readable string |
string | address | Convert a string in the format of address literal to a string |
string | hash | Calculate the hash value of a string |
hash | address | Create a custom type address with value equal to the hash |
hash | string | Convert the hash to a string in the same format as a hash literal, but without ":hash" suffix |
address | string | Convert the address to a string in the same format as a address literal |
A couple examples:
int16 x = 1000i16;
uint8 y = uint8(x); // Runtime error: 1000 is not within value range of uint8, which is [0, 255]
float256 f = 100.1324;
string s = string(f); // s is now "100.1324"
address a = vffgwr07yq323axszgxbr2qp9azzbyjjm844s90z8ack63s6hrch683z48:ed25519
s = string(a); // s is now "vffgwr07yq323axszgxbr2qp9azzbyjjm844s90z8ack63s6hrch683z48:ed25519"
hash h = 36nwe8x9sig7gb98zkb6gh@qarffhvf6c3ok9433@tz9ne4mb6qi:hash
s = string(h); // s is now "36nwe8x9s1g7gb98zkb6hzzqarffhvf6c30k9433ztz9ne4mb6q0"