Материал проверен 2 ноября 2026?
БК

ГЛАВНАЯ / ИНСТРУКЦИИ / FALLBACK И RECEIVE В SOLIDITY: КУДА ПОПАДАЕТ ВЫЗОВ БЕЗ ФУНКЦИИ

fallback и receive в Solidity: куда попадает вызов без функции

В Solidity receive предназначена для вызова с пустым calldata, а fallback служит резервным обработчиком, если функция не найдена. Обе функции могут повлиять на приём Ether, но выбор зависит от calldata, наличия receive и payable. По одному факту перевода нельзя понять, какой код выполнился.

Маршрутизация

Сначала Solidity ищет функцию по selector

При обычном вызове calldata содержит selector функции и закодированные аргументы. Если selector совпадает с известной внешней функцией, выполняется её тело. Если функция не найдена, управление может перейти в fallback. Для пустого calldata отдельная receive имеет приоритет, если она определена.

Receive объявляется как receive() external payable без аргументов и возвращаемого значения. Она предназначена для пустого вызова, в том числе обычной передачи Ether без данных. Наличие этой функции не означает, что контракт принимает любой вызов с value: непустой calldata направляется по другим правилам.

  • пустой calldata маршрутизируется отдельно
  • receive должна быть external payable
  • неизвестный selector передаётся в fallback
Резервный обработчик

Fallback принимает неизвестный вызов, а Ether – только если он payable

Fallback вызывается, когда ни одна объявленная функция не совпала с selector, либо когда calldata пустой и receive отсутствует. Чтобы принять Ether по такому пути, fallback должен быть payable. Если он не payable, вызов с value завершается ошибкой.

Параметрическая форма fallback(bytes calldata input) может принять полный calldata и вернуть bytes. Эта форма применяется в низкоуровневой маршрутизации, например в proxy, но сама по себе не декодирует безопасно любой интерфейс. Сверяйте селектор, получателя и реализацию с ожидаемой схемой; ошибка ABI может отправить вызов в резервный путь.

  • fallback проверен на payable
  • параметрическая форма обрабатывает полный calldata
  • ошибка декодирования не признана безопасным вызовом
ВходЕсли receive естьЕсли receive нет
Пустой calldata, Etherreceivepayable fallback или отказ
Пустой calldata, без Etherreceivefallback
Неизвестный selectorfallbackfallback
Известная функцияФункция по selectorФункция по selector
Приём Ether

Обработчик не видит каждый способ увеличения баланса

Обычный перевод с пустым calldata вызывает receive или payable fallback согласно правилам dispatch. Но баланс контракта может увеличиться и без обычного вызова, например через предусмотренный протоколом механизм принудительной передачи. Тогда Solidity-функция получателя не исполняется, поэтому внутренний счётчик, обновляемый только в receive, может отличаться от address(this).balance.

Учтите ограничения газа вызывающей операции и не полагайтесь на устаревшее предположение, что send или transfer с жёстким stipend подходят для любой логики получателя. Если функция делает больше простого учёта, изучите актуальные правила вызова и тестируйте при достаточном gas; сам факт объявления receive не гарантирует успешную доставку.

Проверка вызова

Сопоставьте calldata, value и фактически выбранную функцию

В обозревателе или trace проверьте адрес назначения, длину calldata, первые четыре байта, переданный value и выбранный код. Для прокси выясните, переслал ли fallback вызов через delegatecall и какая реализация была активна на блоке. Ошибка декодирования интерфейса может показать «unknown method», хотя контракт обработал calldata резервной логикой.

Если ожидается простой перевод Ether, убедитесь, что calldata пустой и получатель может принять value выбранным путём. Если ожидалась конкретная операция, проверьте selector и ABI до подписи, а после исполнения – receipt и изменение состояния. Не делайте вывод о поведении только по названию кнопки кошелька.

FAQ

Частые вопросы

Когда вызывается receive?

При вызове контракта с пустым calldata, если receive объявлена.

Fallback всегда принимает Ether?

Нет. Для приёма Ether он должен быть payable; при наличии receive пустой вызов обрабатывает receive.

Неизвестный selector вызывает receive?

Нет. Он направляется в fallback, если тот есть.

Каждый Ether, поступивший на контракт, вызывает receive?

Нет. Существуют способы увеличения баланса без исполнения функции получателя.

Почему перевод сработал, хотя интерфейс не показал функцию?

Пустой перевод мог быть обработан receive или payable fallback; проверьте код и trace.

Итоговая проверка

Чек-лист: fallback и receive в solidity: куда попадает вызов без функции

  • calldata и selector проверены;
  • наличие receive/fallback установлено;
  • пустой и непустой вызовы различены;
  • payable путь подтверждён;
  • value и gas условия учтены;
  • proxy dispatch и активная реализация проверены;
  • receipt и состояние после вызова сверены.

Материал подготовлен редакцией сайта и проверен 2 ноября 2026 года. Условия бирж, кошельков и блокчейн-сетей могут меняться. Перед операцией сверяйте данные в интерфейсе выбранного сервиса.