Транзакция упала с execution reverted — ни reason string, ни вменяемого лога. Или списала газа в 3 раза больше, чем ожидалось, и непонятно, почему. Или мультисиг отработал не так, но на каком именно вызове — загадка. console.log в Solidity не работает в mainnet, а смотреть raw opcodes в Etherscan — мучение. Такая ситуация — ежедневный хлеб разработчиков смарт-контрактов. В нашей практике около 40% обращений в поддержку связаны с непонятными revert'ами. Анализ трассировки вручную занимает от часа до полдня. Tenderly Debugger сокращает это до 2-3 минут. По данным Tenderly, команды экономят до 90% времени на поиске ошибок. В одном кейсе мы снизили расход газа на 25% после оптимизации, найденной через трассировку.
Как Tenderly Debugger помогает найти причину ошибки?
На каждую транзакцию Tenderly строит:
- Execution trace — пошаговое выполнение opcodes с состоянием стека и памяти
- Call tree — дерево вложенных вызовов (internal calls, delegatecall, staticcall)
- State changes — какие storage слоты изменились и с какого значения на какое
- Event logs — все эмитированные события, включая из вложенных вызовов
- Gas breakdown — сколько газа потребил каждый вызов в дереве
Для контрактов с верифицированным исходным кодом дебаггер показывает Solidity строки, а не opcodes. Это в десятки раз быстрее, чем искать ошибку вручную. Например, при отладке reentrancy-атаки Tenderly показывает точное количество рекурсивных вызовов withdraw() и сумму утекших ETH на каждой итерации.
Пример: отладка reverted транзакции
Частый сценарий: пользователь сообщает о failed транзакции, hash есть, а reason — пусто (контракт старый, require без сообщения). Вставляем hash в Tenderly — сразу видим строку в исходнике, где произошёл revert, и актуальные значения переменных. В одном из проектов мы так за 2 минуты нашли ошибку в расчёте slippage, которая приводила к потерям 0.5% ликвидности на каждой свопе.
Настройка проекта в Tenderly
Добавление контракта
npm install -g @tenderly/cli
tenderly login
tenderly init # создаёт tenderly.yaml в проекте
Для Hardhat-проектов подключается плагин, который автоматически пушит артефакты:
// hardhat.config.js
require("@tenderly/hardhat-tenderly");
module.exports = {
tenderly: {
username: "your-username",
project: "your-project",
privateVerification: false
}
};
После этого npx hardhat run scripts/deploy.js --network mainnet автоматически верифицирует контракты в Tenderly.
Fork для отладки
Tenderly Fork — снапшот состояния сети на конкретном блоке. Можно отправлять транзакции без риска потерять средства и видеть полную трассировку:
const axios = require('axios');
const response = await axios.post(
`https://api.tenderly.co/api/v1/account/${username}/project/${project}/fork`,
{
network_id: "1",
block_number: 19500000
},
{ headers: { 'X-Access-Key': process.env.TENDERLY_ACCESS_KEY } }
);
const forkId = response.data.simulation_fork.id;
const forkRpc = `https://rpc.tenderly.co/fork/${forkId}`;
Подключайтесь к forkRpc как к обычному JSON-RPC — все транзакции записываются и доступны для анализа.
Почему Tenderly Debugger лучше, чем локальная отладка?
| Параметр |
Tenderly Debugger |
Локальный debugger (Hardhat/Foundry) |
| Состояние сети |
Реальное mainnet-состояние |
Изолированное, локальное |
| Поддержка форков |
Да, любой блок |
Требуется импорт состояния |
| Визуализация call tree |
Графическое дерево |
Только текстовый лог |
| Интеграция с CI |
Simulation API |
Запуск скриптов |
| Доступность |
SaaS, веб-интерфейс |
Только локально |
Дополнительно: Tenderly позволяет сравнивать газовые затраты разных подходов. Например, типичный transfer тратит ~21000 gas, а swap через Uniswap V3 — от 80000 до 150000 gas в зависимости от проскальзывания.
| Операция |
Расход газа (Ethereum mainnet) |
| Простой перевод ETH |
21000 gas |
Вызов approve() ERC-20 |
~45000 gas |
transferFrom() ERC-20 |
~35000 gas |
| Swap через Uniswap V3 |
~100000 gas |
| Деплой простого контракта |
~200000 gas |
Эти цифры помогают оценить, где скрываются неоптимальные вызовы.
Simulation API для тестирования
Simulation API позволяет симулировать транзакции перед отправкой в сеть. Используем в CI для автоматической регрессии:
const simulation = await axios.post(
`https://api.tenderly.co/api/v1/account/${username}/project/${project}/simulate`,
{
network_id: "1",
from: "0xSenderAddress",
to: "0xContractAddress",
input: contractInterface.encodeFunctionData("transfer", [recipient, amount]),
gas: 200000,
gas_price: "20000000000",
value: "0",
save: true
},
{ headers: { 'X-Access-Key': process.env.TENDERLY_ACCESS_KEY } }
);
console.log(simulation.data.transaction.status);
console.log(simulation.data.transaction.gas_used);
Интеграция Simulation API в CI-пайплайн: получение API-ключа, создание эндпоинта, добавление шага в GitHub Actions или GitLab CI, проверка статуса и газа. Если параметры выходят за рамки, пайплайн падает.
Что входит в настройку Tenderly под ключ?
- Полная верификация всех контрактов проекта в Tenderly
- Настройка fork-окружения для отладки и тестирования
- Интеграция Simulation API в CI/CD
- Документация по использованию и конфигурации
- Обучение команды (1-2 сессии)
- Поддержка в течение месяца после внедрения
Мы — команда с 5-летним опытом в блокчейн-разработке, выполнили более 20 проектов смарт-контрактов и DApps. Наша экспертиза гарантирует быструю и качественную настройку.
Ориентиры по срокам
Базовая настройка с верификацией и подключением Hardhat плагина: 1-2 дня. Расширенная конфигурация с fork, Simulation API и мониторингом: до 5 дней.
Чтобы оценить возможности Tenderly для вашего проекта получите консультацию — свяжитесь с нами. Закажите настройку отладчика под ключ и получите полную прозрачность транзакций.
Разработка смарт-контрактов
Мы столкнулись с ситуацией: контракт задеплоен, через две недели приходит сообщение — пул дренирован на $800k. Смотрим транзакцию в Tenderly: атакующий вызвал deposit(), внутри callback на ERC-777 повторно вызвал withdraw() — баланс обновился только после второго выхода. Классическая reentrancy, но не через ETH transfer, а через хук ERC-777. ReentrancyGuard стоял только на withdraw().
Такие случаи — не редкость. Смарт-контракт — это финансовая логика без возможности пропатчить её ночью. Наша команда разрабатывает контракты под ключ, встраивая защиту от reentrancy, MEV и gas-атак на ранних этапах.
Как мы разрабатываем смарт-контракты под ключ
Начинаем с аудита бизнес-логики и выбора стека. Solidity 0.8.x — стандарт для EVM-совместимых чейнов: Ethereum, Arbitrum, Optimism, Polygon, BSC, Avalanche C-Chain. Для Solana используем Rust и Anchor: модель аккаунтов и программ требует явного объявления всех ресурсов. Для проектов с формальной верификацией подходит Move (Aptos, Sui) — линейные типы языка исключают копирование ресурсов на уровне компилятора. Vyper выбираем для контрактов, где критична простота аудита (Curve Finance).
| Язык |
Модель исполнения |
Типичная область |
Риски |
| Solidity 0.8.x |
EVM, последовательное исполнение |
DeFi, NFT, токены |
Reentrancy, переполнение (unchecked) |
| Rust (Anchor) |
Solana, параллельное |
Высоконагруженные DEX, игры |
Неправильное объявление аккаунтов |
| Move |
Aptos/Sui, ресурсная |
Крупные протоколы |
Сложность экосистемы |
| Vyper |
EVM, ограниченный синтаксис |
Критические контракты (Curve) |
Зависимость от стабильности компилятора |
Gas optimization — не преждевременная оптимизация, а архитектурное решение. На Ethereum mainnet деплой плохо спроектированного контракта может стоить 2–5 ETH только из-за неоптимального storage layout. Переупаковка структуры Proposal с 7 слотов до 4 сэкономила 18k gas на каждом голосовании — около $1.5 при gas price 30 gwei. Экономия на масштабе протокола с тысячами голосований в день даёт ощутимую годовую выгоду.
Типичные ошибки в gas: передача массивов через memory вместо calldata в external функциях (дороже в 2–3 раза); использование require с длинными строками вместо custom error error InsufficientBalance(...). Кастомные ошибки дешевле на 50–200 gas на revert и передают структурированные данные фронтенду.
Почему аудит смарт-контрактов критичен для безопасности
Аудит — не разовая проверка, а встроенный этап разработки. Используем три уровня:
-
Статический анализ —
Slither (30 секунд в CI) выявляет reentrancy, неинициализированные переменные, опасный delegatecall.
-
Фаззинг и invariant тесты —
Foundry с --fuzz-runs 50000 находит edge cases, которые пропускают сотни unit-тестов. Реальный кейс: AMM контракт с кастомной математикой после 150 тестов в Hardhat — Foundry нашёл integer division truncation, позволявший пылевой атаке копить dust на контракте. Echidna проверяет инварианты («сумма всех балансов ≤ totalSupply»).
-
Ручной code review — наши инженеры с опытом 10+ лет в блокчейне выявляют логические ошибки, которые не ловят инструменты. Для протоколов с TVL > $1M обязателен внешний аудит со стороны Trail of Bits, Consensys Diligence или OpenZeppelin. Срок — 2–4 недели.
Любой апгрейдируемый протокол должен иметь timelock. TimelockController из OpenZeppelin: операция предлагается → ждёт минимальный delay (48–72 часа) → выполняется. Без timelock один скомпрометированный deployer wallet = потеря всего пула.
Какие паттерны апгрейда выбираем
| Паттерн |
Механизм |
Риск |
Когда использовать |
Наш опыт |
| Transparent Proxy (OZ) |
admin vs user разделение |
Storage collision, centralization |
Стандартные проекты |
15+ реализаций |
| UUPS |
Логика апгрейда в implementation |
Забыть _authorizeUpgrade → контракт навсегда сломан |
Газ-оптимизированные проекты |
7 проектов |
| Diamond (EIP-2535) |
Множество facets |
Сложность аудита |
Крупные протоколы с 10+ контрактами |
3 внедрения |
| Beacon Proxy |
Один beacon для множества proxies |
Beacon = single point of failure |
Фабрики однотипных контрактов |
5 фабрик |
Storage collision — главная опасность прокси. Implementation v2 не должен добавлять переменные перед существующими. OpenZeppelin Upgrades plugin для Hardhat и Foundry проверяет это автоматически, но только при использовании его API.
Как защитить контракт от MEV и front-running
На Ethereum mainnet транзакции в mempool видны всем. MEV-боты проводят sandwich-атаки на DEX, фронтраннинги минтинга и governance. Решение: commit-reveal scheme для аукционов, приватная отправка через Flashbots PROTECT RPC. EIP-7702 и PBS (proposer-builder separation) меняют картину, но пока не массово.
Процесс разработки
-
Аналитика — спецификация функций, диаграмма вызовов, анализ edge cases. Без этого кодинг начинается впустую.
-
Разработка — Solidity/Rust с тестами параллельно. Тест → код → рефакторинг. Используем Foundry для fuzz и invariant тестов.
-
Внутренний аудит — Slither + Echidna + ручной code review. Foundry invariant tests для протокольных инвариантов.
-
Внешний аудит — для проектов с реальными деньгами. Срок: 2–4 недели.
-
Деплой — Foundry scripts или Hardhat Ignition с verify на Etherscan. Gnosis Safe для ownership transfer сразу после деплоя.
-
Мониторинг — Tenderly alerts, OpenZeppelin Defender, Forta Network.
Что входит в работу
- Документация на архитектуру и спецификацию контракта (NatSpec).
- Исходный код с репозиторием и CI (Slither, Foundry, coverage).
- Развёрнутая версия контракта с verify на блокчейн-эксплорере.
- Результаты аудита (внутреннего и внешнего по запросу).
- Доступы к мониторингу и управлению (Gnosis Safe).
- Гарантия на код: фиксы критических багов в течение месяца после деплоя.
- Консультация по интеграции с веб-интерфейсом (wagmi, RainbowKit).
Сроки ориентировочно
- ERC-20 token с базовыми функциями: 1–2 недели
- Vesting контракт с cliff/linear schedule: 2–3 недели
- NFT ERC-721/1155 с маркетплейсом: 4–6 недель
- AMM или lending протокол: 2–4 месяца
- Мультичейн протокол с bridge: 4–7 месяцев
Аудит добавляет 3–6 недель и идёт параллельно с финальным тестированием где возможно. Стоимость рассчитывается индивидуально — свяжитесь с нами, и мы оценим ваш проект бесплатно.
Закажите разработку смарт-контракта — получите консультацию по архитектуре и защите от reentrancy, MEV и gas-атак. Хотите обсудить детали? Напишите нам — мы подберём оптимальный стек под вашу задачу.