Messages TL-B schemes
This section provides a detailed explanation of the TL-B schemes used for messages.
Message TL-B
TL-B
The main TL-B scheme for messages is defined 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;
Message X
refers to the standard message structure.MessageRelaxed X
is a variant that uses aCommonMsgInfoRelaxed
body.Message Any
is a union of both structures.
The message structure is unified using X:Type, which in this context represents a cell.
According to TL-B rules, all data can be stored within a single cell—if it fits within 1023 bits—or distributed across references using the caret symbol ^
.
A serialized Message X
is placed into the action list using the FunC method send_raw_message()
. The smart contract then executes this action, and the message is sent.
Definition of explicit serialization
To construct valid binary data according to a TL-B structure, serialization must be performed as defined recursively for each type. To serialize a Message X
, you must also know how to serialize nested structures like StateInit
, CommonMsgInfo
, etc.
Each nested structure is defined in a separate TL-B scheme, which must be referenced and resolved recursively. This continues until the serialization of the top-level structure becomes explicit—that is, every bit is defined by a boolean or a bit-representable type, e.g., bits
, uint
, varuint
.
Structures not commonly used in regular development are marked with an asterisk *
in the Type column. For example, *Anycast
is typically omitted during serialization.
message$_
This is the top-level TL-B scheme for messages, referred to as Message X
:
message$_ {X:Type} info:CommonMsgInfo
init:(Maybe (Either StateInit ^StateInit))
body:(Either X ^X) = Message X;
Structure | Type | Required | Description |
---|---|---|---|
message$_ | Constructor | Defined according to the constructor rule. The empty tag $_ indicates that no bits are added initially. | |
info | CommonMsgInfo | Required | Contains detailed message properties such as destination and value. It is always stored in the message's root cell. |
init | StateInit | Optional | The general structure is used in TON to initialize new contracts. It can be placed in either a cell reference or the root cell. |
body | X | Required | Message payload. It can be placed in either a cell reference or the 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
work—we can serialize different cases:
[CommonMsgInfo][10][StateInit][0][X]
- aMessage X
fully serialized into a single cell.


[CommonMsgInfo][11][^StateInit][1][^X]
- aMessage X
with references.


CommonMsgInfo TL-B
CommonMsgInfo
CommonMsgInfo
is a set of parameters that define how the message will be delivered on the 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
represents an internal message, meaning it can only be sent between smart contracts.
Use case: regular cross-contract communication within the TON blockchain.
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 | The $0 tag indicates that the CommonMsgInfo begins with a 0 bit in serialization, denoting an internal message. |
ihr_disabled | Bool | Required | Flag indicating whether hypercube routing (IHR) is disabled. |
bounce | Bool | Required | Specifies whether the message should be bounced if an error occurs during processing. If set to 1 , the message is bounceable. |
bounced | Bool | Required | Indicates that the message is a result of a bounce. |
src | MsgAddressInt | Required | The sender's smart contract address. |
dest | MsgAddressInt | Required | The recipient's smart contract address. |
value | CurrencyCollection | Required | Describes the currency details, including the total funds transferred with the message. |
ihr_fee | VarUInteger 16 | Required | Fee for delivering the message using hypercube routing. |
fwd_fee | VarUInteger 16 | Required | Validators set the fee for forwarding the message. |
created_lt | uint64 | Required | Logic time of the message, used by validators to order actions in smart contracts. |
created_at | uint32 | Required | UNIX timestamp indicating when the message was created. |
ext_in_msg_info$10
ext_in_msg_info$10
– represents an external incoming message. This message is sent from the off-chain world to a smart contract.
Use case: a wallet application sending a request to a 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_in_msg_info$10 | Constructor | Required | The $10 tag indicates that the CommonMsgInfo begins with 10 bits in serialization, denoting an external incoming message. |
ihr_disabled | Bool | Required | Flag indicating whether hyper routing is disabled. Currently, it is always set to true . |
src | MsgAddressExt | Required | The external sender’s address. |
dest | MsgAddressInt | Required | The destination smart contract address. |
import_fee | VarUInteger 16 | Required | The fee for executing and delivering the message. |
ext_out_msg_info$11
ext_out_msg_info$11
– represents an external outgoing message. This message is sent from a smart contract to the off-chain world.
Use case: logs.
//external outgoing 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 | The $11 tag indicates that the CommonMsgInfo begins with 11 bits in serialization, denoting an external outgoing message. |
src | MsgAddressInt | Required | The sender’s smart contract address. |
dest | MsgAddressExt | Required | The external destination address for the message. |
created_lt | uint64 | Required | Logic times of the message, assigned by the validator. Used for ordering actions in the smart contract. |
created_at | uint32 | Required | UNIX timestamp representing when the message was created. |
StateInit TL-B
StateInit
– delivers initial data to a contract during its 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 | A parameter for high-load contracts that defines the behavior of splitting into multiple instances across different shards. Currently, StateInit is used without it. |
special | TickTock* | Optional | A structure used for invoking smart contracts in every new blockchain block. Available only in the MasterChain and not typically used in regular user contracts. |
code | Cell | Optional | The contract's serialized code. |
data | Cell | Optional | The initial data for the contract. |
library | HashmapE 256 SimpleLib* | Optional | Currently, StateInit is used without libraries. |
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 for various serializations of addresses. The structure depends on the participant, either off-chain or a smart contract, sending the message. Different structures are employed based on whether the message comes from an off-chain participant or a smart contract.
addr_none$00
addr_none$00
defines a null address for an off-chain participant. This indicates that an external message can be sent to a contract without specifying a unique sender's address.
addr_none$00 = MsgAddressExt;
Structure | Type | Required | Description |
---|---|---|---|
addr_none$00 | Constructor | Required | The $00 tag in serialization indicates that MsgAddressExt starts with 00 bits. This signifies that the entire external address is 00 . |
addr_extern$01
addr_extern$01 len:(## 9) external_address:(bits len)
= MsgAddressExt;
Structure | Type | Required | Description |
---|---|---|---|
addr_extern$01 | Constructor | Required | The $01 tag in serialization indicates that MsgAddressExt starts with 01 bits and describes an external address. |
len | ## 9 | Required | Represents an unsigned N-bit number, similar to uintN . |
external_address | (bits len) | Required | A bitstring address, where the length of the address equals the previously defined 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 | The $10 tag in serialization indicates that MsgAddressInt starts with 10 bits and describes an internal address. |
anycast | Anycast* | Optional | Represents additional address data. Currently not used in ordinary internal messages. |
workchain_id | int8 | Required | The WorkChain where the smart contract of the destination address is located. Currently, this value always equals zero. |
address | (bits256) | Required | The 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 | The $11 tag indicates that in the serialization of MsgAddressInt , the address starts with 11 bits, representing an internal contract address. |
anycast | Anycast* | Optional | Additional address data is not currently used in regular internal messages. |
addr_len | ## 9 | Required | Same as uintN – represents an unsigned N-bit number. |
workchain_id | int32 | Required | The WorkChain is where the smart contract for the destination address is located. Currently, this is always set to zero. |
address | (bits256) | Required | The payload address (this could be the account ID). |
Basic used types
CurrencyCollection
nanograms$_ amount:(VarUInteger 16) = Grams;
currencies$_ grams:Grams other:ExtraCurrencyCollection
= CurrencyCollection;
Structure | Type | Required | Description |
---|---|---|---|
currencies$_ | Constructor | Required | The $_ empty tag indicates that no bits are added at the beginning during the serialization of CurrencyCollection . |
grams | (VarUInteger 16) | Required | Represents the message value, expressed in nanoTons. |
other | ExtraCurrencyCollection | Optional | ExtraCurrencyCollection is a dictionary intended for additional, typically empty currencies. |
- ExtraCurrencyCollection is a complex type usually written as an empty dictionary 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 | The var_uint$_ is an empty tag, indicating that no bits are added at the beginning of CurrencyCollection serialization. |
len | uintN | Required | Specifies the bit-length used to encode the next value. |
value | (uint (len * 8)) | Optional | An optional unsigned integer encoded 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
Validators always overwrite message parts, which can be skipped and filled with zero bits. The message's sender is also skipped and 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();