Настройка Tenderly Simulator для тестирования
Тестировать транзакцию на mainnet через eth_call — это читать состояние чейна, но не видеть, что происходит внутри. Tenderly Simulator идёт дальше: полный execution trace, изменение state до отправки, симуляция с подменой балансов и состояния контрактов. Это отдельный инструмент, который закрывает gap между локальными тестами и реальным mainnet.
Что умеет Tenderly Simulator, чего нет в Hardhat fork
Hardhat --fork поднимает локальный EVM с форком mainnet. Это работает для unit-тестов, но требует запускать ноду локально, управлять состоянием вручную. Tenderly Simulator — это API: отправляешь транзакцию без отправки, получаешь полный trace.
Ключевые возможности:
- Симуляция с переопределением state (storage overrides, balance overrides)
- Полный stack trace с именами функций (если контракт верифицирован)
- Gas profiling: сколько gas потратил каждый вызов
- Event logs в человекочитаемом виде
- Симуляция bundle транзакций (несколько транзакций последовательно)
Настройка через API
Базовая симуляция через Tenderly API:
const TENDERLY_API = 'https://api.tenderly.co/api/v1';
const headers = {
'X-Access-Key': process.env.TENDERLY_ACCESS_KEY!,
'Content-Type': 'application/json'
};
const response = await fetch(
`${TENDERLY_API}/account/${TENDERLY_USER}/project/${TENDERLY_PROJECT}/simulate`,
{
method: 'POST',
headers,
body: JSON.stringify({
network_id: '1', // mainnet
from: userAddress,
to: contractAddress,
input: encodedCalldata,
gas: 500000,
gas_price: '0',
value: '0',
save: true, // сохранить симуляцию в дашборде
state_objects: {
// override баланса пользователя
[userAddress]: { balance: '0xDE0B6B3A7640000' } // 1 ETH
}
})
}
);
const simulation = await response.json();
console.log('Gas used:', simulation.transaction.gas_used);
console.log('Status:', simulation.transaction.status); // true/false
Virtual TestNets: замена локального форка
Tenderly Virtual TestNets (бывший Tenderly Forks) — это persistent fork mainnet с RPC endpoint. Подключаешь через MetaMask или wagmi как обычную сеть и тестируешь прямо в браузере с реальным UI. Нет нужды разворачивать Anvil локально.
Создание Virtual TestNet через CLI:
tenderly devnet spawn-rpc \
--template mainnet \
--project my-project \
--account my-account
Возвращает RPC URL. Добавляем в wagmi config:
const virtualMainnet = defineChain({
id: 1,
name: 'Virtual Mainnet',
rpcUrls: {
default: { http: [process.env.TENDERLY_VIRTUAL_TESTNET_RPC!] }
}
});
State сбрасывается по запросу или по расписанию — удобно для CI, где каждый тест-ран начинается с чистого состояния.
Интеграция в CI pipeline
В GitHub Actions добавляем step с симуляцией критических транзакций перед деплоем:
- name: Simulate deployment transaction
env:
TENDERLY_ACCESS_KEY: ${{ secrets.TENDERLY_ACCESS_KEY }}
run: npx ts-node scripts/simulate-deploy.ts
Скрипт симулирует деплой контракта, проверяет, что gas не превышает лимит, статус success, нет unexpected revert-ов. Failing симуляция — failing CI job, деплой не происходит.
Настройка занимает 1 рабочий день: создание проекта в Tenderly, API ключи, базовый скрипт симуляции, интеграция в pipeline.







