Рекомендації щодо безпеки смарт-контрактів
Дотримуйтесь цих загальних рекомендацій, щоб створювати більш безпечні смарт-контракти.
Рекомендації щодо проєктування
Проєктування контракту слід обговорити заздалегідь, ще до написання будь-якого рядка коду.
Документація та специфікації
Документація може бути написана на різних рівнях і повинна оновлюватися під час реалізації контрактів:
- Опис системи простою мовою, який пояснює, що роблять контракти, та будь-які припущення щодо кодової бази.
- Схеми та архітектурні діаграми, включаючи взаємодії контрактів та автомат станів системи. Принтери Слізер (opens in a new tab) можуть допомогти згенерувати ці схеми.
- Ретельна документація коду, для Solidity можна використовувати формат NatSpec (opens in a new tab).
Ончейн та позамережеві обчислення
- Тримайте якомога більше коду позамережевим. Зберігайте ончейн-рівень невеликим. Попередньо обробляйте дані за допомогою позамережевого коду таким чином, щоб ончейн-перевірка була простою. Вам потрібен упорядкований список? Відсортуйте список позамережево, а потім лише перевірте його порядок ончейн.
Можливість оновлення
Ми обговорювали різні рішення для можливості оновлення в нашій статті в блозі (opens in a new tab). Зробіть свідомий вибір щодо підтримки можливості оновлення ще до написання будь-якого коду. Це рішення вплине на те, як ви структуруєте свій код. Загалом ми рекомендуємо:
- Надавати перевагу міграції контрактів (opens in a new tab) замість можливості оновлення. Системи міграції мають багато тих самих переваг, що й системи з можливістю оновлення, але без їхніх недоліків.
- Використовувати патерн розділення даних замість патерна delegatecallproxy. Якщо ваш проєкт має чітке розділення абстракцій, можливість оновлення з використанням розділення даних потребуватиме лише кількох коригувань. Патерн delegatecallproxy вимагає глибоких знань EVM і є дуже схильним до помилок.
- Документувати процедуру міграції/оновлення перед розгортанням. Якщо вам доведеться реагувати в стресовій ситуації без жодних інструкцій, ви наробите помилок. Напишіть процедуру, якої слід дотримуватися, заздалегідь. Вона повинна включати:
- Виклики, які ініціюють нові контракти
- Де зберігаються ключі та як отримати до них доступ
- Як перевірити розгортання! Розробіть та протестуйте скрипт після розгортання.
Рекомендації щодо реалізації
Прагніть до простоти. Завжди використовуйте найпростіше рішення, яке відповідає вашій меті. Будь-який член вашої команди повинен мати змогу зрозуміти ваше рішення.
Композиція функцій
Архітектура вашої кодової бази повинна робити ваш код легким для перевірки. Уникайте архітектурних рішень, які ускладнюють розуміння його правильності.
- Розділяйте логіку вашої системи, або через кілька контрактів, або шляхом групування схожих функцій разом (наприклад, автентифікація, арифметика тощо).
- Пишіть невеликі функції з чіткою метою. Це полегшить перевірку та дозволить тестувати окремі компоненти.
Успадкування
- Зберігайте успадкування керованим. Успадкування слід використовувати для розділення логіки, однак ваш проєкт повинен прагнути мінімізувати глибину та ширину дерева успадкування.
- Використовуйте принтер успадкування (opens in a new tab) Слізер, щоб перевірити ієрархію контрактів. Принтер успадкування допоможе вам перевірити розмір ієрархії.
Події
- Записуйте в лог усі важливі операції. Події допоможуть налагодити контракт під час розробки та контролювати його після розгортання.
Уникайте відомих пасток
- Будьте обізнані про найпоширеніші проблеми безпеки. Існує багато онлайн-ресурсів, щоб дізнатися про поширені проблеми, такі як Ethernaut CTF (opens in a new tab), Capture the Ether (opens in a new tab) або Not so smart contracts (opens in a new tab).
- Звертайте увагу на розділи з попередженнями в документації Solidity (opens in a new tab). Розділи з попередженнями поінформують вас про неочевидну поведінку мови.
Залежності
- Використовуйте добре протестовані бібліотеки. Імпорт коду з добре протестованих бібліотек зменшить ймовірність написання коду з помилками. Якщо ви хочете написати контракт ERC-20, використовуйте ОупенЗеппелін (opens in a new tab).
- Використовуйте менеджер залежностей; уникайте копіювання та вставлення коду. Якщо ви покладаєтеся на зовнішнє джерело, ви повинні підтримувати його в актуальному стані відповідно до оригіналу.
Тестування та верифікація
- Пишіть ретельні модульні тести. Великий набір тестів має вирішальне значення для створення високоякісного програмного забезпечення.
- Пишіть власні перевірки та властивості для Слізер (opens in a new tab), Ехідна (opens in a new tab) та Мантікора (opens in a new tab). Автоматизовані інструменти допоможуть переконатися, що ваш контракт безпечний. Перегляньте решту цього посібника, щоб дізнатися, як писати ефективні перевірки та властивості.
- Використовуйте crytic.io (opens in a new tab). Crytic інтегрується з GitHub, надає доступ до приватних детекторів Слізер і запускає власні перевірки властивостей з Ехідна.
Solidity
- Надавайте перевагу Solidity 0.5 замість 0.4 та 0.6. На нашу думку, Solidity 0.5 є більш безпечною та має кращі вбудовані практики, ніж 0.4. Solidity 0.6 виявилася занадто нестабільною для продакшену і потребує часу для вдосконалення.
- Використовуйте стабільний реліз для компіляції; використовуйте останній реліз для перевірки на наявність попереджень. Переконайтеся, що у вашому коді немає повідомлень про проблеми з останньою версією компілятора. Однак Solidity має швидкий цикл випуску та історію помилок компілятора, тому ми не рекомендуємо останню версію для розгортання (див. рекомендації щодо версії solc (opens in a new tab) від Слізер).
- Не використовуйте вбудований асемблер (inline assembly). Асемблер вимагає глибоких знань EVM. Не пишіть код для EVM, якщо ви не опанували Жовту книгу.
Рекомендації щодо розгортання
Після того, як контракт було розроблено та розгорнуто:
- Контролюйте свої контракти. Слідкуйте за логами та будьте готові реагувати у разі компрометації контракту або гаманця.
- Додайте свою контактну інформацію до blockchain-security-contacts (opens in a new tab). Цей список допомагає третім сторонам зв’язатися з вами, якщо буде виявлено недолік безпеки.
- Захистіть гаманці привілейованих користувачів. Дотримуйтесь наших найкращих практик (opens in a new tab), якщо ви зберігаєте ключі в апаратних гаманцях.
- Майте план реагування на інциденти. Враховуйте, що ваші смарт-контракти можуть бути скомпрометовані. Навіть якщо ваші контракти не містять помилок, зловмисник може отримати контроль над ключами власника контракту.
Останнє оновлення сторінки: 3 березня 2026 р.