Одна з проблем Ethereum полягає в тому, що за замовчуванням роздутість і складність будь-якого блокчейн-протоколу з часом зростає. Це відбувається в двох місцях:
Для того, щоб Ethereum зберігав себе в довгостроковій перспективі, нам потрібен сильний контртиск проти обох цих тенденцій, зменшуючи складність і роздуття з часом. Але в той же час нам потрібно зберегти одну з ключових властивостей, яка робить блокчейни чудовими: їх постійність. Ви можете помістити NFT, любовну записку в транзакції calldata або смарт-контракт, що містить мільйон доларів, ончейн, піти в печеру на десять років, вийти і виявити, що він все ще там, чекаючи, поки ви прочитаєте і зможете з ним взаємодіяти. Для того, щоб децентралізовані застосунки почувалися комфортно, вони повинні бути впевнені, що їхні залежності не порушать їх, особливо сам L1.
Прибирання, дорожня карта на 2023 рік.
Забалансувати між цими двома потребами та мінімізувати або знищити надмірне зростання, складність і розклад при збереженні неперервності цілком можливо, якщо ми приділимо цьому увагу. Живі організми можуть це зробити: хоча більшість старіють з часом,щасливі обраний не роблять. Навіть соціальні системи можуть має надзвичайно довговічністьНа кількох випадках Ethereum вже показував успіхи: доказ роботи вже відсутній, опкод SELFDESTRUCT в основному відсутній, а вузли ланцюга маяка вже зберігають старі дані лише до шести місяців. Знаходження цього шляху для Ethereum більш узагальненим способом і рухання в напрямку кінцевого результату, який є стабільним на довготривалий термін, - це кінцеве виклик для довгострокової масштабованості Ethereum, технічної стійкості навіть безпеки.
На момент написання цієї статті повністю синхронізований вузол Ethereum вимагає приблизно 1.1 терабайтидискового простору для виконавчий клієнт, плюс ще кілька сотень гігабайтів для клієнта згоди. Велика більшість з них - це історія: дані про історичні блоки, транзакції та квитанції, більшість з яких мають кілька років. Це означає, що розмір вузла зростає на сотні гігабайтів щороку, навіть якщо ліміт газу не збільшується.
Ключовою спрощувальною особливістю проблеми зберігання історії є те, що кожний блок вказує на попередній блок за допомогою хеш-посилання (і іншийструктури), мати згоду щодо теперішнього достатньо, щоб мати згоду щодо історії. Якщо мережа має згоду щодо останнього блоку, будь-який історичний блок або транзакція або стан (баланс рахунку, nonce, код, сховище) може бути наданий будь-яким окремим актором разом з доказом Меркле, і доказ дозволяє будь-кому іншому перевірити його правильність. Хоча згода - це модель довіри N/2 з N, історія - це 1-of-N модель довіри.
Це відкриває багато варіантів того, як ми можемо зберігати історію. Один природний варіант - мережа, де кожен вузол зберігає лише невеликий відсоток даних. Це те, як працюють торрент-мережі десятиліттями: хоча мережа в цілому зберігає й поширює мільйони файлів, кожен учасник зберігає й поширює лише кілька з них. Можливо, противорічно, цей підхід навіть не обов'язково зменшує надійність даних. Якщо, зробивши роботу вузла більш доступною, ми зможемо дійти до мережі з 100 000 вузлів, де кожен вузол зберігає випадковий 10% історії, то кожний шматок даних буде реплікований 10 000 разів - точно такий самий коефіцієнт реплікації, як і в мережі з 10 000 вузлів, де кожен вузол зберігає все.
Сьогодні Ethereum вже почало відходити від моделі, коли всі вузли зберігають всю історію назавжди. Блоки консенсусу (тобто частини, пов'язані з консенсусом доказу урахування) зберігаються лише протягом приблизно 6 місяців. Блоби зберігаються лише протягом приблизно 18 днів.EIP-4444 має на меті ввести однорічний термін зберігання історичних блоків та квитанцій. Довгострокова мета - мати узгоджений період (який може бути ~18 днів), протягом якого кожен вузол відповідає за зберігання всього, а потім мати мережу з вузлів Ethereum, які зберігають старі дані розподіленим чином.
Коди помилок можна використовувати для збільшення надійності, залишаючи при цьому фактор реплікації незмінним. Насправді, блоби вже мають код помилок для підтримки вибірковості доступу до даних. Найпростішим рішенням може бути використання цього коду помилок для включення даних блоків виконання та консенсусу також у блоби.
Основна залишена робота полягає в побудові та інтеграції конкретного розподіленого рішення для зберігання історії - принаймні історії виконання, але в кінцевому підсумку також згоди та блоків. Найпростіші рішення для цього - (i) просто ввести існуючу бібліотеку торрентів, та (ii) рішення, що нативно для Ethereum, викликало мережа Portal. Як тільки буде введено будь-яку з цих функцій, ми зможемо увімкнути EIP-4444. Сам EIP-4444 не вимагає жорсткого відгалуження, хоча він потребує нової версії мережевого протоколу. З цієї причини є цінність у ввімкненні його для всіх клієнтів одночасно, оскільки в іншому випадку є ризики неправильної роботи клієнтів при підключенні до інших вузлів, які очікують завантаження повної історії, але фактично не отримують її.
Головна компроміс полягає у тому, наскільки ми намагаємося зробити доступними «старі» історичні дані. Найпростішим рішенням було б просто припинити зберігання старої історії завтра і покладатися на існуючі архівні вузли та різні централізовані провайдери для реплікації. Це легко, але це ослаблює позицію Ethereum як місця для зберігання постійних записів. Важший, але безпечніший шлях - спочатку розробити і інтегрувати мережу торрентів для зберігання історії у розподіленому вигляді. Тут є дві виміри «наскільки ми намагаємося»:
Максимально параноїдальний підхід до (1) передбачав би доказ власності: фактично потрібно, щоб кожен валідатор доказу утримання зберігав певний відсоток історії та регулярно криптографічно перевіряв, чи він це робить. Більш помірний підхід полягає в тому, щоб встановити добровільний стандарт для того, який відсоток історії зберігає кожен клієнт.
Для (2) базова реалізація передбачає просто брати те, що вже зроблено сьогодні: Портал вже зберігає файли ERA, що містять всю історію Ethereum. Більш ретельна реалізація передбачатиме фактичне підключення цього до процесу синхронізації, щоб, якщо хтось хоче синхронізувати вузол, який зберігає повну історію або архівний вузол, вони могли це зробити навіть у випадку, якщо немає інших архівних вузлів онлайн, синхронізуючись безпосередньо з мережі Порталу.
Зменшення вимог до зберігання історії, можливо, навіть важливіше, ніж відсутність стану, якщо ми хочемо зробити запуск або розгортання вузла надзвичайно простим: з 1,1 ТБ, які повинен мати вузол, ~300 ГБ є станом, а решта ~800 ГБ є історією. Концепція вузла Ethereum, що працює на смарт-годиннику та потребує лише кількох хвилин для налаштування, досяжна лише за умови реалізації як безгромадянства, так і EIP-4444.
Обмеження зберігання історії також робить більш життєздатним для нових реалізацій вузлів Ethereum підтримувати лише останні версії протоколу, що дозволяє їм бути набагато простішими. Наприклад, багато рядків коду можна безпечно видалити тепер, коли порожні слоти для зберігання, створені під час DoS-атак 2016 року, були видалено. Тепер, коли перехід на доказ ставки - це стара історія, клієнти можуть безпечно видалити весь код, пов'язаний з доказом роботи.
Навіть якщо ми усунемо потребу клієнтів зберігати історію, вимоги до зберігання клієнта будуть продовжувати зростати, приблизно на 50 ГБ щороку, через постійний ріст стану: баланси рахунків та номери, код контракту та сховище контракту. Користувачі можуть сплатити одноразову вартість, щоб навіки навантажити поточних і майбутніх клієнтів Ethereum.
Стан набагато важче "закінчити", ніж історію, оскільки EVM фундаментально розроблений на основі припущення, що як тільки об'єкт стану створено, він завжди буде там і може бути прочитаний будь-якою транзакцією в будь-який час. Якщо ми введемо безстандартність, є аргумент, що, можливо, ця проблема не така погана: лише спеціалізований клас будівельників блоків дійсно потребуватиме зберігати стан, і всі інші вузли (навіть список включенняпродукція!) може працювати без збереження стану. Однак існує аргумент, що ми не хочемо надто розраховувати на безстатевість, і в кінцевому підсумку ми можемо бажати видаляти стан, щоб зберегти Ethereum децентралізованим.
Сьогодні, коли ви створюєте новий об'єкт стану (що може статися одним із трьох способів: (i) надсилання ETH на новий рахунок, (ii) створення нового рахунку з кодом, (iii) встановлення раніше непорушеного слоту сховища), цей об'єкт стану залишається в стані назавжди. Те, що ми хочемо замість цього, - це автоматичний закінчення терміну дії об'єктів з плином часу. Ключове викликання полягає в тому, як це зробити таким чином, щоб досягти трьох цілей:
Легко вирішити проблему, не задовольняючи цих цілей. Наприклад, ви можете зробити так, щоб кожен об'єкт стану також зберігав лічильник для свого терміну дії (який можна було б подовжити, записавши ETH, що може статися автоматично кожного разу, коли він читається або записується), і мати процес, який циклічно проходить через стан, щоб видалити прострочені об'єкти стану. Однак це вводить додаткові обчислення (і навіть вимоги до зберігання), і це, безумовно, не задовольняє вимогу зручності для користувача. Розробникам також було б важко міркувати про крайні випадки, пов'язані зі значеннями сховища, які іноді скидаються до нуля. Якщо ви зробите таймер закінчення терміну дії на весь контракт, це технічно полегшить життя розробникам, але ускладнить економіку: розробникам доведеться думати про те, як «перекласти» поточні витрати на зберігання даних на своїх користувачів.
Це проблеми, з якими спільнота розробників ядра Ethereum боролася протягом багатьох років, включаючи такі пропозиції, як «блокчейн оренда“ і “регенезаВ кінцевому рахунку ми поєднали найкращі частини пропозицій і сконцентрувались на двох категоріях «найменш поганих відомих рішень»:
Пропозиції щодо часткового закінчення терміну дії працюють за одним принципом. Ми ділимо державу на шматки. Кожен постійно зберігає «карту верхнього рівня», фрагменти якої порожні або непорожні. Дані в кожному фрагменті зберігаються лише в тому випадку, якщо до цих даних було нещодавно отримано доступ. Існує механізм «воскресіння», коли якщо фрагмент більше не зберігається, будь-хто може повернути ці дані, надавши докази того, якими були дані.
Основні відмінності між цими пропозиціями полягають в наступному: (i) як ми визначаємо "недавно", і (ii) як ми визначаємо "частину"? Одна конкретна пропозиція полягає в тому, що EIP-7736, який базується на дизайні «стебло і листок»введений для дерев Веркле (хоча сумісний з будь-якою формою безгромадянства, наприклад, бінарними деревами). У такій конструкції заголовок, код і слоти зберігання, які примикають один до одного, зберігаються під одним «стеблом». Обсяг даних, що зберігаються під стеблом, може становити не більше 256 * 31 = 7,936 байт. У багатьох випадках увесь заголовок і код, а також багато слотів для зберігання ключів облікового запису зберігатимуться в одній основі. Якщо дані під даним стеблом не читаються і не записуються протягом 6 місяців, дані більше не зберігаються, а замість цього зберігається лише 32-байтове зобов'язання («заглушка») до даних. Майбутні транзакції, які отримають доступ до цих даних, повинні будуть «воскресити» дані з доказом, який буде звірятися з заглушкою.
Існують інші способи реалізації подібної ідеї. Наприклад, якщо рівень деталізації на рівні облікового запису недостатній, ми можемо створити схему, в якій кожна 1/232 частина дерева контролюється аналогічним механізмом стебла та листя.
Це складніше через стимули: зловмисник може змусити клієнтів постійно зберігати дуже велику кількість стану, поміщаючи дуже велику кількість даних в одне піддерево і відправляючи одну транзакцію щороку для «оновлення дерева». Якщо ви зробите вартість поновлення пропорційною (або тривалість поновлення обернено пропорційною) розміру дерева, то хтось може засмутити іншого користувача, помістивши дуже велику кількість даних у те саме піддерево, що й він. Можна спробувати обмежити обидві проблеми, зробивши деталізацію динамічною на основі розміру піддерева: наприклад, кожен наступний 216 = 65536 об'єктів стану може розглядатися як «група». Однак ці ідеї більш складні; Підхід, заснований на STEM, простий, і він узгоджує стимули, оскільки, як правило, всі дані в STEM пов'язані з одним і тим же додатком або користувачем.
Що, якщо ми хочемо уникнути будь-якого постійного зростання стану, навіть 32-байтові підсили? Це складна проблема через@vbuterin/state_size_management#Resurrection-conflicts">resurrection конфлікти: що, якщо об'єкт стану видаляється, пізніше виконання EVM розміщує інший об'єкт стану в точно тій самій позиції, але після цього хтось, кому цікавий початковий об'єкт стану, повертається і намагається його відновити? З частковим строком придатності об'єкта стану «заглушка» запобігає створенню нових даних. З повним строком придатності об'єкта стану нам не вистачає навіть заглушки.
Дизайн, заснований на адресному періоді, є найвідомішою ідеєю для вирішення цієї проблеми. Замість того, щоб мати одне дерево стану, що зберігає весь стан, ми маємо постійно зростаючий список дерев станів, і будь-який стан, який читається або записується, зберігається в останньому дереві станів. Нове порожнє дерево стану додається один раз на період (подумайте: 1 рік). Старі державні дерева вимерзли твердими. Очікується, що повні ноди зберігатимуть лише останні два дерева. Якщо об'єкт стану не чіпався протягом двох періодів і, таким чином, потрапляє в прострочене дерево, його все одно можна прочитати або записати, але транзакція повинна буде довести доказ Меркла для нього - і як тільки це станеться, копія знову буде збережена в останньому дереві.
Ключовою ідеєю для того, щоб зробити все це зручним для користувачів і розробників, є концепція адресних періодів. Період адреси – це число, яке є частиною адреси. Ключове правило полягає в тому, що адреса з періодом адреси N може бути прочитана або записана тільки під час або після періоду N (тобто, коли список дерева станів досягає довжини N). Якщо ви зберігаєте новий об'єкт стану (наприклад, новий контракт або новий баланс ERC20), якщо ви обов'язково помістили об'єкт стану в контракт з періодом адреси N або N-1, ви можете зберегти його негайно, без необхідності надавати докази того, що там нічого не було раніше. З іншого боку, будь-які доповнення або правки, внесені в старі періоди адреси, вимагають доказів.
Цей дизайн зберігає більшість поточних властивостей Ethereum, дуже легкий для додаткового обчислення, дозволяє писати додатки майже так само, як сьогодні (ERC20-и повинні переписати, щоб забезпечити, що баланси адрес з адресним періодом N зберігаються в дочірньому договорі, який сам має адресний період N), і вирішує проблему «користувач йде в печеру на п'ять років». Однак у нього є одна велика проблема: адреси потрібно розширити понад 20 байт, щоб вмістити адресні періоди.
Одна з пропозицій - ввести новий формат адреси з 32 байтами, який включає номер версії, номер періоду адреси та розширений хеш.
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
Червоний це номер версії. Чотири нулі, забарвлені помаранчево, тут призначені як порожній простір, який може вміщати номер частки у майбутньому. Зелений - це номер періоду адреси. Синій - це хеш 26 байтів.
Основним викликом тут є зворотна сумісність. Існуючі контракти розроблені навколо 20-байтових адрес, і часто використовують техніки жорсткого упаковування байтів, які явно передбачають, що адреси складають точно 20 байт.@ipsilonОдин із варіантів вирішення цієї проблеми передбачає карту перекладу, де контракти старого стилю, що взаємодіють з адресами нового стилю, бачили б 20-байтний хеш адреси нового стилю. Однак це пов'язано зі значними складнощами у забезпеченні цього безпечним.
Ще один підхід йде у протилежному напрямку: ми одразу ж забороняємо деякий піддіапазон розміром 2128 адрес (наприклад, всі адреси, що починаються з 0xffffffff), а потім використовуємо цей діапазон для введення адрес з періодами адрес і хешів розміром 14 байт.
0xfffffff000169125d5dFcb7B8C2659029395bdF
Ключова жертва, яку приносить цей підхід, полягає в тому, що він представляє ризики безпеки для контрфактних адрес: адреси, які утримують активи або дозволи, але код яких ще не був опублікований на ланцюжку. Ризик полягає в тому, що хтось створює адресу, яка претендує на наявність одного шматка (ще не опублікованого) коду, але також має інший дійсний шматок коду, який має однаковий хеш з адресою. Обчислення такого зіткнення вимагає 280 хеші сьогодні; Скорочення адресного простору зменшило б це число до дуже доступного 256хеши.
Ключова область ризику, контрфактні адреси, які не є гаманцями, утримуваними одним власником, сьогодні є відносно рідкісним випадком, але ймовірно стане більш поширеним, коли ми увійдемо в світ багаторівневих рішень. Єдиний варіант - просто прийняти цей ризик, але визначити всі типові ситуації, де це може стати проблемою, і знайти ефективні обхідні шляхи.
Я бачу чотири життєздатних шляхи для майбутнього:
Один важливий момент полягає в тому, що складні питання розширення та стиснення адресного простору в кінцевому рахунку мають бути вирішені незалежно від того, чи будуть впроваджені схеми закінчення терміну дії держави, які залежать від змін формату адреси. Сьогодні це займає приблизно 280гешує для генерації колізії адрес, обчислювальне навантаження, яке вже є можливим для надзвичайно ресурсних акторів: відеокарта може виконувати приблизно 227хеші, тому протягом року він може обчислити 252, отже все ~2^30 відеокарт в світіможе обчислити зіткнення за ~1/4 року, а FPGA та ASIC можуть ще більше прискорити цей процес. У майбутньому такі атаки стануть доступними для все більшої кількості людей. Тому фактична вартість впровадження повного закінчення терміну дії стану може бути не такою високою, як здається, оскільки нам все одно потрібно вирішити цю дуже складну проблему адреси.
Виконання терміну дії стану потенційно полегшує переходи від одного формату дерева стану до іншого, оскільки не буде потреби в процедурі переходу: ви можете просто почати створювати нові дерева за новим форматом, а потім зробити хардфорк, щоб перетворити старі дерева. Тому, хоча термін дії стану є складним, він має переваги в спрощенні інших аспектів дорожньої карти.
Однією з ключових передумов безпеки, доступності та достовірна нейтральність це простота. Якщо протокол красивий і простий, це зменшує ймовірність того, що в ньому виникнуть помилки. Це збільшує шанс на те, що нові розробники зможуть прийти і попрацювати з будь-якою його частиною. Швидше за все, це буде справедливо і легше захищатися від особливих інтересів. На жаль, протоколи, як і будь-яка соціальна система, за замовчуванням з часом ускладнюються. Якщо ми не хочемо, щоб Ethereum потрапив у чорну діру постійно зростаючої складності, нам потрібно зробити одну з двох речей: (i) припинити вносити зміни та закостеніти протокол, (ii) мати можливість фактично видаляти функції та зменшувати складність. Також можливий проміжний шлях, який полягає у внесенні меншої кількості змін до протоколу, а також усуненні хоча б невеликої складності з часом. У цьому розділі ми розповімо про те, як ми можемо зменшити або усунути складність.
Немає жодного великого одноразового виправлення, яке може зменшити складність протоколу; вроджена природа проблеми полягає в тому, що є багато малих виправлень.
Один приклад, який вже в основному закінчений і може слугувати зразком для того, як вирішувати інші, є@vbuterin/selfdestruct">видалення коду операції SELFDESTRUCT. Код операції SELFDESTRUCT був єдиним кодом операції, який міг змінювати необмежену кількість слотів зберігання в межах одного блоку, вимагаючи від клієнтів реалізації значно більшої складності, щоб уникнути DoS-атак. Початкова мета операційного коду полягала в тому, щоб уможливити добровільне очищення штату, дозволяючи розміру штату з часом зменшуватися. На практиці мало хто в кінцевому підсумку скористався нею. Об'єкт опкод був зменшений дозволяти лише саморуйнівні облікові записи, створені під час однієї транзакції в хардфорку Dencun. Це вирішує проблему DoS і дозволяє значно спростити код клієнта. У майбутньому, ймовірно, має сенс з часом повністю видалити код операції.
Деякі ключові приклади можливостей спрощення протоколу, які вже були виявлені, включають наступне. По-перше, деякі приклади, які знаходяться поза EVM; вони є відносно неінвазивними і, отже, легше досягти згоди та реалізувати за короткий період часу.
Зараз деякі приклади, які знаходяться всередині EVM:
Основним компромісом при спрощенні такого роду можливостей є (i) наскільки ми спрощуємо та наскільки швидко проти (ii) зворотної сумісності. Вартість Ethereum як ланцюга полягає в тому, що ви можете розгорнути додаток і бути впевненими, що він працюватиме ще багато років. В той же час, можливо підійти до цієї ідеї занадто далеко і, перефразувати Вільяма Дженнінгса Браяна, «розіп'яти Ethereum на хресті зворотної сумісності». Якщо в Ethereum існують лише дві програми, які використовують певну функцію, і одна з них не має жодного користувача протягом років, а інша майже повністю не використовується і захищає загальну суму в $57, то ми просто повинні видалити цю функцію, і якщо потрібно, відшкодувати постраждалим $57 з власного карману.
Більш широкою соціальною проблемою є створення стандартизованого конвеєра для здійснення зворотної сумісності, яка не порушує невідкладних змін. Один з способів підходу до цього полягає в розгляді та розширенні існуючих прецедентів, таких як процес SELFDESTRUCT. Конвеєр виглядає так:
Між кроком 1 та кроком 4 має бути багаторічний конвеєр, з чіткою інформацією про те, які елементи знаходяться на якому кроці. На цьому етапі є компроміс між тим, наскільки енергійним та швидким є процес видалення функцій, порівняно з більш консервативним підходом і вкладанням більше ресурсів у інші галузі розвитку протоколу, але ми все ще далекі від Парето-фронту.
Головний набір змін, який був запропонований для EVM, цеФормат об'єкта EVM (EOF). EOF вводить велику кількість змін, таких як заборона газової спостережуваності, спостережуваність коду (тобто відсутність CODECOPY), що дозволяє лише статичні стрибки. Мета полягає в тому, щоб дозволити EVM більше оновлюватися, таким чином, щоб він мав сильніші властивості, зберігаючи при цьому зворотну сумісність (оскільки EVM до EOF все ще існуватиме).
Це має ту перевагу, що створює природний шлях до додавання нових функцій EVM і заохочення переходу на більш обмежувальний EVM із сильнішими гарантіями. Його недолік полягає в тому, що він значно збільшує складність протоколу, якщо ми не зможемо знайти спосіб зрештою застаріти та видалити старий EVM. Одне з основних питань полягає в наступному: яку роль відіграє EOF у пропозиціях щодо спрощення EVM, особливо якщо метою є зменшення складності EVM в цілому?
Багато з пропозицій «вдосконалення» в іншій частині дорожньої карти також є можливостями для спрощення старих функцій. Щоб повторити деякі приклади зверху:
Більш радикальна стратегія спрощення Ethereum полягає в тому, щоб залишити протокол як є, але перенести велику частину його з рис протоколу на код контракту.
Найекстремальніша версія цього полягає в тому, щоб Ethereum L1 фактично був лише ланцюжком маяка та ввести мінімальну ВМ (наприклад, RISC-V, Каїрабо ще більш мінімальний, спеціалізований для систем доведення) , що дозволяє будь-кому створювати власний rollup. EVM стане першим з цих rollup. Це іронічно виявляється тим самим результатом, що й в Пропозиції щодо середовища виконання на 2019-20 роки, хоча SNARKs роблять його значно більш життєздатним для фактичної реалізації.
Більш помірний підхід полягає в тому, щоб залишити відношення між ланцюжком-маяком та поточним середовищем виконання Ethereum без змін, але зробити заміну EVM на місці. Ми можемо вибрати RISC-V, Cairo або іншу віртуальну машину (VM) в якості нового «офіційного Ethereum VM», а потім примусово конвертувати всі контракти EVM у новий код VM, який інтерпретує логіку початкового коду (шляхом компіляції або інтерпретації). Теоретично, це навіть можна зробити з «цільовою VM», яка є версією EOF.
Одна з проблем Ethereum полягає в тому, що за замовчуванням роздутість і складність будь-якого блокчейн-протоколу з часом зростає. Це відбувається в двох місцях:
Для того, щоб Ethereum зберігав себе в довгостроковій перспективі, нам потрібен сильний контртиск проти обох цих тенденцій, зменшуючи складність і роздуття з часом. Але в той же час нам потрібно зберегти одну з ключових властивостей, яка робить блокчейни чудовими: їх постійність. Ви можете помістити NFT, любовну записку в транзакції calldata або смарт-контракт, що містить мільйон доларів, ончейн, піти в печеру на десять років, вийти і виявити, що він все ще там, чекаючи, поки ви прочитаєте і зможете з ним взаємодіяти. Для того, щоб децентралізовані застосунки почувалися комфортно, вони повинні бути впевнені, що їхні залежності не порушать їх, особливо сам L1.
Прибирання, дорожня карта на 2023 рік.
Забалансувати між цими двома потребами та мінімізувати або знищити надмірне зростання, складність і розклад при збереженні неперервності цілком можливо, якщо ми приділимо цьому увагу. Живі організми можуть це зробити: хоча більшість старіють з часом,щасливі обраний не роблять. Навіть соціальні системи можуть має надзвичайно довговічністьНа кількох випадках Ethereum вже показував успіхи: доказ роботи вже відсутній, опкод SELFDESTRUCT в основному відсутній, а вузли ланцюга маяка вже зберігають старі дані лише до шести місяців. Знаходження цього шляху для Ethereum більш узагальненим способом і рухання в напрямку кінцевого результату, який є стабільним на довготривалий термін, - це кінцеве виклик для довгострокової масштабованості Ethereum, технічної стійкості навіть безпеки.
На момент написання цієї статті повністю синхронізований вузол Ethereum вимагає приблизно 1.1 терабайтидискового простору для виконавчий клієнт, плюс ще кілька сотень гігабайтів для клієнта згоди. Велика більшість з них - це історія: дані про історичні блоки, транзакції та квитанції, більшість з яких мають кілька років. Це означає, що розмір вузла зростає на сотні гігабайтів щороку, навіть якщо ліміт газу не збільшується.
Ключовою спрощувальною особливістю проблеми зберігання історії є те, що кожний блок вказує на попередній блок за допомогою хеш-посилання (і іншийструктури), мати згоду щодо теперішнього достатньо, щоб мати згоду щодо історії. Якщо мережа має згоду щодо останнього блоку, будь-який історичний блок або транзакція або стан (баланс рахунку, nonce, код, сховище) може бути наданий будь-яким окремим актором разом з доказом Меркле, і доказ дозволяє будь-кому іншому перевірити його правильність. Хоча згода - це модель довіри N/2 з N, історія - це 1-of-N модель довіри.
Це відкриває багато варіантів того, як ми можемо зберігати історію. Один природний варіант - мережа, де кожен вузол зберігає лише невеликий відсоток даних. Це те, як працюють торрент-мережі десятиліттями: хоча мережа в цілому зберігає й поширює мільйони файлів, кожен учасник зберігає й поширює лише кілька з них. Можливо, противорічно, цей підхід навіть не обов'язково зменшує надійність даних. Якщо, зробивши роботу вузла більш доступною, ми зможемо дійти до мережі з 100 000 вузлів, де кожен вузол зберігає випадковий 10% історії, то кожний шматок даних буде реплікований 10 000 разів - точно такий самий коефіцієнт реплікації, як і в мережі з 10 000 вузлів, де кожен вузол зберігає все.
Сьогодні Ethereum вже почало відходити від моделі, коли всі вузли зберігають всю історію назавжди. Блоки консенсусу (тобто частини, пов'язані з консенсусом доказу урахування) зберігаються лише протягом приблизно 6 місяців. Блоби зберігаються лише протягом приблизно 18 днів.EIP-4444 має на меті ввести однорічний термін зберігання історичних блоків та квитанцій. Довгострокова мета - мати узгоджений період (який може бути ~18 днів), протягом якого кожен вузол відповідає за зберігання всього, а потім мати мережу з вузлів Ethereum, які зберігають старі дані розподіленим чином.
Коди помилок можна використовувати для збільшення надійності, залишаючи при цьому фактор реплікації незмінним. Насправді, блоби вже мають код помилок для підтримки вибірковості доступу до даних. Найпростішим рішенням може бути використання цього коду помилок для включення даних блоків виконання та консенсусу також у блоби.
Основна залишена робота полягає в побудові та інтеграції конкретного розподіленого рішення для зберігання історії - принаймні історії виконання, але в кінцевому підсумку також згоди та блоків. Найпростіші рішення для цього - (i) просто ввести існуючу бібліотеку торрентів, та (ii) рішення, що нативно для Ethereum, викликало мережа Portal. Як тільки буде введено будь-яку з цих функцій, ми зможемо увімкнути EIP-4444. Сам EIP-4444 не вимагає жорсткого відгалуження, хоча він потребує нової версії мережевого протоколу. З цієї причини є цінність у ввімкненні його для всіх клієнтів одночасно, оскільки в іншому випадку є ризики неправильної роботи клієнтів при підключенні до інших вузлів, які очікують завантаження повної історії, але фактично не отримують її.
Головна компроміс полягає у тому, наскільки ми намагаємося зробити доступними «старі» історичні дані. Найпростішим рішенням було б просто припинити зберігання старої історії завтра і покладатися на існуючі архівні вузли та різні централізовані провайдери для реплікації. Це легко, але це ослаблює позицію Ethereum як місця для зберігання постійних записів. Важший, але безпечніший шлях - спочатку розробити і інтегрувати мережу торрентів для зберігання історії у розподіленому вигляді. Тут є дві виміри «наскільки ми намагаємося»:
Максимально параноїдальний підхід до (1) передбачав би доказ власності: фактично потрібно, щоб кожен валідатор доказу утримання зберігав певний відсоток історії та регулярно криптографічно перевіряв, чи він це робить. Більш помірний підхід полягає в тому, щоб встановити добровільний стандарт для того, який відсоток історії зберігає кожен клієнт.
Для (2) базова реалізація передбачає просто брати те, що вже зроблено сьогодні: Портал вже зберігає файли ERA, що містять всю історію Ethereum. Більш ретельна реалізація передбачатиме фактичне підключення цього до процесу синхронізації, щоб, якщо хтось хоче синхронізувати вузол, який зберігає повну історію або архівний вузол, вони могли це зробити навіть у випадку, якщо немає інших архівних вузлів онлайн, синхронізуючись безпосередньо з мережі Порталу.
Зменшення вимог до зберігання історії, можливо, навіть важливіше, ніж відсутність стану, якщо ми хочемо зробити запуск або розгортання вузла надзвичайно простим: з 1,1 ТБ, які повинен мати вузол, ~300 ГБ є станом, а решта ~800 ГБ є історією. Концепція вузла Ethereum, що працює на смарт-годиннику та потребує лише кількох хвилин для налаштування, досяжна лише за умови реалізації як безгромадянства, так і EIP-4444.
Обмеження зберігання історії також робить більш життєздатним для нових реалізацій вузлів Ethereum підтримувати лише останні версії протоколу, що дозволяє їм бути набагато простішими. Наприклад, багато рядків коду можна безпечно видалити тепер, коли порожні слоти для зберігання, створені під час DoS-атак 2016 року, були видалено. Тепер, коли перехід на доказ ставки - це стара історія, клієнти можуть безпечно видалити весь код, пов'язаний з доказом роботи.
Навіть якщо ми усунемо потребу клієнтів зберігати історію, вимоги до зберігання клієнта будуть продовжувати зростати, приблизно на 50 ГБ щороку, через постійний ріст стану: баланси рахунків та номери, код контракту та сховище контракту. Користувачі можуть сплатити одноразову вартість, щоб навіки навантажити поточних і майбутніх клієнтів Ethereum.
Стан набагато важче "закінчити", ніж історію, оскільки EVM фундаментально розроблений на основі припущення, що як тільки об'єкт стану створено, він завжди буде там і може бути прочитаний будь-якою транзакцією в будь-який час. Якщо ми введемо безстандартність, є аргумент, що, можливо, ця проблема не така погана: лише спеціалізований клас будівельників блоків дійсно потребуватиме зберігати стан, і всі інші вузли (навіть список включенняпродукція!) може працювати без збереження стану. Однак існує аргумент, що ми не хочемо надто розраховувати на безстатевість, і в кінцевому підсумку ми можемо бажати видаляти стан, щоб зберегти Ethereum децентралізованим.
Сьогодні, коли ви створюєте новий об'єкт стану (що може статися одним із трьох способів: (i) надсилання ETH на новий рахунок, (ii) створення нового рахунку з кодом, (iii) встановлення раніше непорушеного слоту сховища), цей об'єкт стану залишається в стані назавжди. Те, що ми хочемо замість цього, - це автоматичний закінчення терміну дії об'єктів з плином часу. Ключове викликання полягає в тому, як це зробити таким чином, щоб досягти трьох цілей:
Легко вирішити проблему, не задовольняючи цих цілей. Наприклад, ви можете зробити так, щоб кожен об'єкт стану також зберігав лічильник для свого терміну дії (який можна було б подовжити, записавши ETH, що може статися автоматично кожного разу, коли він читається або записується), і мати процес, який циклічно проходить через стан, щоб видалити прострочені об'єкти стану. Однак це вводить додаткові обчислення (і навіть вимоги до зберігання), і це, безумовно, не задовольняє вимогу зручності для користувача. Розробникам також було б важко міркувати про крайні випадки, пов'язані зі значеннями сховища, які іноді скидаються до нуля. Якщо ви зробите таймер закінчення терміну дії на весь контракт, це технічно полегшить життя розробникам, але ускладнить економіку: розробникам доведеться думати про те, як «перекласти» поточні витрати на зберігання даних на своїх користувачів.
Це проблеми, з якими спільнота розробників ядра Ethereum боролася протягом багатьох років, включаючи такі пропозиції, як «блокчейн оренда“ і “регенезаВ кінцевому рахунку ми поєднали найкращі частини пропозицій і сконцентрувались на двох категоріях «найменш поганих відомих рішень»:
Пропозиції щодо часткового закінчення терміну дії працюють за одним принципом. Ми ділимо державу на шматки. Кожен постійно зберігає «карту верхнього рівня», фрагменти якої порожні або непорожні. Дані в кожному фрагменті зберігаються лише в тому випадку, якщо до цих даних було нещодавно отримано доступ. Існує механізм «воскресіння», коли якщо фрагмент більше не зберігається, будь-хто може повернути ці дані, надавши докази того, якими були дані.
Основні відмінності між цими пропозиціями полягають в наступному: (i) як ми визначаємо "недавно", і (ii) як ми визначаємо "частину"? Одна конкретна пропозиція полягає в тому, що EIP-7736, який базується на дизайні «стебло і листок»введений для дерев Веркле (хоча сумісний з будь-якою формою безгромадянства, наприклад, бінарними деревами). У такій конструкції заголовок, код і слоти зберігання, які примикають один до одного, зберігаються під одним «стеблом». Обсяг даних, що зберігаються під стеблом, може становити не більше 256 * 31 = 7,936 байт. У багатьох випадках увесь заголовок і код, а також багато слотів для зберігання ключів облікового запису зберігатимуться в одній основі. Якщо дані під даним стеблом не читаються і не записуються протягом 6 місяців, дані більше не зберігаються, а замість цього зберігається лише 32-байтове зобов'язання («заглушка») до даних. Майбутні транзакції, які отримають доступ до цих даних, повинні будуть «воскресити» дані з доказом, який буде звірятися з заглушкою.
Існують інші способи реалізації подібної ідеї. Наприклад, якщо рівень деталізації на рівні облікового запису недостатній, ми можемо створити схему, в якій кожна 1/232 частина дерева контролюється аналогічним механізмом стебла та листя.
Це складніше через стимули: зловмисник може змусити клієнтів постійно зберігати дуже велику кількість стану, поміщаючи дуже велику кількість даних в одне піддерево і відправляючи одну транзакцію щороку для «оновлення дерева». Якщо ви зробите вартість поновлення пропорційною (або тривалість поновлення обернено пропорційною) розміру дерева, то хтось може засмутити іншого користувача, помістивши дуже велику кількість даних у те саме піддерево, що й він. Можна спробувати обмежити обидві проблеми, зробивши деталізацію динамічною на основі розміру піддерева: наприклад, кожен наступний 216 = 65536 об'єктів стану може розглядатися як «група». Однак ці ідеї більш складні; Підхід, заснований на STEM, простий, і він узгоджує стимули, оскільки, як правило, всі дані в STEM пов'язані з одним і тим же додатком або користувачем.
Що, якщо ми хочемо уникнути будь-якого постійного зростання стану, навіть 32-байтові підсили? Це складна проблема через@vbuterin/state_size_management#Resurrection-conflicts">resurrection конфлікти: що, якщо об'єкт стану видаляється, пізніше виконання EVM розміщує інший об'єкт стану в точно тій самій позиції, але після цього хтось, кому цікавий початковий об'єкт стану, повертається і намагається його відновити? З частковим строком придатності об'єкта стану «заглушка» запобігає створенню нових даних. З повним строком придатності об'єкта стану нам не вистачає навіть заглушки.
Дизайн, заснований на адресному періоді, є найвідомішою ідеєю для вирішення цієї проблеми. Замість того, щоб мати одне дерево стану, що зберігає весь стан, ми маємо постійно зростаючий список дерев станів, і будь-який стан, який читається або записується, зберігається в останньому дереві станів. Нове порожнє дерево стану додається один раз на період (подумайте: 1 рік). Старі державні дерева вимерзли твердими. Очікується, що повні ноди зберігатимуть лише останні два дерева. Якщо об'єкт стану не чіпався протягом двох періодів і, таким чином, потрапляє в прострочене дерево, його все одно можна прочитати або записати, але транзакція повинна буде довести доказ Меркла для нього - і як тільки це станеться, копія знову буде збережена в останньому дереві.
Ключовою ідеєю для того, щоб зробити все це зручним для користувачів і розробників, є концепція адресних періодів. Період адреси – це число, яке є частиною адреси. Ключове правило полягає в тому, що адреса з періодом адреси N може бути прочитана або записана тільки під час або після періоду N (тобто, коли список дерева станів досягає довжини N). Якщо ви зберігаєте новий об'єкт стану (наприклад, новий контракт або новий баланс ERC20), якщо ви обов'язково помістили об'єкт стану в контракт з періодом адреси N або N-1, ви можете зберегти його негайно, без необхідності надавати докази того, що там нічого не було раніше. З іншого боку, будь-які доповнення або правки, внесені в старі періоди адреси, вимагають доказів.
Цей дизайн зберігає більшість поточних властивостей Ethereum, дуже легкий для додаткового обчислення, дозволяє писати додатки майже так само, як сьогодні (ERC20-и повинні переписати, щоб забезпечити, що баланси адрес з адресним періодом N зберігаються в дочірньому договорі, який сам має адресний період N), і вирішує проблему «користувач йде в печеру на п'ять років». Однак у нього є одна велика проблема: адреси потрібно розширити понад 20 байт, щоб вмістити адресні періоди.
Одна з пропозицій - ввести новий формат адреси з 32 байтами, який включає номер версії, номер періоду адреси та розширений хеш.
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
Червоний це номер версії. Чотири нулі, забарвлені помаранчево, тут призначені як порожній простір, який може вміщати номер частки у майбутньому. Зелений - це номер періоду адреси. Синій - це хеш 26 байтів.
Основним викликом тут є зворотна сумісність. Існуючі контракти розроблені навколо 20-байтових адрес, і часто використовують техніки жорсткого упаковування байтів, які явно передбачають, що адреси складають точно 20 байт.@ipsilonОдин із варіантів вирішення цієї проблеми передбачає карту перекладу, де контракти старого стилю, що взаємодіють з адресами нового стилю, бачили б 20-байтний хеш адреси нового стилю. Однак це пов'язано зі значними складнощами у забезпеченні цього безпечним.
Ще один підхід йде у протилежному напрямку: ми одразу ж забороняємо деякий піддіапазон розміром 2128 адрес (наприклад, всі адреси, що починаються з 0xffffffff), а потім використовуємо цей діапазон для введення адрес з періодами адрес і хешів розміром 14 байт.
0xfffffff000169125d5dFcb7B8C2659029395bdF
Ключова жертва, яку приносить цей підхід, полягає в тому, що він представляє ризики безпеки для контрфактних адрес: адреси, які утримують активи або дозволи, але код яких ще не був опублікований на ланцюжку. Ризик полягає в тому, що хтось створює адресу, яка претендує на наявність одного шматка (ще не опублікованого) коду, але також має інший дійсний шматок коду, який має однаковий хеш з адресою. Обчислення такого зіткнення вимагає 280 хеші сьогодні; Скорочення адресного простору зменшило б це число до дуже доступного 256хеши.
Ключова область ризику, контрфактні адреси, які не є гаманцями, утримуваними одним власником, сьогодні є відносно рідкісним випадком, але ймовірно стане більш поширеним, коли ми увійдемо в світ багаторівневих рішень. Єдиний варіант - просто прийняти цей ризик, але визначити всі типові ситуації, де це може стати проблемою, і знайти ефективні обхідні шляхи.
Я бачу чотири життєздатних шляхи для майбутнього:
Один важливий момент полягає в тому, що складні питання розширення та стиснення адресного простору в кінцевому рахунку мають бути вирішені незалежно від того, чи будуть впроваджені схеми закінчення терміну дії держави, які залежать від змін формату адреси. Сьогодні це займає приблизно 280гешує для генерації колізії адрес, обчислювальне навантаження, яке вже є можливим для надзвичайно ресурсних акторів: відеокарта може виконувати приблизно 227хеші, тому протягом року він може обчислити 252, отже все ~2^30 відеокарт в світіможе обчислити зіткнення за ~1/4 року, а FPGA та ASIC можуть ще більше прискорити цей процес. У майбутньому такі атаки стануть доступними для все більшої кількості людей. Тому фактична вартість впровадження повного закінчення терміну дії стану може бути не такою високою, як здається, оскільки нам все одно потрібно вирішити цю дуже складну проблему адреси.
Виконання терміну дії стану потенційно полегшує переходи від одного формату дерева стану до іншого, оскільки не буде потреби в процедурі переходу: ви можете просто почати створювати нові дерева за новим форматом, а потім зробити хардфорк, щоб перетворити старі дерева. Тому, хоча термін дії стану є складним, він має переваги в спрощенні інших аспектів дорожньої карти.
Однією з ключових передумов безпеки, доступності та достовірна нейтральність це простота. Якщо протокол красивий і простий, це зменшує ймовірність того, що в ньому виникнуть помилки. Це збільшує шанс на те, що нові розробники зможуть прийти і попрацювати з будь-якою його частиною. Швидше за все, це буде справедливо і легше захищатися від особливих інтересів. На жаль, протоколи, як і будь-яка соціальна система, за замовчуванням з часом ускладнюються. Якщо ми не хочемо, щоб Ethereum потрапив у чорну діру постійно зростаючої складності, нам потрібно зробити одну з двох речей: (i) припинити вносити зміни та закостеніти протокол, (ii) мати можливість фактично видаляти функції та зменшувати складність. Також можливий проміжний шлях, який полягає у внесенні меншої кількості змін до протоколу, а також усуненні хоча б невеликої складності з часом. У цьому розділі ми розповімо про те, як ми можемо зменшити або усунути складність.
Немає жодного великого одноразового виправлення, яке може зменшити складність протоколу; вроджена природа проблеми полягає в тому, що є багато малих виправлень.
Один приклад, який вже в основному закінчений і може слугувати зразком для того, як вирішувати інші, є@vbuterin/selfdestruct">видалення коду операції SELFDESTRUCT. Код операції SELFDESTRUCT був єдиним кодом операції, який міг змінювати необмежену кількість слотів зберігання в межах одного блоку, вимагаючи від клієнтів реалізації значно більшої складності, щоб уникнути DoS-атак. Початкова мета операційного коду полягала в тому, щоб уможливити добровільне очищення штату, дозволяючи розміру штату з часом зменшуватися. На практиці мало хто в кінцевому підсумку скористався нею. Об'єкт опкод був зменшений дозволяти лише саморуйнівні облікові записи, створені під час однієї транзакції в хардфорку Dencun. Це вирішує проблему DoS і дозволяє значно спростити код клієнта. У майбутньому, ймовірно, має сенс з часом повністю видалити код операції.
Деякі ключові приклади можливостей спрощення протоколу, які вже були виявлені, включають наступне. По-перше, деякі приклади, які знаходяться поза EVM; вони є відносно неінвазивними і, отже, легше досягти згоди та реалізувати за короткий період часу.
Зараз деякі приклади, які знаходяться всередині EVM:
Основним компромісом при спрощенні такого роду можливостей є (i) наскільки ми спрощуємо та наскільки швидко проти (ii) зворотної сумісності. Вартість Ethereum як ланцюга полягає в тому, що ви можете розгорнути додаток і бути впевненими, що він працюватиме ще багато років. В той же час, можливо підійти до цієї ідеї занадто далеко і, перефразувати Вільяма Дженнінгса Браяна, «розіп'яти Ethereum на хресті зворотної сумісності». Якщо в Ethereum існують лише дві програми, які використовують певну функцію, і одна з них не має жодного користувача протягом років, а інша майже повністю не використовується і захищає загальну суму в $57, то ми просто повинні видалити цю функцію, і якщо потрібно, відшкодувати постраждалим $57 з власного карману.
Більш широкою соціальною проблемою є створення стандартизованого конвеєра для здійснення зворотної сумісності, яка не порушує невідкладних змін. Один з способів підходу до цього полягає в розгляді та розширенні існуючих прецедентів, таких як процес SELFDESTRUCT. Конвеєр виглядає так:
Між кроком 1 та кроком 4 має бути багаторічний конвеєр, з чіткою інформацією про те, які елементи знаходяться на якому кроці. На цьому етапі є компроміс між тим, наскільки енергійним та швидким є процес видалення функцій, порівняно з більш консервативним підходом і вкладанням більше ресурсів у інші галузі розвитку протоколу, але ми все ще далекі від Парето-фронту.
Головний набір змін, який був запропонований для EVM, цеФормат об'єкта EVM (EOF). EOF вводить велику кількість змін, таких як заборона газової спостережуваності, спостережуваність коду (тобто відсутність CODECOPY), що дозволяє лише статичні стрибки. Мета полягає в тому, щоб дозволити EVM більше оновлюватися, таким чином, щоб він мав сильніші властивості, зберігаючи при цьому зворотну сумісність (оскільки EVM до EOF все ще існуватиме).
Це має ту перевагу, що створює природний шлях до додавання нових функцій EVM і заохочення переходу на більш обмежувальний EVM із сильнішими гарантіями. Його недолік полягає в тому, що він значно збільшує складність протоколу, якщо ми не зможемо знайти спосіб зрештою застаріти та видалити старий EVM. Одне з основних питань полягає в наступному: яку роль відіграє EOF у пропозиціях щодо спрощення EVM, особливо якщо метою є зменшення складності EVM в цілому?
Багато з пропозицій «вдосконалення» в іншій частині дорожньої карти також є можливостями для спрощення старих функцій. Щоб повторити деякі приклади зверху:
Більш радикальна стратегія спрощення Ethereum полягає в тому, щоб залишити протокол як є, але перенести велику частину його з рис протоколу на код контракту.
Найекстремальніша версія цього полягає в тому, щоб Ethereum L1 фактично був лише ланцюжком маяка та ввести мінімальну ВМ (наприклад, RISC-V, Каїрабо ще більш мінімальний, спеціалізований для систем доведення) , що дозволяє будь-кому створювати власний rollup. EVM стане першим з цих rollup. Це іронічно виявляється тим самим результатом, що й в Пропозиції щодо середовища виконання на 2019-20 роки, хоча SNARKs роблять його значно більш життєздатним для фактичної реалізації.
Більш помірний підхід полягає в тому, щоб залишити відношення між ланцюжком-маяком та поточним середовищем виконання Ethereum без змін, але зробити заміну EVM на місці. Ми можемо вибрати RISC-V, Cairo або іншу віртуальну машину (VM) в якості нового «офіційного Ethereum VM», а потім примусово конвертувати всі контракти EVM у новий код VM, який інтерпретує логіку початкового коду (шляхом компіляції або інтерпретації). Теоретично, це навіть можна зробити з «цільовою VM», яка є версією EOF.