Di Ethereum, sumber daya baru-baru ini terbatas dan dipatok menggunakan satu sumber daya yang disebut “gas”. Gas adalah ukuran dari jumlah “upaya komputasi” yang diperlukan untuk memproses transaksi atau blok tertentu. Gas menggabungkan berbagai jenis “upaya”, terutama:
Sebagai contoh, transaksi inibahwa saya kirim total biaya 47.085 gas. Ini dibagi antara (i) “biaya dasar” sebesar 21.000 gas, (ii) 1556 gas untuk byte dalam calldata yang disertakan sebagai bagian dari transaksi, (iii) 16500 gas untuk membaca dan menulis ke penyimpanan, (iv) gas 2149 untuk membuat alog, dan sisanya untuk eksekusi EVM. Biaya transaksi yang harus dibayarkan oleh pengguna berbanding lurus dengan gas yang dikonsumsi oleh transaksi tersebut. Sebuah blok dapat berisi maksimum hingga 30 juta gas, dan harga gas terus disesuaikan melalui @vbuterin/eip-1559-faq">Mekanisme penargetan EIP-1559, memastikan bahwa rata-rata, blok mengandung 15 juta gas.
Pendekatan ini memiliki satu efisiensi utama: karena semua digabungkan ke dalam satu sumber daya virtual, hal ini mengarah pada desain pasar yang sangat sederhana. Mengoptimalkan transaksi untuk meminimalkan biaya menjadi mudah, mengoptimalkan blok untuk mengumpulkan biaya tertinggi mungkin relatif mudah (tidak termasuk MEV) dan tidak ada insentif aneh yang mendorong beberapa transaksi untuk dibundel dengan transaksi lain untuk menghemat biaya.
Namun pendekatan ini juga memiliki satu ketidaksempurnaan utama: itu memperlakukan sumber daya yang berbeda sebagai saling dapat dikonversi, ketika batasan sebenarnya dari apa yang jaringan dapat tangani tidak. Salah satu cara untuk memahami masalah ini adalah dengan melihat diagram ini:
Batas gas memberlakukan pembatasan
𝑥1∗𝑑𝑎𝑡𝑎+𝑥2∗𝑐𝑜𝑚𝑝𝑢𝑡𝑎𝑡𝑖𝑜𝑛<𝑁
. Kendala keamanan yang sebenarnya lebih sering berhubungan dengan
𝑚𝑎𝑥(𝑥1∗𝑑𝑎𝑡𝑎,𝑥2∗𝑐𝑜𝑚𝑝𝑢𝑡𝑎𝑡𝑖𝑜𝑛)<𝑁
Ketidaksesuaian ini mengakibatkan batas gas secara tidak perlu mengesampingkan blok yang sebenarnya aman, atau menerima blok yang sebenarnya tidak aman, atau beberapa campuran dari keduanya.
Jika ada
n
sumber daya yang memiliki batasan keamanan yang berbeda, maka gas satu dimensi secara masuk akal dapat mengurangi throughput hingga faktor
𝑛
Untuk alasan ini, telah lama ada minat dalam konsep gas multi-dimensi, dan dengan EIP-4844kami sebenarnya memiliki gas multi-dimensi yang bekerja pada Ethereum saat ini. Pos ini menjelajahi manfaat dari pendekatan ini, dan prospek untuk meningkatkannya lebih lanjut.
Di awal tahun ini, blok rata-rata 150 kB dalam ukuranSebagian besar dari ukuran tersebut adalah data rollup: protokol lapisan 2menyimpan data di chain untuk keamanan. Data ini mahal: meskipun transaksi di rollups akan biaya ~5-10x lebih sedikit dari transaksi yang sesuai di Ethereum L1, bahkan biaya tersebut terlalu tinggi untuk banyak kasus penggunaan.
Mengapa tidak mengurangi biaya gas calldata (saat ini 16 gas per byte yang bukan nol dan 4 gas per byte nol), untuk membuat rollups lebih murah? Kami melakukan ini sebelumnya, kita bisa melakukannya lagi. Jawabannya di sini adalah: ukuran kasus terburuk dari sebuah blok adalah
30,000,00016=1,875,000
byte yang tidak nol, dan jaringan sudah hampir tidak mampu menangani blok sebesar itu. Mengurangi biaya lagi 4x akan meningkatkan maksimum menjadi 7,5 MB, yang akan menjadi risiko besar untuk keselamatan.
Masalah ini akhirnya diatasi dengan memperkenalkan ruang data yang ramah rollup terpisah, yang dikenal sebagai “blob”, ke setiap blok. Kedua sumber daya memiliki harga dan batas yang terpisah: setelah hard fork Dencun, sebuah blok Ethereum dapat berisi paling banyak (i) 30 juta gas, dan (ii) 6 blob, yang dapat berisi ~125 kB data panggilan masing-masing. Kedua sumber daya memiliki harga yang terpisah, disesuaikan olehmecanisme penetapan harga mirip EIP-1559 terpisah, dengan target penggunaan rata-rata 15 juta gas dan 3 blob per blok.
Sebagai hasilnya, rollups telah menjadi 100x lebih murah, volume transaksi pada rollups meningkat lebih dari 3x, dan ukuran blok maksimum teoretis hanya sedikit meningkat: dari ~1.9 MB menjadi ~2.6 MB.
Biaya transaksi pada rollups, atas kebaikan growthepie.xyzFork Dencun, yang memperkenalkan blob dengan harga multidimensi, terjadi pada 13 Maret 2024.
Di masa depan, masalah serupa akan muncul mengenai bukti penyimpanan untuk klien tanpa status. Klien tanpa status adalah jenis klien baru yang akan dapat memverifikasi rantai tanpa menyimpan banyak atau sama sekali data secara lokal. Klien tanpa status melakukan hal ini dengan menerima bukti-bukti bagian spesifik dari status Ethereum yang transaksi dalam blok tersebut perlu sentuh.
Sebuah klien tanpa status menerima blok, bersama dengan bukti-bukti yang membuktikan nilai-nilai saat ini di bagian-bagian tertentu dari status (misalnya, saldo akun, kode, penyimpanan) yang disentuh oleh eksekusi blok tersebut. Hal ini memungkinkan sebuah node untuk memverifikasi sebuah blok tanpa harus memiliki penyimpanan sendiri.
Biaya baca penyimpanan sekitar 2100-2600 gas tergantung pada jenis bacaan, dan penulisan penyimpanan lebih mahal. Rata-rata, sebuah blok melakukan sekitar 1000 bacaan dan penulisan penyimpanan (termasuk pemeriksaan saldo ETH, panggilan SSTORE dan SLOAD, pembacaan kode kontrak, dan operasi lainnya). Namun, maksimum teoritisnya adalah
30,000,0002,100=14,285
membaca. Beban bandwidth klien stateless secara langsung berbanding lurus dengan jumlah ini.
Hari ini, rencananya adalah mendukung klien tanpa status dengan memindahkan desain pohon status Ethereum dari pohon Merkle PatriciauntukPohon VerkleNamun, pohon Verkle tidak tahan terhadap kuantum, dan tidak optimal untuk gelombang baru sistem pembuktian STARK. Sebagai hasilnya, banyak orang tertarik untuk mendukung klien tanpa status melalui pohon Merkle biner dan STARKssebagai gantinya - baik dengan melewatkan Verkle sama sekali, atau meng-upgrade beberapa tahun setelah transisi Verkle ketika STARKs menjadi lebih matang.
Bukti STARK dari cabang pohon hash biner memiliki banyak keunggulan, tetapi memiliki kelemahan kunci bahwa bukti memerlukan waktu yang lama untuk dihasilkan: sementara pohon Verklebisa membuktikanlebih dari seratus ribu nilai per detik, STARK berbasis hash biasanya hanya dapat membuktikan beberapa ribu hash per detik, dan membuktikan setiap nilai memerlukan 'cabang' yang berisi banyak hash.
Dengan angka-angka yang diproyeksikan hari ini dari sistem bukti yang sangat dioptimalkan seperti BiniusdanPlonky3dan hash khusus sepertiVisi-Mark-32, sepertinya kemungkinan besar kita akan untuk beberapa waktu berada dalam rezim di mana praktis untuk membuktikan 1.000 nilai dalam waktu kurang dari satu detik, tetapi tidak 14.285 nilai. Blok rata-rata akan baik, tetapi blok kasus terburuk, yang mungkin dipublikasikan oleh seorang penyerang, akan merusak jaringan.
Cara 'default' yang kami gunakan untuk menangani skenario tersebut adalah dengan melakukan penyesuaian harga: membuat pembacaan penyimpanan lebih mahal untuk mengurangi maksimum per blok menjadi sesuatu yang lebih aman. Namun, kami memilikisudahselesaiinibanyakwaktu, dan akan membuat terlalu banyak aplikasi terlalu mahal untuk melakukan ini lagi. Pendekatan yang lebih baik adalah gas multidimensional: batasi dan kenakan biaya untuk akses penyimpanan secara terpisah, menjaga penggunaan rata-rata pada 1.000 akses penyimpanan per blok tetapi menetapkan batas per blok misalnya 2.000.
Salah satu sumber daya lain yang layak dipertimbangkan adalah pertumbuhan ukuran status: operasi yang meningkatkan ukuran status Ethereum, yang akan perlu dipegang oleh node penuh mulai dari saat itu. Properti unik dari pertumbuhan ukuran status adalah bahwa alasan dari pembatasannya berasal sepenuhnya dari penggunaan berkelanjutan jangka panjang, dan bukan lonjakan. Oleh karena itu, mungkin ada nilai tambah dalam menambahkan dimensi gas terpisah untuk operasi peningkatan ukuran status (misalnya, SSTORE nol-ke-non-nol, penciptaan kontrak), tetapi dengan tujuan yang berbeda: kita bisa menetapkan harga mengambang untuk menargetkan penggunaan rata-rata tertentu, tetapi tidak menetapkan batasan per blok sama sekali.
Ini menunjukkan salah satu properti kuat dari gas multidimensi: itu memungkinkan kita untuk secara terpisah bertanya pertanyaan-pertanyaan (i) apa penggunaan rata-rata ideal, dan (ii) apa penggunaan maksimum per-blok yang aman, untuk setiap sumber daya. Alih-alih menetapkan harga gas berdasarkan maksimum per-blok, dan membiarkan penggunaan rata-rata mengikuti, kita memiliki
2𝑛
derajat kebebasan untuk ditetapkan
2𝑛
parameter, menyesuaikan masing-masing berdasarkan apa yang aman untuk jaringan.
Situasi yang lebih rumit, seperti di mana dua sumber daya memiliki pertimbangan keamanan yang sebagian aditif, dapat ditangani dengan membuat opcode atau biaya sumber daya beberapa jumlah dari beberapa jenis gas (misalnya, sebuah SSTORE nol-ke-non-nol bisa biaya 5000 gas bukti klien tanpa status dan 20000 gas ekspansi penyimpanan).
Biarkan
𝑥1
menjadi biaya gas data dan
𝑥2
menjadi biaya gas komputasi, sehingga dalam sistem gas satu dimensi kita dapat menulis biaya gas dari sebuah transaksi:
gas=x1*data+x2*computatio
Dalam skema ini, kami malah mendefinisikan biaya gas dari sebuah transaksi sebagai:
gas=max(x1*data,x2*computational)
Yaitu, alih-alih sebuah transaksi dikenakan biaya untuk data ditambah komputasi, transaksi tersebut dikenakan biaya berdasarkan sumber daya mana yang lebih banyak digunakan. Ini dapat dengan mudah diperluas untuk mencakup lebih banyak dimensi (misalnya.
𝑚𝑎𝑥(…,𝑥3∗𝑠𝑡𝑜𝑟𝑎𝑔𝑒_𝑎𝑐𝑐𝑒𝑠𝑠)
).
Seharusnya mudah untuk melihat bagaimana ini meningkatkan throughput sambil menjaga keselamatan. Jumlah data maksimum teoretis dalam satu blok masih
𝐺𝐴𝑆𝐿𝐼𝑀𝐼𝑇𝑥1
, persis sama seperti dalam skema gas satu dimensi. Demikian pula, jumlah komputasi maksimum teoretis adalah
𝐺𝐴𝑆𝐿𝐼𝑀𝐼𝑇𝑥2
, lagi-lagi persis sama seperti dalam skema gas satu dimensi. Namun, biaya gas dari transaksi apa pun yang mengonsumsi baik data maupun komputasi akan berkurang.
Ini kira-kira skema yang digunakan dalam usulan tersebutEIP-7623, untuk mengurangi ukuran blok maksimum sekaligus meningkatkan jumlah blob lebih lanjut. Mekanisme yang tepat dalam EIP-7623 sedikit lebih rumit: ia menjaga harga calldata saat ini sebesar 16 gas per byte, tetapi menambahkan "harga dasar" sebesar 48 gas per byte; Transaksi membayar lebih tinggi dari (16 byte + gas eksekusi) dan (48 bytes). Sebagai hasilnya, EIP-7623 mengurangi calldata transaksi maksimum teoritis dalam satu blok dari ~1.9 MB menjadi ~0.6 MB, sambil meninggalkan biaya sebagian besar aplikasi tetap sama. Manfaat dari pendekatan ini adalah bahwa ini adalah perubahan yang sangat kecil dari skema gas satu dimensi saat ini, sehingga sangat mudah untuk diimplementasikan.
Ada dua kekurangan:
Saya akan berpendapat bahwa aturan gaya EIP-7623, baik untuk data panggilan transaksi maupun untuk sumber daya lainnya, dapat memberikan manfaat yang cukup besar sehingga layak dilakukan meskipun ada kekurangan tersebut. Namun, jika dan ketika kita bersedia untuk melakukan upaya pengembangan (yang jauh lebih tinggi), ada pendekatan yang lebih ideal.
Mari kita pertama-tama mengulang kembali bagaimana EIP-1559 “biasa” bekerja. Kita akan fokus pada versi yang diperkenalkan dalam EIP-4844 untuk blobs, karena secara matematis lebih elegan.
Kami melacak parameter, excess_blobs. Selama setiap blok, kami mengatur:
kelebihan_blobs <— max(kelebihan_blobs + len(blok.blobs) - TARGET, 0)
Dimana TARGET = 3. Artinya, jika sebuah blok memiliki lebih banyak blob dari target, excess_blobs meningkat, dan jika sebuah blok memiliki kurang dari target, itu berkurang. Kami kemudian menetapkan blob_basefee = exp(excess_blobs / 25.47), di mana exp adalah perkiraan dari fungsi eksponensial
𝑒𝑥𝑝(𝑥)=2.71828𝑥
.
Yaitu, setiap kali excess_blobs meningkat sebesar ~25, basefee blob meningkat dengan faktor ~2.7. Jika blob menjadi terlalu mahal, penggunaan rata-rata turun, dan excess_blobs mulai berkurang, secara otomatis menurunkan harga kembali. Harga blob terus menyesuaikan untuk memastikan bahwa rata-rata, blok setengah penuh - yaitu, mereka mengandung rata-rata 3 blob masing-masing.
Jika terjadi lonjakan penggunaan jangka pendek, maka batasan akan berlaku: setiap blok hanya dapat berisi maksimum 6 blob, dan dalam keadaan seperti itu transaksi dapat bersaing satu sama lain dengan menawar biaya prioritas mereka. Namun, dalam kasus normal, setiap blob hanya perlu membayar blob_basefee ditambah biaya prioritas tambahan yang kecil sebagai insentif untuk disertakan secara keseluruhan.
Jenis penetapan harga seperti ini telah ada di Ethereum untuk gas selama bertahun-tahun: mekanisme yang sangat mirip diperkenalkan dengan @vbuterin/eip-1559-faq">EIP-1559 kembali pada tahun 2020. Dengan EIP-4844, sekarang kita memiliki dua harga terapung secara terpisah untuk gas dan untuk blobs.
Biaya dasar gas selama satu jam pada 08-05-2024, dalam gwei. Sumber: ultrasound.money.
Pada dasarnya, kita bisa menambahkan biaya terapung secara terpisah untuk membaca penyimpanan, dan jenis operasi lainnya, meskipun dengan satu peringatan yang akan saya perluas di bagian berikutnya.
Bagi pengguna, pengalaman ini sangat mirip dengan hari ini: alih-alih membayar satu biaya dasar, Anda membayar dua biaya dasar, tetapi dompet Anda dapat menyembunyikannya dari Anda dan hanya menunjukkan biaya yang diharapkan dan biaya maksimum yang dapat Anda harapkan untuk dibayar.
Bagi para pembangun blok, sebagian besar waktu strategi optimalnya sama seperti hari ini: termasuk segala hal yang valid. Sebagian besar blok tidak penuh - tidakdalam gasjuga tidakdalam blobKasus yang menantang adalah ketika terdapat cukup gas atau cukup blob untuk melebihi batas blok, dan pembangun perlu untuk potensial menyelesaikan sebuahMasalah ransel multidimensiuntuk memaksimalkan keuntungannya. Namun, bahkan di sana algoritma pendekatan yang cukup baik ada, dan keuntungan dari membuat algoritma propietari untuk mengoptimalkan keuntungan dalam kasus ini jauh lebih kecil dibandingkan dengan keuntungan dari melakukan hal yang sama dengan MEV.
Bagi para pengembang, tantangan utama adalah kebutuhan untuk merancang ulang fitur-fitur dari EVM, dan infrastruktur sekitarnya, yang dirancang berdasarkan satu harga dan satu batas saat ini menjadi desain yang dapat menampung berbagai harga dan berbagai batas. Salah satu masalah bagi pengembang aplikasi adalah bahwa optimisasi menjadi sedikit lebih sulit: dalam beberapa kasus, Anda tidak dapat lagi dengan tegas mengatakan bahwa A lebih efisien daripada B, karena jika A menggunakan lebih banyak calldata tetapi B menggunakan lebih banyak eksekusi, maka A mungkin lebih murah ketika calldata murah, dan lebih mahal ketika calldata mahal. Namun, para pengembang masih dapat mendapatkan hasil yang cukup baik dengan mengoptimalkan berdasarkan harga rata-rata historis jangka panjang.
Ada satu masalah yang tidak muncul dengan blob, dan tidak akan muncul dengan EIP-7623 atau bahkan implementasi harga multidimensi “penuh” untuk calldata, tetapi akan muncul jika kita mencoba membandingkan akses state secara terpisah, atau sumber daya lainnya: batas gas dalam panggilan sub.
Batas gas dalam EVM terdapat di dua tempat. Pertama, setiap transaksi menetapkan batas gas, yang membatasi jumlah total gas yang dapat digunakan dalam transaksi tersebut. Kedua, ketika kontrak memanggil kontrak lain, panggilan tersebut dapat menetapkan batas gasnya sendiri. Hal ini memungkinkan kontrak untuk memanggil kontrak lain yang tidak mereka percayai, dan masih menjamin bahwa mereka akan memiliki gas yang tersisa untuk melakukan perhitungan lain setelah panggilan tersebut.
Jejak transaksi abstraksi akun, di mana sebuah akun memanggil akun lain, dan hanya memberikan jumlah gas yang terbatas kepada penerima panggilan, untuk memastikan bahwa panggilan luar dapat terus berjalan meskipun penerima panggilan menghabiskan seluruh gas yang diberikan padanya.
Tantangannya adalah: membuat gas multidimensional di antara berbagai jenis eksekusi nampaknya akan memerlukan sub-panggilan untuk memberikan batasan ganda untuk setiap jenis gas, yang akan memerlukan perubahan yang sangat dalam pada EVM, dan tidak akan kompatibel dengan aplikasi yang sudah ada.
Ini adalah salah satu alasan mengapa proposal gas multidimensional sering berhenti pada dua dimensi: data dan eksekusi. Data (baik itu calldata transaksi atau blob) hanya ditugaskan di luar EVM, sehingga tidak ada yang perlu berubah di dalam EVM untuk membuat calldata atau blob dipisahkan harganya.
Kita dapat memikirkan solusi gaya “EIP-7623” untuk masalah ini. Berikut adalah satu implementasi sederhana: selama eksekusi, kenakan biaya 4x lebih banyak untuk operasi penyimpanan; untuk menyederhanakan analisis, katakanlah 10000 gas per operasi penyimpanan. Pada akhir transaksi, pengembalian dana min(7500 * operasi_penyimpanan, gas_eksekusi). Hasilnya akan menjadi bahwa, setelah dikurangi pengembalian dana, seorang pengguna dikenai biaya:
execution_gas + 10000 operasi penyimpanan - min(7500 storage_operations, execution_gas)
Yang sama dengan:
maksimum(execution_gas + 2500operasi penyimpanan, 10000storage_operations)
Ini mencerminkan struktur EIP-7623. Cara lain untuk melakukannya adalah melacak storage_operations dan execution_gas secara real time, dan menagih biaya sebesar 2500 atau 10000 tergantung seberapa banyak max(execution_gas + 2500operasi penyimpanan, 10000Operasi penyimpanan) naik pada saat opcode dipanggil. Hal ini menghindari kebutuhan transaksi untuk mengalokasikan gas berlebih yang sebagian besar akan dikembalikan melalui pengembalian dana.
Kami tidak mendapatkan izin yang sangat halus untuk sub-panggilan: sebuah sub-panggilan bisa menghabiskan semua "ijin" transaksi untuk operasi penyimpanan murah. Tetapi kami mendapatkan sesuatu yang cukup baik, di mana kontrak yang melakukan sub-panggilan dapat menetapkan batasan dan memastikan bahwa setelah sub-panggilan selesai dieksekusi, panggilan utama masih memiliki cukup gas untuk melakukan apa pun yang perlu dilakukan setelah proses.
Solusi harga penuh multidimensional paling mudah yang bisa saya pikirkan adalah: kita memperlakukan batas gas sub-call sebagai proporsional. Artinya, misalkan ada
𝑘
berbagai jenis eksekusi, dan setiap transaksi menetapkan batasan multi-dimensi
𝐿1…𝐿𝑘
. Misalkan, pada titik eksekusi saat ini, gas yang tersisa adalah
𝑔1…𝑔𝑘
Misalkan opcode CALL dipanggil, dengan batas gas sub-call
𝑆
. Biarkan
s1=𝑆
, dan kemudian
𝑠2=𝑠1𝑔1∗𝑔2
,
𝑠3=𝑠1𝑔1∗gas3
, dan sebagainya.
Yaitu, kita memperlakukan jenis gas pertama (secara realistis, eksekusi VM) sebagai jenis "unit rekening" yang istimewa, dan kemudian menetapkan jenis gas lainnya sehingga panggilan sub mendapatkan persentase yang sama dari gas yang tersedia di setiap jenis. Ini agak tidak rapi, tetapi memaksimalkan kompatibilitas mundur. Jika kita ingin membuat skema lebih "netral" antara berbagai jenis gas, dengan mengorbankan kompatibilitas mundur, kita bisa saja memiliki parameter batas gas panggilan sub mewakili pecahan (mis. [1…63] / 64) dari gas yang tersisa dalam konteks saat ini)
Dalam kedua kasus tersebut, namun, layak ditekankan bahwa begitu Anda mulai memperkenalkan gas eksekusi multidimensi, tingkat keburukan yang melekat meningkat, dan ini tampak sulit dihindari. Oleh karena itu, tugas kita adalah membuat trade-off yang rumit: apakah kita menerima sedikit lebih keburukan di tingkat EVM, untuk secara aman membuka keuntungan skalabilitas L1 yang signifikan, dan jika ya, proposal spesifik mana yang paling baik untuk ekonomi protokol dan pengembang aplikasi? Kemungkinan besar, bukan salah satu dari yang saya sebutkan di atas, dan masih ada ruang untuk menciptakan sesuatu yang lebih elegan dan lebih baik.
株式
内容
Di Ethereum, sumber daya baru-baru ini terbatas dan dipatok menggunakan satu sumber daya yang disebut “gas”. Gas adalah ukuran dari jumlah “upaya komputasi” yang diperlukan untuk memproses transaksi atau blok tertentu. Gas menggabungkan berbagai jenis “upaya”, terutama:
Sebagai contoh, transaksi inibahwa saya kirim total biaya 47.085 gas. Ini dibagi antara (i) “biaya dasar” sebesar 21.000 gas, (ii) 1556 gas untuk byte dalam calldata yang disertakan sebagai bagian dari transaksi, (iii) 16500 gas untuk membaca dan menulis ke penyimpanan, (iv) gas 2149 untuk membuat alog, dan sisanya untuk eksekusi EVM. Biaya transaksi yang harus dibayarkan oleh pengguna berbanding lurus dengan gas yang dikonsumsi oleh transaksi tersebut. Sebuah blok dapat berisi maksimum hingga 30 juta gas, dan harga gas terus disesuaikan melalui @vbuterin/eip-1559-faq">Mekanisme penargetan EIP-1559, memastikan bahwa rata-rata, blok mengandung 15 juta gas.
Pendekatan ini memiliki satu efisiensi utama: karena semua digabungkan ke dalam satu sumber daya virtual, hal ini mengarah pada desain pasar yang sangat sederhana. Mengoptimalkan transaksi untuk meminimalkan biaya menjadi mudah, mengoptimalkan blok untuk mengumpulkan biaya tertinggi mungkin relatif mudah (tidak termasuk MEV) dan tidak ada insentif aneh yang mendorong beberapa transaksi untuk dibundel dengan transaksi lain untuk menghemat biaya.
Namun pendekatan ini juga memiliki satu ketidaksempurnaan utama: itu memperlakukan sumber daya yang berbeda sebagai saling dapat dikonversi, ketika batasan sebenarnya dari apa yang jaringan dapat tangani tidak. Salah satu cara untuk memahami masalah ini adalah dengan melihat diagram ini:
Batas gas memberlakukan pembatasan
𝑥1∗𝑑𝑎𝑡𝑎+𝑥2∗𝑐𝑜𝑚𝑝𝑢𝑡𝑎𝑡𝑖𝑜𝑛<𝑁
. Kendala keamanan yang sebenarnya lebih sering berhubungan dengan
𝑚𝑎𝑥(𝑥1∗𝑑𝑎𝑡𝑎,𝑥2∗𝑐𝑜𝑚𝑝𝑢𝑡𝑎𝑡𝑖𝑜𝑛)<𝑁
Ketidaksesuaian ini mengakibatkan batas gas secara tidak perlu mengesampingkan blok yang sebenarnya aman, atau menerima blok yang sebenarnya tidak aman, atau beberapa campuran dari keduanya.
Jika ada
n
sumber daya yang memiliki batasan keamanan yang berbeda, maka gas satu dimensi secara masuk akal dapat mengurangi throughput hingga faktor
𝑛
Untuk alasan ini, telah lama ada minat dalam konsep gas multi-dimensi, dan dengan EIP-4844kami sebenarnya memiliki gas multi-dimensi yang bekerja pada Ethereum saat ini. Pos ini menjelajahi manfaat dari pendekatan ini, dan prospek untuk meningkatkannya lebih lanjut.
Di awal tahun ini, blok rata-rata 150 kB dalam ukuranSebagian besar dari ukuran tersebut adalah data rollup: protokol lapisan 2menyimpan data di chain untuk keamanan. Data ini mahal: meskipun transaksi di rollups akan biaya ~5-10x lebih sedikit dari transaksi yang sesuai di Ethereum L1, bahkan biaya tersebut terlalu tinggi untuk banyak kasus penggunaan.
Mengapa tidak mengurangi biaya gas calldata (saat ini 16 gas per byte yang bukan nol dan 4 gas per byte nol), untuk membuat rollups lebih murah? Kami melakukan ini sebelumnya, kita bisa melakukannya lagi. Jawabannya di sini adalah: ukuran kasus terburuk dari sebuah blok adalah
30,000,00016=1,875,000
byte yang tidak nol, dan jaringan sudah hampir tidak mampu menangani blok sebesar itu. Mengurangi biaya lagi 4x akan meningkatkan maksimum menjadi 7,5 MB, yang akan menjadi risiko besar untuk keselamatan.
Masalah ini akhirnya diatasi dengan memperkenalkan ruang data yang ramah rollup terpisah, yang dikenal sebagai “blob”, ke setiap blok. Kedua sumber daya memiliki harga dan batas yang terpisah: setelah hard fork Dencun, sebuah blok Ethereum dapat berisi paling banyak (i) 30 juta gas, dan (ii) 6 blob, yang dapat berisi ~125 kB data panggilan masing-masing. Kedua sumber daya memiliki harga yang terpisah, disesuaikan olehmecanisme penetapan harga mirip EIP-1559 terpisah, dengan target penggunaan rata-rata 15 juta gas dan 3 blob per blok.
Sebagai hasilnya, rollups telah menjadi 100x lebih murah, volume transaksi pada rollups meningkat lebih dari 3x, dan ukuran blok maksimum teoretis hanya sedikit meningkat: dari ~1.9 MB menjadi ~2.6 MB.
Biaya transaksi pada rollups, atas kebaikan growthepie.xyzFork Dencun, yang memperkenalkan blob dengan harga multidimensi, terjadi pada 13 Maret 2024.
Di masa depan, masalah serupa akan muncul mengenai bukti penyimpanan untuk klien tanpa status. Klien tanpa status adalah jenis klien baru yang akan dapat memverifikasi rantai tanpa menyimpan banyak atau sama sekali data secara lokal. Klien tanpa status melakukan hal ini dengan menerima bukti-bukti bagian spesifik dari status Ethereum yang transaksi dalam blok tersebut perlu sentuh.
Sebuah klien tanpa status menerima blok, bersama dengan bukti-bukti yang membuktikan nilai-nilai saat ini di bagian-bagian tertentu dari status (misalnya, saldo akun, kode, penyimpanan) yang disentuh oleh eksekusi blok tersebut. Hal ini memungkinkan sebuah node untuk memverifikasi sebuah blok tanpa harus memiliki penyimpanan sendiri.
Biaya baca penyimpanan sekitar 2100-2600 gas tergantung pada jenis bacaan, dan penulisan penyimpanan lebih mahal. Rata-rata, sebuah blok melakukan sekitar 1000 bacaan dan penulisan penyimpanan (termasuk pemeriksaan saldo ETH, panggilan SSTORE dan SLOAD, pembacaan kode kontrak, dan operasi lainnya). Namun, maksimum teoritisnya adalah
30,000,0002,100=14,285
membaca. Beban bandwidth klien stateless secara langsung berbanding lurus dengan jumlah ini.
Hari ini, rencananya adalah mendukung klien tanpa status dengan memindahkan desain pohon status Ethereum dari pohon Merkle PatriciauntukPohon VerkleNamun, pohon Verkle tidak tahan terhadap kuantum, dan tidak optimal untuk gelombang baru sistem pembuktian STARK. Sebagai hasilnya, banyak orang tertarik untuk mendukung klien tanpa status melalui pohon Merkle biner dan STARKssebagai gantinya - baik dengan melewatkan Verkle sama sekali, atau meng-upgrade beberapa tahun setelah transisi Verkle ketika STARKs menjadi lebih matang.
Bukti STARK dari cabang pohon hash biner memiliki banyak keunggulan, tetapi memiliki kelemahan kunci bahwa bukti memerlukan waktu yang lama untuk dihasilkan: sementara pohon Verklebisa membuktikanlebih dari seratus ribu nilai per detik, STARK berbasis hash biasanya hanya dapat membuktikan beberapa ribu hash per detik, dan membuktikan setiap nilai memerlukan 'cabang' yang berisi banyak hash.
Dengan angka-angka yang diproyeksikan hari ini dari sistem bukti yang sangat dioptimalkan seperti BiniusdanPlonky3dan hash khusus sepertiVisi-Mark-32, sepertinya kemungkinan besar kita akan untuk beberapa waktu berada dalam rezim di mana praktis untuk membuktikan 1.000 nilai dalam waktu kurang dari satu detik, tetapi tidak 14.285 nilai. Blok rata-rata akan baik, tetapi blok kasus terburuk, yang mungkin dipublikasikan oleh seorang penyerang, akan merusak jaringan.
Cara 'default' yang kami gunakan untuk menangani skenario tersebut adalah dengan melakukan penyesuaian harga: membuat pembacaan penyimpanan lebih mahal untuk mengurangi maksimum per blok menjadi sesuatu yang lebih aman. Namun, kami memilikisudahselesaiinibanyakwaktu, dan akan membuat terlalu banyak aplikasi terlalu mahal untuk melakukan ini lagi. Pendekatan yang lebih baik adalah gas multidimensional: batasi dan kenakan biaya untuk akses penyimpanan secara terpisah, menjaga penggunaan rata-rata pada 1.000 akses penyimpanan per blok tetapi menetapkan batas per blok misalnya 2.000.
Salah satu sumber daya lain yang layak dipertimbangkan adalah pertumbuhan ukuran status: operasi yang meningkatkan ukuran status Ethereum, yang akan perlu dipegang oleh node penuh mulai dari saat itu. Properti unik dari pertumbuhan ukuran status adalah bahwa alasan dari pembatasannya berasal sepenuhnya dari penggunaan berkelanjutan jangka panjang, dan bukan lonjakan. Oleh karena itu, mungkin ada nilai tambah dalam menambahkan dimensi gas terpisah untuk operasi peningkatan ukuran status (misalnya, SSTORE nol-ke-non-nol, penciptaan kontrak), tetapi dengan tujuan yang berbeda: kita bisa menetapkan harga mengambang untuk menargetkan penggunaan rata-rata tertentu, tetapi tidak menetapkan batasan per blok sama sekali.
Ini menunjukkan salah satu properti kuat dari gas multidimensi: itu memungkinkan kita untuk secara terpisah bertanya pertanyaan-pertanyaan (i) apa penggunaan rata-rata ideal, dan (ii) apa penggunaan maksimum per-blok yang aman, untuk setiap sumber daya. Alih-alih menetapkan harga gas berdasarkan maksimum per-blok, dan membiarkan penggunaan rata-rata mengikuti, kita memiliki
2𝑛
derajat kebebasan untuk ditetapkan
2𝑛
parameter, menyesuaikan masing-masing berdasarkan apa yang aman untuk jaringan.
Situasi yang lebih rumit, seperti di mana dua sumber daya memiliki pertimbangan keamanan yang sebagian aditif, dapat ditangani dengan membuat opcode atau biaya sumber daya beberapa jumlah dari beberapa jenis gas (misalnya, sebuah SSTORE nol-ke-non-nol bisa biaya 5000 gas bukti klien tanpa status dan 20000 gas ekspansi penyimpanan).
Biarkan
𝑥1
menjadi biaya gas data dan
𝑥2
menjadi biaya gas komputasi, sehingga dalam sistem gas satu dimensi kita dapat menulis biaya gas dari sebuah transaksi:
gas=x1*data+x2*computatio
Dalam skema ini, kami malah mendefinisikan biaya gas dari sebuah transaksi sebagai:
gas=max(x1*data,x2*computational)
Yaitu, alih-alih sebuah transaksi dikenakan biaya untuk data ditambah komputasi, transaksi tersebut dikenakan biaya berdasarkan sumber daya mana yang lebih banyak digunakan. Ini dapat dengan mudah diperluas untuk mencakup lebih banyak dimensi (misalnya.
𝑚𝑎𝑥(…,𝑥3∗𝑠𝑡𝑜𝑟𝑎𝑔𝑒_𝑎𝑐𝑐𝑒𝑠𝑠)
).
Seharusnya mudah untuk melihat bagaimana ini meningkatkan throughput sambil menjaga keselamatan. Jumlah data maksimum teoretis dalam satu blok masih
𝐺𝐴𝑆𝐿𝐼𝑀𝐼𝑇𝑥1
, persis sama seperti dalam skema gas satu dimensi. Demikian pula, jumlah komputasi maksimum teoretis adalah
𝐺𝐴𝑆𝐿𝐼𝑀𝐼𝑇𝑥2
, lagi-lagi persis sama seperti dalam skema gas satu dimensi. Namun, biaya gas dari transaksi apa pun yang mengonsumsi baik data maupun komputasi akan berkurang.
Ini kira-kira skema yang digunakan dalam usulan tersebutEIP-7623, untuk mengurangi ukuran blok maksimum sekaligus meningkatkan jumlah blob lebih lanjut. Mekanisme yang tepat dalam EIP-7623 sedikit lebih rumit: ia menjaga harga calldata saat ini sebesar 16 gas per byte, tetapi menambahkan "harga dasar" sebesar 48 gas per byte; Transaksi membayar lebih tinggi dari (16 byte + gas eksekusi) dan (48 bytes). Sebagai hasilnya, EIP-7623 mengurangi calldata transaksi maksimum teoritis dalam satu blok dari ~1.9 MB menjadi ~0.6 MB, sambil meninggalkan biaya sebagian besar aplikasi tetap sama. Manfaat dari pendekatan ini adalah bahwa ini adalah perubahan yang sangat kecil dari skema gas satu dimensi saat ini, sehingga sangat mudah untuk diimplementasikan.
Ada dua kekurangan:
Saya akan berpendapat bahwa aturan gaya EIP-7623, baik untuk data panggilan transaksi maupun untuk sumber daya lainnya, dapat memberikan manfaat yang cukup besar sehingga layak dilakukan meskipun ada kekurangan tersebut. Namun, jika dan ketika kita bersedia untuk melakukan upaya pengembangan (yang jauh lebih tinggi), ada pendekatan yang lebih ideal.
Mari kita pertama-tama mengulang kembali bagaimana EIP-1559 “biasa” bekerja. Kita akan fokus pada versi yang diperkenalkan dalam EIP-4844 untuk blobs, karena secara matematis lebih elegan.
Kami melacak parameter, excess_blobs. Selama setiap blok, kami mengatur:
kelebihan_blobs <— max(kelebihan_blobs + len(blok.blobs) - TARGET, 0)
Dimana TARGET = 3. Artinya, jika sebuah blok memiliki lebih banyak blob dari target, excess_blobs meningkat, dan jika sebuah blok memiliki kurang dari target, itu berkurang. Kami kemudian menetapkan blob_basefee = exp(excess_blobs / 25.47), di mana exp adalah perkiraan dari fungsi eksponensial
𝑒𝑥𝑝(𝑥)=2.71828𝑥
.
Yaitu, setiap kali excess_blobs meningkat sebesar ~25, basefee blob meningkat dengan faktor ~2.7. Jika blob menjadi terlalu mahal, penggunaan rata-rata turun, dan excess_blobs mulai berkurang, secara otomatis menurunkan harga kembali. Harga blob terus menyesuaikan untuk memastikan bahwa rata-rata, blok setengah penuh - yaitu, mereka mengandung rata-rata 3 blob masing-masing.
Jika terjadi lonjakan penggunaan jangka pendek, maka batasan akan berlaku: setiap blok hanya dapat berisi maksimum 6 blob, dan dalam keadaan seperti itu transaksi dapat bersaing satu sama lain dengan menawar biaya prioritas mereka. Namun, dalam kasus normal, setiap blob hanya perlu membayar blob_basefee ditambah biaya prioritas tambahan yang kecil sebagai insentif untuk disertakan secara keseluruhan.
Jenis penetapan harga seperti ini telah ada di Ethereum untuk gas selama bertahun-tahun: mekanisme yang sangat mirip diperkenalkan dengan @vbuterin/eip-1559-faq">EIP-1559 kembali pada tahun 2020. Dengan EIP-4844, sekarang kita memiliki dua harga terapung secara terpisah untuk gas dan untuk blobs.
Biaya dasar gas selama satu jam pada 08-05-2024, dalam gwei. Sumber: ultrasound.money.
Pada dasarnya, kita bisa menambahkan biaya terapung secara terpisah untuk membaca penyimpanan, dan jenis operasi lainnya, meskipun dengan satu peringatan yang akan saya perluas di bagian berikutnya.
Bagi pengguna, pengalaman ini sangat mirip dengan hari ini: alih-alih membayar satu biaya dasar, Anda membayar dua biaya dasar, tetapi dompet Anda dapat menyembunyikannya dari Anda dan hanya menunjukkan biaya yang diharapkan dan biaya maksimum yang dapat Anda harapkan untuk dibayar.
Bagi para pembangun blok, sebagian besar waktu strategi optimalnya sama seperti hari ini: termasuk segala hal yang valid. Sebagian besar blok tidak penuh - tidakdalam gasjuga tidakdalam blobKasus yang menantang adalah ketika terdapat cukup gas atau cukup blob untuk melebihi batas blok, dan pembangun perlu untuk potensial menyelesaikan sebuahMasalah ransel multidimensiuntuk memaksimalkan keuntungannya. Namun, bahkan di sana algoritma pendekatan yang cukup baik ada, dan keuntungan dari membuat algoritma propietari untuk mengoptimalkan keuntungan dalam kasus ini jauh lebih kecil dibandingkan dengan keuntungan dari melakukan hal yang sama dengan MEV.
Bagi para pengembang, tantangan utama adalah kebutuhan untuk merancang ulang fitur-fitur dari EVM, dan infrastruktur sekitarnya, yang dirancang berdasarkan satu harga dan satu batas saat ini menjadi desain yang dapat menampung berbagai harga dan berbagai batas. Salah satu masalah bagi pengembang aplikasi adalah bahwa optimisasi menjadi sedikit lebih sulit: dalam beberapa kasus, Anda tidak dapat lagi dengan tegas mengatakan bahwa A lebih efisien daripada B, karena jika A menggunakan lebih banyak calldata tetapi B menggunakan lebih banyak eksekusi, maka A mungkin lebih murah ketika calldata murah, dan lebih mahal ketika calldata mahal. Namun, para pengembang masih dapat mendapatkan hasil yang cukup baik dengan mengoptimalkan berdasarkan harga rata-rata historis jangka panjang.
Ada satu masalah yang tidak muncul dengan blob, dan tidak akan muncul dengan EIP-7623 atau bahkan implementasi harga multidimensi “penuh” untuk calldata, tetapi akan muncul jika kita mencoba membandingkan akses state secara terpisah, atau sumber daya lainnya: batas gas dalam panggilan sub.
Batas gas dalam EVM terdapat di dua tempat. Pertama, setiap transaksi menetapkan batas gas, yang membatasi jumlah total gas yang dapat digunakan dalam transaksi tersebut. Kedua, ketika kontrak memanggil kontrak lain, panggilan tersebut dapat menetapkan batas gasnya sendiri. Hal ini memungkinkan kontrak untuk memanggil kontrak lain yang tidak mereka percayai, dan masih menjamin bahwa mereka akan memiliki gas yang tersisa untuk melakukan perhitungan lain setelah panggilan tersebut.
Jejak transaksi abstraksi akun, di mana sebuah akun memanggil akun lain, dan hanya memberikan jumlah gas yang terbatas kepada penerima panggilan, untuk memastikan bahwa panggilan luar dapat terus berjalan meskipun penerima panggilan menghabiskan seluruh gas yang diberikan padanya.
Tantangannya adalah: membuat gas multidimensional di antara berbagai jenis eksekusi nampaknya akan memerlukan sub-panggilan untuk memberikan batasan ganda untuk setiap jenis gas, yang akan memerlukan perubahan yang sangat dalam pada EVM, dan tidak akan kompatibel dengan aplikasi yang sudah ada.
Ini adalah salah satu alasan mengapa proposal gas multidimensional sering berhenti pada dua dimensi: data dan eksekusi. Data (baik itu calldata transaksi atau blob) hanya ditugaskan di luar EVM, sehingga tidak ada yang perlu berubah di dalam EVM untuk membuat calldata atau blob dipisahkan harganya.
Kita dapat memikirkan solusi gaya “EIP-7623” untuk masalah ini. Berikut adalah satu implementasi sederhana: selama eksekusi, kenakan biaya 4x lebih banyak untuk operasi penyimpanan; untuk menyederhanakan analisis, katakanlah 10000 gas per operasi penyimpanan. Pada akhir transaksi, pengembalian dana min(7500 * operasi_penyimpanan, gas_eksekusi). Hasilnya akan menjadi bahwa, setelah dikurangi pengembalian dana, seorang pengguna dikenai biaya:
execution_gas + 10000 operasi penyimpanan - min(7500 storage_operations, execution_gas)
Yang sama dengan:
maksimum(execution_gas + 2500operasi penyimpanan, 10000storage_operations)
Ini mencerminkan struktur EIP-7623. Cara lain untuk melakukannya adalah melacak storage_operations dan execution_gas secara real time, dan menagih biaya sebesar 2500 atau 10000 tergantung seberapa banyak max(execution_gas + 2500operasi penyimpanan, 10000Operasi penyimpanan) naik pada saat opcode dipanggil. Hal ini menghindari kebutuhan transaksi untuk mengalokasikan gas berlebih yang sebagian besar akan dikembalikan melalui pengembalian dana.
Kami tidak mendapatkan izin yang sangat halus untuk sub-panggilan: sebuah sub-panggilan bisa menghabiskan semua "ijin" transaksi untuk operasi penyimpanan murah. Tetapi kami mendapatkan sesuatu yang cukup baik, di mana kontrak yang melakukan sub-panggilan dapat menetapkan batasan dan memastikan bahwa setelah sub-panggilan selesai dieksekusi, panggilan utama masih memiliki cukup gas untuk melakukan apa pun yang perlu dilakukan setelah proses.
Solusi harga penuh multidimensional paling mudah yang bisa saya pikirkan adalah: kita memperlakukan batas gas sub-call sebagai proporsional. Artinya, misalkan ada
𝑘
berbagai jenis eksekusi, dan setiap transaksi menetapkan batasan multi-dimensi
𝐿1…𝐿𝑘
. Misalkan, pada titik eksekusi saat ini, gas yang tersisa adalah
𝑔1…𝑔𝑘
Misalkan opcode CALL dipanggil, dengan batas gas sub-call
𝑆
. Biarkan
s1=𝑆
, dan kemudian
𝑠2=𝑠1𝑔1∗𝑔2
,
𝑠3=𝑠1𝑔1∗gas3
, dan sebagainya.
Yaitu, kita memperlakukan jenis gas pertama (secara realistis, eksekusi VM) sebagai jenis "unit rekening" yang istimewa, dan kemudian menetapkan jenis gas lainnya sehingga panggilan sub mendapatkan persentase yang sama dari gas yang tersedia di setiap jenis. Ini agak tidak rapi, tetapi memaksimalkan kompatibilitas mundur. Jika kita ingin membuat skema lebih "netral" antara berbagai jenis gas, dengan mengorbankan kompatibilitas mundur, kita bisa saja memiliki parameter batas gas panggilan sub mewakili pecahan (mis. [1…63] / 64) dari gas yang tersisa dalam konteks saat ini)
Dalam kedua kasus tersebut, namun, layak ditekankan bahwa begitu Anda mulai memperkenalkan gas eksekusi multidimensi, tingkat keburukan yang melekat meningkat, dan ini tampak sulit dihindari. Oleh karena itu, tugas kita adalah membuat trade-off yang rumit: apakah kita menerima sedikit lebih keburukan di tingkat EVM, untuk secara aman membuka keuntungan skalabilitas L1 yang signifikan, dan jika ya, proposal spesifik mana yang paling baik untuk ekonomi protokol dan pengembang aplikasi? Kemungkinan besar, bukan salah satu dari yang saya sebutkan di atas, dan masih ada ruang untuk menciptakan sesuatu yang lebih elegan dan lebih baik.