Ф'ючерси
Сотні безстрокових контрактів
TradFi
Золото
Одна платформа для світових активів
Опціони
Hot
Торгівля ванільними опціонами європейського зразка
Єдиний рахунок
Максимізуйте ефективність вашого капіталу
Демо торгівля
Вступ до ф'ючерсної торгівлі
Підготуйтеся до ф’ючерсної торгівлі
Ф'ючерсні події
Заробляйте, беручи участь в подіях
Демо торгівля
Використовуйте віртуальні кошти для безризикової торгівлі
Запуск
CandyDrop
Збирайте цукерки, щоб заробити аірдропи
Launchpool
Швидкий стейкінг, заробляйте нові токени
HODLer Airdrop
Утримуйте GT і отримуйте масові аірдропи безкоштовно
Launchpad
Будьте першими в наступному великому проекту токенів
Alpha Поінти
Ончейн-торгівля та аірдропи
Ф'ючерсні бали
Заробляйте фʼючерсні бали та отримуйте аірдроп-винагороди
Інвестиції
Simple Earn
Заробляйте відсотки за допомогою неактивних токенів
Автоінвестування
Автоматичне інвестування на регулярній основі
Подвійні інвестиції
Прибуток від волатильності ринку
Soft Staking
Earn rewards with flexible staking
Криптопозика
0 Fees
Заставте одну криптовалюту, щоб позичити іншу
Центр кредитування
Єдиний центр кредитування
Центр багатства VIP
Преміальні плани зростання капіталу
Управління приватним капіталом
Розподіл преміальних активів
Квантовий фонд
Квантові стратегії найвищого рівня
Стейкінг
Стейкайте криптовалюту, щоб заробляти на продуктах PoS
Розумне кредитне плече
Кредитне плече без ліквідації
Випуск GUSD
Мінтинг GUSD для прибутку RWA
Я просто хочу поділитися проблемою безпеки смарт-контрактів, яку багато розробників все ще ігнорують — атакою reentrancy. Якщо ви створюєте смарт-контракт на Solidity, це те, що вам обов’язково потрібно зрозуміти.
Найпростіше, reentrancy трапляється, коли один контракт викликає інший контракт, і цей контракт може викликати назад початковий контракт під час його виконання. Уявіть, у вас є ContractA з 10 Ether, і ContractB надсилає туди 1 Ether. Коли ContractB знімає гроші, ContractA перевіряє, чи баланс більший за 0, і якщо так — відправляє Ether назад. Але якщо у ContractB є fallback-функція (функція резерву), вона може викликати знову функцію зняття у ContractA, поки ця ще не завершилася. Результат? Баланс ContractB все ще фіксується як 1 Ether, тому він отримає ще 1 Ether, і так далі, доки ContractA не буде виснажений.
Як працює ця атака? Зловмисник потребує двох речей: функції attack() для початку, і fallback-функції для повторного виклику функції зняття. Fallback-функція — це спеціальна зовнішня функція без імені, без параметрів, яку будь-хто може активувати, викликавши неіснуючу функцію, не передавши дані або надіславши Ether без даних.
Ось конкретний приклад: контракт EtherStore має функцію deposit() для збереження балансу і функцію withdrawAll() для зняття всього. Проблема у тому, що withdrawAll() перевіряє баланс, відправляє Ether, а потім оновлює баланс до 0. Це створює вразливість для атаки reentrancy.
Як захиститися? Ось три способи.
Перший — використання модифікатора noReentrant. Ідея дуже проста: блокувати контракт під час виконання функції. Якщо хтось спробує викликати цю функцію знову, перевірка блокування не пропустить. Блокування відкриється лише після завершення функції. Модифікатор — це особливий тип функції, що дозволяє додати умови до інших функцій без переписування всієї логіки.
Другий — застосування шаблону Check-Effect-Interaction. Замість того, щоб спочатку перевіряти умови, надсилати гроші, а потім оновлювати баланс, краще зробити навпаки: перевірити, оновити баланс одразу (до відправки Ether), і лише потім взаємодіяти з зовнішніми контрактами. Таким чином, навіть якщо станеться reentrancy, баланс вже оновлений до 0, і зловмисник не зможе вивести додаткові кошти.
Третій — якщо у вашому проекті багато взаємодіючих контрактів, використовуйте GlobalReentrancyGuard. Замість блокування окремої функції, ви блокуватимете всю систему за допомогою змінної стану, збереженої у окремому контракті. Коли викликається будь-яка функція у будь-якому з контрактів, система перевіряє, чи вона не заблокована. Якщо так — транзакція відхиляється. Це особливо корисно, коли у вас є контракти, наприклад, ScheduledTransfer, що надсилає гроші до AttackTransfer — GlobalReentrancyGuard запобігатиме всім ланцюгам атак reentrancy.
Плюс цих трьох методів у тому, що їх можна комбінувати залежно від ситуації. Важлива функція? Використовуйте noReentrant. Багато схожих функцій? Застосовуйте Check-Effect-Interaction. Весь складний проект? Впроваджуйте GlobalReentrancyGuard. Глибше розуміння reentrancy і способів його запобігання допоможе вам створювати більш безпечні смарт-контракти.