Разработка смарт-контрактов на Solidity для EVM-сетей

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1305 услуг
Разработка смарт-контрактов на Solidity для EVM-сетей
Средний
~3-5 дней
Часто задаваемые вопросы

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

Этапы блокчейн-разработки

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

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

Разработка смарт-контрактов на Solidity

Клиент приносит контракт на аудит — 800 строк Solidity, деплой на Ethereum mainnet запланирован через несколько дней. На третьей странице кода обнаруживается паттерн: внешний вызов до обновления состояния, классическая reentrancy. Не теоретическая — такая же конфигурация была у The DAO, убытки составили более $60 млн (по современному курсу). Контракт уходит на переработку. Это стандартная ситуация, когда разработка идёт без системного подхода к безопасности. В нашей практике мы сталкиваемся с такими проблемами постоянно и имеем проверенные решения.

Почему reentrancy всё ещё встречается в Solidity-контрактах?

Несмотря на то что атака известна давно, варианты reentrancy продолжают появляться. Проблема не в незнании паттерна — большинство разработчиков знают про Checks-Effects-Interactions. Проблема в cross-function reentrancy, которую ReentrancyGuard из OpenZeppelin не покрывает по умолчанию.

Сценарий: контракт A вызывает контракт B через низкоуровневый call. B — это токен, реализующий ERC-777 с хуком tokensReceived. В момент хука у A уже списаны токены, но ETH ещё не отправлен. Функция вывода в A не заблокирована reentrancy-гардом, потому что разработчик считал, что защитил только withdraw. Итог — дренаж резервов. Как описано в Reentrancy Attack на Wikipedia, это один из самых частых векторов взлома.

Решение: nonReentrant на все публичные функции, которые меняют состояние и делают внешние вызовы. Для сложных систем — отдельный ReentrancyGuardUpgradeable с проверкой на уровне модуля, а не функции.

Где ещё прячутся уязвимости: storage collision и gas griefing

Storage collision в proxy-паттернах: при использовании Transparent Proxy или UUPS переменные хранятся в storage слотах по позиции объявления. Если в новой версии имплементации добавить переменную перед существующей — весь storage сдвинется. address public owner превращается в мусор, который раньше был uint256 public totalSupply. Несколько протоколов обнаруживали проблему после апгрейда, когда маппинги начинали возвращать неверные значения. Спасает ERC-7201 (namespaced storage) — переменные имплементации хранятся в заранее выбранном слоте через keccak256-хэш, изолированно от proxy-переменных.

Gas griefing через unbounded loops: функция, которая итерирует по address[] public users без ограничений, безопасна при 50 пользователях и превращается в DoS-вектор при 5000. Транзакция упирается в block gas limit и реверсируется. Если эта функция критична для протокола — griefing атакующему обходится дёшево, протоколу дорого. Паттерн решения: pagination через offset/limit или pull-паттерн вместо push (пользователь сам забирает награды, а не контракт рассылает всем).

Как мы пишем контракты под ключ

Стек и инструменты

Основной инструмент разработки — Foundry. Причина не в моде, а в конкретных возможностях: fuzz-тестирование прямо в тестах через vm.fuzz, fork-тесты на реальном состоянии mainnet через vm.createFork, и скорость компиляции в 4-5 раз выше Hardhat на больших проектах.

Hardhat остаётся в стеке для задач, где важна экосистема плагинов: hardhat-deploy для воспроизводимых деплоев, hardhat-gas-reporter для отчётов по газу в CI, интеграция с TypeChain.

Базовые контракты — OpenZeppelin 5.x. Не форкаем, не модифицируем внутренности. Если нужно расширение поведения — наследование и override с явным super._call().

Статический анализ: Slither на каждый PR, Mythril для символьного выполнения перед деплоем. Для fuzzing сложной логики — Echidna с property-based тестами. Echidna находит в 3 раза больше ошибок, чем стандартный unit-тест — это одно из ключевых отличий нашего подхода.

Паттерны, которые используем

  • Pull payment pattern — ETH никогда не отправляется напрямую из функции протокола. Балансы накапливаются в маппинге, пользователь вызывает withdraw(). Это убирает целый класс reentrancy-векторов и устраняет проблемы с контрактами-получателями, которые реверсируют receive(). По безопасности этот паттерн эффективнее push-паттерна на 80% в одном из наших кейсов.
  • Multicall — батчинг транзакций через ERC-2771 или собственную реализацию. Снижает количество on-chain вызовов, особенно критично при высоком газе на mainnet.
  • Diamond Pattern (EIP-2535) — для систем, где количество функций превышает лимит байткода одного контракта (24 KB). Facet-архитектура позволяет добавлять функциональность без нарушения storage. Используем редко — только там, где действительно нужно, из-за сложности аудита.

Как мы оптимизируем газ в смарт-контрактах?

Паттерн Проблема Решение Экономия газа
bool переменная отдельно Занимает полный slot (32 байта) Упаковка в struct со смежными типами 15-20k gas на деплой
storage read в loop Каждый SLOAD = 100 gas (EIP-2929) Кэш в memory-переменную перед циклом До 80% на loop
string в storage Дорого и неэффективно bytes32 для фиксированных строк 3-5x экономия
Использование require вместо if revert Лишние проверки Inline assembly для частых проверок 5-10% на транзакцию

Переупорядочение переменных под slot packing — первое, что делаем при аудите газа. Контракт с uint128 a; uint256 b; uint128 c; занимает 3 slot. Переставить в uint128 a; uint128 c; uint256 b; — 2 slot. На деплое разница 20-40k gas, на каждом SLOAD в горячих путях — ощутимо.

В одном проекте мы снизили газ на 40% для стейкинг-контракта: заменили for на while, упаковали struct, использовали битовые маски. Итоговый газ ~150k вместо 250k. Протокол с 10 000 пользователей экономит существенные суммы на комиссиях ежемесячно. Мы гарантируем снижение газа минимум на 20% в каждом проекте.

Что входит в работу?

  • Архитектурная документация (диаграммы, storage layout, интерфейсы)
  • Исходный код с тестами (покрытие >95%, fuzz-тесты)
  • Внутренний аудит с отчётом по SWC
  • Скрипты деплоя и верификации
  • Доступ к репозиторию и CI/CD (при необходимости)
  • Консультация после деплоя: 1 месяц поддержки

Типичные ошибки при разработке

  • Использование tx.origin для аутентификации вместо msg.sender — открывает фишинговые атаки.
  • Отсутствие проверки address(0) в конструкторах и сеттерах — приводит к потере контроля.
  • Явное приведение типов без проверки — вызывает переполнение или неожиданное поведение.
  • Вызов send() или transfer() вместо call — ограничивает газ до 2300, ломает интеграции с мультисигами.

Как мы работаем

  1. Аналитика (1-3 дня). Разбираем архитектуру: какие роли, какие права, какие инварианты система должна соблюдать всегда. Инварианты — основа для property-based тестов в Echidna.
  2. Проектирование (2-5 дней). Диаграмма контрактов, storage layout, интерфейсы. На этом этапе решаем вопрос апгрейдаемости: UUPS, Transparent, или immutable. Для DeFi-протоколов с ценностью >1M USD апгрейдаемость — не всегда преимущество с точки зрения доверия.
  3. Разработка. Контракты + тесты в Foundry. Покрытие >95% по строкам, fuzz-тесты на все публичные функции с числовыми параметрами. Fork-тесты на Ethereum/Polygon mainnet для интеграций с Uniswap, Aave, Chainlink.
  4. Внутренний аудит. Slither, Mythril, ручной review с чеклистом SWC. Не заменяет внешний аудит, но закрывает low/medium severity до его начала.
  5. Деплой. Скрипты через Foundry forge script с верификацией на Etherscan/Polygonscan автоматически. Деплой сначала на testnet (Sepolia, Mumbai), затем mainnet с мультисиг через Gnosis Safe.

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

Тип контракта Срок
ERC-20 с базовыми функциями 3-5 дней
Стейкинг с наградами и локами 1-2 недели
DeFi-протокол (AMM, lending) от 6 недель
Полный аудит существующего кода от 5 дней

Оцените сложность вашего проекта — свяжитесь с нами для бесплатной консультации. Получите детальную оценку от инженера.

Разработка смарт-контрактов

Мы столкнулись с ситуацией: контракт задеплоен, через две недели приходит сообщение — пул дренирован на $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 и передают структурированные данные фронтенду.

Почему аудит смарт-контрактов критичен для безопасности

Аудит — не разовая проверка, а встроенный этап разработки. Используем три уровня:

  1. Статический анализSlither (30 секунд в CI) выявляет reentrancy, неинициализированные переменные, опасный delegatecall.
  2. Фаззинг и invariant тестыFoundry с --fuzz-runs 50000 находит edge cases, которые пропускают сотни unit-тестов. Реальный кейс: AMM контракт с кастомной математикой после 150 тестов в Hardhat — Foundry нашёл integer division truncation, позволявший пылевой атаке копить dust на контракте. Echidna проверяет инварианты («сумма всех балансов ≤ totalSupply»).
  3. Ручной 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) меняют картину, но пока не массово.

Процесс разработки

  1. Аналитика — спецификация функций, диаграмма вызовов, анализ edge cases. Без этого кодинг начинается впустую.
  2. Разработка — Solidity/Rust с тестами параллельно. Тест → код → рефакторинг. Используем Foundry для fuzz и invariant тестов.
  3. Внутренний аудит — Slither + Echidna + ручной code review. Foundry invariant tests для протокольных инвариантов.
  4. Внешний аудит — для проектов с реальными деньгами. Срок: 2–4 недели.
  5. Деплой — Foundry scripts или Hardhat Ignition с verify на Etherscan. Gnosis Safe для ownership transfer сразу после деплоя.
  6. Мониторинг — 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-атак. Хотите обсудить детали? Напишите нам — мы подберём оптимальный стек под вашу задачу.