Types

Viper is a statically typed language, which means that the type of each variable (state and local) needs to be specified or at least known at compile-time. Viper provides several elementary types which can be combined to form complex types.

In addition, types can interact with each other in expressions containing operators.

Value Types

The following types are also called value types because variables of these types will always be passed by value, i.e. they are always copied when they are used as function arguments or in assignments.

Boolean

Keyword: bool

A boolean is a type to store a logical/truth value.

Values

The only possible values are the constants true and false.

Operators

Operator Description
x not y Logical negation
x and y Logical conjunction
x or y Logical disjunction
x == y Equality
x != y Inequality

The operators or and and apply the common short-circuiting rules.

Signed Integer (128 bit)

Keyword: num

A signed integer (128 bit) is a type to store positive and negative integers.

Values

Signed integer values between -2127 and (2127 - 1), inclusive.

Operators

Comparisons

Comparisons return a boolean value.

Operator Description
x < y Less than
x <= y Less or equal
x == y Equals
x != y Does not equal
x >= y Greater or equal
x > y Greater than

x and y must be of the type num.

Arithmetic Operators
Operator Description
x + y Addition
x - y Subtraction
-x Unary minus/Negation
x * y Multiplication
x / y Divison
x**y Exponentiation
x % y Modulo
min(x, y) Minimum
max(x, y) Maximum

x and y must be of the type num.

Unsigned Integer (256 bit)

Keyword: num256

An unsigned integer (256 bit) is a type to store non-negative integers.

Values

Integer values between 0 and (2257-1).

Note

Integer literals are always interpreted as num. In order to assign a literal to a num256 use as_num256(_literal).

Operators

Comparisons

Comparisons return a boolean value.

Operator Description
num256_lt(x, y) Less than
num256_le(x, y) Less or equal
x == y Equals
x != y Does not equal
num256_ge(x, y) Greater or equal
num256_gt(x, y) Greater than

x and y must be of the type num256.

Arithmetic Operators
Operator Description
num256_add(x, y) Addition
num256_sub(x, y) Subtraction
num256_addmod(x, y) Modular addition
num256_mul(x, y) Multiplication
num256_mulmod(x, y) Modular multiplication
num256_div(x, y) Divison
num256_exp(x, y) Exponentiation
num256_mod(x, y) Modulo
min(x, y) Minimum
max(x, y) Maximum

x and y must be of the type num256.

Bitwise Operators
Operator Description
bitwise_and(x, y) AND
bitwise_not(x, y) NOT
bitwise_or(x, y) OR
bitwise_xor(x, y) XOR
shift(x, _shift) Bitwise Shift

x and y must be of the type num256. _shift must be of the type num.

Note

Positive _shift equals a left shift; negative _shift equals a right shift. Values shifted above/below the most/least significant bit get discarded.

Decimals

Keyword: decimal

A decimal is a type to store a decimal fixed point value.

Values

A value with a precision of 10 decimal places between -2127 and (2127 - 1).

Operators

Comparisons

Comparisons return a boolean value.

Operator Description
x < y Less than
x <= y Less or equal
x == y Equals
x != y Does not equal
x >= y Greater or equal
x > y Greater than

x and y must be of the type decimal.

Arithmetic Operators
Operator Description
x + y Addition
x - y Subtraction
-x Unary minus/Negation
x * y Multiplication
x / y Divison
x % y Modulo
min(x, y) Minimum
max(x, y) Maximum
floor(x) Largest integer <= x. Returns num.

x and y must be of the type decimal.

Address

Keyword: address

The address type holds an Ethereum address.

Values

An address type can hold an Ethereum address which equates to 20 bytes/160 bits. Returns in hexadecimal notation with a leading 0x.

Members
Member Description
balance Query balance of an address. Returns wei_value.
codesize Query the code size of an address. Returns num.

Syntax as follows: _address.<member>, where _address is of the type address and <member> is one of the above keywords.

Unit Types

Viper allows the definition of types with discrete units e.g. meters, seconds, wei, ... . These types may only be based on either num or decimal. Viper has multiple unit types built in, which are the following:

Time
Keyword Unit Base type Description
timestamp 1 sec num Represents a point in time
timedelta 1 sec num A number of seconds

Note

Two timedelta can be added together, as can a timedelta and a timestamp, but not two timestamps.

Currency
Keyword Unit Base type Description
wei_value 1 wei num An amount of Ether in wei
currency_value 1 currency num An amount of currency
currency1_value 1 currency1 num An amount of currency1
currency2_value 1 currency2 num An amount of currency2

32-bit-wide Byte Array

Keyword: bytes32 A 32-bit-wide byte array. Otherwise similiar to byte arrays.

Example:

# Declaration
hash: bytes32
# Assignment
self.hash = _hash

Operators

Keyword Description
len(x) Returns the length as an integer
sha3(x) Returns the sha3 hash as bytes32
concat(x, ...) Concatenates multiple inputs
slice(x, start=_start, len=_len) Returns a slice of _len starting at _start

Where x is a byte array and _start as well as _len are integer values.

Fixed-size Byte Arrays

Keyword: bytes

A byte array with a fixed size. The syntax being bytes <= maxLen, where maxLen is an integer which denotes the maximum number of bits.

Strings

Fixed-size byte arrays can hold strings with equal or fewer characters than the maximum length of the byte array.

Example:

exampleString = "Test String"

Operators

Keyword Description
len(x) Returns the length as an integer
sha3(x) Returns the sha3 hash as bytes32
concat(x, ...) Concatenates multiple inputs
slice(x, start=_start, len=_len) Returns a slice of _len starting at _start

Where x is a byte array and _start as well as _len are integer values.

Reference Types

Reference types do not fit into 32 Bytes. Because of this, copying their value is not as feasible as with value types. Therefore only the location, the reference, of the data is passed.

Fixed-size Lists

Fixed-size lists hold a finite number of elements which belong to a specified type.

Syntax

Lists can be declared with _name: _ValueType[_Integer]. Multidimensional lists are also possible.

Example:

#Defining a list
exampleList: num[3]
#Setting values
exampleList = [10, 11, 12]
exampleList[2] = 42
#Returning a value
return exampleList[0]

Structs

Structs are custom defined types that can group several variables.

Syntax

Structs can be accessed via struct.argname. Example:

#Defining a struct
exampleStruct: {
    value1: num,
    value2: decimal,
}
#Accessing a value
exampleStruct.value1 = 1

Mappings

Mappings in Viper can be seen as hash tables which are virtually initialized such that every possible key exists and is mapped to a value whose byte-representation is all zeros: a type’s default value. The similarity ends here, though: The key data is not actually stored in a mapping, only its keccak256 hash used to look up the value. Because of this, mappings do not have a length or a concept of a key or value being “set”.

It is possible to mark mappings public and have Viper create a getter. The _KeyType will become a required parameter for the getter and it will return _ValueType.

Note

Mappings are only allowed as state variables.

Syntax

Mapping types are declared as _ValueType[_KeyType]. Here _KeyType can be almost any type except for mappings, a contract, or a struct. _ValueType can actually be any type, including mappings.

Example:

#Defining a mapping
exampleMapping: decimal[num]
#Accessing a value
exampleMapping[0] = 10.1

Note

Mappings can only be accessed, not iterated over.

Conversion

Following conversions are possible.

Keyword Input Output
as_num128(x) num256, address, bytes32 num
as_num256(x) num , address, bytes32 num256
as_bytes32(x) num, num256, address bytes32
bytes_to_num(x) bytes num
as_wei_value(x) num , decimal; denomination literal wei_value