Skip to content

Variables

etch is a statically-typed programming language. For good coding practice, you should explicitly declare all variable types.

Declare a variable with the keyword var. Declare numeric values with literals where possible. You can also use an explicit type cast operation. See below for explicit type declaration rules.

Naming

Variable naming follows the same rules as C++.

function main()

    var ABC = 1;
    var abc = 2;
    var _abc = 3;
    // var *abc = 4; // error at '*', expected variable name
    // var 123 = 5; // error at '123', expected variable name
    var a123 = 6;
    var a_123 = 7;

endfunction

Integers

Integers can be signed or unsigned and are currently restricted to the width range 8-64 bits (1 to 8 bytes).

They are declared as signed Int8, Int16, Int32, Int64, and unsigned UInt8, UInt16, UInt32, UInt64, UInt256.

Int32 is the compiler default so you don't need to explicitly declare this type.

Below is a selection of example integer assignations including any errors on operations currently unsupported.

function main()

    // default signed 32 bit integer type
    var int32bit_default = 42;
    // declaring the variable type
    var int32bit : Int32 = -43;
    printLn(toString(int32bit_default));
    printLn(toString(int32bit));

endfunction
function main()

    // assigning various signed integer types explicitly and with label
    var int8a = 0i8; 
    printLn(toString(int8a)); // error: unable to find matching function for 'toString'
    var int8b : Int8 = -0i8; 
    printLn(toString(int8b)); // error: unable to find matching function for 'toString'
    var int16a = 0i16; 
    printLn(toString(int16a)); // error: unable to find matching function for 'toString'
    var int16b : Int16 = -1i16; 
    printLn(toString(int16b)); // error: unable to find matching function for 'toString'

endfunction
function main()

    // Int32 is default but can be explicit also
    var int32a = 0i32;
    printLn(toString(int32a));
    var int32b : Int32 = -1i32;
    printLn(toString(int32b));
    var int64a = 0i64;
    printLn(toString(int64a));
    var int64b : Int64 = -1i64; 
    printLn(toString(int64b));

endfunction
function main()

    // assigning various unsigned integer types
    var uint8a = 45u8; 
    printLn(toString(uint8a)); // error: unable to find matching function for 'toString'
    var uint8b : UInt8 = 1u8; 
    printLn(toString(uint8b)); // error: unable to find matching function for 'toString'
    var uint16a = 0u16; 
    printLn(toString(uint16a)); // error: unable to find matching function for 'toString'
    var uint16b : UInt16 = 1u16; 
    printLn(toString(uint16b)); // error: unable to find matching function for 'toString'

endfunction
function main()

    // assigning various unsigned integer types
    var uint32a = 0u32;
    printLn(toString(uint32a));
    var uint32b : UInt32 = 1u32; 
    printLn(toString(uint32b));
    var uint64a = 0u64;
    printLn(toString(uint64a));
    var uint64b : UInt64 = 1u64;
    printLn(toString(uint64b)); 

endfunction

In the current version, UInt256 is built from a UInt64 literal, like this:

function main()

   var uint256 = UInt256(100u64); 
   printLn(toString(uint256));

endfunction

Floats

Signed and unsigned decimal numbers are available as floating point types in 32 and 64 bit representation (4 and 8 bytes).

Unspecified floats default to Float64.

A Float declared with f is Float32.

Float types are declared as Float32, Float64.

function main()

    // default 64 bit float declaration
    var float64bit_default = 64.0;
    // 64 bit type declaration
    var float64bit : Float64 = 64.0;
    printLn(toString(float64bit_default));
    printLn(toString(float64bit));

    // var float32bit : Float32 = 32.0; // error: incompatible types
    // declare 32 bit float with `f`
    var float32bit = 32.0f;
    printLn(toString(float32bit));

endfunction

Fixed Points

Fixed point variables are available as Fixed32 and Fixed64 types.

You must declare FixedPoint variables with the postfix literals fp32 and fp64.

function main()

    var fixed32bit : Fixed32 = 32.1fp32; 
    var fixed64bit : Fixed64 = 64.1fp64; 

    printLn(toString(fixed32bit));
    printLn(toString(fixed64bit));

endfunction

For brevity, you do not need the full declaration.

function main()

    var fixed32bit = 2.0fp32;
    var fixed64bit = 3.0fp64;

    printLn(toString(fixed32bit));
    printLn(toString(fixed64bit));

endfunction

Boolean

Declare and initialise Bool types as follows:

function main()

    var myFBool : Bool = false;
    var myTBool : Bool = true;

    printLn(toString(myFBool)); 
    printLn(toString(myTBool));     

endfunction

Strings

Declare and initialise strings as follows:

function main()

    var myString : String = "hello";
    var myInferredString = "hello again";
    var x: String = null;

    printLn(myString);
    printLn(myInferredString);
    printLn(myInferredString + " " + myString);
    printLn(x); 

endfunction

Find out more about etch Strings here.

Arrays

You must explicitly declare array element types and array size.

Array<Type>(size) declares an array with elements of type Type and size size.

function main()

    var myArray = Array<Int32>(5);
    myArray[0] = 40;
    myArray[1] = 41;
    myArray[2] = 42;
    myArray[3] = 43;
    myArray[4] = 44;

    printLn(toString(myArray[3]));

    for (i in 0:4)
        printLn(toString(myArray[i]));
    endfor

    printLn(myArray);

endfunction

Find out more about etch Arrays here.

Buffer

Create a Buffer byte array type like this:

var myBuffer = Buffer(8);

Maps

Declare the dictionary Map type with Map<KeyType, ValueType>().

function main()

    var myMap = Map<String, Int32>();
    myMap["balance1"] = 1000; 
    myMap["balance2"] = 2000; 
    myMap["balance3"] = 3000; 

    printLn(toString(myMap["balance1"]));
    printLn(toString(myMap["balance2"]));
    printLn(toString(myMap["balance3"]));

endfunction

Note

Coming soon: common Map operations.

StructuredData types

A StructuredData type is another map type containing key/value pairs.

The main difference with Map is that a StructuredData type will always be able to generate yaml, json, or similar.

function main()

    var data = StructuredData();

    data.set("key1", 200i32);
    data.set("key2", 500u64);
    data.set("key3", "hello world");

    printLn(toString(data.getInt32("key1")));
    printLn(toString(data.getUInt64("key2")));
    printLn(data.getString("key3"));

endfunction

States

A State is a data structure used by etch smart contracts for storing and querying data on the Fetch.AI ledger shards.

Unique identifiers for the ledger data are created at State construction time. These are unique to the smart contract alone.

Declare and initialise a State type with State<ValueType> where values set with set() are mapped to the unique ledger identifieraccount:

var myState = State<Int32>("account");

Getters and setters are available for State types.

function main()

    var myState = State<Int32>("account");
    myState.set(10);
    printLn("My state var value = " + toString(myState.get()));

endfunction

Find out more about etch States here.

ShardedState

A ShardedState is also used for reading and writing data to the Fetch.AI ledger. However, it is much more efficient and powerful.

ShardedState uses State types behind the scenes but, for etch programmer purposes, a ShardedState operates like a Map with keys and values.

In the following code, we create a ShardedState, set() a key/value pair on it, and finally we print the value using get() on a key with a default value.

function main()

    var myShardedState = ShardedState<Int32>("account1");
    myShardedState.set("salary", 45000i32);
    printLn(toString(myShardedState.get("salary", 0i32)));

endfunction

Find out more about etch ShardedStates here.

Addresses

The cryptographic Address type is currently represented by a 64 byte binary canonical ECDSA public key which is then base 58 encoded.

Declare and initialise an Address like this:

function main()

  var account = Address("2ifr5dSFRAnXexBMC3HYEVp3JHSuz7KBPXWDRBV4xdFrqGy6R9");

endfunction

Find out more about etch Addresses here.

Mathematical, ML, and AI

etch provides powerful mathematical, machine learning, and AI specific data types and functions.

For more details on the mathematical computation functions above, please check the section on maths libraries and functions.

For more details on the machine learning implementations, please check the section on machine learning and artificial intelligence.

Type casting

If you need a specific non-default numerical type, you can make an explicit cast of the default Int32 and Float64 types.

Use to<Type>Name to type cast.

There is no implicit type casting in etch.

function main()

    // signed 32 bit integer type
    var int32bit = 42;
    // cast to Int8
    var int8Variable = toInt8(int32bit);
    // cast to Int16
    var int16Variable = toInt16(int32bit);
    // cast to Int64
    var int64Variable = toInt64(int32bit);
    // cast to UInt8
    var uint8Variable = toUInt8(int32bit); 
    // cast to UInt16
    var uint16Variable = toUInt16(int32bit);
    // cast to UInt32
    var uint32Variable = toUInt32(int32bit);
    // cast to UInt64
    var uint64Variable = toUInt64(int32bit);


    // float casting
    var float64bit = 42.0;
    // cast to Int8
    var intFVariable = toInt32(float64bit);
    // cast to Float32
    var float32Variable = toFloat32(float64bit);
    // cast to Float64
    var float64variable = toFloat64(int32bit);

    // cast to string
    var stringVariable = toString(int32bit);

endfunction

Data size

In the table below, we detail the memory size of each data type.

Type Memory size
Int8 1 byte
Int16 2 bytes
Int32 4 bytes
Int64 8 bytes
UInt8 1 byte
UInt16 2 bytes
UInt32 4 bytes
UInt64 8 bytes
UInt256 32 bytes
Float32 4 bytes
Float64 8 bytes
Bool 1 byte
String 8 bytes + length character size (changing with UTF-8)
Array 8 bytes + length x element size
Map 8 bytes + n x (key + value) storage
Address 32 bytes

Currently, there is a 2 unit charge per 1 byte of ledger storage.

Scope

etch has no global variables.

Null

Non-primitives can be set to null.

function main()

    //  var myInt = null; // error: unable to infer type
    var str : String = null;
    var myArray : Array<Int32> = null;
    var myMap : Map<Int32, Int32> = null;
    var myState : State<Int32> = null;
    var myAddress : Address = null;

    var myString : String = null;
    printLn(myString); // (nullptr)

endfunction

Default values

Certain types not explicitly initialised receive a default value.

Type Default value
Int8 tbc
Int16 tbc
Int32 0
Int64 0
UInt8 tbc
UInt16 tbc
UInt32 0
UInt64 0
UInt256 tbc
Float32 0.000000
Float64 0.000000
Bool false
String no default