Messages TL-B schemes
In this section detailed explanation of TL-B schemes for messages.
Message TL-B
TL-B
Main message TL-B scheme declared as a combination of several nested structures
message$_ {X:Type} info:CommonMsgInfo
init:(Maybe (Either StateInit ^StateInit))
body:(Either X ^X) = Message X;
message$_ {X:Type} info:CommonMsgInfoRelaxed
init:(Maybe (Either StateInit ^StateInit))
body:(Either X ^X) = MessageRelaxed X;
_ (Message Any) = MessageAny;
Here Message X - is common message structure, MessageRelaxed X additional type with CommonMsgInfoRelaxed body and Message Any is a union of both.
Message structure unified with X:Type, that in other words is a Cell.
According to TL-B we can combine all data in one cell(if it will be fit to 1023 bits) or use references declared with caret ^.
Serialized Message X placed to action list with FunC method send_raw_message(), than smart contract execute this action and message send.
Definition of explicit serialization
For building valid binary data according TL-B structure we should do serialization, which defined for each type recurrently. It means, that for serialization of Message X we need to know how to serialize
StateInit, CommonMsgInfo and so on.
Every nested structure we should get from another TL-B scheme according to link recurrently, until serialization for top structure will be explicit - every bit defined by Boolean or bit-like type(bits, uint, varuint).
Structures that currently does not use in regular development will mark with * in Type column, for example *Anycast usually skipped in serialization.
message$_
There is the top TL-B scheme whole messages Message X:
message$_ {X:Type} info:CommonMsgInfo
init:(Maybe (Either StateInit ^StateInit))
body:(Either X ^X) = Message X;
| Structure | Type | Required | Description | 
|---|---|---|---|
| message$_ | Constructor | It defined according the constructor ruler. Empty tag $_means we will not add any bits in the beginning | |
| info | CommonMsgInfo | Required | Detailed Message properties define destination and its value. Always placed in message root cell. | 
| init | StateInit | Optional | General structure using in TON for initilizing new contracts. Could be write in cell reference or root cell. | 
| body | X | Required | Message Payload. Could be write in cell reference or root cell. | 
nothing$0 {X:Type} = Maybe X;
just$1 {X:Type} value:X = Maybe X;
left$0 {X:Type} {Y:Type} value:X = Either X Y;
right$1 {X:Type} {Y:Type} value:Y = Either X Y;
Recall how Maybe and Either works, we can serialize different cases:
- [CommonMsgInfo][10][StateInit][0][X]-- Message Xin the one cell

 
- [CommonMsgInfo][11][^StateInit][1][^X]-- Message Xwith references

 
CommonMsgInfo TL-B
CommonMsgInfo
CommonMsgInfo is a list of parameters, that defines how message will be delivered in TON blockchain.
//internal message
int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
  src:MsgAddressInt dest:MsgAddressInt
  value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams
  created_lt:uint64 created_at:uint32 = CommonMsgInfo;
//external incoming message
ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt
  import_fee:Grams = CommonMsgInfo;
//external outgoing message
ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt
  created_lt:uint64 created_at:uint32 = CommonMsgInfo;
int_msg_info$0
int_msg_info is a case of internal message. This means they could be sent between contracts, and only between contracts.
Use case - ordinary cross contract messages.
nanograms$_ amount:(VarUInteger 16) = Grams;
//internal message
int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool
  src:MsgAddressInt dest:MsgAddressInt
  value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams
  created_lt:uint64 created_at:uint32 = CommonMsgInfo;
| Structure | Type | Required | Description | 
|---|---|---|---|
| int_msg_info$0 | Constructor | Required | $0 tag means, that in serialization CommonMsgInfo started with 0 bit describes a internal message. | 
| ihr_disabled | Bool | Required | Hyper cube routing flag. | 
| bounce | Bool | Required | Message should be bounced if there are errors during processing. If message's flat bounce = 1, it calls bounceable. | 
| bounced | Bool | Required | Flag that describes, that message itself is a result of bounce. | 
| src | MsgAddressInt | Required | Address of smart contract sender of message. | 
| dest | MsgAddressInt | Required | Address of smart contract destination of message. | 
| value | CurrencyCollection | Required | Structure which describes currency information including total funds transferred in message. | 
| ihr_fee | VarUInteger 16 | Required | Fees for hyper routing delivery | 
| fwd_fee | VarUInteger 16 | Required | Fees for forwarding messages assigned by validators | 
| created_lt | uint64 | Required | Logic time of sending message assigned by validator. Using for odering actions in smart contract. | 
| created_at | uint32 | Required | Unix time | 
ext_in_msg_info$10
ext_in_msg_info$10 is a case of external incoming message. This means this type of messages sent from contracts to off-chain space.
Use case - wallet application request to wallet contract.
nanograms$_ amount:(VarUInteger 16) = Grams;
//external incoming message
ext_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt
  import_fee:Grams = CommonMsgInfo;
| Structure | Type | Required | Description | 
|---|---|---|---|
| ext_out_msg_info$10 | Constructor | Required | $10tag means, that in serialization CommonMsgInfo started with10bits describes a external incoming message. | 
| ihr_disabled | Bool | Required | Hyper routing flag. (currently always true) | 
| src | MsgAddressExt | Required | Address of a external sender of the message. | 
| dest | MsgAddressInt | Required | Address of smart contract destination of message. | 
| import_fee | VarUInteger 16 | Required | Fee for executing and delivering of message. | 
ext_out_msg_info$11
ext_out_msg_info$11 is a case of external outgoing message. This means they could be sent from contracts to off-chain space.
Use case - logs.
//internal message
ext_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt
  created_lt:uint64 created_at:uint32 = CommonMsgInfo;
| Structure | Type | Required | Description | 
|---|---|---|---|
| ext_out_msg_info$11 | Constructor | Required | $11tag means, that in serialization CommonMsgInfo started with11bit describes a external outgoing message. | 
| src | MsgAddressInt | Required | Hyper routing flag. v | 
| dest | MsgAddressExt | Required | General structure using in TON for initializing new contracts. Could be write in cell reference or root cell. | 
| created_lt | uint64 | Required | Logic time of sending message assigned by validator. Using for odering actions in smart contract. | 
| created_at | uint32 | Required | Unix time | 
StateInit TL-B
StateInit serves to delivery inital data to contract and used in contract deployment.
_ split_depth:(Maybe (## 5)) special:(Maybe TickTock)
  code:(Maybe ^Cell) data:(Maybe ^Cell)
  library:(HashmapE 256 SimpleLib) = StateInit;
| Structure | Type | Required | Description | 
|---|---|---|---|
| split_depth | (## 5) | Optional | Parameter for the highload contracts, defines behaviour of splitting into multiple instances in different shards. Currently StateInit used without it. | 
| special | TickTock* | Optional | Used for invoking smart contracts in every new block of the blockchain. Available only in the masterchain. Regular user's contracts used without it. | 
| code | Cell | Optional | Contract's serialized code. | 
| data | Cell | Optional | Contract initial data. | 
| library | HashmapE 256 SimpleLib* | Optional | Currently used StateInit without libs | 
General detailed explanations for Hashmaps
MsgAddressExt TL-B
addr_none$00 = MsgAddressExt;
addr_extern$01 len:(## 9) external_address:(bits len)
= MsgAddressExt;
MsgAddress is a scheme of various serialization for addresses. Depends on which participant(off-chain or smartcontract) messages sent, different structures using.
addr_none$00
addr_none$00 - using for defining null address of off-chain participant. It means, that we can send external message to contract without unique sender's address.
addr_none$00 = MsgAddressExt;
| Structure | Type | Required | Description | 
|---|---|---|---|
| addr_none$00 | Constructor | Required | $00tag means, that in serialization MsgAddressExt started with00bits. This means whole external address is00. | 
addr_extern$01
addr_extern$01 len:(## 9) external_address:(bits len)
= MsgAddressExt;
| Structure | Type | Required | Description | 
|---|---|---|---|
| addr_extern$01 | Constructor | Required | $01tag means, that in the serialization MsgAddressExt started with a01bits describes an external address. | 
| len | ## 9 | Required | Same as uintN - means an unsigned N-bit number | 
| external_address | (bits len) | Required | Address is a bitstring of the len equal to previous len | 
MsgAddressInt TL-B
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;
addr_std$10
addr_std$10 anycast:(Maybe Anycast)
workchain_id:int8 address:bits256  = MsgAddressInt;
| Structure | Type | Required | Description | 
|---|---|---|---|
| addr_std$10 | Constructor | Required | $10tag means, that in the serialization MsgAddressExt started with a10bits describes an external address. | 
| anycast | Anycast* | Optional | Additional address data, currently do not used in ordinary internal messages | 
| workchain_id | int8 | Required | Workchain where smart contract of destination address placed. At moment always equals zero. | 
| address | (bits256) | Required | Smart contract account ID number | 
addr_var$11
addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
workchain_id:int32 address:(bits addr_len) = MsgAddressInt;
| Structure | Type | Required | Description | 
|---|---|---|---|
| addr_var$11 | Constructor | Required | $11tag means, that in the serialization MsgAddressInt started with a11bits describes an internal contract address. | 
| anycast | Anycast* | Optional | Additional address data, currently do not used in ordinary internal messages | 
| addr_len | ## 9 | Required | Same as uintN - means an unsigned N-bit number | 
| workchain_id | int32 | Required | Workchain where smart contract of destination address placed. At moment always equals zero. | 
| address | (bits256) | Required | Payload address(could be account ID) | 
Basic used types
CurrencyCollection
nanograms$_ amount:(VarUInteger 16) = Grams;
currencies$_ grams:Grams other:ExtraCurrencyCollection
= CurrencyCollection;
| Structure | Type | Required | Description | 
|---|---|---|---|
| currencies$_ | Constructor | Required | $_empty tag means, that in the serialization CurrencyCollection we will not add any bits in the beginning | 
| grams | (VarUInteger 16) | Required | Message value in nanoTons | 
| other | ExtraCurrencyCollection | Optional | ExtraCurrencyCollection is a dict designed for additional currencies, that usually empty | 
- ExtraCurrencyCollection complex type, that usually wrote as empty dict in messages
VarUInteger n
var_uint$_ {n:#} len:(#< n) value:(uint (len * 8))
= VarUInteger n;
var_int$_ {n:#} len:(#< n) value:(int (len * 8))
= VarInteger n;
| Structure | Type | Required | Description | 
|---|---|---|---|
| var_uint$_ | Constructor | Required | var_uint$_empty tag means, that in the serialization CurrencyCollection we will not add any bits in the beginning | 
| len | uintN | Required | bits len parameter for next value | 
| value | (uint (len * 8)) | Optional | uint value for integer number wrote in (len * 8) bits | 
Message example
Regular func internal message
  var msg = begin_cell()
    .store_uint(0, 1) ;; tag
    .store_uint(1, 1) ;; ihr_disabled
    .store_uint(1, 1) ;; allow bounces
    .store_uint(0, 1) ;; not bounced itself
    .store_slice(source)
    .store_slice(destination)
    ;; serialize CurrencyCollection (see below)
    .store_coins(amount)
    .store_dict(extra_currencies)
    .store_coins(0) ;; ihr_fee
    .store_coins(fwd_value) ;; fwd_fee
    .store_uint(cur_lt(), 64) ;; lt of transaction
    .store_uint(now(), 32) ;; unixtime of transaction
    .store_uint(0,  1) ;; no init-field flag (Maybe)
    .store_uint(0,  1) ;; inplace message body flag (Either)
    .store_slice(msg_body)
  .end_cell();
Regular func message in short form
Message parts that are always overwritten by validators could be skipped(fill with zero bits). Message's sender here skipped too, serialized as addr_none$00.
  cell msg = begin_cell()
        .store_uint(0x18, 6)
        .store_slice(addr)
        .store_coins(amount)
        .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
        .store_slice(message_body)
.end_cell();