Skip to main content
T TON Adoption
← Glossary
NODE/03 · Term

Cell (TVM data structure)

Atomic data unit in TON. Holds up to 1023 bits of data and up to 4 references to other cells. Every contract storage and message body is a tree of cells.

Aliases: ton cell, tvm cell

A cell is the fundamental data structure of the TON Virtual Machine. Everything on TON — contract code, contract storage, message bodies, jetton metadata, NFT content, transaction proofs — is a tree of cells.

What’s inside a cell

Each cell carries:

  • Up to 1023 bits of payload data.
  • Up to 4 references to other cells.
  • A header that records lengths, depth, and a SHA-256 hash of the contents.

That’s it. No types, no schemas — those are layered on top via TL-B (a serialisation language) or by the contract reading the cell.

Immutability and DAG structure

Cells are immutable: once built and hashed, they cannot be modified. To “change” a cell you build a new one and update the reference. This makes cells form a directed acyclic graph (DAG):

  • Circular references are forbidden (and impossible in practice — computing a hash that includes itself is impossible).
  • The same cell can be referenced from multiple parents — the DAG can share subtrees, which saves space when cells are duplicated.

Every cell has a deterministic SHA-256 hash that depends on its data, its references’ hashes, and a few descriptor bits. This is what makes cells the building block of Merkle proofs.

Reading and writing

Contracts don’t manipulate cells in place. Instead:

  • Builders are write cursors. You start with begin_cell() (FunC) or beginCell() (TypeScript libs), append data with store_uint, store_slice, store_ref, and call end_cell() to materialise the cell.
  • Slices are read cursors. You start with begin_parse() on a cell, read fields with load_uint, load_slice, load_ref.

That cursor-based model is one of the things that makes TON contract code feel different from Solidity. There is no mapping[address] — there are dictionaries (HashmapE) that compile down to cell trees, walked via slices.

Cell types

  • Ordinary cells — the kind described above; what 99% of contract data looks like.
  • Exotic cells — special types identified by a leading byte (0x01 pruned branch, 0x02 library reference, 0x03 Merkle proof, 0x04 Merkle update). They’re used by the protocol itself for proofs and code libraries; ordinary developers rarely build them by hand.

Storage and gas implications

  • Reading a cell costs gas; reading a referenced cell (“loading a ref”) also costs gas. Deeply nested data is expensive.
  • Storage fees scale with the total cell tree size. A contract that stores a giant dictionary pays storage fees on every cell.
  • Cells encourage compact encoding: it is normal to pack 5–10 fields into a single cell’s bit space rather than spreading them across many cells.

Why this design

Cells are the protocol’s answer to two requirements at once:

  • Cheap Merkle proofs — anyone can prove that a piece of state (a balance, a nonce) belongs to a contract by handing over the path of cell hashes from the value up to the contract’s root.
  • Sharding-friendly state — because state is a hash-rooted tree, a sharded chain can verify another shard’s state with a small proof, no full node needed.

The trade-off is developer ergonomics: working with cells, slices, and builders is more low-level than typed Solidity structs, and it takes a while to internalise. Higher-level languages (Tact, Tolk) hide most of this with generated parsers/serialisers.

Related terms