Primitive data types
Tezos contracts support these primitive data types. The high-level languages may implement these data types slightly differently, but they all behave the same way in the compiled Michelson code:
- Numeric data types:
intandnat - Token amounts:
mutezandtez - Strings
- Bytes
- Booleans
- Timestamps
- Addresses
Numeric data types: int and nat
Integers (int) are whole numbers that can be positive or negative.
Naturals (nat) are whole numbers that can only be positive or zero.
Tezos differentiates these two types to prevent problems such as performing operations that may not always return a positive number.
On Tezos, there is no hard limit to how large nat and int values can be.
The only limits are those associated with the storage and gas costs.
This means you never need to worry about overflow issues.
You can perform these ordinary arithmetic operations on int and nat or a mix of the two:
- Getting the opposite of a number (
NEG) - Adding (
ADD), subtracting(SUB) or multiplying (MUL) two values - Performing an integer division between two values (
EDIV), which returns a pair with the result and the remainder
The type of the output may not be the same type as the inputs.
In general, the output type depends on whether the result can be negative.
For example, subtraction always returns an int, but addition returns a nat if both inputs are nat and an int if either input was an int.
You can perform bitwise logical operations: the usual OR, AND, XOR, NOT.
You can also perform bitwise left and right shifts (LSL and LSR), with a parameter that indicates by how many bits you shift the value.
For information about comparing values, see Comparing values.
Finally, you can convert an int to a nat or vice versa:
- To convert an
intto anat, use the absolute value function (ABS). - To convert a
natinto anint, use theINTfunction.
You can also convert an int to an option on a nat (ISNAT).
Why are decimal numbers not supported?
Tezos does not support floating point or decimal numbers. These kinds of numbers and their associated rounding errors cause many problems.
For example, Tezos protocol upgrades could cause inconsistencies with floating point numbers. If this happens, different nodes may get different results for the same transactions, which would lead to inconsistencies on the blockchain. Also, code that uses floating point numbers is much harder to run formal verification on.
Token amounts: mutez and tez
The mutez type (or micro tez) stores amounts of tokens from the native cryptocurrency of Tezos, the tez.
One mutez is equal to one millionth of a tez.
Some languages also support the tez type, but the internal type is always the mutez, so you can see a value of type tez as a shortcut for the corresponding value in mutez.
mutez values, like nat values, are whole non-negative numbers.
However, contrary to nat, they can't hold arbitrarily large values.
More precisely, mutez are stored as signed 64 bit values.
This means their value can only be between and , which is approximately mutez, and corresponds to 9 trillion tez.
Although it is rare to work with mutez amounts this large, there is still a risk of overflow. For example, if code performs intermediate computations such as squaring a number, it might reach the storage limit.
You can do these arithmetic operations on mutez:
- Adding two mutez values (
ADD) - Subtracting two
mutezvalues (SUB_MUTEZ), which returns anoptionbecause the result could be negative - Multiplying a
mutezvalue with anat(MUL), which returns a result inmutez - Performing an integer division (
EDIV)
For information about comparing values, see Comparing values.
Strings
On Tezos, a string is a sequence of standard non-extended ASCII characters.
This means there are only 128 possible values for each character, which excludes any accented letters.
This limited list of characters prevents compatibility issues with unicode characters.
If you need to store unicode text, store it as bytes.
Like int and nat, there is no limit on the size of a string other than the indirect limits caused by the associated costs of storage.
You can do these operations on strings:
- Concatenate two
stringtypes (CONCAT) - Get the size of a
string(SIZE), which returns anat - Extract a substring of a
string(SLICE) - Compare two
stringtypes based on their lexicographical order; see Comparing values
Bytes
You can store any piece of information as a sequence of bytes.
This type has no limits on its size other than the indirect limits caused by the associated costs.
bytes have the same operations as strings:
- Concatenate two
bytestypes (CONCAT) - Get the size of a
bytes(SIZE), which returns anat - Extract a substring of a
bytes(SLICE) - Compare two
bytestypes based on their lexicographical order; see Comparing values
To save space, you can store most other data types in a bytes type.
To convert
Furthermore, bytes can be used to store values of most other valid types in an optimized binary representation.
To convert values to and from bytes, use these functions:
- To convert any value of a supported type to
bytes, usePACK - To convert
bytesto the encoded type, useUNPACK
Serialization is also useful in applying cryptographic functions to data, as in these examples:
- Computing a cryptographic hash of some data using one of several hash functions, such as
Blake2b-256 - Checking that a sequence of
byteshas been signed with a given key - Applying elliptic-curve cryptographic primitives (
BLS12-381)
For more information about serialization, see Serialization.
bytes are also used in Sapling.
Booleans
Boolean types on Tezos (bool) work the same way as in most programming languages.
- A boolean value can be
TrueorFalse - Comparison operators produce boolean values
- Boolean values can be used in conditional statements or
whileloops - The usual logic operators are supported:
AND,OR,XOR,NOT
Timestamps
Dates are very important in smart contracts, such as verifying that a call is made before or after a given deadline.
The timestamp type represents the number of seconds since January 1st, 1970, also known as UNIX time.
Internally, timestamps are stored as an int, so like int types, timestamps can have arbitrarily large positive or negative numbers, representing times long before or after January 1st, 1970.
The special instruction NOW represents the timestamp of the current block.
The following operations are supported on timestamps:
- Adding a number of seconds to a
timestamp(ADD) - Subtracting a number of seconds from a
timestamp(SUB) - Computing the difference in seconds between two
timestampvalues (SUB) - Comparing two
timestamps(COMPARE); see Comparing values
Addresses
On Tezos, each account is uniquely identified by its address, whether it is a user account (implicit account) or a contract (originated account).
Internally, addresses take the form of a string type.
For implicit accounts, the string starts with "tz1", "tz2", "tz3" or "tz4".
For originated accounts, the string starts with "KT1".
| Type of Account | Example |
|---|---|
| Implicit Account | tz1YWK1gDPQx9N1Jh4JnmVre7xN6xhGGM4uC |
| Originated Account | KT1S5hgipNSTFehZo7v81gq6fcLChbRwptqy |
The next part of the string is a Base58 encoded hash, followed by a 4-byte checksum.
Data type implementations
See these links for technical information about how different languages handle different data types:
- Michelson: int and nat, booleans, strings, timestamps, mutez.
- Archetype: Types basics, Types, Arithmetic operators
- SmartPy: Integers and mutez, Booleans, Strings and Bytes, Timestamps
- LIGO: numbers and tez, strings & bytes, booleans