> ## 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.

# Cells, slices, builders

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>
    </>;
};

In TON, all data is stored in **cells**.
Cells opened for reading are called **slices**.
Cells being constructed are called **builders**.
Having a builder, only writing is possible. Having a slice, only reading is possible.

Tolk provides low-level capabilities to construct and parse cells manually, as well as automatic packing structures to/from cells.

## Cells

A cell is the fundamental data structure in TON. It's a container that holds **up to 1023 bits** of data and **up to 4 references** to other cells.

Everything in TON (contracts, messages, storage) is represented using cells.
They are read-only and immutable once created.
[Read more about cells](/foundations/serialization/cells).

In Tolk, the basic type `cell` describes "some cell".

```tolk theme={null}
struct SomeMessage {
    // ...
    customPayload: cell
}
```

## Typed cells: `Cell<T>`

Besides "some cell", Tolk has a "cell with known shape" `Cell<T>`.
Since one cell can store only 1023 bits, when storage exceeds this limit, the solution is to split it
into multiple cells, so they become referencing each other.

```tolk theme={null}
struct Demo {
    ref1: cell          // untyped ref
    ref2: Cell<Inner>   // typed ref
    ref3: Cell<int256>? // maybe ref
}
```

<Aside type="tip">
  Yes, `point.toCell()` really gives <code>{'Cell<' + 'Point' + '>'}</code>
</Aside>

A typed cell can be assigned to `cell` implicitly.

## Slices: cells opened for reading

To manually read data from a cell, use `beginParse()` to get a slice:

```tolk theme={null}
var s = cell.beginParse();
```

Then load data incrementally: integers, coins, sub-slices, references, etc.

```tolk theme={null}
val mode = s.loadUint(8);
val dest = s.loadAddress();
val firstRef = s.loadRef();   // cell

if (s.remainingBitsCount()) {
   // ...
}
```

An IDE will suggest applicable methods after a dot.

## Builders: cells at the moment of writing

To manually construct a cell, create a builder, write some data, and finalize this builder:

```tolk theme={null}
var b = beginCell();
b.storeUint(123, 8);
b.storeAddress(dest);
val c = b.endCell();
```

Since methods `storeXXX` return `self`, these calls can be chained:

```tolk theme={null}
val c = beginCell()
    .storeUint(123, 8)
    .storeAddress(dest)
    .endCell();
```

## How to read from a builder

The only way to access already written bits is to convert a builder into a slice:

```tolk theme={null}
var s = b.asSlice();
// or (absolutely the same)
var s = b.endCell().beginParse();
```

Constructing a cell is generally expensive in terms of gas, but `b.endCell().beginParse()` is optimized to a cheap asm instruction `BTOS` without intermediate cell creation.

## Auto packing to/from cells

Tolk type system is designed to avoid cumbersome manual work with slices and builders.
Almost every practical use case can be represented with an auto-serializable structure.

```tolk theme={null}
struct Something {
    // ...
}

fun parseAndModify(c: cell): cell {
    var smth = Something.fromCell(c);
    // ...
    return smth.toCell();
}
```

Having `Cell<T>`, just call `load()` to get `T`:

```tolk theme={null}
fun parsePoint(c: Cell<Point>) {
    // same as `Point.fromCell(c)`
    var p = c.load();
}
```

Read a detailed article [automatic serialization](/languages/tolk/features/auto-serialization).

Internally, `fromCell()` does `beginParse()` and reads data from a slice.

## Auto packing to/from builders/slices

A struct can be parsed not only from a cell but also from a slice:

```tolk theme={null}
val smth = Something.fromSlice(s);
```

Auto-serialization works at low-level also: by analogy with `loadUint()` and others, there is a `loadAny<T>()` method:

```tolk theme={null}
val smth = s.loadAny<Something>();
// or even
val smth: Something = s.loadAny();  // T=Something deduced
```

<Aside type="caution" title={"T.fromSlice(s) does not mutate the slice, but s.loadAny<T>() does"}>
  By analogy, a call `doSmth(s)`, does not change `s`, whereas `s.loadAddress()` shifts its internal pointer.
  See [mutability](/languages/tolk/syntax/mutability).
</Aside>

Similarly, `storeAny<T>()` for a builder accepts any serializable value:

```tolk theme={null}
beginCell()
    .storeAddress(dest)
    .storeAny(smth)         // T=Something deduced
    .storeUint(123, 8);
```

Furthermore, it works not only with structures but also with arbitrary types.

```tolk theme={null}
s.loadAny<int32>();           // same as loadInt(32)
s.loadAny<(coins, bool?)>();  // read a pair (a tensor)

b.storeAny(someAddress);      // same as storeAddress
b.storeAny(0xFF as uint8);    // same as storeUint(0xFF, 8)
```

This approach allows both low-level and high-level intentions to be expressed uniformly.

## Builders and slices can NOT be serialized

Builders and slices are low-level primitives used for constructing and parsing cells. They contain raw binary data.
For this reason, attempting to read an arbitrary slice from another slice is impossible: how many bits should be read?

```tolk theme={null}
struct CantBeRead {
    before: int8
    s: slice
    after: int8
}
```

An attempt to call `CantBeRead.fromCell(c)` will fire an error *"Can not be deserialized, because `CantBeRead.s` is `slice`"*.

Express shape of data using the type system to make serialization distinct. For example, `s: bits100` if it's exactly 100 bits.

## Type `bitsN`: fixed-size slices

By analogy: `int` can not be serialized, but `int32` and `int64` can.
The same: `slice` can not be serialized, but `bits32` and `bytes8` can.
At runtime, `bitsN` is a TVM `SLICE`, like `int32` is a TVM `INT`.

```tolk theme={null}
struct OkayToRead {
    before: int8
    s: bits100
    after: int8
}

fun read(c: cell) {
    // a cell `c` is expected to be 116 bits
    val r = OkayToRead.fromCell(c);
    // on the stack: INT, SLICE, INT
}
```

**To cast `slice` to `bitsN`, use the unsafe `as` operator**. It's intentional, because slices may have refs, so explicit casting forces a programmer to think whether this transformation is valid. At runtime, it's no-op.

```tolk theme={null}
fun calcHash(raw: bits512) {
    // ...
}

fun demo() {
    calcHash(someSlice);                   // error
    calcHash(someSlice as bits512);        // ok

    someBytes.loadAddress();               // error
    (someBytes as slice).loadAddress();    // ok
}
```

## "The remaining" slice when reading

A common pattern is to read a portion of data and then retrieve the remainder. With manual parsing, it happens naturally:

```tolk theme={null}
val ownerId = s.loadUint(32);
val dest = s.loadAddress();
// `s` contains all bits/refs still unread
val payload = s;
```

To express the same with the type system use **a special type `RemainingBitsAndRefs`**:

```tolk theme={null}
struct WithPayload {
    ownerId: uint32
    dest: address
    payload: RemainingBitsAndRefs
}
```

Then, `obj = WithPayload.fromSlice(s)` will return an object, where `obj.payload` contains "all bits/refs left".
This is a special type:

```tolk theme={null}
// declared in stdlib, handled specially by the compiler
type RemainingBitsAndRefs = slice
```

Naturally, such a field must appear last in a struct: no more data exists after reading it.

## Embedding constant slices into a contract

A string literal is represented as a slice:

```tolk theme={null}
// `slice` with 4 bytes: 97,98,99,100 (0x61626364)
const SLICE1 = "abcd"
```

Also, use `stringHexToSlice("...")` to embed hexadecimal binary data:

```tolk theme={null}
// `slice` with 2 bytes: 16,32 (0x1020)
const SLICE2 = stringHexToSlice("1020")
```

TVM does not have string types; it operates solely on slices. [Read about emulating strings](/languages/tolk/types/strings).

## Stack layout and serialization

Both `cell` and `Cell<T>` are backed by TVM `CELL`. Serialized as a reference; nullable are "maybe reference".

The primitive types `builder` and `slice` cannot be serialized. Use `bitsN` and `RemainingBitsAndRefs`.

For details, follow [TVM representation](/languages/tolk/types/overall-tvm-stack) and [Serialization](/languages/tolk/types/overall-serialization).
