Компания RSquad, участвующая в развитии технологии Free TON с момента запуска проекта, накопила достаточный опыт разработки под Free TON, который будет полезен всем, кто интересуется темой блокчейна и планирует профессионально развиваться в этом направлении. Своим опытом делится автор статьи — лидер blockchain-практики RSquad, Алексей Поляков.
Отличия от других блокчейнов
У Free TON есть особенности, которые необходимо учитывать при реализации бизнес-логики. Во-первых, это асинхронный блокчейн, что сразу же меняет подход к разработке, а во-вторых, здесь все является смарт-контрактом.
Например, для хранения токенов нужна не только пара ключей (публичный и секретный), но и задеплоенный смарт-контракт кошелька.
Дело в том, что каждый адрес содержит какое-то количество кристаллов, однако для изменения баланса по этому адресу должен быть код, который может обработать эту задачу. Именно этот код и называется смарт-контракт.
Стоит отметить, что сам адрес вычисляется исходя из кода смарт-контракта и каких-то дополнительных данных, причем эта комбинация уникальна. Дважды задеплоить (развернуть) контракт по одному и тому же адресу нельзя. Уникальность адресов дает нам возможность воспринимать блокчейн Free TON как распределенный реестр, хранящий информацию о смарт-контрактах.
Разработку смарт-контрактов можно вести на C++ или на Solidity. Пример для статьи написан на Solidity.
В этой статье мы рассмотрим смарт-контракты Free TON, расскажем, как они могут взаимодействовать между собой, и продемонстрируем это на примере.
В блокчейне Free TON основой является смарт-контракт
Это компьютерный алгоритм, исполняемый виртуальной машиной блокчейна. Смарт-контракт отслеживает и обеспечивает исполнение обязательств сторонами-участниками контракта.
По сути, каждый смарт-контракт описывает класс. Если рассматривать эту ситуацию с точки зрения ООП, то, когда контракт деплоится в блокчейн, создается инстанс класса.
В контракте хранятся данные, а также присутствует бизнес-логика. С контрактами можно взаимодействовать вне блокчейна через SDK.
С другой стороны, смарт-контракты взаимодействуют между собой. Любое их взаимодействие осуществляется посредством сообщений (message).
Взаимодействие смарт-контрактов

При получении входящего сообщения, которое не вызвало ошибок в процессе обработки, создается транзакция. В результате генерируются исходящие сообщения к другим контрактам. Соответственно, можно создавать крупные проекты с большим количеством контрактов и сложными взаимодействиями между ними.
Сообщение
Состоит из заголовка header и полезной нагрузки payload.
Хедер бывает трех типов, в соответствии с которыми сообщение будет обработано:
internal message — внутреннее сообщение;
external in message — внешнее входящее сообщение;
external outmessage — внешнее исходящее сообщение.
Все они содержат адрес источника — src и адрес назначения — dest, имеют логическое время создания created_lt и unixtime created_at.
Internal (внутреннее) сообщение, помимо этого, содержит некоторое value в TON Crystal или других валютах, параметр bounce, и флаги, которые устанавливают порядок оплаты действий в блокчейне.
Payload произвольный, но должен соответствовать смарт-контракту, на адрес которого отправлено сообщение. Иначе смарт-контракт не сможет его обработать и выдаст ошибку.
При компиляции смарт-контракта создается два файла: .abi и .tvc. Все функции, которые реализованы в смарт-контракте, описаны в файле .abi.
Транзакция
Это результат выполнения контракта. Обычно она генерируется одним входящим сообщением (внешним или внутренним) и в результате может генерировать несколько исходящих сообщений (внешних или внутренних). Транзакция может быть успешной или прерванной.
В блокчейн Free TON отправка и обработка сообщений оплачиваются
Мы оплачиваем, в том числе, и хранение данных внутри блокчейна. Чтобы контролировать оплату internal messages (внутренних сообщений), при отправке нужны флаги. По сути, речь идет о битовой маске.
Возможные значения:
0 — переводит средства, равные значению value, по назначению. Комиссия за отправку вычитается из value.
128 — содержит весь остаток текущего смарт-контракта. Значение value игнорируется. Баланс контракта будет равен нулю.
64 — переносит средства, равные значению value и всему оставшемуся значению входящего сообщения.
Флаг параметра также можно изменить:
flag + 1 — отправитель желает оплачивать комиссию за перевод отдельно от баланса контракта.
flag + 2 —любые ошибки, возникающие при обработке этого сообщения на этапе действия, следует игнорировать.
flag + 32 —текущий счет должен быть уничтожен, если его результирующий баланс равен нулю.
Пример: flag: 128 + 32 используется для отправки всего баланса и разрушения контракта.
Рассмотрим простой пример
Возьмем два контракта, которые реализуют один интерфейс.
В этом примере намеренно реализован интерфейс в двух вариантах, чтобы было очевидно, каким образом работают вызовы методов смарт-контрактов. Для вызова функции важна не реализация, а интерфейс, т.е. название функции, ее параметры и возвращаемые значения.
Первый контракт ClassA может увеличивать аккумулятор _accum, в соответствии с типом переменной, но не может за один раз прибавить к себе значение большее, чем лимит _limit.
Второй контракт ClassB, помимо этого, имеет ограничение по емкости _capacity аккумулятора. Для простоты значения лимита _limit и емкость _capacity задаются в конструкторе.
Метод send() может быть вызван любым способом как и метод accept(), т.к. они оба публичные, но реализация такова, что при вызове метода send() посылается internal message с параметрами, в том числе и флагами, отвечающими за то, как будет оплачен этот вызов.


IClass — общий интерфейс

ClassA — первая реализация

ClassB — вторая реализация

Errors — константы ошибок

Желаем удачи в разработке
Этот пример может помочь любому начинающему разработку смарт-контрактов в блокчейне Free TON. Мы дали подробный разбор для понимания основ. Надеемся, что с помощью этого материала новички быстрее сделают первые шаги в разработке проектов на Free TON и присоединятся к сообществу.
Еще больше информации можно найти здесь.