Skip to main content

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;
StructureTypeRequiredDescription
message$_ConstructorIt defined according the constructor ruler. Empty tag $_ means we will not add any bits in the beginning
infoCommonMsgInfoRequiredDetailed Message properties define destination and its value. Always placed in message root cell.
initStateInitOptionalGeneral structure using in TON for initilizing new contracts. Could be write in cell reference or root cell.
bodyXRequiredMessage 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 X in the one cell


  • [CommonMsgInfo][11][^StateInit][1][^X] - Message X with 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;
StructureTypeRequiredDescription
int_msg_info$0ConstructorRequired$0 tag means, that in serialization CommonMsgInfo started with 0 bit describes a internal message.
ihr_disabledBoolRequiredHyper cube routing flag.
bounceBoolRequiredMessage should be bounced if there are errors during processing. If message's flat bounce = 1, it calls bounceable.
bouncedBoolRequiredFlag that describes, that message itself is a result of bounce.
srcMsgAddressIntRequiredAddress of smart contract sender of message.
destMsgAddressIntRequiredAddress of smart contract destination of message.
valueCurrencyCollectionRequiredStructure which describes currency information including total funds transferred in message.
ihr_feeVarUInteger 16RequiredFees for hyper routing delivery
fwd_feeVarUInteger 16RequiredFees for forwarding messages assigned by validators
created_ltuint64RequiredLogic time of sending message assigned by validator. Using for odering actions in smart contract.
created_atuint32RequiredUnix 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;
StructureTypeRequiredDescription
ext_out_msg_info$10ConstructorRequired$10 tag means, that in serialization CommonMsgInfo started with 10 bits describes a external incoming message.
ihr_disabledBoolRequiredHyper routing flag. (currently always true)
srcMsgAddressExtRequiredAddress of a external sender of the message.
destMsgAddressIntRequiredAddress of smart contract destination of message.
import_feeVarUInteger 16RequiredFee 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;
StructureTypeRequiredDescription
ext_out_msg_info$11ConstructorRequired$11 tag means, that in serialization CommonMsgInfo started with 11 bit describes a external outgoing message.
srcMsgAddressIntRequiredHyper routing flag. v
destMsgAddressExtRequiredGeneral structure using in TON for initializing new contracts. Could be write in cell reference or root cell.
created_ltuint64RequiredLogic time of sending message assigned by validator. Using for odering actions in smart contract.
created_atuint32RequiredUnix 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;
StructureTypeRequiredDescription
split_depth(## 5)OptionalParameter for the highload contracts, defines behaviour of splitting into multiple instances in different shards. Currently StateInit used without it.
specialTickTock*OptionalUsed for invoking smart contracts in every new block of the blockchain. Available only in the masterchain. Regular user's contracts used without it.
codeCellOptionalContract's serialized code.
dataCellOptionalContract initial data.
libraryHashmapE 256 SimpleLib*OptionalCurrently 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;
StructureTypeRequiredDescription
addr_none$00ConstructorRequired$00 tag means, that in serialization MsgAddressExt started with 00 bits. This means whole external address is 00.

addr_extern$01

addr_extern$01 len:(## 9) external_address:(bits len)
= MsgAddressExt;
StructureTypeRequiredDescription
addr_extern$01ConstructorRequired$01 tag means, that in the serialization MsgAddressExt started with a 01 bits describes an external address.
len## 9RequiredSame as uintN - means an unsigned N-bit number
external_address(bits len)RequiredAddress 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;
StructureTypeRequiredDescription
addr_std$10ConstructorRequired$10 tag means, that in the serialization MsgAddressExt started with a 10 bits describes an external address.
anycastAnycast*OptionalAdditional address data, currently do not used in ordinary internal messages
workchain_idint8RequiredWorkchain where smart contract of destination address placed. At moment always equals zero.
address(bits256)RequiredSmart contract account ID number

addr_var$11

addr_var$11 anycast:(Maybe Anycast) addr_len:(## 9)
workchain_id:int32 address:(bits addr_len) = MsgAddressInt;
StructureTypeRequiredDescription
addr_var$11ConstructorRequired$11 tag means, that in the serialization MsgAddressInt started with a 11 bits describes an internal contract address.
anycastAnycast*OptionalAdditional address data, currently do not used in ordinary internal messages
addr_len## 9RequiredSame as uintN - means an unsigned N-bit number
workchain_idint32RequiredWorkchain where smart contract of destination address placed. At moment always equals zero.
address(bits256)RequiredPayload address(could be account ID)

Basic used types

CurrencyCollection

nanograms$_ amount:(VarUInteger 16) = Grams;
currencies$_ grams:Grams other:ExtraCurrencyCollection
= CurrencyCollection;
StructureTypeRequiredDescription
currencies$_ConstructorRequired$_ empty tag means, that in the serialization CurrencyCollection we will not add any bits in the beginning
grams(VarUInteger 16)RequiredMessage value in nanoTons
otherExtraCurrencyCollectionOptionalExtraCurrencyCollection 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;
StructureTypeRequiredDescription
varuint$ConstructorRequiredvar_uint$_ empty tag means, that in the serialization CurrencyCollection we will not add any bits in the beginning
lenuintNRequiredbits len parameter for next value
value(uint (len * 8))Optionaluint 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();