Solidity vs FunC
Введение
В разработке смарт-контрактов используют языки вроде Solidity для Ethereum и FunC для TON. Solidity — это объектно-ориентированный язык высокого уровня со строгой типизацией, отчасти вдохновлённый C++, Python и JavaScript. Он спроектирован именно для разработки смарт-контрактов, которые выполняются на блокчейн-платформе Ethereum.
FunC также является языком высокого уровня, используемым для программирования смарт-контрактов на блокчейне TON. Он объектно-ориентированный, C-подобный, статически типизированный.
В следующих разделах кратко проанализируем различные аспекты этих языков: типы данных, хранилища, функции, структуры управления потоком, словари (hashmaps).
Различия Solidity и FunC
Схема хранения
Solidity
Solidity обеспечивает плоскую модель хранения: это значит, что все переменные состояния хранятся в едином непрерывном блоке памяти, его называют хранилищем. Там всё хранится в формате «ключ-значение», где каждый ключ является 256-битным целым числом, представляющим собой номер ячейки хранения, а каждое значение — это 256-битное слово, хранящееся в этой ячейке. Ячейки нумеруются последовательно, начиная с нуля, и в каждой из них может храни ться только одно слово. Solidity позволяет разработчику сформировать структуру хранилища, используя ключевое слово «storage» для определения переменных состояния. Порядок, в котором задаются переменные, определяет их положение в хранилище.
FunC
Данные постоянного хранилища в блокчейне TON хранятся в виде ячеек. Ячейки играют роль памяти в стековой TVM. Чтобы прочитать данные из ячейки, надо преобразовать её в тип slice, а затем получить биты данных и ссылки на другие ячейки, считывая их из этого «слайса». Для записи данных надо сохранить биты данных и необходимые ссылки на другие ячейки в объект типа builder, а затем создать из этого builder новую ячейку.
Типы данных
Solidity
Solidity включает следующие базовые типы данных:
- Целые числа: со знаком и беззнаковые (signed/unsigned integers)
- Булевы значения (boolean)
- Адреса (addresses) — используются для хранения адресов кошельков Ethereum или смарт-контрактов, обычно около 20 байт. Тип адреса может быть дополнен ключевым словом
payable
, что отличается его использованием только для адресов кошельков, а также функциями transfer и send. - Массивы байтов (byte arrays) — объявляются ключевым словом bytes, представляют собой массив фиксированного размера, используемый для хранения предопределенного количества байтов до 32, обычно задаются вместе с ключевым словом.
- Литералы (literals) — неизменяемые значения, такие как адреса, рациональные и целые числа, строки, юникод и шестнадцатеричные числа, которые могут храниться в переменной.
- Перечисления (enums)
- Массивы (arrays) — фиксированные или динамические
- Структуры (structs)
- Маппинги (mappings)
FunC
В случае FunC основными типами данных являются:
- Целые числа (integers)
- Ячейка (cell) — базовая для TON непрозрачная структура данных, которая содержит до 1023 бит и до 4 ссылок на другие ячейки
- Slice и Builder — специальные объекты для чтения и записи в ячейки
- Continuation — еще одна разновидность ячейки, которая содержит готовый к выполнению байт-код TVM
- Кортежи (tuple) — упорядоченная коллекция, в которой может быть до 255 компонентов с произвольными типами значений, возможно, различными.
- Тензоры (tensor) — это упорядоченная коллекция, готовая к массовому присвоению вроде такого:
(int, int) a = (2, 4)
. Частным случаем тензорного типа является()
. Он означает, что функция не возвращает никакого значения или не имеет аргументов.
В настоящее время FunC не поддерживает определение пользовательских типов. Можете прочитать больше о типах на странице Statements.
Объявление и использование переменных
Solidity
Solidity — это язык со статической типизацией, то есть тип каждой переменной должен быть указан при её объявлении.
uint test = 1; // Declaring an unsigned variable of integer type
bool isActive = true; // Logical variable
string name = "Alice"; // String variable
FunC
FunC — более абстрактный и функционально-ориентированный язык. Он поддерживает динамическую типизацию и функциональный стиль программирования.
(int x, int y) = (1, 2); // A tuple containing two integer variables
var z = x + y; // Dynamic variable declaration
Прочитать можно на странице Statements.