Skip to main content

Variables

Defining variables is a fundamental part of any programming language. In this section, we will look at the different types of variables you can define in EOS Smart Contracts.

C++ supports a wide range of data types. EOS++ extends the set of types with EOS-specific types.

Defining variables

Variables are defined in the same way as in C++.

function main() {
// <type> <name> = <value>;
int a = 5;
}

Basic types

These are the basic types that come built-in with C++. You have likely used some form of these types before in other programming languages you have used.

Unless otherwise specified, the types below are imported from the <eosio/eosio.hpp> header.

#include <eosio/eosio.hpp>

Integer types

Integer types are used to represent whole numbers. They can be either signed (positive or negative) or unsigned (positive only).

Integer TypesDescription
boolBoolean (true/false)
int8_tSigned 8-bit integer
int16_tSigned 16-bit integer
int32_tSigned 32-bit integer
int64_tSigned 64-bit integer
int128_tSigned 128-bit integer
uint8_tUnsigned 8-bit integer
uint16_tUnsigned 16-bit integer
uint32_tUnsigned 32-bit integer
uint64_tUnsigned 64-bit integer
uint128_tUnsigned 128-bit integer

Required Header

#include <eosio/varint.hpp>
Integer TypesDescription
signed_intVariable-length signed 32-bit integer
unsigned_intVariable-length unsigned 32-bit integer

Floating-Point types

Floating-point types are used to represent decimal numbers.

Warning

Floating-point types are not precise. They are not suitable for storing currency values, and are often problematic for storing other types of data as well. Use them with caution, especially when dealing with blockchains.

Float TypesDescription
float32-bit floating-point number
double64-bit floating-point number

Byte types

Byte types are used to represent raw byte sequences, such as binary data / strings.

Blob TypesDescription
bytesRaw byte sequence
stringString

Time types

Time types are used to represent time, specifically relating to blocks.

Time TypesDescription
time_pointPoint in time in microseconds
time_point_secPoint in time in seconds
block_timestampBlock timestamp

Helpful functions

FunctionDescription
time_point eosio::current_time_point()Get the current time point
const microseconds& time_point.time_since_epoch()Get the microseconds since the epoch
uint32_t time_point.sec_since_epoch()Get the seconds since the epoch
block_timestamp eosio::current_block_time()Get the current block time

Hash types

Hash types are used to represent cryptographic hashes such as SHA-256.

Checksum TypesDescription
checksum160160-bit checksum
checksum256256-bit checksum
checksum512512-bit checksum

Custom types

These are the custom types that come built-in with EOS++. You will likely use some of these types often in your EOS Smart Contracts.

Name type

The name type is used to represent account names. It is a 64-bit integer, but is displayed as a string.

A variety of system functions require names as parameters.

You have three ways of turning a string into a name:

  • name{"string"}
  • name("string")
  • "string"_n

If you want to get the uint64_t value of a name, you can use the value method.

name a = name("hello");
uint64_t b = a.value;

Key and Signature types

The public_key and signature types are used to represent cryptographic keys and signatures, and are also an EOS++ specific type.

Required Header

#include <eosio/crypto.hpp>

Recovering a key from a signature

function recover(checksum256 hash, signature sig) {
public_key recovered_key = recover_key(hash, sig);
}

Asset types

The asset type is used to represent a quantity of a digital asset. It is a 64-bit integer with a symbol, but is displayed as a string.

It is resistent to overflow and underflow, and has various methods for performing arithmetic operations easily.

Required Header

#include <eosio/asset.hpp>
Asset TypesDescription
symbolAsset symbol
symbol_codeAsset symbol code
assetAsset

Creating an asset

There are two parts to an asset: the quantity, and the symbol. The quantity is a 64-bit integer, and the symbol is a combination of a string and a precision.

// symbol(<symbol (string)>, <precision (1-18)>)
symbol mySymbol = symbol("TKN", 4);

// asset(<quantity (int64_t)>, <symbol>)
asset myAsset = asset(1'0000, mySymbol);

Performing arithmetic operations

You can easily do arithmetic operations on assets.

asset a = asset(1'0000, symbol("TKN", 4));
asset b = asset(2'0000, symbol("TKN", 4));

asset c = a + b; // 3'0000 TKN
asset d = a - b; // -1'0000 TKN
asset e = a * 2; // 2'0000 TKN
asset f = a / 2; // 0'5000 TKN

?? Symbol matching

Doing arithmetic operations on assets with different symbols will throw an error, but only during runtime. Make sure that you are always doing operations on assets with the same symbol.

Asset methods

You can convert an asset to a string using the to_string method.

std::string result = a.to_string(); // "1.0000 TKN"

You can also get the quantity and symbol of an asset using the amount and symbol methods.

int64_t quantity = a.amount; // 1'0000
symbol sym = a.symbol; // symbol("TKN", 4)

When using an asset, you always want to make sure that it is valid (that the amount is within range).

bool valid = a.is_valid();

Symbol methods

You can convert a symbol to a string using the to_string method.

std::string result = mySymbol.to_string(); // "4,TKN"

You can also get the raw uint64_t value of a symbol using the value method.

uint64_t value = mySymbol.value;

When using a symbol by itself, you always want to make sure that it is valid. However, when using asset, it already checks the validity of the symbol within its own is_valid method.

bool valid = mySymbol.is_valid();

Symbol limitations

Symbols have a precision between 1 and 18. This means that you can have a maximum of 18 decimal places.

// Valid
symbol mySymbol = symbol("TKN", 4);

// Invalid
symbol mySymbol = symbol("TKN", 19);

Symbol codes are limited to 7 characters.

// Valid
symbol mySymbol = symbol("TKN", 4);

// Invalid
symbol mySymbol = symbol("ISTOOLONG", 4);

Structs

Structs are used to represent complex data. They are similar to classes, but are simpler and more lightweight. Think of a JSON object.

You can use these in EOS++, but if you are storing them in a table you should use the TABLE keyword which we will discuss in the next section.

struct myStruct {
uint64_t id;
};