Читать состояние десяти контрактов по отдельности — это десять 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 месяц инцидент-менеджмента и поддержки.
- Обучение команды заказчика работе с контрактом.
Пошаговый процесс разработки
- Анализ требований — определяем сценарии использования, требования к безопасности и gas-лимиты.
- Проектирование архитектуры — выбираем между Multicall3 и кастомным контрактом, проектируем структуру данных.
- Написание кода — реализуем Solidity-контракт с учётом gas optimization и проверок.
- Тестирование — модульные тесты на Foundry, стресс-тесты на Tenderly, симуляция.
- Аудит безопасности — статический анализ (Slither, Mythril), ручной review опытными разработчиками.
- Деплой и верификация — развёртывание в целевой сети, верификация кода на Etherscan.
- Документация и поддержка — Natspec, README, 1 месяц инцидент-менеджмента.
Закажите разработку — наши инженеры оценят ваш проект за один день. Получите консультацию в Telegram или по почте. Опыт — 5+ лет, более 20 успешных запусков. Гарантируем чистоту кода и прохождение внешнего аудита.







