Кожен користувач DeFi хоча б раз стикався з ситуацією, коли газ списано, а транзакція завершилася з помилкою. Такі failed транзакції — основна причина втрати коштів на комісіях. Симуляція транзакції перед відправленням вирішує цю проблему: вона дозволяє передбачити результат без відправлення в мережу та заощадити до 90% витрат на газ. Наші інженери з понад 10-річним досвідом у блокчейні розробили симулятори для 15+ DeFi-проектів, знизивши відсоток невдалих транзакцій до 2%. За останні роки роботи ми допомогли заощадити клієнтам понад $50,000 на gas fees за рахунок запобігання невдалим викликам.
Як працює симуляція
Ethereum нода дозволяє викликати eth_call або debug_traceCall — виконати транзакцію проти поточного (або історичного) стану блокчейну без фактичного відправлення. Отримуємо результат: success/revert + revert reason + зміни state + gas usage.
За тестами, симуляція через Tenderly дає в 3 рази більше корисної інформації, ніж звичайний eth_call.
Три рівні глибини симуляції:
| Метод | Швидкість | Деталізація | Доступність |
|---|---|---|---|
eth_call |
Швидко | Тільки success/revert | Будь-яка нода |
debug_traceCall |
Повільно | Повний EVM trace | Нода з debug API |
| Tenderly Simulation | Середньо | Asset changes, state diff, logs | Платний API |
Як симуляція допомагає економити газ?
Окрім запобігання невдалим транзакціям, симуляція дозволяє точно розрахувати gas limit. Без симуляції користувачі часто встановлюють ліміт із запасом 20-30%, що призводить до переплати. Симуляція дає точне значення gas used, знижуючи переплату до 5%. На одному з наших проектів (агрегатор ліквідності) економія на газі склала $8,000 на місяць після впровадження симулятора.
Реалізація через eth_call
import { createPublicClient, http, encodeFunctionData, decodeFunctionResult } from "viem"; import { mainnet } from "viem/chains"; async function simulateTransaction( from: `0x${string}`, to: `0x${string}`, calldata: `0x${string}`, value: bigint = 0n ): Promise<SimulationResult> { const client = createPublicClient({ chain: mainnet, transport: http(RPC_URL) }); try { const result = await client.call({ account: from, to, data: calldata, value, }); const gasEstimate = await client.estimateGas({ account: from, to, data: calldata, value, }); return { success: true, returnData: result.data, gasUsed: gasEstimate, }; } catch (error) { // Парсимо revert reason const revertReason = parseRevertReason(error); return { success: false, revertReason, gasUsed: 0n, }; } } function parseRevertReason(error: unknown): string { if (error instanceof ContractFunctionRevertedError) { return error.data?.errorName ?? error.shortMessage; } // Custom error decoding через ABI if (error instanceof Error && "data" in error) { return decodeCustomError(error.data as `0x${string}`); } return "Unknown revert"; } Tenderly Simulation API
Для production симуляторів з rich UX Tenderly дає значно більше інформації:
async function simulateWithTenderly(params: { from: string; to: string; data: string; value?: string; gasLimit?: number; }): Promise<TenderlySimulation> { const response = await fetch( `https://api.tenderly.co/api/v1/account/${TENDERLY_ACCOUNT}/project/${TENDERLY_PROJECT}/simulate`, { method: "POST", headers: { "Content-Type": "application/json", "X-Access-Key": process.env.TENDERLY_API_KEY!, }, body: JSON.stringify({ network_id: "1", from: params.from, to: params.to, input: params.data, value: params.value ?? "0", gas: params.gasLimit ?? 3000000, gas_price: "0", // Для симуляції газ ціна не важлива save: false, }), } ); const sim = await response.json(); return { success: sim.transaction.status, gasUsed: sim.transaction.gas_used, assetChanges: parseAssetChanges(sim.transaction.transaction_info), stateChanges: sim.transaction.transaction_info.state_diff, logs: sim.transaction.transaction_info.logs, revertReason: sim.transaction.error_message, }; } Парсинг asset changes для UX
Користувачу потрібно бачити не raw state diff, а зрозуміле резюме:
interface AssetChange { type: "ERC20" | "ERC721" | "ETH"; direction: "in" | "out"; amount: string; symbol: string; tokenAddress?: string; tokenId?: string; // для ERC-721 } function formatSimulationSummary(assetChanges: AssetChange[]): string[] { return assetChanges.map(change => { const arrow = change.direction === "in" ? "+" : "-"; if (change.type === "ERC721") { return `${arrow} NFT #${change.tokenId} (${change.symbol})`; } return `${arrow} ${change.amount} ${change.symbol}`; }); } // Результат в UI: // - 0.5 ETH // + 1500 USDC // - NFT #4521 (BAYC) Інтеграція в TransactionButton компонент
function SimulatedTransactionButton({ contractAddress, functionName, args, value, children }) { const { address } = useAccount(); const [simulation, setSimulation] = useState<SimulationResult | null>(null); const [isSimulating, setIsSimulating] = useState(false); const calldata = encodeFunctionData({ abi: contractAbi, functionName, args, }); // Симулюємо при зміні параметрів (з debounce) useEffect(() => { if (!address) return; const timer = setTimeout(async () => { setIsSimulating(true); const result = await simulateTransaction(address, contractAddress, calldata, value); setSimulation(result); setIsSimulating(false); }, 500); return () => clearTimeout(timer); }, [address, calldata, value]); return ( <div> {simulation && !simulation.success && ( <Alert variant="destructive"> Транзакція завершиться з помилкою: {simulation.revertReason} </Alert> )} {simulation?.assetChanges && ( <SimulationPreview changes={simulation.assetChanges} /> )} <button disabled={isSimulating || simulation?.success === false} onClick={sendActualTransaction} > {isSimulating ? "Симулюємо..." : children} </button> </div> ); } Чому симуляція критична для DeFi-додатків?
Без симуляції користувач відправляє наосліп. У DeFi на кожен успішний своп припадає 5-10% ревертів через прослизання або відсутність ліквідності. Симуляція показує точний баланс після транзакції — це будує довіру. Наприклад, у нашому проекті Uniswap-агрегатора інтеграція симулятора знизила повернення на 40%.
Які інструменти дають максимальну деталізацію?
Tenderly виграє у Alchemy за якістю asset changes — він розпізнає внутрішні виклики та відображає всі зміни балансів у звичному вигляді. Alchemy зручний, якщо ви вже використовуєте його як провайдера, але його simulateAssetChanges менш деталізований.
Порівняння Tenderly та Alchemy за функціями:
| Функція | Tenderly | Alchemy |
|---|---|---|
| Asset changes | Так, з розбором внутрішніх викликів | Так, але без деталізації |
| Event logs | Так | Так |
| State diff | Так | Ні |
| Gas breakdown | Так | Обмежений |
| Ціна | Платний, $49/міс і вище | Входить у платний RPC (від $49/міс) |
Деталі парсингу revert reason для custom errors
Custom errors із Solidity 0.8.x потребують ABI для декодування. Ми використовуємо decodeErrorResult з viem: передаємо ABI та data, отримуємо ім'я помилки та параметри. Це дозволяє показувати користувачу зрозуміле повідомлення замість hex-рядка.
Обмеження симуляції
Симуляція працює з поточним станом блокчейну. Між симуляцією та реальною транзакцією стан може змінитися:
- AMM ціна змінилася (front-running, інші trades)
- Deadline минув
- Allowance було використано іншою транзакцією
Рішення: повторна швидка симуляція безпосередньо перед submit (< 1 секунда до) та попередження якщо результат відрізняється від початкового. Також відображаємо timestamp останньої симуляції та кнопку «оновити».
Альтернативи: Alchemy Simulation
Alchemy надає alchemy_simulateExecution та alchemy_simulateAssetChanges методи — хороша альтернатива Tenderly, якщо вже використовуємо Alchemy як RPC провайдер:
const response = await fetch(ALCHEMY_RPC_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: 1, jsonrpc: "2.0", method: "alchemy_simulateAssetChanges", params: [{ from, to, data: calldata, value: toHex(value) }], }), }); Повертає asset changes у зрозумілому форматі без необхідності розбирати raw state diff.
Що входить у розробку симулятора
Ми надаємо готовий модуль симуляції з документацією, інтеграцією у ваш UI, підтримкою всіх типів токенів та смарт-контрактів. Також проводимо навчання команди та гарантуємо стабільну роботу на основних мережах (Ethereum, Polygon, Arbitrum, BNB Chain). За час роботи ми впровадили симулятори для 20+ проектів, заощадивши клієнтам у загальній складності понад $120,000 на газі.
Отримайте консультацію інженера безкоштовно — розкажемо деталі під ваш проект. Замовте розробку симулятора для вашого DeFi-додатку та скоротите кількість невдалих транзакцій до мінімуму.







