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

Каждая транзакция Solana имеет бюджет вычислений, измеряемый в Compute Units (CU). Понимание стоимости CU помогает проектировать эффективные контракты Rome.

## Обзор бюджета

| Режим              | Макс. CU                          | Примечания                    |
| ------------------ | --------------------------------- | ----------------------------- |
| Атомарный (VmAt)   | \~1 400 000 CU                    | Одна транзакция Solana        |
| Итеративный (VmIt) | Неограниченно (мульти-транзакции) | \~500 опкодов за шаг итерации |

Каждая транзакция Solana имеет бюджет по умолчанию в 200 000 CU, который можно увеличить примерно до 1,4 млн CU с помощью инструкций бюджета вычислений (автоматически добавляются SDK Rome).

## Оценки стоимости CU

### Операции EVM

| Операция                         | Примерно CU          | Примечания                             |
| -------------------------------- | -------------------- | -------------------------------------- |
| Проверка подписи (ecrecover)     | \~5 000 CU           | secp256k1 через системный вызов Solana |
| Простое перевод                  | \~50 000–100 000 CU  | Только обновления баланса              |
| Перевод ERC-20                   | \~100 000–150 000 CU | Включает вызов SPL precompile          |
| Развертывание контракта (малого) | \~200 000–400 000 CU | Зависит от размера байткода            |
| Запись в хранилище (SSTORE)      | \~5 000–20 000 CU    | Холодный vs. тёплый доступ             |

### Операции CPI

| Операция                                | Примерно CU | Примечания                               |
| --------------------------------------- | ----------- | ---------------------------------------- |
| Базовые накладные расходы transfer hook | 100 000 CU  | За каждый перевод                        |
| Нативный sub-hook                       | 50 000 CU   | За каждый нативный хук Solana            |
| EVM sub-hook                            | 200 000 CU  | За каждый EVM-хук                        |
| Рекомендуемый EVM-перевод с хукaми      | 800 000 CU  | Безопасный бюджет для переводов с хуками |

### Операции precompile

| Прекомпиляция   | Примерно CU      |
| --------------- | ---------------- |
| ecrecover       | \~3 000–5 000 CU |
| SHA-256         | \~1 000 CU       |
| BN254 ecAdd     | \~10 000 CU      |
| BN254 ecMul     | \~40 000 CU      |
| BN254 ecPairing | \~200 000+ CU    |

## Методы оптимизации

### 1. Используйте Yul для горячих путей

Оптимизатор Solidity выдаёт вполне приемлемый код, но Yul (встроенная ассемблерная вставка) может значительно снизить CU для критически важных операций:

```solidity
// До: ~600K CU
function createPairAccount(bytes32 token0, bytes32 token1) external {
    // Операции на уровне Solidity
}

// После: ~150K CU (оптимизация Yul)
function createPairAccount(bytes32 token0, bytes32 token1) external {
    assembly {
        // Прямое управление памятью, без накладных расходов ABI-кодирования
    }
}
```

### 2. Кэшируйте вычисления PDA

Вычисление PDA через `find_program_address` дорогостоящее. Сохраняйте вычисленные PDA в хранилище контракта вместо того, чтобы вычислять их при каждом вызове:

```solidity
mapping(address => bytes32) private cachedPdas;

function getPda(address user) internal returns (bytes32) {
    bytes32 cached = cachedPdas[user];
    if (cached != bytes32(0)) return cached;

    bytes32 pda = RomeEVMAccount.pda(user);
    cachedPdas[user] = pda;
    return pda;
}
```

### 3. Жёстко задавайте известные ID программ

Не загружайте ID программ из хранилища — используйте константы:

```solidity
// Дорого: чтение из хранилища
bytes32 splTokenProgram = storage_program_id;

// Дёшево: константа времени компиляции
bytes32 constant SPL_TOKEN_PROGRAM = 0x06ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a9;
```

### 4. Минимизируйте количество аккаунтов

Каждый аккаунт в транзакции Solana увеличивает накладные расходы CU. Сократите число аккаунтов за счёт:

* Пакетирования операций, которые используют общие аккаунты
* Использования меньшего числа промежуточных аккаунтов
* Избегания избыточных проверок создания ATA

### 5. Используйте настройки оптимизатора

```javascript
// hardhat.config.js
solidity: {
  version: "0.8.28",
  settings: {
    optimizer: { enabled: true, runs: 200 },
  },
}
```

## Измерение потребления CU

Используйте `eth_estimateGas` чтобы измерить CU перед отправкой:

```bash
cast estimate --rpc-url http://localhost:9090 \
  0xCONTRACT "myFunction(uint256)" 42
```

Или через ethers.js:

```javascript
const gas = await contract.myFunction.estimateGas(42);
console.log("Estimated gas:", gas.toString());
```

## Что дальше

* [Ограничения](/ru/osnovnye-koncepcii/constraints.md) — полный список лимитов и границ
* [Руководство по оптимизации CU](https://github.com/rome-protocol/docs/blob/main/developer-guides/cu-optimization.md) — подробный справочник по оптимизации


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rome.builders/ru/osnovnye-koncepcii/compute-budget.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
