Разработка Multicall-контрактов (batch операции)

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

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

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

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

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

Читать состояние десяти контрактов по отдельности — это десять RPC-запросов, десять round-trip-ов до ноды. На публичных эндпоинтах загрузка dApp растягивается на 2–5 секунд. Batch-операции Multicall решают проблему: на чтение — агрегация запросов в один RPC вызов, на запись — несколько on-chain операций в одной транзакции. Нагрузка на ноду снижается на 90%, пользовательский опыт становится отзывчивым.

Наш опыт — 5+ лет в Web3, мы развернули более 20 смарт-контрактов для DeFi-протоколов, NFT-маркетплейсов и кросс-чейн мостов. Все контракты проходят аудит безопасности, гарантируем соответствие лучшим практикам.

Как Multicall3 снижает RPC-нагрузку?

Multicall3 на адресе 0xcA11bde05977b3631167028862bE2a173976CA11 задеплоен на 50+ сетях. Принимает массив (address target, bytes callData), исполняет все call-ы и возвращает результаты. Для read-only запросов используется eth_call, при этом все вызовы выполняются за один RPC-запрос.

Типичное использование через wagmi/viem:

import { useReadContracts } from 'wagmi';

const { data } = useReadContracts({
  contracts: [
    { address: token1, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
    { address: token2, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
    { address: pool, abi: poolAbi, functionName: 'getReserves' },
    { address: oracle, abi: oracleAbi, functionName: 'latestAnswer' },
  ]
});
// один RPC запрос вместо четырёх

Wagmi использует Multicall3 под капотом: все вызовы в одном useReadContracts схлопываются в один eth_call. Если сеть не поддерживает Multicall3, wagmi fallback-ает к параллельным eth_call, что всё равно экономит время. Экономия газа до 70% в batch-операциях.

Когда кастомный контракт выигрывает?

Multicall3 не хранит состояние, не проверяет авторизацию, не поддерживает нативный ETH на отдельные вызовы. Для write-операций с кастомной логикой пишем собственный контракт.

Паттерн self-multicall — контракт вызывает сам себя через несколько функций в одной транзакции. OpenZeppelin Multicall реализует это через Multicall.sol:

abstract contract Multicall {
    function multicall(bytes[] calldata data)
        external
        virtual
        returns (bytes[] memory results)
    {
        results = new bytes[](data.length);
        for (uint256 i = 0; i < data.length; i++) {
            (bool success, bytes memory result) = address(this).delegatecall(data[i]);
            require(success, _getRevertMsg(result));
            results[i] = result;
        }
    }
}

delegatecall на address(this) — контракт вызывает свои функции от имени оригинального msg.sender. Это позволяет делать approve + deposit в одном вызове, где оба шага видят одинаковый msg.sender.

Критическое предупреждение по безопасности

delegatecall на address(this) с пользовательским data — потенциальная уязвимость. Если контракт не изолирован от привилегированных функций, атакующий может составить data, вызывающий transferOwnership. OpenZeppelin предупреждает: не используйте этот паттерн с контрактами, где авторизация зависит от msg.sender, без дополнительных проверок. Мы при разработке обязательно применяем проверки прав доступа на каждом шаге: каждая функция, доступная через self-multicall, проверяет msg.sender.

Как реализовать атомарные multi-step операции?

Для сложных DeFi операций (flash loan → swap → repay) нужен контракт с промежуточным состоянием, который откатывает всё при ошибке любого шага:

contract AtomicBatcher {
    struct Step {
        address target;
        bytes callData;
        uint256 value;
        uint256 minReturnValue; // проверка результата
    }
    
    function executeBatch(Step[] calldata steps) 
        external 
        payable 
        returns (bytes[] memory results) 
    {
        results = new bytes[](steps.length);
        for (uint256 i = 0; i < steps.length; i++) {
            (bool success, bytes memory result) = steps[i].target.call{
                value: steps[i].value
            }(steps[i].callData);
            
            require(success, string(abi.encodePacked("Step ", i, " failed")));
            
            if (steps[i].minReturnValue > 0) {
                uint256 returnValue = abi.decode(result, (uint256));
                require(returnValue >= steps[i].minReturnValue, "Slippage exceeded");
            }
            
            results[i] = result;
        }
        
        // вернуть незатраченный ETH
        if (address(this).balance > 0) {
            (bool sent,) = msg.sender.call{value: address(this).balance}("");
            require(sent);
        }
    }
}

minReturnValue — встроенная защита от slippage на каждом шаге. Swap вернул меньше минимума — вся транзакция откатывается.

Сравнение Multicall3 и кастомного контракта

Сценарий Multicall3 Кастомный
Агрегация read-запросов Достаточно Избыточно
Несколько ERC-20 transfer Достаточно Избыточно
Approve + protocol action (один токен) Достаточно Достаточно
Flash loan + arbitrage + repay Не подходит Нужен
Условные действия (если результат шага X > Y) Не подходит Нужен
Распределение ETH по адресам с разными суммами Не подходит Нужен

Оценка длительности разработки

Сложность Примерная длительность Gas-оптимизация
Простая (read aggregation) 1 день Достаточно Multicall3
Средняя (write batch с проверками) 2-3 дня Частично кастомная
Сложная (multi-step DeFi) 3-5 дней Полностью кастомная

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

  • Анализ требований и проектирование архитектуры.
  • Написание и тестирование Solidity-контракта (Foundry, Tenderly).
  • Аудит безопасности (Slither, Mythril, ручной review).
  • Деплой и верификация кода на Etherscan.
  • Документация (Natspec, README) и доступ к репозиторию.
  • 1 месяц инцидент-менеджмента и поддержки.
  • Обучение команды заказчика работе с контрактом.

Пошаговый процесс разработки

  1. Анализ требований — определяем сценарии использования, требования к безопасности и gas-лимиты.
  2. Проектирование архитектуры — выбираем между Multicall3 и кастомным контрактом, проектируем структуру данных.
  3. Написание кода — реализуем Solidity-контракт с учётом gas optimization и проверок.
  4. Тестирование — модульные тесты на Foundry, стресс-тесты на Tenderly, симуляция.
  5. Аудит безопасности — статический анализ (Slither, Mythril), ручной review опытными разработчиками.
  6. Деплой и верификация — развёртывание в целевой сети, верификация кода на Etherscan.
  7. Документация и поддержка — Natspec, README, 1 месяц инцидент-менеджмента.

Закажите разработку — наши инженеры оценят ваш проект за один день. Получите консультацию в Telegram или по почте. Опыт — 5+ лет, более 20 успешных запусков. Гарантируем чистоту кода и прохождение внешнего аудита.

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

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