ขอขอบคุณเป็นพิเศษสำหรับ Yoav Weiss, Dan Finlay, Martin Koppelmann และทีม Arbitrum, Optimism, Polygon, Scroll และ SoulWallet สำหรับคำติชมและบทวิจารณ์
ใน โพสต์เรื่อง Three Transitions นี้ ฉันได้สรุปเหตุผลสำคัญบางประการว่าทำไมการเริ่มคิดอย่างชัดเจนเกี่ยวกับการรองรับ L1 + cross-L2 ความปลอดภัยของกระเป๋าเงิน และความเป็นส่วนตัว ว่าเป็นคุณสมบัติพื้นฐานที่จำเป็นของระบบนิเวศสแต็ก แทนที่จะสร้างแต่ละสิ่งเหล่านี้เป็น ส่วนเสริมที่สามารถออกแบบแยกกันโดยกระเป๋าสตางค์แต่ละใบ
โพสต์นี้จะเน้นโดยตรงไปที่ด้านเทคนิคของปัญหาย่อยเฉพาะเจาะจง: วิธีทำให้อ่าน L1 จาก L2 ได้ง่ายขึ้น L2 จาก L1 หรือ L2 จาก L2 อื่น การแก้ปัญหานี้ถือเป็นสิ่งสำคัญสำหรับการนำสถาปัตยกรรมการแยก Asset / Keystore ไปใช้ แต่ก็มีกรณีการใช้งานที่มีคุณค่าในด้านอื่นๆ โดยเฉพาะอย่างยิ่งการเพิ่มประสิทธิภาพการเรียกข้าม L2 ที่เชื่อถือได้ รวมถึงกรณีการใช้งาน เช่น การย้ายสินทรัพย์ระหว่าง L1 และ L2
เมื่อ L2 กลายเป็นกระแสหลักมากขึ้น ผู้ใช้จะมีสินทรัพย์ใน L2 หลายตัว และอาจเป็น L1 ด้วยเช่นกัน เมื่อกระเป๋าเงินสัญญาอัจฉริยะ (multisig, การฟื้นฟูทางสังคมหรืออย่างอื่น) กลายเป็นกระแสหลัก คีย์ที่จำเป็นในการเข้าถึงบัญชีบางส่วนจะมีการเปลี่ยนแปลงเมื่อเวลาผ่านไป และคีย์เก่าจะต้องใช้ไม่ได้อีกต่อไป เมื่อทั้งสองสิ่งนี้เกิดขึ้น ผู้ใช้จะต้องมีวิธีในการเปลี่ยนคีย์ที่มีสิทธิ์ในการเข้าถึงบัญชีจำนวนมากซึ่งอาศัยอยู่ในที่ต่างๆ มากมาย โดยไม่ต้องทำธุรกรรมเป็นจำนวนมาก
โดยเฉพาะอย่างยิ่ง เราต้องการวิธีจัดการกับที่อยู่ปลอม: ที่อยู่ที่ยังไม่ได้ "ลงทะเบียน" ด้วยวิธีใด ๆ บนเครือข่าย แต่ยังจำเป็นต้องได้รับและเก็บเงินไว้อย่างปลอดภัย เราทุกคนขึ้นอยู่กับที่อยู่ที่ไม่เป็นความจริง: เมื่อคุณใช้ Ethereum เป็นครั้งแรก คุณสามารถสร้างที่อยู่ ETH ที่ใครบางคนสามารถใช้เพื่อจ่ายเงินให้คุณได้ โดยไม่ต้อง "ลงทะเบียน" ที่อยู่แบบออนไลน์ (ซึ่งจะต้องเสียค่าธรรมเนียม txfees และด้วยเหตุนี้ มี ETH บางส่วนอยู่แล้ว)
เมื่อใช้ EOA ที่อยู่ทั้งหมดจะเริ่มต้นด้วยที่อยู่ที่ไม่เป็นข้อเท็จจริง ด้วยกระเป๋าเงินสัญญาอัจฉริยะ ที่อยู่ที่เป็นเท็จยังคงเป็นไปได้ ส่วนใหญ่ต้องขอบคุณ CREATE2 ซึ่งช่วยให้คุณมีที่อยู่ ETH ที่สามารถเติมได้ด้วยสัญญาอัจฉริยะที่มีรหัสที่ตรงกับแฮชเฉพาะเท่านั้น
อัลกอริธึมการคำนวณที่อยู่ EIP-1014 (CREATE2)
อย่างไรก็ตาม กระเป๋าเงินสัญญาอัจฉริยะนำเสนอความท้าทายใหม่: ความเป็นไปได้ในการเปลี่ยนแปลงคีย์การเข้าถึง ที่อยู่ซึ่งเป็นแฮชของรหัสเริ่มต้นจะมีได้เฉพาะรหัสยืนยันเริ่มต้นของกระเป๋าเงินเท่านั้น คีย์การยืนยันปัจจุบันจะถูกจัดเก็บไว้ในที่เก็บข้อมูลของกระเป๋าเงิน แต่บันทึกการจัดเก็บข้อมูลนั้นจะไม่เผยแพร่ไปยัง L2 อื่น ๆ อย่างน่าอัศจรรย์
หากผู้ใช้มีที่อยู่จำนวนมากใน L2 จำนวนมาก รวมถึงที่อยู่ที่ (เนื่องจากเป็นข้อมูลที่ไม่เป็นจริง) โดย L2 ที่พวกเขาอยู่ไม่ทราบ ดูเหมือนว่ามีเพียงวิธีเดียวเท่านั้นที่จะอนุญาตให้ผู้ใช้เปลี่ยนคีย์ของตนได้: สินทรัพย์ / ที่เก็บคีย์ สถาปัตยกรรมการแยก ผู้ใช้แต่ละรายมี (i) “สัญญาที่เก็บคีย์” (บน L1 หรือบน L2 หนึ่งรายการ) ซึ่งจัดเก็บคีย์การตรวจสอบสำหรับกระเป๋าเงินทั้งหมดพร้อมกับกฎสำหรับการเปลี่ยนรหัส และ (ii) “สัญญากระเป๋าเงิน” บน L1 และอีกมาก L2 ซึ่งอ่าน cross-chain เพื่อรับรหัสยืนยัน
มีสองวิธีในการดำเนินการนี้:
เพื่อแสดงความซับซ้อนทั้งหมด เราจะสำรวจกรณีที่ยากที่สุด: โดยที่ที่เก็บคีย์อยู่ที่ L2 อันหนึ่ง และกระเป๋าเงินอยู่บน L2 อื่น หากที่เก็บคีย์หรือกระเป๋าเงินอยู่บน L1 ก็จำเป็นต้องใช้การออกแบบนี้เพียงครึ่งหนึ่งเท่านั้น
สมมติว่าที่เก็บคีย์อยู่บน Linea และกระเป๋าเงินอยู่บน Kakarot หลักฐานกุญแจเข้ากระเป๋าสตางค์ฉบับเต็มประกอบด้วย:
มีคำถามหลักๆ เกี่ยวกับการใช้งานที่ยุ่งยากสองข้อที่นี่:
มีห้าตัวเลือกหลัก:
ในแง่ของงานโครงสร้างพื้นฐานที่จำเป็นและต้นทุนสำหรับผู้ใช้ ฉันจัดอันดับคร่าวๆ ดังนี้:
“การรวมกลุ่ม” หมายถึงแนวคิดในการรวบรวมการพิสูจน์ทั้งหมดที่ผู้ใช้จัดทำไว้ภายในแต่ละบล็อกให้เป็น meta-proof ขนาดใหญ่ที่รวมเอาทั้งหมดเข้าด้วยกัน สิ่งนี้เป็นไปได้สำหรับ SNARK และสำหรับ KZG แต่ไม่ใช่สำหรับสาขา Merkle (คุณสามารถ รวมสาขา Merkle ได้นิดหน่อย แต่จะช่วยคุณบันทึกเท่านั้น (txs ต่อบล็อก) / log (จำนวนที่เก็บคีย์ทั้งหมด) อาจ 15-30% ในทางปฏิบัติจึงไม่คุ้มกับต้นทุน)
การรวมกลุ่มจะคุ้มค่าก็ต่อเมื่อสคีมมีผู้ใช้จำนวนมาก ดังนั้น ตามความเป็นจริงแล้ว การใช้งานเวอร์ชัน 1 จึงไม่ต้องมีการรวมกลุ่ม และนำไปใช้กับเวอร์ชัน 2 ตามความเป็นจริง
อันนี้ง่าย: ทำตาม แผนภาพในส่วนก่อนหน้า โดยตรง แม่นยำยิ่งขึ้น แต่ละ "การพิสูจน์" (สมมติว่าเป็นกรณีความยากสูงสุดในการพิสูจน์ L2 หนึ่งไปยัง L2 อีกอันหนึ่ง) จะมี:
น่าเสียดายที่การพิสูจน์สถานะ Ethereum มีความซับซ้อน แต่มี ไลบรารีสำหรับตรวจสอบ และหากคุณใช้ไลบรารีเหล่านี้ กลไกนี้ไม่ซับซ้อนเกินกว่าจะนำไปใช้
ปัญหาที่ใหญ่กว่าคือต้นทุน การพิสูจน์ Merkle นั้นยาว และน่าเสียดายที่ต้นไม้ Patricia นั้นยาวเกินความจำเป็น ~3.9 เท่า (แม่นยำ: การพิสูจน์ Merkle ในอุดมคติในต้นไม้ที่ถือวัตถุ N นั้นมี ความยาว 32 log2(N) ไบต์ และเนื่องจากต้นไม้ Patricia ของ Ethereum มี 16 ใบต่อเด็กหนึ่งคน การพิสูจน์ สำหรับต้นไม้เหล่านั้นมีความยาว 32 15 log16(N) ~= 125 log2(N) ไบต์) ในสถานะที่มี บัญชีประมาณ 250 ล้าน (~2²⁸) บัญชี ทำให้แต่ละบัญชีพิสูจน์ได้ 125 * 28 = 3,500 ไบต์หรือประมาณ 56,000 gas รวมถึงค่าใช้จ่ายเพิ่มเติมสำหรับการถอดรหัสและการตรวจสอบแฮช
การพิสูจน์สองรายการร่วมกันจะมีราคาประมาณ 100,000 ถึง 150,000 Gas (ไม่รวมการตรวจสอบลายเซ็นหากใช้ต่อธุรกรรม) ซึ่งมากกว่าฐานปัจจุบัน 21,000 Gas ต่อธุรกรรมอย่างมีนัยสำคัญ แต่ความแตกต่างจะแย่ลงหากการพิสูจน์ได้รับการตรวจสอบบน L2 การคำนวณภายใน L2 มีราคาถูก เนื่องจากการคำนวณเสร็จสิ้นแบบออฟไลน์และในระบบนิเวศที่มีโหนดน้อยกว่า L1 มาก ในทางกลับกัน ข้อมูลจะต้องโพสต์ไปที่ L1 ดังนั้นการเปรียบเทียบจึงไม่ใช่ 21,000 ก๊าซกับ 150,000 ก๊าซ มันคือ 21,000 L2 ก๊าซเทียบกับ 100,000 L1 ก๊าซ
เราสามารถคำนวณความหมายได้โดยดูการเปรียบเทียบระหว่างต้นทุนก๊าซ L1 และต้นทุนก๊าซ L2:
ปัจจุบัน L1 มีราคาแพงกว่า L2 ประมาณ 15-25 เท่าสำหรับการส่งแบบธรรมดา และแพงกว่าประมาณ 20-50 เท่าสำหรับการแลกเปลี่ยนโทเค็น การส่งแบบธรรมดานั้นมีข้อมูลค่อนข้างหนัก แต่สวอปนั้นต้องใช้การคำนวณมากกว่ามาก ดังนั้น สวอปจึงเป็นเกณฑ์มาตรฐานที่ดีกว่าในการประมาณต้นทุนของการคำนวณ L1 เทียบกับการคำนวณ L2 เมื่อพิจารณาทั้งหมดนี้แล้ว ถ้าเราถือว่าอัตราส่วนต้นทุน 30 เท่าระหว่างต้นทุนการคำนวณ L1 และต้นทุนการคำนวณ L2 ดูเหมือนว่าจะบอกเป็นนัยว่าการใส่ Merkle proof บน L2 จะมีราคาเทียบเท่ากับธุรกรรมปกติประมาณห้าสิบครั้ง
แน่นอนว่าการใช้ binary Merkle tree สามารถลดต้นทุนได้ ~4x แต่ถึงกระนั้น ค่าใช้จ่ายในกรณีส่วนใหญ่จะสูงเกินไป - และถ้าเราเต็มใจที่จะเสียสละเพราะไม่สามารถเข้ากันได้กับ hexary ในปัจจุบันของ Ethereum อีกต่อไป ต้นไม้ประจำรัฐ เราอาจแสวงหาทางเลือกที่ดีกว่านี้เช่นกัน
ตามหลักการแล้ว การใช้ ZK-SNARK ก็เข้าใจได้ง่ายเช่นกัน เพียงคุณแทนที่การพิสูจน์ Merkle ใน แผนภาพด้านบน ด้วย ZK-SNARK เพื่อพิสูจน์ว่าการพิสูจน์ Merkle เหล่านั้นมีอยู่จริง ZK-SNARK มีค่าใช้จ่ายประมาณ 400,000 Gas ในการคำนวณ และประมาณ 400 ไบต์ (เปรียบเทียบ: 21,000 Gas และ 100 ไบต์สำหรับธุรกรรมพื้นฐาน ในอนาคต จะลดเหลือ ~25 ไบต์ด้วยการบีบอัด) ดังนั้น จากมุมมองด้านการคำนวณ ZK-SNARK มีราคา 19 เท่าของต้นทุนของธุรกรรมพื้นฐานในปัจจุบัน และจากมุมมองข้อมูล ZK-SNARK มีราคา 4 เท่าของธุรกรรมพื้นฐานในปัจจุบัน และ 16 เท่าของต้นทุนของธุรกรรมพื้นฐาน อนาคต.
ตัวเลขเหล่านี้เป็นการปรับปรุงอย่างมากจากการพิสูจน์ของ Merkle แต่ก็ยังมีราคาค่อนข้างแพง มีสองวิธีในการปรับปรุง: (i) การพิสูจน์ KZG ที่มีจุดประสงค์พิเศษ หรือ (ii) การรวมกลุ่ม คล้ายกับ การรวม ERC-4337 แต่ใช้คณิตศาสตร์ที่ซับซ้อนกว่า เราสามารถดูทั้งสองอย่างได้
คำเตือน ส่วนนี้เนื้อหาเข้มข้นกว่าส่วนอื่นๆ มาก เนื่องจากเรากำลังก้าวไปไกลกว่าเครื่องมือทั่วไปและสร้างบางสิ่งที่มีจุดประสงค์พิเศษให้มีราคาถูกลง ดังนั้นเราจึงต้อง "ซ่อนเร้น" มากกว่านี้มาก หากคุณไม่ชอบคณิตศาสตร์เชิงลึก ให้ข้ามไปยัง หัวข้อถัดไปเลย
ขั้นแรก สรุปว่าข้อผูกพันของ KZG ทำงานอย่างไร:
คุณสมบัติหลักบางประการที่สำคัญที่ต้องเข้าใจคือ:
ดังนั้นเราจึงมีโครงสร้างที่คุณสามารถเพิ่มมูลค่าต่อท้ายรายการที่เพิ่มขึ้นเรื่อยๆ แม้ว่าจะมีขีดจำกัดขนาดอยู่ก็ตาม (ตามความเป็นจริง หลายร้อยล้านรายการอาจใช้งานได้) จากนั้นเราจะใช้สิ่งนั้นเป็นโครงสร้างข้อมูลของเราในการจัดการ (i) ข้อผูกพันต่อรายการคีย์ในแต่ละ L2 ซึ่งจัดเก็บไว้ใน L2 นั้นและมิเรอร์ไปยัง L1 และ (ii) ข้อผูกพันต่อรายการข้อผูกพันคีย์ L2 ซึ่งจัดเก็บไว้ใน Ethereum L1 และสะท้อนไปยัง L2 แต่ละตัว
การปรับปรุงข้อผูกพันอาจกลายเป็นส่วนหนึ่งของตรรกะ L2 หลัก หรืออาจนำไปใช้ได้โดยไม่ต้องเปลี่ยนโปรโตคอลหลัก L2 ผ่านทางสะพานฝากและถอน
หลักฐานที่สมบูรณ์จะต้องมี:
จริงๆ แล้ว เป็นไปได้ที่จะรวมการพิสูจน์ KZG ทั้งสองเป็นอันเดียว ดังนั้นเราจึงได้ขนาดรวมเพียง 100 ไบต์
หมายเหตุรายละเอียดปลีกย่อยประการหนึ่ง: เนื่องจากรายการคีย์คือรายการ และไม่ใช่แมปคีย์/ค่าเหมือนกับสถานะ รายการคีย์จึงต้องกำหนดตำแหน่งตามลำดับ สัญญาข้อผูกมัดหลักจะมีรีจิสทรีภายในของตัวเองที่แมปแต่ละที่เก็บคีย์กับ ID และสำหรับแต่ละคีย์จะจัดเก็บแฮช (คีย์ ที่อยู่ของที่เก็บคีย์) แทนที่จะเป็นเพียงคีย์ เพื่อสื่อสารกับ L2 อื่น ๆ อย่างชัดเจนซึ่งที่เก็บคีย์รายการเฉพาะคือ พูดคุยเกี่ยวกับ.
ข้อดีของเทคนิคนี้คือมันทำงานได้ดีมากบน L2 ข้อมูลมีขนาด 100 ไบต์ สั้นกว่า ZK-SNARK ประมาณ 4 เท่า และสั้นกว่าการพิสูจน์ Merkle มาก ค่าใช้จ่ายในการคำนวณส่วนใหญ่เป็นเช็คจับคู่ขนาด 2 เดียวหรือ ประมาณ 119,000 แก๊ส บน L1 ข้อมูลมีความสำคัญน้อยกว่าการคำนวณ และน่าเสียดายที่ KZG ค่อนข้างแพงกว่าการพิสูจน์ Merkle
โดยพื้นฐานแล้ว Verkle tree เกี่ยวข้องกับการซ้อนข้อผูกพัน KZG (หรือ ข้อผูกพัน IPA ซึ่งสามารถมีประสิทธิภาพมากกว่าและใช้การเข้ารหัสที่ง่ายกว่า) ทับซ้อนกัน: เพื่อจัดเก็บค่า 2⁴⁸ คุณสามารถกำหนดข้อผูกพัน KZG ในรายการค่า 2²⁴ ซึ่งแต่ละค่านั้นเอง คือความมุ่งมั่นของ KZG ต่อค่านิยม 2²⁴ ต้นไม้ Verkle<a href="https://notes.ethereum.org/ @vbuterin /verkle_tree_eip">แข็งแกร่ง พิจารณาสำหรับแผนผังสถานะ Ethereum เนื่องจากต้นไม้ Verkle สามารถใช้เพื่อเก็บแผนที่คีย์-ค่าและไม่ใช่แค่รายการ (โดยพื้นฐานแล้ว คุณสามารถสร้างแผนภูมิขนาด-2²⁵⁶ ได้ แต่เริ่มต้นให้ว่างเปล่า โดยกรอกเฉพาะบางส่วนของแผนผังเมื่อคุณทำจริงแล้ว จำเป็นต้องกรอก)
ต้นไม้ Verkle มีลักษณะอย่างไร ในทางปฏิบัติ คุณอาจให้แต่ละโหนดมีความกว้าง 256 == 2⁸ สำหรับทรีที่ใช้ IPA หรือ 2²⁴ สำหรับทรีที่ใช้ KZG
การพิสูจน์ในต้นไม้ Verkle นั้นค่อนข้างยาวกว่า KZG; อาจมีความยาวสองสามร้อยไบต์ นอกจากนี้ยังตรวจสอบได้ยาก โดยเฉพาะอย่างยิ่งหากคุณพยายามรวมการพิสูจน์หลายรายการไว้ในที่เดียว
ตามความเป็นจริงแล้ว ต้นไม้ Verkle ควรได้รับการพิจารณาให้เหมือนกับต้นไม้ Merkle แต่สามารถทำงานได้มากกว่าหากไม่มี SNARKing (เนื่องจากต้นทุนข้อมูลที่ต่ำกว่า) และถูกกว่าด้วย SNARKing (เนื่องจากต้นทุนตัวพิสูจน์ที่ต่ำกว่า)
ข้อได้เปรียบที่ใหญ่ที่สุดของต้นไม้ Verkle คือความเป็นไปได้ในการประสานโครงสร้างข้อมูล: Verkle proofs สามารถใช้โดยตรงบนสถานะ L1 หรือ L2 โดยไม่มีโครงสร้างซ้อนทับ และใช้กลไกเดียวกันทุกประการสำหรับ L1 และ L2 เมื่อคอมพิวเตอร์ควอนตัมกลายเป็นปัญหา หรือเมื่อพิสูจน์ว่าสาขาของ Merkle มีประสิทธิภาพเพียงพอแล้ว Verkle tree ก็ถูกแทนที่ด้วยแผนผังแฮชไบนารีที่มีฟังก์ชันแฮชที่เป็นมิตรกับ SNARK ที่เหมาะสม
หากผู้ใช้ N ทำธุรกรรม N (หรือตามความเป็นจริงมากกว่านั้น N ERC-4337 UserOperations) ที่ต้องพิสูจน์การอ้างสิทธิ์แบบข้ามสาย N เราสามารถประหยัดน้ำมันได้มากโดยการรวบรวมการพิสูจน์เหล่านั้น: ตัวสร้างที่จะรวมธุรกรรมเหล่านั้นไว้ในบล็อก หรือบันเดิลที่เข้าไปในบล็อกสามารถสร้างหลักฐานเดียวที่พิสูจน์การอ้างสิทธิ์เหล่านั้นทั้งหมดพร้อมกัน
นี่อาจหมายถึง:
ในทั้งสามกรณี การพิสูจน์แต่ละครั้งจะใช้ค่าน้ำมันเพียงไม่กี่แสนเท่านั้น ตัวสร้างจะต้องสร้างอย่างใดอย่างหนึ่งบน L2 แต่ละตัวสำหรับผู้ใช้ใน L2 นั้น ดังนั้น เพื่อให้สิ่งนี้มีประโยชน์ในการสร้าง โครงการโดยรวมจำเป็นต้องมีการใช้งานเพียงพอ โดยมักจะมีธุรกรรมอย่างน้อยสองสามรายการภายในบล็อกเดียวกันบน L2 หลักหลายรายการ
หากใช้ ZK-SNARK ต้นทุนส่วนเพิ่มหลักเป็นเพียง "ตรรกะทางธุรกิจ" ในการส่งตัวเลขไปมาระหว่างสัญญา ดังนั้นอาจมีก๊าซ L2 สองสามพันต่อผู้ใช้ หากใช้การพิสูจน์หลายรายการของ KZG ผู้พิสูจน์จะต้องเพิ่มก๊าซ 48 หน่วยสำหรับ L2 ที่เก็บคีย์แต่ละอันที่ใช้ภายในบล็อกนั้น ดังนั้นต้นทุนส่วนเพิ่มของโครงการต่อผู้ใช้จะบวกก๊าซอีกประมาณ 800 L1 ต่อ L2 (ไม่ใช่ต่อ ผู้ใช้) ด้านบน แต่ต้นทุนเหล่านี้ต่ำกว่าต้นทุนของการไม่รวมกลุ่มอย่างมาก ซึ่งย่อมเกี่ยวข้องกับก๊าซ L1 มากกว่า 10,000 ลิตรและก๊าซ L2 หลายแสนต่อผู้ใช้อย่างหลีกเลี่ยงไม่ได้ สำหรับ Verkle tree คุณสามารถใช้ Verkle multi-proofs ได้โดยตรง โดยเพิ่มประมาณ 100-200 ไบต์ต่อผู้ใช้ หรือคุณสามารถสร้าง ZK-SNARK ของ Verkle multi-proofs ได้ ซึ่งมีต้นทุนใกล้เคียงกับ ZK-SNARKs ของสาขา Merkle แต่ ถูกกว่ามากในการพิสูจน์
จากมุมมองของการนำไปปฏิบัติ อาจเป็นการดีที่สุดที่จะมีการรวมการพิสูจน์ข้ามสายโซ่ผ่านมาตรฐานการแยกบัญชี ERC-4337 ERC-4337 มีกลไกสำหรับผู้สร้างเพื่อรวมส่วนของ UserOperations ด้วยวิธีที่กำหนดเองอยู่แล้ว มีแม้กระทั่ง <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> การใช้งานสิ่งนี้สำหรับการรวมลายเซ็น BLS ซึ่งสามารถลดต้นทุนก๊าซใน L2 ลง 1.5x ถึง 3x ขึ้นอยู่กับ รูปแบบการบีบอัดอื่น ๆ รวมอยู่ด้วย
แผนภาพจาก <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> โพสต์การใช้งานกระเป๋าเงิน BLS ที่แสดงขั้นตอนการทำงานของลายเซ็นรวม BLS ภายใน ERC-4337 เวอร์ชันก่อนหน้า ขั้นตอนการทำงานของการรวมการพิสูจน์ข้ามสายโซ่จะมีลักษณะคล้ายกันมาก
ความเป็นไปได้ขั้นสุดท้าย และสิ่งหนึ่งที่ใช้ได้กับ L2 ที่อ่าน L1 เท่านั้น (และไม่ใช่ L1 ที่อ่าน L2) คือการแก้ไข L2 เพื่อให้พวกมันทำการเรียกแบบคงที่ไปยังสัญญาบน L1 โดยตรง
ซึ่งสามารถทำได้ด้วย opcode หรือพรีคอมไพล์ ซึ่งอนุญาตให้เรียกเข้าสู่ L1 โดยที่คุณระบุที่อยู่ปลายทาง gas และข้อมูลการโทร และส่งคืนเอาต์พุต แม้ว่าเนื่องจากการเรียกเหล่านี้เป็นการเรียกแบบคงที่ จึงไม่สามารถเปลี่ยนสถานะ L1 ใด ๆ ได้ L2 ต้องระวัง L1 อยู่แล้วในการดำเนินการฝากเงิน ดังนั้นจึงไม่มีพื้นฐานใดที่จะหยุดยั้งการดำเนินการดังกล่าวได้ มันเป็นความท้าทายในการใช้งานทางเทคนิคเป็นหลัก (ดู: RFP นี้จากการมองในแง่ดีเพื่อรองรับการโทรแบบคงที่ใน L1)
โปรดสังเกตว่าหากที่เก็บคีย์อยู่บน L1 และ L2 รวมฟังก์ชันการโทรแบบคงที่ของ L1 ไว้ ก็ไม่จำเป็นต้องมีการพิสูจน์เลย! อย่างไรก็ตาม หาก L2 ไม่รวมการโทรแบบคงที่ของ L1 หรือหากที่เก็บคีย์อยู่บน L2 (ซึ่งอาจต้องเป็นเช่นนั้นในที่สุด เมื่อ L1 มีราคาแพงเกินไปสำหรับผู้ใช้ที่จะใช้แม้แต่น้อย) ก็จำเป็นต้องมีการพิสูจน์
รูปแบบทั้งหมดข้างต้นจำเป็นต้องใช้ L2 เพื่อเข้าถึงรูทของสถานะ L1 ล่าสุด หรือสถานะ L1 ล่าสุดทั้งหมด โชคดีที่ L2 ทั้งหมดมีฟังก์ชันบางอย่างในการเข้าถึงสถานะ L1 ล่าสุดอยู่แล้ว เนื่องจากพวกเขาต้องการฟังก์ชันดังกล่าวในการประมวลผลข้อความที่เข้ามาจาก L1 ถึง L2 โดยเฉพาะเงินฝาก
และจริงๆ แล้ว ถ้า L2 มีฟีเจอร์การฝากเงิน คุณสามารถใช้ L2 ตามที่เป็นอยู่เพื่อย้าย L1 state root ไปเป็นสัญญาบน L2: เพียงแค่มีสัญญาใน L1 เรียก opcode ของ BLOCKHASH แล้วส่งต่อให้ L2 เป็น ข้อความการฝากเงิน สามารถรับส่วนหัวของบล็อกแบบเต็มได้ และรากสถานะจะถูกแยกออกที่ฝั่ง L2 อย่างไรก็ตาม มันจะดีกว่ามากสำหรับ L2 ทุกตัวที่จะมีวิธีที่ชัดเจนในการเข้าถึงสถานะ L1 ล่าสุดแบบเต็มหรือรูทสถานะ L1 ล่าสุดโดยตรง
ความท้าทายหลักในการเพิ่มประสิทธิภาพวิธีที่ L2 ได้รับสถานะ L1 ล่าสุดคือการบรรลุความปลอดภัยและความหน่วงต่ำไปพร้อมๆ กัน:
นอกจากนี้ ในทิศทางตรงกันข้าม (L1 อ่านว่า L2):
ความเร็วบางส่วนสำหรับการดำเนินการข้ามสายโซ่ที่ไม่น่าเชื่อถือนั้นช้าจนไม่อาจยอมรับได้สำหรับกรณีการใช้งาน defi หลายกรณี ในกรณีดังกล่าว คุณจะต้องมีบริดจ์ที่เร็วกว่าพร้อมกับโมเดลความปลอดภัยที่ไม่สมบูรณ์มากกว่า อย่างไรก็ตาม สำหรับกรณีการใช้งานในการอัปเดตคีย์กระเป๋าสตางค์ ความล่าช้าที่นานกว่านั้นเป็นที่ยอมรับมากกว่า: คุณไม่ได้ชะลอการทำธุรกรรมเป็นชั่วโมง แต่คุณกำลังชะลอการเปลี่ยนแปลงคีย์ คุณจะต้องเก็บกุญแจเก่าไว้อีกต่อไป หากคุณกำลังเปลี่ยนกุญแจเนื่องจากกุญแจถูกขโมย คุณจะมีช่องโหว่อยู่ช่วงหนึ่ง แต่สามารถบรรเทาได้ เช่น โดยกระเป๋าเงินมีฟังก์ชั่นแช่แข็ง
ท้ายที่สุดแล้ว โซลูชันการลดเวลาแฝงที่ดีที่สุดคือให้ L2 ใช้การอ่านโดยตรงของรากสถานะ L1 ในวิธีที่เหมาะสมที่สุด โดยแต่ละบล็อก L2 (หรือบันทึกการคำนวณรากสถานะ) มีตัวชี้ไปยังบล็อก L1 ล่าสุด ดังนั้นหาก L1 เปลี่ยนกลับ , L2 สามารถย้อนกลับได้เช่นกัน ควรวางสัญญา Keystore บน mainnet หรือบน L2 ที่เป็น ZK-rollups และสามารถผูกมัดกับ L1 ได้อย่างรวดเร็ว
บล็อกของสายโซ่ L2 สามารถพึ่งพาได้ไม่เพียงแต่บล็อก L2 ก่อนหน้าเท่านั้น แต่ยังรวมถึงบล็อก L1 ด้วย หาก L1 ย้อนกลับผ่านลิงก์ดังกล่าว L2 จะย้อนกลับด้วย เป็นที่น่าสังเกตว่านี่คือวิธีที่ Sharding เวอร์ชันก่อนหน้า (ก่อน Dank) ถูกจินตนาการให้ใช้งานได้ ดู ที่นี่ สำหรับรหัส
น่าแปลกที่ไม่มากขนาดนั้น จริงๆ แล้วไม่จำเป็นต้องเป็น Rollup ด้วยซ้ำ หากเป็น L3 หรือ Validium ก็ไม่เป็นไรที่จะถือ Wallet ไว้ที่นั่น ตราบใดที่คุณถือ Keystores บน L1 หรือ ZK Rollup สิ่งที่คุณต้องการคือเพื่อให้เชนสามารถเข้าถึงรากของสถานะ Ethereum ได้โดยตรง และความมุ่งมั่นด้านเทคนิคและสังคมที่จะเต็มใจที่จะจัดระเบียบใหม่หาก Ethereum มีองค์กรใหม่ และฮาร์ดฟอร์คหาก Ethereum ฮาร์ดฟอร์ค
ปัญหาการวิจัยที่น่าสนใจประการหนึ่งคือการระบุว่าเป็นไปได้มากน้อยเพียงใดที่เครือข่ายจะมีรูปแบบการเชื่อมต่อกับเครือข่ายอื่นๆ จำนวนมาก (เช่น อีเธอเรียม และ Zcash) การทำแบบไร้เดียงสานั้นเป็นไปได้: chain ของคุณอาจตกลงที่จะจัดตั้งใหม่หาก Ethereum หรือ Zcash reorg (และ hard fork หาก Ethereum หรือ Zcash hard fork) แต่โดยทั่วไปแล้วผู้ดำเนินการโหนดของคุณและชุมชนของคุณโดยทั่วไปจะมีการพึ่งพาทางเทคนิคและการเมืองเป็นสองเท่า ดังนั้นเทคนิคดังกล่าวจึงสามารถนำไปใช้เชื่อมต่อกับเครือข่ายอื่นๆ ได้ แต่จะมีต้นทุนเพิ่มขึ้น แบบแผนที่ใช้ บริดจ์ ZK มีคุณสมบัติทางเทคนิคที่น่าสนใจ แต่มีจุดอ่อนที่สำคัญคือไม่แข็งแกร่งต่อการโจมตี 51% หรือฮาร์ดฟอร์ก อาจมีวิธีแก้ปัญหาที่ชาญฉลาดกว่านี้
ตามหลักการแล้ว เรายังต้องการรักษาความเป็นส่วนตัวด้วย หากคุณมีกระเป๋าสตางค์หลายใบที่ได้รับการจัดการโดยที่เก็บคีย์เดียวกัน เราต้องการให้แน่ใจว่า:
สิ่งนี้ทำให้เกิดปัญหาบางประการ:
ด้วย SNARK วิธีแก้ปัญหานั้นง่ายตามแนวคิด: การพิสูจน์จะซ่อนข้อมูลไว้ตามค่าเริ่มต้น และผู้รวบรวมจำเป็นต้องสร้าง SNARK แบบเรียกซ้ำเพื่อพิสูจน์ SNARK
ความท้าทายหลักของแนวทางนี้ในปัจจุบันก็คือ การรวมกลุ่มต้องการให้ผู้รวบรวมสร้าง SNARK แบบเรียกซ้ำ ซึ่งปัจจุบันค่อนข้างช้า
ด้วย KZG เราสามารถใช้<a href="https://notes.ethereum.org/ @vbuterin /non_index_revealing_proof">สิ่งนี้ ทำงานเกี่ยวกับการพิสูจน์ KZG ที่ไม่เปิดเผยดัชนี (ดูเพิ่มเติมที่: เวอร์ชันที่เป็นทางการมากขึ้นของงานนั้นใน กระดาษ Caulk ) เป็นจุดเริ่มต้น อย่างไรก็ตาม การรวมหลักฐานที่ปกปิดไว้เป็นปัญหาเปิดที่ต้องให้ความสนใจมากขึ้น
น่าเสียดายที่การอ่าน L1 โดยตรงจากภายใน L2 ไม่ได้รักษาความเป็นส่วนตัว แม้ว่าการนำฟังก์ชันการอ่านโดยตรงไปใช้ยังคงมีประโยชน์มาก ทั้งเพื่อลดเวลาแฝงให้เหลือน้อยที่สุดและเนื่องจากประโยชน์ใช้สอยสำหรับแอปพลิเคชันอื่นๆ
Bagikan
ขอขอบคุณเป็นพิเศษสำหรับ Yoav Weiss, Dan Finlay, Martin Koppelmann และทีม Arbitrum, Optimism, Polygon, Scroll และ SoulWallet สำหรับคำติชมและบทวิจารณ์
ใน โพสต์เรื่อง Three Transitions นี้ ฉันได้สรุปเหตุผลสำคัญบางประการว่าทำไมการเริ่มคิดอย่างชัดเจนเกี่ยวกับการรองรับ L1 + cross-L2 ความปลอดภัยของกระเป๋าเงิน และความเป็นส่วนตัว ว่าเป็นคุณสมบัติพื้นฐานที่จำเป็นของระบบนิเวศสแต็ก แทนที่จะสร้างแต่ละสิ่งเหล่านี้เป็น ส่วนเสริมที่สามารถออกแบบแยกกันโดยกระเป๋าสตางค์แต่ละใบ
โพสต์นี้จะเน้นโดยตรงไปที่ด้านเทคนิคของปัญหาย่อยเฉพาะเจาะจง: วิธีทำให้อ่าน L1 จาก L2 ได้ง่ายขึ้น L2 จาก L1 หรือ L2 จาก L2 อื่น การแก้ปัญหานี้ถือเป็นสิ่งสำคัญสำหรับการนำสถาปัตยกรรมการแยก Asset / Keystore ไปใช้ แต่ก็มีกรณีการใช้งานที่มีคุณค่าในด้านอื่นๆ โดยเฉพาะอย่างยิ่งการเพิ่มประสิทธิภาพการเรียกข้าม L2 ที่เชื่อถือได้ รวมถึงกรณีการใช้งาน เช่น การย้ายสินทรัพย์ระหว่าง L1 และ L2
เมื่อ L2 กลายเป็นกระแสหลักมากขึ้น ผู้ใช้จะมีสินทรัพย์ใน L2 หลายตัว และอาจเป็น L1 ด้วยเช่นกัน เมื่อกระเป๋าเงินสัญญาอัจฉริยะ (multisig, การฟื้นฟูทางสังคมหรืออย่างอื่น) กลายเป็นกระแสหลัก คีย์ที่จำเป็นในการเข้าถึงบัญชีบางส่วนจะมีการเปลี่ยนแปลงเมื่อเวลาผ่านไป และคีย์เก่าจะต้องใช้ไม่ได้อีกต่อไป เมื่อทั้งสองสิ่งนี้เกิดขึ้น ผู้ใช้จะต้องมีวิธีในการเปลี่ยนคีย์ที่มีสิทธิ์ในการเข้าถึงบัญชีจำนวนมากซึ่งอาศัยอยู่ในที่ต่างๆ มากมาย โดยไม่ต้องทำธุรกรรมเป็นจำนวนมาก
โดยเฉพาะอย่างยิ่ง เราต้องการวิธีจัดการกับที่อยู่ปลอม: ที่อยู่ที่ยังไม่ได้ "ลงทะเบียน" ด้วยวิธีใด ๆ บนเครือข่าย แต่ยังจำเป็นต้องได้รับและเก็บเงินไว้อย่างปลอดภัย เราทุกคนขึ้นอยู่กับที่อยู่ที่ไม่เป็นความจริง: เมื่อคุณใช้ Ethereum เป็นครั้งแรก คุณสามารถสร้างที่อยู่ ETH ที่ใครบางคนสามารถใช้เพื่อจ่ายเงินให้คุณได้ โดยไม่ต้อง "ลงทะเบียน" ที่อยู่แบบออนไลน์ (ซึ่งจะต้องเสียค่าธรรมเนียม txfees และด้วยเหตุนี้ มี ETH บางส่วนอยู่แล้ว)
เมื่อใช้ EOA ที่อยู่ทั้งหมดจะเริ่มต้นด้วยที่อยู่ที่ไม่เป็นข้อเท็จจริง ด้วยกระเป๋าเงินสัญญาอัจฉริยะ ที่อยู่ที่เป็นเท็จยังคงเป็นไปได้ ส่วนใหญ่ต้องขอบคุณ CREATE2 ซึ่งช่วยให้คุณมีที่อยู่ ETH ที่สามารถเติมได้ด้วยสัญญาอัจฉริยะที่มีรหัสที่ตรงกับแฮชเฉพาะเท่านั้น
อัลกอริธึมการคำนวณที่อยู่ EIP-1014 (CREATE2)
อย่างไรก็ตาม กระเป๋าเงินสัญญาอัจฉริยะนำเสนอความท้าทายใหม่: ความเป็นไปได้ในการเปลี่ยนแปลงคีย์การเข้าถึง ที่อยู่ซึ่งเป็นแฮชของรหัสเริ่มต้นจะมีได้เฉพาะรหัสยืนยันเริ่มต้นของกระเป๋าเงินเท่านั้น คีย์การยืนยันปัจจุบันจะถูกจัดเก็บไว้ในที่เก็บข้อมูลของกระเป๋าเงิน แต่บันทึกการจัดเก็บข้อมูลนั้นจะไม่เผยแพร่ไปยัง L2 อื่น ๆ อย่างน่าอัศจรรย์
หากผู้ใช้มีที่อยู่จำนวนมากใน L2 จำนวนมาก รวมถึงที่อยู่ที่ (เนื่องจากเป็นข้อมูลที่ไม่เป็นจริง) โดย L2 ที่พวกเขาอยู่ไม่ทราบ ดูเหมือนว่ามีเพียงวิธีเดียวเท่านั้นที่จะอนุญาตให้ผู้ใช้เปลี่ยนคีย์ของตนได้: สินทรัพย์ / ที่เก็บคีย์ สถาปัตยกรรมการแยก ผู้ใช้แต่ละรายมี (i) “สัญญาที่เก็บคีย์” (บน L1 หรือบน L2 หนึ่งรายการ) ซึ่งจัดเก็บคีย์การตรวจสอบสำหรับกระเป๋าเงินทั้งหมดพร้อมกับกฎสำหรับการเปลี่ยนรหัส และ (ii) “สัญญากระเป๋าเงิน” บน L1 และอีกมาก L2 ซึ่งอ่าน cross-chain เพื่อรับรหัสยืนยัน
มีสองวิธีในการดำเนินการนี้:
เพื่อแสดงความซับซ้อนทั้งหมด เราจะสำรวจกรณีที่ยากที่สุด: โดยที่ที่เก็บคีย์อยู่ที่ L2 อันหนึ่ง และกระเป๋าเงินอยู่บน L2 อื่น หากที่เก็บคีย์หรือกระเป๋าเงินอยู่บน L1 ก็จำเป็นต้องใช้การออกแบบนี้เพียงครึ่งหนึ่งเท่านั้น
สมมติว่าที่เก็บคีย์อยู่บน Linea และกระเป๋าเงินอยู่บน Kakarot หลักฐานกุญแจเข้ากระเป๋าสตางค์ฉบับเต็มประกอบด้วย:
มีคำถามหลักๆ เกี่ยวกับการใช้งานที่ยุ่งยากสองข้อที่นี่:
มีห้าตัวเลือกหลัก:
ในแง่ของงานโครงสร้างพื้นฐานที่จำเป็นและต้นทุนสำหรับผู้ใช้ ฉันจัดอันดับคร่าวๆ ดังนี้:
“การรวมกลุ่ม” หมายถึงแนวคิดในการรวบรวมการพิสูจน์ทั้งหมดที่ผู้ใช้จัดทำไว้ภายในแต่ละบล็อกให้เป็น meta-proof ขนาดใหญ่ที่รวมเอาทั้งหมดเข้าด้วยกัน สิ่งนี้เป็นไปได้สำหรับ SNARK และสำหรับ KZG แต่ไม่ใช่สำหรับสาขา Merkle (คุณสามารถ รวมสาขา Merkle ได้นิดหน่อย แต่จะช่วยคุณบันทึกเท่านั้น (txs ต่อบล็อก) / log (จำนวนที่เก็บคีย์ทั้งหมด) อาจ 15-30% ในทางปฏิบัติจึงไม่คุ้มกับต้นทุน)
การรวมกลุ่มจะคุ้มค่าก็ต่อเมื่อสคีมมีผู้ใช้จำนวนมาก ดังนั้น ตามความเป็นจริงแล้ว การใช้งานเวอร์ชัน 1 จึงไม่ต้องมีการรวมกลุ่ม และนำไปใช้กับเวอร์ชัน 2 ตามความเป็นจริง
อันนี้ง่าย: ทำตาม แผนภาพในส่วนก่อนหน้า โดยตรง แม่นยำยิ่งขึ้น แต่ละ "การพิสูจน์" (สมมติว่าเป็นกรณีความยากสูงสุดในการพิสูจน์ L2 หนึ่งไปยัง L2 อีกอันหนึ่ง) จะมี:
น่าเสียดายที่การพิสูจน์สถานะ Ethereum มีความซับซ้อน แต่มี ไลบรารีสำหรับตรวจสอบ และหากคุณใช้ไลบรารีเหล่านี้ กลไกนี้ไม่ซับซ้อนเกินกว่าจะนำไปใช้
ปัญหาที่ใหญ่กว่าคือต้นทุน การพิสูจน์ Merkle นั้นยาว และน่าเสียดายที่ต้นไม้ Patricia นั้นยาวเกินความจำเป็น ~3.9 เท่า (แม่นยำ: การพิสูจน์ Merkle ในอุดมคติในต้นไม้ที่ถือวัตถุ N นั้นมี ความยาว 32 log2(N) ไบต์ และเนื่องจากต้นไม้ Patricia ของ Ethereum มี 16 ใบต่อเด็กหนึ่งคน การพิสูจน์ สำหรับต้นไม้เหล่านั้นมีความยาว 32 15 log16(N) ~= 125 log2(N) ไบต์) ในสถานะที่มี บัญชีประมาณ 250 ล้าน (~2²⁸) บัญชี ทำให้แต่ละบัญชีพิสูจน์ได้ 125 * 28 = 3,500 ไบต์หรือประมาณ 56,000 gas รวมถึงค่าใช้จ่ายเพิ่มเติมสำหรับการถอดรหัสและการตรวจสอบแฮช
การพิสูจน์สองรายการร่วมกันจะมีราคาประมาณ 100,000 ถึง 150,000 Gas (ไม่รวมการตรวจสอบลายเซ็นหากใช้ต่อธุรกรรม) ซึ่งมากกว่าฐานปัจจุบัน 21,000 Gas ต่อธุรกรรมอย่างมีนัยสำคัญ แต่ความแตกต่างจะแย่ลงหากการพิสูจน์ได้รับการตรวจสอบบน L2 การคำนวณภายใน L2 มีราคาถูก เนื่องจากการคำนวณเสร็จสิ้นแบบออฟไลน์และในระบบนิเวศที่มีโหนดน้อยกว่า L1 มาก ในทางกลับกัน ข้อมูลจะต้องโพสต์ไปที่ L1 ดังนั้นการเปรียบเทียบจึงไม่ใช่ 21,000 ก๊าซกับ 150,000 ก๊าซ มันคือ 21,000 L2 ก๊าซเทียบกับ 100,000 L1 ก๊าซ
เราสามารถคำนวณความหมายได้โดยดูการเปรียบเทียบระหว่างต้นทุนก๊าซ L1 และต้นทุนก๊าซ L2:
ปัจจุบัน L1 มีราคาแพงกว่า L2 ประมาณ 15-25 เท่าสำหรับการส่งแบบธรรมดา และแพงกว่าประมาณ 20-50 เท่าสำหรับการแลกเปลี่ยนโทเค็น การส่งแบบธรรมดานั้นมีข้อมูลค่อนข้างหนัก แต่สวอปนั้นต้องใช้การคำนวณมากกว่ามาก ดังนั้น สวอปจึงเป็นเกณฑ์มาตรฐานที่ดีกว่าในการประมาณต้นทุนของการคำนวณ L1 เทียบกับการคำนวณ L2 เมื่อพิจารณาทั้งหมดนี้แล้ว ถ้าเราถือว่าอัตราส่วนต้นทุน 30 เท่าระหว่างต้นทุนการคำนวณ L1 และต้นทุนการคำนวณ L2 ดูเหมือนว่าจะบอกเป็นนัยว่าการใส่ Merkle proof บน L2 จะมีราคาเทียบเท่ากับธุรกรรมปกติประมาณห้าสิบครั้ง
แน่นอนว่าการใช้ binary Merkle tree สามารถลดต้นทุนได้ ~4x แต่ถึงกระนั้น ค่าใช้จ่ายในกรณีส่วนใหญ่จะสูงเกินไป - และถ้าเราเต็มใจที่จะเสียสละเพราะไม่สามารถเข้ากันได้กับ hexary ในปัจจุบันของ Ethereum อีกต่อไป ต้นไม้ประจำรัฐ เราอาจแสวงหาทางเลือกที่ดีกว่านี้เช่นกัน
ตามหลักการแล้ว การใช้ ZK-SNARK ก็เข้าใจได้ง่ายเช่นกัน เพียงคุณแทนที่การพิสูจน์ Merkle ใน แผนภาพด้านบน ด้วย ZK-SNARK เพื่อพิสูจน์ว่าการพิสูจน์ Merkle เหล่านั้นมีอยู่จริง ZK-SNARK มีค่าใช้จ่ายประมาณ 400,000 Gas ในการคำนวณ และประมาณ 400 ไบต์ (เปรียบเทียบ: 21,000 Gas และ 100 ไบต์สำหรับธุรกรรมพื้นฐาน ในอนาคต จะลดเหลือ ~25 ไบต์ด้วยการบีบอัด) ดังนั้น จากมุมมองด้านการคำนวณ ZK-SNARK มีราคา 19 เท่าของต้นทุนของธุรกรรมพื้นฐานในปัจจุบัน และจากมุมมองข้อมูล ZK-SNARK มีราคา 4 เท่าของธุรกรรมพื้นฐานในปัจจุบัน และ 16 เท่าของต้นทุนของธุรกรรมพื้นฐาน อนาคต.
ตัวเลขเหล่านี้เป็นการปรับปรุงอย่างมากจากการพิสูจน์ของ Merkle แต่ก็ยังมีราคาค่อนข้างแพง มีสองวิธีในการปรับปรุง: (i) การพิสูจน์ KZG ที่มีจุดประสงค์พิเศษ หรือ (ii) การรวมกลุ่ม คล้ายกับ การรวม ERC-4337 แต่ใช้คณิตศาสตร์ที่ซับซ้อนกว่า เราสามารถดูทั้งสองอย่างได้
คำเตือน ส่วนนี้เนื้อหาเข้มข้นกว่าส่วนอื่นๆ มาก เนื่องจากเรากำลังก้าวไปไกลกว่าเครื่องมือทั่วไปและสร้างบางสิ่งที่มีจุดประสงค์พิเศษให้มีราคาถูกลง ดังนั้นเราจึงต้อง "ซ่อนเร้น" มากกว่านี้มาก หากคุณไม่ชอบคณิตศาสตร์เชิงลึก ให้ข้ามไปยัง หัวข้อถัดไปเลย
ขั้นแรก สรุปว่าข้อผูกพันของ KZG ทำงานอย่างไร:
คุณสมบัติหลักบางประการที่สำคัญที่ต้องเข้าใจคือ:
ดังนั้นเราจึงมีโครงสร้างที่คุณสามารถเพิ่มมูลค่าต่อท้ายรายการที่เพิ่มขึ้นเรื่อยๆ แม้ว่าจะมีขีดจำกัดขนาดอยู่ก็ตาม (ตามความเป็นจริง หลายร้อยล้านรายการอาจใช้งานได้) จากนั้นเราจะใช้สิ่งนั้นเป็นโครงสร้างข้อมูลของเราในการจัดการ (i) ข้อผูกพันต่อรายการคีย์ในแต่ละ L2 ซึ่งจัดเก็บไว้ใน L2 นั้นและมิเรอร์ไปยัง L1 และ (ii) ข้อผูกพันต่อรายการข้อผูกพันคีย์ L2 ซึ่งจัดเก็บไว้ใน Ethereum L1 และสะท้อนไปยัง L2 แต่ละตัว
การปรับปรุงข้อผูกพันอาจกลายเป็นส่วนหนึ่งของตรรกะ L2 หลัก หรืออาจนำไปใช้ได้โดยไม่ต้องเปลี่ยนโปรโตคอลหลัก L2 ผ่านทางสะพานฝากและถอน
หลักฐานที่สมบูรณ์จะต้องมี:
จริงๆ แล้ว เป็นไปได้ที่จะรวมการพิสูจน์ KZG ทั้งสองเป็นอันเดียว ดังนั้นเราจึงได้ขนาดรวมเพียง 100 ไบต์
หมายเหตุรายละเอียดปลีกย่อยประการหนึ่ง: เนื่องจากรายการคีย์คือรายการ และไม่ใช่แมปคีย์/ค่าเหมือนกับสถานะ รายการคีย์จึงต้องกำหนดตำแหน่งตามลำดับ สัญญาข้อผูกมัดหลักจะมีรีจิสทรีภายในของตัวเองที่แมปแต่ละที่เก็บคีย์กับ ID และสำหรับแต่ละคีย์จะจัดเก็บแฮช (คีย์ ที่อยู่ของที่เก็บคีย์) แทนที่จะเป็นเพียงคีย์ เพื่อสื่อสารกับ L2 อื่น ๆ อย่างชัดเจนซึ่งที่เก็บคีย์รายการเฉพาะคือ พูดคุยเกี่ยวกับ.
ข้อดีของเทคนิคนี้คือมันทำงานได้ดีมากบน L2 ข้อมูลมีขนาด 100 ไบต์ สั้นกว่า ZK-SNARK ประมาณ 4 เท่า และสั้นกว่าการพิสูจน์ Merkle มาก ค่าใช้จ่ายในการคำนวณส่วนใหญ่เป็นเช็คจับคู่ขนาด 2 เดียวหรือ ประมาณ 119,000 แก๊ส บน L1 ข้อมูลมีความสำคัญน้อยกว่าการคำนวณ และน่าเสียดายที่ KZG ค่อนข้างแพงกว่าการพิสูจน์ Merkle
โดยพื้นฐานแล้ว Verkle tree เกี่ยวข้องกับการซ้อนข้อผูกพัน KZG (หรือ ข้อผูกพัน IPA ซึ่งสามารถมีประสิทธิภาพมากกว่าและใช้การเข้ารหัสที่ง่ายกว่า) ทับซ้อนกัน: เพื่อจัดเก็บค่า 2⁴⁸ คุณสามารถกำหนดข้อผูกพัน KZG ในรายการค่า 2²⁴ ซึ่งแต่ละค่านั้นเอง คือความมุ่งมั่นของ KZG ต่อค่านิยม 2²⁴ ต้นไม้ Verkle<a href="https://notes.ethereum.org/ @vbuterin /verkle_tree_eip">แข็งแกร่ง พิจารณาสำหรับแผนผังสถานะ Ethereum เนื่องจากต้นไม้ Verkle สามารถใช้เพื่อเก็บแผนที่คีย์-ค่าและไม่ใช่แค่รายการ (โดยพื้นฐานแล้ว คุณสามารถสร้างแผนภูมิขนาด-2²⁵⁶ ได้ แต่เริ่มต้นให้ว่างเปล่า โดยกรอกเฉพาะบางส่วนของแผนผังเมื่อคุณทำจริงแล้ว จำเป็นต้องกรอก)
ต้นไม้ Verkle มีลักษณะอย่างไร ในทางปฏิบัติ คุณอาจให้แต่ละโหนดมีความกว้าง 256 == 2⁸ สำหรับทรีที่ใช้ IPA หรือ 2²⁴ สำหรับทรีที่ใช้ KZG
การพิสูจน์ในต้นไม้ Verkle นั้นค่อนข้างยาวกว่า KZG; อาจมีความยาวสองสามร้อยไบต์ นอกจากนี้ยังตรวจสอบได้ยาก โดยเฉพาะอย่างยิ่งหากคุณพยายามรวมการพิสูจน์หลายรายการไว้ในที่เดียว
ตามความเป็นจริงแล้ว ต้นไม้ Verkle ควรได้รับการพิจารณาให้เหมือนกับต้นไม้ Merkle แต่สามารถทำงานได้มากกว่าหากไม่มี SNARKing (เนื่องจากต้นทุนข้อมูลที่ต่ำกว่า) และถูกกว่าด้วย SNARKing (เนื่องจากต้นทุนตัวพิสูจน์ที่ต่ำกว่า)
ข้อได้เปรียบที่ใหญ่ที่สุดของต้นไม้ Verkle คือความเป็นไปได้ในการประสานโครงสร้างข้อมูล: Verkle proofs สามารถใช้โดยตรงบนสถานะ L1 หรือ L2 โดยไม่มีโครงสร้างซ้อนทับ และใช้กลไกเดียวกันทุกประการสำหรับ L1 และ L2 เมื่อคอมพิวเตอร์ควอนตัมกลายเป็นปัญหา หรือเมื่อพิสูจน์ว่าสาขาของ Merkle มีประสิทธิภาพเพียงพอแล้ว Verkle tree ก็ถูกแทนที่ด้วยแผนผังแฮชไบนารีที่มีฟังก์ชันแฮชที่เป็นมิตรกับ SNARK ที่เหมาะสม
หากผู้ใช้ N ทำธุรกรรม N (หรือตามความเป็นจริงมากกว่านั้น N ERC-4337 UserOperations) ที่ต้องพิสูจน์การอ้างสิทธิ์แบบข้ามสาย N เราสามารถประหยัดน้ำมันได้มากโดยการรวบรวมการพิสูจน์เหล่านั้น: ตัวสร้างที่จะรวมธุรกรรมเหล่านั้นไว้ในบล็อก หรือบันเดิลที่เข้าไปในบล็อกสามารถสร้างหลักฐานเดียวที่พิสูจน์การอ้างสิทธิ์เหล่านั้นทั้งหมดพร้อมกัน
นี่อาจหมายถึง:
ในทั้งสามกรณี การพิสูจน์แต่ละครั้งจะใช้ค่าน้ำมันเพียงไม่กี่แสนเท่านั้น ตัวสร้างจะต้องสร้างอย่างใดอย่างหนึ่งบน L2 แต่ละตัวสำหรับผู้ใช้ใน L2 นั้น ดังนั้น เพื่อให้สิ่งนี้มีประโยชน์ในการสร้าง โครงการโดยรวมจำเป็นต้องมีการใช้งานเพียงพอ โดยมักจะมีธุรกรรมอย่างน้อยสองสามรายการภายในบล็อกเดียวกันบน L2 หลักหลายรายการ
หากใช้ ZK-SNARK ต้นทุนส่วนเพิ่มหลักเป็นเพียง "ตรรกะทางธุรกิจ" ในการส่งตัวเลขไปมาระหว่างสัญญา ดังนั้นอาจมีก๊าซ L2 สองสามพันต่อผู้ใช้ หากใช้การพิสูจน์หลายรายการของ KZG ผู้พิสูจน์จะต้องเพิ่มก๊าซ 48 หน่วยสำหรับ L2 ที่เก็บคีย์แต่ละอันที่ใช้ภายในบล็อกนั้น ดังนั้นต้นทุนส่วนเพิ่มของโครงการต่อผู้ใช้จะบวกก๊าซอีกประมาณ 800 L1 ต่อ L2 (ไม่ใช่ต่อ ผู้ใช้) ด้านบน แต่ต้นทุนเหล่านี้ต่ำกว่าต้นทุนของการไม่รวมกลุ่มอย่างมาก ซึ่งย่อมเกี่ยวข้องกับก๊าซ L1 มากกว่า 10,000 ลิตรและก๊าซ L2 หลายแสนต่อผู้ใช้อย่างหลีกเลี่ยงไม่ได้ สำหรับ Verkle tree คุณสามารถใช้ Verkle multi-proofs ได้โดยตรง โดยเพิ่มประมาณ 100-200 ไบต์ต่อผู้ใช้ หรือคุณสามารถสร้าง ZK-SNARK ของ Verkle multi-proofs ได้ ซึ่งมีต้นทุนใกล้เคียงกับ ZK-SNARKs ของสาขา Merkle แต่ ถูกกว่ามากในการพิสูจน์
จากมุมมองของการนำไปปฏิบัติ อาจเป็นการดีที่สุดที่จะมีการรวมการพิสูจน์ข้ามสายโซ่ผ่านมาตรฐานการแยกบัญชี ERC-4337 ERC-4337 มีกลไกสำหรับผู้สร้างเพื่อรวมส่วนของ UserOperations ด้วยวิธีที่กำหนดเองอยู่แล้ว มีแม้กระทั่ง <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> การใช้งานสิ่งนี้สำหรับการรวมลายเซ็น BLS ซึ่งสามารถลดต้นทุนก๊าซใน L2 ลง 1.5x ถึง 3x ขึ้นอยู่กับ รูปแบบการบีบอัดอื่น ๆ รวมอยู่ด้วย
แผนภาพจาก <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> โพสต์การใช้งานกระเป๋าเงิน BLS ที่แสดงขั้นตอนการทำงานของลายเซ็นรวม BLS ภายใน ERC-4337 เวอร์ชันก่อนหน้า ขั้นตอนการทำงานของการรวมการพิสูจน์ข้ามสายโซ่จะมีลักษณะคล้ายกันมาก
ความเป็นไปได้ขั้นสุดท้าย และสิ่งหนึ่งที่ใช้ได้กับ L2 ที่อ่าน L1 เท่านั้น (และไม่ใช่ L1 ที่อ่าน L2) คือการแก้ไข L2 เพื่อให้พวกมันทำการเรียกแบบคงที่ไปยังสัญญาบน L1 โดยตรง
ซึ่งสามารถทำได้ด้วย opcode หรือพรีคอมไพล์ ซึ่งอนุญาตให้เรียกเข้าสู่ L1 โดยที่คุณระบุที่อยู่ปลายทาง gas และข้อมูลการโทร และส่งคืนเอาต์พุต แม้ว่าเนื่องจากการเรียกเหล่านี้เป็นการเรียกแบบคงที่ จึงไม่สามารถเปลี่ยนสถานะ L1 ใด ๆ ได้ L2 ต้องระวัง L1 อยู่แล้วในการดำเนินการฝากเงิน ดังนั้นจึงไม่มีพื้นฐานใดที่จะหยุดยั้งการดำเนินการดังกล่าวได้ มันเป็นความท้าทายในการใช้งานทางเทคนิคเป็นหลัก (ดู: RFP นี้จากการมองในแง่ดีเพื่อรองรับการโทรแบบคงที่ใน L1)
โปรดสังเกตว่าหากที่เก็บคีย์อยู่บน L1 และ L2 รวมฟังก์ชันการโทรแบบคงที่ของ L1 ไว้ ก็ไม่จำเป็นต้องมีการพิสูจน์เลย! อย่างไรก็ตาม หาก L2 ไม่รวมการโทรแบบคงที่ของ L1 หรือหากที่เก็บคีย์อยู่บน L2 (ซึ่งอาจต้องเป็นเช่นนั้นในที่สุด เมื่อ L1 มีราคาแพงเกินไปสำหรับผู้ใช้ที่จะใช้แม้แต่น้อย) ก็จำเป็นต้องมีการพิสูจน์
รูปแบบทั้งหมดข้างต้นจำเป็นต้องใช้ L2 เพื่อเข้าถึงรูทของสถานะ L1 ล่าสุด หรือสถานะ L1 ล่าสุดทั้งหมด โชคดีที่ L2 ทั้งหมดมีฟังก์ชันบางอย่างในการเข้าถึงสถานะ L1 ล่าสุดอยู่แล้ว เนื่องจากพวกเขาต้องการฟังก์ชันดังกล่าวในการประมวลผลข้อความที่เข้ามาจาก L1 ถึง L2 โดยเฉพาะเงินฝาก
และจริงๆ แล้ว ถ้า L2 มีฟีเจอร์การฝากเงิน คุณสามารถใช้ L2 ตามที่เป็นอยู่เพื่อย้าย L1 state root ไปเป็นสัญญาบน L2: เพียงแค่มีสัญญาใน L1 เรียก opcode ของ BLOCKHASH แล้วส่งต่อให้ L2 เป็น ข้อความการฝากเงิน สามารถรับส่วนหัวของบล็อกแบบเต็มได้ และรากสถานะจะถูกแยกออกที่ฝั่ง L2 อย่างไรก็ตาม มันจะดีกว่ามากสำหรับ L2 ทุกตัวที่จะมีวิธีที่ชัดเจนในการเข้าถึงสถานะ L1 ล่าสุดแบบเต็มหรือรูทสถานะ L1 ล่าสุดโดยตรง
ความท้าทายหลักในการเพิ่มประสิทธิภาพวิธีที่ L2 ได้รับสถานะ L1 ล่าสุดคือการบรรลุความปลอดภัยและความหน่วงต่ำไปพร้อมๆ กัน:
นอกจากนี้ ในทิศทางตรงกันข้าม (L1 อ่านว่า L2):
ความเร็วบางส่วนสำหรับการดำเนินการข้ามสายโซ่ที่ไม่น่าเชื่อถือนั้นช้าจนไม่อาจยอมรับได้สำหรับกรณีการใช้งาน defi หลายกรณี ในกรณีดังกล่าว คุณจะต้องมีบริดจ์ที่เร็วกว่าพร้อมกับโมเดลความปลอดภัยที่ไม่สมบูรณ์มากกว่า อย่างไรก็ตาม สำหรับกรณีการใช้งานในการอัปเดตคีย์กระเป๋าสตางค์ ความล่าช้าที่นานกว่านั้นเป็นที่ยอมรับมากกว่า: คุณไม่ได้ชะลอการทำธุรกรรมเป็นชั่วโมง แต่คุณกำลังชะลอการเปลี่ยนแปลงคีย์ คุณจะต้องเก็บกุญแจเก่าไว้อีกต่อไป หากคุณกำลังเปลี่ยนกุญแจเนื่องจากกุญแจถูกขโมย คุณจะมีช่องโหว่อยู่ช่วงหนึ่ง แต่สามารถบรรเทาได้ เช่น โดยกระเป๋าเงินมีฟังก์ชั่นแช่แข็ง
ท้ายที่สุดแล้ว โซลูชันการลดเวลาแฝงที่ดีที่สุดคือให้ L2 ใช้การอ่านโดยตรงของรากสถานะ L1 ในวิธีที่เหมาะสมที่สุด โดยแต่ละบล็อก L2 (หรือบันทึกการคำนวณรากสถานะ) มีตัวชี้ไปยังบล็อก L1 ล่าสุด ดังนั้นหาก L1 เปลี่ยนกลับ , L2 สามารถย้อนกลับได้เช่นกัน ควรวางสัญญา Keystore บน mainnet หรือบน L2 ที่เป็น ZK-rollups และสามารถผูกมัดกับ L1 ได้อย่างรวดเร็ว
บล็อกของสายโซ่ L2 สามารถพึ่งพาได้ไม่เพียงแต่บล็อก L2 ก่อนหน้าเท่านั้น แต่ยังรวมถึงบล็อก L1 ด้วย หาก L1 ย้อนกลับผ่านลิงก์ดังกล่าว L2 จะย้อนกลับด้วย เป็นที่น่าสังเกตว่านี่คือวิธีที่ Sharding เวอร์ชันก่อนหน้า (ก่อน Dank) ถูกจินตนาการให้ใช้งานได้ ดู ที่นี่ สำหรับรหัส
น่าแปลกที่ไม่มากขนาดนั้น จริงๆ แล้วไม่จำเป็นต้องเป็น Rollup ด้วยซ้ำ หากเป็น L3 หรือ Validium ก็ไม่เป็นไรที่จะถือ Wallet ไว้ที่นั่น ตราบใดที่คุณถือ Keystores บน L1 หรือ ZK Rollup สิ่งที่คุณต้องการคือเพื่อให้เชนสามารถเข้าถึงรากของสถานะ Ethereum ได้โดยตรง และความมุ่งมั่นด้านเทคนิคและสังคมที่จะเต็มใจที่จะจัดระเบียบใหม่หาก Ethereum มีองค์กรใหม่ และฮาร์ดฟอร์คหาก Ethereum ฮาร์ดฟอร์ค
ปัญหาการวิจัยที่น่าสนใจประการหนึ่งคือการระบุว่าเป็นไปได้มากน้อยเพียงใดที่เครือข่ายจะมีรูปแบบการเชื่อมต่อกับเครือข่ายอื่นๆ จำนวนมาก (เช่น อีเธอเรียม และ Zcash) การทำแบบไร้เดียงสานั้นเป็นไปได้: chain ของคุณอาจตกลงที่จะจัดตั้งใหม่หาก Ethereum หรือ Zcash reorg (และ hard fork หาก Ethereum หรือ Zcash hard fork) แต่โดยทั่วไปแล้วผู้ดำเนินการโหนดของคุณและชุมชนของคุณโดยทั่วไปจะมีการพึ่งพาทางเทคนิคและการเมืองเป็นสองเท่า ดังนั้นเทคนิคดังกล่าวจึงสามารถนำไปใช้เชื่อมต่อกับเครือข่ายอื่นๆ ได้ แต่จะมีต้นทุนเพิ่มขึ้น แบบแผนที่ใช้ บริดจ์ ZK มีคุณสมบัติทางเทคนิคที่น่าสนใจ แต่มีจุดอ่อนที่สำคัญคือไม่แข็งแกร่งต่อการโจมตี 51% หรือฮาร์ดฟอร์ก อาจมีวิธีแก้ปัญหาที่ชาญฉลาดกว่านี้
ตามหลักการแล้ว เรายังต้องการรักษาความเป็นส่วนตัวด้วย หากคุณมีกระเป๋าสตางค์หลายใบที่ได้รับการจัดการโดยที่เก็บคีย์เดียวกัน เราต้องการให้แน่ใจว่า:
สิ่งนี้ทำให้เกิดปัญหาบางประการ:
ด้วย SNARK วิธีแก้ปัญหานั้นง่ายตามแนวคิด: การพิสูจน์จะซ่อนข้อมูลไว้ตามค่าเริ่มต้น และผู้รวบรวมจำเป็นต้องสร้าง SNARK แบบเรียกซ้ำเพื่อพิสูจน์ SNARK
ความท้าทายหลักของแนวทางนี้ในปัจจุบันก็คือ การรวมกลุ่มต้องการให้ผู้รวบรวมสร้าง SNARK แบบเรียกซ้ำ ซึ่งปัจจุบันค่อนข้างช้า
ด้วย KZG เราสามารถใช้<a href="https://notes.ethereum.org/ @vbuterin /non_index_revealing_proof">สิ่งนี้ ทำงานเกี่ยวกับการพิสูจน์ KZG ที่ไม่เปิดเผยดัชนี (ดูเพิ่มเติมที่: เวอร์ชันที่เป็นทางการมากขึ้นของงานนั้นใน กระดาษ Caulk ) เป็นจุดเริ่มต้น อย่างไรก็ตาม การรวมหลักฐานที่ปกปิดไว้เป็นปัญหาเปิดที่ต้องให้ความสนใจมากขึ้น
น่าเสียดายที่การอ่าน L1 โดยตรงจากภายใน L2 ไม่ได้รักษาความเป็นส่วนตัว แม้ว่าการนำฟังก์ชันการอ่านโดยตรงไปใช้ยังคงมีประโยชน์มาก ทั้งเพื่อลดเวลาแฝงให้เหลือน้อยที่สุดและเนื่องจากประโยชน์ใช้สอยสำหรับแอปพลิเคชันอื่นๆ