Перейти до основного вмісту

Рекомендації щодо безпеки смарт-контрактів

Solidity
смарт-контракти
безпека
Середній рівень
Trailofbits
6 вересня 2020 р.
4 хвилин на читання

Дотримуйтесь цих загальних рекомендацій, щоб створювати більш безпечні смарт-контракти.

Рекомендації щодо проєктування

Проєктування контракту слід обговорити заздалегідь, ще до написання будь-якого рядка коду.

Документація та специфікації

Документація може бути написана на різних рівнях і повинна оновлюватися під час реалізації контрактів:

Ончейн та позамережеві обчислення

  • Тримайте якомога більше коду позамережевим. Зберігайте ончейн-рівень невеликим. Попередньо обробляйте дані за допомогою позамережевого коду таким чином, щоб ончейн-перевірка була простою. Вам потрібен упорядкований список? Відсортуйте список позамережево, а потім лише перевірте його порядок ончейн.

Можливість оновлення

Ми обговорювали різні рішення для можливості оновлення в нашій статті в блозі (відкривається в новій вкладці). Зробіть свідомий вибір щодо підтримки можливості оновлення ще до написання будь-якого коду. Це рішення вплине на те, як ви структуруєте свій код. Загалом ми рекомендуємо:

  • Надавати перевагу міграції контрактів (відкривається в новій вкладці) замість можливості оновлення. Системи міграції мають багато тих самих переваг, що й системи з можливістю оновлення, але без їхніх недоліків.
  • Використовувати патерн розділення даних замість патерна delegatecallproxy. Якщо ваш проєкт має чітке розділення абстракцій, можливість оновлення з використанням розділення даних потребуватиме лише кількох коригувань. Патерн delegatecallproxy вимагає глибоких знань EVM і є дуже схильним до помилок.
  • Документувати процедуру міграції/оновлення перед розгортанням. Якщо вам доведеться реагувати в стресовій ситуації без жодних інструкцій, ви наробите помилок. Напишіть процедуру, якої слід дотримуватися, заздалегідь. Вона повинна включати:
    • Виклики, які ініціюють нові контракти
    • Де зберігаються ключі та як отримати до них доступ
    • Як перевірити розгортання! Розробіть та протестуйте скрипт після розгортання.

Рекомендації щодо реалізації

Прагніть до простоти. Завжди використовуйте найпростіше рішення, яке відповідає вашій меті. Будь-який член вашої команди повинен мати змогу зрозуміти ваше рішення.

Композиція функцій

Архітектура вашої кодової бази повинна робити ваш код легким для перевірки. Уникайте архітектурних рішень, які ускладнюють розуміння його правильності.

  • Розділяйте логіку вашої системи, або через кілька контрактів, або шляхом групування схожих функцій разом (наприклад, автентифікація, арифметика тощо).
  • Пишіть невеликі функції з чіткою метою. Це полегшить перевірку та дозволить тестувати окремі компоненти.

Успадкування

  • Зберігайте успадкування керованим. Успадкування слід використовувати для розділення логіки, однак ваш проєкт повинен прагнути мінімізувати глибину та ширину дерева успадкування.
  • Використовуйте принтер успадкування (відкривається в новій вкладці) Слізер, щоб перевірити ієрархію контрактів. Принтер успадкування допоможе вам перевірити розмір ієрархії.

Події

  • Записуйте в лог усі важливі операції. Події допоможуть налагодити контракт під час розробки та контролювати його після розгортання.

Уникайте відомих пасток

Залежності

  • Використовуйте добре протестовані бібліотеки. Імпорт коду з добре протестованих бібліотек зменшить ймовірність написання коду з помилками. Якщо ви хочете написати контракт ERC-20, використовуйте ОупенЗеппелін (відкривається в новій вкладці).
  • Використовуйте менеджер залежностей; уникайте копіювання та вставлення коду. Якщо ви покладаєтеся на зовнішнє джерело, ви повинні підтримувати його в актуальному стані відповідно до оригіналу.

Тестування та верифікація

Solidity

  • Надавайте перевагу Solidity 0.5 замість 0.4 та 0.6. На нашу думку, Solidity 0.5 є більш безпечною та має кращі вбудовані практики, ніж 0.4. Solidity 0.6 виявилася занадто нестабільною для продакшену і потребує часу для вдосконалення.
  • Використовуйте стабільний реліз для компіляції; використовуйте останній реліз для перевірки на наявність попереджень. Переконайтеся, що у вашому коді немає повідомлень про проблеми з останньою версією компілятора. Однак Solidity має швидкий цикл випуску та історію помилок компілятора, тому ми не рекомендуємо останню версію для розгортання (див. рекомендації щодо версії solc (відкривається в новій вкладці) від Слізер).
  • Не використовуйте вбудований асемблер (inline assembly). Асемблер вимагає глибоких знань EVM. Не пишіть код для EVM, якщо ви не опанували Жовту книгу.

Рекомендації щодо розгортання

Після того, як контракт було розроблено та розгорнуто:

  • Контролюйте свої контракти. Слідкуйте за логами та будьте готові реагувати у разі компрометації контракту або гаманця.
  • Додайте свою контактну інформацію до blockchain-security-contacts (відкривається в новій вкладці). Цей список допомагає третім сторонам зв’язатися з вами, якщо буде виявлено недолік безпеки.
  • Захистіть гаманці привілейованих користувачів. Дотримуйтесь наших найкращих практик (відкривається в новій вкладці), якщо ви зберігаєте ключі в апаратних гаманцях.
  • Майте план реагування на інциденти. Враховуйте, що ваші смарт-контракти можуть бути скомпрометовані. Навіть якщо ваші контракти не містять помилок, зловмисник може отримати контроль над ключами власника контракту.