Using the Fift language is not required for programming TON smart contracts, but if you want to get acquainted with
Fift, we have prepared this article for you.
What is Fift?
Fift is a stack-based general-purpose programming language designed specifically for interacting with the TON Virtual
Machine and the TON Blockchain.
What is a stack-based language?
Stack-oriented programming is a programming paradigm in which parameters are passed using a stack machine model.
Stack-oriented languages work with one or more stacks, each of which can have a particular purpose. Some stack-oriented
languages, such as Fift, use postfix or reverse Polish notation. Any command arguments or parameters are listed before
the command. Postfix notation, for example for multiply(2, 3), would be expressed as 2, 3, multiply.
Setup
To use Fift, you'll need to have the Fift compiler binaries first. You can
either compile from the sources or simply download
from TON Autobuilds according to
your platform.
You should be able to use Fift interpreter just by typing fift in your shell. If you encounter the following error:
log
[ 1][t 0][2022-05-08 14:36:43.170977500][fift-main.cpp:180] Error interpreting standard preamble file `Fift.fif`: cannot locate file `Fift.fif`
Check that correct include path is set by -I or by FIFTPATH environment variable, or disable standard preamble by -n.
You should either set the FIFTPATH env variable to fift libs directory or pass directory path by -I flag:
bash
fift -I /path/to/fift/libs
Types
These are some basic data types used in Fift:
Type
Description
Usual Stack Notation
Integer
A Signed 257-bit integer
x, y, or z
Cell
TVM Cell
c, c', or c2
Slice
partial view of Cell
s
Builder
partially built Cell
b
Null
null value
⟂
Tuple
Ordered collection of values
String
A UTF-8 String
S
Bytes
Sequence of bytes, representing binary data
B
Stack Notation
As mentioned before, Fift uses postfix or reverse Polish notation. Fift parser processes the code line-by-line. As it
reads the line, If it encounters a value, pushes it onto the stack and If it encounters a word, executes it. Words can
be assumed as function/code definitions and primitives and functions are implemented as those. All words are stored in
Fift's global dictionary.
Primitives are the word that are already defined by the interpreter (in the implementation), other words are defined
in Fift.fif standard library. Users can define words and extend the dictionary later.
Every time the interpreter finishes interpreting the line, it prints ok to standard output.
As an example, let's see the following code:
code
2 3 + .
First, 2 will be pushed to the stack then 3, + primitive will be executed which will pop two values from the stack
and push their sum into the stack, at last . primitive will print the integer to standard output. So the standard
output after executing the code will be:
code
5 ok
To understand the effect of words easily, a notation is used that shows the top of the stack before and after the word's
execution. It's in word-name (before — after) format and here are some examples:
Primitives and standard library words are documented in
the Fift Documentation, along with their notation and a
description of what they do.
List of useful words
Here is the table of some useful words that are predefined:
Word
Notation
Description
+
(x y — x + y)
Replaces two Integers x and y passed at the top of the stack with their sum x + y
-
(x y — x - y)
Computes the difference x − y of two Integers x and y
*
(x y — xy)
Computes the product xy of two Integers x and y
/
(x y — q := floor(x/y))
Computes the floor-rounded quotient of two Integers x and y
<
(x y — ?)
Checks whether x < y (i.e., pushes −1 if x < y, 0 otherwise)
>, =, <>, <=, >=
(x y — ?)
Compare x and y and push −1 or 0 depending on the result of the comparison.
"<string>"
( — S)
Pushes a String literal into the stack
."<string>"
( — )
Prints a constant string into the standard output
type
(S — )
Prints a String S taken from the top of the stack into the standard output
cr
( — )
Outputs a carriage return (or a newline character) into the standard output
b{<binary-data>}
( – s)
Creates a Slice s that contains no references and up to 1023 data bits specified in <binary-data>, which must be a string consisting only of the characters ‘0’ and ‘1’
x{<hex-data>}
( – s)
Creates a Slice s that contains no references and up to 1023 data bits specified in <hex-data>
<b
( – b)
Creates a new empty Builder
b>
(b – c)
Transforms a Builder b into a new Cell c containing the same data as b
i,
(b x y – b')
Appends binary representation of signed y-bit integer x (0 <= y <= 257) to Builder b
u,
(b x y – b')
Appends binary representation of unsigned y-bit integer x (0 <= y <= 256) to Builder b
ref,
(b c – b')
Appends a reference to Cell c to Builder b
s,
(b s – b')
Appends data bits and references taken from Slice s to Builder b
$,
(b S – b')
Appends String S to Builder b
B>boc
(B – c)
Deserializes a “standard” bag of cells represented by Bytes B, and returns the root Cell c
boc+>B
(c x – B)
Creates and serializes a “standard” bag of cells, consisting one root Cell c along with all its descendants. x represents flags for the additional options
B{<hex-digits>}
( – B)
Pushes a Bytes literal containing data represented by an even number of hexadecimal digits.
Bx.
(B – )
Prints the hexadecimal representation of a Bytes value
file>B
(S – B)
Reads the (binary) file with the name specified in String S and returns its contents as a Bytes value
B>file
(B S – )
Creates a new (binary) file with the name specified in String S and writes data from Bytes B into the new file.
smca>$
(x y z – S)
Packs a standard TON smart-contract address with workchain x (a signed 32-bit Integer) and in-workchain address y (an unsigned 256-bit Integer) into a 48-character string S (the human-readable representation of the address) according to flags z. Possible individual flags in z are: +1 for non-bounceable addresses, +2 for testnet-only addresses, and +4 for base64url output instead of base64.
gt;smca
(S – x y z -1 or 0)
Unpacks a standard TON smart-contract address from its human-readable string representation S.
Creating messages with Fift
To interact with smart contracts on TON Network we mostly need to create and send messages to them. There are several
ways to do that, but Fift is the main and preferred way of creating messages.
Let's say we have a contract that requires an input body in the below format:
code
Internal message has the following structure:
op_code:uint32 query_id:uint64 amount:(VarUInteger 16)
destination:MsgAddress = InternalMsgBody;
To construct this with Fift:
code
"Asm.fif" include
"TonUtil.fif" include
<b 24 32 u, 0 64 u, 1 Gram,
"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX" gt;smca 2drop Addr,
b>
2 boc+>B dup Bx. cr
What it does is:
Imports Asm.fif and TonUtil.fif libraries
Constructs an empty builder
Appends 24 as op_code (32-bit unsigned integer)
Appends 0 as query_id (64-bit unsigned integer)
Appends 1 nanoton as amount
Parses address EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX and stores it to builder as destination
using x,y (drops z and result) by invoking Addr, word that is defined in TonUtil.fif
Constructs cell from the builder
Writes the bag of cells to Bytes
Prints hex representation of the result and leaves the result at top of the stack.
Here is the execution of it with fift interpreter:
code
"Asm.fif" include
ok
"TonUtil.fif" include
ok
<b 24 32 u, 0 64 u, 1 Gram,
ok
"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX" gt;smca 2drop Addr,
ok
b>
ok
2 boc+>B dup Bx. cr
B5EE9C7241010101003100005D0000001800000000000000001018006ED66A12E4F138D32C3F29C0E5FD68430E1077EFED9D97B342BDBCD35C5739A9EF4BC35F
ok
.s
BYTES:B5EE9C7241010101003100005D0000001800000000000000001018006ED66A12E4F138D32C3F29C0E5FD68430E1077EFED9D97B342BDBCD35C5739A9EF4BC35F
ok
TonWeb: An Alternative Way
TonWeb is a JavaScript SDK for The Open Network. It comes with classes that ease
interacting with TON ecosystem. One of those is Cell class which can be used to create the bag of cells.
For example, the above example could be done in JS this way:
javascript
const TonWeb = require("tonweb");
const Cell = TonWeb.boc.Cell;
const Address = TonWeb.utils.Address;
let cell = new Cell();
cell.bits.writeUint(24, 32); // op_code
cell.bits.writeUint(0, 64); // query_id
cell.bits.writeCoins(1); // amount
let address = new Address("EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX"); // destination
cell.bits.writeAddress(address);
console.log(cell.print()); // print cell data like Fift
let bocBytes = cell.toBoc(false);
bocBytes.then((res) => {
console.log(Buffer.from(res).toString("hex"))
});
What we discussed in two previous sections were just only message bodies, If we want to create complete messages, we
should pick the appropriate type of the message and construct it according to
the TL-B Schema. Messages have two types:
Internal Messages: messages that contracts send to each other on the blockchain
External Messages: messages that come from outside the blockchain (Messages from nowhere or Inbound External
Messages) or go outside the blockchain (Messages to nowhere or Outbound External Messages)
To construct a full internal message we will have:
code
"Asm.fif" include
"TonUtil.fif" include
// message body:
<b 24 32 u, 0 64 u, 1 Gram,
"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX" gt;smca 2drop Addr,
b> constant msg_body // we define the message body and store it in a constant named msg_body, so we can later use it
<b
// First we define CommonMsgInfo, we're gonna pick int_msg_info$0 so first bit will be => '0'
// as schema follows, want to disable ihr, allow bounces and is not bounced itself so we'll have => '011'
// next is source address which we'll use addr_none so => '00' (this will be overwritten when sent to correct address)
// concating all we'll get final bitstring => '011000' that we can append to builder
// Note: one can use 0x18 and append it as an 6-bit uint which will result in same outcome
b{011000} s,
// Now we parse and append the destination address
"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX" gt;smca 2drop Addr,
// Appending the amount
1 Gram,
// We now have extra_currencies which we'll have no, so a null dictionary will be needed => '0'
// ihr_fee and fwd_fee are zero which we'll encode as `VarUInteger 16`, it will be overwritten later
// created_lt and create_at fields will be zero so it could be overwritten later, they're 64-bit and 32-bit
// Now we go through message body:
// we append a zero bit to indicate there is no init field => '0'
// later we append another zero bit which indicates in-place serialization of the body
// All of these values are zeros so we sum the length (let's say its m) and write a m-bit 0 uint to builder
0 1 4 4 64 32 1 1 + + + + + + u,
// Now we parse msg_body cell to slice and append it to builder
msg_body <s s,
b>
// to be accessible by other contracts
dup constant internal_msg
2 boc+>B dup Bx. cr
The message we just created is an internal message and only can be sent by the contracts. If we want to send messages
from outside to the blockchain, we should create an inbound external message and send it to the blockchain.
For example, we can create an external message containing an internal message to our wallet's smart contract, so the
smart contract will read our internal message and send it to the other contract.
Here's an example of an inbound external message which contains the internal message we just created as the body
assuming the recipient contract will read the body and send it as a full raw message (with send_raw_message):
code
"Asm.fif" include
"TonUtil.fif" include
// this will import the internal message that we just created
// (it will be as internal_msg constant)
"internal.fif" include
<b
// Again we'll define CommonMsgInfo, we're gonna pick ext_in_msg_info$10 this time, so first two bits will be => '10'
// next is source address which we'll use addr_none so => '00' (from nowhere)
// now we need to append destination which should be MsgAddressInt, we'll use:
// addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt;
// and it will not be anycast so we'll get => '100'
// after concating all of them: '1000100'
b{1000100} s,
// Now we parse and append the destination address (workchain_id:int8 address:bits256)
"EQBoOEfPe5LUnrXTPuUFIK9i4kMsltc63k3vFGkmbPpXcGo5" gt;smca 2drop Addr,
// Then append import_fee
0 Gram,
// Now we go through message body:
// we append a zero bit to indicate there is no init field => '0'
// later we append a 1 bit which indicates body is a cell ref (otherwise the whoule message won't fit in 1023-bits) => '1'
b{01} s,
// Now we append internal_msg as a cell reference
internal_msg ref,
b>
2 boc+>B dup Bx. cr
These messages were just simple demonstrations and messages in real-life apps can get quite complicated. For example,
external messages should be signed and sent along with the signature so the smart contract can verify it's from the
authorized sender and execute it. Also, more complex control flows can be used in Fift, like conditions, loops, and ...
. As an example we could determine if a cell will be able to get serialized in-place and act accordingly automatically.
Leveraging these capabilities helps to generalize our Fift scripts. Much more complex messages and also Fift control
flows will be covered in the next sections.
gt;smca\u003c/code>\u003c/td>\n\u003ctd>\u003ccode>(S – x y z -1 or 0)\u003c/code>\u003c/td>\n\u003ctd>Unpacks a standard TON smart-contract address from its human-readable string representation \u003ccode>S\u003c/code>.\u003c/td>\n\u003c/tr>\n\u003c/tbody>\u003c/table>\n\u003ch2>Creating messages with Fift\u003c/h2>\n\u003cp>To interact with smart contracts on TON Network we mostly need to create and send messages to them. There are several\nways to do that, but Fift is the main and preferred way of creating messages.\u003c/p>\n\u003cp>Let's say we have a contract that requires an input body in the below format:\u003c/p>\n\u003cpre>\u003ccode>Internal message has the following structure:\n op_code:uint32 query_id:uint64 amount:(VarUInteger 16)\n destination:MsgAddress = InternalMsgBody;\n\u003c/code>\u003c/pre>\n\u003cp>To construct this with Fift:\u003c/p>\n\u003cpre>\u003ccode>\"Asm.fif\" include\n\"TonUtil.fif\" include\n<b 24 32 u, 0 64 u, 1 Gram,\n\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\" gt;smca 2drop Addr,\nb>\n2 boc+>B dup Bx. cr\n\u003c/code>\u003c/pre>\n\u003cp>What it does is:\u003c/p>\n\u003cul>\n\u003cli>Imports \u003ccode>Asm.fif\u003c/code> and \u003ccode>TonUtil.fif\u003c/code> libraries\u003c/li>\n\u003cli>Constructs an empty builder\u003c/li>\n\u003cli>Appends \u003ccode>24\u003c/code> as \u003ccode>op_code\u003c/code> (32-bit unsigned integer)\u003c/li>\n\u003cli>Appends \u003ccode>0\u003c/code> as \u003ccode>query_id\u003c/code> (64-bit unsigned integer)\u003c/li>\n\u003cli>Appends \u003ccode>1 nanoton\u003c/code> as \u003ccode>amount\u003c/code>\u003c/li>\n\u003cli>Parses address \u003ccode>EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\u003c/code> and stores it to builder as \u003ccode>destination\u003c/code>\nusing \u003ccode>x,y\u003c/code> (drops \u003ccode>z\u003c/code> and result) by invoking \u003ccode>Addr,\u003c/code> word that is defined in \u003ccode>TonUtil.fif\u003c/code>\u003c/li>\n\u003cli>Constructs cell from the builder\u003c/li>\n\u003cli>Writes the bag of cells to Bytes\u003c/li>\n\u003cli>Prints hex representation of the result and leaves the result at top of the stack.\u003c/li>\n\u003c/ul>\n\u003cp>Here is the execution of it with fift interpreter:\u003c/p>\n\u003cpre>\u003ccode>\"Asm.fif\" include\n ok\n\"TonUtil.fif\" include\n ok\n<b 24 32 u, 0 64 u, 1 Gram,\n ok\n\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\" gt;smca 2drop Addr,\n ok\nb>\n ok\n2 boc+>B dup Bx. cr\nB5EE9C7241010101003100005D0000001800000000000000001018006ED66A12E4F138D32C3F29C0E5FD68430E1077EFED9D97B342BDBCD35C5739A9EF4BC35F\n ok\n.s\nBYTES:B5EE9C7241010101003100005D0000001800000000000000001018006ED66A12E4F138D32C3F29C0E5FD68430E1077EFED9D97B342BDBCD35C5739A9EF4BC35F\n ok\n\u003c/code>\u003c/pre>\n\u003ch2>TonWeb: An Alternative Way\u003c/h2>\n\u003cp>\u003ca href=\"https://github.com/toncenter/tonweb/\" rel=\"noopener noreferrer\">TonWeb\u003c/a> is a JavaScript SDK for The Open Network. It comes with classes that ease\ninteracting with TON ecosystem. One of those is \u003ccode>Cell\u003c/code> class which can be used to create the bag of cells.\u003c/p>\n\u003cp>For example, the above example could be done in JS this way:\u003c/p>\n\u003cpre>\u003ccode class=\"language-javascript\">const TonWeb = require(\"tonweb\");\n\nconst Cell = TonWeb.boc.Cell;\nconst Address = TonWeb.utils.Address;\n\nlet cell = new Cell();\ncell.bits.writeUint(24, 32); // op_code\ncell.bits.writeUint(0, 64); // query_id\ncell.bits.writeCoins(1); // amount\nlet address = new Address(\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\"); // destination\ncell.bits.writeAddress(address);\nconsole.log(cell.print()); // print cell data like Fift\nlet bocBytes = cell.toBoc(false);\nbocBytes.then((res) => {\n console.log(Buffer.from(res).toString(\"hex\"))\n});\n\u003c/code>\u003c/pre>\n\u003cp>If we execute the script above, we get:\u003c/p>\n\u003cpre>\u003ccode class=\"language-bash\">$ node message.js\nx{0000001800000000000000001018006ED66A12E4F138D32C3F29C0E5FD68430E1077EFED9D97B342BDBCD35C5739A9_}\n\nb5ee9c7241010101003100005d0000001800000000000000001018006ed66a12e4f138d32c3f29c0e5fd68430e1077efed9d97b342bdbcd35c5739a9ef4bc35f\n\u003c/code>\u003c/pre>\n\u003ch2>Creating Full Messages\u003c/h2>\n\u003cp>What we discussed in two previous sections were just only message bodies, If we want to create complete messages, we\nshould pick the appropriate type of the message and construct it according to\nthe \u003ca href=\"https://github.com/ton-blockchain/ton/blob/master/crypto/block/block.tlb\" rel=\"noopener noreferrer\">\u003ccode>TL-B Schema\u003c/code>\u003c/a>. Messages have two types:\u003c/p>\n\u003cul>\n\u003cli>\u003cstrong>Internal Messages\u003c/strong>: messages that contracts send to each other on the blockchain\u003c/li>\n\u003cli>\u003cstrong>External Messages\u003c/strong>: messages that come from outside the blockchain (Messages from nowhere or Inbound External\nMessages) or go outside the blockchain (Messages to nowhere or Outbound External Messages)\u003c/li>\n\u003c/ul>\n\u003cp>Here is the \u003ccode>TL-B Schema\u003c/code> for \u003ccode>Message\u003c/code>:\u003c/p>\n\u003cpre>\u003ccode>message$_ {X:Type} info:CommonMsgInfo\n init:(Maybe (Either StateInit ^StateInit))\n body:(Either X ^X) = Message X;\n\nint_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool\n src:MsgAddressInt dest:MsgAddressInt \n value:CurrencyCollection ihr_fee:Grams fwd_fee:Grams\n created_lt:uint64 created_at:uint32 = CommonMsgInfo;\next_in_msg_info$10 src:MsgAddressExt dest:MsgAddressInt \n import_fee:Grams = CommonMsgInfo;\next_out_msg_info$11 src:MsgAddressInt dest:MsgAddressExt\n created_lt:uint64 created_at:uint32 = CommonMsgInfo;\n\u003c/code>\u003c/pre>\n\u003cp>To construct a full internal message we will have:\u003c/p>\n\u003cpre>\u003ccode>\"Asm.fif\" include\n\"TonUtil.fif\" include\n\n// message body:\n<b 24 32 u, 0 64 u, 1 Gram,\n\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\" gt;smca 2drop Addr,\nb> constant msg_body // we define the message body and store it in a constant named msg_body, so we can later use it\n\n<b \n // First we define CommonMsgInfo, we're gonna pick int_msg_info$0 so first bit will be => '0'\n // as schema follows, want to disable ihr, allow bounces and is not bounced itself so we'll have => '011'\n // next is source address which we'll use addr_none so => '00' (this will be overwritten when sent to correct address)\n // concating all we'll get final bitstring => '011000' that we can append to builder\n // Note: one can use 0x18 and append it as an 6-bit uint which will result in same outcome\nb{011000} s,\n// Now we parse and append the destination address\n\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\" gt;smca 2drop Addr,\n// Appending the amount\n 1 Gram,\n // We now have extra_currencies which we'll have no, so a null dictionary will be needed => '0'\n // ihr_fee and fwd_fee are zero which we'll encode as `VarUInteger 16`, it will be overwritten later\n // created_lt and create_at fields will be zero so it could be overwritten later, they're 64-bit and 32-bit\n // Now we go through message body:\n // we append a zero bit to indicate there is no init field => '0'\n // later we append another zero bit which indicates in-place serialization of the body\n // All of these values are zeros so we sum the length (let's say its m) and write a m-bit 0 uint to builder\n 0 1 4 4 64 32 1 1 + + + + + + u,\n // Now we parse msg_body cell to slice and append it to builder\n msg_body <s s,\nb>\n// to be accessible by other contracts\ndup constant internal_msg\n2 boc+>B dup Bx. cr\n\u003c/code>\u003c/pre>\n\u003cp>With TonWeb:\u003c/p>\n\u003cpre>\u003ccode class=\"language-javascript\">const TonWeb = require(\"tonweb\");\n\nconst Cell = TonWeb.boc.Cell;\nconst Address = TonWeb.utils.Address;\n\n// message body\nconst body = new Cell();\nbody.bits.writeUint(24, 32); // op_code\nbody.bits.writeUint(0, 64); // query_id\nbody.bits.writeCoins(1); // amount\nlet address = new Address(\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\"); // destination\nbody.bits.writeAddress(address);\n\n// message itself:\nconst message = new Cell();\nmessage.bits.writeUint(0x18, 6); // 0x18 = 0b011000\nmessage.bits.writeAddress(address);\nmessage.bits.writeCoins(1);\nmessage.bits.writeUint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);\nmessage.writeCell(body);\n\n\nconst bocBytes = message.toBoc(false);\nbocBytes.then((res) => {\n console.log(Buffer.from(res).toString(\"hex\"))\n});\n\u003c/code>\u003c/pre>\n\u003cp>The result will be:\u003c/p>\n\u003cpre>\u003ccode>b5ee9c724101010100620000bf62001bb59a84b93c4e34cb0fca70397f5a10c3841dfbfb6765ecd0af6f34d715ce6a0808000000000000000000000000000000001800000000000000001018006ed66a12e4f138d32c3f29c0e5fd68430e1077efed9d97b342bdbcd35c5739a97d492a80\n\u003c/code>\u003c/pre>\n\u003cp>The message we just created is an internal message and only can be sent by the contracts. If we want to send messages\nfrom outside to the blockchain, we should create an inbound external message and send it to the blockchain.\u003c/p>\n\u003cp>For example, we can create an external message containing an internal message to our wallet's smart contract, so the\nsmart contract will read our internal message and send it to the other contract.\u003c/p>\n\u003cp>Here's an example of an inbound external message which contains the internal message we just created as the body\nassuming the recipient contract will read the body and send it as a full raw message (with \u003ccode>send_raw_message\u003c/code>):\u003c/p>\n\u003cpre>\u003ccode>\"Asm.fif\" include\n\"TonUtil.fif\" include\n\n// this will import the internal message that we just created \n// (it will be as internal_msg constant)\n\"internal.fif\" include\n\n<b \n // Again we'll define CommonMsgInfo, we're gonna pick ext_in_msg_info$10 this time, so first two bits will be => '10'\n // next is source address which we'll use addr_none so => '00' (from nowhere)\n// now we need to append destination which should be MsgAddressInt, we'll use:\n// addr_std$10 anycast:(Maybe Anycast) workchain_id:int8 address:bits256 = MsgAddressInt;\n// and it will not be anycast so we'll get => '100'\n// after concating all of them: '1000100'\nb{1000100} s,\n// Now we parse and append the destination address (workchain_id:int8 address:bits256)\n\"EQBoOEfPe5LUnrXTPuUFIK9i4kMsltc63k3vFGkmbPpXcGo5\" gt;smca 2drop Addr,\n// Then append import_fee\n 0 Gram,\n // Now we go through message body:\n // we append a zero bit to indicate there is no init field => '0'\n // later we append a 1 bit which indicates body is a cell ref (otherwise the whoule message won't fit in 1023-bits) => '1'\n b{01} s, \n // Now we append internal_msg as a cell reference\n internal_msg ref,\nb>\n2 boc+>B dup Bx. cr\n\u003c/code>\u003c/pre>\n\u003cp>with TonWeb:\u003c/p>\n\u003cpre>\u003ccode class=\"language-javascript\">const TonWeb = require(\"tonweb\");\n\nconst Cell = TonWeb.boc.Cell;\nconst Address = TonWeb.utils.Address;\n\n// message body\nconst body = new Cell();\nbody.bits.writeUint(24, 32); // op_code\nbody.bits.writeUint(0, 64); // query_id\nbody.bits.writeCoins(1); // amount\nlet address = new Address(\"EQA3azUJcnicaZYflOBy_rQhhwg79_bOy9mhXt5priuc1EuX\"); // destination\nbody.bits.writeAddress(address);\n\n// message itself:\nconst message = new Cell();\nmessage.bits.writeUint(0x18, 6); // 0x18 = 0b011000\nmessage.bits.writeAddress(address);\nmessage.bits.writeCoins(1);\nmessage.bits.writeUint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1);\nmessage.writeCell(body);\n\nconst ext = new Cell();\next.bits.writeUint(0x44, 7); // 0x44 = 0b1000100\nlet naddr = new Address(\"EQBoOEfPe5LUnrXTPuUFIK9i4kMsltc63k3vFGkmbPpXcGo5\"); // destination\next.bits.writeAddress(naddr);\next.bits.writeCoins(0);\next.bits.writeUint(1, 2); // 1 = 0b01\next.refs.push(message);\n\nconst bocBytes = ext.toBoc(false);\nbocBytes.then((res) => {\n console.log(Buffer.from(res).toString(\"hex\"))\n});\n\u003c/code>\u003c/pre>\n\u003cp>The result will be:\u003c/p>\n\u003cpre>\u003ccode>b5ee9c7241010201008800014689001a0e11f3dee4b527ad74cfb941482bd8b890cb25b5ceb7937bc51a499b3e95dc010100bf62001bb59a84b93c4e34cb0fca70397f5a10c3841dfbfb6765ecd0af6f34d715ce6a0808000000000000000000000000000000001800000000000000001018006ed66a12e4f138d32c3f29c0e5fd68430e1077efed9d97b342bdbcd35c5739a9a3cca5b3\n\u003c/code>\u003c/pre>\n\u003cp>These messages were just simple demonstrations and messages in real-life apps can get quite complicated. For example,\nexternal messages should be signed and sent along with the signature so the smart contract can verify it's from the\nauthorized sender and execute it. Also, more complex control flows can be used in Fift, like conditions, loops, and ...\n. As an example we could determine if a cell will be able to get serialized in-place and act accordingly automatically.\u003c/p>\n\u003cp>Leveraging these capabilities helps to generalize our Fift scripts. Much more complex messages and also Fift control\nflows will be covered in the next sections.\u003c/p>\n","author":"Amin Rezaei","sourceUrl":"https://blog.ton.org/introduction-to-fift","archiveUrl":"https://web.archive.org/web/20240224221514/https://blog.ton.org/introduction-to-fift","readingTimeMin":16},"newer":{"slug":"ton-society-partner-twitter-spaces-huobi-x-ton-fanzee","title":"Partner Twitter Spaces #1: Huobi x TON","excerpt":"On September 5th at 09:00 (UTC), Steve Yun, a founding member of the TON Foundation, and spokesperson of Huobi held an energetic AMA session on Twitter Spaces for an hour.","category":"community","cover":"/media/8f9784ab0772e2d3.png","publishedAt":"2022-09-04T20:00:00.000Z"},"older":{"slug":"how-to-shard-your-ton-smart-contract-and-why-studying-the-anatomy-of-tons-jettons","title":"How to shard your TON smart contract and why - studying the anatomy of TON's Jettons","excerpt":"*Sharding* is a mature concept originating in [database design](https://en.wikipedia.org/wiki/Shard_(database_architecture)). It involves splitting and distributing one logical data set across multiple databases that share nothing and can be deployed across multiple servers. Simply put, sharding allows *horizontal scalability* - splitting data to distinct, independent pieces that can be processed in parallel.","category":"development","cover":null,"publishedAt":"2022-08-15T20:00:00.000Z"}},"dataUpdateCount":1,"dataUpdatedAt":1790698344636,"error":null,"errorUpdateCount":0,"errorUpdatedAt":0,"fetchFailureCount":0,"fetchFailureReason":null,"fetchMeta":null,"isInvalidated":false,"status":"success","fetchStatus":"idle"},"queryKey":[["tonBlog","bySlug"],{"input":{"slug":"introduction-to-fift"},"type":"query"}],"queryHash":"[[\"tonBlog\",\"bySlug\"],{\"input\":{\"slug\":\"introduction-to-fift\"},\"type\":\"query\"}]"},{"dehydratedAt":1790698344636,"state":{"data":{"today":52},"dataUpdateCount":1,"dataUpdatedAt":1790698344630,"error":null,"errorUpdateCount":0,"errorUpdatedAt":0,"fetchFailureCount":0,"fetchFailureReason":null,"fetchMeta":null,"isInvalidated":false,"status":"success","fetchStatus":"idle"},"queryKey":[["visitors","today"],{"type":"query"}],"queryHash":"[[\"visitors\",\"today\"],{\"type\":\"query\"}]"},{"dehydratedAt":1790698344636,"state":{"data":{"usd":1.53,"change24h":-5.086440953009061,"sparkline":[{"t":1790092800000,"p":1.4408684060374553},{"t":1790096400000,"p":1.4396411494036538},{"t":1790100000000,"p":1.4475337607702923},{"t":1790103600000,"p":1.4568069560181374},{"t":1790107200000,"p":1.452287645106675},{"t":1790110800000,"p":1.4484471414689921},{"t":1790114400000,"p":1.453051711691552},{"t":1790118000000,"p":1.4603608260136218},{"t":1790121600000,"p":1.472385436753103},{"t":1790125200000,"p":1.4603028646403715},{"t":1790128800000,"p":1.458608448071146},{"t":1790132400000,"p":1.464331918334693},{"t":1790136000000,"p":1.4653879894353095},{"t":1790139600000,"p":1.471694943435796},{"t":1790143200000,"p":1.4691261980725663},{"t":1790146800000,"p":1.473044053973757},{"t":1790150400000,"p":1.456681426884249},{"t":1790154000000,"p":1.4494826657566753},{"t":1790157600000,"p":1.4523015170212838},{"t":1790161200000,"p":1.4515314818206095},{"t":1790164800000,"p":1.4433365014677404},{"t":1790168400000,"p":1.4416515396250948},{"t":1790172000000,"p":1.4405944949624403},{"t":1790175600000,"p":1.4127013770945898},{"t":1790179200000,"p":1.39951646775128},{"t":1790182800000,"p":1.40902144780904},{"t":1790186400000,"p":1.407780355896114},{"t":1790190000000,"p":1.4095507139423826},{"t":1790193600000,"p":1.4087652063257183},{"t":1790197200000,"p":1.4062200858108416},{"t":1790200800000,"p":1.4124401082570612},{"t":1790204400000,"p":1.4178797189756467},{"t":1790208000000,"p":1.4127632451095815},{"t":1790211600000,"p":1.4111408768133453},{"t":1790215200000,"p":1.406309403228636},{"t":1790218800000,"p":1.4179377152936496},{"t":1790222400000,"p":1.4149034001915386},{"t":1790226000000,"p":1.4195568826489782},{"t":1790229600000,"p":1.424937671771278},{"t":1790233200000,"p":1.4266912347217},{"t":1790236800000,"p":1.4227889501162136},{"t":1790240400000,"p":1.410317776074687},{"t":1790244000000,"p":1.404835447468008},{"t":1790247600000,"p":1.406107540643504},{"t":1790251200000,"p":1.3979484300360556},{"t":1790254800000,"p":1.3992696210350524},{"t":1790258400000,"p":1.4115315242848576},{"t":1790262000000,"p":1.4147567173239837},{"t":1790265600000,"p":1.431364216648206},{"t":1790269200000,"p":1.437850934477613},{"t":1790272800000,"p":1.4211192096973986},{"t":1790276400000,"p":1.4248593685186928},{"t":1790280000000,"p":1.428318798651322},{"t":1790283600000,"p":1.4189114451930607},{"t":1790287200000,"p":1.4149527853328723},{"t":1790290800000,"p":1.4096951432278255},{"t":1790294400000,"p":1.4082135344576445},{"t":1790298000000,"p":1.405496785210913},{"t":1790301600000,"p":1.405345654359848},{"t":1790305200000,"p":1.4214619513548277},{"t":1790308800000,"p":1.40753704696215},{"t":1790312400000,"p":1.4093432955251692},{"t":1790316000000,"p":1.4101801824632056},{"t":1790319600000,"p":1.4049591786123927},{"t":1790323200000,"p":1.4074272783068753},{"t":1790326800000,"p":1.4194741864129308},{"t":1790330400000,"p":1.4213359207955518},{"t":1790334000000,"p":1.4229146101525343},{"t":1790337600000,"p":1.4255616691339825},{"t":1790341200000,"p":1.4325758300190714},{"t":1790344800000,"p":1.419009330460223},{"t":1790348400000,"p":1.4172007802050401},{"t":1790352000000,"p":1.4192117421150423},{"t":1790355600000,"p":1.4249043195599846},{"t":1790359200000,"p":1.420939341879199},{"t":1790362800000,"p":1.4311376608870023},{"t":1790366400000,"p":1.4362496751476954},{"t":1790370000000,"p":1.4381294249466408},{"t":1790373600000,"p":1.4260538368245523},{"t":1790377200000,"p":1.450116777395903},{"t":1790380800000,"p":1.4585708726124782},{"t":1790384400000,"p":1.448543198983591},{"t":1790388000000,"p":1.4459682769629247},{"t":1790391600000,"p":1.4470774500936125},{"t":1790395200000,"p":1.4469543954562243},{"t":1790398800000,"p":1.455347585024186},{"t":1790402400000,"p":1.4489156129736736},{"t":1790406000000,"p":1.4471152336082638},{"t":1790409600000,"p":1.4481576762893529},{"t":1790413200000,"p":1.4537241877620244},{"t":1790416800000,"p":1.4480916654786733},{"t":1790420400000,"p":1.456869471078002},{"t":1790424000000,"p":1.461492789256442},{"t":1790427600000,"p":1.4728946769097346},{"t":1790431200000,"p":1.475245855538882},{"t":1790434800000,"p":1.4758950760002507},{"t":1790438400000,"p":1.4833396933025187},{"t":1790442000000,"p":1.5355441585657865},{"t":1790445600000,"p":1.5330215721087135},{"t":1790449200000,"p":1.5622361802814806},{"t":1790452800000,"p":1.5558367554128345},{"t":1790456400000,"p":1.5640734415019508},{"t":1790460000000,"p":1.5707887386143462},{"t":1790463600000,"p":1.5654973100664415},{"t":1790467200000,"p":1.614164696815342},{"t":1790470800000,"p":1.5880689601722806},{"t":1790474400000,"p":1.5944525245914294},{"t":1790478000000,"p":1.5557209073022176},{"t":1790481600000,"p":1.550727477501848},{"t":1790485200000,"p":1.5703532919684842},{"t":1790488800000,"p":1.5817762943873466},{"t":1790492400000,"p":1.586408568437046},{"t":1790496000000,"p":1.585227369118685},{"t":1790499600000,"p":1.5861940145167979},{"t":1790503200000,"p":1.608801109147179},{"t":1790506800000,"p":1.6421573223772001},{"t":1790510400000,"p":1.6125939378067677},{"t":1790514000000,"p":1.6092049849624752},{"t":1790517600000,"p":1.5992491836848564},{"t":1790521200000,"p":1.5839693241245802},{"t":1790524800000,"p":1.6519102816321487},{"t":1790528400000,"p":1.66981024684438},{"t":1790532000000,"p":1.6607112654358327},{"t":1790535600000,"p":1.652380715354133},{"t":1790539200000,"p":1.6397928843049339},{"t":1790542800000,"p":1.6307168858772418},{"t":1790546400000,"p":1.6334025345736265},{"t":1790550000000,"p":1.627975999835562},{"t":1790553600000,"p":1.6309578947361185},{"t":1790557200000,"p":1.6089804483907848},{"t":1790560800000,"p":1.6272577181044168},{"t":1790564400000,"p":1.6056718879531953},{"t":1790568000000,"p":1.6064688005849603},{"t":1790571600000,"p":1.621113312038681},{"t":1790575200000,"p":1.627715471676055},{"t":1790578800000,"p":1.6080273071028508},{"t":1790582400000,"p":1.616480321292127},{"t":1790586000000,"p":1.626185624839791},{"t":1790589600000,"p":1.664294139379649},{"t":1790593200000,"p":1.676246277162915},{"t":1790596800000,"p":1.6573218634241702},{"t":1790600400000,"p":1.6605871270826462},{"t":1790604000000,"p":1.6828277543079644},{"t":1790607600000,"p":1.6130123743780513},{"t":1790611200000,"p":1.6081756693179912},{"t":1790614800000,"p":1.6538744110053094},{"t":1790618400000,"p":1.6407137733134174},{"t":1790622000000,"p":1.6469966328706704},{"t":1790625600000,"p":1.6028023474872135},{"t":1790629200000,"p":1.6018899222560719},{"t":1790632800000,"p":1.570437199997658},{"t":1790636400000,"p":1.5745105641559247},{"t":1790640000000,"p":1.572425434967619},{"t":1790643600000,"p":1.5644729082436633},{"t":1790647200000,"p":1.5531772972293847},{"t":1790650800000,"p":1.53989734772413},{"t":1790654400000,"p":1.5519304956461373},{"t":1790658000000,"p":1.558218387543837},{"t":1790661600000,"p":1.5526945250518662},{"t":1790665200000,"p":1.5795418746258125},{"t":1790668800000,"p":1.5895808989043008},{"t":1790672400000,"p":1.5879426071990643},{"t":1790676000000,"p":1.586482375469687},{"t":1790679600000,"p":1.5732314769064384},{"t":1790683200000,"p":1.5812612289463843},{"t":1790686800000,"p":1.5533729773114582},{"t":1790690400000,"p":1.551656426611582},{"t":1790694000000,"p":1.5468954667453945},{"t":1790698210000,"p":1.5320393080102555}],"ohlc":[{"t":1790092800000,"o":1.42,"h":1.45,"l":1.42,"c":1.44},{"t":1790107200000,"o":1.44,"h":1.47,"l":1.43,"c":1.45},{"t":1790121600000,"o":1.45,"h":1.48,"l":1.45,"c":1.47},{"t":1790136000000,"o":1.47,"h":1.48,"l":1.46,"c":1.47},{"t":1790150400000,"o":1.47,"h":1.48,"l":1.45,"c":1.46},{"t":1790164800000,"o":1.46,"h":1.46,"l":1.44,"c":1.44},{"t":1790179200000,"o":1.44,"h":1.45,"l":1.4,"c":1.4},{"t":1790193600000,"o":1.4,"h":1.41,"l":1.39,"c":1.41},{"t":1790208000000,"o":1.41,"h":1.42,"l":1.41,"c":1.41},{"t":1790222400000,"o":1.41,"h":1.42,"l":1.4,"c":1.41},{"t":1790236800000,"o":1.41,"h":1.43,"l":1.41,"c":1.42},{"t":1790251200000,"o":1.42,"h":1.43,"l":1.4,"c":1.4},{"t":1790265600000,"o":1.4,"h":1.43,"l":1.4,"c":1.43},{"t":1790280000000,"o":1.43,"h":1.44,"l":1.42,"c":1.43},{"t":1790294400000,"o":1.43,"h":1.43,"l":1.41,"c":1.41},{"t":1790308800000,"o":1.41,"h":1.43,"l":1.4,"c":1.41},{"t":1790323200000,"o":1.41,"h":1.41,"l":1.4,"c":1.41},{"t":1790337600000,"o":1.41,"h":1.43,"l":1.41,"c":1.43},{"t":1790352000000,"o":1.43,"h":1.44,"l":1.41,"c":1.42},{"t":1790366400000,"o":1.42,"h":1.44,"l":1.42,"c":1.44},{"t":1790380800000,"o":1.44,"h":1.46,"l":1.43,"c":1.46},{"t":1790395200000,"o":1.46,"h":1.46,"l":1.44,"c":1.45},{"t":1790409600000,"o":1.45,"h":1.47,"l":1.44,"c":1.45},{"t":1790424000000,"o":1.45,"h":1.46,"l":1.45,"c":1.46},{"t":1790438400000,"o":1.46,"h":1.48,"l":1.46,"c":1.48},{"t":1790452800000,"o":1.48,"h":1.59,"l":1.48,"c":1.56},{"t":1790467200000,"o":1.56,"h":1.62,"l":1.55,"c":1.62},{"t":1790481600000,"o":1.61,"h":1.63,"l":1.55,"c":1.55},{"t":1790496000000,"o":1.55,"h":1.62,"l":1.55,"c":1.59},{"t":1790510400000,"o":1.59,"h":1.65,"l":1.58,"c":1.61},{"t":1790524800000,"o":1.61,"h":1.65,"l":1.58,"c":1.65},{"t":1790539200000,"o":1.65,"h":1.72,"l":1.64,"c":1.64},{"t":1790553600000,"o":1.64,"h":1.64,"l":1.62,"c":1.63},{"t":1790568000000,"o":1.63,"h":1.65,"l":1.6,"c":1.61},{"t":1790582400000,"o":1.61,"h":1.65,"l":1.56,"c":1.62},{"t":1790596800000,"o":1.62,"h":1.72,"l":1.61,"c":1.66},{"t":1790611200000,"o":1.66,"h":1.69,"l":1.59,"c":1.61},{"t":1790625600000,"o":1.61,"h":1.68,"l":1.59,"c":1.6},{"t":1790640000000,"o":1.6,"h":1.61,"l":1.56,"c":1.57},{"t":1790654400000,"o":1.57,"h":1.58,"l":1.53,"c":1.55},{"t":1790668800000,"o":1.55,"h":1.59,"l":1.54,"c":1.59},{"t":1790683200000,"o":1.59,"h":1.6,"l":1.56,"c":1.58}]},"dataUpdateCount":1,"dataUpdatedAt":1790698327137,"error":null,"errorUpdateCount":0,"errorUpdatedAt":0,"fetchFailureCount":0,"fetchFailureReason":null,"fetchMeta":null,"isInvalidated":false,"status":"success","fetchStatus":"idle"},"queryKey":["gram-price"],"queryHash":"[\"gram-price\"]"}]}}