Ця стаття головним чином представляє розробку та відповідний вміст абстрактних облікових записів (AA, абстрактні облікові записи) у рішенні рівня 2 zkSync. Основна увага буде зосереджена на трьох частинах:
Договір облікового запису: тип облікового запису, важлива точка входу та відповідні ключові пункти договору облікового запису
Транзакція: метод перевірки, метод виконання та процес транзакції AA
Комісія за обробку: комісія за транзакцію, Paymaster
Зміст
передмова
Короткий огляд контракту zkSync AA
Платна модель і Paymaster в епоху zkSync
Підсумок і порівняння
Висновок
фон
Знайомство зі смарт-контрактним гаманцем і його загальними функціями
Отримайте огляд того, як працюють транзакції Ethereum
Загальне розуміння режиму роботи EIP-4337
Загальне розуміння режиму роботи ZK (валідності) Rollup
Швидкий огляд zkSync
Тут, для зручності читання, немає необхідності глибоко розбиратися в zkSync, а коротко розглянемо основну інформацію про zkSync. Існує дві основні версії zkSync: версія 1.0 (zkSync Lite) і версія 2.0 (zkSync Era).
zkSync версії 1.0 підтримує лише EOA (зовнішній обліковий запис) і не підтримує смарт-контракти (підтримує лише передачу та обмін токенів), тоді як zkSync 2.0, а саме zkSync Era, належить до рідного AA (абстрактного облікового запису) (усі типи облікових записів є контрактами, без EOA) , що є різницею між EOA та контрактним обліковим записом в Ethereum), сумісний з EVM (Ethereum Virtual Machine) і підтримує розробку смарт-контрактів за допомогою Rust, Yul, Vyper, Solidity тощо.
ZkSync, згаданий нижче, стосується zkSync 2.0, а саме zkSync Era, якщо не вказано інше.
В zkSync Era є кілька контрактів, які можна зрозуміти, оскільки вони реалізують деякі важливі функції операційної системи zkSync у смарт-контрактах. Ці контракти є попередньо скомпільованими контрактами, які ніколи не розгорталися (запускаються безпосередньо у вузлі), але всі вони мають офіційну адресу.
Під час реалізації протоколу AA zkSync виконуватиме логічні операції та судження через деякі контракти. Наприклад, під час перевірки nonce це оцінюється NonceHolder, тоді як реалізація механізму абстрактного облікового запису та збору комісії оцінюється завантажувачем. Нижче буде представлено їх один за одним.
Резюме облікового запису
Основну концепцію абстракції облікового запису можна звести до двох ключових моментів: абстракція підпису та абстракція платежу.
Мета абстракції підпису — дозволити різним контрактам облікових записів використовувати різні схеми перевірки. Це означає, що користувачі не обмежені алгоритмом цифрового підпису, який може використовувати лише певну криву, а можуть вибрати будь-який механізм перевірки, який їм подобається.
Абстракція платежів має на меті надати користувачам різноманітні варіанти оплати транзакцій. Наприклад, платежі можуть здійснюватися за допомогою токенів ERC-20 замість власних токенів, або трансакції можуть спонсоруватися третьою стороною, або навіть інші більш спеціальні моделі оплати.
Облікові записи в zkSync 2.0 можуть ініціювати транзакції, як EOA, але також можуть використовувати його можливість програмування для реалізації довільної логіки, наприклад облікові записи контрактів. Це те, що ми називаємо абстракцією облікового запису, яка поєднує в собі переваги двох типів облікових записів в Ethereum, щоб зробити досвід використання облікових записів AA більш гнучким, таким чином досягаючи двох вищезазначених цілей: абстракції підпису та абстракції платежу.
Механізм AA в епоху zkSync
В zkSync Era найважливішою роллю zkSync AA є завантажувач, який є контрактом, який в основному використовується для обробки транзакцій і виконання механізму AA, що відповідає контракту EntryPoint EIP-4337. Завантажувач не може бути викликаний користувачем (його може запустити лише Оператор), і він ніколи не розгортався (запускається безпосередньо на вузлі), але має офіційну адресу (може використовуватися для отримання платежів).
Оператор відіграє важливу роль у ZK Rollup. Це централізований сервер поза ланцюгом. Подібно до Sequencer, який ви, можливо, бачили, він відповідає за ініціювання контрактів, таких як завантажувач іззовні.
Власні протоколи абстрагування облікових записів (такі як StarkNet, zkSync) в основному розроблені з посиланням на EIP-4337. У реалізації zkSync користувач надсилає транзакцію оператору, а оператор надсилає транзакцію завантажувачу та запускає ряд обробки.
З точки зору блоку:
Коли завантажувач отримує вхідні дані від оператора, завантажувач спочатку визначає деякі змінні середовища для блоку (такі як ціна на газ, номер блоку, мітка часу блоку тощо). Потім завантажувач послідовно прочитає список транзакцій, спочатку запитає, чи договір облікового запису узгоджується з транзакцією (тобто викличе функцію перевірки в механізмі AA), а потім помістить їх у блок.
Після перевірки кожної транзакції Оператор перевіряє, чи достатньо великий блок, щоб його було надіслано верифікатору (чи минув час очікування). Якщо він достатньо великий або минув час очікування, Оператор закриває блок, припиняє додавати нові транзакції до завантажувача та завершує виконання транзакції.
З точки зору транзакцій, коли Оператор запускає завантажувач, завантажувач оброблятиме кожну транзакцію послідовно:
Переконайтеся, що nonce, що відповідає контрактній адресі облікового запису користувача, є законним
Викличте функцію перевірки в контракті облікового запису користувача для перевірки
Після проходження верифікації договір рахунку перерахує плату за газ на адресу завантажувача (або через Paymaster, який буде введено пізніше), а завантажувач перевірить, чи достатньо він отримав грошей.
Викличте функцію ute в контракті облікового запису користувача, щоб виконати транзакцію.
Перші три кроки вище відповідають циклу перевірки (Verification Loop) EIP-4337, а четвертий крок відповідає циклу виконання (ution Loop) EIP-4337.
Тут наведено в основному оглядовий вступ, а деталі та ролі кожного кроку будуть детально описані один за одним у наступному детальному описі.
Швидкий огляд договору абстрактного облікового запису zkSync
Один раз
Обліковий запис nonce для zkSync записується в системному контракті під назвою NonceHolder, який запам’ятовує, чи використовується кожна пара (account_address, nonce) шляхом зіставлення (відображення), щоб визначити, чи є nonce законним.
Відповідно до вищезазначеного, першим кроком після запуску завантажувача оператором є перевірка nonce. Таким чином, перед початком кожної транзакції NonceHolder використовуватиметься для підтвердження того, чи набір nonces, який зараз використовується, є законним (наразі лише перевіряє, чи вони були використані). Якщо nonce є законним, він увійде у фазу перевірки (Verification Phase), під час якої nonce буде позначено як використаний; якщо він не є законним, транзакція (перевірка) не вдасться.
Важливі моменти щодо поточного nonce zkSync:
Хоча наразі користувачі можуть надсилати кілька транзакцій з різними одноразовими номерами в обліковий запис для виконання одночасно, оскільки zkSync не підтримує паралельну обробку, транзакції з різними одноразовими номерами все одно оброблятимуться послідовно.
Теоретично користувачі можуть використовувати будь-яке 256-розрядне ненульове ціле число як nonce, але zkSync все одно рекомендує використовувати incrementNonceIfEquals як спосіб керування nonce, щоб гарантувати, що він збільшується в порядку (наразі механізм AA zkSync лише підтверджує невикористані nonce, але офіційно документ вказує на те, що послідовне збільшення може знадобитися в майбутньому).
Договір про обліковий запис
Договір облікового запису в zkSync має наступні чотири необхідні точки входу (точка входу), а саме:
validateTransaction: викликається під час етапу перевірки, щоб підтвердити, чи дозволено операцію власником облікового запису, де користувачі можуть налаштувати власну логіку перевірки (наприклад, різні алгоритми підпису, мультипідпис тощо).
payForTransaction: коли комісія за транзакцію сплачується цим обліковим записом (замість використання paymaster), оператор викличе цю функцію, щоб сплатити принаймні tx.gasprice * tx.gaslimit ETH на адресу завантажувача.
Підготовка до Paymaster: коли Paymaster сплачуватиме комісію за транзакцію, оператор викличе цю функцію, щоб завершити підготовчу роботу перед взаємодією з Paymaster. Приклад, наданий zkSync, — це токен ERC-20, схвалений Paymaster.
uteTransaction: після успішного проходження етапу перевірки та успішного стягнення комісії за транзакцію ця функція використовуватиметься для виконання операції, яку хоче виконати користувач (наприклад, взаємодія з контрактом, переказ тощо).
Про Paymaster, розмір комісії за обробку (tx.gasprice * tx.gaslimit) тощо буде пояснено в наступних розділах.
В обліковому записі zkSync також є необов’язкова функція страхування uteTransactionFromOutside. Кошти можна вивести на L1 за допомогою «механізму виходу», якщо операції не можуть бути виконані (наприклад, коли генератор послідовностей не відповідає або zkSync вважається регуляторним ризиком). Ця частина має мало спільного з протоколом AA, тому детально описувати її тут не буде, кому цікаво, можете ознайомитися з офіційними документами та специфікацією zkSync.
Ключові моменти та обмеження функцій перевірки
У функції validateTransaction можна реалізовувати різні спеціальні логіки. Наприклад, якщо в обліковому записі реалізовано стандарт EIP-1271, логіку перевірки в EIP-1271 можна застосувати безпосередньо до validateTransaction або звернутися до контракту облікового запису з кількома підписами реалізація в офіційному документі zkSync.
У той же час, щоб уникнути загроз DoS на етапі перевірки EIP-4337, існують деякі обмеження (не можна використовувати зовнішні коди операції та обмежена глибина тощо), а також є подібні обмеження в zkSync, наприклад:
1. Логіка контракту може торкатися лише свого власного слота (якщо адреса контракту облікового запису A):
слот, що належить до адреси А
слот А за будь-якою іншою адресою
Слот keccak256(A||X) будь-якої іншої адреси, яка може безпосередньо використовувати адресу як ключ відображення (наприклад, відображення (адреса=>значення)), також еквівалентно дозволу доступу до слота keccak256( A||X), щоб досягти розширення. Наприклад, баланс токенів на ERC-20.
2. Логіка контракту не повинна використовувати глобальні змінні, такі як block.number
Ключові моменти та обмеження виконання функцій
У функції uteTransaction слід звернути увагу на те, що якщо ви хочете виконати системний виклик (Call), вам потрібно переконатися, що він має прапор is. Оскільки ці системні контракти мають великий вплив на систему облікових записів. Наприклад, єдиний спосіб збільшити nonce – це взаємодіяти з NonceHolder. Щоб розгорнути контракт, ви повинні взаємодіяти з ContractDeployer. Використання прапорця is може гарантувати, що розробники облікових записів свідомо взаємодіють з системними контрактами.
Однак рекомендується використовувати бібліотеку ContractsCaller, надану zkSync, щоб уникнути самостійної обробки прапора is, і використовувати CallWithPropagatedRevert для завершення системного виклику.
Зразок коду вище передбачає взаємодію з DEPLOYER__CONTRACT. Найпоширенішою ситуацією системного контракту, з якою стикаються розробники облікових записів, є те, що ми хочемо використовувати обліковий запис для розгортання контракту. У цей час ми повинні взаємодіяти з системним контрактом ContractDeployer. У цьому випадку розробник облікового запису має зв’язатися з контрактом ContractDeployer, щоб переконатися, що контракт успішно розгорнуто та виконує необхідні операції.
Комісійна модель і Paymaster в епоху zkSync
Збори та ліміт газу
Комісійна модель zkSync дуже схожа на Ethereum, платіжним токеном залишається ETH. Однак, як і інші рішення рівня 2 (такі як Arbitrum, Optimism), zkSync також потребує врахування додаткових витрат на публікацію в L1 (комісія за безпеку) на додаток до основних витрат на обчислення та запис. Оскільки ціна на газ, який публікує дані в L1, дуже нестабільна, Оператор zkSync визначає такі динамічні параметри, коли кожен блок відкривається (починає записувати транзакції):
gasPrice: ціна газу в gwei, тобто tx.gasprice у згаданому вище об’єкті транзакції
gasPerPubdata: кількість газу, необхідна для публікації байта даних в Ethereum.
Крім того, на відміну від EIP-4337, zkSync не потрібно визначати три ліміти газу: verificationGas, utionGas і preVerificationGas, але вимагає лише gasLimit для покриття всіх вищезазначених витрат, тому користувачі повинні переконатися, що gasLimit достатньо для покриття Етап перевірки, етап оновлення та завантаження даних Усі витрати, такі як плата за безпеку, на L1. Ця комісія включена в tx.gaslimit у згаданому вище об’єкті транзакції.
Помножте два (tx.gasprice * tx.gaslimit), щоб отримати комісію за транзакцію, сплачену завантажувачу.
Оплата праці
Paymaster переважно сплачує ETH завантажувачу замість контракту облікового запису користувача на етапі комісії за транзакцію користувача. Користувачі можуть вибрати різні платіжні системи та способи оплати, щоб сплатити комісію за обробку, наприклад (але не обмежуючись цим):
Оплата токенів ERC-20 Paymaster до початку транзакції або після її виконання
Поповнити контракт Paymaster кредитною карткою
Paymaster продовжуватиме сплачувати частину або всі збори для користувачів безкоштовно
Спосіб взаємодії користувачів із Paymaster залежить від різних протоколів, він може бути централізованим або децентралізованим; він може бути до або після транзакції; він може використовувати токени ERC-20 або законний платіжний засіб або навіть безкоштовний.
Контракт Paymaster для zkSync в основному складається з двох функцій, а саме validateAndPayForPaymasterTransaction (обов’язково) і postTransaction (необов’язково), обидві з яких може викликати лише завантажувач:
validateAndPayForPaymasterTransaction — це єдина функція, яка має бути реалізована в усьому контракті Paymaster. Коли оператор отримує транзакцію з параметром Paymaster, це означає, що комісія за обробку оплачується не договором облікового запису користувача, а Paymaster. У цей момент оператор викличе validateAndPayForPaymasterTransaction, щоб визначити, чи готовий Paymaster сплатити комісію за транзакцію. Якщо Paymaster погодиться, ця функція надішле принаймні tx.gasprice * tx.gaslimit ETH до завантажувача.
postTransaction є додатковою функцією, яка зазвичай використовується для відшкодування (повернення невикористаного газу відправнику). Однак поточний zkSync ще не підтримує цю операцію.
Paymaster у zkSync виконає postTransaction після впровадження postTransaction, що відрізняється від EIP-4337. EIP-4337 не викличе postOp, якщо validatePaymasterUserOp не повертає контекст, і навпаки.
Виходячи з вищезазначеного, наприклад, користувач тепер хоче надіслати транзакцію, комісія за обробку якої оплачується Paymaster, процес виглядає наступним чином:
Використовуйте NonceHolder, щоб підтвердити, чи є nonce законним
Викличте validateTransaction у договорі облікового запису користувача, щоб перевірити, чи транзакція авторизована власником облікового запису
Зателефонуйте службі pripravForPaymaster для Контракту облікового запису користувача, який може виконати, наприклад, затвердити певну кількість токенів ERC-20 Paymaster або нічого не робити
Викличте validateAndPayForPaymasterTransaction у контракті Paymaster, щоб підтвердити, що Paymaster готовий сплатити та стягнути комісію за обробку, і в той же час Paymaster стягне з користувача певну суму ERC-20 (затверджено раніше)
Переконайтеся, що завантажувач отримує правильну суму (принаймні tx.gasprice * tx.gaslimit) комісій ETH
Викличте uteTransaction у договорі облікового запису користувача, щоб виконати транзакцію, яку бажає користувач
Якщо контракт Paymaster реалізує postTransaction і газу все ще достатньо (немає помилки out of gas), тоді виконайте postTransaction
На останньому кроці, навіть якщо postTransaction неможливо виконати через помилку браку газу, ця транзакція AA вважається успішною, але дія виклику postTransaction пропускається.
Якщо ви глибше заглибитесь у Paymaster zkSync, то побачите, що його Правила перевірки дещо відрізняються від 4337 (zkSync Paymaster може наступати на будь-який інший контрактний слот), а також існують різні типи (наприклад, на основі схвалення). до порівняння деталей.Кого цікавить може звернутися до офіційних документів або моєї попередньої реалізації.
Підсумок і порівняння
Завдяки попереднім поясненням ми дізналися, які важливі точки входу має договір облікового запису, а також їхні функції та відповідні обмеження. Одночасно ми також дізналися про функції системного контракту. Далі, давайте підсумуємо процес транзакції автоматизованих операцій (AA) у zkSync від будівництва до завершення, і я також надам більш докладні посилання для тих, хто хоче дізнатися більше:
Користувач використовує SDK або гаманець локально для створення об’єктів транзакції (наприклад: від, до, дані, значення тощо).
Користувач підписує транзакцію. Підписом тут не обов’язково є традиційний формат EIP-712 і підпис кривої ECDSA. zkSync також підтримує EIP-2718 і EIP-1559. Ключем до вибору методу підпису та методу перевірки є перевірка за допомогою функції перевірки в договорі облікового запису.
Надішліть підписану транзакцію оператору через RPC API. У цей момент транзакція переходить у стан очікування. Оператор передає транзакцію завантажувачу (викликає функцію processL2Tx у контракті завантажувача) і запускає серію процесів протоколу AA.
Завантажувач перевірить, чи Nonce є законним, і використає NonceHolder для перевірки.
Завантажувач викличе функцію validateTransaction у контракті облікового запису користувача, щоб підтвердити, що транзакцію авторизовано власником облікового запису.
Bootloader може стягувати комісію двома способами, і конкретний спосіб стягнення плати залежить від параметрів транзакції (чи додається параметр paymaster під час створення об’єкта транзакції):
a. Виклик функції payForTransaction і договір рахунку, щоб стягнути комісію за транзакцію;
b. Викличте функції pripravForPaymaster і validateAndPayForPaymasterTransaction, щоб стягнути комісію за транзакцію за контрактом Paymaster.
«Зателефонуйте payForTransaction, щоб укласти комісію з обліковим записом» або «зателефонуйте, щоб підготуватиPaymaster і validateAndPayForPaymasterTransaction, щоб укласти комісію з Paymaster»
Перевірте, чи отримав завантажувач принаймні комісію за транзакцію tx.gasprice * tx.gaslimit.
Завантажувач викличе функцію uteTransaction у контракті облікового запису користувача, щоб виконати транзакцію.
(Необов’язково) Якщо для оплати комісії за транзакцію використовується Paymaster, завантажувач викличе функцію postTransaction. Якщо Paymaster не реалізує postTransaction або газ вичерпано, цей крок буде пропущено.
Наведені вище 4.~7. кроки — це фаза перевірки (визначена в l2TxValidation завантажувача) і фаза виконання 8.~9. кроків (визначена в l2Txution завантажувача).
Порівняння EIP-4337, StarkNet і zkSync Era
В основному процеси механізму АА у трьох подібні, усі вони включають стадію перевірки→механізм комісії за обробку (оплачується за договором рахунку або Paymaster)→етап виконання.Основні відмінності:
Роль реалізації механізму AA така: різниця між відкриттям в епоху zkSync і двома іншими AA полягає в тому, що Оператор повинен співпрацювати із завантажувачем (системний контракт), наприклад, завантажувач відкриє новий блок і визначить відповідні параметри блоку та отримати операцію Трейдер, надіслану учасником і перевірену. У 4337 ця частина координується Bundler і EntryPoint, тоді як у StarkNet ця частина повністю відповідає за Sequencer.
Чи потрібно Gas Cost враховувати комісію за безпеку L1: L2 AA потрібно враховувати вартість завантаження даних на L1, а не лише ZK (Validity) Rollups Native AA, згадане в push, але також має бути включено в L1, коли Optimistic У зведених пакетах реалізовано комісію за безпеку 4337 (розраховується в preVerificationGas, подробиці див. у документах, пов’язаних з Alchemy).
Чи можливо надсилати транзакції до розгортання контракту облікового запису: в епоху StarkNet і zkSync не існує EntryPoint, як 4337, який має поле initCode, щоб дозволити користувачеві розгортати контракт облікового запису, тому він не надсилає транзакції перш ніж можна буде налаштувати обліковий запис.
Порівняно
Оскільки StarkNet ще не реалізував механізм Paymaster, а zkSync ще не завершив розробку механізму відшкодування газу, деякі більш детальні порівняння тут не наведено.
Крім того, ми завершили створення P2P mempool для поточного об’єднувача 4337, а Sequencer і Operator zkRollups також є єдиними офіційними серверами, тому є певні централізовані компоненти.
У процесі розробки, оскільки zkSync не має проблеми підключення до різних групувальників (потрібно лише взаємодіяти з Operator API), він простий у використанні 4337, і досвід розробки контрактів облікових записів (SDK) також кращий; на водночас zkSync може використовувати Solidity як контрактну мову розробки, тому немає потреби перетинати поріг Cairo у розробці StarkNet.
Висновок
Оскільки і StarkNet, і zkSync належать до категорії локальних AA (Native AA), ви також можете звернутися до мого попереднього вступу до StarkNet AA під назвою «Вступ до абстракції облікового запису StarkNet» (Вступ до абстракції облікового запису StarkNet). Крім того, ви можете прочитати інші статті, пов’язані з EIP-4337, щоб отримати додаткові відомості.
Переглянути оригінал
Ця сторінка може містити контент третіх осіб, який надається виключно в інформаційних цілях (не в якості запевнень/гарантій) і не повинен розглядатися як схвалення його поглядів компанією Gate, а також як фінансова або професійна консультація. Див. Застереження для отримання детальної інформації.
Вступ до нативної абстракції облікового запису в zkSync
Автор: Автор ChiHaoLu, imToken Labs
Ця стаття головним чином представляє розробку та відповідний вміст абстрактних облікових записів (AA, абстрактні облікові записи) у рішенні рівня 2 zkSync. Основна увага буде зосереджена на трьох частинах:
Зміст
фон
Тут, для зручності читання, немає необхідності глибоко розбиратися в zkSync, а коротко розглянемо основну інформацію про zkSync. Існує дві основні версії zkSync: версія 1.0 (zkSync Lite) і версія 2.0 (zkSync Era).
zkSync версії 1.0 підтримує лише EOA (зовнішній обліковий запис) і не підтримує смарт-контракти (підтримує лише передачу та обмін токенів), тоді як zkSync 2.0, а саме zkSync Era, належить до рідного AA (абстрактного облікового запису) (усі типи облікових записів є контрактами, без EOA) , що є різницею між EOA та контрактним обліковим записом в Ethereum), сумісний з EVM (Ethereum Virtual Machine) і підтримує розробку смарт-контрактів за допомогою Rust, Yul, Vyper, Solidity тощо.
ZkSync, згаданий нижче, стосується zkSync 2.0, а саме zkSync Era, якщо не вказано інше.
В zkSync Era є кілька контрактів, які можна зрозуміти, оскільки вони реалізують деякі важливі функції операційної системи zkSync у смарт-контрактах. Ці контракти є попередньо скомпільованими контрактами, які ніколи не розгорталися (запускаються безпосередньо у вузлі), але всі вони мають офіційну адресу.
Під час реалізації протоколу AA zkSync виконуватиме логічні операції та судження через деякі контракти. Наприклад, під час перевірки nonce це оцінюється NonceHolder, тоді як реалізація механізму абстрактного облікового запису та збору комісії оцінюється завантажувачем. Нижче буде представлено їх один за одним.
Резюме облікового запису
Основну концепцію абстракції облікового запису можна звести до двох ключових моментів: абстракція підпису та абстракція платежу.
Мета абстракції підпису — дозволити різним контрактам облікових записів використовувати різні схеми перевірки. Це означає, що користувачі не обмежені алгоритмом цифрового підпису, який може використовувати лише певну криву, а можуть вибрати будь-який механізм перевірки, який їм подобається.
Абстракція платежів має на меті надати користувачам різноманітні варіанти оплати транзакцій. Наприклад, платежі можуть здійснюватися за допомогою токенів ERC-20 замість власних токенів, або трансакції можуть спонсоруватися третьою стороною, або навіть інші більш спеціальні моделі оплати.
Облікові записи в zkSync 2.0 можуть ініціювати транзакції, як EOA, але також можуть використовувати його можливість програмування для реалізації довільної логіки, наприклад облікові записи контрактів. Це те, що ми називаємо абстракцією облікового запису, яка поєднує в собі переваги двох типів облікових записів в Ethereum, щоб зробити досвід використання облікових записів AA більш гнучким, таким чином досягаючи двох вищезазначених цілей: абстракції підпису та абстракції платежу.
Механізм AA в епоху zkSync
В zkSync Era найважливішою роллю zkSync AA є завантажувач, який є контрактом, який в основному використовується для обробки транзакцій і виконання механізму AA, що відповідає контракту EntryPoint EIP-4337. Завантажувач не може бути викликаний користувачем (його може запустити лише Оператор), і він ніколи не розгортався (запускається безпосередньо на вузлі), але має офіційну адресу (може використовуватися для отримання платежів).
Оператор відіграє важливу роль у ZK Rollup. Це централізований сервер поза ланцюгом. Подібно до Sequencer, який ви, можливо, бачили, він відповідає за ініціювання контрактів, таких як завантажувач іззовні.
Власні протоколи абстрагування облікових записів (такі як StarkNet, zkSync) в основному розроблені з посиланням на EIP-4337. У реалізації zkSync користувач надсилає транзакцію оператору, а оператор надсилає транзакцію завантажувачу та запускає ряд обробки.
З точки зору блоку:
Коли завантажувач отримує вхідні дані від оператора, завантажувач спочатку визначає деякі змінні середовища для блоку (такі як ціна на газ, номер блоку, мітка часу блоку тощо). Потім завантажувач послідовно прочитає список транзакцій, спочатку запитає, чи договір облікового запису узгоджується з транзакцією (тобто викличе функцію перевірки в механізмі AA), а потім помістить їх у блок.
Після перевірки кожної транзакції Оператор перевіряє, чи достатньо великий блок, щоб його було надіслано верифікатору (чи минув час очікування). Якщо він достатньо великий або минув час очікування, Оператор закриває блок, припиняє додавати нові транзакції до завантажувача та завершує виконання транзакції.
З точки зору транзакцій, коли Оператор запускає завантажувач, завантажувач оброблятиме кожну транзакцію послідовно:
Перші три кроки вище відповідають циклу перевірки (Verification Loop) EIP-4337, а четвертий крок відповідає циклу виконання (ution Loop) EIP-4337.
Тут наведено в основному оглядовий вступ, а деталі та ролі кожного кроку будуть детально описані один за одним у наступному детальному описі.
Швидкий огляд договору абстрактного облікового запису zkSync
Один раз
Обліковий запис nonce для zkSync записується в системному контракті під назвою NonceHolder, який запам’ятовує, чи використовується кожна пара (account_address, nonce) шляхом зіставлення (відображення), щоб визначити, чи є nonce законним.
Відповідно до вищезазначеного, першим кроком після запуску завантажувача оператором є перевірка nonce. Таким чином, перед початком кожної транзакції NonceHolder використовуватиметься для підтвердження того, чи набір nonces, який зараз використовується, є законним (наразі лише перевіряє, чи вони були використані). Якщо nonce є законним, він увійде у фазу перевірки (Verification Phase), під час якої nonce буде позначено як використаний; якщо він не є законним, транзакція (перевірка) не вдасться.
Важливі моменти щодо поточного nonce zkSync:
Хоча наразі користувачі можуть надсилати кілька транзакцій з різними одноразовими номерами в обліковий запис для виконання одночасно, оскільки zkSync не підтримує паралельну обробку, транзакції з різними одноразовими номерами все одно оброблятимуться послідовно.
Теоретично користувачі можуть використовувати будь-яке 256-розрядне ненульове ціле число як nonce, але zkSync все одно рекомендує використовувати incrementNonceIfEquals як спосіб керування nonce, щоб гарантувати, що він збільшується в порядку (наразі механізм AA zkSync лише підтверджує невикористані nonce, але офіційно документ вказує на те, що послідовне збільшення може знадобитися в майбутньому).
Договір про обліковий запис
Договір облікового запису в zkSync має наступні чотири необхідні точки входу (точка входу), а саме:
Про Paymaster, розмір комісії за обробку (tx.gasprice * tx.gaslimit) тощо буде пояснено в наступних розділах.
В обліковому записі zkSync також є необов’язкова функція страхування uteTransactionFromOutside. Кошти можна вивести на L1 за допомогою «механізму виходу», якщо операції не можуть бути виконані (наприклад, коли генератор послідовностей не відповідає або zkSync вважається регуляторним ризиком). Ця частина має мало спільного з протоколом AA, тому детально описувати її тут не буде, кому цікаво, можете ознайомитися з офіційними документами та специфікацією zkSync.
Ключові моменти та обмеження функцій перевірки
У функції validateTransaction можна реалізовувати різні спеціальні логіки. Наприклад, якщо в обліковому записі реалізовано стандарт EIP-1271, логіку перевірки в EIP-1271 можна застосувати безпосередньо до validateTransaction або звернутися до контракту облікового запису з кількома підписами реалізація в офіційному документі zkSync.
У той же час, щоб уникнути загроз DoS на етапі перевірки EIP-4337, існують деякі обмеження (не можна використовувати зовнішні коди операції та обмежена глибина тощо), а також є подібні обмеження в zkSync, наприклад:
1. Логіка контракту може торкатися лише свого власного слота (якщо адреса контракту облікового запису A):
слот, що належить до адреси А
слот А за будь-якою іншою адресою
Слот keccak256(A||X) будь-якої іншої адреси, яка може безпосередньо використовувати адресу як ключ відображення (наприклад, відображення (адреса=>значення)), також еквівалентно дозволу доступу до слота keccak256( A||X), щоб досягти розширення. Наприклад, баланс токенів на ERC-20.
2. Логіка контракту не повинна використовувати глобальні змінні, такі як block.number
Ключові моменти та обмеження виконання функцій
У функції uteTransaction слід звернути увагу на те, що якщо ви хочете виконати системний виклик (Call), вам потрібно переконатися, що він має прапор is. Оскільки ці системні контракти мають великий вплив на систему облікових записів. Наприклад, єдиний спосіб збільшити nonce – це взаємодіяти з NonceHolder. Щоб розгорнути контракт, ви повинні взаємодіяти з ContractDeployer. Використання прапорця is може гарантувати, що розробники облікових записів свідомо взаємодіють з системними контрактами.
Однак рекомендується використовувати бібліотеку ContractsCaller, надану zkSync, щоб уникнути самостійної обробки прапора is, і використовувати CallWithPropagatedRevert для завершення системного виклику.
Зразок коду вище передбачає взаємодію з DEPLOYER__CONTRACT. Найпоширенішою ситуацією системного контракту, з якою стикаються розробники облікових записів, є те, що ми хочемо використовувати обліковий запис для розгортання контракту. У цей час ми повинні взаємодіяти з системним контрактом ContractDeployer. У цьому випадку розробник облікового запису має зв’язатися з контрактом ContractDeployer, щоб переконатися, що контракт успішно розгорнуто та виконує необхідні операції.
Комісійна модель і Paymaster в епоху zkSync
Збори та ліміт газу
Комісійна модель zkSync дуже схожа на Ethereum, платіжним токеном залишається ETH. Однак, як і інші рішення рівня 2 (такі як Arbitrum, Optimism), zkSync також потребує врахування додаткових витрат на публікацію в L1 (комісія за безпеку) на додаток до основних витрат на обчислення та запис. Оскільки ціна на газ, який публікує дані в L1, дуже нестабільна, Оператор zkSync визначає такі динамічні параметри, коли кожен блок відкривається (починає записувати транзакції):
gasPrice: ціна газу в gwei, тобто tx.gasprice у згаданому вище об’єкті транзакції
gasPerPubdata: кількість газу, необхідна для публікації байта даних в Ethereum.
Крім того, на відміну від EIP-4337, zkSync не потрібно визначати три ліміти газу: verificationGas, utionGas і preVerificationGas, але вимагає лише gasLimit для покриття всіх вищезазначених витрат, тому користувачі повинні переконатися, що gasLimit достатньо для покриття Етап перевірки, етап оновлення та завантаження даних Усі витрати, такі як плата за безпеку, на L1. Ця комісія включена в tx.gaslimit у згаданому вище об’єкті транзакції.
Помножте два (tx.gasprice * tx.gaslimit), щоб отримати комісію за транзакцію, сплачену завантажувачу.
Оплата праці
Paymaster переважно сплачує ETH завантажувачу замість контракту облікового запису користувача на етапі комісії за транзакцію користувача. Користувачі можуть вибрати різні платіжні системи та способи оплати, щоб сплатити комісію за обробку, наприклад (але не обмежуючись цим):
Оплата токенів ERC-20 Paymaster до початку транзакції або після її виконання
Поповнити контракт Paymaster кредитною карткою
Paymaster продовжуватиме сплачувати частину або всі збори для користувачів безкоштовно
Спосіб взаємодії користувачів із Paymaster залежить від різних протоколів, він може бути централізованим або децентралізованим; він може бути до або після транзакції; він може використовувати токени ERC-20 або законний платіжний засіб або навіть безкоштовний.
Контракт Paymaster для zkSync в основному складається з двох функцій, а саме validateAndPayForPaymasterTransaction (обов’язково) і postTransaction (необов’язково), обидві з яких може викликати лише завантажувач:
validateAndPayForPaymasterTransaction — це єдина функція, яка має бути реалізована в усьому контракті Paymaster. Коли оператор отримує транзакцію з параметром Paymaster, це означає, що комісія за обробку оплачується не договором облікового запису користувача, а Paymaster. У цей момент оператор викличе validateAndPayForPaymasterTransaction, щоб визначити, чи готовий Paymaster сплатити комісію за транзакцію. Якщо Paymaster погодиться, ця функція надішле принаймні tx.gasprice * tx.gaslimit ETH до завантажувача.
postTransaction є додатковою функцією, яка зазвичай використовується для відшкодування (повернення невикористаного газу відправнику). Однак поточний zkSync ще не підтримує цю операцію.
Paymaster у zkSync виконає postTransaction після впровадження postTransaction, що відрізняється від EIP-4337. EIP-4337 не викличе postOp, якщо validatePaymasterUserOp не повертає контекст, і навпаки.
Виходячи з вищезазначеного, наприклад, користувач тепер хоче надіслати транзакцію, комісія за обробку якої оплачується Paymaster, процес виглядає наступним чином:
На останньому кроці, навіть якщо postTransaction неможливо виконати через помилку браку газу, ця транзакція AA вважається успішною, але дія виклику postTransaction пропускається.
Якщо ви глибше заглибитесь у Paymaster zkSync, то побачите, що його Правила перевірки дещо відрізняються від 4337 (zkSync Paymaster може наступати на будь-який інший контрактний слот), а також існують різні типи (наприклад, на основі схвалення). до порівняння деталей.Кого цікавить може звернутися до офіційних документів або моєї попередньої реалізації.
Підсумок і порівняння
Завдяки попереднім поясненням ми дізналися, які важливі точки входу має договір облікового запису, а також їхні функції та відповідні обмеження. Одночасно ми також дізналися про функції системного контракту. Далі, давайте підсумуємо процес транзакції автоматизованих операцій (AA) у zkSync від будівництва до завершення, і я також надам більш докладні посилання для тих, хто хоче дізнатися більше:
Користувач використовує SDK або гаманець локально для створення об’єктів транзакції (наприклад: від, до, дані, значення тощо).
Користувач підписує транзакцію. Підписом тут не обов’язково є традиційний формат EIP-712 і підпис кривої ECDSA. zkSync також підтримує EIP-2718 і EIP-1559. Ключем до вибору методу підпису та методу перевірки є перевірка за допомогою функції перевірки в договорі облікового запису.
Надішліть підписану транзакцію оператору через RPC API. У цей момент транзакція переходить у стан очікування. Оператор передає транзакцію завантажувачу (викликає функцію processL2Tx у контракті завантажувача) і запускає серію процесів протоколу AA.
Завантажувач перевірить, чи Nonce є законним, і використає NonceHolder для перевірки.
Завантажувач викличе функцію validateTransaction у контракті облікового запису користувача, щоб підтвердити, що транзакцію авторизовано власником облікового запису.
Bootloader може стягувати комісію двома способами, і конкретний спосіб стягнення плати залежить від параметрів транзакції (чи додається параметр paymaster під час створення об’єкта транзакції):
a. Виклик функції payForTransaction і договір рахунку, щоб стягнути комісію за транзакцію;
b. Викличте функції pripravForPaymaster і validateAndPayForPaymasterTransaction, щоб стягнути комісію за транзакцію за контрактом Paymaster.
«Зателефонуйте payForTransaction, щоб укласти комісію з обліковим записом» або «зателефонуйте, щоб підготуватиPaymaster і validateAndPayForPaymasterTransaction, щоб укласти комісію з Paymaster»
Перевірте, чи отримав завантажувач принаймні комісію за транзакцію tx.gasprice * tx.gaslimit.
Завантажувач викличе функцію uteTransaction у контракті облікового запису користувача, щоб виконати транзакцію.
(Необов’язково) Якщо для оплати комісії за транзакцію використовується Paymaster, завантажувач викличе функцію postTransaction. Якщо Paymaster не реалізує postTransaction або газ вичерпано, цей крок буде пропущено.
Наведені вище 4.~7. кроки — це фаза перевірки (визначена в l2TxValidation завантажувача) і фаза виконання 8.~9. кроків (визначена в l2Txution завантажувача).
Порівняння EIP-4337, StarkNet і zkSync Era
В основному процеси механізму АА у трьох подібні, усі вони включають стадію перевірки→механізм комісії за обробку (оплачується за договором рахунку або Paymaster)→етап виконання.Основні відмінності:
Порівняно
Крім того, ми завершили створення P2P mempool для поточного об’єднувача 4337, а Sequencer і Operator zkRollups також є єдиними офіційними серверами, тому є певні централізовані компоненти.
У процесі розробки, оскільки zkSync не має проблеми підключення до різних групувальників (потрібно лише взаємодіяти з Operator API), він простий у використанні 4337, і досвід розробки контрактів облікових записів (SDK) також кращий; на водночас zkSync може використовувати Solidity як контрактну мову розробки, тому немає потреби перетинати поріг Cairo у розробці StarkNet.
Висновок
Оскільки і StarkNet, і zkSync належать до категорії локальних AA (Native AA), ви також можете звернутися до мого попереднього вступу до StarkNet AA під назвою «Вступ до абстракції облікового запису StarkNet» (Вступ до абстракції облікового запису StarkNet). Крім того, ви можете прочитати інші статті, пов’язані з EIP-4337, щоб отримати додаткові відомості.