Оптимизация газа смарт-контрактов: аудит и снижение стоимости транзакций

Оптимизация газа смарт-контрактов К нам обратился DeFi-проект: деплой их ERC-1155 контракта обошёлся в 0.8 ETH вместо ожидаемых 0.3. Пользователи платили по $15 за каждый `transfer()` при gas price 30 gwei, в то время как конкуренты — по $4. Причина — не storage layout и неоптимальные паттерны, к

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Оптимизация газа смарт-контрактов

К нам обратился DeFi-проект: деплой их ERC-1155 контракта обошёлся в 0.8 ETH вместо ожидаемых 0.3. Пользователи платили по $15 за каждый transfer() при gas price 30 gwei, в то время как конкуренты — по $4. Причина — не storage layout и неоптимальные паттерны, которые компилятор Solidity не исправляет за вас. Мы провели аудит газа и снизили стоимость деплоя на 62%, а транзакций — в 3 раза. Наш опыт оптимизации 50+ контрактов показывает, что 80% потерь устраняются правильной архитектурой хранилища. Каждая лишняя операция SLOAD или SSTORE умножается на тысячи вызовов. В этой статье мы разберём конкретные паттерны, которые дают экономию 30–50% на типовых контрактах.

Почему storage — главный источник потерь газа?

SSTORE стоит 20 000 gas при записи в холодный слот, 2 900 gas при обновлении тёплого. SLOAD — 2 100 gas для холодного, 100 для тёплого (согласно EIP-2929). Именно поэтому архитектура хранилища определяет 60-80% стоимости контракта.

Slot packing — первый инструмент. EVM хранит данные в 32-байтовых слотах. Если объявить переменные так:

// Плохо: 3 слота uint128 a; uint256 b; uint128 c; // Хорошо: 2 слота (a и c упакованы) uint128 a; uint128 c; uint256 b; 

Даёт экономию двух SLOAD при чтении. На контракте с 10 000 деплоями экономия — сотни ETH суммарно.

Таблица стоимости операций storage

Операция Gas (холодный) Gas (тёплый)
SLOAD 2100 100
SSTORE (new) 20000 20000
SSTORE (update) 2900 2900
BALANCE 2600 100

Это не просто цифры — знание этих значений позволяет выбирать между чтением из storage и вычислением.

Как найти узкие места в контракте?

Инструменты анализа

Инструмент Что показывает
Hardhat Gas Reporter Gas на каждый вызов функции в тестах
Foundry forge test --gas-report То же, но быстрее и с diff между коммитами
eth-gas-reporter Детализация по opcodes через --verbose
Tenderly Gas Profiler Breakdown по EVM-трейсу реальной транзакции
Remix Gas Estimation Быстрая проверка без setup

Foundry — предпочтительный выбор. forge snapshot создаёт .gas-snapshot файл, который можно коммитить в репозиторий и отслеживать регрессии газа в CI:

forge snapshot # изменяем код forge snapshot --diff 

Разница сразу видна построчно по каждой функции.

Mappings vs Arrays

mapping(uint256 => address) — O(1) доступ, gas-эффективен. address[] с поиском по значению — O(n) и в 99% случаев ошибка архитектуры. Если нужна итерация — индексируй через события, читай off-chain через The Graph.

Неочевидный источник: keccak256 на коротких строках

string memory name в функции, которая вызывается тысячи раз — это ABI encoding overhead. Замена строк на bytes32 константы там, где строки известны заранее, даёт 200-500 gas на вызов.

Конкретные паттерны оптимизации

Custom errors вместо require с строками

// До: 24 000 gas на деплой одной строки require(amount > 0, "Amount must be positive"); // После: экономия ~200 gas per revert + меньше байткода error AmountZero(); if (amount == 0) revert AmountZero(); 

Custom errors (EIP-838) стали стандартом с Solidity 0.8.4. Строки в require — это bytecode, который увеличивает стоимость деплоя и revert.

Unchecked arithmetic

С Solidity 0.8.0 все арифметические операции проверяют overflow по умолчанию. Проверка стоит ~100 gas per operation. Там, где overflow математически невозможен:

unchecked { ++i; // в цикле for — стандартный паттерн total += amounts[i]; // если суммы ограничены и проверены выше } 

На цикле из 100 итераций — экономия 10 000+ gas.

Immutable и constant

constant — значение встраивается в байткод, SLOAD не нужен. immutable — значение записывается в байткод при деплое, читается как PUSH32. Оба в ~3 раза дешевле чтения из storage. Адрес токена, fee basis points, адрес owner в контракте, который не апгрейдится — всё это кандидаты на immutable.

Calldata vs memory для входных параметров

// memory — копирует данные в память function process(uint256[] memory ids) external // calldata — читает напрямую из calldata, не копирует function process(uint256[] calldata ids) external 

Для внешних функций (external), где данные только читаются — calldata дешевле. Разница растёт с размером массива: на массиве из 50 элементов — 3 000-5 000 gas.

Что входит в оптимизацию газа

  • Аудит baseline: запускаем все тесты с forge test --gas-report, фиксируем baseline. Никаких изменений без измерений до и после.
  • Профилирование через Tenderly: берём реальные транзакции из mainnet (если контракт уже задеплоен) или симулируем в Tenderly fork. Смотрим breakdown по EVM opcodes.
  • Итеративная оптимизация: применяем изменения по одному, измеряем. Slot packing обычно даёт наибольший эффект — начинаем с него.
  • Regression testing: forge snapshot в CI. Любой PR, который увеличивает gas более чем на 1%, требует обоснования.
  • Документация и отчёт: фиксируем все изменения, экономию по каждой функции, рекомендации по дальнейшей поддержке.

Мы также предоставляем обучение команды: как не наступать на те же грабли в будущем.

Пример расчета экономии на storage packing Контракт с 1 000 000 вызовов `mint` с 3 слотами вместо 2: каждый лишний SLOAD стоит 100 gas (warm) или 2100 (cold). При 30 gwei экономия составляет от нескольких сотен долларов.

Процесс работы

  1. Аналитика: аудит текущего контракта, анализ gas profile.
  2. Проектирование: определяем паттерны, которые дадут максимальный эффект.
  3. Реализация: вносим изменения в код, пишем тесты.
  4. Тестирование: regression, stress test, deploy на testnet.
  5. Деплой: развёртывание оптимизированного контракта, миграция данных (если нужно).

Ориентиры по срокам

Аудит газа существующего контракта + отчёт с рекомендациями: 1-2 дня. Оптимизация с имплементацией изменений и тестами: 2-3 дня в зависимости от сложности контракта. Полная переработка storage layout (если архитектура изначально неоптимальна): от 1 недели, так как требует миграционных скриптов для существующих данных.

Стоимость рассчитывается после анализа контракта и текущего gas profile.

Почему выбирают нас?

  • Более 5 лет опыта в разработке смарт-контрактов на Solidity, Rust и Vyper.
  • Выполнили аудит и оптимизацию для 30+ DeFi-проектов, включая протоколы с TVL > $50M.
  • Гарантируем снижение газа на 20–50% на ключевых функциях.
  • Работаем с контрактами на Ethereum, Polygon, Arbitrum, Optimism, Base, Solana, BNB Chain.

Если вы ищете, как снизить стоимость транзакций и сэкономить на деплое, свяжитесь с нами для бесплатной предварительной оценки. Получите консультацию инженера — определим потенциал оптимизации за 1 час.