TVM: Стековая Машина
TVM (TON Virtual Machine) — это движок, исполняющий код каждого смарт-контракта в сети TON. Понимание стековой архитектуры TVM помогает писать более эффективный код и отлаживать сложные ошибки. Это как знание устройства двигателя для автогонщика: можно ездить и без этого знания, но для победы в гонке (оптимизации газа) оно необходимо.
TVM (TON Virtual Machine) — виртуальная машина TON, исполняющая смарт-контракты. Как и EVM в Ethereum, TVM — стековая машина, но с ключевыми отличиями в типах данных.
Основы стековой машины
TVM оперирует стеком — структурой данных LIFO (Last In, First Out). Инструкции берут аргументы с вершины стека и помещают результат обратно.
Пример: сложение 3 + 5
PUSH 3 стек: [3]
PUSH 5 стек: [3, 5]
ADD стек: [8] ← результат на вершине
Элементы стека в TVM нумеруются от вершины: s0 (вершина), s1 (следующий), s2 и т.д.
Интерактивная визуализация
Рассмотрим реальную TVM-программу: отправка TON с контракта.
Типы данных TVM
В отличие от EVM (только 256-бит слова), TVM поддерживает несколько типов:
| Тип | Описание | Пример |
|---|---|---|
| Integer | 257-бит знаковое целое | Балансы, счётчики, адреса |
| Cell | Неизменяемая ячейка данных (до 1023 бит + 4 ссылки) | Хранение данных контракта |
| Slice | Курсор для чтения данных из Cell | Разбор входящего сообщения |
| Builder | Буфер для создания новой Cell | Формирование исходящего сообщения |
| Continuation | ”Замороженное” вычисление | Условия, циклы, обработка ошибок |
| Tuple | Упорядоченная коллекция значений | Возврат нескольких значений |
| Null | Пустое значение | Отсутствие данных |
TON vs Ethereum: Типы данных виртуальной машины
EVM работает только с 256-битными словами. Все данные (адреса, числа, байты) — это 32-байтные значения. TVM богаче: поддерживает ячейки, слайсы, билдеры, продолжения. Это делает TVM мощнее, но и сложнее.
EVM: Stack, Memory, StorageОсновные инструкции TVM
Стековые операции
| Инструкция | Действие |
|---|---|
PUSH sN | Копирует элемент sN на вершину стека |
POP sN | Удаляет вершину и помещает в позицию sN |
XCHG s0, sN | Меняет местами вершину и элемент sN |
DROP | Удаляет вершину стека |
DUP | Дублирует вершину стека |
NIP | Удаляет s1 (второй элемент) |
Арифметика
| Инструкция | Действие |
|---|---|
ADD | s0 = s1 + s0 |
SUB | s0 = s1 - s0 |
MUL | s0 = s1 * s0 |
DIV | s0 = s1 / s0 |
MOD | s0 = s1 % s0 |
INC | s0 = s0 + 1 |
Работа с ячейками
| Инструкция | Действие |
|---|---|
NEWC | Создаёт новый Builder |
ENDC | Завершает Builder → Cell |
STSLICE | Записывает Slice в Builder |
STGRAMS | Записывает количество TON (VarUInteger) |
STU N | Записывает N-битное беззнаковое число |
CTOS | Преобразует Cell → Slice |
LDU N | Читает N бит из Slice как unsigned int |
Отправка сообщений
| Инструкция | Действие |
|---|---|
SENDRAWMSG | Отправить raw message (Cell + mode) |
RAWRESERVE | Зарезервировать TON на балансе |
Cell, Slice, Builder: рабочий цикл
Работа с данными в TVM следует паттерну:
1. CTOS — Cell → Slice (для чтения)
2. LDU, LDSLICE, LDGRAMS — читаем данные из Slice
3. NEWC — создаём Builder (для записи)
4. STU, STSLICE, STGRAMS — записываем данные в Builder
5. ENDC — Builder → Cell (готово)
Это похоже на сериализацию/десериализацию: Slice для чтения (десериализация), Builder для записи (сериализация).
TVM и языки высокого уровня
Разработчики не пишут TVM-инструкции вручную. Компиляторы Tact и FunC генерируют TVM bytecode:
Tact код: TVM инструкции:
──────────── ────────────────
send(SendParameters{ PUSHINT 1000000000
to: addr, PUSHINT 0
value: ton("1"), NEWC
bounce: true, STSLICE addr
body: ... STGRAMS
}); ENDC
PUSHINT 64
SENDRAWMSG
Понимание TVM помогает оптимизировать gas и отлаживать контракты на низком уровне.
Частые ошибки
- Путают стек TVM со стеком вызовов: TVM использует стек для хранения операндов и результатов операций, а не для управления вложенными вызовами функций.
- Не понимают разницу между stack и registers (c0-c7): регистры TVM хранят контекст исполнения (код, данные, газ), а стек используется для вычислений.
- Забывают, что TVM работает с 257-битными целыми числами, а не с 256-битными как в EVM, что влияет на диапазон значений и совместимость.
- Игнорируют газовую стоимость стековых операций при оптимизации, хотя перестановки элементов стека (SWAP, XCHG) тоже стоят газ.
Проверка знанийЧем TVM принципиально отличается от EVM в плане типов данных на стеке?
Check Your Understanding
Finished the lesson?
Mark it as complete to track your progress
Войдите чтобы оценить урок