Стековый язык Fift создан для разработки смарт-контрактов в блокчейне TON
Синтаксис языка Fift следующий. Код состоит из слов, как правило, разделённых пробелами или переводами строк (частный случай: некоторые слова не требуют разделителя после себя). Любое слово — это регистро-зависимая последовательность символов, которой соответствует некоторое определение (грубо говоря, то, что интерпретатор должен сделать, когда встречает это слово). Если определения слова нет, интерпретатор пытается распарсить его как число и положить на стек. Числа - 257-битные целые, дробных чисел нет, они сразу превращаются в пару целых, образующих числитель и знаменатель рациональной дроби.
Слова, как правило, взаимодействуют со значениями, лежащими на верхушке стека. Отдельный тип слов — префиксный — использует не стек, а последующие за ними символы из исходного файла. Например, так реализованы строковые литералы — символ «кавычка» (") является префиксным словом, которое ищет следующую (закрывающую) кавычку, и помещает строку между ними на стек. Подобным же образом ведут себя однострочные (//) и многострочные (/*) комментарии.
На этом почти всё внутреннее устройство языка заканчивается. Всё остальное (включая управляющие конструкции) определено как слова (либо внутренние, такие как арифметические операции и определение новых слов; либо определённые в «стандартной библиотеке» Fift.fif, которая лежит в папке crypto/fift в исходниках).
Простой пример программы на Fift:
{ dup =: x dup * =: y } : setxy
3 setxy x . y . x y + .
7 setxy x . y . x y + .
В первой строчке определяется новое слово setxy (обратите внимание на префикс {, который создает блок до закрывающего } и префикс :, который собственно определяет слово). setxy берёт число с вершины стека, определяет (или переопределяет) его как глобальную константу x, а квадрат этого числа — как константу y (учитывая, что значения констант можно переопределять, я бы скорее назвал их переменными, но я следую именованию в языке).
В следующих двух строчках на стек кладётся число, вызывается setxy, затем выводятся значения констант x, y (для вывода используется слово .), обе константы помещаются на стек, суммируются и результат тоже выводится. В результате мы увидим:
(Строчку «ok» выводит интерпретатор, когда заканчивает обрабатывать текущую строку в интерактивном режиме ввода)
Код на языке Fift для создания смарт-контракта в TON
"Asm.fif" include
-1 constant wc // create a wallet in workchain -1 (masterchain)
// Create new simple wallet
<{ SETCP0 DUP IFNOTRET INC 32 THROWIF // return if recv_internal, fail unless recv_external
512 INT LDSLICEX DUP 32 PLDU // sign cs cnt
c4 PUSHCTR CTOS 32 LDU 256 LDU ENDS // sign cs cnt cnt' pubk
s1 s2 XCPU // sign cs cnt pubk cnt' cnt
EQUAL 33 THROWIFNOT // ( seqno mismatch? )
s2 PUSH HASHSU // sign cs cnt pubk hash
s0 s4 s4 XC2PU // pubk cs cnt hash sign pubk
CHKSIGNU // pubk cs cnt ?
34 THROWIFNOT // signature mismatch
ACCEPT
SWAP 32 LDU NIP
DUP SREFS IF:<{
8 LDU LDREF // pubk cnt mode msg cs
s0 s2 XCHG SENDRAWMSG // pubk cnt cs ; ( message sent )
}>
ENDS
INC NEWC 32 STU 256 STU ENDC c4 POPCTR
}>c
// code
<b 0 32 u,
newkeypair swap dup constant wallet_pk
"new-wallet.pk" B>file
B,
b> // data
// no libraries
<b b{00110} s, rot ref, swap ref, b> // create StateInit
dup ."StateInit: " <s csr. cr
dup hash dup constant wallet_addr
."new wallet address = " wc . .": " dup x. cr
wc over 7 smca>$ type cr
256 u>B "new-wallet.addr" B>file
<b 0 32 u, b>
dup ."signing message: " <s csr. cr
dup hash wallet_pk ed25519_sign_uint rot
<b b{1000100} s, wc 8 i, wallet_addr 256 u, b{000010} s, swap <s s, b{0} s, swap B, swap <s s, b>
dup ."External message for initialization is " <s csr. cr
2 boc+>B dup Bx. cr
"new-wallet-query.boc" tuck B>file
."(Saved to file " type .")" cr
Данный файл предназначен для создания смарт-контракта — он будет помещён в файл new-wallet-query.boc после выполнения. Обратите внимание, что тут используется ещё один, ассемблерный язык для TON Virtual Machine (на нём я не буду останавливаться подробно), инструкции которого и будут помещены в блокчейн.
Таким образом, ассемблер для TVM написан на Fift — исходники этого ассемблера находятся в файле crypto/fift/Asm.fif и подключаются в начале приведённого выше куска кода.
По материалам пользователя
deNULL