Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Функции и модификаторы
functions_modifiers

Функции и модификаторы

Видимость, pure/view/payable, модификаторы доступа, constructor, fallback и receive

Функции и модификаторы

Модификатор доступа — это не просто синтаксический сахар, а один из главных инструментов безопасности контракта

#Видимость функций

Solidity имеет четыре уровня видимости для функций.

public — функция вызывается как извне (через транзакцию), так и внутри контракта и наследниками. Компилятор создаёт и внешний интерфейс, и internal-вызов.

external — функция вызывается только извне. Нельзя вызвать через this.foo() внутри контракта (технически можно, но это внешний вызов с накладными расходами). Эффективнее public для функций, которые не нужны внутри: параметры-массивы читаются из calldata без копирования в memory.

internal — доступна внутри контракта и наследникам, но не снаружи. Аналог protected в Java.

private — только внутри данного контракта. Наследники не видят. Важно: private не означает секретность — данные storage видны в блокчейне, просто другие контракты не могут вызвать функцию напрямую.

#Мутабельность состояния

view — функция читает state, но не изменяет. Вызов off-chain (через eth_call) бесплатен. При вызове из другой транзакции газ всё равно тратится на накладные расходы.

pure — функция не читает и не изменяет state. Зависит только от аргументов. Полезна для математических утилит, хэш-функций, кодирования.

Функция без этих модификаторов может изменять state — и требует транзакции.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract Vault { address public owner; uint256 private balance; constructor() { owner = msg.sender; } // external + payable: принимает ETH function deposit() external payable { balance += msg.value; } // pure: чистые вычисления, не читает storage function calculateFee(uint256 amount) public pure returns (uint256) { return amount / 100; // 1% } // view: читает storage, не изменяет function getBalance() external view returns (uint256) { return balance; } }

#Payable

Функции, помеченные payable, могут принимать ETH вместе с вызовом. Если вызвать обычную функцию с ненулевым msg.value — транзакция отклонится.

msg.value — сумма ETH (в Wei), отправленная с текущим вызовом. Константа в рамках вызова функции. msg.sender — адрес, который вызвал текущую функцию (может быть EOA или другой контракт).

#Модификаторы

Модификатор — это многоразовый "декоратор" для функций. Он добавляет логику до и/или после тела функции, не дублируя код.

// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; contract Ownable { address public owner; constructor() { owner = msg.sender; } // Модификатор: проверяет, что вызывает владелец modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; // здесь вставляется тело функции } // Модификатор с параметром modifier costs(uint256 price) { require(msg.value >= price, "Insufficient payment"); _; } function withdraw() external onlyOwner { payable(owner).transfer(address(this).balance); } function premiumAction() external payable costs(0.1 ether) { // действие доступно только при оплате минимум 0.1 ETH } function transferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0), "Zero address"); owner = newOwner; } }

Символ _; — место, куда вставляется тело декорируемой функции. Можно поставить до или после проверок. Можно поставить несколько раз — тело выполнится несколько раз (редкий приём). Можно использовать несколько модификаторов на одной функции — они применяются слева направо.

Важно: модификаторы не являются функциями в смысле ABI — компилятор inline вставляет их код в каждую функцию, к которой они применены.

#Constructor

Конструктор выполняется ровно один раз — при деплое контракта. После этого его код не хранится в контракте (экономия газа). Конструктор не имеет имени с версии Solidity 0.4.22 — просто ключевое слово constructor.

Конструктор может быть payable — тогда при деплое можно отправить ETH. Если конструктор не объявлен, создаётся пустой конструктор по умолчанию.

#Fallback и Receive

Это специальные функции, вызываемые автоматически в определённых ситуациях.

receive() external payable — вызывается, когда контракт получает ETH без данных (пустой calldata). Обязана быть payable. Используется для простых ETH-кошельков.

fallback() external [payable] — вызывается, если ни одна функция не совпала с selector в calldata, или если calldata пустой, но receive не определён. Может быть помечена payable для приёма ETH.

contract ETHReceiver { event Received(address sender, uint256 amount); event FallbackCalled(address sender, bytes data); // Принимает ETH без данных receive() external payable { emit Received(msg.sender, msg.value); } // Принимает любые вызовы с неизвестным selector fallback() external payable { emit FallbackCalled(msg.sender, msg.data); } }

Это поведение важно для proxy-контрактов: proxy перехватывает все вызовы через fallback и перенаправляет их через delegatecall к реализации. Этот паттерн разберём в финальной теме.

Далее: События и обработка ошибок