From 779bf074a5e50b0af42d7e606b56af63b0bcbf52 Mon Sep 17 00:00:00 2001 From: razlandau Date: Fri, 20 Jun 2025 15:44:47 -0400 Subject: [PATCH] init&finish --- .htaccess | 1 + .../architecture-and-concepts/nav.adoc | 1 - .../serialization-of-cairo-types.adoc | 319 ------------------ 3 files changed, 1 insertion(+), 320 deletions(-) delete mode 100644 components/Starknet/modules/architecture-and-concepts/pages/smart-contracts/serialization-of-cairo-types.adoc diff --git a/.htaccess b/.htaccess index efbf928e8c..1a8d8ef4b0 100644 --- a/.htaccess +++ b/.htaccess @@ -418,3 +418,4 @@ RewriteRule ^architecture-and-concepts/smart-contracts/contract-address/$ https: RewriteRule ^architecture-and-concepts/smart-contracts/class-hash/$ https://book.cairo-lang.org/ch100-01-contracts-classes-and-instances.html [R=301,L] RewriteRule ^architecture-and-concepts/smart-contracts/contract-classes/$ https://book.cairo-lang.org/ch100-01-contracts-classes-and-instances.html [R=301,L] RewriteRule ^architecture-and-concepts/smart-contracts/cairo-and-sierra/$ https://book.cairo-lang.org/appendix-09-sierra.html [R=301,L] +RewriteRule ^architecture-and-concepts/smart-contracts/serialization-of-cairo-types/$ https://book.cairo-lang.org/ch102-04-serialization-of-cairo-types.html [R=301,L] diff --git a/components/Starknet/modules/architecture-and-concepts/nav.adoc b/components/Starknet/modules/architecture-and-concepts/nav.adoc index ea575c239c..394aff9f00 100644 --- a/components/Starknet/modules/architecture-and-concepts/nav.adoc +++ b/components/Starknet/modules/architecture-and-concepts/nav.adoc @@ -6,7 +6,6 @@ ** xref:fees.adoc[Fees] ** xref:messaging.adoc[L1-L2 messaging] ** xref:data-availability.adoc[Data availability] - ** xref:smart-contracts/serialization-of-cairo-types.adoc[Serialization] ** xref:staking.adoc[Staking] ** xref:state.adoc[State] ** xref:economics-of-starknet.adoc[Tokenomics] diff --git a/components/Starknet/modules/architecture-and-concepts/pages/smart-contracts/serialization-of-cairo-types.adoc b/components/Starknet/modules/architecture-and-concepts/pages/smart-contracts/serialization-of-cairo-types.adoc deleted file mode 100644 index 2d806612c6..0000000000 --- a/components/Starknet/modules/architecture-and-concepts/pages/smart-contracts/serialization-of-cairo-types.adoc +++ /dev/null @@ -1,319 +0,0 @@ -[id="serialization_of_types_in_Cairo"] -= Serialization of Cairo types - -== Overview - -The field element (`felt252`), which contains 252 bits, is the only actual type in the Cairo VM, so xref:data_types_using_at_most_252_bits[all data types that fit in 252 bits] are represented by a single felt and xref:data_types_using_more_than_252_bits[all data types that are larger than 252 bits] are represented by a list of felts. Therefore, in order to interact with a contract, you must know how to xref:serialization_of_data_types_using_more_than_252_bits[serialize any arguments that are larger than 252 bits to lists of felts] so you can correctly formulate the calldata in the transaction. - -[IMPORTANT] -==== -For any developers that are not developing a Starknet library or SDK developer, using either one of the existing xref:tools:interacting-with-starknet.adoc#sdks[Starknet SDKs] or the https://foundry-rs.github.io/starknet-foundry/starknet/calldata-transformation.html#using---arguments[`--argument` flag^] of https://foundry-rs.github.io/starknet-foundry/starknet/sncast-overview.html[Starknet Foundry's `sncast`^] is highly recommend to greatly simply the serialization process. From `sncast` v0.43.0, results of `sncast call` are also parsed into readable information, demonstrated in the following example: -[source,terminal] ----- -sncast call \ - --contract-address=0x00e270c8396d333f88556edf143ac751240f050d907e5190525accbe275f2348 \ - --function=get_order \ - --network=sepolia - -response: Order { - position_id: PositionId { value: 1_u32 }, - base_asset_id: AssetId { value: 0x3 }, - base_amount: -10_i64, - quote_asset_id: AssetId { value: 0x2d }, - fee_asset_id: AssetId { value: 0x4d2 }, - fee_amount: 0_u64, - expiration: Timestamp { seconds: 12341432_u64 }, - salt: 0x0, - name: "This is my order" -} ----- -==== - -== Data types using at most 252 bits - -The following Cairo data types are using at most 252 bits: - -* `ContractAddress` -* `EthAddress` -* `StorageAddress` -* `ClassHash` -* Unsigned integers using at most 252 bits: `u8`, `u16`, `u32`, `u64`, `u128`, and `usize` -* `bytes31` -* `felt252` -* Signed integers: `i8`, `i16`, `i32`, `i64`, and `i128` -+ -[NOTE] -==== -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.adoc[]. -==== - -For these types, each value is serialized as a single-member list that contains one `felt252` value. - -== Data types using more than 252 bits - -The following Cairo data types use more than 252 bits and therefore have non-trivial serialization: - -* Unsigned integers larger than 252 bits: `u256` and `u512` -* Arrays and spans -* Enums -* Structs and tuples -* Byte arrays (which represent strings) - -== Serialization of data types using more than 252 bits - -=== Serialization of `u256` - -A `u256` value in Cairo is represented by two `felt252` values, as follows: - -* The first `felt252` value contains the 128 least significant bits, usually referred to as the low part of the original `u256` value. -* The second `felt252` value contains the 128 most significant bits, usually referred to as the high part of the original `u256` value. - -For example: - -* A `u256` variable whose decimal value is `2` is serialized as `[2,0]`. To understand why, examine the binary representation of `2` and split it into two 128-bit parts, as follows: -+ -[stem] -++++ -\underbrace{0\cdots0}_{\text{128 high bits}} | -\underbrace{0\cdots10}_{\text{128 low bits}} -++++ -// -// [#binary_representation_of_u256] -// .Binary representation of `2` in a serialized `u256` -// [%autowidth,cols="2"] -// |=== -// |`felt252`~1~ = `0`~binary~ = `0`~decimal~|`felt252`~2~ = `10`~binary~ = `2~decimal~` -// -// a|//`0b000...000` -// [stem] -// ++++ -// \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 `[0,1]`. To understand why, examine the binary representation of `2^128^` and split it into two 128-bit parts, as follows: -+ -[stem] -++++ -\underbrace{0\cdots01}_{\text{128 high bits}} | -\underbrace{0\cdots0}_{\text{128 low bits}} -++++ - -* A `u256` variable whose decimal value is `2^129^+2^128^+20`, is serialized as `[20,3]`. To understand why, examine the binary representation of the `2^129^+2^128^+20` and split it into two 128-bit parts, as follows: -+ -[stem] -++++ -\underbrace{0\cdots011}_{\text{128 high bits}} | -\underbrace{0\cdots10100}_{\text{128 low bits}} -++++ - -=== Serialization of `u512` - -The `u512` type in Cairo is a struct containing four `felt252` members, each representing a 128-bit limb of the original integer, similar to the `u256` type. - - -=== Serialization of arrays and spans - -Arrays and spans are serialized as follows: - -`<__array/span_length__>, <__serialized_member_0__>,..., <__serialized_member_n__>` - -For example, consider the following array of `u256` values: - -[source,cairo] ----- -let POW_2_128: u256 = 0x100000000000000000000000000000000 -let array: Array = array![10, 20, POW_2_128] ----- - -Each `u256` value in the array is represented by two `felt252` values. So the array above is serialized as follows: - -[stem] -++++ -\underbrace{3}_{\textit{number_of_array_members}} , -\underbrace{10,0}_{\textit{serialized_member_0}} , -\underbrace{20,0}_{\textit{serialized_member_1}} , -\underbrace{0,1}_{\textit{serialized_member_2}} -++++ - -Combining the above, the array is serialized as follows: `[3,10,0,20,0,0,1]` - -[#serialization_of_enums] -=== Serialization of enums - -An enum is serialized as follows: - -`<__index_of_enum_variant__>,<__serialized_variant__>` - -Note that enum variants indices are 0-based, not to confuse with their storage layout, which is 1-based, to distinguish the first variant from an uninitialized storage slot. - -.Enum serialization example 1 - -Consider the following definition of an enum named `Week`: - -[source,cairo] ----- -enum Week { - Sunday: (), // Index=0. The variant type is the unit type (0-tuple). - Monday: u256, // Index=1. The variant type is u256. -} ----- - -Now consider instantiations of the `Week` enum's variants as shown in the table below: - -[#serialization_of_Week] -.Serialization of `Week` variants - -[cols=",,",] -|=== -|Instance |Description |Serialization - -|`Week::Sunday` | Index=`0`. The variant's type is the unit type. | `[0]` -|`Week::Monday(5)` a| Index=`1`. The variant's type is `u256`, hence serialized to `[5,0]`, as shown in xref:#serialization_in_u256_values[] .| `[1,5,0]` -|=== - -.Enum serialization example 2 - -Consider the following definition of an enum named `MessageType`: - -[source,cairo] ----- -enum MessageType { - A, - #[default] - B: u128, - C -} ----- - -Now consider instantiations of the `MessageType` enum's variants as shown in the table below: - -[#serialization_of_MessageType] -.Serialization of `MessageType` variants -[cols=",,",] -|=== -|Instance |Description |Serialization - -|`MessageType::A` | Index=`1`. The variant's type is the unit type. | `[0]` -|`MessageType::B(6)` a| Index=`0`. The variant's type is `u128`. | `[1,6]` -|`MessageType::C` | Index=`2`. The variant's type is the unit type. | `[2]` -|=== - -As you can see about, the `#[default]` attribute does not affect serialization. It only affects the storage layout of `MessageType`, where the default variant -`B` will be stored as `0`. - -=== Serialization of structs and tuples - -Structs and tuples are serialized by serializing their members one at a time. - -A struct's members are serialized in the order in which they appear in its definition. - -For example, consider the following definition of the struct `MyStruct`: - -[source,cairo] ----- -struct MyStruct { - a: u256, - b: felt252, - c: Array -} - ----- - -The serialization is the same for both of the following instantiations of the struct's members: - -[cols="2"] -|=== -a|[source,cairo] ----- -let my_struct = MyStruct { - a: 2, b: 5, c: [1,2,3] -}; ----- - -a|[source,cairo] ----- -let my_struct = MyStruct { - b: 5, c: [1,2,3], a: 2 -}; ----- -|=== - -The serialization of `MyStruct` is determined as shown in the table xref:#serialization_for_a_struct_in_cairo[]. - -[#serialization_for_a_struct_in_cairo] -.Serialization for a struct in Cairo -[cols="3"] -|=== -|Member |Description |Serialization - -| `a: 2` -| For information on serializing `u256` values, see xref:#serialization_in_u256_values[] -| [`2,0`] -| `b: 5` -| One `felt252` value -| `5` -| `c: [1,2,3]` -| An array of three `felt252` values -| [`3,1,2,3`] -|=== - -Combining the above, the struct is serialized as follows: `[2,0,5,3,1,2,3]` - -[#serialization_of_byte_arrays] -=== Serialization of byte arrays - -A string is represented in Cairo as a `ByteArray` type. A byte array is actually a struct with the following members: - -. *`data: Array`* + -Contains 31-byte chunks of the byte array. Each `felt252` value has exactly 31 bytes. If the number of bytes in the byte array is less than 31, then this array is empty. - -. *`pending_word: felt252`* + -The bytes that remain after filling the `data` array with full 31-byte chunks. The pending word consists of at most 30 bytes. - - -. *`pending_word_len: usize`* + -The number of bytes in `pending_word`. - -.Example 1: A string shorter than 31 characters - -Consider the string `hello`, whose ASCII encoding is the 5-byte hex value `0x68656c6c6f`. The resulting byte array is serialized as follows: - -[source,cairo] ----- - - 0, // Number of 31-byte words in the data array. - 0x68656c6c6f, // Pending word - 5 // Length of the pending word, in bytes - ----- - -.Example 2: A string longer than 31 bytes - -Consider the string `Long string, more than 31 characters.`, which is represented by the following hex values: - -* `0x4c6f6e6720737472696e672c206d6f7265207468616e203331206368617261` (31-byte word) -* `0x63746572732e` (6-byte pending word) - -The resulting byte array is serialized as follows: - -[source,cairo] ----- - 1, // Number of 31-byte words in the array construct. - 0x4c6f6e6720737472696e672c206d6f7265207468616e203331206368617261, // 31-byte word. - 0x63746572732e, // Pending word - 6 // Length of the pending word, in bytes -----