Skip to main content
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Транзакция Solana — это список инструкций, исполняемых атомарно. Понимание структуры транзакции — инструкции, аккаунты, подписанты, бюджет вычислений — необходимо для разработки, отладки или оптимизации чего-либо с Raydium. На этой странице рассматривается эта структура, лимиты, которые её ограничивают, и то, как две категории комиссий (сетевые комиссии Solana, комиссии протокола Raydium) складываются в реальном своре.

Анатомия транзакции

Транзакция Solana состоит из трёх основных компонентов:
  • Message: упорядоченный список инструкций, аккаунты, на которые они ссылаются, и свежий блокхеш.
  • Signatures: по одной для каждого подписанта, подтверждающие авторизацию транзакции.
  • Recent blockhash: доказывает, что транзакция свежая; транзакции с устаревшими блокхешами (старше 150 слотов) отклоняются.

Инструкции

Инструкция задаёт:
  • program_id — программу для вызова.
  • accounts — аккаунты (и их флаги записываемости/подписанта), которые может задействовать программа.
  • data — непрозрачные байты, которые программа интерпретирует.
Одна транзакция может содержать несколько инструкций. Они исполняются по порядку; если любая терпит неудачу, все предыдущие инструкции откатываются (атомарно). Типичная транзакция своппа Raydium включает:
  1. ComputeBudget::SetComputeUnitLimit — увеличение лимита CU по умолчанию.
  2. ComputeBudget::SetComputeUnitPrice — установка приоритетной комиссии.
  3. Опционально CreateAssociatedTokenAccount — создание выходного ATA, если у пользователя его нет.
  4. Raydium::SwapBaseInput — выполнение своппа.
  5. Опционально CloseAccount — закрытие обёрнутого SOL ATA.
SDK автоматически упаковывает эти инструкции через raydium.trade.swap().

Аккаунты в транзакциях

Каждый аккаунт, задействованный любой инструкцией в транзакции, должен быть указан в ключах аккаунтов транзакции. Каждый аккаунт помечается:
  • Подписант / не подписант: должен ли владелец аккаунта подписать транзакцию?
  • Записываемый / только для чтения: может ли транзакция изменять аккаунт?
Runtime переполняет эти флаги: программа, пытающаяся писать в не записываемый аккаунт, терпит неудачу, и runtime отклоняет транзакции с отсутствующими требуемыми подписантами. Для своппа CPMM список аккаунтов содержит примерно 13 записей (см. solana-fundamentals/account-model). Своппы CLMM с несколькими пересечениями tick array могут иметь 20+.

Лимит размера транзакции

Solana ограничивает транзакции 1232 байтами включая подписи, message и заголовки. Это наиболее распространённое препятствие для сложных транзакций — CLMM Raydium с много-хоп маршрутизацией регулярно упирается в этот лимит. Разбор типичного своппа Raydium размером ~1000 байт:

Таблицы поиска адресов (ALTs)

ALT позволяют транзакции ссылаться на аккаунты через однобайтовый индекс в опубликованную таблицу вместо полного 32-байтового публичного ключа. Это резко сжимает транзакцию:
  • Транзакция со ссылками на 20 аккаунтов напрямую: ~640 Б публичных ключей.
  • Та же транзакция с использованием ALT: ~20 Б индексов + ссылки на ALT.
Raydium ведёт ALT для путей своппов CPMM/CLMM на mainnet. SDK использует их автоматически. Агрегаторы, строящие много-хоп маршруты, полагаются на них широко.

Бюджет вычислений

Каждая транзакция имеет бюджет compute unit (CU). Его превышение прерывает исполнение и терпит неудачу.
  • По умолчанию: 200 000 CU за транзакцию.
  • Максимум: 1 400 000 CU за транзакцию (повышено через ComputeBudget::SetComputeUnitLimit).
  • Лимит на блок: 48M CU на блок (уровень протокола).
Типичное потребление CU Raydium (см. integration-guides/priority-fee-tuning для полной таблицы): Всегда устанавливайте явный лимит CU через ComputeBudget; иначе вы получите 200k по умолчанию, что слишком мало для большинства инструкций Raydium.
Если установить лимит CU слишком низким, транзакция терпит неудачу при достижении лимита; слишком высокий — рискуете быть понижены в приоритете при перегрузке (и, в зависимости от модели ценообразования, вы платите за вычисления, которые никогда не использовали).

Приоритетные комиссии

Помимо базовой комиссии транзакции (5000 lamports за подпись), валидаторы всё чаще приоритизируют транзакции, платящие приоритетные комиссии: подсказку за CU в микролампортах.
Пример: 10 000 µL/CU × 300 000 CU = 3 000 000 µL = 0.003 SOL. Приоритетные комиссии локальны — они влияют только на упорядочивание внутри блока; они не улучшают ваш шанс быть включённым против не включённого. Установка разумной приоритетной комиссии необходима при перегрузке.
См. integration-guides/priority-fee-tuning о том, как размер это динамически.

Лимиты количества инструкций и аккаунтов

Помимо общего лимита в 1232 байта:
  • Макс аккаунтов за транзакцию: 128.
  • Макс аккаунтов за инструкцию (CPI): 64.
  • Макс инструкций за транзакцию: жёсткого лимита нет, ограничен только лимитом размера.
  • Макс глубина CPI: 4 (программа может вызвать другую, которая может вызвать другую, 4 уровня глубины).
Своппы CLMM Raydium, пересекающие несколько tick array, могут упираться в лимит аккаунтов — один своп задействует пул, входные/выходные хранилища, входные/выходные ATA, несколько tick array, возможно дополнительные аккаунты программы transfer-hook, плюс обязательные ссылки на compute budget / system / token program. Конструкции, компонующие Raydium через CPI (например, auto-compounder), должны учитывать это.

Категории комиссий в своппе Raydium

Пользовательская транзакция своппа платит комиссии в двух категориях:

Сетевые комиссии Solana

Выплачиваются валидаторам в SOL.
  • Базовая комиссия подписи: 5000 lamports за подпись. Почти всегда 1 подпись = 0.000005 SOL.
  • Приоритетная комиссия: CU-price × CU-limit в микролампортах. Варьируется с перегрузкой; см. integration-guides/priority-fee-tuning.
Эти комиссии идут валидаторам, не связаны с Raydium и взимаются даже за неудачные транзакции (кроме некоторых граничных случаев приоритетной комиссии).

Комиссии протокола Raydium

Вычитаются из суммы своппа.
  • Комиссия своппа: процент от входа (CPMM 0.25% типично, CLMM 0.01%–1% на уровень). Делится между LP и протоколом. См. ray/protocol-fees.
Эти комиссии являются внутренней для бухгалтерии Raydium — пользователь видит их как меньший выходной объём, чем произвёл бы пул с нулевой комиссией.

Пример: $1000 USDC → SOL через CPMM 0.25% уровень

Slippage (ценовой удар + движение рынка) не является комиссией, но влияет на же итоговую строку.

Versioned транзакции

Solana имеет два формата транзакций:
  • Legacy: оригинальный формат, нет поддержки ALT.
  • v0 (Versioned): поддерживает ALT, расширяемый для будущих версий.
Весь современный инструмент Solana использует v0. SDK Raydium выдаёт v0 транзакции по умолчанию.

Свежесть блокхеша

Транзакция должна включать блокхеш из последних ~150 слотов (~60 секунд). За пределами этого окна валидаторы её отклоняют. Для retry циклов получайте свежий блокхеш при каждом retry:
См. integration-guides/priority-fee-tuning для полного retry-с-возрастающими-комиссиями паттерна.

Параллельное исполнение

Solana исполняет не конфликтующие транзакции параллельно на многоядерных валидаторах. Две транзакции конфликтуют, если обе записывают один и тот же аккаунт. Последствия для Raydium:
  • Два своппа на одном пуле не могут исполняться параллельно — оба записывают состояние пула.
  • Своп на Пуле A и своп на Пуле B исполняются параллельно, если списки аккаунтов не перекрываются.
  • Только-для-чтения транзакция никогда не блокирует писателя на том же аккаунте (только-для-чтения конкурирует с собой, но не с записями).
Это почему Solana может поддерживать высокий DEX throughput несмотря на сериализацию одного пула.

Уровни подтверждения транзакции

При отправке транзакции вы выбираете уровень подтверждения: Для UX своппа confirmed стандарт. Для операций с большой ценностью (создание пула, пополнение вознаграждения), finalized безопаснее.

Симуляция

Solana поддерживает симуляцию транзакции перед отправкой:
SDK Raydium использует симуляцию внутри при вычислении getBestSwapInfo для проверки, что выбранный маршрут действительно работает. Симуляция не бесплатна — она потребляет RPC ёмкость — но она ловит ошибки перед оплатой.

Указатели

Источники: