ERC 4337: абстракция без промени в протокола на Ethereum

ERC20/vitalik.ca

Абстракцията от акаунти отдавна е мечта на общността на разработчиците на Ethereum. Вместо кодът на ELM да се използва само за реализиране на логиката на приложенията, той ще се използва и за реализиране на логиката за проверка (консенсус, подписи… ) на портфейлите на отделните потребители. Това би отговорило вратата за креативност в дизайна на портфейлите, които биха могли да предоставят някои важни функции:

  • Multissg и социално възстановяване
  • По-ефективни и по-прости алгоритми за подписване (напр. Schonrr, BLS)
  • Постквантови алгоритми за безопасен подпис (например Lamport, Winternitz)
  • Възможност за надграждане

Днес е възможно да се правят тези неща с портфейли за интелигентни договори, но фактът, че самият протокол Ethereum изисква всичко да бъде пакетирано в трансакция, произхождаща от защитена с ECDSA външна сметка (EOA), прави това много трудно. Всяка потребителска операция трябва да бъде опакована от трансакция от EOA, което добавя 21000 газ режийни разходи. Потребителят трябва или да има ETH в отделна EOA, за да плаща газ, и да управлява салдата в две сметки, или да разчита на релейна система, които обикновено са централизирани.

EIP 2938 е един от начините за поправяне на този проблем, като въвежда някои промени в протокола на Ethereum, които позволяват трансакциите на най-високо ниво в Ethereum да започват от договор вместо от EOA. Самият договор ще има логика за проверка и плащане на такси, за която миньорите ще проверяват. Това обаче изисква значителни промени в протокола в момент, когато разработчиците на протокола се фокусират силно върху сливането и мащабируемостта. В новото предложение (ERC 4337) предоставя начин за постигане на същите ползи без промени в протокола на консенсусния слой.

Как работи това предложение?

Вместо да променяме логиката на самия консенсусен слой, ние възприемаме функционалността на трансакционния мемпул в системата от по-всико ниво. Потребителите изпращат обекти UserOperation, които пакетират намеренията на потребителя заедно с подписи и други данни за проверка. Миньорите или пакетиращите оператори, използващи услуги като Flashbots, могат да пакетират набор от UserOperation обекти в една “пакетна трансакция”, която след това се включва в блок на Ethereum.

0 IThEWr1KugkIQHrf

Пакетиращият плаща таксата за пакетната трансакция в ETH и получава компенсация чрез таксите, платени като част то всички индивидуални изплащания на UserOperation. Пакетиращите лица ще избират кои OpenOpertaion обекти да включват въз основа на логика за приоритизиране на таксите, подобно на тази, по която работят миньорите в съществуващия мемпул на трансакциите. UserOperation прилича на трансакция; това е кодирана в ABI структура, която включва полета като:

  • sender: портфейлът, който извършва операцията
  • nonce и signature: параметри, които се предават на функцията за проверка на портфейла, за да може портфейлът да провери дадена операция.
  • initCode: кодът за създаване на портфейла, ако портфейлът все още не съществува.
  • callData: с какви данни да се извика портфейлът за действителната стъпка на изпълнение.

Останалите полета са свързани с управлението на газа и таксите; пълен списък на полетата може да бъде намерен в спецификацията на ERC 4337.

Портфейлът е интелигентен договор и трябва да има две функции:

validateUserOp, който приема UserOperation като вход. Тази функция трябва да провери signature и nonce на UserOperation, да плати таксата и да увеличи nonce, ако проверката е успешна, и да хвърли изключение, ако проверката е неуспешна.

Функция за изпълнение на операции, която интерпретира calldata като инструкция за действие на портфейла. Начинът, по който тази функция интерпретира calldata и какво прави в резултат на това, е напълно отворен; но очакваме, че най-често срещаното поведение ще бъде да анализира calldata като инструкция за портфейла да извърши едно или повече повиквания.

За да се опрости логиката на портфейла, голяма част от сложните трикове на интелигентните договори, необходими за осигуряване на безопасността, се извършват не в самия портфейл, а в глобален договор, неречен входна точка. Очаква се функцията validateeUserOp и изпълнение да бъдат защитени с require (msg.sender== ENTRY_POINT), така че само доверената входна точка може да накара портфейла да извърши някакви действия или да плати такси. Входната точка прави произволно повикване към портфейла само след като validateUserOp с UserOperation, носеща тази calldate, вече е успяла, така че това е достатъчно, за да защити портфейлите от атаки. Входната точка също така отговаря за създаването на портфейл, като използва предоставения initCode, ако портфейлът вече не съществува.

0 iZUtwChqWHYclWd

Съществуват някои ограничения, които възлите на mempool и пакетите трябва да наложат по отношение на това, което validateUserOp може да прави: по-специално изпълнението на validateUserOp не може да чете или записва хранилище на други договори, не може да използва кодове на средата, като TIMESTAMP, и не може да извиква други договори, освен ако тези договори не са доказано неспособни да се самоунищожат. Това е необходимо, за да се гарантира, че симулирането изпълнение на validateUserOp, използвано от пакетите и възлите на UserOperation menpool, за да се провери дали дадена UserOperation е подходяща за включване или препращане, ще има същия ефект, ако тя действително бъде включена в бъдещ блок.

Ако проверката на UserOperation е била симурана успешно, UserOperation гарантирано ще може да бъде включена във вътрешното си състояние (поради друга UserOperation със същия изпращач или друг договор, който се обажда на изпращача; и в двата случая задействането на това условие за една сметка изисква изразходването на над 7500 газ във веригата). Освен това операцията UserOperation задава лимит на газа за стъпката validateUserOp, а възлите на mempool и пакетиращите устройства ще я отхвърлят, освен ако този лимит на газа не е много малък (например под 200000). Тези ограничения възпроизвеждат ключовите свойства на съществуващите трансакции в Ethereum, които предпазват mempool от DoS атаки. Пакетиращите устройства и възлите на mempool могат да използват логика, подобна на днешната логика за обработка на трансакции в Ethereum, за да определят дали да включват или препратят UserOperation.

Какви свойства добавя, поддържа и жертва този дизайн в сравнение с обикновения мемпул за трансакции на Ethereum?

Поддържани имоти:

  • Няма централизирани актьори: всичко се извършва чрез peer-to-peer mempool
  • Безопасност на DoS (гарантирано е, че UserOperation, която преминава проверките за симулация, може да бъде включена, докато изпращачът не промени състоянието си, което би изисквало от нападателя да плати 7500+ газ на изпращач)
  • Няма сложни настройки на портфейла от страна на потребителя: потребителите не трябва да се интересуват от това дали договорът им за потрфейл е “вече публикуван”, протфейлите съществуват на детерминистични адреси CREATE2, а ако портфейлът все още не съществува, първата UserOperation го създава автоматично.
  • Пълна поддръжка на EIP 1559, включително опростено определяне на таксите (потребителите могат да определят фиксирана премия и висока максимална обща такса и да очакват бързо включване и справедливо таксуване)
  • Възможност за замяна чрез такса, като се изпраща нова UserOperation със значително по-висока премия от старата, за да се замени операцията или да се включи по-бързо.

Нови предимства:

  • Гъвкавост на логиката за проверка: функцията validateUserOp може да добавя произволна логика за проверка на signature и nonce ( нови схеми за подписване, многозначност…)
  • Достатъчно за квантовата сигурност на слоя за изпълнение: ако това предложение бъде прието повсеместно, не е необходимо да се извършва допълнителна работа по слоя за изпълнение за квантова сигурност. Потребителите могат индивидуално да наградят портфейлите си до квантово сигурни. Дори обвиващата трансакция е безопасна, тъй като миньорът може да използва нова, прясно създадена и следователно защитена с хеш EOA за всяка трансакция на пакета и да не публикува трансакцията, преди тя да бъде добавена в блока.
  • Възможност за надграждане на портфейла: логиката за проверка на портфейла може да бъде в зависимост от състоянието, така че портфейлите могат да променят своите публични ключове или (ако са публикувани с DELEGATECALL) да надградят изцяло своя код.
  • Гъвкавост на логиката на изпълнение: портфейлите могат да добавят персонализирана логика за стъпката на изпълнение, например извършване на атомични мултиоперации (ключова цел на EIP 3074).

Слабости:

  • Леко увеличена уязвимост на DoS въпреки всички усилия на протокола, просто защото е позволено логиката на проверката да бъде малко по-сложна от статуквото на единична проверка на ECDSA.
  • Наднормени разходи за таз: малко повече наднормени разходи за газ в сравнение с обикновените трансакции (макар че в някои случаи на употреба те се компенсират от поддръжката на множество операции).
  • Една трансакция в даден момент: сметките не могат да се редят на опашка и да изпращат множество трансакции в мемпула. Възможността за извършване на атомарни мултиоперации обаче прави тази функция много по-малко необходима.

Спонсорство с paymasters

Спонсорираните трансакции имат няколко основни случая на използване. Най-често цитираните желани случаи на употреба са:

  1. Разрешаване на разработчиците на приложения да плащат такси от името на своите потребители
  2. Позволява на потребителите да плащат в токени ERC20, като договор служи като посредник за събиране на ERC20 и плащане в ETH.

Настоящото предложение може да поддържа тази функционалност чрез вграден механизъм за платежни средства. UserOperation може да зададе друг адрес като свой платец. Ако платецът е зададен (т.е. не е нула), по време на етапа на проверка входната точка също се обръща към платеца, за да провери дали платецът е готов да плати за UserOperation. Ако това е така, таксите се изтеглят от ETH на платеца, заложен в точката за въвеждане (със забавяне на изтеглянето за сигурност), вместо от портфейла. По време на стъпката на изпълнение протфейлът се извиква с calldata в UserOperation, както обикновено, но след това платецът се извиква с postOp.

Примерни работни потоци за горните два случая на употреба са:

  • Платецът проверява дали paymasterData съдържа подпис от споносра, който удостоверява, че спонсорът е готов да плати за UserOperatiion. Ако подписът е валиден, платецът приема и таксите за UserOperation се изплащат от залога на спонсора.
  • Платецът проверява дали портфейлът на изпращача разполага с достатъчност ERC20 баланс, за да плати за UserOperaton. Ако това е така, платецът приема и заплаща таксите ETH, след което изисква ERC20 токените като компенсация в postOp (ако postOp се провали, защото UserOperation e изчерпала баланса на ERC20, изпълнението ще се върне и postOp ще се извика отново, така че платецът винаги ще получи плащане). Имайте предвид, че засега това може да се направи само ако ERC20 е обвиващ токен, управляван от самия платец.

Обърнете специално внимание, че във втория случай администраторът на плащания може да бъде изцяло пасивен, може би е изключение на периодично ребалансиране и повторно задаване на параметрите. Това е драстично подобрение в сравнение със съществуващите опити за спонсориране, които изискваха платежният оператор да бъде винаги онлайн, за да може активно да опакова отделните трансакции.

Докъде е стигнало това предложение?

ERC20 4337 можете да намерите тук. Тук се извършва изпълнение. Очаква се скоро да се появи алфа-версия за ранни разработчици, след което следващата стъпка ще бъде уточнявана на окончателните детайли и провеждане на одити за потвърждаване на безопасност на схемата.

Разработчиците трябва да могат скоро да започнат да експериментират с портфейли, абстрахирани от акаунти.