Разработчик пишет код для автоматического распределения средств, но сталкивается с тем, что контракт срабатывает при любых условиях или выдает ошибку при попытке вызвать функцию. Это происходит из-за неправильного синтаксиса проверок или неверного выбора оператора. Разберемся, как использовать логические выражения в смарт-контрактах, чтобы код работал строго по инструкции. Вы узнаете, как настроить условия в блокчейне и защитить функции от несанкционированного доступа за несколько минут.
Особенности синтаксиса условий в Solidity
В языке Solidity логика прописывается внутри функций. Здесь используются стандартные конструкции, которые интерпретирует виртуальная машина Ethereum (EVM). Условия определяют, будет ли выполнена та или иная часть кода в момент транзакции. Основная задача логики в блокчейне — гарантировать, что состояние контракта изменится только при соблюдении всех заданных правил.
Работа с булевыми переменными и инициализация
Для создания условий требуются булевы значения. В Solidity используется специальный тип данных bool. Он принимает только два возможных значения: true (истина) или false (ложь).
Объявление переменной происходит простым указанием типа и имени. Например, bool public isOpen = true;. Инициализация базовых условий позволяет создавать «переключатели» в коде, которые меняют поведение контракта в зависимости от текущего состояния системы.
Пошаговое руководство по базовым операторам и конструкциям
Реализация простой логики в смарт-контракте строится по следующему алгоритму:
- Определите переменную или условие сравнения. Используйте операторы
>,<или==для сопоставления значений. - Напишите ключевое слово if. Укажите условие в круглых скобках. Если результат будет true, код внутри фигурных скобок выполнится.
- Добавьте блок else. Пропишите действия, которые должны произойти, если условие оказалось ложным.
- Примените логические связки для сложных проверок. Используйте оператор
&&(AND), если должны быть верны оба условия, или||(OR), если достаточно одного из них. - Используйте оператор
!(NOT). Он инвертирует значение: истина станет ложью, и наоборот.
Я однажды перепутал операторы && и || в проверке прав доступа, из-за чего любой пользователь мог вызвать административную функцию. Это напомнило мне о важности тщательного тестирования каждой ветки условий.
Инструменты для реализации сложной бизнес-логики
Для защиты контракта недостаточно обычных if-else. Существуют специализированные функции:
- require — проверяет входные данные или условия перед выполнением кода. Если условие ложно, транзакция отменяется, а часть газа возвращается пользователю.
- assert — используется для проверки внутренних инвариантов. Если assert возвращает false, это означает критическую ошибку в коде, и все ресурсы транзакции сгорают.
- Модификаторы — позволяют вынести повторяющиеся проверки (например, проверку на владельца контракта) в отдельный блок и применять их к разным функциям.
Основные операторы сравнения и логические связки
Для быстрого написания кода используйте следующую таблицу соответствий:
| Символ | Название | Действие |
|---|---|---|
&& |
Логическое И (AND) | Вернет true, если оба условия истинны |
|| |
Логическое ИЛИ (OR) | Вернет true, если хотя бы одно условие истинно |
! |
Логическое НЕ (NOT) | Инвертирует логическое значение |
== |
Равно | Проверяет равенство двух значений |
!= |
Не равно | Проверяет неравенство двух значений |
Связь логики с массивами, циклами и внешними вызовами
Логические выражения часто работают в связке с итераторами. Внутри циклов while или for можно использовать if для фильтрации элементов массива. Например, при переборе списка адресов контракт может проверять, соответствует ли конкретный адрес заданному критерию.
При внешних вызовах к другим смарт-контрактам логика используется для обработки ответа. Если сторонний контракт возвращает булево значение, оно становится триггером для дальнейших действий в основном коде.
Типичные ошибки и проблемы безопасности
При написании условий часто допускаются промахи, которые стоят дорого:
- Избыточный расход газа. Слишком сложные вложенные условия внутри циклов резко увеличивают стоимость транзакции.
- Логические дыры. Отсутствие проверки на нулевой адрес (
address(0)) может привести к потере средств. - Неверный выбор функции. Использование assert вместо require для проверки пользовательского ввода.
Я заметил, что вынос сложных вычислений из условий в отдельные локальные переменные немного снижает стоимость газа для конечного пользователя.
Часто задаваемые вопросы
В чем разница между require и if?
if просто направляет поток выполнения, а require полностью останавливает транзакцию и откатывает все изменения в блокчейне при ошибке.
Как сэкономить газ при использовании условий?
Старайтесь ставить самые «дешевые» и наиболее вероятные ложные условия в начало цепочки &&, чтобы EVM прекратила проверку как можно раньше.
Можно ли использовать цикл while в смарт-контрактах?
Можно, но это опасно. Если цикл окажется бесконечным или слишком длинным, транзакция будет отклонена из-за превышения лимита газа.
Что происходит, если assert возвращает false?
Происходит паника (Panic), транзакция прерывается, и весь затраченный газ сгорает без возврата.
Безопасно ли использовать много вложенных if?
Это работает, но делает код трудночитаемым. Я рекомендую использовать модификаторы или разделять логику на несколько мелких функций.
Сравнение функций проверки условий
| Параметр | require | assert |
|---|---|---|
| Цель | Валидация ввода, проверка условий | Проверка внутренних ошибок кода |
| Поведение при ошибке | Отмена транзакции (Revert) | Критический сбой (Panic) |
| Затраты газа | Возвращает остаток газа пользователю | Потребляет весь доступный газ |


