Серія безпеки Web3: Чи можна врятувати кошти, випадково переказані на інший блокчейн?

У світі криптовалют один невірний клік може спричинити “цифрову катастрофу”. Одним із найпоширеніших кошмарів є випадкова відправка активів на неправильний блокчейн. Наприклад, ви хотіли надіслати ETH на адресу тестової мережі Ethereum Sepolia, але випадково відправили їх на адресу основної мережі Ethereum. У такому випадку, чи можливо повернути помилково переведені кошти з основної мережі Ethereum? Чи можна відновити активи, залежить від типу отримуваної адреси. У цій статті ми проаналізуємо різні ситуації.

1. Сцена 1: Адреса отримувача — EOA

EOA (Externally Owned Account) — це звичайний гаманець, який контролюється приватним ключем або мнемонічною фразою.

Умови для відновлення активів:

  • Ви переказали активи на адресу EOA.
  • Ви маєте приватний ключ або мнемонічну фразу цієї цільової адреси EOA. (Зазвичай це ваш інший гаманець або гаманець друга, і він готовий співпрацювати.)
  • Ця цільова ланцюг сумісна з EVM.

Спосіб відновлення активів:

Власник приватного ключа цільової адреси EOA може просто зняти кошти безпосередньо на цільовому ланцюгу.

2. Сцена 2: Адреса отримувача — контракт

Це один із найвідчайдушніших сценаріїв. Оскільки адреса смарт-контракту не генерується приватним ключем, ніхто не має приватного ключа цього контракту. Без нього неможливо контролювати контракт так само, як EOA. Якщо контракт не містить попередньо створеної функції для обробки “помилкового переказу”, тоді помилково переведені кошти можуть бути назавжди заблоковані у контракті, і ніхто не зможе їх зняти.

Однак у деяких випадках є певна надія. Далі ми розглянемо сценарій з ETH, заблокованими у контракті на основній мережі, і пояснимо, як їх врятувати.

2.1. Опис сценарію

Загалом, користувач спочатку хотів викликати контракт у тестовій мережі Sepolia, щоб перевести ETH у цей контракт і створити токени. Однак під час транзакції він помилково підключився до основної мережі Ethereum, у результаті ETH були заблоковані у контракті основної мережі. Детальніше:

1. У тестовій мережі Ethereum Sepolia проект (EOA) розгорнув контракт, функція якого полягає у тому, щоб користувачі могли внести ETH для створення відповідних токенів (приклад функції mintTokens). Адреса розгортання — A. Важливо, що у цьому контракті немає функції для безпосереднього виведення ETH.

2. У тестовій мережі Ethereum Sepolia проект розгорнув фабричний контракт, який може, використовуючи вхідні дані — адресу реалізаційного контракту та salt — розгортати проксі-контракти (Clones), що вказують на цей реалізаційний контракт (наприклад, через функцію deployProxyByImplementation). Адреса розгортання — B. Потім викликаючи deployProxyByImplementation з вказанням реалізаційної адреси A у параметрі _implementation, було розгорнуто проксі-контракт, що вказує на A, — C.

3. Користувач хотів у тестовій мережі Sepolia викликати функцію для створення токенів, переказуючи ETH на адресу проксі-контракту C. Вони зробили виклик цього контракту. Очікувалося, що C викликає функцію mintTokens на реалізаційному контракті A, щоб завершити операцію. Однак користувач помилково підключився до основної мережі Ethereum і переказав ETH безпосередньо на адресу C у основній мережі. Оскільки на цій адресі немає розгорнутого контракту, і приватний ключ від C невідомий, кошти користувача тимчасово заблоковані на цій адресі.

2.2. Важливі поняття

Перед розглядом способів врятування необхідно ознайомитися з базовими знаннями.

2.2.1. create & create2

create і create2 — це поширені способи розгортання контрактів у Solidity.

  • create — адреса контракту залежить від адреси відправника та його nonce (чисельник транзакцій). Не залежить від вмісту контракту.

  • create2 — адреса контракту обчислюється за формулою, яка враховує:

    • 0xff

    • адреса контракту-створювача

    • salt (змінна для унікальності)

    • init_code (код для створення контракту)

![])https://img-cdn.gateio.im/social/moments-dccef4147d8ed262ab8b835ed3984395(2.2.2. Мінімальний проксі-контракт (Clones)

https://docs.openzeppelin.com/contracts/4.x/api/proxy#clones

Мінімальні проксі-контракти, або Clones, — це спосіб швидко і з низькими витратами (gas) розгорнути проксі, що вказує на реалізаційний контракт. У контракті Clones можна використовувати create або create2. Зокрема, функція cloneDeterministic використовує create2 для створення проксі.

У функції cloneDeterministic створений проксі-контракт має короткий байткод: 0x363d3d373d3d3d363d73<адреса реалізаційного контракту>5af43d82803e903d91602b57fd5bf3. Адреса проксі-контракту обчислюється на основі адреси створювача, salt і реалізаційної адреси, але не залежить від байткоду реалізаційного контракту.

![])https://img-cdn.gateio.im/webp-social/moments-628ce0ce97dbf40349dc8b7a0c07eab3.webp###

(# 2.3. План врятування

Наступним кроком — врятувати ETH на адресі C у основній мережі. Основна ідея — розгорнути контракт на цій адресі, щоб він контролював цю адресу і міг зняти кошти. Деталі:

![])https://img-cdn.gateio.im/webp-social/moments-22428dd6bb1fbd62d2205538c0cc6c92.webp#最小代理合约(Clones)#

1. Розгорнути у основній мережі фабричний контракт з такою ж адресою B, як і у тестовій. Це потрібно, щоб адреса проксі-контракту, що буде створений з використанням cloneDeterministic, збіглася. Визначити nonce у тестовій мережі для цієї транзакції та обчислити правильний nonce у основній мережі. Потім розгорнути фабричний контракт у основній мережі з тим самим адресою.

2. Розгорнути у основній мережі реалізаційний контракт A з тією ж адресою, що і у тестовій. Оскільки адреса проксі у методі cloneDeterministic залежить від salt і реалізаційної адреси, а не від вмісту контракту, достатньо розгорнути контракт A на цій же адресі. Це дозволить у майбутньому створювати проксі, що вказують на цей контракт, у тому числі і для зняття ETH.

3. Розгорнути у основній мережі проксі-контракт на тій же адресі C, використовуючи той самий salt, що і у тестовій. Для цього викликати deployProxyByImplementation у фабричному контракті B з параметрами — адреса реалізаційного контракту A і salt.

4. Викликати функцію withdraw у проксі-контракті C для зняття заблокованих ETH і повернути їх користувачу.

(# 2.4. Висновки

Загалом, можливість врятувати кошти залежить від багатьох умов, зокрема: nonce створювача у цільовому ланцюгу не використаний, контракт має функцію для зняття або його можна розгорнути так, щоб вона з’явилася, або використовуються проксі-контракти Clones.

Тому при проведенні транзакцій необхідно бути дуже обережним і ретельно перевіряти кожну операцію. Перед взаємодією з контрактами рекомендується використовувати інструмент AI SCAN від ZAN для аналізу безпеки. У разі блокування коштів не панікуйте — звертайтеся до команди з аудиту безпеки ZAN для допомоги у врятуванні активів.

Цю статтю створили команда ZANTeam (X аккаунт @zan_team) та AntChain OpenLabs (X аккаунт @AntChainOpenLab) разом із Cara (X аккаунт @Cara6289).

ETH0.02%
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
  • Нагородити
  • Прокоментувати
  • Репост
  • Поділіться
Прокоментувати
0/400
Немає коментарів
  • Закріпити