Я хочу поделиться довольно важной информацией, которую вы, возможно, еще не до конца понимаете — это уязвимость reentrancy в смарт-контрактах. Если вы разрабатываете dapp или работаете с блокчейном, это must-know.



В чем заключается основная проблема reentrancy? Она возникает, когда один смарт-контракт вызывает другой контракт, и этот контракт может вызвать обратно исходный контракт, пока он все еще выполняется. Злоумышленник может воспользоваться этим временем, чтобы украсть деньги.

Представьте, что ContractA имеет 10 эфиров, а ContractB уже отправил туда 1 эфир. Когда ContractB вызывает функцию вывода, ContractA проверяет, есть ли баланс больше 0, и если да — отправляет эфир обратно. Но здесь есть проблема — ContractA обновляет баланс только после отправки. Поэтому во время отправки, если у ContractB есть fallback-функция, она может снова вызвать функцию вывода ContractA. Поскольку баланс еще не обновлен, проверка снова пройдет успешно, и он получит еще 1 эфир. Этот цикл продолжается, пока ContractA не останется ничего.

Я расскажу вам три способа защитить контракт от этой атаки reentrancy.

Первый способ — использовать модификатор nonReentrant. Идея очень проста — блокировать контракт во время выполнения функции. Если кто-то попытается вызвать эту функцию повторно, вызов будет отклонен, потому что контракт заблокирован. Нужно выполнить весь код функции, а затем разблокировать, и тогда проверка пройдет успешно.

Второй способ — использовать шаблон Checks-Effects-Interactions. Вместо обновления баланса после отправки, обновляйте его сразу после проверки, но до отправки. Таким образом, даже если другой контракт вызовет функцию повторно, баланс уже будет равен 0, и проверка не пройдет. Поэтому порядок очень важен — сначала проверка, затем изменение состояния, и только после этого взаимодействие с внешним контрактом.

Третий способ — создать отдельный глобальный ReentrancyGuard, что особенно полезно, если у вас много взаимодействующих контрактов. Вместо защиты каждой функции отдельно, создайте общий контракт-охранник, который хранит состояние блокировки. Когда любой контракт пытается вызвать защищенную функцию, он проверяет с этим guard-ом. Если guard говорит, что контракт заблокирован, транзакция отклоняется. Этот метод очень мощный, потому что он предотвращает reentrancy не только внутри одного контракта, но и между несколькими контрактами.

Я советую применять все три метода в зависимости от ситуации. Для функций вывода или перевода средств всегда используйте nonReentrant или Checks-Effects-Interactions. А если у вас сложная система контрактов, рассмотрите использование GlobalReentrancyGuard как дополнительного уровня защиты.

Это одна из самых распространенных уязвимостей, которая приводит к крупным потерям, поэтому понимание reentrancy очень важно, если вы хотите писать безопасные смарт-контракты.
XCH-1,80%
TRA0,68%
XEM-2,85%
Посмотреть Оригинал
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
  • Награда
  • комментарий
  • Репост
  • Поделиться
комментарий
Добавить комментарий
Добавить комментарий
Нет комментариев
  • Закреплено