How many addresses fit into a Cell?

Intro

While developing a smart contract, I needed to store several addresses in persistent storage. At first this looked trivial, but then a simple question came up: how many addresses can I actually fit into a single cell?

Since TON storage is measured in bits and cells, and both storage and message forwarding cost gas, answering this question precisely matters. To do that, we need to look at how addresses are defined and serialized at the TL-b level.

TL-b schemes

All address formats used in TON are defined in block.tlb. The relevant schemes are:

addr_none$00 = MsgAddressExt;

addr_extern$01 len:(## 9) external_address:(bits len)
= MsgAddressExt;

anycast_info$_ depth:(#<= 30) { depth >= 1 }
rewrite_pfx:(bits depth) = Anycast;

addr_std$10 anycast:(Maybe Anycast)
workchain_id:int8 address:bits256 = MsgAddressInt;

addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
workchain_id:int32 address:(bits addr_len) = MsgAddressInt;

_ _:MsgAddressInt = MsgAddress;
_ _:MsgAddressExt = MsgAddress;

Address constructors

There are exactly four address constructors:

  • addr_none
  • addr_extern
  • addr_std
  • addr_var

Theoretical aspects: calculating address size

In this section we calculate exact bit sizes based strictly on the TL-B definitions.

addr_none

addr_none$00 = MsgAddressExt;
  • Constructor tag $002 bits

Exact size: 2 bits

addr_extern

addr_extern$01 len:(## 9) external_address:(bits len)

Components:

  • Constructor tag $012 bits
  • len:(## 9)9 bits
  • external_address:(bits len)len bits, where len ∈ [0, 511]

Exact size formula:

2 + 9 + len = 11 + len bits

Minimum size: len = 011 bits

Maximum size: len = 511522 bits

addr_std

addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256

Breakdown:

  • Constructor tag $102 bits
  • anycast:(Maybe Anycast)

    • Presence flag → 1 bit
    • If present:
      • depth:(#<=30)5 bits
      • rewrite_pfx:(bits depth)depth bits, where depth ∈ [1, 30]
  • workchain_id:int88 bits
  • address:bits256256 bits

Exact size formula:

2 + 1 + (anycast ? (5 + depth) : 0) + 8 + 256

Without anycast (presence bit = 0):

2 + 1 + 8 + 256 = 267 bits

With anycast, maximum depth = 30:

2 + 1 + (5 + 30) + 8 + 256 = 302 bits

addr_var

addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
workchain_id:int32 address:(bits addr_len)

Components:

  • Constructor tag $112 bits
  • anycast:(Maybe Anycast)

    • Presence flag → 1 bit
    • If present:
    • depth:(#<=30)5 bits
    • rewrite_pfx:(bits depth)depth bits
  • addr_len:(## 9)9 bits
  • workchain_id:int3232 bits
  • address:(bits addr_len)addr_len bits, where addr_len ∈ [0, 511]

Exact size formula:

2 + 1 + (anycast ? (5 + depth) : 0) + 9 + 32 + addr_len

Without anycast, maximum address length:

2 + 1 + 9 + 32 + 511 = 555 bits

With anycast, maximum depth = 30 and maximum address length:

2 + 1 + (5 + 30) + 9 + 32 + 511 = 590 bits

Practical assumptions (what really happens on mainnet)

Anycast is not used

Since TVM version 10, anycast addresses:

  • are not allowed as message destinations,
  • are not allowed in account addresses,
  • are no longer supported by address parsing and rewrite instructions.

In practice, this means the Maybe Anycast flag is always 0, and the Anycast payload is never present.

addr_var is not used

Currently active workchains (masterchain and basechain):

  • use addr_std,
  • use 256-bit account IDs,
  • use small workchain IDs.

addr_var exists for future extensions and is not used in real contracts today.

Practical address sizes

Internal address (addr_std, real usage)

2 (tag)
+ 1 (anycast flag)
+ 8 (workchain_id)
+ 256 (account_id)
= 267 bits

Exact size: 267 bits

This size is fixed.

External address (addr_extern, maximum)

2 (tag)
+ 9 (length)
+ 511 (payload)
= 522 bits

Summary

  • TON defines four address constructors: addr_none, addr_extern, addr_std, and addr_var.
  • Theoretical address sizes range from 2 bits to 590 bits.
  • On mainnet today:
    • Anycast is unused.
    • addr_var is unused.
    • All internal addresses are addr_std.

As a result, the practical internal address size is fixed and exactly:

➡️ 267 bits

Knowing this exact value is essential when designing compact storage layouts, estimating gas costs, and deciding how many addresses can fit into a single cell.

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post
how-five-pmms-rebuilt-sales-enablement-with-agentic-ai

How five PMMs rebuilt sales enablement with agentic AI

Next Post

A Guide to Fine-Tuning FunctionGemma

Related Posts
variables

Variables

Python – global variables(gloabal o’zgaruvchilar) funksiyadan tashqari yaratilgan ozgaruvchilar (yuqorida barcha misollar bolgan kabi) global ozgaruvchilar deb ataladi…
Read More