Как работают устойчивые к цензуре транзакции в роллапах Ethereum

СреднийJun 11, 2024
Consensys, материнская компания Metamask, заблаговременно закрыла свое Ethereum Уровень 2 решение Linea, чтобы смягчить последствия инцидента со взломом Velocore. Этот инцидент высветил основную проблему недостаточной децентрализации в инфраструктуре. Для решений уровня 2 недецентрализованный секвенсор создает значительные риски для сопротивления цензуре и надежности сети. NIC Lin, глава Ethereum Taipei, провел эксперименты по устойчивым к цензуре транзакционным возможностям четырех основных роллапов, предоставив углубленный анализ конструкции механизма принудительного включения, включая рабочий процесс и операционные методы.
Как работают устойчивые к цензуре транзакции в роллапах Ethereum

Буквально вчера произошло шокирующее событие: Linea, Ethereum Уровень 2 решение, разработанное Consensys, материнской компанией Metamask, было проактивно закрыто. Официальная причина была названа для того, чтобы смягчить последствия инцидента со взломом Velocore. Этот инцидент неизбежно заставляет вспомнить предыдущий случай, когда цепочка BSC (BNB Chain) также была закрыта по официальной координации, чтобы минимизировать потери от взлома. Эти события часто заставляют людей сомневаться в децентрализованных ценностях, которые отстаивает Web3.

Основная причина вышеупомянутых событий кроется в несовершенстве инфраструктуры, в частности, в отсутствии у нее децентрализации. Если бы блокчейн был достаточно децентрализован, он не смог бы так легко закрыться. Из-за уникальной структуры Ethereum Уровень 2 большинство Уровень 2 решений полагаются на централизованные секвенсоры. Несмотря на растущий дискурс о децентрализованных секвенсорах в последние годы, учитывая назначение и структуру уровня 2, мы можем предположить, что секвенсоры уровня 2 вряд ли достигнут высокого уровня децентрализации. На самом деле, они могут оказаться менее децентрализованными, чем цепочка BSC. Если это так, то что можно сделать? Для уровня 2 наиболее непосредственными рисками недецентрализованных секвенсоров являются отсутствие сопротивления цензуре и живости. Если существует всего несколько сущностей, обрабатывающих транзакции (секвенсоры), они имеют абсолютную власть над тем, обслуживать вас или нет: они могут отклонить ваши транзакции по своему желанию, оставив вас без права регресса. Решение проблемы сопротивления цензуре на уровне 2, безусловно, является важной темой. За последние несколько лет различные Ethereum Уровень 2 решения предложили разные подходы к решению этой проблемы. Например, Loopring, Degate и StarkEx ввели функции принудительного вывода и аварийного выхода, в то время как Arbitrum и другие Optimistic Rollups реализовали функции Force Inclusion. Эти механизмы могут налагать проверки на секвенсоры, чтобы предотвратить произвольный отказ от пользовательских транзакций. В сегодняшней статье NIC Lin из Taipei Ethereum Association делится своим личным опытом, экспериментируя с устойчивыми к цензуре функциями транзакций четырех основных роллапов и предоставляя углубленный анализ механизма принудительного включения, уделяя особое внимание рабочему процессу и операционным методам. Этот анализ особенно ценен для сообщества Ethereum и крупных держателей активов.

Транзакционная цензура и принудительное включение

Цензура сопротивление в транзакциях имеет решающее значение для любого блокчейна. Если блокчейн может произвольно цензурировать и отклонять транзакции пользователей, то он ничем не отличается от Web2-сервера. Сопротивление цензуре транзакций Ethereum в настоящее время обеспечивается его многочисленными валидаторами. Если кто-то хочет подвергнуть цензуре транзакцию Боба и предотвратить ее включение в блокчейн, ему придется либо подкупить большинство валидаторов сети, либо заспамить сеть мусорными транзакциями, которые имеют более высокие комиссии, чем у Боба, тем самым занимая место в блоке. Оба метода чрезвычайно затратны.

Примечание: В текущей архитектуре Ethereum Proposer-Builder Separation (PBS) стоимость цензуры транзакций значительно снижена. Например, вы можете посмотреть на долю блоков, которые соответствуют цензуре OFAC в отношении транзакций Tornado Cash. Нынешнее сопротивление цензуре опирается на независимых валидаторов и ретрансляторы, которые находятся вне юрисдикции OFAC и других государственных органов.

Но как насчет роллапов? Роллапы не требуют большого количества валидаторов для обеспечения безопасности. Даже если в накопительном пакете есть только одна централизованная сущность (секвенсор), создающая блоки, он остается таким же безопасным, как и уровень 1 (L1). Однако безопасность и сопротивление цензуре — это две разные вещи. Роллап, будучи таким же безопасным, как и Ethereum, по-прежнему может подвергать цензуре любую транзакцию пользователя, если у него есть только один централизованный секвенсор.


Секвенсор может отказать в обработке транзакции пользователя, в результате чего средства пользователя будут заблокированы и не смогут покинуть роллап.

Механизм принудительного включения

Вместо того, чтобы требовать, чтобы роллапы имели большое количество децентрализованных секвенсоров, более эффективно напрямую использовать С сопротивлением цензуре уровня 1 (L1):

Поскольку секвенсору необходимо упаковать данные транзакции и отправить их в контракт Rollup на L1, мы можем добавить в контракт функцию, которая позволит пользователям самостоятельно вставлять свои транзакции в контракт Rollup. Этот механизм известен как «принудительное включение». лонгПоскольку секвенсор не может подвергать цензуре пользователей на уровне L1, он не может предотвратить принудительную вставку транзакций на уровне L1. Таким образом, накопительный пакет может унаследовать сопротивление цензуре L1.


Секвенсор не может просматривать транзакции L1 пользователя, не заплатив за это высокую цену

Как должны быть реализованы принудительные транзакции?

Если транзакции могут быть записаны непосредственно в контракт Rollup с помощью Force Inclusion (то есть они вступают в силу немедленно), состояние Rollup изменится мгновенно. Например, если Боб использует механизм принудительного включения для вставки транзакции, которая передает 1000 DAI Кэрол, и транзакция вступает в силу немедленно, баланс Боба уменьшится на 1000 DAI, а баланс Кэрол увеличится на 1000 DAI в обновленном состоянии.

Если принудительное включение позволяет записывать транзакции непосредственно в контракт Rollup и немедленно вступать в силу, состояние Rollup изменится мгновенно. Если секвенсор одновременно собирает транзакции вне блокчейна и готовится отправить следующую партию в контракт Rollup, он может быть нарушен принудительно вставленной транзакцией Боба, которая вступает в силу немедленно. Чтобы избежать этой проблемы, накопительные пакеты, как правило, не позволяют транзакциям принудительного включения вступать в силу немедленно. Вместо этого пользователи изначально помещают свои транзакции в очередь ожидания на L1, где они переходят в состояние «подготовки». Когда секвенсор упаковывает транзакции вне блокчейна для отправки в контракт Rollup, он может выбрать, включать ли эти транзакции в очередь. Если секвенсор постоянно игнорирует транзакции в состоянии «подготовки», то по окончании периода окна пользователи могут принудительно вставить эти транзакции в контракт объединения. Секвенсор может решать, когда «случайно включать» транзакции из очереди ожидания, но он все равно может отказаться их обрабатывать. Если секвенсор постоянно отказывается, по истечении определенного периода времени любой пользователь может использовать функцию принудительного включения для принудительной вставки транзакций в контракт Rollup. Далее мы представим реализацию механизма Force Inclusion в четырех известных роллапах: Optimism, Arbitrum, StarkNet и zkSync.

Секвенсор может выбирать, когда получать транзакции из очереди ожидания.

Секвенсоры по-прежнему могут отказываться обрабатывать транзакции в очереди ожидания.

Если секвенсор постоянно отказывается обрабатывать транзакции, по истечении определенного периода времени любой пользователь может использовать функцию Force Inclusion для принудительной вставки транзакций в контракт Rollup. Далее мы представим, как механизм Force Inclusion реализован в четырех известных роллапах: Optimism, Arbitrum, StarkNet и zkSync.

Механизм принудительного включения Optimism

Во-первых, давайте обсудим процесс депозита Optimism. Этот процесс депозита включает в себя не только перевод средств в Optimism, но и отправку «пользовательских сообщений на L2». Когда узел L2 получает только что депонированное сообщение, он преобразует его в транзакцию L2 и выполняет ее, доставляя указанному получателю.


Пользовательские сообщения, отправленные с L1 на L2

Контракт L1CrossDomainMessenger

Когда пользователь хочет депозит ETH или ERC-20 токены в Optimism, он взаимодействует с контрактом L1StandardBridge на L1 через веб-страницу, указывая сумму депозит и адрес L2, на который будут поступать эти активы. Затем мост L1StandardBridge пересылает сообщение контракту L1CrossDomainMessenger, который выступает в качестве основного моста связи между L1 и L2. L1StandardBridge использует этот коммуникационный компонент для взаимодействия с L2StandardBridge на L2, определяя, кто может минтинг токенов на L2 или разблокировать токены из L1. Разработчики, которым необходимо создавать контракты, которые взаимодействуют и синхронизируют состояния между L1 и L2, могут создавать их поверх контракта L1CrossDomainMessenger.


Пользовательские сообщения, передаваемые с L1 на L2 через контракт CrossDomainMessenger

Примечание: На некоторых изображениях в этой статье CrossDomainMessenger записывается как CrossChainMessenger.

Договор OptimismPortal

Затем контракт L1CrossDomainMessenger пересылает сообщение на самый нижний уровень, контракт OptimismPortal. После обработки сообщения контракт OptimismPortal генерирует событие TransactionDeposited, которое включает такие параметры, как «отправитель», «получатель» и другие соответствующие сведения о выполнении. Узлы Optimism на L2 прослушивают это событие TransactionDeposited из контракта OptimismPortal и преобразуют параметры события в транзакцию L2. Инициатором этой транзакции будет «отправитель», указанный в событии, получателем будет «получатель», упомянутый в событии, и другие детали транзакции также будут получены из параметров события.


Узлы L2 преобразуют параметры события Transaction Deposited, генерируемого OptimismPortal, в транзакцию L2.

Например, когда пользователь вносит 0,01 ETH через контракт L1StandardBridge, сообщение и ETH передаются в контракт OptimismPortal (адрес 0xbEb5... 06Ed). Через несколько минут это преобразуется в транзакцию L2: отправителем сообщения является контракт L1CrossDomainMessenger, получателем — контракт L2CrossDomainMessenger на L2, а содержимое сообщения указывает на то, что L1StandardBridge получил 0,01 ETH депозит от Боба. Затем запускаются дополнительные процессы, такие как минтинг 0,01 ETH для L2StandardBridge, который впоследствии передает его Бобу.

Как его запустить

Если вы хотите принудительно включить транзакцию в контракт Optimism Rollup, ваша цель состоит в том, чтобы гарантировать, что транзакция, «инициированная и выполненная с вашего адреса L2 на L2», может быть успешно выполнена. Для этого необходимо отправить сообщение непосредственно в контракт OptimismPortal, используя свой адрес L2 (обратите внимание, что контракт OptimismPortal на самом деле находится на L1, но формат адреса OP соответствует формату адреса L1, поэтому вы можете вызвать этот контракт, используя счет L1 с тем же адресом, что и ваш счет L2). «Отправителем» транзакции L2, полученной из события Transaction Deposited, генерируемого этим контрактом, будет ваш счет L2, а формат транзакции будет соответствовать стандартной транзакции L2.


В транзакции L2, производной от события Transaction Deposited, сам Боб будет инициатором; получателем будет контракт Uniswap; и он будет включать указанный ETH, как если бы Боб сам инициировал транзакцию L2.

Чтобы использовать функцию Force Inclusion Optimism, необходимо напрямую вызвать функцию depositTransaction контракта OptimismPortal и ввести параметры транзакции, которую вы хотите выполнить на L2. Я провел простой эксперимент Force Inclusion. Целью этой транзакции было выполнить самостоятельный перевод на L2 с использованием моего адреса (0xeDc1... 6909) и включить сообщение с надписью «принудительное включение». Это транзакция L1, которую я выполнил, вызвав функцию depositTransaction через контракт OptimismPortal. Как видно из события Transaction Deposited, отправитель и получатель — это я.


Остальные значения в непрозрачном столбце "Данные" кодируют такую информацию, как "сколько ETH присоединено лицо, вызывающее функцию depositTransaction", "сколько ETH инициатор транзакции L2 хочет отправить получателю", "GasLimit транзакции L2" и "Данные для получателя L2". После расшифровки этой информации вы получите следующие детали: «сколько ETH прикрепил человек, вызывающий депозитную транзакцию»: 0, потому что я не депонирую ETH с L1 на L2; «сколько ETH инициатор транзакции L2 хочет отправить получателю»: 5566 (WEI); "L2 транзакция GasLimit": 50000; "Data for the L2 receiver": 0x666f72636520696e636c7573696f6e, что является шестнадцатеричной кодировкой строки "force inclusion". Вскоре после этого появилась преобразованная транзакция L2: транзакция L2, в которой я передаю себе 5566 wei, с полем «Данные», содержащим строку «принудительное включение». Кроме того, в предпоследней строке раздела «Другие атрибуты» TxnType (тип транзакции) отображается как системная транзакция 126 (System), что указывает на то, что эта транзакция не была инициирована мной на L2, а была преобразована из события Deposited транзакции L1.


Преобразованная транзакция L2

Если вы хотите вызвать контракт L2 через Force Inclusion и отправить разные Data, вам просто нужно заполнить параметры в функции depositTransaction. Просто не забудьте использовать тот же адрес L1, что и ваш счет L2 при вызове функции depositTransaction. Таким образом, когда депонированное событие преобразуется в транзакцию L2, инициатором будет ваш счет L2. Окно секвенсора Узел L2 Optimism, который преобразует событие Transaction Deposited в транзакцию L2, на самом деле является секвенсором. Поскольку это включает в себя упорядочение транзакций, только секвенсор может решить, когда преобразовать событие в транзакцию L2. Когда секвенсор прослушивает событие TransactionDeposited, он не обязательно немедленно преобразует событие в транзакцию L2; Может быть задержка. Максимальная продолжительность этой задержки называется окном секвенсора. В настоящее время окно секвенсора в основной сети Optimism составляет 24 часа. Это означает, что когда пользователь вносит деньги с L1 или использует Force Inclusion для транзакции, в худшем случае они будут включены в историю транзакций L2 через 24 часа.

Механизм принудительного включения Arbitrum

В Optimism операция L1 депозит запускает событие Transaction Deposited, а затем остается только ждать, пока секвенсор включит эту операцию. Однако в Arbitrum операции на L1 (такие как внесение средств или отправка сообщений на L2) хранятся в очереди на L1, а не просто генерируют событие. У секвенсора есть определенный период времени, чтобы включить эти транзакции в очередь в историю транзакций L2. Если секвенсор не сделает этого в течение этого промежутка времени, любой пользователь может вмешаться, чтобы завершить включение от имени секвенсора.


Arbitrum поддерживает очередь в контракте L1. Если секвенсор не сможет обработать транзакции в очереди в течение определенного периода времени, любой пользователь может принудительно включить эти транзакции в историю транзакций L2. По замыслу Arbitrum, операции на L1, такие как депозиты, должны проходить через контракт Delayed Inbox, где, как следует из названия, эти операции будут отложены, прежде чем вступят в силу. Другой контракт, Sequencer Inbox, — это контракт, в котором Sequencer напрямую загружает транзакции L2 в L1. Каждый раз, когда секвенсор загружает транзакции L2, он также может брать некоторые ожидающие транзакции из папки отложенных входящих сообщений и включать их в историю транзакций.

Когда
секвенсор записывает новые транзакции, он также может включать транзакции из папки DelayedInbox.

Сложная конструкция и отсутствие справочных материалов

Если вы обратитесь к официальной документации Arbitrum по секвенсору и принудительному включению, вы найдете общее объяснение того, как работает принудительное включение, а также некоторые имена параметров и функций: Пользователи сначала вызывают функцию sendUnsignedTransaction в контракте DelayedInbox. Если секвенсор не включает его в течение примерно 24 часов, пользователи могут вызвать функцию forceInclusion в контракте SequencerInbox. Однако в официальной документации нет ссылок на эти функции, поэтому вам придется искать их в коде контракта самостоятельно. Когда вы находите функцию sendUnsignedTransaction, вы понимаете, что вам нужно самостоятельно заполнить значение nonce и значение maxFeePerGas. Чей это nonce? В какой сети maxFeePerGas? Как правильно его заполнить? Нет никаких справочных документов, даже NatSpec. Вы также найдете много похожих функций в контракте Arbitrum: sendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction. Нет никаких документов, объясняющих различия между этими функциями, как их использовать или как заполнять параметры, даже NatSpec.

Вы пытаетесь заполнить параметры и отправить транзакцию методом проб и ошибок, надеясь найти правильное использование. Однако вы обнаружите, что все эти функции применяют псевдоним адреса к вашему адресу L1, в результате чего отправителем транзакции на L2 становится совершенно другой адрес, оставляя ваш адрес L2 неактивным. Позже вы случайно наткнулись на результат поиска Google, показывающий, что у Arbitrum есть библиотека Tutorial со скриптами, демонстрирующими, как отправлять транзакции L2 из L1 (по сути, Force Inclusion). В учебном пособии перечислена функция, не упомянутая ранее: sendL2Message. Удивительно, но требуемый параметр message на самом деле является подписанной транзакцией L2 с использованием счета L2. Кто бы мог знать, что «сообщение, отправленное L2 через Force Inclusion» на самом деле является «подписанной транзакцией L2»? Более того, нет никаких документов или NatSpec, объясняющих, когда и как использовать эту функцию.

Вывод: Ручная генерация принудительной сделки на Arbitrum достаточно сложна. Рекомендуется следовать официальному руководству и использовать Arbitrum SDK. В отличие от других роллапов, в Arbitrum отсутствует четкая документация для разработчиков и аннотации кода. Во многих функциях отсутствуют объяснения их назначений и параметров, из-за чего разработчикам приходится тратить гораздо больше времени, чем ожидалось, на их интеграцию и использование. Я также обратился за помощью в Arbitrum Discord, но не получил удовлетворительных ответов. Когда я спрашивал в Discord, они только посоветовали мне посмотреть на sendL2Message и не объяснили функции других методов (включая те, которые упоминаются в документации по принудительному включению, такие как sendUnsignedTransaction), их цели, как их использовать или когда их использовать.

Механизм принудительного включения StarkNet

К сожалению, StarkNet в настоящее время не имеет механизма принудительного включения. На официальном форуме есть только две статьи, посвященные цензуре и принудительному включению. Причина невозможности доказать неудачные транзакции заключается в том, что система доказательства с нулевым разглашением StarkNet не может доказать неудачную транзакцию, поэтому принудительное включение не может быть разрешено. Если кто-то злонамеренно (или непреднамеренно) принудительно включит неудачную, недоказуемую транзакцию, StarkNet застрянет: потому что, как только транзакция принудительно включена, Проверяющий должен доказать неудачную транзакцию, но он не может. Ожидается, что StarkNet представит возможность доказательства неудачных транзакций в версии v0.15.0, после чего должен быть реализован механизм Force Inclusion.

Механизм zkSync для передачи сообщений L1->L2 и принудительного включения обрабатывается с помощью функции requestL2Transaction контракта MailBox. Пользователи указывают адрес L2, данные вызова, количество ETH для подключения, значение L2GasLimit и другие детали. Функция requestL2Transaction объединяет эти параметры в транзакцию L2 и помещает ее в PriorityQueue. Когда секвенсор упаковывает транзакции и загружает их в L1 (с помощью функции commitBatches), он указывает, сколько транзакций нужно взять из очереди PriorityQueue для включения в записи транзакций L2. С точки зрения Force Inclusion, zkSync похож на Optimism, где L2-адрес инициатора (такой же, как и L1-адрес) используется для вызова соответствующих функций и заполнения необходимых деталей (calllee, calldata и т.д.), а не как Arbitrum, который требует подписанной L2-транзакции. Тем не менее, по дизайну он похож на Arbitrum, так как оба поддерживают очередь на L1, а Sequencer принимает ожидающие транзакции, отправленные непосредственно пользователями из Queue, и записывает их в историю транзакций.

Если вы депозит ETH через официальный мост zkSync, как эта транзакция, он вызывает функцию requestL2Transaction контракта MailBox. Эта функция помещает транзакцию L2 депозита ETH в PriorityQueue и генерирует событие NewPriorityRequest. Поскольку контракт кодирует данные транзакции L2 в строку байтов, его нелегко прочитать. Однако, если вы посмотрите на параметры этой транзакции L1, вы увидите, что получатель L2 также является инициатором транзакции (поскольку это депозит для себя). Через некоторое время, когда Sequencer заберет эту транзакцию L2 из PriorityQueue и включит ее в историю транзакций, она будет преобразована в транзакцию L2, которую вы перенесете на себя. Сумма перевода будет представлять собой сумму ETH, прикрепленную инициатором в транзакции L1 Deposit ETH. В транзакции L1 Deposit и инициатор, и получатель 0xeDc1... 6909, сумма составляет 0,03 ETH, и calldata отсутствует. На L2 будет транзакция, в которой 0xeDc1... 6909 переводит на себя. Тип транзакции (TxnType) — 255, что указывает на системную транзакцию. Затем, точно так же, как я экспериментировал с функцией принудительной транзакции в Optimism ранее, я вызвал функцию zkSync requestL2Transaction и инициировал транзакцию самопередачи: ETH не был прикреплен, а данные вызова содержали HEX-кодировку строки «принудительное включение». Затем это было преобразовано в транзакцию L2, которую я передаю самому себе, с данными вызова, содержащими шестнадцатеричную строку для "принудительного включения": 0x666f72636520696e636c7573696f6e. Когда секвенсор берет транзакции из PriorityQueue и записывает их в историю транзакций, они преобразуются в соответствующие транзакции L2. Используя функцию requestL2Transaction, пользователи могут отправлять данные на L1 с тем же счетом L1, что и их адрес L2, указывая получателя L2, количество ETH для подключения и данные вызова. Если пользователи хотят вызвать другие контракты или включить другие данные, им просто нужно заполнить параметры в функции requestL2Transaction. Функция принудительного включения для пользователей пока отсутствует Несмотря на то, что транзакция L2, помещенная в PriorityQueue, будет иметь вычисленный период ожидания для включения секвенсором, текущая структура zkSync не имеет функции принудительного включения, которая позволяет пользователям применять ее. Это означает, что это лишь частичное решение. Несмотря на то, что существует «период ожидания включения», в конечном итоге он зависит от того, решит ли секвенсор включить его: он может включить его после истечения периода или никогда не включать транзакции из PriorityQueue. В будущем zkSync должен добавить функции, позволяющие пользователям принудительно включать транзакции в историю транзакций L2, если они не были включены секвенсором после периода ожидания. Это был бы по-настоящему эффективный механизм включения сил. Суммировать

L1 полагается на большое количество валидаторы для обеспечения "безопасности" и "С сопротивлением цензуре" сети. Роллапы, однако, имеют более слабую сопротивление цензуре, поскольку транзакции записываются несколькими или даже одним секвенсором. Таким образом, роллапы нуждаются в механизме принудительного включения, позволяющем пользователям обходить секвенсор и записывать транзакции в историю, предотвращая цензуру со стороны секвенсора, чтобы сделать накопитель непригодным для использования и предотвратить вывод средств пользователями. Принудительное включение позволяет пользователям принудительно записывать транзакции в историю, но дизайн должен выбирать, могут ли «транзакции быть немедленно вставлены в историю и немедленно вступить в силу». Если разрешить немедленный эффект, это отрицательно скажется на секвенсоре, так как ожидающие транзакции на L2 могут быть затронуты принудительно включенными транзакциями из L1. Таким образом, текущие механизмы принудительного включения в накопительных пакетах сначала помещают транзакции, вставленные из L1, в состояние ожидания и дают секвенсору временное окно для реагирования и принятия решения о включении этих ожидающих транзакций. zkSync и Arbitrum поддерживают очередь на L1 для управления транзакциями L2 или сообщениями, отправляемыми с L1 на L2. Arbitrum называет его DelayedInbox; zkSync называет его PriorityQueue. Тем не менее, метод zkSync для отправки транзакций L2 больше похож на Optimism, где сообщения отправляются с L1 с использованием адреса L2, так что при преобразовании в транзакцию L2 инициатором является адрес L2. Функция отправки L2 транзакций в Optimism называется depositTransaction; в zkSync он называется requestL2Transaction. В отличие от этого, Arbitrum генерирует полную транзакцию L2 и подписывает ее, а затем отправляет через функцию sendL2Message. На L2 Arbitrum использует подпись для восстановления подписанта как инициатора транзакции L2. В настоящее время StarkNet не имеет механизма принудительного включения; zkSync имеет наполовину реализованный механизм принудительного включения — у него есть PriorityQueue, и каждая транзакция L2 в очереди имеет срок действия включения, но этот срок действия в настоящее время просто для галочки. На практике секвенсор может не включать транзакции L2 из PriorityQueue.

Отказ от ответственности:

  1. Эта статья переслана с: [Geek Web3], оригинальное название - "Теория и практика: как запустить устойчивые к цензуре транзакции в Ethereum Rollup?", авторские права принадлежат оригинальному автору [NIC Lin, Head of Taipei Ethereum Meetup], если у вас есть какие-либо возражения против перепечатки, пожалуйста, свяжитесь с нами Gate Learn Team, команда разберется с этим как можно скорее в соответствии с соответствующими процедурами.

  2. Дисклеймер: Взгляды и мнения, выраженные в этой статье, представляют собой только личные взгляды автора и не являются какими-либо инвестиционными рекомендациями.

  3. Другие языковые версии статьи переведены командой Gate Learn. Без ссылок Gate.io копирование, распространение или плагиат переведенных статей запрещены.

Как работают устойчивые к цензуре транзакции в роллапах Ethereum

СреднийJun 11, 2024
Consensys, материнская компания Metamask, заблаговременно закрыла свое Ethereum Уровень 2 решение Linea, чтобы смягчить последствия инцидента со взломом Velocore. Этот инцидент высветил основную проблему недостаточной децентрализации в инфраструктуре. Для решений уровня 2 недецентрализованный секвенсор создает значительные риски для сопротивления цензуре и надежности сети. NIC Lin, глава Ethereum Taipei, провел эксперименты по устойчивым к цензуре транзакционным возможностям четырех основных роллапов, предоставив углубленный анализ конструкции механизма принудительного включения, включая рабочий процесс и операционные методы.
Как работают устойчивые к цензуре транзакции в роллапах Ethereum

Буквально вчера произошло шокирующее событие: Linea, Ethereum Уровень 2 решение, разработанное Consensys, материнской компанией Metamask, было проактивно закрыто. Официальная причина была названа для того, чтобы смягчить последствия инцидента со взломом Velocore. Этот инцидент неизбежно заставляет вспомнить предыдущий случай, когда цепочка BSC (BNB Chain) также была закрыта по официальной координации, чтобы минимизировать потери от взлома. Эти события часто заставляют людей сомневаться в децентрализованных ценностях, которые отстаивает Web3.

Основная причина вышеупомянутых событий кроется в несовершенстве инфраструктуры, в частности, в отсутствии у нее децентрализации. Если бы блокчейн был достаточно децентрализован, он не смог бы так легко закрыться. Из-за уникальной структуры Ethereum Уровень 2 большинство Уровень 2 решений полагаются на централизованные секвенсоры. Несмотря на растущий дискурс о децентрализованных секвенсорах в последние годы, учитывая назначение и структуру уровня 2, мы можем предположить, что секвенсоры уровня 2 вряд ли достигнут высокого уровня децентрализации. На самом деле, они могут оказаться менее децентрализованными, чем цепочка BSC. Если это так, то что можно сделать? Для уровня 2 наиболее непосредственными рисками недецентрализованных секвенсоров являются отсутствие сопротивления цензуре и живости. Если существует всего несколько сущностей, обрабатывающих транзакции (секвенсоры), они имеют абсолютную власть над тем, обслуживать вас или нет: они могут отклонить ваши транзакции по своему желанию, оставив вас без права регресса. Решение проблемы сопротивления цензуре на уровне 2, безусловно, является важной темой. За последние несколько лет различные Ethereum Уровень 2 решения предложили разные подходы к решению этой проблемы. Например, Loopring, Degate и StarkEx ввели функции принудительного вывода и аварийного выхода, в то время как Arbitrum и другие Optimistic Rollups реализовали функции Force Inclusion. Эти механизмы могут налагать проверки на секвенсоры, чтобы предотвратить произвольный отказ от пользовательских транзакций. В сегодняшней статье NIC Lin из Taipei Ethereum Association делится своим личным опытом, экспериментируя с устойчивыми к цензуре функциями транзакций четырех основных роллапов и предоставляя углубленный анализ механизма принудительного включения, уделяя особое внимание рабочему процессу и операционным методам. Этот анализ особенно ценен для сообщества Ethereum и крупных держателей активов.

Транзакционная цензура и принудительное включение

Цензура сопротивление в транзакциях имеет решающее значение для любого блокчейна. Если блокчейн может произвольно цензурировать и отклонять транзакции пользователей, то он ничем не отличается от Web2-сервера. Сопротивление цензуре транзакций Ethereum в настоящее время обеспечивается его многочисленными валидаторами. Если кто-то хочет подвергнуть цензуре транзакцию Боба и предотвратить ее включение в блокчейн, ему придется либо подкупить большинство валидаторов сети, либо заспамить сеть мусорными транзакциями, которые имеют более высокие комиссии, чем у Боба, тем самым занимая место в блоке. Оба метода чрезвычайно затратны.

Примечание: В текущей архитектуре Ethereum Proposer-Builder Separation (PBS) стоимость цензуры транзакций значительно снижена. Например, вы можете посмотреть на долю блоков, которые соответствуют цензуре OFAC в отношении транзакций Tornado Cash. Нынешнее сопротивление цензуре опирается на независимых валидаторов и ретрансляторы, которые находятся вне юрисдикции OFAC и других государственных органов.

Но как насчет роллапов? Роллапы не требуют большого количества валидаторов для обеспечения безопасности. Даже если в накопительном пакете есть только одна централизованная сущность (секвенсор), создающая блоки, он остается таким же безопасным, как и уровень 1 (L1). Однако безопасность и сопротивление цензуре — это две разные вещи. Роллап, будучи таким же безопасным, как и Ethereum, по-прежнему может подвергать цензуре любую транзакцию пользователя, если у него есть только один централизованный секвенсор.


Секвенсор может отказать в обработке транзакции пользователя, в результате чего средства пользователя будут заблокированы и не смогут покинуть роллап.

Механизм принудительного включения

Вместо того, чтобы требовать, чтобы роллапы имели большое количество децентрализованных секвенсоров, более эффективно напрямую использовать С сопротивлением цензуре уровня 1 (L1):

Поскольку секвенсору необходимо упаковать данные транзакции и отправить их в контракт Rollup на L1, мы можем добавить в контракт функцию, которая позволит пользователям самостоятельно вставлять свои транзакции в контракт Rollup. Этот механизм известен как «принудительное включение». лонгПоскольку секвенсор не может подвергать цензуре пользователей на уровне L1, он не может предотвратить принудительную вставку транзакций на уровне L1. Таким образом, накопительный пакет может унаследовать сопротивление цензуре L1.


Секвенсор не может просматривать транзакции L1 пользователя, не заплатив за это высокую цену

Как должны быть реализованы принудительные транзакции?

Если транзакции могут быть записаны непосредственно в контракт Rollup с помощью Force Inclusion (то есть они вступают в силу немедленно), состояние Rollup изменится мгновенно. Например, если Боб использует механизм принудительного включения для вставки транзакции, которая передает 1000 DAI Кэрол, и транзакция вступает в силу немедленно, баланс Боба уменьшится на 1000 DAI, а баланс Кэрол увеличится на 1000 DAI в обновленном состоянии.

Если принудительное включение позволяет записывать транзакции непосредственно в контракт Rollup и немедленно вступать в силу, состояние Rollup изменится мгновенно. Если секвенсор одновременно собирает транзакции вне блокчейна и готовится отправить следующую партию в контракт Rollup, он может быть нарушен принудительно вставленной транзакцией Боба, которая вступает в силу немедленно. Чтобы избежать этой проблемы, накопительные пакеты, как правило, не позволяют транзакциям принудительного включения вступать в силу немедленно. Вместо этого пользователи изначально помещают свои транзакции в очередь ожидания на L1, где они переходят в состояние «подготовки». Когда секвенсор упаковывает транзакции вне блокчейна для отправки в контракт Rollup, он может выбрать, включать ли эти транзакции в очередь. Если секвенсор постоянно игнорирует транзакции в состоянии «подготовки», то по окончании периода окна пользователи могут принудительно вставить эти транзакции в контракт объединения. Секвенсор может решать, когда «случайно включать» транзакции из очереди ожидания, но он все равно может отказаться их обрабатывать. Если секвенсор постоянно отказывается, по истечении определенного периода времени любой пользователь может использовать функцию принудительного включения для принудительной вставки транзакций в контракт Rollup. Далее мы представим реализацию механизма Force Inclusion в четырех известных роллапах: Optimism, Arbitrum, StarkNet и zkSync.

Секвенсор может выбирать, когда получать транзакции из очереди ожидания.

Секвенсоры по-прежнему могут отказываться обрабатывать транзакции в очереди ожидания.

Если секвенсор постоянно отказывается обрабатывать транзакции, по истечении определенного периода времени любой пользователь может использовать функцию Force Inclusion для принудительной вставки транзакций в контракт Rollup. Далее мы представим, как механизм Force Inclusion реализован в четырех известных роллапах: Optimism, Arbitrum, StarkNet и zkSync.

Механизм принудительного включения Optimism

Во-первых, давайте обсудим процесс депозита Optimism. Этот процесс депозита включает в себя не только перевод средств в Optimism, но и отправку «пользовательских сообщений на L2». Когда узел L2 получает только что депонированное сообщение, он преобразует его в транзакцию L2 и выполняет ее, доставляя указанному получателю.


Пользовательские сообщения, отправленные с L1 на L2

Контракт L1CrossDomainMessenger

Когда пользователь хочет депозит ETH или ERC-20 токены в Optimism, он взаимодействует с контрактом L1StandardBridge на L1 через веб-страницу, указывая сумму депозит и адрес L2, на который будут поступать эти активы. Затем мост L1StandardBridge пересылает сообщение контракту L1CrossDomainMessenger, который выступает в качестве основного моста связи между L1 и L2. L1StandardBridge использует этот коммуникационный компонент для взаимодействия с L2StandardBridge на L2, определяя, кто может минтинг токенов на L2 или разблокировать токены из L1. Разработчики, которым необходимо создавать контракты, которые взаимодействуют и синхронизируют состояния между L1 и L2, могут создавать их поверх контракта L1CrossDomainMessenger.


Пользовательские сообщения, передаваемые с L1 на L2 через контракт CrossDomainMessenger

Примечание: На некоторых изображениях в этой статье CrossDomainMessenger записывается как CrossChainMessenger.

Договор OptimismPortal

Затем контракт L1CrossDomainMessenger пересылает сообщение на самый нижний уровень, контракт OptimismPortal. После обработки сообщения контракт OptimismPortal генерирует событие TransactionDeposited, которое включает такие параметры, как «отправитель», «получатель» и другие соответствующие сведения о выполнении. Узлы Optimism на L2 прослушивают это событие TransactionDeposited из контракта OptimismPortal и преобразуют параметры события в транзакцию L2. Инициатором этой транзакции будет «отправитель», указанный в событии, получателем будет «получатель», упомянутый в событии, и другие детали транзакции также будут получены из параметров события.


Узлы L2 преобразуют параметры события Transaction Deposited, генерируемого OptimismPortal, в транзакцию L2.

Например, когда пользователь вносит 0,01 ETH через контракт L1StandardBridge, сообщение и ETH передаются в контракт OptimismPortal (адрес 0xbEb5... 06Ed). Через несколько минут это преобразуется в транзакцию L2: отправителем сообщения является контракт L1CrossDomainMessenger, получателем — контракт L2CrossDomainMessenger на L2, а содержимое сообщения указывает на то, что L1StandardBridge получил 0,01 ETH депозит от Боба. Затем запускаются дополнительные процессы, такие как минтинг 0,01 ETH для L2StandardBridge, который впоследствии передает его Бобу.

Как его запустить

Если вы хотите принудительно включить транзакцию в контракт Optimism Rollup, ваша цель состоит в том, чтобы гарантировать, что транзакция, «инициированная и выполненная с вашего адреса L2 на L2», может быть успешно выполнена. Для этого необходимо отправить сообщение непосредственно в контракт OptimismPortal, используя свой адрес L2 (обратите внимание, что контракт OptimismPortal на самом деле находится на L1, но формат адреса OP соответствует формату адреса L1, поэтому вы можете вызвать этот контракт, используя счет L1 с тем же адресом, что и ваш счет L2). «Отправителем» транзакции L2, полученной из события Transaction Deposited, генерируемого этим контрактом, будет ваш счет L2, а формат транзакции будет соответствовать стандартной транзакции L2.


В транзакции L2, производной от события Transaction Deposited, сам Боб будет инициатором; получателем будет контракт Uniswap; и он будет включать указанный ETH, как если бы Боб сам инициировал транзакцию L2.

Чтобы использовать функцию Force Inclusion Optimism, необходимо напрямую вызвать функцию depositTransaction контракта OptimismPortal и ввести параметры транзакции, которую вы хотите выполнить на L2. Я провел простой эксперимент Force Inclusion. Целью этой транзакции было выполнить самостоятельный перевод на L2 с использованием моего адреса (0xeDc1... 6909) и включить сообщение с надписью «принудительное включение». Это транзакция L1, которую я выполнил, вызвав функцию depositTransaction через контракт OptimismPortal. Как видно из события Transaction Deposited, отправитель и получатель — это я.


Остальные значения в непрозрачном столбце "Данные" кодируют такую информацию, как "сколько ETH присоединено лицо, вызывающее функцию depositTransaction", "сколько ETH инициатор транзакции L2 хочет отправить получателю", "GasLimit транзакции L2" и "Данные для получателя L2". После расшифровки этой информации вы получите следующие детали: «сколько ETH прикрепил человек, вызывающий депозитную транзакцию»: 0, потому что я не депонирую ETH с L1 на L2; «сколько ETH инициатор транзакции L2 хочет отправить получателю»: 5566 (WEI); "L2 транзакция GasLimit": 50000; "Data for the L2 receiver": 0x666f72636520696e636c7573696f6e, что является шестнадцатеричной кодировкой строки "force inclusion". Вскоре после этого появилась преобразованная транзакция L2: транзакция L2, в которой я передаю себе 5566 wei, с полем «Данные», содержащим строку «принудительное включение». Кроме того, в предпоследней строке раздела «Другие атрибуты» TxnType (тип транзакции) отображается как системная транзакция 126 (System), что указывает на то, что эта транзакция не была инициирована мной на L2, а была преобразована из события Deposited транзакции L1.


Преобразованная транзакция L2

Если вы хотите вызвать контракт L2 через Force Inclusion и отправить разные Data, вам просто нужно заполнить параметры в функции depositTransaction. Просто не забудьте использовать тот же адрес L1, что и ваш счет L2 при вызове функции depositTransaction. Таким образом, когда депонированное событие преобразуется в транзакцию L2, инициатором будет ваш счет L2. Окно секвенсора Узел L2 Optimism, который преобразует событие Transaction Deposited в транзакцию L2, на самом деле является секвенсором. Поскольку это включает в себя упорядочение транзакций, только секвенсор может решить, когда преобразовать событие в транзакцию L2. Когда секвенсор прослушивает событие TransactionDeposited, он не обязательно немедленно преобразует событие в транзакцию L2; Может быть задержка. Максимальная продолжительность этой задержки называется окном секвенсора. В настоящее время окно секвенсора в основной сети Optimism составляет 24 часа. Это означает, что когда пользователь вносит деньги с L1 или использует Force Inclusion для транзакции, в худшем случае они будут включены в историю транзакций L2 через 24 часа.

Механизм принудительного включения Arbitrum

В Optimism операция L1 депозит запускает событие Transaction Deposited, а затем остается только ждать, пока секвенсор включит эту операцию. Однако в Arbitrum операции на L1 (такие как внесение средств или отправка сообщений на L2) хранятся в очереди на L1, а не просто генерируют событие. У секвенсора есть определенный период времени, чтобы включить эти транзакции в очередь в историю транзакций L2. Если секвенсор не сделает этого в течение этого промежутка времени, любой пользователь может вмешаться, чтобы завершить включение от имени секвенсора.


Arbitrum поддерживает очередь в контракте L1. Если секвенсор не сможет обработать транзакции в очереди в течение определенного периода времени, любой пользователь может принудительно включить эти транзакции в историю транзакций L2. По замыслу Arbitrum, операции на L1, такие как депозиты, должны проходить через контракт Delayed Inbox, где, как следует из названия, эти операции будут отложены, прежде чем вступят в силу. Другой контракт, Sequencer Inbox, — это контракт, в котором Sequencer напрямую загружает транзакции L2 в L1. Каждый раз, когда секвенсор загружает транзакции L2, он также может брать некоторые ожидающие транзакции из папки отложенных входящих сообщений и включать их в историю транзакций.

Когда
секвенсор записывает новые транзакции, он также может включать транзакции из папки DelayedInbox.

Сложная конструкция и отсутствие справочных материалов

Если вы обратитесь к официальной документации Arbitrum по секвенсору и принудительному включению, вы найдете общее объяснение того, как работает принудительное включение, а также некоторые имена параметров и функций: Пользователи сначала вызывают функцию sendUnsignedTransaction в контракте DelayedInbox. Если секвенсор не включает его в течение примерно 24 часов, пользователи могут вызвать функцию forceInclusion в контракте SequencerInbox. Однако в официальной документации нет ссылок на эти функции, поэтому вам придется искать их в коде контракта самостоятельно. Когда вы находите функцию sendUnsignedTransaction, вы понимаете, что вам нужно самостоятельно заполнить значение nonce и значение maxFeePerGas. Чей это nonce? В какой сети maxFeePerGas? Как правильно его заполнить? Нет никаких справочных документов, даже NatSpec. Вы также найдете много похожих функций в контракте Arbitrum: sendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction. Нет никаких документов, объясняющих различия между этими функциями, как их использовать или как заполнять параметры, даже NatSpec.

Вы пытаетесь заполнить параметры и отправить транзакцию методом проб и ошибок, надеясь найти правильное использование. Однако вы обнаружите, что все эти функции применяют псевдоним адреса к вашему адресу L1, в результате чего отправителем транзакции на L2 становится совершенно другой адрес, оставляя ваш адрес L2 неактивным. Позже вы случайно наткнулись на результат поиска Google, показывающий, что у Arbitrum есть библиотека Tutorial со скриптами, демонстрирующими, как отправлять транзакции L2 из L1 (по сути, Force Inclusion). В учебном пособии перечислена функция, не упомянутая ранее: sendL2Message. Удивительно, но требуемый параметр message на самом деле является подписанной транзакцией L2 с использованием счета L2. Кто бы мог знать, что «сообщение, отправленное L2 через Force Inclusion» на самом деле является «подписанной транзакцией L2»? Более того, нет никаких документов или NatSpec, объясняющих, когда и как использовать эту функцию.

Вывод: Ручная генерация принудительной сделки на Arbitrum достаточно сложна. Рекомендуется следовать официальному руководству и использовать Arbitrum SDK. В отличие от других роллапов, в Arbitrum отсутствует четкая документация для разработчиков и аннотации кода. Во многих функциях отсутствуют объяснения их назначений и параметров, из-за чего разработчикам приходится тратить гораздо больше времени, чем ожидалось, на их интеграцию и использование. Я также обратился за помощью в Arbitrum Discord, но не получил удовлетворительных ответов. Когда я спрашивал в Discord, они только посоветовали мне посмотреть на sendL2Message и не объяснили функции других методов (включая те, которые упоминаются в документации по принудительному включению, такие как sendUnsignedTransaction), их цели, как их использовать или когда их использовать.

Механизм принудительного включения StarkNet

К сожалению, StarkNet в настоящее время не имеет механизма принудительного включения. На официальном форуме есть только две статьи, посвященные цензуре и принудительному включению. Причина невозможности доказать неудачные транзакции заключается в том, что система доказательства с нулевым разглашением StarkNet не может доказать неудачную транзакцию, поэтому принудительное включение не может быть разрешено. Если кто-то злонамеренно (или непреднамеренно) принудительно включит неудачную, недоказуемую транзакцию, StarkNet застрянет: потому что, как только транзакция принудительно включена, Проверяющий должен доказать неудачную транзакцию, но он не может. Ожидается, что StarkNet представит возможность доказательства неудачных транзакций в версии v0.15.0, после чего должен быть реализован механизм Force Inclusion.

Механизм zkSync для передачи сообщений L1->L2 и принудительного включения обрабатывается с помощью функции requestL2Transaction контракта MailBox. Пользователи указывают адрес L2, данные вызова, количество ETH для подключения, значение L2GasLimit и другие детали. Функция requestL2Transaction объединяет эти параметры в транзакцию L2 и помещает ее в PriorityQueue. Когда секвенсор упаковывает транзакции и загружает их в L1 (с помощью функции commitBatches), он указывает, сколько транзакций нужно взять из очереди PriorityQueue для включения в записи транзакций L2. С точки зрения Force Inclusion, zkSync похож на Optimism, где L2-адрес инициатора (такой же, как и L1-адрес) используется для вызова соответствующих функций и заполнения необходимых деталей (calllee, calldata и т.д.), а не как Arbitrum, который требует подписанной L2-транзакции. Тем не менее, по дизайну он похож на Arbitrum, так как оба поддерживают очередь на L1, а Sequencer принимает ожидающие транзакции, отправленные непосредственно пользователями из Queue, и записывает их в историю транзакций.

Если вы депозит ETH через официальный мост zkSync, как эта транзакция, он вызывает функцию requestL2Transaction контракта MailBox. Эта функция помещает транзакцию L2 депозита ETH в PriorityQueue и генерирует событие NewPriorityRequest. Поскольку контракт кодирует данные транзакции L2 в строку байтов, его нелегко прочитать. Однако, если вы посмотрите на параметры этой транзакции L1, вы увидите, что получатель L2 также является инициатором транзакции (поскольку это депозит для себя). Через некоторое время, когда Sequencer заберет эту транзакцию L2 из PriorityQueue и включит ее в историю транзакций, она будет преобразована в транзакцию L2, которую вы перенесете на себя. Сумма перевода будет представлять собой сумму ETH, прикрепленную инициатором в транзакции L1 Deposit ETH. В транзакции L1 Deposit и инициатор, и получатель 0xeDc1... 6909, сумма составляет 0,03 ETH, и calldata отсутствует. На L2 будет транзакция, в которой 0xeDc1... 6909 переводит на себя. Тип транзакции (TxnType) — 255, что указывает на системную транзакцию. Затем, точно так же, как я экспериментировал с функцией принудительной транзакции в Optimism ранее, я вызвал функцию zkSync requestL2Transaction и инициировал транзакцию самопередачи: ETH не был прикреплен, а данные вызова содержали HEX-кодировку строки «принудительное включение». Затем это было преобразовано в транзакцию L2, которую я передаю самому себе, с данными вызова, содержащими шестнадцатеричную строку для "принудительного включения": 0x666f72636520696e636c7573696f6e. Когда секвенсор берет транзакции из PriorityQueue и записывает их в историю транзакций, они преобразуются в соответствующие транзакции L2. Используя функцию requestL2Transaction, пользователи могут отправлять данные на L1 с тем же счетом L1, что и их адрес L2, указывая получателя L2, количество ETH для подключения и данные вызова. Если пользователи хотят вызвать другие контракты или включить другие данные, им просто нужно заполнить параметры в функции requestL2Transaction. Функция принудительного включения для пользователей пока отсутствует Несмотря на то, что транзакция L2, помещенная в PriorityQueue, будет иметь вычисленный период ожидания для включения секвенсором, текущая структура zkSync не имеет функции принудительного включения, которая позволяет пользователям применять ее. Это означает, что это лишь частичное решение. Несмотря на то, что существует «период ожидания включения», в конечном итоге он зависит от того, решит ли секвенсор включить его: он может включить его после истечения периода или никогда не включать транзакции из PriorityQueue. В будущем zkSync должен добавить функции, позволяющие пользователям принудительно включать транзакции в историю транзакций L2, если они не были включены секвенсором после периода ожидания. Это был бы по-настоящему эффективный механизм включения сил. Суммировать

L1 полагается на большое количество валидаторы для обеспечения "безопасности" и "С сопротивлением цензуре" сети. Роллапы, однако, имеют более слабую сопротивление цензуре, поскольку транзакции записываются несколькими или даже одним секвенсором. Таким образом, роллапы нуждаются в механизме принудительного включения, позволяющем пользователям обходить секвенсор и записывать транзакции в историю, предотвращая цензуру со стороны секвенсора, чтобы сделать накопитель непригодным для использования и предотвратить вывод средств пользователями. Принудительное включение позволяет пользователям принудительно записывать транзакции в историю, но дизайн должен выбирать, могут ли «транзакции быть немедленно вставлены в историю и немедленно вступить в силу». Если разрешить немедленный эффект, это отрицательно скажется на секвенсоре, так как ожидающие транзакции на L2 могут быть затронуты принудительно включенными транзакциями из L1. Таким образом, текущие механизмы принудительного включения в накопительных пакетах сначала помещают транзакции, вставленные из L1, в состояние ожидания и дают секвенсору временное окно для реагирования и принятия решения о включении этих ожидающих транзакций. zkSync и Arbitrum поддерживают очередь на L1 для управления транзакциями L2 или сообщениями, отправляемыми с L1 на L2. Arbitrum называет его DelayedInbox; zkSync называет его PriorityQueue. Тем не менее, метод zkSync для отправки транзакций L2 больше похож на Optimism, где сообщения отправляются с L1 с использованием адреса L2, так что при преобразовании в транзакцию L2 инициатором является адрес L2. Функция отправки L2 транзакций в Optimism называется depositTransaction; в zkSync он называется requestL2Transaction. В отличие от этого, Arbitrum генерирует полную транзакцию L2 и подписывает ее, а затем отправляет через функцию sendL2Message. На L2 Arbitrum использует подпись для восстановления подписанта как инициатора транзакции L2. В настоящее время StarkNet не имеет механизма принудительного включения; zkSync имеет наполовину реализованный механизм принудительного включения — у него есть PriorityQueue, и каждая транзакция L2 в очереди имеет срок действия включения, но этот срок действия в настоящее время просто для галочки. На практике секвенсор может не включать транзакции L2 из PriorityQueue.

Отказ от ответственности:

  1. Эта статья переслана с: [Geek Web3], оригинальное название - "Теория и практика: как запустить устойчивые к цензуре транзакции в Ethereum Rollup?", авторские права принадлежат оригинальному автору [NIC Lin, Head of Taipei Ethereum Meetup], если у вас есть какие-либо возражения против перепечатки, пожалуйста, свяжитесь с нами Gate Learn Team, команда разберется с этим как можно скорее в соответствии с соответствующими процедурами.

  2. Дисклеймер: Взгляды и мнения, выраженные в этой статье, представляют собой только личные взгляды автора и не являются какими-либо инвестиционными рекомендациями.

  3. Другие языковые версии статьи переведены командой Gate Learn. Без ссылок Gate.io копирование, распространение или плагиат переведенных статей запрещены.

Начните торговать сейчас
Зарегистрируйтесь сейчас и получите ваучер на
$100
!