> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/ru/klyuchevye-ponyatiya/compute-budget.md).

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

Затраты вычислительных единиц Solana (CU) для операций Rome EVM — атомарные и итеративные бюджеты и то, как проектировать контракты Solidity, эффективно использующие CU.

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

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

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

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

Итеративное выполнение не является безграничным. Одна сессия завершается после 160 итераций, а итеративный компоновщик Rust Rome SDK планирует не более 128 шагов. План, который кошелёк подписывает самостоятельно, проходит через `rome_submitSignedV1Plan`, который принимает не более 64 транзакций за один вызов. Большинству вызовов требуется гораздо меньше. CPI из legacy-track отклоняются внутри итеративной сессии, поэтому вызов, который их создаёт, должен укладываться в атомарный бюджет. См. [Ретранслируемые вызовы и длинные вызовы](/ru/rukovodstva-dlya-razrabotchikov/call-evm-from-solana.md#relayed-calls-and-long-calls) и [Ограничения](/ru/klyuchevye-ponyatiya/constraints.md).

## Оценки затрат CU

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

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

### Операции прекомпилов

| Precompile      | Примерный CU                                      | Примечания                                                                                                                                                                                                                                                                           |
| --------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ecrecover       | \~25 700 CU                                       |                                                                                                                                                                                                                                                                                      |
| SHA-256         | \~257 CU на каждое 32-байтное слово по измерениям | Плюс небольшая фиксированная стоимость. Программа оценивает SHA-256, RIPEMD-160 и identity-прекомпайл по единой ставке за слово — около 2 200 CU, рассчитанной по RIPEMD-160, самому дорогому из трёх, поэтому за вызов SHA-256 списывается больше CU, чем он фактически использует. |
| BN254 ecAdd     | Почти 0 CU                                        | Дешевле, чем копирование 32 байт                                                                                                                                                                                                                                                     |
| BN254 ecMul     | \~4 200 CU                                        |                                                                                                                                                                                                                                                                                      |
| BN254 ecPairing | \~22 000 CU плюс \~12 800 CU за пару              | Проверка на четырёх парах занимает около 73 000 CU и вполне укладывается в одну атомарную транзакцию                                                                                                                                                                                 |

Эти цифры основаны на собственной калибровке программы, в ходе которой использовались вычислительные единицы, считанные с узла Solana в развёртывании на тестнете. Для этой страницы они не пересчитывались; измерьте свой собственный вызов с помощью `computeUnitsConsumed`.

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

### 1. Используйте Yul для критически важных участков

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

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

// После: ~150 тыс. 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. Используйте настройки оптимизатора

```typescript
// hardhat.config.ts — включите оптимизатор в профиле сборки
solidity: {
  profiles: {
    default: { version: "0.8.28" },
    production: {
      version: "0.8.28",
      settings: { optimizer: { enabled: true, runs: 200 } },
    },
  },
}
```

Соберите с помощью `npx hardhat compile --build-profile production`.

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

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

```bash
cast estimate --rpc-url https://hadrian.testnet.romeprotocol.xyz/ \
  0xCONTRACT "myFunction(uint256)" 42
```

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

```javascript
const gas = await contract.myFunction.estimateGas(42);
console.log("Оценочный gas:", gas.toString());
```

## Что дальше

* [Ограничения](/ru/klyuchevye-ponyatiya/constraints.md) — полный список ограничений и пределов


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.rome.builders/ru/klyuchevye-ponyatiya/compute-budget.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
