TL-B: язык описания схем данных
Что такое TL-B
TL-B (Type Language — Binary) — формальный язык описания структуры данных в cells. Это как Protocol Buffers или JSON Schema, но для бинарных cell trees.
TL-B определяет:
1. Какие bits в какой cell
2. Порядок полей
3. Типы данных (uint, int, address, coins, ...)
4. Где references на дочерние cells
5. Conditional fields (Maybe, Either)
Основной синтаксис
Primitive Types
Address & Coins
References (^Cell)
Maybe X (1 bit if absent)
Either X Y (1 bit selector)
Op Codes (#prefix)
Простой пример
// TL-B определение Jetton transfer message
transfer#f8a7ea5
query_id:uint64
amount:(VarUInteger 16)
destination:MsgAddress
response_destination:MsgAddress
custom_payload:(Maybe ^Cell)
forward_ton_amount:(VarUInteger 16)
forward_payload:(Either Cell ^Cell)
= InternalMsgBody;
Разбор:
transfer— название типа#f8a7ea5— op code (32-bit prefix)query_id:uint64— поле query_id, тип uint64amount:(VarUInteger 16)— variable-length unsigned integerdestination:MsgAddress— TON address(Maybe ^Cell)— опциональная ссылка на cell(Either Cell ^Cell)— inline или в reference
Ключевые типы TL-B
| Тип | Описание | Bits |
|---|---|---|
uint1…uint256 | Unsigned integer | N bits |
int1…int257 | Signed integer | N bits |
bits256 | Fixed 256 bits | 256 |
MsgAddress | TON address | 267 |
Grams / VarUInteger 16 | Coin amount | Variable |
^Cell | Reference to cell | 0 (reference, not data) |
Maybe X | Optional (1 bit flag + X) | 1 + sizeof(X) |
Either X Y | Union (1 bit flag + variant) | 1 + max(sizeof) |
Читаем TL-B схемы
Пример: NFT Item Data
// TL-B определение NFT Item state
nft_item_data#_
index:uint64
collection_address:MsgAddress
owner_address:MsgAddress
content:^Cell
= NFTItemData;
Перевод:
nft_item_data#_— тип без explicit op code (#_= автоматический)index:uint64— порядковый номер в коллекцииcollection_address:MsgAddress— адрес Collection контрактаowner_address:MsgAddress— текущий владелецcontent:^Cell— metadata (в отдельной referenced cell)
Расчёт размера
NFTItemData size:
index: 64 bits
collection: 267 bits
owner: 267 bits
content ref: 0 bits (reference, не data)
─────────────────────
Total: 598 bits + 1 reference
Помещается в одну cell? 598 < 1023 [OK]
TL-B для System Design
1. Проектирование message format
Перед написанием кода — определите TL-B schema:
// Ваш custom protocol
subscribe#a1b2c3d4
query_id:uint64
plan_id:uint8
duration_months:uint16
= SubscribeMsg;
unsubscribe#b2c3d4e5
query_id:uint64
= UnsubscribeMsg;
subscription_status#c3d4e5f6
query_id:uint64
plan_id:uint8
expiry:uint32
= StatusResponse;
2. State layout design
TL-B для contract state:
// Subscription Master state
subscription_master#_
admin:MsgAddress
next_user_id:uint64
total_subscribers:uint64
plans:^Cell // ref: plans dictionary
user_code:^Cell // ref: child contract code
= SubscriptionMasterData;
// Subscription Child state
subscription_user#_
owner:MsgAddress
master:MsgAddress
plan_id:uint8
expiry:uint32
total_paid:(VarUInteger 16)
= SubscriptionUserData;
3. Версионирование
TL-B op codes позволяют версионировать протокол:
// Version 1
transfer_v1#f8a7ea5 ... = InternalMsgBody;
// Version 2 (новые поля)
transfer_v2#f8a7ea6 ... memo:(Maybe ^Cell) = InternalMsgBody;
// Контракт проверяет op code и выбирает handler:
if (op == 0xf8a7ea5) { handle_v1(); }
if (op == 0xf8a7ea6) { handle_v2(); }
TIP
Практическое правило
Всегда определяйте TL-B schema ПЕРЕД написанием кода. Это:
- Документирует протокол (другие контракты знают формат)
- Предотвращает ошибки сериализации
- Позволяет рассчитать gas заранее (знаем размер messages)
- Упрощает version migration