Я хочу поділитися досить важливою інформацією, можливо, ви ще не зовсім її розумієте — це вразливість 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. Якщо він заблокований, транзакція відхиляється. Це дуже потужний спосіб — він запобігає reentrancy не лише у одному контракті, а й між кількома.

Рекомендую застосовувати всі три техніки залежно від ситуації. Для функцій зняття або переказу активів завжди використовуйте nonReentrant або Checks-Effects-Interactions. А якщо у вашому проекті багато взаємодіючих контрактів, розгляньте додавання GlobalReentrancyGuard як додатковий рівень захисту.

Це одна з найпоширеніших вразливостей, що призводять до великих втрат, тому глибоке розуміння reentrancy дуже важливе, якщо ви хочете писати безпечні смарт-контракти.
XCH-7,34%
TRA-4,01%
XEM2,01%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • Прокоментувати
  • Репост
  • Поділіться
Прокоментувати
Додати коментар
Додати коментар
Немає коментарів
  • Закріплено