Solidity
Solidity — мова більшості смартконтрактів: програм у сумісних з Ethereum блокчейнах, що тримають гроші, виконуються на кожному вузлі й не латаються. Кожна функція відкрита будь-кому, зокрема іншим контрактам, які можуть повернутися посеред виконання функції; кожен крок коштує викликачу газу; а помилку можна виправити, лише якщо шлях оновлення заклали наперед. Сторінка починається з дванадцяти припущень, які приносить бекенд-розробник, і того, що правда в EVM натомість; далі — машина й мова до Solidity 0.8.37, зовнішні виклики й reentrancy, оновлення й ключі адміністратора, гроші й ціни, тестування й аудит, п’ять задокументованих втрат і те, де все це вироджується, — зокрема коли контракт узагалі не той інструмент.
- Поточна версія
- Solidity 0.8.37 · 10 вер. 2026
- Де виконується
- EVM — кожен вузол виконує кожен виклик
- Після розгортання
- Код незмінний; оновлення — лише закладені наперед
Дванадцять речей, які припускає бекенд-розробник, і що правда всередині контракту
Смартконтракт схожий на бекенд-клас: стан у полях, методи, що його змінюють, require там, де контролер перевіряв би ввід. Майже кожна звичка, яку приносить бекенд-розробник, десь у ньому хибна, бо машина під ним — не сервер. Це Ethereum Virtual Machine, EVM, яку запускає кожен вузол мережі. Вона виконує транзакції одну за одною, бере плату за кожну інструкцію, тримає кожен байт публічним і ніколи не дає змінити код. Ось дванадцять припущень, що справджуються на сервері, і те, що справджується натомість. Наступні розділи посилаються на рядки за номерами.
| # | На сервері ви припускаєте | Усередині контракту | Що робити натомість |
|---|---|---|---|
| 1 | Ваш API можуть викликати лише ваші користувачі | Кожну public і external функцію може викликати будь-хто — зокрема інший контракт | Перевірка доступу в кожній функції, що змінює стан; вважайте викликача ворожим |
| 2 | Помилку виправляють, розгорнувши патч | Розгорнутий код не змінюється ніколи | Вирішіть до запуску: незмінний контракт або шлях оновлення за таймлоком |
| 3 | Секрет може жити в конфігурації чи в базі даних | Усе сховище може прочитати будь-хто; private ховає лише від інших контрактів | Тримайте секрети поза ланцюгом; commit–reveal для прихованих виборів |
| 4 | Виклик іншого сервісу просто повертає відповідь | Зовнішній виклик передає керування чужому коду, який може викликати вас знову | Перевірки, зміни стану, взаємодії — саме в такому порядку — і захист від reentrancy |
| 5 | Запити виконуються паралельно й у порядку надходження | Транзакції виконуються по одній, у порядку, який обирає той, хто збирає блок | Вважайте, що вашу транзакцію хтось бачить першим: ліміти прослизання, дедлайни |
| 6 | Невдалий запит лишає частковий стан, який треба прибрати | Невдала транзакція відкочує кожну зміну — а викликач однаково платить за витрачений газ | Перевіряйте рано й відкочуйте; покладайтеся на атомарність, а не на код прибирання |
| 7 | Цикл коштує процесорного часу | Кожна інструкція коштує газу, який платить викликач, у межах ліміту на блок | Жодних циклів по списках, які користувачі можуть нарощувати; нехай кожен знімає сам |
| 8 | Гроші можна тримати в десятковому чи дробовому числі | Жодних дробів: 256-бітні цілі, а ділення округлює донизу | Множте до ділення; округлюйте на користь протоколу |
| 9 | Сервер знає час і вміє генерувати випадкові числа | block.timestamp — час блоку, а не виклику, і ніщо в ланцюгу не є непередбачуваним для того, хто пропонує блок | Оракул перевірної випадковості (VRF) або commit–reveal |
| 10 | Ціну можна взяти з API | Контракт бачить лише ланцюг; ціна — це те, що повідомляє якийсь контракт | Оракул, стійкий до маніпуляцій, з перевіркою свіжості й меж |
| 11 | Адміністратор може виправити дані вручну | Повноваження адміністратора — це функція, яку може викликати будь-хто з ключем | Мультипідпис, таймлок і опубліковані межі того, що можуть адміністратори |
| 12 | Розмір коду й глибина стека — чужа проблема | Контракт обмежено 24 КБ коду, а EVM дістає лише 16 комірок стека | Діліть на бібліотеки й модулі; тримайте функції малими |
Машина і мова: акаунти, газ і Solidity 0.8
В Ethereum є два види акаунтів. Зовнішній акаунт — EOA, externally owned account — керується приватним ключем: людина, гаманець, сервер, що тримає ключ. Контрактний акаунт керується своїм кодом. Почати транзакцію може лише EOA. Транзакція може викликати контракт, той — інші контракти, і весь ланцюг викликів або вдається разом, або разом відкочується. Кожен вузол виконує ту саму транзакцію й мусить отримати той самий результат, і тому контракт не може прочитати годинник, файл чи інтернет: усе, що могло б відрізнятися між двома вузлами, просто недоступне.
Газ — спосіб, яким мережа оцінює цю роботу. Кожна інструкція EVM має фіксовану ціну в газі; відправник задає максимум і платить за використане за ціною за одиницю газу, яку визначає ринок: базова плата, що спалюється, плюс чайові тому, хто пропонує блок, — модель, що діє з серпня 2021 року. Якщо транзакції бракує газу, вона відкочується, а газ однаково витрачено. З грудня 2025 року блок типово вміщує 60 мільйонів газу, а одна транзакція — щонайбільше близько 16,8 мільйона. На практиці числа кажуть одне: сховище дороге, а обчислення дешеві.
| Операція | Газ | Що це означає |
|---|---|---|
| Будь-яка транзакція, ще до будь-якої дії | 21 000 | Фіксована ціна простого переказу |
| Додати два числа | 3 | Обчислення майже безкоштовні |
| Прочитати комірку сховища вперше за транзакцію | 2100 | Приблизно 700 додавань |
| Прочитати ту саму комірку вдруге | 100 | Однаково варто кешувати в локальній змінній |
| Записати комірку сховища, що була нульовою | 20 000+ | Створення стану — найдорожче, що ви робите |
| Змінити ненульову комірку | 2900+ | Оновлювати значно дешевше, ніж створювати |
| Викликати інший контракт уперше | 2600+ | Плюс усе, що витратить той, кого викликали |
| Calldata, за кожен ненульовий байт | 16 | За вхідні дані платять побайтово |
Це сьогоднішні ціни, і вони не вічні. Наступне оновлення мережі, Glamsterdam, — у тестовій мережі Sepolia з 6 жовтня 2026 року, дати для основної мережі ще немає — переоцінює створення стану й доступ до нього, а його оголошення просить розробників перевірити оцінки газу й усе, що жорстко прописує кількість газу. Це загальний урок: контракт, що залежить від точної ціни в газі, залежить від того, що протокол уже кілька разів змінював і змінить знову. Тому ж Solidity 0.8.31 оголосив застарілими transfer і send, які передають фіксовані 2300 газу.
Мова: що змінив 0.8 і як писати сьогодні
Solidity схожий на JavaScript чи Java з типами, і подібність лише зовнішня. Контракт — це клас, чиї поля зберігаються в ланцюгу назавжди (це змінні стану), а функції — його APIApplication Programming Interface — контракт між програмамиПравила, за якими одна програма звертається до іншої: які запити можна надіслати, у якому вигляді й що прийде у відповідь. Для того, хто звертається, це контракт — усе, що за ним, лишається чорною скринькою, і саме тому другий бік можна переписати, не зламавши вас.Докладніше в статті →Усі терміни. Версія 0.8.0 у грудні 2020 року зробила найважливішу зміну в історії мови: арифметика за замовчуванням перевіряється, тож переповнення відкочує транзакцію замість загортання. До неї кожен контракт потребував бібліотеки SafeMath, а її відсутність раз у раз ставала способом надрукувати токени з нічого. Код під 0.7 і давніші версії часто трапляється в старих репозиторіях і аудитах, і його арифметику треба читати з цим на увазі.
| Де живуть дані | Скільки живуть | Ціна | Для чого |
|---|---|---|---|
storage | Назавжди, на кожному вузлі | Тисячі газу за комірку | Змінні стану — баланси, власники, налаштування |
transient | Одна транзакція (з Cancun, березень 2024) | Близько 100 газу | Блокування від reentrancy; значення між викликами в одній транзакції |
memory | Один виклик функції | Кілька газу за слово, більше з розміром | Робочі копії масивів і структур |
calldata | Один зовнішній виклик, лише читання | Найдешевше — уже оплачено | Параметри external-функцій |
| Події (логи) | Назавжди, але контракти їх не читають | Дешево порівняно зі сховищем | Те, що потрібно індексаторам і інтерфейсам поза ланцюгом |
Чотири ключові слова видимості вирішують, хто може викликати функцію: external і public — будь-хто, як каже рядок 1; internal — цей контракт і ті, що від нього успадковують; private — лише цей контракт. Жодне не ховає даних: вони керують викликами, а не читанням. Хто викликає, кажуть дві глобальні змінні. msg.sender — безпосередній викликач, EOA чи контракт на один крок вище, і перевіряти треба саме його. tx.origin — EOA, що почав усю транзакцію, і перевіряти його — класична помилка: зловмисний контракт, який власника обманом змусили викликати, проходить перевірку tx.origin == owner. А з травня 2025 року EOA може мати й власний код (EIP-7702), тож стара перевірка require(msg.sender == tx.origin) на «викликала людина, а не контракт» уже не означає того, що колись.
Як виглядає контракт, написаний у 2026 році: зафіксована версія компілятора — pragma solidity 0.8.37; замість ^0.8.0, — щоб байткод, який пройшов аудит, і був розгорнутим; власні помилки (error Unauthorized(); з revert Unauthorized();) замість рядків — дешевші й придатні до декодування; OpenZeppelin Contracts для токенів, контролю доступу й захистів замість саморобних версій; подія на кожну зміну стану, потрібну системі поза ланцюгом; і жодних transfer, send чи selfdestruct. Перші два застарілі, а selfdestruct з березня 2024 року не видаляє контракт, хіба що в тій самій транзакції, що його створила.
Зовнішні виклики і reentrancy
Рядок 4 — помилка, що визначила всю галузь. Коли контракт надсилає ether чи викликає інший контракт, виконання переходить на інший бік, а там може виконатися будь-який код — зокрема виклик просто назад у контракт, який ще не закінчив. Якщо перший контракт надіслав гроші раніше, ніж оновив свої записи, другий виклик бачить старий баланс і отримує виплату ще раз. І ще раз — доки не закінчиться газ чи гроші. Це повторний вхід, reentrancy, і вирішує його порядок трьох рядків.
Правило називається checks–effects–interactions: перевірки, зміни, взаємодії. Спершу перевірте кожну умову. Потім застосуйте кожну зміну до власного стану — обнуліть баланс. І лише тоді взаємодійте із зовнішнім світом: надсилайте ether, викликайте контракт, переказуйте токени. У такому порядку повторний виклик бачить уже оновлений стан і нічого не отримує. Поверх порядку додайте захист: ReentrancyGuard з OpenZeppelin блокує кожну функцію з позначкою nonReentrant, а після оновлення Cancun це блокування може жити в тимчасовому сховищі за частку колишньої ціни. І віддавайте перевагу тому, щоб користувачі самі знімали належне їм, — pull, — а не розсилці списку отримувачів у циклі, push, що заразом прибирає необмежений цикл із рядка 7.
Reentrancy переріс свою хрестоматійну форму. Міжфункціональна атака входить повторно через іншу функцію, що ділить той самий стан. Атака лише на читання викликає view-функцію контракту посеред оновлення, читає на мить хибну ціну чи баланс і використовує їх у третьому контракті, який їм довіряв. Блокування однієї функції не захищає від жодної з них — і тому порядок змін і взаємодій важить більше за будь-який окремий захист.
Оновлення, проксі і ключі адміністратора
Рядок 2 має один запасний вихід, і це патерн, а не можливість мови. Проксі — маленький контракт, що тримає весь стан і пересилає кожен виклик через delegatecall контрактові-реалізації, який тримає код. delegatecall виконує код іншого контракту над власним сховищем того, хто викликає. Оновлення — це перемкнути проксі на нову реалізацію; адреса, яку знають користувачі, і дані лишаються тими самими. OpenZeppelin постачає поширені варіанти — transparent, UUPS і beacon-проксі, — а EIP-1967 фіксує комірку сховища, де лежить адреса реалізації, щоб вона не перетиналася зі звичайними змінними.
Патерн міняє один ризик на три. Перший — розкладка сховища. Змінні реалізації розкладаються за позицією, комірка за коміркою, у сховищі проксі, тож нова версія, що вставляє змінну над старою, змушує кожну наступну змінну читати не ту комірку. Лише додавайте в кінець і дайте інструменту порівняти розкладки — плагін оновлень OpenZeppelin відмовляється від несумісної. Другий — ініціалізація. Контракт за проксі не може мати конструктора, бо конструктор виконується на реалізації, а не на проксі; натомість він має функцію initialize, яку можна викликати рівно один раз, а саму реалізацію треба заблокувати через _disableInitializers(), щоб ніхто інший не міг її ініціалізувати. Третій — адміністратор: хто може оновлювати, той може замінити код будь-чим, і тому ключ оновлення — найцінніше, чим володіє проєкт.
Гроші, ціни і флеш-кредити
В EVM немає дробів. Суми — це цілі числа в найменших одиницях токена: ether має 18 десяткових знаків, тож один ether — це 10^18 wei, а USDC має 6, — і кожне ділення округлює донизу. З рядка 8 випливають два правила. Множте до ділення: a * b / c зберігає точність, яку a / c * b викидає. І обирайте напрям кожного округлення свідомо, на користь протоколу — вниз те, що отримують користувачі, вгору те, що вони винні, — бо помилка округлення, повторена тисячу разів в одній транзакції, — це вже виведення коштів. Друга постійна помилка — змішувати токени з різною кількістю знаків без масштабування: одна одиниця USDC — це мільйонна частка долара, а одна одиниця DAI — квінтильйонна.
ERC-20, стандарт токенів, менш однорідний, ніж обіцяє його інтерфейс. transfer у USDT не повертає нічого замість true, тож контракт, що перевіряє повернене значення, на ньому відкочується; деякі токени беруть комісію з кожного переказу, тож доходить менше, ніж надіслано; деякі вміють ставити адреси на паузу чи в чорний список. Користуйтеся обгортками SafeERC20 з OpenZeppelin, вимірюйте баланс до й після переказу, коли це важливо, і тримайте список токенів, які ви справді підтримуєте.
У рядку 10 більшість логіки протоколу зустрічається із зовнішнім світом. Протокол кредитування мусить знати, скільки варта застава, і спокуслива відповідь — ціна в пулі децентралізованої біржі, яку можна прочитати одним викликом. Флеш-кредит робить цю відповідь нікчемною. Флеш-кредит позичає будь-яку суму без застави за однієї умови: його повертають у тій самій транзакції, інакше вся транзакція відкочується, рівно як обіцяє рядок 6. Тож на час однієї транзакції будь-хто має десятки мільйонів, щоб зрушити ціну пулу, скористатися спотвореною ціною, повернути її назад і погасити кредит.
У жовтні 2020 року Harvest Finance втратив так близько $24 мільйонів: його сховища оцінювали внески й зняття за ціною в пулі Curve, яку щойно зрушила угода на флеш-кредит. Захист — ціна, яку не можна зрушити за одну транзакцію (середня, зважена за часом на багатьох блоках, або мережа оракулів на кшталт Chainlink, що зводить багато джерел), плюс перевірки, що відповідь свіжа й у розумних межах, і обмеження того, наскільки одна транзакція може зрушити протокол.
Тестування, аудит і постачання
Набір тестів контракту мусить зробити ту роботу, яку інакше зробив би інцидент у продакшені, бо гарячого виправлення не буде. Модульні тести — це мінімум. Окупаються фазинг — випадкові вхідні дані, тисячі на тест, — і тестування інваріантів, яке запускає випадкові послідовності викликів і після кожного перевіряє, що властивість досі тримається: «сума балансів дорівнює загальній емісії», «жоден акаунт не може зняти більше, ніж вніс». Foundry запускає обидва з тестових файлів на Solidity; Hardhat робить те саме з TypeScriptJavaScript із перевіркою типівJavaScript плюс опис того, що саме функція приймає й повертає, — і цей опис перевіряється в редакторі ще до запуску. У браузер він не потрапляє: перед складанням його компілюють назад у звичайний JavaScript, тож типи — це інструмент розробки, і не більше.Докладніше в статті →Усі терміни. Тест на форку виконується на копії стану основної мережі — зі справжніми токенами й оракулами, які зустріне контракт.
| Рівень | Інструменти | Що ловить |
|---|---|---|
| Статичний аналіз | Slither; власні попередження компілятора | Відомі патерни помилок — reentrancy, неперевірені виклики, затінені змінні |
| Фазинг та інваріанти | Foundry, Echidna, Medusa | Вхідні дані й послідовності викликів, які ніхто не здогадався записати |
| Формальна верифікація | Certora, Halmos, SMTChecker у компіляторі | Доказ, що властивість тримається для будь-якого входу, — для тих властивостей, які ви записали |
| Аудит | Зовнішня фірма або публічний конкурс | Помилки задуму й логіки, яких команда не бачить у власному коді |
| Bug bounty | Immunefi та подібні платформи | Те, що лишилося, — знаходять люди, яким платять за пошук після запуску |
| Моніторинг і пауза | Сповіщення з ланцюга; роль охоронця, що може поставити паузу | Атака в процесі — коли рахунок іде на хвилини |
Розгортання має власний чекліст. Верифікуйте код на оглядачі блоків, щоб будь-хто міг прочитати, чому довіряє. Перенесіть кожну адміністративну роль із ключа, яким розгортали, на мультипідпис і таймлок, а ролі, які нікому не потрібні, зречіться. Перевірте шлях оновлення й паузу в тестовій мережі з тією самою конфігурацією. І опублікуйте, що адміністратори можуть, а чого ні: користувачі закладають цей ризик у ціну, а чесна відповідь захищає команду не менше, ніж їх.
П’ять втрат і чого бракувало в кожній
Кожен кейс задокументовано — власним розбором команди, незалежним аналізом чи владою. Вони тягнуться від першого великого провалу до найбільшого, і саме в найбільшому не було жодної помилки в коді контракту. The DAO і Parity розказано вище, там, де живе їхній механізм.
| Кейс | Що сталося | Чого бракувало |
|---|---|---|
| The DAO, черв. 2016 | Reentrancy вивів близько 3,6 мільйона ether; Ethereum зробив хардфорк, щоб це скасувати | Зміни стану до взаємодій |
| Parity, лип. і лист. 2017 | Ініціалізатор міг викликати будь-хто: 153 000 ether вкрадено, потім 513 774 заморожено | Ініціалізатор, який можна викликати лише раз, — і жодного kill |
| Nomad, серп. 2022 | Оновлення зробило нульовий геш довіреним коренем; $190 мільйонів забрали наслідувачі | Один негативний тест оновленого контракту |
| Euler, бер. 2023 | Нова функція оминала перевірку платоспроможності; близько $197 мільйонів, згодом повернених | Інваріант: жодна дія не лишає акаунт без достатньої застави |
| Bybit, лют. 2025 | Зламаний інтерфейс підпису змусив підписантів схвалити нову реалізацію; близько $1,5 мільярда | Підписанти, що самостійно перевіряють саму транзакцію |
Третій кейс — одне хибне значення під час ініціалізації. Nomad був мостом: він видавав токени в одному ланцюгу, коли повідомлення доводило, що їх заблоковано в іншому. Повідомлення вважалося доведеним, якщо його корінь Меркла був у мапінгу довірених коренів. Під час рутинного оновлення контракт ініціалізували з нульовим гешем як довіреним коренем. У мапінгу Solidity кожен відсутній ключ читається як нуль, тож будь-яке повідомлення, яке ніколи не доводили, шукало нульовий корінь — і проходило. 1 серпня 2022 року перший зловмисник зняв кошти підробленим повідомленням; за кілька годин сотні адрес скопіювали транзакцію, змінивши лише отримувача, і з мосту пішло близько $190 мільйонів. Бракувало тесту, що оновлений контракт відхиляє недоведене повідомлення, — одного негативного тесту.
Четвертий — інваріант, якого ніхто не записав. Протокол кредитування Euler Finance дозволяв користувачам «пожертвувати» частину застави в резерви протоколу через donateToReserves — функцію, додану оновленням у 2022 році. Вона не перевіряла, чи кредит донора лишається покритим після пожертви. 13 березня 2023 року зловмисник за допомогою флеш-кредиту побудував велику позицію з плечем, навмисно пожертвував стільки застави, щоб зробити її неплатоспроможною, і ліквідував її з другого акаунта зі знижкою, яку дозволяли правила протоколу, — близько $197 мільйонів за одну послідовність. Майже все зловмисник повернув протягом кількох тижнів. Інваріант, що спіймав би це, вміщується в одне речення: жодна дія не може лишити акаунт без достатньої застави.
П’ятий — найбільша крадіжка на сьогодні, і жоден рядок коду контракту не був хибним. 21 лютого 2025 року біржа Bybit переказувала ether із холодного гаманця — мультипідписного контракту Safe — і кілька підписантів схвалювали це у вебінтерфейсі Safe{Wallet}. Інтерфейс було зламано: зловмисник проник на машину розробника Safe{Wallet} і підклав у сховище сайту JavaScript, націлений на гаманець Bybit. Підписанти бачили звичайний переказ. Підписали ж вони delegatecall до контракту зловмисника, який перезаписав комірку, де проксі Safe тримає адресу реалізації. Коли код замінили, близько 401 000 ether — приблизно $1,5 мільярда — пішли за лічені хвилини. За п’ять днів ФБР приписало крадіжку Північній Кореї. Бракувало незалежної перевірки: кожен підписант мав перевіряти сиру транзакцію — адресата, тип операції й дані — на окремому пристрої перед підписом.
Де вона вироджується
Solidity вироджується двома шляхами: як код, що вважає, ніби працює на сервері, і як процес, що заявляє більше безпеки, ніж має. Перше — це дванадцять рядків; друге — театр:
- Функції, що змінюють стан без перевірки доступу, бо «ніхто не знає, що така функція є» (рядок 1).
- Зовнішні виклики до оновлення стану або захист від reentrancy на одній функції й не на її сусідах (рядок 4).
- Ціна, прочитана з одного пулу в одному блоці, без меж і без перевірки свіжості (рядок 10).
- Цикли по масивах, які користувачі можуть нарощувати і які одного дня коштуватимуть більше газу, ніж дозволено транзакції (рядок 7).
tx.originдля авторизації абоmsg.sender == tx.originяк доказ, що викликала людина.- Контракти з оновленням під одним ключем або під мультипідписом 2 з 3, чиї підписанти сидять в одному офісі.
- Позначка «пройшов аудит» для коміту, який уже не той, що розгорнутий.
- Підписанти, що схвалюють те, що показує вебсторінка, а не те, що містить транзакція.
- Плаваюча
pragmaй оновлення компілятора без повторного запуску тестів. - Код, скопійований з туторіалу під Solidity 0.6, разом із неперевіреною арифметикою.
Чесна межа — питання, якого сторінка ще не ставила: чи потрібен тут контракт узагалі? Смартконтракт виправдовує свою ціну — публічний код, газ, жодних патчів, ворожі викликачі — лише тоді, коли користувачі мусять довіряти системі, не довіряючи тому, хто її веде: зберігання, яке ніхто не може конфіскувати, правила, які ніхто не може тихо змінити, розрахунки між сторонами, що не довіряють одна одній. Якщо оператору однаково довіряють — він тримає фронтенд, має ключ адміністратора, що може оновити все, або може поставити все на паузу, коли схоче, — база даних робить ту саму роботу швидше, дешевше й з можливістю виправити помилку у звичайний вівторок. Багато продуктів, які за останнє десятиліття поклали в ланцюг, належали до другої групи. Поставте це питання до першого рядка на Solidity.
Практична перевірка для контракту, якому ви збираєтеся довіритися чи який збираєтеся випустити: прочитайте pragma і список відомих помилок для цієї версії. Знайдіть кожну функцію без перевірки доступу й спитайте, чому так. Знайдіть кожен зовнішній виклик і перевірте, що стан оновлено до нього. З’ясуйте, звідки беруться ціни. Складіть список тих, хто може оновити чи поставити контракт на паузу, і подивіться, який таймлок. І порівняйте розгорнутий байткод із комітом, що пройшов аудит.
Коли це застосовувати
Застосовуйте, коли
- Зберігання й розрахунки між сторонами, що не довіряють одна одній чи оператору.
- Токени й активи, що мають переходити між незалежними застосунками за спільними правилами.
- Правила, що мають бути публічними й незмінними — або змінюватися лише після оголошеної затримки.
- Продукти на Ethereum чи сумісних з EVM ланцюгах, де Solidity має найбільшу базу інструментів і аудиту.
Уникайте, коли
- Будь-яка система, чиєму оператору однаково довіряють, — база даних дешевша, швидша й піддається виправленню.
- Логіка, якій потрібні секрети, приватні дані, справжня випадковість чи зовнішні дані без оракула.
- Команди без бюджету на аудит, моніторинг і процес керування ключами.
- Важкі обчислення чи великі дані — газ бере плату за кожен збережений байт і кожен крок циклу.
Джерела й метод
На чому стоїть ця стаття
- 23 джерела
- 6 задокументованих збоїв
- Перевірено 13 жовтня 2026 р.
Збої, на яких вчиться стаття
розділ «П’ять втрат і чого бракувало в кожній» і випадок Vyper після нього- СтаттяHard Fork Completed (відкривається в новій вкладці)Ethereum Foundation Blog · 20.07.2016
- ПостмортемThe Multi-sig Hack: A PostmortemParity Technologies · 19.07.2017
- ПостмортемA Postmortem on the Parity Multi-Sig Library Self-DestructParity Technologies · 06.11.2017
- ПостмортемHack Analysis: Nomad Bridge, August 2022 (відкривається в новій вкладці)Immunefi · 08.2022
- ПостмортемVyper Nonreentrancy Lock Vulnerability Technical Post-Mortem Report (відкривається в новій вкладці)Vyper · 08.2023
- СтаттяEuler Finance Exploiter Returns All ‘Recoverable Funds’ From $200M Hack (відкривається в новій вкладці)Decrypt · 04.2023
- Звіт регулятораNorth Korea Responsible for $1.5 Billion Bybit Hack (відкривається в новій вкладці)FBI · Internet Crime Complaint Center · 26.02.2025
Дослідження
що це були за втрати, порахувані за рікПрактики й походження термінів
дванадцять припущень, storage, gas і компілятор- ДокументаціяSolidity — Security Considerations (відкривається в новій вкладці)docs.soliditylang.org
- ДокументаціяSolidity — Layout of State Variables in Storage and Transient Storage (відкривається в новій вкладці)docs.soliditylang.org
- ДокументаціяSolidity v0.8.0 Breaking Changes (відкривається в новій вкладці)docs.soliditylang.org
- ДокументаціяSolidity — List of Known Bugs (відкривається в новій вкладці)docs.soliditylang.org
- Документаціяargotorg/solidity — Releases (відкривається в новій вкладці)GitHub
- СтаттяBuilding on Ethereum in 2026: what has changed (відкривається в новій вкладці)ethereum.org · 2026
- СтаттяGlamsterdam Testnet AnnouncementEthereum Foundation · 2026
Зміни протоколу за таблицею gas
розмір коду, ціна storage, transient storage, комісії й ліміти- СтандартEIP-170: Contract code size limit (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-1559: Fee market change for ETH 1.0 chain (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-2929: Gas cost increases for state access opcodes (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-1153: Transient storage opcodes (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-6780: SELFDESTRUCT only in same transaction (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-7702: Set Code for EOAs (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-7825: Transaction Gas Limit Cap (відкривається в новій вкладці)Ethereum Improvement Proposals
- СтандартEIP-7935: Set default gas limit to 60M (відкривається в новій вкладці)Ethereum Improvement Proposals
Дослідження з Claude. Пошук і звірку першоджерел зроблено з Claude (Anthropic). Відбір, текст і перевірку фактів — редакція Anatomy of IT Product.
Було корисно?
Поділіться з тим, хто працює над тією ж задачею.