Learning Platform
Глоссарий Troubleshooting
Урок 06.05 · 15 мин
Продвинутый
Storage OptimizationData LayoutGas OptimizationCell Packing

Storage Optimization и Data Layout

Почему это важно

Storage fee — постоянный расход. В отличие от gas (платится один раз при транзакции), storage fee начисляется каждый блок за весь хранимый state. Оптимизация storage = постоянная экономия.

Экономия на storage:
Экономия 1 cell = ~0.000004 TON/год
Экономия 100 cells = ~0.0004 TON/год
Экономия 10,000 cells = ~0.04 TON/год

Для контракта с 100K users × 10 cells = 1M cells:
  Before optimization: ~4 TON/год
  After (-30% cells): ~2.8 TON/год
  Savings: 1.2 TON/год

Technique 1: Bit Packing

Storage Optimization Techniques Comparison
Bit Packing
Optional Fields (Maybe)
Cleanup Expired
Shared Code Refs (auto-dedup)
State Layout Planning
Self-Destruct (0 fee)

Упаковывайте несколько значений в минимум bits:

[NO] Wasteful (3 cells):
Cell 1: status: uint256 = 3        // 256 bits для значения 0-5
Cell 2: plan_id: uint256 = 2       // 256 bits для значения 0-10  
Cell 3: is_active: uint256 = 1     // 256 bits для boolean

Total: 768 bits, 3 references

[OK] Packed (1 cell):
Cell 1:
  status: uint3 = 3       // 3 bits
  plan_id: uint4 = 2      // 4 bits
  is_active: bit = 1      // 1 bit
  
Total: 8 bits, 0 references
Savings: 760 bits, 3 cells → 1 cell

Technique 2: Optional Fields

Используйте Maybe для полей, которые часто пустые:

// TL-B с Maybe
user_data#_ 
  balance:Grams 
  locked_until:(Maybe uint32)     // 1 bit if absent, 33 bits if present
  referral:(Maybe MsgAddress)     // 1 bit if absent, 268 bits if present
  = UserData;

// Для user БЕЗ lock и referral:
  balance + 1 bit (no lock) + 1 bit (no referral) = ~126 bits

// Для user С lock и referral:
  balance + 33 bits + 268 bits = ~427 bits

Savings: users без optional fields экономят ~300 bits each

Technique 3: Shared Code References

В sharded design все child contracts имеют одинаковый code. TON дедуплицирует code cells:

1000 child contracts с одинаковым code:
  Storage: 1 × code_size + 1000 × data_size
  НЕ: 1000 × (code_size + data_size)

TON автоматически sharing-ает cells с одинаковым hash!

Technique 4: Cleanup Expired Data

Удаляйте данные, которые больше не нужны:

// При каждой транзакции — cleanup
recv_internal(msg) {
  // Cleanup expired entries
  if (now() > self.next_cleanup) {
    let deleted = cleanup_expired(self.dict, 10); // max 10 per tx
    self.next_cleanup = now() + 3600; // next cleanup in 1 hour
  }
  
  // Normal processing...
}
WARNING

Gas-bounded cleanup

Не удаляйте все expired entries за одну транзакцию — может не хватить gas. Удаляйте bounded batch (10-50 entries per tx). Spread cleanup across multiple transactions.

Technique 5: State Layout Reference Card

Шаблон для проектирования state layout:

Contract State Layout Design:

1. List all fields with types and bit sizes
2. Sort by frequency of access (most accessed first)
3. Pack into root cell (up to 1023 bits)
4. Overflow → references (up to 4)
5. Large/optional data → ref cells
6. Collections → HashmapE (≤1000) or child contracts (>1000)
7. Calculate total cells and annual storage fee

Template:
Root Cell [used: ??? / 1023 bits, refs: ? / 4]:
  ├── field_1: type (N bits) — always present
  ├── field_2: type (N bits) — always present
  ├── field_3: Maybe type (1+N bits) — optional
  └── Refs:
      ├── Ref 0 → data_cell [used: ??? / 1023 bits]
      ├── Ref 1 → dict_cell [HashmapE, ~K entries]
      └── Ref 2 → code_cell [immutable]

Storage estimate:
  cells_count: ???
  annual_fee: ??? TON
  min_balance: ??? TON (cover 1 year fees)

Complete Example: Optimized Staking Position

Staking Position Contract — State Layout:

Root Cell [892 / 1023 bits, 1 ref]:
  ├── owner: MsgAddress (267 bits)
  ├── pool_master: MsgAddress (267 bits)
  ├── staked_amount: Grams (124 bits)
  ├── reward_debt: Grams (124 bits)
  ├── stake_time: uint32 (32 bits)
  ├── lock_until: Maybe uint32 (1+32 = 33 bits)
  ├── auto_compound: bit (1 bit)
  ├── status: uint2 (2 bits) — 0:active, 1:unstaking, 2:withdrawn
  └── Ref 0 → pool_code: Cell (for verification)

Cells: 2 (root + code ref)
Annual storage fee: ~0.000008 TON
Min balance for 10 years: ~0.00008 TON + gas reserve
Проверка знанийKnowledge check
ОтветAnswer

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 2. Контракт имеет 1M cells в state. Annual storage fee ~4 TON. Какая техника даст наибольшую экономию?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5