> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-ton-storage.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Automatic serialization

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

All data in TON (messages, storage, etc.) is represented with **cells**.
Tolk type system is designed to express cell contents,
enabling auto-serialization via `fromCell` and `toCell`:

```tolk theme={null}
struct Point {
    x: int8
    y: int8
}

fun demo() {
    var value: Point = { x: 10, y: 20 };

    // makes a cell containing "0A14" (hex)
    var c = value.toCell();
    // back to { x: 10, y: 20 }
    var p = Point.fromCell(c);
}
```

## How each type is serialized

To dig into binary data, follow [Overall: serialization](/languages/tolk/types/overall-serialization).

A `struct` can provide its "serialization prefix".
32-bit ones are typically called **opcodes** and used for messages (incoming and outgoing):

```tolk theme={null}
struct (0x7362d09c) TransferNotification {
    queryId: uint64
    // ...
}
```

But prefixes are not restricted to be 32-bit: `0x000F` is a 16-bit prefix, `0b010` is 3-bit (binary).

[Serialization of structures](/languages/tolk/types/overall-serialization#structures) is also on the "overall" page.

## Controlling cell references. Typed cells

Fields of a struct are serialized one by one.
The compiler does not reorder fields, create implicit references, etc.
When data should be stored in a ref, it's done explicitly.
A developer controls exactly when each ref is loaded.

**There are two types of references — typed and untyped**:

* `cell` — untyped ref — just "some cell", "arbitrary content"
* `Cell<T>` — typed ref — a cell, which internal structure is known

```tolk theme={null}
struct NftStorage {
    ownerAddress: address
    nextItemIndex: uint64
    content: cell                  // untyped ref
    royalty: Cell<RoyaltyParams>   // typed ref
}

struct RoyaltyParams {
    numerator: uint16
    // ...
}
```

A call `NftCollectionStorage.fromCell()` is processed as follows:

1. read `address`
2. read `uint64`
3. read two refs without unpacking them: only their pointers are loaded

## `Cell<T>` must be loaded to get `T`

Let's look at the `royalty` above:

```tolk theme={null}
struct NftStorage {
    // ...
    royalty: Cell<RoyaltyParams>
}
```

Since it is a cell, `storage.royalty.xxx` is NOT valid:

```ansi theme={null}
// error: `Cell<RoyaltyParams>` has no field `numerator`
storage.royalty.numerator;
                ^^^^^^^^^
```

To access `numerator` and other fields, manually **load that ref**:

```tolk theme={null}
val royalty = storage.royalty.load();   // Cell<T> to T
// or, alternatively
val royalty = RoyaltyParams.fromCell(storage.royalty);

// ok
royalty.numerator;
```

And conversely, when composing an instance, **assign a cell, not an object**:

```tolk theme={null}
val storage: NftStorage = {
    // error
    royalty: RoyaltyParams{ ... }
    // correct
    royalty: RoyaltyParams{ ... }.toCell()
}
```

The following snippet summarizes the behavior:

```tolk theme={null}
pCell = point.toCell();  // `Point` to `Cell<Point>`
point = pCell.load();    // `Cell<Point>` to `Point`
```

Note that `Cell<address>` or even `Cell<int32 | int64>` is also okay, `T` is not restricted to structures.

## Custom serializers for custom types

Using type aliases, it is possible to override serialization behavior when it cannot be expressed using existing types:

```tolk theme={null}
type MyString = slice

fun MyString.packToBuilder(self, mutate b: builder) {
    // custom logic
}

fun MyString.unpackFromSlice(mutate s: slice) {
    // custom logic
}
```

<Aside type="caution">
  This works only with aliases! Not with structures, enums, etc.
</Aside>

See [Serialization of type aliases](/languages/tolk/types/overall-serialization#type-aliases) for examples.

## What if input is corrupted

How will `Point.fromCell(c)` work if `c` is less than 16 bits?

```tolk theme={null}
struct Point {
    x: int8
    y: int8
}

fun demo() {
    Point.fromCell(createEmptyCell());
}
```

The answer: **an exception is thrown**. In multiple cases, actually:

* input is too small — not enough bits or refs, unless `lazy fromCell`
* input is too big — contains extra data (can be turned off)
* `address` has incorrect format
* `enum` has an invalid value
* a struct prefix does not match
* etc.

An exception code is typically 9 ("cell underflow") or 5 ("out of range").

Some aspects of this behavior can be controlled. For example, if "input is too big" is okay, use an option:

```tolk theme={null}
MyMsg.fromSlice(s, {
    assertEndAfterReading: false
})
```

## UnpackOptions and PackOptions

Behavior of `fromCell` and `toCell` can be controlled by options:

```tolk theme={null}
MyMsg.fromCell(c, {
    // options object
})
```

For deserialization (`fromCell` and similar), there are two options:

```tolk theme={null}
MyMsg.fromCell(c, {
    // call `assertEnd` to ensure no remaining data left;
    // (in other words, the struct describes all data)
    assertEndAfterReading: true,        // default: true

    // this errCode is thrown if opcode doesn't match,
    // e.g. for `struct (0x01) A` given input "88...",
    // or for a union type, none of the prefixes match
    throwIfOpcodeDoesNotMatch: 63,      // default: 63
})
```

For serialization (`toCell` and similar), there is one option:

```tolk theme={null}
obj.toCell({
    // for `bits128` and similar (a slice under the hood),
    // insert the checks (bits == 128 and refs == 0);
    // turn off to save gas if you guarantee input is valid;
    // `intN` are always validated, it's only for `bitsN`
    skipBitsNValidation: false,         // default: false
});
```

## Not only `fromCell`, but `fromSlice` and more

This API is also designed to integrate with low-level features.
Each of these functions can be controlled by `UnpackOptions`.

1. `T.fromCell(c)` — parse a cell: "c.beginParse() + fromSlice":

```tolk theme={null}
var storage = NftStorage.fromCell(contract.getData());
```

2. `T.fromSlice(s)` — parse a slice (a slice is **not mutated**):

```tolk theme={null}
var msg = CounterIncrement.fromSlice(s);
```

3. `slice.loadAny<T>()` — **mutate** the slice:

```tolk theme={null}
var storage = s.loadAny<NftStorage>();
var nextNum = s.loadAny<int32>();    // also ok
```

Note: `options.assertEndAfterReading` is ignored by this function because it is intended to read data from the middle.

4. `slice.skipAny<T>()` — like `skipBits()` and similar:

```tolk theme={null}
s.skipAny<Point>();    // skips 16 bits
```

**Same for serialization.**
Each of these functions can be controlled by `PackOptions`.

1. `T.toCell()` — works as "beginCell() + serialize + endCell()":

```tolk theme={null}
contract.setData(storage.toCell());
```

2. `builder.storeAny<T>(v)` — like `storeUint()` and similar:

```tolk theme={null}
var b = beginCell()
       .storeUint(32)
       .storeAny(msgBody)  // T=MyMsg here
       .endCell();
```

## Special type: RemainingBitsAndRefs

It's a built-in type to get "all the rest" slice tail on reading. Example:

```tolk theme={null}
struct JettonMessage {
     // ... some fields
     forwardPayload: RemainingBitsAndRefs
}
```

After `JettonMessage.fromCell`, forwardPayload contains **everything left after reading the fields above**.
Essentially, it's an alias to a slice which is handled specially by the compiler:

```tolk theme={null}
type RemainingBitsAndRefs = slice
```

## What if data exceeds 1023 bits

Tolk compiler warns if a serializable struct potentially exceeds 1023 bits.
A developer should **take one of the following actions**:

1. to suppress the error; it means "okay, I understand"
2. or reorganize a struct by splitting into multiple cells

Why "potentially exceeds"? Because for many types, their size can vary. For example, `int8?` is either one or nine bits, `coins` is 4..124 bits, etc.

So, given a struct:

```tolk theme={null}
struct MoneyInfo {
    fixed: bits800
    wallet1: coins
    wallet2: coins
}
```

And trying to serialize it, the compiler prints an error:

```ansi wrap theme={null}
struct `MoneyInfo` can exceed 1023 bits in serialization (estimated size: 808..1048 bits)
... (and some instructions)
```

Actually, two choices are available:

1. if `coins` values are expected to be relatively small, and this struct will 100% fit in reality; then, suppress the error using an annotation:

```tolk theme={null}
@overflow1023_policy("suppress")
struct MoneyInfo {
    ...
}
```

2. or `coins` are expected to be billions of billions, so data really can exceed; in this case, extract some fields into a separate cell; for example, store 800 bits as a ref or extract the other two fields:

```tolk theme={null}
// extract the first field
struct MoneyInfo {
    fixed: Cell<bits800>
    wallet1: coins
    wallet2: coins
}

// or extract the other two fields
struct WalletsBalances {
    wallet1: coins
    wallet2: coins
}
struct MoneyInfo {
    fixed: bits800
    balances: Cell<WalletsBalances>
}
```

A general guideline: leave frequently used fields directly and place less-frequent fields into a nested ref.
Overall, the compiler reports potential overflow, and it is the developer's responsibility to resolve it.

## What if serialization is unavailable

A common mistake: using `int` (it cannot be serialized; use `int32`, `uint64`, etc.; see [numeric types](/languages/tolk/types/numbers)).

```tolk theme={null}
struct Storage {
    owner: address
    lastTime: int     // mistake is here
}

fun errDemo() {
    Storage.fromSlice("");
}
```

The compiler reports a reasonable error:

```ansi theme={null}
auto-serialization via fromSlice() is not available for type `Storage`
because field `Storage.lastTime` of type `int` can't be serialized
because type `int` is not serializable, it doesn't define binary width
hint: replace `int` with `int32` / `uint64` / `coins` / etc.
```

## Integration with message sending

Auto-serialization is integrated natively with message sending to other contracts:

```tolk theme={null}
val reply = createMessage({
    // ...
    body: RequestedInfo {     // auto-serialized
        // ...
    }
});
reply.send(SEND_MODE_REGULAR);
```

See: [sending messages](/languages/tolk/features/message-sending).

## Not "fromCell" but "lazy fromCell"

Tolk provides a special keyword `lazy` combined with auto-deserialization.
The compiler loads only the fields requested, rather than the entire struct.

```tolk theme={null}
struct Storage {
    isSignatureAllowed: bool
    seqno: uint32
    subwalletId: uint32
    publicKey: uint256
    extensions: cell?
}

get fun publicKey() {
    val st = lazy Storage.fromCell(contract.getData());
    // <-- here "skip 65 bits, preload uint256" is inserted
    return st.publicKey
}
```

See: [lazy loading](/languages/tolk/features/lazy-loading).
