Solidity для чайников: Секреты безопасных смарт-контрактов, которые не расскажут в школе.

Защита от переполнений и потерь точности

Базовые учебники по Solidity часто упоминают переполнения и потерь точности. Однако, недостаточно просто использовать SafeMath библиотеки. Необходимо понимать, как они работают и какие сценарии они не покрывают.

safe math library example code snippet

Рассмотрим пример: при использовании

uint

переменных, переполнение приводит к возврату к нулю. Это может привести к неожиданному поведению, особенно в контексте токенов или распределения активов. В более новых версиях Solidity (0.8.0+) переполнения и потерь точности обычно отлавливаются компилятором и генерируют ошибку во время компиляции, что значительно упрощает задачу. Однако, необходимо понимать, что это не панацея. Особенно важно внимательно следить за использованием

unchecked

блоков, в которых эти проверки отключаются для оптимизации газа.

Reentrancy – змея, которая возвращается укусить

Reentrancy атаки – один из самых распространенных и опасных типов атак на смарт-контракты. Они возникают, когда контракт вызывает внешнюю функцию, и эта функция вызывает обратно в контракт до завершения первоначального вызова. Если контракт не защищен должным образом, злоумышленник может использовать это для многократного снятия средств или изменения состояния.

reentrancy attack diagram

Как предотвратить reentrancy:

  • Check-Effects-Interactions Pattern:


    Сначала выполняйте действия, которые изменяют состояние контракта, а затем вызывайте внешние функции.


  • Reentrancy Guards:

    Используйте переменные состояния (например,

    bool private _isProcessing;

    ) для предотвращения рекурсивных вызовов. Это самый простой и эффективный способ защиты.


  • Pull over Push:

    Вместо того, чтобы отправлять средства напрямую (push), позволяйте пользователям самостоятельно запрашивать их (pull).

Делегирование вызовов и DelegateCall

DelegateCall – мощный инструмент, который позволяет одному контракту выполнять код другого. Он может быть использован для создания гибких и модульных систем, но он также может быть источником уязвимостей, если используется неправильно.

delegate call diagram showing how it executes code from another contract

Важно понимать, что при использовании

delegatecall

, контекст вызова (sender,

msg.data

,

msg.value

) прикрепляется к вызываемому контракту. Это может позволить злоумышленнику изменить состояние вызываемого контракта, используя

delegatecall

для выполнения вредоносных функций.


Совет:

Будьте крайне осторожны при использовании

delegatecall

, особенно если вызываемый контракт не принадлежит вам и вы не полностью доверяете его коду.

Проблемы с округлением и математические операции

При работе с дробями и точными значениями в смарт-контрактах, ошибки округления могут привести к значительным потерям для пользователей. Вместо использования стандартных операций над числами с плавающей запятой, рекомендуется использовать библиотеки, специально разработанные для работы с точными значениями.

floating point number example showing rounding errors

Пример: Если вы хотите разделить два числа и получить точный результат, вы можете использовать библиотеку, которая работает с большими целыми числами, а затем преобразовать результат в нужное представление.

Front Running и Gas Withholding

Front running – это когда злоумышленник наблюдает за транзакциями в мемпуле и использует эту информацию для получения прибыли. Gas withholding – это когда злоумышленник перехватывает газ, предназначенный для другого пользователя, и использует его для своих целей.

front running example diagram showing how a malicious actor can exploit pending transactions


Как защититься:

  • Используйте механизмы задержки транзакций.
  • Разрабатывайте смарт-контракты с учетом возможности front running.

  • Используйте механизмы обфускации кода.

Проверка входных данных: невидимые угрозы

Всегда тщательно проверяйте все входные данные. Не полагайтесь на то, что пользователи будут предоставлять корректные данные. Используйте assert и require для проверки допустимости входных данных.

input validation example code snippet

Проверка входных данных – это один из самых простых и эффективных способов защиты смарт-контрактов от уязвимостей.

Аудит кода – ваш лучший друг

Даже если вы являетесь опытным разработчиком, важно проводить аудит вашего кода другими экспертами. Аудиторы могут обнаружить уязвимости, которые вы могли пропустить.


Важно:

Аудит должен проводиться независимыми экспертами, не связанными с разработкой смарт-контракта.

#Solidity #SmartContracts #BlockchainSecurity #SecurityAudit #Reentrancy #Overflow #Underflow #SafeMath #GasOptimization

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *