Tytuł oryginalny: „Wprowadzenie do mechanizmu włączania siły firmy Rollup”
Autor: NIC Lin, szef spotkania Taipei Ethereum
Zaledwie wczoraj wydarzyło się coś, co zszokowało niezliczone osoby: Linea, druga warstwa Ethereum uruchomiona przez spółkę-matkę Metamask Consensys, została proaktywnie zamknięta. Urzędnicy twierdzą, że miało to na celu zmniejszenie skutków incydentu zhakowaniem Velocore. Nie może to pomóc, ale przypomina ludziom o poprzednim zamknięciu sieci BSC (łańcucha BNB) w ramach oficjalnej koordynacji w celu zmniejszenia strat wynikających z ataków hakerskich. Ilekroć ludzie będą mówić o tego typu sprawach, będą wątpić w zdecentralizowaną wartość propagowaną przez Web3.
Oczywiście podstawową przyczyną wyżej wymienionych incydentów jest raczej niedoskonałość samej infrastruktury, czyli niewystarczająca decentralizacja: jeśli sieć jest wystarczająco zdecentralizowana, nie powinna zatrzymywać się na chwilę. Ze względu na unikalną strukturę drugiej warstwy Ethereum, większość warstwy 2 opiera się na scentralizowanym sekwencerze, choć w ostatnich latach pojawia się coraz więcej argumentów za zdecentralizowanymi sekwencerami, biorąc pod uwagę cel drugiej warstwy i jej strukturę, prawdopodobnie tak. można uznać, że sortownik warstwy 2 najprawdopodobniej nie będzie bardzo zdecentralizowany i ostatecznie może nie być tak zdecentralizowany jak łańcuch BSC. Jeśli rzeczywiście tak jest, co powinniśmy zrobić?
W rzeczywistości w przypadku drugiej warstwy najbardziej bezpośrednią szkodą spowodowaną brakiem decentralizacji sortownika jest jego opór i aktywność wobec cenzury. Jeśli jest tylko kilka podmiotów (sekwencerów), które przetwarzają transakcje, ma on absolutną władzę nad tym, czy Ci służyć: może Cię odrzucić, jeśli chce, a Ty możesz nie mieć wyboru. Sposób rozwiązania problemu antycenzury w warstwie 2 jest oczywiście ważnym tematem.
W ciągu ostatnich kilku lat główne drugie warstwy Ethereum zaproponowały różne rozwiązania problemów związanych z cenzurą, takie jak Loopring i Degate, funkcje wymuszonego wycofania i luku ewakuacyjnego StarkEx oraz Arbitrum i inne funkcje Force Inclusion w OP Rollup. Metody te mogą tworzyć kontrole i równoważy sekwencer pod pewnymi warunkami, aby zapobiec odrzuceniu żądania transakcji użytkownika bez powodu.
W dzisiejszym artykule NIC Lin z Taipei Ethereum Association przedstawia własne konto, osobiście eksperymentował z antycenzurowymi funkcjami transakcyjnymi czterech popularnych rollupów i dogłębnie przeanalizował konstrukcję mechanizmu Force Inclusion pod kątem takich aspektów, jak przepływ pracy i metody działania, co jest bardzo ważne dla Ethereum Jest to szczególnie cenne dla społeczności i dużych inwestorów z ogromnymi aktywami.
Przegląd transakcji i wymuszenie włączenia
Odporność na cenzurę transakcji (Censorship Resistance) jest bardzo ważna dla blockchainu. Jeśli blockchain może dowolnie przeglądać i odrzucać transakcje inicjowane przez użytkowników, nie będzie się różnił od serwera Web2. Obecna odporność transakcji Ethereum na cenzurę wynika z dużej liczby walidatorów. Jeśli ktoś chce sprawdzić transakcje Boba i uniemożliwić przesłanie jego transakcji do łańcucha, musi albo spróbować przekupić większość walidatorów w sieci, albo zasmucić całą sieć. sieci. Ciągle wysyłaj niepotrzebne transakcje z wyższymi opłatami manipulacyjnymi niż Bob, aby zająć miejsce w blokach. Tak czy inaczej, koszt będzie bardzo wysoki.
Uwaga: w obecnej strukturze PBS Ethereum koszt przeglądania transakcji zostanie znacznie obniżony. Możesz odnieść się do proporcji bloków, które współpracują z OFAC w celu przeglądu transakcji Tornado Cash. Obecny opór przed cenzurą opiera się na niezależnych weryfikatorach i przekazach poza jurysdykcją OFAC i rządu.
A co z Rollupem? Rollup nie wymaga dużej liczby walidatorów, aby zapewnić bezpieczeństwo. Nawet jeśli Rollup ma tylko jedną scentralizowaną rolę (sekwenser) do generowania bloków, jest tak samo bezpieczny jak L1. Jednak bezpieczeństwo i odporność na cenzurę to dwie różne rzeczy. Nawet jeśli pakiet zbiorczy jest tak bezpieczny jak Ethereum, z tylko jednym scentralizowanym sekwencerem, transakcje dowolnego użytkownika mogą zostać ocenzurowane.
Sequencer może odmówić przetworzenia transakcji użytkownika, powodując wstrzymanie środków użytkownika i niemożność opuszczenia Rollupu.
Mechanizm włączenia siły
Zamiast wymagać od Rollupa posiadania dużej liczby zdecentralizowanych sekwencerów, lepiej jest bezpośrednio wykorzystać możliwości antycenzury L1:
Pierwotnie Sequencer miał za zadanie pakować dane transakcyjne i wysyłać je do kontraktu L1 Rollup. Lepiej jest dodać projekt do kontraktu, aby użytkownicy mogli samodzielnie wstawiać transakcje do kontraktu Rollup. Mechanizm ten nazywa się „Force Inclusion”. Dopóki Sequencer nie może cenzurować użytkowników na poziomie L1, nie może uniemożliwić użytkownikom wymuszania wprowadzania transakcji na poziomie L1. W ten sposób Rollup może odziedziczyć odporność L1 na cenzurę.
Sequencer nie może przeglądać transakcji L1 użytkownika bez poniesienia wysokich kosztów
Jak transakcje wymuszone powinny obowiązywać?
Jeśli transakcje mogą być zapisywane bezpośrednio w umowie Rollup poprzez Force Inclusion (to znaczy ze skutkiem natychmiastowym), status Rollup zmieni się natychmiast. Na przykład Bob wstawia transakcję „przelej 1000 DAI do Carol” poprzez Force Inclusion Jeśli transakcja zacznie obowiązywać natychmiast, saldo Boba w ostatnim stanie będzie o 1000 DAI mniejsze, a saldo Carol będzie o 1000 DAI wyższe.
Jeśli Force Inclusion może bezpośrednio zapisać transakcję w umowie Rollup i zastosować ją natychmiast, status zmieni się natychmiast.
Jeśli sekwencer zbiera w tym czasie również transakcje poza łańcuchem i wysyła następną partię transakcji do kontraktu zbiorczego, mogą na to mieć wpływ transakcje, które Bob wstawia na siłę i które zaczynają obowiązywać natychmiast. Tego rodzaju problemów należy unikać tak bardzo, jak to możliwe, więc pakiet zbiorczy zazwyczaj nie powoduje natychmiastowego działania transakcji Force Inclusion. Zamiast tego pozwala najpierw użytkownikowi wstawić transakcję do kolejki oczekującej na L1 i wejść w stan „przygotowania”. .
Kiedy Sequencer pakuje transakcje poza łańcuchem i wysyła je do kontraktu zbiorczego, decyduje, czy wstawić wyżej wymienione transakcje do sekwencji transakcji. Jeśli Sequencer ignorował te transakcje w stanie „przygotowania”, po zakończeniu okresu okna użytkownik może wymusić te transakcje. Wstaw do umowy zbiorczej.
Sequencer może zdecydować, kiedy „przypadkowo odebrać” transakcje oczekujące w kolejce
Sekwenser może w dalszym ciągu odmówić przetworzenia transakcji znajdujących się w kolejce oczekującej.
Jeśli sekwencer odmawia przez dłuższy czas, po pewnym czasie każdy może wymusić transakcję w ramach umowy zbiorczej za pomocą funkcji Force Inclusion.
Następnie przedstawimy w kolejności implementację mechanizmu Force Inclusion czterech znanych Rollupów, w tym Optimism, Arbitrum, StarkNet i zkSync.
Mechanizm włączenia siły optymizmu
Najpierw przedstawimy proces Depozytu Optymizmu. Depozyt ten nie tylko odnosi się do wpłacania pieniędzy do Optymizmu, ale obejmuje także „wysyłanie informacji wysyłanych przez użytkowników do L2” do L2. Po odebraniu nowo zdeponowanej wiadomości węzeł L2 przekształci wiadomość w transakcję L2 w celu realizacji i wyśle ją do wyznaczonego odbiorcy wiadomości.
Wiadomość użytkownika z depozytu L1 do depozytu L2
Umowa L1CrossDomainMessenger
Kiedy użytkownik chce zdeponować tokeny ETH lub ERC-20 w Optimism, wejdzie w interakcję z umową L1StandardBridge na L1 za pośrednictwem strony internetowej, określając kwotę wpłaty i adres L2, na który mają otrzymać te aktywa.
Kontrakt L1StandardBridge przekaże wiadomość do kontraktu L1CrossDomainMessenger następnego poziomu. Kontrakt ten jest używany głównie jako komponent wzajemnej komunikacji pomiędzy L1 i L2. L1StandardBridge komunikuje się z L2StandardBridge na L2 za pośrednictwem tego ogólnego komponentu komunikacji, aby zdecydować, kto może rzucić token. w monetach L2 lub kto może odblokować tokeny z L1.
Jeśli programista musi opracować kontrakt, który komunikuje i synchronizuje status między L1 i L2, może go zbudować na kontrakcie L1CrossDomainMessenger.
Wiadomość użytkownika jest przekazywana z L1 do L2 poprzez kontrakt CrossDomainMessenger
Uwaga: na niektórych ilustracjach w tym artykule CrossDomainMessager jest zapisywany jako CrossChainMessager
Umowa na portal optymizmu
Kontrakt L1CrossDomainMessenger wyśle wiadomość do kontraktu OptimismPortal najniższego poziomu. Po przetworzeniu kontrakt OptimismPortal wygeneruje zdarzenie o nazwie TransactionDeposited. Parametry obejmują „osobę, która wysłała wiadomość”, „osobę, która otrzymała wiadomość”. i powiązane parametry wykonania.
Następnie węzeł L2 Optimism będzie nasłuchiwał zdarzenia Transaction Depozyt zgłoszonego przez kontrakt OptimismPortal i konwertował parametry zdarzenia na transakcję L2. Inicjatorem tej transakcji będzie „nadawca wiadomości” określony w parametrze zdarzenia Transaction Depozyt odbiorca transakcji to „osoba, która odbiera wiadomość” w parametrach zdarzenia, a inne parametry transakcji również pochodzą z parametrów w powyższych zdarzeniach.
Węzeł L2 przekształci parametr zdarzenia Depozyt transakcji w OptimismPortalemit w transakcję L2
Na przykład jest to transakcja, podczas której użytkownik wpłaca 0,01 ETH za pośrednictwem kontraktu L1StandardBridge. Ten komunikat i ETH są przesyłane aż do kontraktu OptimismPortal (adres to 0xbEb5...06Ed), a następnie konwertowane na kontrakt L2. transakcja kilka minut później:
Inicjatorem wiadomości jest kontrakt L1CrossDomainMessenger; odbiorcą jest kontrakt L2CrossDomainMessenger na L2; treść wiadomości jest taka, że L1StandardBridge otrzymał depozyt BoB w wysokości 0,01ETH. Następnie zostaną uruchomione niektóre procesy, takie jak wydanie dodatkowego 0,01 ETH do L2StandardBridge, który następnie zostanie przekazany Bobowi.
Jak to konkretnie wywołać
Jeśli chcesz wymusić transakcję w ramach umowy Rollup firmy Optimism, efektem, który chcesz osiągnąć, jest umożliwienie sprawnego wykonania „transakcji zainicjowanej i wykonanej na L2 z Twojego adresu L2”. W tym momencie powinieneś użyć swojego adresu L2 przesyła wiadomość bezpośrednio do umowy OptimismPortal (należy pamiętać, że umowa OptimismPortal faktycznie znajduje się na L1, ale format adresu OP jest taki sam jak format adresu L1. Możesz bezpośrednio wywołać powyższą umowę za pomocą konta L1 z tym samym adresem co konto L2).
„Inicjatorem” transakcji L2 przeliczonej przez zdarzenie Transaction Depozyt zgłoszone przez kontrakt będzie Twoje konto L2. W tym momencie format transakcji jest zgodny z normalną transakcją L2.
W transakcji L2 konwertowanej ze zdarzenia Transaction Depozyt inicjatorem będzie sam Bob; odbiorcą będzie kontrakt Uniswap i będzie mu towarzyszył określony ETH, tak jak sam Bob zainicjował transakcję L2.
Jeśli chcesz wywołać funkcję Force Inclusion w Optimism, musisz bezpośrednio wywołać funkcję depozytTransaction kontraktu OptimismPortal i wypełnić parametry transakcji, którą chcesz wykonać w L2.
Przeprowadziłem prosty eksperyment z włączeniem siły. Transakcja ta miała na celu osiągnięcie jednej rzeczy: użycie mojego adresu do samodzielnego przeniesienia na L2 (0xeDc1...6909) i załączenie wiadomości tekstowej o „wymuszeniu włączenia”.
To jest transakcja L1, w której wykonuję funkcję depozytu Transakcji za pośrednictwem kontraktu OptimismPortal. Widać to w zdarzeniu Transakcja zdeponowana, które wyrzuca zarówno od, jak i do mnie.
Wartości w pozostałej nieprzezroczystej kolumnie Dane kodują „ile ETH przychodzi z osobą wywołującą funkcję Transakcji depozytowej”, „ile ETH inicjator transakcji L2 chce wysłać do odbiorcy”, „Transakcja L2 GasLimit” oraz „ do danych odbiorcy L2” i inne informacje.
Po rozszyfrowaniu powyższych informacji otrzymasz:
„Ile ETH załączyła osoba dzwoniąca do Transakcji depozytowej”: 0, ponieważ nie wpłaciłem ETH od L1 do L2;
„Ile ETH inicjator transakcji L2 chce wysłać do odbiorcy”: 5566 (wei)
„GasLimit dla transakcji L2”: 50000
„Dane dla odbiornika L2”: 0x666f72636520696e636c7573696f6e, czyli kodowanie szesnastkowe ciągu „wymuś włączenie”
Niedługo potem pojawiła się przekonwertowana transakcja L2: transakcja L2, w której przelałem sobie pieniądze, kwota wynosiła 5566 wei, a danymi był ciąg „force inclusion”. I możesz zauważyć, że TxnType (typ transakcji) w innych atrybutach w przedostatniej linii na obrazku pokazuje transakcję systemową 126 (System), co oznacza, że ta transakcja nie została zainicjowana przeze mnie w L2, ale została zdeponowana przez transakcję L1 Przekonwertowano z wydarzeń.
Przekonwertowana transakcja L2
Jeśli chcesz wywołać kontrakt L2 i przesłać inne dane poprzez Force Inclusion, to nic innego jak wpisanie parametrów po kolei do funkcji Transakcji poprzedniej wpłaty. Pamiętaj tylko, aby do dzwonienia użyć tego samego adresu L1, co Twoje konto L2 funkcję transakcji depozytowej, tak że gdy Zdarzenie zdeponowane zostanie przekształcone w transakcję L2, inicjatorem będzie Twoje konto L2.
Okno sekwencera
Wspomniany wcześniej węzeł Optymizmu L2 konwertuje zdarzenie Zdeponowane Transakcję na transakcję L2 W rzeczywistości ten węzeł Optymizmu odnosi się do Sekwencera. W końcu jest to związane z sekwencjonowaniem transakcji, więc tylko Sekwenser może zdecydować, kiedy przekonwertować wspomniane zdarzenie transakcję L2.
Podczas nasłuchiwania zdarzenia TransactionDeposited sekwencer niekoniecznie natychmiast konwertuje zdarzenie na transakcję L2. Maksymalna wartość tego okresu nazywa się SequencerWindow.
Bieżące okno sekwencera w głównej sieci Optimism trwa 24 godziny, co oznacza, że gdy użytkownik zdeponuje pewną sumę pieniędzy z poziomu L1 lub transakcji Force Zawiera, najgorszy scenariusz jest taki, że zostanie ona uwzględniona w historii transakcji L2 po 24 godzinach.
Mechanizm włączania siły Arbitrum
W Optymizmie operacja Depozyt w L1 wygeneruje zdarzenie Depozyt transakcji, a reszta polega na oczekiwaniu, aż sekwencer zbierze powyższe operacje; ale w Arbitrum operacje, które mają miejsce w L1 (oszczędzanie pieniędzy lub wysyłanie wiadomości do L2 itp.) .) będą przechowywane w L1 w kolejce, zamiast po prostu zgłaszać zdarzenie.
Sekwenser otrzyma pewien czas na włączenie transakcji z powyższej kolejki do historii transakcji L2. Jeśli Sekwenser nie zrobi nic w wyznaczonym czasie, każdy może wykonać tę czynność dla Sekwencera.
Arbitrum będzie utrzymywał Kolejkę w kontrakcie L1. Jeśli Sekwencer nie będzie aktywnie przetwarzał transakcji w Kolejce, po upływie wyznaczonego czasu każdy może wymusić włączenie transakcji z Kolejki do historii transakcji L2.
W projekcie Arbitrum operacje takie jak wpłaty dokonywane na L1 muszą przejść przez umowę Opóźnionej Skrzynki odbiorczej, jak sama nazwa wskazuje, operacje tutaj zostaną opóźnione, aby zaczęły obowiązywać; drugim kontraktem jest Skrzynka odbiorcza Sequencer, która jest bezpośrednim miejscem, w którym Sekwenser przesyła transakcje L2 do L1. Za każdym razem, gdy sekwencer przesyła transakcję L2, może pobrać niektóre oczekujące transakcje ze skrzynki odbiorczej z opóźnieniem i zapisać je w historii transakcji.
Kiedy Sequencer zapisuje nową transakcję, może pobrać transakcję z DelayedInbox i zapisać ją razem.
Skomplikowane projekty i obszerne materiały referencyjne
Jeśli czytelnicy bezpośrednio odwołują się do oficjalnego rozdziału Arbitrum na temat sekwencera i włączenia siły, zobaczą, że wspomina się w nim z grubsza o działaniu włączenia wymuszonego, a także niektóre nazwy parametrów i nazw funkcji:
Użytkownik najpierw udaje się do kontraktu DelayedInbox, aby wywołać funkcję sendUnsignedTransaction. Jeśli sekwencer nie zostanie dołączony w ciągu około 24 godzin, użytkownik może wywołać funkcję forceInclusion kontraktu SequencerInbox. Następnie urzędnik Arbitrum nie załączył linku do funkcji do dokumentu oficjalnej strony internetowej, więc możesz sam sprawdzić tylko odpowiednią funkcję w kodzie umowy.
Gdy znajdziesz funkcję sendUnsignedTransaction, okaże się, że musisz samodzielnie wpisać wartość jednorazową i wartość maxFeePerGas. Który adres to nonce? W jakiej sieci jest maxFeePerGas? Jak najlepiej go wypełnić? Nie ma odniesienia do pliku, nawet Natpsec. Następnie w kontrakcie Arbitrum znajdziesz również szereg podobnie wyglądających funkcji:
SendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction, nie ma dokumentu opisującego różnicę między tymi funkcjami, jak z nich korzystać, jak wypełnić parametry, nawet Natpsec.
Próbujesz wypełnić parametry i wysłać transakcję, myśląc, że spróbujesz. Chcesz zastosować metodę prób i błędów, aby sprawdzić, czy uda ci się znaleźć właściwe użycie, ale okazuje się, że wszystkie te funkcje wykonują AddressAliasing na twoim adresie L1. , co skutkuje końcowym błędem na L2. Nadawca przy inicjowaniu transakcji jest po prostu innym adresem, więc Twój adres L2 pozostaje nieruchomy.
wyślij wiadomość L2
Później przypadkowo kliknąłem wyszukiwarkę Google i dowiedziałem się, że Arbitrum posiada bibliotekę Tutorial, która zawiera skrypty demonstrujące, jak wysyłać transakcje L2 z L1 (co oznacza Force Inclusion), a funkcje w nim wymienione nie są żadną z funkcji wspomniany powyżej, ale funkcja o nazwie sendL2Message, a parametr komunikatu jest w rzeczywistości transakcją podpisaną za pomocą konta L2?
Kto by wiedział, że „wiadomość wysłana do L2 poprzez wymuszenie włączenia” będzie w rzeczywistości „podpisaną transakcją L2”? Nie ma też dokumentacji ani Natspec wyjaśniających, kiedy i jak używać tej funkcji.
Wniosek: Ręczne generowanie wymuszonej transakcji Arbitrum jest kłopotliwe. Zaleca się skorzystanie z oficjalnego samouczka i uruchomienie zestawu SDK Arbitrum. W przeciwieństwie do innych pakietów zbiorczych, Arbitrum ma przejrzystą dokumentację dla programistów i uwagi do kodu. Cel i parametry wielu funkcji nie są wyjaśnione, co powoduje, że programiści spędzają więcej czasu, niż oczekiwano, na dostępie i korzystaniu z nich. Zapytałem także ludzi Arbitrum na Discordzie Arbitrum, ale nie otrzymałem zadowalającej odpowiedzi.
Kiedy pytałem na Discordzie, druga strona kazała mi tylko zajrzeć do sendL2Message. Nie chciała wyjaśniać funkcji innych funkcji (nawet sendUnsignedTransaction wspomnianej w dokumencie Force Inclusion), do czego służą i jak z nich korzystać. i kiedy ich używać.
Mechanizm ForceInclusion firmy StarkNet
Niestety, StarkNet nie posiada obecnie mechanizmu ForceInclusion. Na oficjalnym forum są tylko dwa artykuły omawiające cenzurę i ForceInclusion.
Nie można udowodnić nieudanej transakcji
Powyższy powód jest w rzeczywistości taki, że system dowodu wiedzy zerowej StarkNet nie może udowodnić nieudanej transakcji, więc nie można zezwolić na wymuszenie włączenia. Ponieważ jeśli ktoś złośliwie (lub nieumyślnie) wymusi uwzględnienie nieudanej transakcji, której nie można udowodnić, StarkNet bezpośrednio utknie: ponieważ po wymuszeniu transakcji Prover musi udowodnić nieudaną transakcję, ale nie ma możliwości tego udowodnić.
StarkNet spodziewa się wprowadzenia funkcji potwierdzania nieudanych transakcji w wersji v0.15.0 i wtedy powinna być możliwa dalsza implementacja mechanizmu Force Inclusion.
Mechanizm ForceInclusion zkSync
Transmisja komunikatów L1->L2 w zkSync oraz mechanizm Force Inclusion są wykonywane poprzez funkcję requestL2Transaction kontraktu MailBox. Użytkownik określa adres L2, dane połączenia, dodatkową kwotę ETH, wartość L2GasLimit itp. requestL2Transaction połączy te parametry w L2. transakcja jest następnie umieszczana w kolejce priorytetowej (PriorityQueue). Kiedy transakcja jest pakowana i przesyłana do L1 (poprzez funkcję commitBatches), sekwencer wskaże, ile transakcji należy pobrać z kolejki priorytetowej i uwzględnić je w rekordzie transakcji L2. .
zkSync jest bardzo podobny do Optimism w formie Force Inclusion Wykorzystuje adres L2 inicjatora (zgodny z adresem L1) do wywoływania powiązanych funkcji i wypełniania danych (wywoływany, dane wywołania itp.), a nie jak Arbitrum Fill w podpisanej transakcji L2; ale projekt jest taki sam jak Arbitrum, oba utrzymują kolejkę w L1, a Sequencer pobiera oczekujące transakcje przesłane bezpośrednio przez użytkownika z Kolejki i zapisuje je w środku historii transakcji.
Jeśli przejdziesz do wpłaty ETH przez oficjalny most zkSync, na przykład w tej transakcji, wywoła ona funkcję requestL2Transaction kontraktu MailBox. Umieści transakcję L2 wpłaty ETH w kolejce priorytetowej i wygeneruje zdarzenie NewPriorityRequest. Ponieważ kontrakt koduje dane transakcji L2 w ciągu bajtów, jest to trudne do odczytania. Jeśli spojrzysz na parametry tej transakcji L1, zobaczysz, że odbiorca L2 w parametrach jest jednocześnie inicjatorem transakcji (. ponieważ jest zdeponowana na Twoim koncie), więc po chwili, gdy ta transakcja L2 zostanie wyjęta z kolejki priorytetowej przez Sequencer i uwzględniona w historii transakcji, zostanie ona przeliczona na transakcję przeniesioną do niej na L2, a kwota przelewem jest Depozyt inicjatora transakcji w L1 Kwota ETH przeniesiona w transakcji ETH.
W transakcji L1Deposit inicjator i odbiorca transakcji to 0xeDc1...6909, kwota wynosi 0,03ETH, a dane wywołania są puste.
Nastąpi transakcja o wartości 0xeDc1...6909 przekazująca pieniądze do Ciebie na L2. Typ transakcji (TxnType) to 255, co jest transakcją systemową.
Następnie bezpośrednio wywołałem funkcję requestL2Transaction w zkSync i wysłałem własny transfer, tak jak to zrobiłem wcześniej, kiedy eksperymentowałem z funkcją wymuszonej transakcji OP: bez żadnego ETH dane wywołania wprowadziły kodowanie HEX ciągu „wymuszonego włączenia”.
Następnie jest konwertowany na ostatnią transakcję L2. Dane wywołania to ciąg szesnastkowy „wymuszenia włączenia”: 0x666f72636520696e636c7573696f6e.
Kiedy sekwencer usunie transakcję z kolejki PriorityQueue i zapisze ją w historii transakcji, zostanie ona przekonwertowana na odpowiednią transakcję L2 na L2.
Dzięki funkcji requestL2Transaction użytkownicy mogą używać konta L1 z tym samym adresem L2 do przesyłania informacji w L1, określając odbiorcę L2, towarzyszącą mu kwotę ETH i dane połączenia. Jeżeli użytkownik chce wywołać inne kontrakty z innymi Danymi, robi to samo wpisując po kolei parametry do funkcji requestL2Transaction.
Nie ma funkcji, która pozwalałaby użytkownikom wymusić włączenie
Chociaż po umieszczeniu transakcji L2 w kolejce priorytetowej, okres oczekiwania na włączenie transakcji L2 do sekwencera zostanie obliczony przypadkowo. Jednakże bieżący projekt zkSync nie posiada funkcji wymuszania włączenia, którą użytkownicy mogliby wymusić odpowiednik tylko połowy zestawu. Oznacza to, że chociaż istnieje „okres oczekiwania na włączenie”, w rzeczywistości oznacza to „sprawdzenie, czy sekwencer chce otrzymać przychód”: sekwencer może poczekać do daty wygaśnięcia przed otrzymaniem transakcji lub nigdy nie może otrzymać żadnych transakcji w kolejce priorytetowej.
W przyszłości zkSync powinien dodać powiązane funkcje, aby użytkownicy mogli wymusić włączenie transakcji do historii transakcji L2, gdy minie okres ważności dochodu, ale nie zostanie uwzględniona w sekwencerze. Jest to naprawdę skuteczny mechanizm wymuszonego włączenia.
Podsumować
L1 opiera się na dużej liczbie walidatorów, aby zapewnić „bezpieczeństwo” i „odporność sieci na cenzurę”. Rollup używa niewielkiej liczby lub nawet jednego sekwencera do zapisywania transakcji, a jego odporność na cenzurę jest jeszcze słabsza. Dlatego Rollup potrzebuje mechanizmu Force Inclusion, który umożliwi użytkownikom ominięcie Sequencera i zapisanie transakcji w historii, aby uniknąć sprawdzenia przez Sequencer i uniemożliwienia wykorzystania i wypłaty środków z Rollupu.
Wymuś włączenie pozwala użytkownikom wymusić zapisanie transakcji w historii, ale w projekcie muszą wybrać, czy transakcję można natychmiast wstawić do historii i natychmiast zastosować. Jeśli transakcje zostaną wprowadzone natychmiast, będzie to miało negatywny wpływ na sekwencer, ponieważ na transakcje oczekujące na odbiór na L2 mogą mieć wpływ transakcje otrzymane siłą przez L1.
Dlatego obecny mechanizm Force Inclusion w Rollupie najpierw wprowadzi transakcje wstawione na L1 w stan oczekiwania i da sekwencerowi czas na reakcję i podjęcie decyzji, czy uwzględnić te oczekujące transakcje.
Zarówno zkSync, jak i Arbitrum utrzymują kolejkę Queue w L1 w celu zarządzania transakcjami L2 wysyłanymi przez użytkowników z L1 lub wiadomościami do L2. Arbitrum nazywa się DelayedInbox; zkSync nazywa się PriorityQueue
Jednakże sposób, w jaki zkSync wysyła transakcje L2, jest podobny do tego w Optimism. Używa adresu L2 do wysyłania wiadomości do L1. Po konwersji na transakcję L2, inicjatorem będzie adres L2. Funkcja Optimism do wysyłania transakcji L2 nazywa się depozytTransaction; zkSync nazywa się requestL2Transaction. Arbitrum generuje i podpisuje kompletną transakcję L2, a następnie wysyła ją poprzez funkcję sendL2Message. Arbitrum przywróci osobę podpisującą poprzez podpis na L2 jako inicjator transakcji L2.
StarkNet nie ma obecnie mechanizmu wymuszonego włączenia; zkSync jest jak połowa zestawu wymuszonego włączenia - istnieje kolejka priorytetów i każda transakcja L2 w kolejce ma okres ważności włączenia, ale ten okres ważności ma obecnie jedynie charakter dekoracyjny. Sekwenser może w ogóle nie uwzględniać żadnych transakcji L2 w kolejce priorytetowej