Кожен користувач 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-додатку та скоротите кількість невдалих транзакцій до мінімуму.







