Skip to content

Commit

Permalink
Adding sections for all types.
Browse files Browse the repository at this point in the history
  • Loading branch information
stoobie committed Dec 31, 2023
1 parent 569e5f8 commit 61cc256
Showing 1 changed file with 150 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,22 +1,153 @@
[id="serialization_of_cairo_types"]
= Serialization of multi-member constructs in Cairo

When you interact with contracts, especially if you are a library or SDK developer that wants to create transactions, you need to understand how Cairo handles multi-member data structures, such as arrays and structs, and even integers larger than 252 bits.

The field element (`felt252`), which contains 252 bits, is the only actual type in the Cairo VM. So all high-level Cairo types that are larger than 252 bits, such as `uint256` or arrays, are ultimately represented by a list of felts.

To interact with a contract, you need to know how the types in the contract’s function signature are serialized, so you can correctly formulate the calldata in the transaction. This calldata is usually encapsulated by an SDK, such as `starknet.js`. So if you use an SDK, you don’t necessarily need to know that `u256`, for example, is represented by two felts. You simply specify a `uint256`, and the SDK properly encodes it.

== Affected data types

The following data types are serialized:

* addresses: `ContractAddress`, `EthAddress`, `StorageAddress`, `ClassHash`
* all integer types
* array
* enum
* struct
* string, represented by the `ByteArray` type
[id="serialization_of_types_in_Cairo"]
= Serialization of types in Cairo

When you interact with contracts, especially if you are a library or SDK developer that wants to create transactions, you need to understand how Cairo handles types that are larger than 252 bits so you can correctly formulate the calldata in a transaction.

The field element (`felt252`), which contains 252 bits, is the only actual type in the Cairo VM. So all high-level Cairo types that are larger than 252 bits, such as `u256` or arrays, are ultimately represented by a list of felts.

In order to interact with a contract, you need to know how the felts in these lists are serialized in the Cairo VM so you can correctly formulate the calldata in the transaction. SDKs, such as starknet.js, serialize these values for you, so you can simply specify any type and the SDK properly formulates the calldata. For example, you don’t need to know that a `u256` value is represented by two `felt252` values. You can simply specify a `u256` value in your code, and the SDK takes care of the serialization and encoding.


[#data_types_with_trivial_serialization]
== Data types with trivial serialization

The following types are smaller than 252 bits. For these types, each value is represented by a single-member list, whose only member is a `felt252` value.

* Signed integers smaller than 252 bits: `i8`, `i16`, `i32`, `i64`, and `i128`.
+
A negative value, stem:[-x], is serialized as stem:[P-x], where:
+
[stem]
++++
P = 2^{251} + 17*2^{192} + 1
++++
+
For example, `-5` is serialized as stem:[P-5]. For more information on the value of stem:[P], see xref:architecture_and_concepts:Cryptography/p-value.adoc[The STARK field].

* `ContractAddress`
* `EthAddress`
* `StorageAddress`
* `ClassHash`
* Unsigned integers smaller than 252 bits: `u8`, `u16`, `u32`, `u64`, `u128`, and `usize`
* `byte31`
* `felt252`

[#data_types_that_require_serialization]
== Data types that require serialization

The following data types require serialization:

* Unsigned integer types 252 bits or larger: `u252` and `u512`.
* `array`
* `enum`
* `struct`
* `ByteArray`, which represents strings


[#serialization_of_unsigned_integers]
== Serialization of unsigned integers

For `u256` and `u512` values, serialization is necessary.

[#serialization_in_u256_values]
=== Serialization in `u256` values

A `u256` value in Cairo is serialized across two `felt252` values, each containing 128 meaningful bits. The most significant bit is in the first 128-bit `felt252` value. For example:

* A `u256` variable whose decimal value is `2` is serialized as `(0,2)`~decimal~ using two `felt252` values, each with 128 meaningful bits, as follows:
+
[cols="2"]
|===
|`felt252`~1~ = `0`~binary~ = `0`~decimal~|`felt252`~2~ = `10`~binary~ = `2~decimal~`

a|//`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots0}_{\text{128 bits}}
++++
a| //`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots10}_{\text{128 bits}}
++++
|===

* A `u256` variable whose decimal value is `2^128^` is serialized as `(1,0)`~decimal~ using two `felt252` values, each with 128 meaningful bits, as follows:
+
[cols="2"]
|===
|`felt252`~1~ = `1`~binary~ = `1`~decimal~|`felt252`~2~ = `0`

a|//`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots1}_{\text{128 bits}}
++++
a| //`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots0}_{\text{128 bits}}
++++
|===

* A `u256` variable whose decimal value is `2^129^+2^129^+20`, is serialized as `(3,20)`~decimal~ using two `felt252` values, each with 128 meaningful bits, as follows:
+
[cols="2"]
|===
|`felt252`~1~ = `11`~binary~ = `3`~decimal~|`felt252`~2~ = `10100`~binary~ = `20`~decimal~

a|//`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots11}_{\text{128 bits}}
++++
a| //`0b000...000`
[stem]
++++
\underbrace{0\cdots0}_{\text{128 bits}}
\underbrace{0\cdots10100}_{\text{128 bits}}
++++
|===

[#serialization_in_u512_values]
=== Serialization of `u512` values

A `u512` value in Cairo is serialized similarly to a `u256` value, but it requires four `felt252` values, each with 128 bits. The most significant bit is in the first 128-bit value.

[#serialization_of_arrays]
== Serialization of arrays

An array is serialized as follows when encoded as calldata:

`<number_of_array_members>, <serialized_member_0>,..., <serialized_member_n>`

For example, consider the following array of `u256` values:

`Array<u256>[10,20,2^128^]`

Each `u256` value in the array is represented by two `felt252` values. So the calldata for the array above is serialized as follows:

// `3,0,10,0,20,1,0`

[stem]
++++
\underbrace{3}_{\text{number_of_array_members}} ,
\underbrace{0,10}_{\text{serialized_member_0}}
\underbrace{0,20}_{\text{serialized_member_1}}
\underbrace{1,0}_{\text{serialized_member_2}}
++++



'''
'''
'''
'''


== How these data types are serialized in Cairo
Expand Down

0 comments on commit 61cc256

Please sign in to comment.