РозробкаБудь-який рівень

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. Транзакція може викликати контракт, той — інші контракти, і весь ланцюг викликів або вдається разом, або разом відкочується. Кожен вузол виконує ту саму транзакцію й мусить отримати той самий результат, і тому контракт не може прочитати годинник, файл чи інтернет: усе, що могло б відрізнятися між двома вузлами, просто недоступне.

Почати транзакцію може лише акаунт під керуванням приватного ключа. Транзакція може викликати контракт, той — інші, і весь ланцюг або фіксується разом, або разом відкочується. Зовнішній виклик передає керування іншому контракту, і той може одразу повернутися назад, поки викликач не закінчив, — корінь reentrancy. Кожна інструкція коштує газу, який платить відправник; запис у сховище — найдорожча частина, а коли газ закінчується, транзакція відкочується, але газ однаково витрачено. Кожен вузол виконує ту саму транзакцію й мусить отримати той самий результат, і тому контракт не може прочитати годинник, файл чи інтернет.

Газ — спосіб, яким мережа оцінює цю роботу. Кожна інструкція 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 з типами, і подібність лише зовнішня. Контракт — це клас, чиї поля зберігаються в ланцюгу назавжди (це змінні стану), а функції — його . Версія 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, і вирішує його порядок трьох рядків.

Коли контракт надсилає ether, виконується код контракту-отримувача — і він може знову викликати відправника, поки той не закінчив. Якщо сховище оновлює баланс після надсилання, кожен повторний вхід бачить старий баланс і отримує виплату знову, доки сховище не спорожніє. Саме так The DAO у 2016 році втратив близько 3,6 мільйона 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(), щоб ніхто інший не міг її ініціалізувати. Третій — адміністратор: хто може оновлювати, той може замінити код будь-чим, і тому ключ оновлення — найцінніше, чим володіє проєкт.

Проксі тримає весь стан і виконує над ним код реалізації через delegatecall. Змінні реалізації відображаються на сховище проксі за позицією — комірка 0, комірка 1, комірка 2, — а не за іменем. Тож нова версія, що вставляє змінну над наявними, змушує кожну наступну змінну читати комірку сусіда: тут fee підхоплює старий total, а total — старий прапорець paused. Нові змінні, додані після старих, лишають кожну наявну комірку на місці. Плагін оновлень OpenZeppelin порівнює дві розкладки й відмовляється від несумісного оновлення. Значення ілюстративні.

Гроші, ціни і флеш-кредити

В 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 мільйонів. Середню, зважену за часом на багатьох блоках, чи мережу оракулів, що зводить багато джерел, однією транзакцією не зрушиш; решту ловлять перевірки свіжості й меж. Суми ілюстративні.

У жовтні 2020 року Harvest Finance втратив так близько $24 мільйонів: його сховища оцінювали внески й зняття за ціною в пулі Curve, яку щойно зрушила угода на флеш-кредит. Захист — ціна, яку не можна зрушити за одну транзакцію (середня, зважена за часом на багатьох блоках, або мережа оракулів на кшталт Chainlink, що зводить багато джерел), плюс перевірки, що відповідь свіжа й у розумних межах, і обмеження того, наскільки одна транзакція може зрушити протокол.

Тестування, аудит і постачання

Набір тестів контракту мусить зробити ту роботу, яку інакше зробив би інцидент у продакшені, бо гарячого виправлення не буде. Модульні тести — це мінімум. Окупаються фазинг — випадкові вхідні дані, тисячі на тест, — і тестування інваріантів, яке запускає випадкові послідовності викликів і після кожного перевіряє, що властивість досі тримається: «сума балансів дорівнює загальній емісії», «жоден акаунт не може зняти більше, ніж вніс». Foundry запускає обидва з тестових файлів на Solidity; Hardhat робить те саме з . Тест на форку виконується на копії стану основної мережі — зі справжніми токенами й оракулами, які зустріне контракт.

РівеньІнструментиЩо ловить
Статичний аналізSlither; власні попередження компілятораВідомі патерни помилок — reentrancy, неперевірені виклики, затінені змінні
Фазинг та інваріантиFoundry, Echidna, MedusaВхідні дані й послідовності викликів, які ніхто не здогадався записати
Формальна верифікаціяCertora, Halmos, SMTChecker у компіляторіДоказ, що властивість тримається для будь-якого входу, — для тих властивостей, які ви записали
АудитЗовнішня фірма або публічний конкурсПомилки задуму й логіки, яких команда не бачить у власному коді
Bug bountyImmunefi та подібні платформиТе, що лишилося, — знаходять люди, яким платять за пошук після запуску
Моніторинг і паузаСповіщення з ланцюга; роль охоронця, що може поставити паузуАтака в процесі — коли рахунок іде на хвилини

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

П’ять втрат і чого бракувало в кожній

Кожен кейс задокументовано — власним розбором команди, незалежним аналізом чи владою. Вони тягнуться від першого великого провалу до найбільшого, і саме в найбільшому не було жодної помилки в коді контракту. The DAO і Parity розказано вище, там, де живе їхній механізм.

КейсЩо сталосяЧого бракувало
The DAO, черв. 2016Reentrancy вивів близько 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 р.

Дослідження з Claude. Пошук і звірку першоджерел зроблено з Claude (Anthropic). Відбір, текст і перевірку фактів — редакція Anatomy of IT Product.

Було корисно?

Поділіться з тим, хто працює над тією ж задачею.