> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Транзакции и комиссии

> Структура транзакций Solana, лимиты, в которых они работают, и две категории комиссий — сетевые комиссии Solana и комиссии протокола Raydium — которые платит типичный своп.

<Info>
  **Эта страница переведена с помощью ИИ. За эталон принимается английская версия.**

  [Открыть английскую версию →](/solana-fundamentals/transactions-and-fees)
</Info>

Транзакция 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`](/ru/solana-fundamentals/account-model)). Своппы CLMM с несколькими пересечениями tick array могут иметь 20+.

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

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

Разбор типичного своппа Raydium размером \~1000 байт:

| Компонент                    | Размер       |
| ---------------------------- | ------------ |
| Подпись                      | 64 Б         |
| Количество подписей          | 1 Б          |
| Заголовок message            | 3 Б          |
| Блокхеш                      | 32 Б         |
| Ключи аккаунтов (13 × 32 Б)  | 416 Б        |
| Инструкции (4 × \~100-150 Б) | 400–600 Б    |
| **Всего**                    | \~900–1100 Б |

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

ALT позволяют транзакции ссылаться на аккаунты через однобайтовый индекс в опубликованную таблицу вместо полного 32-байтового публичного ключа. Это резко сжимает транзакцию:

* Транзакция со ссылками на 20 аккаунтов напрямую: \~640 Б публичных ключей.
* Та же транзакция с использованием ALT: \~20 Б индексов + ссылки на ALT.

Raydium ведёт ALT для путей своппов CPMM/CLMM на mainnet. SDK использует их автоматически. Агрегаторы, строящие много-хоп маршруты, полагаются на них широко.

```ts theme={null}
import { VersionedTransaction } from "@solana/web3.js";

// SDK строит v0 (versioned) tx со ссылками на ALT
const { transaction } = await raydium.trade.swap({ /* ... */ });
// transaction это VersionedTransaction, не legacy Transaction.
```

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

Каждая транзакция имеет **бюджет compute unit (CU)**. Его превышение прерывает исполнение и терпит неудачу.

* **По умолчанию**: 200 000 CU за транзакцию.
* **Максимум**: 1 400 000 CU за транзакцию (повышено через `ComputeBudget::SetComputeUnitLimit`).
* **Лимит на блок**: 48M CU на блок (уровень протокола).

Типичное потребление CU Raydium (см. [`integration-guides/priority-fee-tuning`](/ru/integration-guides/priority-fee-tuning) для полной таблицы):

| Инструкция                       | CU        |
| -------------------------------- | --------- |
| Своп CPMM                        | \~140 000 |
| Своп CLMM (без пересечений tick) | \~170 000 |
| Своп CLMM (4 пересечения tick)   | \~320 000 |
| Стейкинг Farm v6                 | \~130 000 |
| Создание пула CPMM               | \~250 000 |

Всегда устанавливайте явный лимит CU через `ComputeBudget`; иначе вы получите 200k по умолчанию, что слишком мало для большинства инструкций Raydium.

```ts theme={null}
import { ComputeBudgetProgram } from "@solana/web3.js";

tx.add(
  ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }),
);
```

Если установить лимит CU слишком низким, транзакция терпит неудачу при достижении лимита; слишком высокий — рискуете быть понижены в приоритете при перегрузке (и, в зависимости от модели ценообразования, вы платите за вычисления, которые никогда не использовали).

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

Помимо базовой комиссии транзакции (5000 lamports за подпись), валидаторы всё чаще приоритизируют транзакции, платящие **приоритетные комиссии**: подсказку за CU в микролампортах.

```
priority_fee = compute_unit_price (micro-lamports) × compute_unit_limit
```

Пример: 10 000 µL/CU × 300 000 CU = 3 000 000 µL = 0.003 SOL.

Приоритетные комиссии локальны — они влияют только на упорядочивание внутри блока; они не улучшают ваш шанс быть включённым против не включённого. Установка разумной приоритетной комиссии необходима при перегрузке.

```ts theme={null}
tx.add(
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }),
);
```

См. [`integration-guides/priority-fee-tuning`](/ru/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`](/ru/integration-guides/priority-fee-tuning).

Эти комиссии идут валидаторам, не связаны с Raydium и взимаются даже за неудачные транзакции (кроме некоторых граничных случаев приоритетной комиссии).

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

Вычитаются из суммы своппа.

* **Комиссия своппа**: процент от входа (CPMM 0.25% типично, CLMM 0.01%–1% на уровень). Делится между LP и протоколом. См. [`ray/protocol-fees`](/ru/ray/protocol-fees).

Эти комиссии являются внутренней для бухгалтерии Raydium — пользователь видит их как меньший выходной объём, чем произвёл бы пул с нулевой комиссией.

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

| Категория комиссии                       | Сумма                     | Идёт          |
| ---------------------------------------- | ------------------------- | ------------- |
| Базовая комиссия подписи                 | 0.000005 SOL (\~\$0.0007) | Валидатор     |
| Приоритетная комиссия (10k µL × 300k CU) | 0.003 SOL (\~\$0.45)      | Валидатор     |
| Комиссия своппа CPMM (0.25%)             | \$2.50                    | LP + протокол |
| **Всего стоимость пользователя**         | \~\$2.95                  |               |

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

## Versioned транзакции

Solana имеет два формата транзакций:

* **Legacy**: оригинальный формат, нет поддержки ALT.
* **v0 (Versioned)**: поддерживает ALT, расширяемый для будущих версий.

Весь современный инструмент Solana использует v0. SDK Raydium выдаёт v0 транзакции по умолчанию.

```ts theme={null}
// Построение v0 tx напрямую
import { VersionedTransaction, TransactionMessage } from "@solana/web3.js";

const msg = new TransactionMessage({
  payerKey:        owner.publicKey,
  recentBlockhash: blockhash,
  instructions:    [ /* ... */ ],
}).compileToV0Message([lookupTableAccount]);

const tx = new VersionedTransaction(msg);
tx.sign([owner]);
```

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

Транзакция должна включать блокхеш из последних \~150 слотов (\~60 секунд). За пределами этого окна валидаторы её отклоняют.

Для retry циклов получайте свежий блокхеш при каждом retry:

```ts theme={null}
async function sendWithRetry(tx, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
    tx.message.recentBlockhash = blockhash;
    tx.sign([owner]);
    try {
      return await connection.sendRawTransaction(tx.serialize());
    } catch (e) {
      if (i === maxRetries - 1) throw e;
    }
  }
}
```

См. [`integration-guides/priority-fee-tuning`](/ru/integration-guides/priority-fee-tuning) для полного retry-с-возрастающими-комиссиями паттерна.

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

Solana исполняет не конфликтующие транзакции параллельно на многоядерных валидаторах. Две транзакции конфликтуют, если обе записывают один и тот же аккаунт.

Последствия для Raydium:

* Два своппа на одном пуле не могут исполняться параллельно — оба записывают состояние пула.
* Своп на Пуле A и своп на Пуле B исполняются параллельно, если списки аккаунтов не перекрываются.
* Только-для-чтения транзакция никогда не блокирует писателя на том же аккаунте (только-для-чтения конкурирует с собой, но не с записями).

Это почему Solana может поддерживать высокий DEX throughput несмотря на сериализацию одного пула.

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

При отправке транзакции вы выбираете уровень подтверждения:

| Уровень     | Ожидание | Финальность                         |
| ----------- | -------- | ----------------------------------- |
| `processed` | \~400 мс | Не финализирована; может откатиться |
| `confirmed` | \~1 с    | Большинство голосовало              |
| `finalized` | \~13 с   | Большинство укоренилось             |

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

```ts theme={null}
await connection.sendAndConfirmTransaction(tx, [owner], {
  commitment: "confirmed",
});
```

## Симуляция

Solana поддерживает симуляцию транзакции перед отправкой:

```ts theme={null}
const sim = await connection.simulateTransaction(tx);
console.log(sim.value.logs);
console.log(sim.value.unitsConsumed);
```

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

## Указатели

* [`solana-fundamentals/account-model`](/ru/solana-fundamentals/account-model) — аккаунты в транзакциях.
* [`solana-fundamentals/pdas-and-cpis`](/ru/solana-fundamentals/pdas-and-cpis) — как программы вызывают друг друга.
* [`integration-guides/priority-fee-tuning`](/ru/integration-guides/priority-fee-tuning) — размер лимитов CU и приоритетных комиссий.
* [`ray/protocol-fees`](/ru/ray/protocol-fees) — структура комиссий протокола Raydium.

Источники:

* [Документация Solana Transaction](https://docs.solana.com/developing/programming-model/transactions).
* [Предложение Address Lookup Tables](https://docs.solana.com/developing/lookup-tables).
* [Документация Compute budget](https://docs.solana.com/developing/programming-model/runtime).
