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

# Solidity Cheatcodes

> Справочник интерфейса IVnetPrecompile для чит-кодов уровня Solidity, доступных в каждой Virtual Environment по адресу 0xc100000000000000000000000000000000000000.

Каждая Virtual Environment предоставляет прекомпайл-контракт по адресу `0xc100000000000000000000000000000000000000`. Вызов функций этого прекомпайла изнутри транзакции позволяет вашим контрактам напрямую манипулировать состоянием on-chain — слотами хранилища, балансами, nonce и логами событий — без имперсонации аккаунтов и деплоя вспомогательных прокси.

Эти чит-коды дополняют [методы Admin RPC](/virtual-environments/admin-rpc). Методы Admin RPC манипулируют состоянием извне транзакции (через JSON-RPC). Прекомпайл манипулирует состоянием изнутри транзакции (через Solidity-вызов). Используйте прекомпайл, когда ваш сетап должен оставаться атомарным, быть воспроизводимым по хешу транзакции или выполняться в цикле по многим слотам.

## Интерфейс

Добавьте этот файл в ваш проект как `IVnetPrecompile.sol`:

```solidity title="IVnetPrecompile.sol" theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IVnetPrecompile {
    function setStorageAt(address target, bytes32 slot, bytes32 value) external returns (bool);
    function getStorageAt(address target, bytes32 slot) external view returns (bytes32);
    function setBalance(address target, uint256 balance) external returns (bool);
    function addBalance(address target, uint256 amount) external returns (bool);
    function setNonce(address target, uint256 value) external returns (bool);

    function emitEvent(address target, bytes calldata data) external returns (bool);
    function emitEvent(address target, bytes32 topic1) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes calldata data) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes calldata data) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes calldata data) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes32 topic4) external returns (bool);
    function emitEvent(address target, bytes32 topic1, bytes32 topic2, bytes32 topic3, bytes32 topic4, bytes calldata data) external returns (bool);
}
```

Ссылайтесь на него в вашем контракте по фиксированному адресу:

```solidity theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
IVnetPrecompile constant VNET = IVnetPrecompile(0xc100000000000000000000000000000000000000);
```

## Функции

### Хранилище

| Функция        | Параметры                                         | Возвращает | Описание                                    |
| -------------- | ------------------------------------------------- | ---------- | ------------------------------------------- |
| `setStorageAt` | `address target`, `bytes32 slot`, `bytes32 value` | `bool`     | Записывает `value` в `slot` на `target`.    |
| `getStorageAt` | `address target`, `bytes32 slot`                  | `bytes32`  | Читает текущее значение `slot` на `target`. |

```solidity theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
VNET.setStorageAt(tokenContract, balanceSlot, bytes32(uint256(1000e18)));
bytes32 val = VNET.getStorageAt(tokenContract, balanceSlot);
```

### Баланс

| Функция      | Параметры                           | Возвращает | Описание                                             |
| ------------ | ----------------------------------- | ---------- | ---------------------------------------------------- |
| `setBalance` | `address target`, `uint256 balance` | `bool`     | Устанавливает ETH-баланс `target` в точное значение. |
| `addBalance` | `address target`, `uint256 amount`  | `bool`     | Добавляет `amount` к текущему ETH-балансу `target`.  |

```solidity theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
VNET.setBalance(account, 10 ether);
VNET.addBalance(account, 2 ether);
```

### Nonce

| Функция    | Параметры                         | Возвращает | Описание                                |
| ---------- | --------------------------------- | ---------- | --------------------------------------- |
| `setNonce` | `address target`, `uint256 value` | `bool`     | Задаёт счётчик транзакций для `target`. |

```solidity theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
VNET.setNonce(account, 42);
```

### События

`emitEvent` эмитирует лог, у которого поле `address` — это `target`, а не вызывающий контракт. Нижестоящие потребители (индексеры, subgraphs, вебхуки) считают лог реальной эмиссией от `target`.

Девять перегрузок покрывают от нуля до четырёх индексируемых топиков с необязательным неиндексируемым data-payload:

| Перегрузка                                | Топики | Данные |
| ----------------------------------------- | ------ | ------ |
| `emitEvent(target, data)`                 | 0      | ✓      |
| `emitEvent(target, t1)`                   | 1      | ,      |
| `emitEvent(target, t1, data)`             | 1      | ✓      |
| `emitEvent(target, t1, t2)`               | 2      | ,      |
| `emitEvent(target, t1, t2, data)`         | 2      | ✓      |
| `emitEvent(target, t1, t2, t3)`           | 3      | ,      |
| `emitEvent(target, t1, t2, t3, data)`     | 3      | ✓      |
| `emitEvent(target, t1, t2, t3, t4)`       | 4      | ,      |
| `emitEvent(target, t1, t2, t3, t4, data)` | 4      | ✓      |

`topic1` обычно равен `keccak256("EventName(type,type,...)")`. Пример, подделываем `Transfer` для USDC:

```solidity theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
VNET.emitEvent(
    USDC,
    keccak256("Transfer(address,address,uint256)"),
    bytes32(uint256(uint160(from))),
    bytes32(uint256(uint160(to))),
    abi.encode(amount)
);
```

<Note>
  Прекомпайл также эмитирует собственные диагностические логи (установка баланса, установка nonce, запись в хранилище) с `address` = `0xc100000000000000000000000000000000000000`. При проверке чека транзакции на предмет подделанного лога фильтруйте `logs[]` по целевому адресу, чтобы игнорировать собственные записи прекомпайла.
</Note>

## Известные ограничения

* **Virtual Environments на основе Arbitrum.** Вызовы чит-кодов через `eth_call` не работают из-за внутренних особенностей Arbitrum. Транзакции, оценка газа и симуляции работают как ожидается.

## См. также

* [Admin RPC](/virtual-environments/admin-rpc) — эквивалентные JSON-RPC методы для манипуляции состоянием извне транзакции.
* [Туториал по чит-кодам в Foundry](/virtual-environments/develop/solidity-cheatcodes) — сквозное прохождение с деплоем переиспользуемой песочницы чит-кодов.
