Baru kemarin, peristiwa mengejutkan terjadi: Linea, solusi Ethereum Layer 2 yang dikembangkan oleh Consensys, perusahaan induk Metamask, ditutup secara proaktif. Alasan resmi yang diberikan adalah untuk mengurangi dampak insiden peretasan Velocore. Kejadian ini pasti mengingatkan pada kasus sebelumnya di mana rantai BSC (BNB Chain) juga ditutup di bawah koordinasi resmi untuk meminimalkan kerugian peretasan. Peristiwa ini sering membuat orang mempertanyakan nilai-nilai terdesentralisasi yang didukung Web3.
Alasan utama di balik peristiwa tersebut terletak pada ketidaksempurnaan infrastruktur, khususnya kurangnya desentralisasi. Jika blockchain cukup terdesentralisasi, seharusnya tidak dapat ditutup dengan mudah. Karena struktur Ethereum Layer 2 yang unik, sebagian besar solusi Layer 2 mengandalkan sequencer terpusat. Terlepas dari wacana yang berkembang tentang sequencer terdesentralisasi dalam beberapa tahun terakhir, mengingat tujuan dan struktur Layer 2, kita dapat mengasumsikan bahwa sequencer Layer 2 tidak mungkin mencapai tingkat desentralisasi yang tinggi. Bahkan, mereka mungkin berakhir menjadi kurang terdesentralisasi daripada rantai BSC. Jika ini masalahnya, apa yang bisa dilakukan? Bagi Layer 2, risiko paling cepat dari sequencer yang tidak terdesentralisasi adalah kurangnya resistensi pensensoran dan kehidupan. Jika hanya ada beberapa entitas yang memproses transaksi (sequencer), mereka memiliki kekuasaan mutlak atas apakah akan melayani Anda atau tidak: mereka dapat menolak transaksi Anda sesuka hati, meninggalkan Anda tanpa bantuan. Mengatasi masalah resistensi pensensoran di Layer 2 jelas merupakan topik penting. Selama beberapa tahun terakhir, berbagai solusi Ethereum Layer 2 telah mengusulkan pendekatan yang berbeda untuk mengatasi masalah ini. Misalnya, Loopring, Degate, dan StarkEx telah memperkenalkan fungsi penarikan paksa dan escape hatch, sementara Arbitrum dan Optimistic Rollups lainnya telah menerapkan fitur Force Inclusion. Mekanisme ini dapat memaksakan pemeriksaan pada sequencer untuk mencegah penolakan transaksi pengguna secara sewenang-wenang. Dalam artikel hari ini, NIC Lin dari Asosiasi Ethereum Taipei berbagi pengalaman langsungnya, bereksperimen dengan fitur transaksi tahan sensor dari empat Rollup utama dan memberikan analisis mendalam tentang mekanisme Force Inclusion, dengan fokus pada alur kerja dan metode operasional. Analisis ini sangat berharga bagi komunitas Ethereum dan pemegang aset besar.
Censorship resistensi dalam transaksi sangat penting untuk blockchain apa pun. Jika blockchain dapat secara sewenang-wenang menyensor dan menolak transaksi pengguna, itu tidak berbeda dengan server Web2. resistensi pensensoran transaksi Ethereum saat ini dipastikan dengan banyaknya validator. Jika seseorang ingin menyensor transaksi Bob dan mencegahnya dimasukkan ke dalam blockchain, mereka harus menyuap sebagian besar validator jaringan atau mengirim spam ke jaringan dengan transaksi sampah yang memiliki biaya lebih tinggi daripada Bob, sehingga menempati ruang blok. Kedua metode ini sangat mahal.
Catatan: Dalam arsitektur Proposer-Builder Separation (PBS) Ethereum saat ini, biaya penyensoran transaksi berkurang secara signifikan. Misalnya, Anda dapat melihat proporsi blok yang mematuhi sensor OFAC terhadap transaksi Tornado Cash. resistensi pensensoran saat ini bergantung pada validator dan relai independen yang berada di luar yurisdiksi OFAC dan entitas pemerintah lainnya.
Tapi bagaimana dengan Rollups? Rollup tidak memerlukan validator dalam jumlah besar untuk memastikan keamanan. Bahkan jika Rollup hanya memiliki satu entitas terpusat (Sequencer) yang menghasilkan blok, itu tetap seaman Layer 1 (L1). Namun, keamanan dan resistensi pensensoran adalah dua hal yang berbeda. Rollup, meskipun seaman Ethereum, masih dapat menyensor transaksi pengguna mana pun jika hanya memiliki sequencer terpusat tunggal.
Sequencer dapat menolak untuk memproses transaksi pengguna, sehingga dana pengguna terkunci dan tidak dapat meninggalkan Rollup.
mengharuskan Rollups memiliki sejumlah besar sequencer terdesentralisasi, lebih efektif untuk secara langsung memanfaatkan resistensi pensensoran Layer 1 (L1):
Karena sequencer perlu mengemas data transaksi dan mengirimkannya ke kontrak Rollup di L1, kita dapat menambahkan fitur dalam kontrak yang memungkinkan pengguna untuk memasukkan transaksi mereka ke dalam kontrak Rollup itu sendiri. Mekanisme ini dikenal sebagai "Force Inclusion." Sebagai long sequencer tidak dapat menyensor pengguna di tingkat L1, itu tidak dapat mencegah pengguna memasukkan transaksi secara paksa di L1. Dengan cara ini, Rollup dapat mewarisi resistensi pensensoran L1.
Sequencer tidak dapat meninjau transaksi L1 pengguna tanpa membayar biaya tinggi
Jika transaksi diizinkan untuk langsung ditulis ke dalam kontrak Rollup melalui Force Inclusion (artinya transaksi berlaku segera), status Rollup akan berubah secara instan. Misalnya, jika Bob menggunakan mekanisme Force Inclusion untuk memasukkan transaksi yang mentransfer 1000 DAI ke Carol, dan transaksi segera berlaku, saldo Bob akan berkurang 1000 DAI, sedangkan saldo Carol akan meningkat 1000 DAI dalam keadaan diperbarui.
Jika Force Inclusion memungkinkan transaksi untuk langsung ditulis ke dalam kontrak Rollup dan berlaku segera, status Rollup akan berubah secara instan. Jika sequencer secara bersamaan mengumpulkan transaksi off-chain dan bersiap untuk mengirim batch berikutnya ke kontrak Rollup, itu bisa terganggu oleh transaksi Bob yang dimasukkan secara paksa yang segera berlaku. Untuk menghindari masalah ini, Rollup umumnya tidak memungkinkan transaksi Force Inclusion berlaku segera. Sebaliknya, pengguna awalnya memasukkan transaksi mereka ke dalam antrian menunggu di L1, di mana mereka memasuki status "persiapan". Ketika paket sequencer off-chain transaksi untuk dikirim ke kontrak Rollup, ia dapat memilih apakah akan menyertakan transaksi antrian ini. Jika sequencer terus-menerus mengabaikan transaksi dalam status "persiapan", setelah periode jendela berakhir, pengguna dapat secara paksa memasukkan transaksi ini ke dalam kontrak Rollup. Sequencer dapat memutuskan kapan harus "secara kebetulan memasukkan" transaksi dari antrian tunggu, tetapi masih dapat menolak untuk memprosesnya. Jika sequencer secara konsisten menolak, setelah jangka waktu tertentu, siapa pun dapat menggunakan fungsi Force Inclusion untuk memasukkan transaksi secara paksa ke dalam kontrak Rollup. Selanjutnya, kami akan memperkenalkan implementasi mekanisme Force Inclusion dalam empat Rollup terkemuka: Optimisme, Arbitrum, StarkNet, dan zkSync.
Sequencer dapat memilih kapan harus mendapatkan transaksi dari antrian tunggu.
Sequencer masih dapat menolak untuk memproses transaksi dalam antrian tunggu.
Jika sequencer secara konsisten menolak untuk memproses transaksi, setelah jangka waktu tertentu, siapa pun dapat menggunakan fungsi Force Inclusion untuk memasukkan transaksi secara paksa ke dalam kontrak Rollup. Selanjutnya, kami akan memperkenalkan bagaimana mekanisme Force Inclusion diimplementasikan dalam empat Rollup terkemuka: Optimisme, Arbitrum, StarkNet, dan zkSync.
Pertama, mari kita bahas proses Deposit Optimisme. Proses Deposit ini melibatkan tidak hanya mentransfer dana ke Optimisme tetapi juga mengirim "pesan pengguna ke L2." Ketika node L2 menerima pesan yang baru disimpan, ia mengubah pesan menjadi transaksi L2 dan mengeksekusinya, mengirimkannya ke penerima yang ditentukan.
Pesan Pengguna yang Disetorkan dari L1 ke L2
Kontrak L1CrossDomainMessenger
Ketika pengguna ingin setor ETH atau ERC-20 token ke dalam Optimisme, mereka berinteraksi dengan kontrak L1StandardBridge di L1 melalui halaman web frontend, menentukan jumlah yang akan setor dan alamat L2 yang akan menerima aset ini. Kontrak L1StandardBridge kemudian meneruskan pesan ke kontrak L1CrossDomainMessenger, yang bertindak sebagai bridge komunikasi utama antara L1 dan L2. L1StandardBridge menggunakan komponen komunikasi ini untuk berinteraksi dengan L2StandardBridge di L2, menentukan siapa yang dapat cetak token di L2 atau membuka kunci token dari L1. Pengembang yang perlu membuat kontrak yang saling mengoperasikan dan menyinkronkan status antara L1 dan L2 dapat membangunnya di atas kontrak L1CrossDomainMessenger.
Pesan Pengguna yang Ditransmisikan dari L1 ke L2 melalui Kontrak CrossDomainMessenger
Catatan: Dalam beberapa gambar dalam artikel ini, CrossDomainMessenger ditulis sebagai CrossChainMessenger.
Kontrak OptimismPortal
Kontrak L1CrossDomainMessenger kemudian meneruskan pesan ke lapisan terendah, kontrak OptimismPortal. Setelah memproses pesan, kontrak OptimismPortal memancarkan peristiwa yang disebut TransactionDeposited, yang mencakup parameter seperti "pengirim", "penerima", dan detail eksekusi relevan lainnya. Node Optimisme pada L2 mendengarkan peristiwa TransactionDeposited ini dari kontrak OptimismPortal dan mengubah parameter peristiwa menjadi transaksi L2. Pemrakarsa transaksi ini akan menjadi "pengirim" yang ditentukan dalam acara, penerima akan menjadi "penerima" yang disebutkan dalam acara tersebut, dan detail transaksi lainnya juga akan diturunkan dari parameter acara.
L2 node mengubah parameter peristiwa Deposit Transaksi yang dipancarkan oleh OptimismPortal menjadi transaksi L2.
Misalnya, ketika pengguna menyetor 0,01 ETH melalui kontrak L1StandardBridge, pesan dan ETH dikirimkan ke kontrak OptimismPortal (alamat 0xbEb5... 06Ed). Beberapa menit kemudian, ini diubah menjadi transaksi L2: pengirim pesan adalah kontrak L1CrossDomainMessenger, penerima adalah kontrak L2CrossDomainMessenger di L2, dan konten pesan menunjukkan bahwa L1StandardBridge menerima ETH setor 0,01 dari Bob. Ini kemudian memicu proses tambahan, seperti pencetakan 0,01 ETH untuk L2StandardBridge, yang kemudian mentransfernya ke Bob.
Cara memicunya
Jika Anda ingin secara paksa memasukkan transaksi dalam kontrak Rollup Optimisme, tujuan Anda adalah untuk memastikan bahwa transaksi "dimulai dan dieksekusi dari alamat L2 Anda di L2" dapat berhasil dijalankan. Untuk mencapai hal ini, Anda harus mengirimkan pesan langsung ke kontrak OptimismPortal menggunakan alamat L2 Anda (perhatikan bahwa kontrak OptimismPortal sebenarnya ada di L1, tetapi format alamat OP cocok dengan format alamat L1, sehingga Anda dapat memanggil kontrak ini menggunakan akun L1 dengan alamat yang sama dengan akun L2 Anda). "Pengirim" transaksi L2 yang berasal dari peristiwa Deposit Transaksi yang dipancarkan oleh kontrak ini kemudian akan menjadi akun L2 Anda, dan format transaksi akan konsisten dengan transaksi L2 standar.
Dalam transaksi L2 yang berasal dari peristiwa Transaksi yang Disetorkan, Bob sendiri yang akan menjadi pemrakarsa; penerima akan menjadi kontrak Uniswap; dan itu akan mencakup ETH yang ditentukan, seolah-olah Bob memulai transaksi L2 sendiri.
Untuk menggunakan fungsi Force Inclusion Optimism, Anda perlu langsung memanggil fungsi depositTransaction dari kontrak OptimismPortal dan memasukkan parameter transaksi yang ingin Anda jalankan di L2. Saya melakukan eksperimen Force Inclusion sederhana. Tujuan dari transaksi ini adalah untuk melakukan transfer mandiri di L2 menggunakan alamat saya (0xeDc1... 6909) dan menyertakan pesan yang mengatakan "inklusi paksa." Ini adalah transaksi L1 yang saya lakukan dengan memanggil fungsi depositTransaction melalui kontrak OptimismPortal. Seperti yang dapat Anda lihat dari peristiwa Transaksi yang Ditransmisikan yang dipancarkannya, pengirim dan penerima adalah saya sendiri.
Nilai yang tersisa di kolom Data buram menyandikan informasi seperti "berapa banyak ETH orang yang memanggil fungsi depositTransaction terlampir," "berapa banyak ETH yang ingin dikirim oleh inisiator transaksi L2 ke penerima," "GasLimit transaksi L2," dan "Data untuk penerima L2." Setelah mendekode informasi ini, Anda akan mendapatkan detail berikut: "berapa ETH orang yang memanggil depositTransaction terlampir": 0, karena saya tidak menyetor ETH dari L1 ke L2; "berapa banyak ETH yang ingin dikirim oleh pemrakarsa transaksi L2 ke penerima": 5566 (wei); "L2 transaksi GasLimit": 50000; "Data untuk penerima L2": 0x666f72636520696e636c7573696f6e, yang merupakan pengkodean heksadesimal dari string "inklusi gaya." Tak lama setelah itu, transaksi L2 yang dikonversi muncul: transaksi L2 di mana saya mentransfer 5566 wei ke diri saya sendiri, dengan bidang Data berisi string "force inclusion." Selain itu, di baris kedua hingga terakhir dari bagian Atribut Lainnya, TxnType (jenis transaksi) ditampilkan sebagai transaksi sistem 126 (Sistem), yang menunjukkan bahwa transaksi ini tidak dimulai oleh saya di L2 tetapi dikonversi dari peristiwa Deposit dari transaksi L1.
Transaksi L2 yang dikonversi
Jika Anda ingin memanggil kontrak L2 melalui Force Inclusion dan mengirim Data yang berbeda, Anda hanya perlu mengisi parameter dalam fungsi depositTransaction. Ingatlah untuk menggunakan alamat L1 yang sama dengan akun L2 Anda saat memanggil fungsi depositTransaction. Dengan cara ini, ketika Peristiwa yang Disetorkan diubah menjadi transaksi L2, inisiatornya adalah akun L2 Anda. Jendela Sequencer Simpul Optimisme L2 yang mengubah peristiwa Transaksi yang Disetorkan menjadi transaksi L2 sebenarnya adalah Sequencer. Karena ini melibatkan pemesanan transaksi, hanya Sequencer yang dapat memutuskan kapan harus mengubah acara menjadi transaksi L2. Ketika Sequencer mendengarkan peristiwa TransactionDeposited, itu tidak selalu mengubah peristiwa menjadi transaksi L2 segera; Mungkin ada penundaan. Durasi maksimum penundaan ini disebut Sequencer Window. Saat ini, Jendela Sequencer di mainnet Optimism adalah 24 jam. Ini berarti bahwa ketika pengguna menyetor uang dari L1 atau menggunakan Force Inclusion untuk transaksi, dalam skenario terburuk, itu akan dimasukkan dalam riwayat transaksi L2 setelah 24 jam.
Dalam Optimisme, operasi setor L1 memicu peristiwa Transaksi yang Disimpan, dan kemudian hanya masalah menunggu Sequencer untuk memasukkan operasi. Namun, di Arbitrum, operasi pada L1 (seperti menyetor dana atau mengirim pesan ke L2) disimpan dalam antrian di L1, bukan hanya memancarkan peristiwa. Sequencer memiliki periode tertentu untuk memasukkan transaksi antrian ini ke dalam riwayat transaksi L2. Jika Sequencer gagal melakukannya dalam jangka waktu ini, siapa pun dapat masuk untuk menyelesaikan penyertaan atas nama Sequencer.
Arbitrum mempertahankan Antrian dalam kontrak L1. Jika Sequencer gagal memproses transaksi dalam Antrian dalam periode tertentu, siapa pun dapat secara paksa memasukkan transaksi ini ke dalam riwayat transaksi L2. Dalam desain Arbitrum, operasi pada L1, seperti deposito, harus melalui kontrak Kotak Masuk Tertunda, di mana, seperti namanya, operasi ini akan ditunda sebelum berlaku. Kontrak lain, Kotak Masuk Sequencer, adalah tempat Sequencer secara langsung mengunggah transaksi L2 ke L1. Setiap kali Sequencer mengunggah transaksi L2, Sequencer juga dapat mengambil beberapa transaksi tertunda dari Kotak Masuk Tertunda dan memasukkannya ke dalam riwayat transaksi.
Saat Sequencer menulis transaksi baru, Sequencer juga dapat menyertakan transaksi dari DelayedInbox.
Desain Kompleks dan Kurangnya Bahan Referensi
Jika Anda merujuk ke dokumentasi resmi Arbitrum tentang Sequencer dan Force Inclusion, Anda akan menemukan penjelasan umum tentang cara kerja Force Inclusion, bersama dengan beberapa parameter dan nama fungsi: Pengguna pertama-tama memanggil fungsi sendUnsignedTransaction pada kontrak DelayedInbox. Jika Sequencer tidak menyertakannya dalam waktu sekitar 24 jam, pengguna dapat memanggil fungsi forceInclusion pada kontrak SequencerInbox. Namun, dokumentasi resmi tidak menyediakan tautan ke fungsi-fungsi ini, jadi Anda harus mencarinya sendiri di kode kontrak. Ketika Anda menemukan fungsi sendUnsignedTransaction, Anda menyadari bahwa Anda harus mengisi nilai nonce dan nilai maxFeePerGas sendiri. nonce siapa itu? MaxFeePerGas jaringan mana? Bagaimana seharusnya Anda mengisinya dengan benar? Tidak ada dokumen referensi, bahkan NatSpec. Anda juga akan menemukan banyak fungsi serupa dalam kontrak Arbitrum: sendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction. Tidak ada dokumen yang menjelaskan perbedaan antara fungsi-fungsi ini, cara menggunakannya, atau cara mengisi parameter, bahkan NatSpec.
Anda mencoba mengisi parameter dan mengirimkan transaksi dengan pendekatan trial-and-error, berharap menemukan penggunaan yang benar. Namun, Anda menemukan bahwa semua fungsi ini berlaku Alamat Aliasing ke alamat L1 Anda, menyebabkan Pengirim transaksi di L2 menjadi alamat yang sama sekali berbeda, meninggalkan alamat L2 Anda tidak aktif. Kemudian, Anda secara tidak sengaja menemukan hasil pencarian Google yang mengungkapkan bahwa Arbitrum memiliki perpustakaan Tutorial dengan skrip yang menunjukkan cara mengirim transaksi L2 dari L1 (pada dasarnya Force Inclusion). Tutorial mencantumkan fungsi yang tidak disebutkan sebelumnya: sendL2Message. Anehnya, parameter pesan yang diperlukan sebenarnya adalah transaksi L2 yang ditandatangani menggunakan akun L2. Siapa yang tahu bahwa "pesan yang dikirim ke L2 melalui Force Inclusion" sebenarnya adalah "transaksi L2 yang ditandatangani"? Selain itu, tidak ada dokumen atau NatSpec yang menjelaskan kapan dan bagaimana menggunakan fungsi ini.
Kesimpulan: Menghasilkan transaksi paksa secara manual di Arbitrum cukup rumit. Disarankan untuk mengikuti Tutorial resmi dan menggunakan SDK Arbitrum. Tidak seperti Rollup lainnya, Arbitrum tidak memiliki dokumentasi pengembang dan anotasi kode yang jelas. Banyak fungsi tidak memiliki penjelasan untuk tujuan dan parameternya, menyebabkan pengembang menghabiskan lebih banyak waktu daripada yang diharapkan untuk mengintegrasikan dan menggunakannya. Saya juga meminta bantuan dalam Perselisihan Arbitrum, tetapi tidak menerima jawaban yang memuaskan. Saat bertanya di Discord, mereka hanya mengarahkan saya untuk melihat sendL2Message dan tidak menjelaskan fungsi metode lain (termasuk yang disebutkan dalam dokumentasi Force Inclusion seperti sendUnsignedTransaction), tujuannya, cara menggunakannya, atau kapan menggunakannya.
Sayangnya, StarkNet saat ini tidak memiliki mekanisme Force Inclusion. Hanya ada dua artikel di forum resmi yang membahas Sensor dan Inklusi Paksa. Alasan ketidakmampuan untuk membuktikan transaksi yang gagal adalah bahwa sistem bukti tanpa pengetahuan StarkNet tidak dapat membuktikan transaksi yang gagal, sehingga Force Inclusion tidak dapat diizinkan. Jika seseorang dengan jahat (atau tidak sengaja) Memaksa Termasuk transaksi yang gagal dan tidak dapat dibuktikan, StarkNet akan terjebak: karena begitu transaksi dimasukkan secara paksa, Prover harus membuktikan transaksi yang gagal, tetapi tidak bisa. StarkNet diharapkan untuk memperkenalkan kemampuan untuk membuktikan transaksi gagal dalam versi v0.15.0, setelah itu mekanisme Force Inclusion harus diterapkan lebih lanjut.
Mekanisme zkSync untuk transmisi pesan L1->L2 dan Force Inclusion ditangani melalui fungsi requestL2Transaction dari kontrak MailBox. Pengguna menentukan alamat L2, calldata, jumlah ETH yang akan dilampirkan, nilai L2GasLimit, dan detail lainnya. Fungsi requestL2Transaction menggabungkan parameter ini ke dalam transaksi L2 dan menempatkannya ke dalam PriorityQueue. Ketika Sequencer mengemas transaksi dan mengunggahnya ke L1 (melalui fungsi commitBatches), ini menunjukkan berapa banyak transaksi yang harus diambil dari PriorityQueue untuk disertakan dalam catatan transaksi L2. Dalam hal Force Inclusion, zkSync mirip dengan Optimisme, di mana alamat L2 inisiator (sama dengan alamat L1) digunakan untuk memanggil fungsi yang relevan dan mengisi detail yang diperlukan (callee, calldata, dll.), Daripada seperti Arbitrum, yang membutuhkan transaksi L2 yang ditandatangani. Namun, dalam desain, ini mirip dengan Arbitrum, karena keduanya mempertahankan antrian di L1, dan Sequencer mengambil transaksi tertunda yang dikirimkan langsung oleh pengguna dari Antrian dan menuliskannya ke dalam riwayat transaksi.
Jika Anda setor ETH melalui bridge resmi zkSync, seperti transaksi ini, ia memanggil fungsi requestL2Transaction dari kontrak MailBox. Fungsi ini menempatkan transaksi Deposit ETH L2 ke dalam PriorityQueue dan memancarkan peristiwa NewPriorityRequest. Karena kontrak mengkodekan data transaksi L2 menjadi string byte, itu tidak mudah dibaca. Namun, jika Anda melihat parameter transaksi L1 ini, Anda akan melihat bahwa penerima L2 juga merupakan pemrakarsa transaksi (karena ini adalah setor untuk diri sendiri). Setelah beberapa waktu, ketika Sequencer mengeluarkan transaksi L2 ini dari PriorityQueue dan memasukkannya ke dalam riwayat transaksi, itu akan diubah menjadi transaksi L2 tempat Anda mentransfer ke diri Anda sendiri. Jumlah transfer akan menjadi jumlah ETH yang dilampirkan oleh pemrakarsa dalam transaksi ETH Setoran L1. Dalam transaksi Deposito L1, baik pemrakarsa maupun penerima 0xeDc1... 6909, jumlahnya 0,03 ETH, dan tidak ada calldata. Di L2, akan ada transaksi di mana 0xeDc1... 6909 transfer ke dirinya sendiri. Jenis transaksi (TxnType) adalah 255, menunjukkan transaksi sistem. Kemudian, seperti saya bereksperimen dengan fungsi transaksi paksa pada Optimisme sebelumnya, saya memanggil fungsi requestL2Transaction zkSync dan memulai transaksi transfer mandiri: tidak ada ETH yang dilampirkan, dan calldata berisi pengkodean HEX dari string "force inclusion." Ini kemudian diubah menjadi transaksi L2 di mana saya mentransfer ke diri saya sendiri, dengan calldata yang berisi string heksadesimal untuk "force inclusion": 0x666f72636520696e636c7573696f6e. Ketika Sequencer mengambil transaksi dari PriorityQueue dan menuliskannya ke dalam riwayat transaksi, transaksi tersebut diubah menjadi transaksi L2 yang sesuai. Dengan menggunakan fungsi requestL2Transaction, pengguna dapat mengirimkan data pada L1 dengan akun L1 yang sama dengan alamat L2 mereka, menentukan penerima L2, jumlah ETH yang akan dilampirkan, dan calldata. Jika pengguna ingin memanggil kontrak lain atau menyertakan Data yang berbeda, mereka hanya perlu mengisi parameter dalam fungsi requestL2Transaction. Belum ada fungsi Force Inclusion untuk pengguna Meskipun transaksi L2 yang ditempatkan di PriorityQueue akan memiliki masa tunggu yang dihitung untuk dimasukkan oleh Sequencer, desain zkSync saat ini tidak memiliki fungsi Force Inclusion yang memungkinkan pengguna untuk menegakkannya. Ini berarti hanya solusi parsial. Meskipun ada "masa tunggu untuk dimasukkan," pada akhirnya tergantung pada apakah Sequencer memutuskan untuk memasukkannya: Sequencer dapat memasukkannya setelah periode berakhir atau tidak pernah menyertakan transaksi apa pun dari PriorityQueue. Di masa depan, zkSync harus menambahkan fungsi yang memungkinkan pengguna untuk secara paksa memasukkan transaksi ke dalam riwayat transaksi L2 jika mereka belum dimasukkan oleh Sequencer setelah masa tunggu. Ini akan menjadi mekanisme Force Inclusion yang benar-benar efektif. Ringkas
L1 bergantung pada sejumlah besar validator untuk memastikan "keamanan" dan "resistensi pensensoran" jaringan. Rollup, bagaimanapun, memiliki resistensi pensensoran yang lebih lemah karena transaksi ditulis oleh beberapa atau bahkan satu Sequencer. Oleh karena itu, Rollup memerlukan mekanisme Force Inclusion untuk memungkinkan pengguna melewati Sequencer dan menulis transaksi ke dalam riwayat, mencegah sensor oleh Sequencer membuat Rollup tidak dapat digunakan dan mencegah pengguna menarik dana. Force Inclusion memungkinkan pengguna untuk secara paksa menulis transaksi ke dalam riwayat, tetapi desain harus memilih apakah "transaksi dapat segera dimasukkan ke dalam riwayat dan segera berlaku." Jika efek langsung diizinkan, itu akan berdampak negatif pada Sequencer karena transaksi yang tertunda pada L2 dapat dipengaruhi oleh transaksi yang dimasukkan secara paksa dari L1. Oleh karena itu, mekanisme Force Inclusion saat ini dalam Rollups pertama-tama menempatkan transaksi yang dimasukkan dari L1 ke dalam keadaan menunggu dan memberi Sequencer jendela waktu untuk bereaksi dan memutuskan apakah akan memasukkan transaksi yang tertunda ini. zkSync dan Arbitrum keduanya mempertahankan antrian di L1 untuk mengelola transaksi L2 atau pesan yang dikirim dari L1 ke L2. Arbitrum menyebutnya DelayedInbox; zkSync menyebutnya PriorityQueue. Namun, metode pengiriman transaksi L2 zkSync lebih mirip dengan Optimisme, di mana pesan dikirim dari L1 menggunakan alamat L2, sehingga ketika dikonversi ke transaksi L2, inisiatornya adalah alamat L2. Fungsi untuk mengirim transaksi L2 di Optimism disebut depositTransaction; di zkSync, ini disebut requestL2Transaction. Sebaliknya, Arbitrum menghasilkan transaksi L2 lengkap dan menandatanganinya, lalu mengirimkannya melalui fungsi sendL2Message. Pada L2, Arbitrum menggunakan tanda tangan untuk mengembalikan penandatangan sebagai pemrakarsa transaksi L2. StarkNet saat ini tidak memiliki mekanisme Force Inclusion; zkSync memiliki mekanisme Force Inclusion yang setengah diimplementasikan — ia memiliki PriorityQueue, dan setiap transaksi L2 dalam Queue memiliki periode validitas inklusi, tetapi periode validitas ini saat ini hanya untuk pertunjukan. Dalam praktiknya, Sequencer dapat memilih untuk tidak menyertakan transaksi L2 apa pun dari PriorityQueue.
Artikel ini diteruskan dari: [Geek Web3], judul aslinya adalah "Theory and Practice: How to trigger censorship-resistant transactions in Ethereum Rollup?", atribusi hak cipta kepada penulis asli [NIC Lin, Head of Taipei Ethereum Meetup], jika Anda keberatan dengan cetak ulang, silakan hubungi Tim Gate Learn, tim akan menanganinya sesegera mungkin sesuai prosedur yang relevan.
Penafian: Pandangan dan pendapat yang diungkapkan dalam artikel ini hanya mewakili pandangan pribadi penulis dan bukan merupakan saran investasi.
Versi bahasa lain dari artikel ini diterjemahkan oleh tim Gate Learn. Tanpa merujuk Gate.io, menyalin, mendistribusikan, atau menjiplak artikel terjemahan dilarang.
Baru kemarin, peristiwa mengejutkan terjadi: Linea, solusi Ethereum Layer 2 yang dikembangkan oleh Consensys, perusahaan induk Metamask, ditutup secara proaktif. Alasan resmi yang diberikan adalah untuk mengurangi dampak insiden peretasan Velocore. Kejadian ini pasti mengingatkan pada kasus sebelumnya di mana rantai BSC (BNB Chain) juga ditutup di bawah koordinasi resmi untuk meminimalkan kerugian peretasan. Peristiwa ini sering membuat orang mempertanyakan nilai-nilai terdesentralisasi yang didukung Web3.
Alasan utama di balik peristiwa tersebut terletak pada ketidaksempurnaan infrastruktur, khususnya kurangnya desentralisasi. Jika blockchain cukup terdesentralisasi, seharusnya tidak dapat ditutup dengan mudah. Karena struktur Ethereum Layer 2 yang unik, sebagian besar solusi Layer 2 mengandalkan sequencer terpusat. Terlepas dari wacana yang berkembang tentang sequencer terdesentralisasi dalam beberapa tahun terakhir, mengingat tujuan dan struktur Layer 2, kita dapat mengasumsikan bahwa sequencer Layer 2 tidak mungkin mencapai tingkat desentralisasi yang tinggi. Bahkan, mereka mungkin berakhir menjadi kurang terdesentralisasi daripada rantai BSC. Jika ini masalahnya, apa yang bisa dilakukan? Bagi Layer 2, risiko paling cepat dari sequencer yang tidak terdesentralisasi adalah kurangnya resistensi pensensoran dan kehidupan. Jika hanya ada beberapa entitas yang memproses transaksi (sequencer), mereka memiliki kekuasaan mutlak atas apakah akan melayani Anda atau tidak: mereka dapat menolak transaksi Anda sesuka hati, meninggalkan Anda tanpa bantuan. Mengatasi masalah resistensi pensensoran di Layer 2 jelas merupakan topik penting. Selama beberapa tahun terakhir, berbagai solusi Ethereum Layer 2 telah mengusulkan pendekatan yang berbeda untuk mengatasi masalah ini. Misalnya, Loopring, Degate, dan StarkEx telah memperkenalkan fungsi penarikan paksa dan escape hatch, sementara Arbitrum dan Optimistic Rollups lainnya telah menerapkan fitur Force Inclusion. Mekanisme ini dapat memaksakan pemeriksaan pada sequencer untuk mencegah penolakan transaksi pengguna secara sewenang-wenang. Dalam artikel hari ini, NIC Lin dari Asosiasi Ethereum Taipei berbagi pengalaman langsungnya, bereksperimen dengan fitur transaksi tahan sensor dari empat Rollup utama dan memberikan analisis mendalam tentang mekanisme Force Inclusion, dengan fokus pada alur kerja dan metode operasional. Analisis ini sangat berharga bagi komunitas Ethereum dan pemegang aset besar.
Censorship resistensi dalam transaksi sangat penting untuk blockchain apa pun. Jika blockchain dapat secara sewenang-wenang menyensor dan menolak transaksi pengguna, itu tidak berbeda dengan server Web2. resistensi pensensoran transaksi Ethereum saat ini dipastikan dengan banyaknya validator. Jika seseorang ingin menyensor transaksi Bob dan mencegahnya dimasukkan ke dalam blockchain, mereka harus menyuap sebagian besar validator jaringan atau mengirim spam ke jaringan dengan transaksi sampah yang memiliki biaya lebih tinggi daripada Bob, sehingga menempati ruang blok. Kedua metode ini sangat mahal.
Catatan: Dalam arsitektur Proposer-Builder Separation (PBS) Ethereum saat ini, biaya penyensoran transaksi berkurang secara signifikan. Misalnya, Anda dapat melihat proporsi blok yang mematuhi sensor OFAC terhadap transaksi Tornado Cash. resistensi pensensoran saat ini bergantung pada validator dan relai independen yang berada di luar yurisdiksi OFAC dan entitas pemerintah lainnya.
Tapi bagaimana dengan Rollups? Rollup tidak memerlukan validator dalam jumlah besar untuk memastikan keamanan. Bahkan jika Rollup hanya memiliki satu entitas terpusat (Sequencer) yang menghasilkan blok, itu tetap seaman Layer 1 (L1). Namun, keamanan dan resistensi pensensoran adalah dua hal yang berbeda. Rollup, meskipun seaman Ethereum, masih dapat menyensor transaksi pengguna mana pun jika hanya memiliki sequencer terpusat tunggal.
Sequencer dapat menolak untuk memproses transaksi pengguna, sehingga dana pengguna terkunci dan tidak dapat meninggalkan Rollup.
mengharuskan Rollups memiliki sejumlah besar sequencer terdesentralisasi, lebih efektif untuk secara langsung memanfaatkan resistensi pensensoran Layer 1 (L1):
Karena sequencer perlu mengemas data transaksi dan mengirimkannya ke kontrak Rollup di L1, kita dapat menambahkan fitur dalam kontrak yang memungkinkan pengguna untuk memasukkan transaksi mereka ke dalam kontrak Rollup itu sendiri. Mekanisme ini dikenal sebagai "Force Inclusion." Sebagai long sequencer tidak dapat menyensor pengguna di tingkat L1, itu tidak dapat mencegah pengguna memasukkan transaksi secara paksa di L1. Dengan cara ini, Rollup dapat mewarisi resistensi pensensoran L1.
Sequencer tidak dapat meninjau transaksi L1 pengguna tanpa membayar biaya tinggi
Jika transaksi diizinkan untuk langsung ditulis ke dalam kontrak Rollup melalui Force Inclusion (artinya transaksi berlaku segera), status Rollup akan berubah secara instan. Misalnya, jika Bob menggunakan mekanisme Force Inclusion untuk memasukkan transaksi yang mentransfer 1000 DAI ke Carol, dan transaksi segera berlaku, saldo Bob akan berkurang 1000 DAI, sedangkan saldo Carol akan meningkat 1000 DAI dalam keadaan diperbarui.
Jika Force Inclusion memungkinkan transaksi untuk langsung ditulis ke dalam kontrak Rollup dan berlaku segera, status Rollup akan berubah secara instan. Jika sequencer secara bersamaan mengumpulkan transaksi off-chain dan bersiap untuk mengirim batch berikutnya ke kontrak Rollup, itu bisa terganggu oleh transaksi Bob yang dimasukkan secara paksa yang segera berlaku. Untuk menghindari masalah ini, Rollup umumnya tidak memungkinkan transaksi Force Inclusion berlaku segera. Sebaliknya, pengguna awalnya memasukkan transaksi mereka ke dalam antrian menunggu di L1, di mana mereka memasuki status "persiapan". Ketika paket sequencer off-chain transaksi untuk dikirim ke kontrak Rollup, ia dapat memilih apakah akan menyertakan transaksi antrian ini. Jika sequencer terus-menerus mengabaikan transaksi dalam status "persiapan", setelah periode jendela berakhir, pengguna dapat secara paksa memasukkan transaksi ini ke dalam kontrak Rollup. Sequencer dapat memutuskan kapan harus "secara kebetulan memasukkan" transaksi dari antrian tunggu, tetapi masih dapat menolak untuk memprosesnya. Jika sequencer secara konsisten menolak, setelah jangka waktu tertentu, siapa pun dapat menggunakan fungsi Force Inclusion untuk memasukkan transaksi secara paksa ke dalam kontrak Rollup. Selanjutnya, kami akan memperkenalkan implementasi mekanisme Force Inclusion dalam empat Rollup terkemuka: Optimisme, Arbitrum, StarkNet, dan zkSync.
Sequencer dapat memilih kapan harus mendapatkan transaksi dari antrian tunggu.
Sequencer masih dapat menolak untuk memproses transaksi dalam antrian tunggu.
Jika sequencer secara konsisten menolak untuk memproses transaksi, setelah jangka waktu tertentu, siapa pun dapat menggunakan fungsi Force Inclusion untuk memasukkan transaksi secara paksa ke dalam kontrak Rollup. Selanjutnya, kami akan memperkenalkan bagaimana mekanisme Force Inclusion diimplementasikan dalam empat Rollup terkemuka: Optimisme, Arbitrum, StarkNet, dan zkSync.
Pertama, mari kita bahas proses Deposit Optimisme. Proses Deposit ini melibatkan tidak hanya mentransfer dana ke Optimisme tetapi juga mengirim "pesan pengguna ke L2." Ketika node L2 menerima pesan yang baru disimpan, ia mengubah pesan menjadi transaksi L2 dan mengeksekusinya, mengirimkannya ke penerima yang ditentukan.
Pesan Pengguna yang Disetorkan dari L1 ke L2
Kontrak L1CrossDomainMessenger
Ketika pengguna ingin setor ETH atau ERC-20 token ke dalam Optimisme, mereka berinteraksi dengan kontrak L1StandardBridge di L1 melalui halaman web frontend, menentukan jumlah yang akan setor dan alamat L2 yang akan menerima aset ini. Kontrak L1StandardBridge kemudian meneruskan pesan ke kontrak L1CrossDomainMessenger, yang bertindak sebagai bridge komunikasi utama antara L1 dan L2. L1StandardBridge menggunakan komponen komunikasi ini untuk berinteraksi dengan L2StandardBridge di L2, menentukan siapa yang dapat cetak token di L2 atau membuka kunci token dari L1. Pengembang yang perlu membuat kontrak yang saling mengoperasikan dan menyinkronkan status antara L1 dan L2 dapat membangunnya di atas kontrak L1CrossDomainMessenger.
Pesan Pengguna yang Ditransmisikan dari L1 ke L2 melalui Kontrak CrossDomainMessenger
Catatan: Dalam beberapa gambar dalam artikel ini, CrossDomainMessenger ditulis sebagai CrossChainMessenger.
Kontrak OptimismPortal
Kontrak L1CrossDomainMessenger kemudian meneruskan pesan ke lapisan terendah, kontrak OptimismPortal. Setelah memproses pesan, kontrak OptimismPortal memancarkan peristiwa yang disebut TransactionDeposited, yang mencakup parameter seperti "pengirim", "penerima", dan detail eksekusi relevan lainnya. Node Optimisme pada L2 mendengarkan peristiwa TransactionDeposited ini dari kontrak OptimismPortal dan mengubah parameter peristiwa menjadi transaksi L2. Pemrakarsa transaksi ini akan menjadi "pengirim" yang ditentukan dalam acara, penerima akan menjadi "penerima" yang disebutkan dalam acara tersebut, dan detail transaksi lainnya juga akan diturunkan dari parameter acara.
L2 node mengubah parameter peristiwa Deposit Transaksi yang dipancarkan oleh OptimismPortal menjadi transaksi L2.
Misalnya, ketika pengguna menyetor 0,01 ETH melalui kontrak L1StandardBridge, pesan dan ETH dikirimkan ke kontrak OptimismPortal (alamat 0xbEb5... 06Ed). Beberapa menit kemudian, ini diubah menjadi transaksi L2: pengirim pesan adalah kontrak L1CrossDomainMessenger, penerima adalah kontrak L2CrossDomainMessenger di L2, dan konten pesan menunjukkan bahwa L1StandardBridge menerima ETH setor 0,01 dari Bob. Ini kemudian memicu proses tambahan, seperti pencetakan 0,01 ETH untuk L2StandardBridge, yang kemudian mentransfernya ke Bob.
Cara memicunya
Jika Anda ingin secara paksa memasukkan transaksi dalam kontrak Rollup Optimisme, tujuan Anda adalah untuk memastikan bahwa transaksi "dimulai dan dieksekusi dari alamat L2 Anda di L2" dapat berhasil dijalankan. Untuk mencapai hal ini, Anda harus mengirimkan pesan langsung ke kontrak OptimismPortal menggunakan alamat L2 Anda (perhatikan bahwa kontrak OptimismPortal sebenarnya ada di L1, tetapi format alamat OP cocok dengan format alamat L1, sehingga Anda dapat memanggil kontrak ini menggunakan akun L1 dengan alamat yang sama dengan akun L2 Anda). "Pengirim" transaksi L2 yang berasal dari peristiwa Deposit Transaksi yang dipancarkan oleh kontrak ini kemudian akan menjadi akun L2 Anda, dan format transaksi akan konsisten dengan transaksi L2 standar.
Dalam transaksi L2 yang berasal dari peristiwa Transaksi yang Disetorkan, Bob sendiri yang akan menjadi pemrakarsa; penerima akan menjadi kontrak Uniswap; dan itu akan mencakup ETH yang ditentukan, seolah-olah Bob memulai transaksi L2 sendiri.
Untuk menggunakan fungsi Force Inclusion Optimism, Anda perlu langsung memanggil fungsi depositTransaction dari kontrak OptimismPortal dan memasukkan parameter transaksi yang ingin Anda jalankan di L2. Saya melakukan eksperimen Force Inclusion sederhana. Tujuan dari transaksi ini adalah untuk melakukan transfer mandiri di L2 menggunakan alamat saya (0xeDc1... 6909) dan menyertakan pesan yang mengatakan "inklusi paksa." Ini adalah transaksi L1 yang saya lakukan dengan memanggil fungsi depositTransaction melalui kontrak OptimismPortal. Seperti yang dapat Anda lihat dari peristiwa Transaksi yang Ditransmisikan yang dipancarkannya, pengirim dan penerima adalah saya sendiri.
Nilai yang tersisa di kolom Data buram menyandikan informasi seperti "berapa banyak ETH orang yang memanggil fungsi depositTransaction terlampir," "berapa banyak ETH yang ingin dikirim oleh inisiator transaksi L2 ke penerima," "GasLimit transaksi L2," dan "Data untuk penerima L2." Setelah mendekode informasi ini, Anda akan mendapatkan detail berikut: "berapa ETH orang yang memanggil depositTransaction terlampir": 0, karena saya tidak menyetor ETH dari L1 ke L2; "berapa banyak ETH yang ingin dikirim oleh pemrakarsa transaksi L2 ke penerima": 5566 (wei); "L2 transaksi GasLimit": 50000; "Data untuk penerima L2": 0x666f72636520696e636c7573696f6e, yang merupakan pengkodean heksadesimal dari string "inklusi gaya." Tak lama setelah itu, transaksi L2 yang dikonversi muncul: transaksi L2 di mana saya mentransfer 5566 wei ke diri saya sendiri, dengan bidang Data berisi string "force inclusion." Selain itu, di baris kedua hingga terakhir dari bagian Atribut Lainnya, TxnType (jenis transaksi) ditampilkan sebagai transaksi sistem 126 (Sistem), yang menunjukkan bahwa transaksi ini tidak dimulai oleh saya di L2 tetapi dikonversi dari peristiwa Deposit dari transaksi L1.
Transaksi L2 yang dikonversi
Jika Anda ingin memanggil kontrak L2 melalui Force Inclusion dan mengirim Data yang berbeda, Anda hanya perlu mengisi parameter dalam fungsi depositTransaction. Ingatlah untuk menggunakan alamat L1 yang sama dengan akun L2 Anda saat memanggil fungsi depositTransaction. Dengan cara ini, ketika Peristiwa yang Disetorkan diubah menjadi transaksi L2, inisiatornya adalah akun L2 Anda. Jendela Sequencer Simpul Optimisme L2 yang mengubah peristiwa Transaksi yang Disetorkan menjadi transaksi L2 sebenarnya adalah Sequencer. Karena ini melibatkan pemesanan transaksi, hanya Sequencer yang dapat memutuskan kapan harus mengubah acara menjadi transaksi L2. Ketika Sequencer mendengarkan peristiwa TransactionDeposited, itu tidak selalu mengubah peristiwa menjadi transaksi L2 segera; Mungkin ada penundaan. Durasi maksimum penundaan ini disebut Sequencer Window. Saat ini, Jendela Sequencer di mainnet Optimism adalah 24 jam. Ini berarti bahwa ketika pengguna menyetor uang dari L1 atau menggunakan Force Inclusion untuk transaksi, dalam skenario terburuk, itu akan dimasukkan dalam riwayat transaksi L2 setelah 24 jam.
Dalam Optimisme, operasi setor L1 memicu peristiwa Transaksi yang Disimpan, dan kemudian hanya masalah menunggu Sequencer untuk memasukkan operasi. Namun, di Arbitrum, operasi pada L1 (seperti menyetor dana atau mengirim pesan ke L2) disimpan dalam antrian di L1, bukan hanya memancarkan peristiwa. Sequencer memiliki periode tertentu untuk memasukkan transaksi antrian ini ke dalam riwayat transaksi L2. Jika Sequencer gagal melakukannya dalam jangka waktu ini, siapa pun dapat masuk untuk menyelesaikan penyertaan atas nama Sequencer.
Arbitrum mempertahankan Antrian dalam kontrak L1. Jika Sequencer gagal memproses transaksi dalam Antrian dalam periode tertentu, siapa pun dapat secara paksa memasukkan transaksi ini ke dalam riwayat transaksi L2. Dalam desain Arbitrum, operasi pada L1, seperti deposito, harus melalui kontrak Kotak Masuk Tertunda, di mana, seperti namanya, operasi ini akan ditunda sebelum berlaku. Kontrak lain, Kotak Masuk Sequencer, adalah tempat Sequencer secara langsung mengunggah transaksi L2 ke L1. Setiap kali Sequencer mengunggah transaksi L2, Sequencer juga dapat mengambil beberapa transaksi tertunda dari Kotak Masuk Tertunda dan memasukkannya ke dalam riwayat transaksi.
Saat Sequencer menulis transaksi baru, Sequencer juga dapat menyertakan transaksi dari DelayedInbox.
Desain Kompleks dan Kurangnya Bahan Referensi
Jika Anda merujuk ke dokumentasi resmi Arbitrum tentang Sequencer dan Force Inclusion, Anda akan menemukan penjelasan umum tentang cara kerja Force Inclusion, bersama dengan beberapa parameter dan nama fungsi: Pengguna pertama-tama memanggil fungsi sendUnsignedTransaction pada kontrak DelayedInbox. Jika Sequencer tidak menyertakannya dalam waktu sekitar 24 jam, pengguna dapat memanggil fungsi forceInclusion pada kontrak SequencerInbox. Namun, dokumentasi resmi tidak menyediakan tautan ke fungsi-fungsi ini, jadi Anda harus mencarinya sendiri di kode kontrak. Ketika Anda menemukan fungsi sendUnsignedTransaction, Anda menyadari bahwa Anda harus mengisi nilai nonce dan nilai maxFeePerGas sendiri. nonce siapa itu? MaxFeePerGas jaringan mana? Bagaimana seharusnya Anda mengisinya dengan benar? Tidak ada dokumen referensi, bahkan NatSpec. Anda juga akan menemukan banyak fungsi serupa dalam kontrak Arbitrum: sendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction. Tidak ada dokumen yang menjelaskan perbedaan antara fungsi-fungsi ini, cara menggunakannya, atau cara mengisi parameter, bahkan NatSpec.
Anda mencoba mengisi parameter dan mengirimkan transaksi dengan pendekatan trial-and-error, berharap menemukan penggunaan yang benar. Namun, Anda menemukan bahwa semua fungsi ini berlaku Alamat Aliasing ke alamat L1 Anda, menyebabkan Pengirim transaksi di L2 menjadi alamat yang sama sekali berbeda, meninggalkan alamat L2 Anda tidak aktif. Kemudian, Anda secara tidak sengaja menemukan hasil pencarian Google yang mengungkapkan bahwa Arbitrum memiliki perpustakaan Tutorial dengan skrip yang menunjukkan cara mengirim transaksi L2 dari L1 (pada dasarnya Force Inclusion). Tutorial mencantumkan fungsi yang tidak disebutkan sebelumnya: sendL2Message. Anehnya, parameter pesan yang diperlukan sebenarnya adalah transaksi L2 yang ditandatangani menggunakan akun L2. Siapa yang tahu bahwa "pesan yang dikirim ke L2 melalui Force Inclusion" sebenarnya adalah "transaksi L2 yang ditandatangani"? Selain itu, tidak ada dokumen atau NatSpec yang menjelaskan kapan dan bagaimana menggunakan fungsi ini.
Kesimpulan: Menghasilkan transaksi paksa secara manual di Arbitrum cukup rumit. Disarankan untuk mengikuti Tutorial resmi dan menggunakan SDK Arbitrum. Tidak seperti Rollup lainnya, Arbitrum tidak memiliki dokumentasi pengembang dan anotasi kode yang jelas. Banyak fungsi tidak memiliki penjelasan untuk tujuan dan parameternya, menyebabkan pengembang menghabiskan lebih banyak waktu daripada yang diharapkan untuk mengintegrasikan dan menggunakannya. Saya juga meminta bantuan dalam Perselisihan Arbitrum, tetapi tidak menerima jawaban yang memuaskan. Saat bertanya di Discord, mereka hanya mengarahkan saya untuk melihat sendL2Message dan tidak menjelaskan fungsi metode lain (termasuk yang disebutkan dalam dokumentasi Force Inclusion seperti sendUnsignedTransaction), tujuannya, cara menggunakannya, atau kapan menggunakannya.
Sayangnya, StarkNet saat ini tidak memiliki mekanisme Force Inclusion. Hanya ada dua artikel di forum resmi yang membahas Sensor dan Inklusi Paksa. Alasan ketidakmampuan untuk membuktikan transaksi yang gagal adalah bahwa sistem bukti tanpa pengetahuan StarkNet tidak dapat membuktikan transaksi yang gagal, sehingga Force Inclusion tidak dapat diizinkan. Jika seseorang dengan jahat (atau tidak sengaja) Memaksa Termasuk transaksi yang gagal dan tidak dapat dibuktikan, StarkNet akan terjebak: karena begitu transaksi dimasukkan secara paksa, Prover harus membuktikan transaksi yang gagal, tetapi tidak bisa. StarkNet diharapkan untuk memperkenalkan kemampuan untuk membuktikan transaksi gagal dalam versi v0.15.0, setelah itu mekanisme Force Inclusion harus diterapkan lebih lanjut.
Mekanisme zkSync untuk transmisi pesan L1->L2 dan Force Inclusion ditangani melalui fungsi requestL2Transaction dari kontrak MailBox. Pengguna menentukan alamat L2, calldata, jumlah ETH yang akan dilampirkan, nilai L2GasLimit, dan detail lainnya. Fungsi requestL2Transaction menggabungkan parameter ini ke dalam transaksi L2 dan menempatkannya ke dalam PriorityQueue. Ketika Sequencer mengemas transaksi dan mengunggahnya ke L1 (melalui fungsi commitBatches), ini menunjukkan berapa banyak transaksi yang harus diambil dari PriorityQueue untuk disertakan dalam catatan transaksi L2. Dalam hal Force Inclusion, zkSync mirip dengan Optimisme, di mana alamat L2 inisiator (sama dengan alamat L1) digunakan untuk memanggil fungsi yang relevan dan mengisi detail yang diperlukan (callee, calldata, dll.), Daripada seperti Arbitrum, yang membutuhkan transaksi L2 yang ditandatangani. Namun, dalam desain, ini mirip dengan Arbitrum, karena keduanya mempertahankan antrian di L1, dan Sequencer mengambil transaksi tertunda yang dikirimkan langsung oleh pengguna dari Antrian dan menuliskannya ke dalam riwayat transaksi.
Jika Anda setor ETH melalui bridge resmi zkSync, seperti transaksi ini, ia memanggil fungsi requestL2Transaction dari kontrak MailBox. Fungsi ini menempatkan transaksi Deposit ETH L2 ke dalam PriorityQueue dan memancarkan peristiwa NewPriorityRequest. Karena kontrak mengkodekan data transaksi L2 menjadi string byte, itu tidak mudah dibaca. Namun, jika Anda melihat parameter transaksi L1 ini, Anda akan melihat bahwa penerima L2 juga merupakan pemrakarsa transaksi (karena ini adalah setor untuk diri sendiri). Setelah beberapa waktu, ketika Sequencer mengeluarkan transaksi L2 ini dari PriorityQueue dan memasukkannya ke dalam riwayat transaksi, itu akan diubah menjadi transaksi L2 tempat Anda mentransfer ke diri Anda sendiri. Jumlah transfer akan menjadi jumlah ETH yang dilampirkan oleh pemrakarsa dalam transaksi ETH Setoran L1. Dalam transaksi Deposito L1, baik pemrakarsa maupun penerima 0xeDc1... 6909, jumlahnya 0,03 ETH, dan tidak ada calldata. Di L2, akan ada transaksi di mana 0xeDc1... 6909 transfer ke dirinya sendiri. Jenis transaksi (TxnType) adalah 255, menunjukkan transaksi sistem. Kemudian, seperti saya bereksperimen dengan fungsi transaksi paksa pada Optimisme sebelumnya, saya memanggil fungsi requestL2Transaction zkSync dan memulai transaksi transfer mandiri: tidak ada ETH yang dilampirkan, dan calldata berisi pengkodean HEX dari string "force inclusion." Ini kemudian diubah menjadi transaksi L2 di mana saya mentransfer ke diri saya sendiri, dengan calldata yang berisi string heksadesimal untuk "force inclusion": 0x666f72636520696e636c7573696f6e. Ketika Sequencer mengambil transaksi dari PriorityQueue dan menuliskannya ke dalam riwayat transaksi, transaksi tersebut diubah menjadi transaksi L2 yang sesuai. Dengan menggunakan fungsi requestL2Transaction, pengguna dapat mengirimkan data pada L1 dengan akun L1 yang sama dengan alamat L2 mereka, menentukan penerima L2, jumlah ETH yang akan dilampirkan, dan calldata. Jika pengguna ingin memanggil kontrak lain atau menyertakan Data yang berbeda, mereka hanya perlu mengisi parameter dalam fungsi requestL2Transaction. Belum ada fungsi Force Inclusion untuk pengguna Meskipun transaksi L2 yang ditempatkan di PriorityQueue akan memiliki masa tunggu yang dihitung untuk dimasukkan oleh Sequencer, desain zkSync saat ini tidak memiliki fungsi Force Inclusion yang memungkinkan pengguna untuk menegakkannya. Ini berarti hanya solusi parsial. Meskipun ada "masa tunggu untuk dimasukkan," pada akhirnya tergantung pada apakah Sequencer memutuskan untuk memasukkannya: Sequencer dapat memasukkannya setelah periode berakhir atau tidak pernah menyertakan transaksi apa pun dari PriorityQueue. Di masa depan, zkSync harus menambahkan fungsi yang memungkinkan pengguna untuk secara paksa memasukkan transaksi ke dalam riwayat transaksi L2 jika mereka belum dimasukkan oleh Sequencer setelah masa tunggu. Ini akan menjadi mekanisme Force Inclusion yang benar-benar efektif. Ringkas
L1 bergantung pada sejumlah besar validator untuk memastikan "keamanan" dan "resistensi pensensoran" jaringan. Rollup, bagaimanapun, memiliki resistensi pensensoran yang lebih lemah karena transaksi ditulis oleh beberapa atau bahkan satu Sequencer. Oleh karena itu, Rollup memerlukan mekanisme Force Inclusion untuk memungkinkan pengguna melewati Sequencer dan menulis transaksi ke dalam riwayat, mencegah sensor oleh Sequencer membuat Rollup tidak dapat digunakan dan mencegah pengguna menarik dana. Force Inclusion memungkinkan pengguna untuk secara paksa menulis transaksi ke dalam riwayat, tetapi desain harus memilih apakah "transaksi dapat segera dimasukkan ke dalam riwayat dan segera berlaku." Jika efek langsung diizinkan, itu akan berdampak negatif pada Sequencer karena transaksi yang tertunda pada L2 dapat dipengaruhi oleh transaksi yang dimasukkan secara paksa dari L1. Oleh karena itu, mekanisme Force Inclusion saat ini dalam Rollups pertama-tama menempatkan transaksi yang dimasukkan dari L1 ke dalam keadaan menunggu dan memberi Sequencer jendela waktu untuk bereaksi dan memutuskan apakah akan memasukkan transaksi yang tertunda ini. zkSync dan Arbitrum keduanya mempertahankan antrian di L1 untuk mengelola transaksi L2 atau pesan yang dikirim dari L1 ke L2. Arbitrum menyebutnya DelayedInbox; zkSync menyebutnya PriorityQueue. Namun, metode pengiriman transaksi L2 zkSync lebih mirip dengan Optimisme, di mana pesan dikirim dari L1 menggunakan alamat L2, sehingga ketika dikonversi ke transaksi L2, inisiatornya adalah alamat L2. Fungsi untuk mengirim transaksi L2 di Optimism disebut depositTransaction; di zkSync, ini disebut requestL2Transaction. Sebaliknya, Arbitrum menghasilkan transaksi L2 lengkap dan menandatanganinya, lalu mengirimkannya melalui fungsi sendL2Message. Pada L2, Arbitrum menggunakan tanda tangan untuk mengembalikan penandatangan sebagai pemrakarsa transaksi L2. StarkNet saat ini tidak memiliki mekanisme Force Inclusion; zkSync memiliki mekanisme Force Inclusion yang setengah diimplementasikan — ia memiliki PriorityQueue, dan setiap transaksi L2 dalam Queue memiliki periode validitas inklusi, tetapi periode validitas ini saat ini hanya untuk pertunjukan. Dalam praktiknya, Sequencer dapat memilih untuk tidak menyertakan transaksi L2 apa pun dari PriorityQueue.
Artikel ini diteruskan dari: [Geek Web3], judul aslinya adalah "Theory and Practice: How to trigger censorship-resistant transactions in Ethereum Rollup?", atribusi hak cipta kepada penulis asli [NIC Lin, Head of Taipei Ethereum Meetup], jika Anda keberatan dengan cetak ulang, silakan hubungi Tim Gate Learn, tim akan menanganinya sesegera mungkin sesuai prosedur yang relevan.
Penafian: Pandangan dan pendapat yang diungkapkan dalam artikel ini hanya mewakili pandangan pribadi penulis dan bukan merupakan saran investasi.
Versi bahasa lain dari artikel ini diterjemahkan oleh tim Gate Learn. Tanpa merujuk Gate.io, menyalin, mendistribusikan, atau menjiplak artikel terjemahan dilarang.