Комиссии Free TON являются составными из нескольких типов платежей, выплачиваемых за транзакцию на различных этапах выполнения. Каждый тип платежей вычисляется по определенным формулам, которые здесь тщательно рассматривать не имеет смысла, достаточно просто ознакомиться с каждым типом платежа в общем (за исключением формулы расчета storage_fees, которая будет рассмотрена подробней). В целом комиссия за транзакцию состоит из суммы:
transaction_fee = inbound_external_message_fee + storage_fees + gas_fees + total_action_fees + outbound_internal_messages_fee
inbound_external_message_fee — эта часть уплачивается если в транзакцию импортируется входящее внешнее сообщение.
outbound_internal_messages_fee - это платеж за внутренние сообщения, сгенерированные в транзакции.
Оба этих типа платежа вычисляются по специальной формуле.
gas_fees — плата за газ.
total_action_fees — плата за действие по отправке сообщений, состоит из сборов за все внешние и часть внутренних сообщений.
Если во время транзакции не выполняется действий, то и total_action_fees отсутствует.
Аналогично gas_fees также может отсутствовать, если в транзакции не инициализирован этап вычислений TVM.
И это еще не все: inbound_external_message_fee и outbound_internal_messages_fee также могут отсутствовать в зависимости от характера транзакции.
Но в транзакционные издержки всегда входит storage_fees — плата за хранение.
Это и есть самый интересный тип оплаты за транзакции. Данный тип платежа является оплатой за этап хранения транзакции (транзакции в Free TON имеют этап хранения) и взимается с баланса аккаунта. Плата взимается за период между транзакциями и расчитывается по формуле:
storage fee = ceil ((account.bits * global_bit_price + account.cells * global_cell_price) * period / 2 ^ 16)
account.bits и account.cells — количество битов и ячеек в структуре аккаунта.
global_bit_price и global_cell_price — цены за хранение 1 бита и за хранение 1 ячейки. Это параметры глобальной конфигурации, которые могут быть изменены только голосованием валидаторов.
Самым интересным множителем является period — время в секундах с момента предыдущей платы за хранение. Чем больше period, тем выше storage_fees.
Поскольку данный тип платы взимается с баланса аккаунта, то в случае его недостаточности для оплаты storage_fees, аккаунт замораживается, баланс снижается до нуля, а недостающая сумма хранится на аккаунте как долг в виде отрицательного числа. Это такой пограничный случай, который не так интересен, как транзакции на аккаунты, содержащие балансы, заведомо превышающие возможную величину storage_fees.
Если сама входящая транзакция на аккаунт содержит сумму кристаллов, меньшую, чем плата за хранение, то баланс аккаунта уменьшится и тем больше, чем больше прошло времени с момента предыдущей входящей или исходящей транзакции (не забываем о множителе period).
Конечно, все это весьма незначительные суммы, но сам факт внешнего влияния на баланс аккаунта в сторону его уменьшения является довольно интересной особенностью сети Free TON. Сравните с Bitcoin: баланс может как увеличиваться, так и уменьшаться по воле владельца адреса/кошелька, по внешнему воздействию может увеличиваться, но никогда — уменьшаться.
Для наглядности возьмем готовый пример расчета storage_fees для хранения 1КВ из docs.ton.dev и предположим, что такая плата существовала бы в Bitcoin. Итак, баланс BTC лежал на адресе нетронутым 10 лет, до момента пока на него не отправили 1KB данных (какое-то микроскопическое число сатох):
Результат получится в 1/10 сатох (у Bitcoin 8 десятичных, а не 9 как у Free TON), поэтому последнюю цифру просто откинем. В любом случае в применении к Bitcoin этот расчет весьма условный, вымышленный только для демонстрации.
period = 10 лет = 315576000 сек.
account.bits = 8192
global_bit_price = 1
account.cells = 8192/1023 = 9
global_cell_price = 500
Цифры взяты из примера с docs.ton.dev без изменений. account.cells рассчитан как account.bits, поделенный на максимальное количество бит в ячейке, и округлен вверх до целого. (account.cells может значительно отличаться для разных типов данных).
storage fee = ceil((8192 * 1 + 9 * 500) * 315576000 / 65536) = 61115884 = 0.06111588 BTC
Таким образом, этот умозрительный пример показывает в «увеличенном масштабе» как входящая транзакция может влиять на баланс через storage fee.
В заключение можно сделать несколько выводов:
- Не занимайтесь стейкингом мелких сумм.
- Трейдинг профитнее, чем hodl (но не для всех). Особенно с учетом идущего в настоящее время конкурса трейдеров: Traders Contest Proposal
Эти два умозаключения и так являются общеизвестными истинами, чего не скажешь о следующем откровении:
- Не каждая входящая транзакция увеличивает баланс аккаунта. Хотя это экономически невыгодно отправителю, но он может руководствоваться более сильными мотивами. Например, входящие пылевые транзакции от мужа вашей любовницы уменьшают ваш баланс, если вы здоровяк, и у него просто не хватает сил, чтобы набить вам ...лицо))