Tìm hiểu sâu hơn về cách đọc chéo L2 cho ví và các trường hợp sử dụng khác

Nâng caoFeb 29, 2024
Trong bài viết này, Vitalik trực tiếp đề cập đến khía cạnh kỹ thuật cụ thể của một bài toán con: cách đọc từ L2 sang L1, từ L1 đến L2 hoặc từ L2 này sang L2 khác dễ dàng hơn. Giải quyết vấn đề này là rất quan trọng để đạt được kiến trúc phân tách tài sản/khóa, nhưng nó cũng có các trường hợp sử dụng có giá trị trong các lĩnh vực khác, đáng chú ý nhất là tối ưu hóa các cuộc gọi chéo L2 đáng tin cậy, bao gồm các trường hợp sử dụng như di chuyển tài sản giữa L1 và L2.
Tìm hiểu sâu hơn về cách đọc chéo L2 cho ví và các trường hợp sử dụng khác

Đặc biệt cảm ơn Yoav Weiss, Dan Finlay, Martin Koppelmann và các nhóm Arbitrum, Optimism, Polygon, Scroll và SoulWallet đã phản hồi và đánh giá.

Trong bài đăng này về Ba lần chuyển đổi, tôi đã nêu ra một số lý do chính tại sao việc bắt đầu suy nghĩ rõ ràng về hỗ trợ L1 + chéo L2, bảo mật ví và quyền riêng tư như các tính năng cơ bản cần thiết của hệ sinh thái là rất có giá trị, thay vì xây dựng từng thứ này như các tiện ích bổ sung có thể được thiết kế riêng biệt theo từng ví riêng lẻ.

Bài đăng này sẽ tập trung trực tiếp hơn vào các khía cạnh kỹ thuật của một vấn đề phụ cụ thể: cách đọc L1 từ L2, L2 từ L1 hoặc L2 từ L2 khác dễ dàng hơn. Việc giải quyết vấn đề này là rất quan trọng để triển khai kiến trúc phân tách nội dung/kho khóa, nhưng nó cũng có các trường hợp sử dụng có giá trị trong các lĩnh vực khác, đáng chú ý nhất là tối ưu hóa các cuộc gọi chéo L2 đáng tin cậy, bao gồm các trường hợp sử dụng như di chuyển nội dung giữa L1 và L2.

Các bài đọc trước được đề xuất

Mục lục

Mục tiêu là gì?

Khi L2 trở nên phổ biến hơn, người dùng sẽ có tài sản trên nhiều L2 và có thể cả L1 nữa. Khi ví hợp đồng thông minh (multisig, social recovery hay cách khác) trở thành xu hướng phổ biến, các khóa cần thiết để truy cập vào một số tài khoản sẽ thay đổi theo thời gian và các khóa cũ sẽ không còn hiệu lực nữa. Khi cả hai điều này xảy ra, người dùng sẽ cần có cách thay đổi khóa có quyền truy cập vào nhiều tài khoản sống ở nhiều nơi khác nhau mà không cần thực hiện số lượng giao dịch cực cao.

Đặc biệt, chúng tôi cần một cách để xử lý các địa chỉ phản thực tế: các địa chỉ chưa được “đăng ký” trên chuỗi theo bất kỳ cách nào, tuy nhiên vẫn cần nhận và giữ tiền một cách an toàn. Tất cả chúng ta đều phụ thuộc vào các địa chỉ giả định: khi bạn sử dụng Ethereum lần đầu tiên, bạn có thể tạo một địa chỉ ETH mà ai đó có thể sử dụng để thanh toán cho bạn mà không cần “đăng ký” địa chỉ trên chuỗi (điều này sẽ yêu cầu phải trả phí tx và do đó đã nắm giữ một số ETH).

Với EOA, tất cả các địa chỉ đều bắt đầu dưới dạng địa chỉ phản thực tế. Với ví hợp đồng thông minh, các địa chỉ giả vẫn có thể thực hiện được, phần lớn là nhờ CREATE2, cho phép bạn có địa chỉ ETH chỉ có thể được điền bằng hợp đồng thông minh có mã khớp với một hàm băm cụ thể.

Thuật toán tính toán địa chỉ EIP-1014 (CREATE2) .

Tuy nhiên, ví hợp đồng thông minh đưa ra một thách thức mới: khả năng thay đổi khóa truy cập. Địa chỉ là hàm băm của initcode, chỉ có thể chứa khóa xác minh ban đầu của ví. Khóa xác minh hiện tại sẽ được lưu trữ trong bộ lưu trữ của ví, nhưng bản ghi lưu trữ đó không được truyền sang các L2 khác một cách kỳ diệu.

Nếu người dùng có nhiều địa chỉ trên nhiều L2, bao gồm cả các địa chỉ mà (vì chúng phản thực) mà L2 mà họ đang sử dụng không biết, thì có vẻ như chỉ có một cách duy nhất để cho phép người dùng thay đổi khóa của họ: assets / keystore kiến trúc tách biệt. Mỗi người dùng có (i) một “hợp đồng kho khóa” (trên L1 hoặc trên một L2 cụ thể), lưu trữ khóa xác minh cho tất cả các ví cùng với các quy tắc thay đổi khóa và (ii) “hợp đồng ví” trên L1 và nhiều ví khác. L2, đọc chuỗi chéo để lấy khóa xác minh.

Có hai cách để thực hiện điều này:

  • Phiên bản nhẹ (chỉ kiểm tra để cập nhật khóa): mỗi ví lưu trữ khóa xác minh cục bộ và chứa một chức năng có thể được gọi để kiểm tra bằng chứng chuỗi chéo về trạng thái hiện tại của kho khóa và cập nhật khóa xác minh được lưu trữ cục bộ cho phù hợp. Khi một ví được sử dụng lần đầu tiên trên một L2 cụ thể, việc gọi hàm đó để lấy khóa xác minh hiện tại từ kho khóa là bắt buộc.
    • Ưu điểm: sử dụng bằng chứng chuỗi chéo một cách tiết kiệm, vì vậy sẽ không sao nếu bằng chứng chuỗi chéo đắt tiền. Tất cả số tiền chỉ có thể được chi tiêu bằng các khóa hiện tại, vì vậy nó vẫn an toàn.
    • Nhược điểm: Để thay đổi khóa xác minh, bạn phải thực hiện thay đổi khóa trên chuỗi ở cả kho khóa và trong mọi ví đã được khởi tạo (mặc dù không phải là ví tiền giả). Điều này có thể tốn rất nhiều xăng.
  • Phiên bản nặng (kiểm tra mọi tx): bằng chứng chuỗi chéo hiển thị khóa hiện có trong kho khóa là cần thiết cho mỗi giao dịch.
    • Ưu điểm: độ phức tạp hệ thống ít hơn và cập nhật kho khóa rẻ.
    • Nhược điểm: đắt tiền trên mỗi tx, do đó đòi hỏi nhiều kỹ thuật hơn để tạo ra bằng chứng chuỗi chéo có giá rẻ ở mức chấp nhận được. Cũng không dễ tương thích với ERC-4337, hiện không hỗ trợ đọc hợp đồng chéo các đối tượng có thể thay đổi trong quá trình xác thực.

Bằng chứng chuỗi chéo trông như thế nào?

Để thể hiện toàn bộ sự phức tạp, chúng ta sẽ khám phá trường hợp khó khăn nhất: kho khóa nằm trên một L2 và ví nằm trên một L2 khác. Nếu kho khóa hoặc ví nằm trên L1 thì chỉ cần một nửa thiết kế này.

Giả sử kho khóa nằm trên Linea và ví nằm trên Kakarot. Bằng chứng đầy đủ về chìa khóa của ví bao gồm:

  • Một bằng chứng chứng minh trạng thái gốc Linea hiện tại, dựa trên trạng thái gốc Ethereum hiện tại mà Kakarot biết về
  • Bằng chứng chứng minh các khóa hiện tại trong kho khóa, dựa trên gốc trạng thái Linea hiện tại

Có hai câu hỏi triển khai phức tạp chính ở đây:

  1. Chúng ta sử dụng loại bằng chứng nào? (Có phải bằng chứng Merkle không? thứ gì khác?)
  2. Làm thế nào để L2 tìm hiểu gốc trạng thái L1 (Ethereum) gần đây (hoặc, như chúng ta sẽ thấy, có thể là trạng thái L1 đầy đủ) ngay từ đầu? Và cách khác, L1 học gốc trạng thái L2 như thế nào?
    • Trong cả hai trường hợp, độ trễ giữa điều gì đó xảy ra ở một bên và điều đó có thể được chứng minh đối với bên kia là bao lâu?

Chúng ta có thể sử dụng những loại sơ đồ chứng minh nào?

Có năm lựa chọn chính:

  • Bằng chứng Merkle
  • ZK-SNARK đa năng
  • Bằng chứng cho mục đích đặc biệt (ví dụ. với KZG)
  • Bằng chứng Verkle nằm giữa KZG và ZK-SNARK về cả khối lượng công việc và chi phí cơ sở hạ tầng.
  • Không có bằng chứng và dựa vào việc đọc trạng thái trực tiếp

Về công việc cơ sở hạ tầng cần thiết và chi phí cho người dùng, tôi xếp hạng đại khái như sau:

“Tập hợp” đề cập đến ý tưởng tổng hợp tất cả bằng chứng do người dùng cung cấp trong mỗi khối thành một siêu bằng chứng lớn kết hợp tất cả chúng. Điều này có thể áp dụng cho SNARK và KZG, nhưng không áp dụng cho các nhánh Merkle (bạn có thể kết hợp các nhánh Merkle một chút, nhưng nó chỉ giúp bạn tiết kiệm nhật ký (txs mỗi khối)/log (tổng số kho khóa), có thể là 15-30% trong thực tế, vì vậy nó có thể không đáng giá).

Việc tổng hợp chỉ có giá trị khi lược đồ có số lượng người dùng đáng kể, vì vậy trên thực tế, việc triển khai phiên bản 1 có thể loại bỏ tính năng tổng hợp và triển khai tính năng tổng hợp đó cho phiên bản 2.

Bằng chứng Merkle sẽ hoạt động như thế nào?

Cách này rất đơn giản: hãy làm theo sơ đồ trong phần trước một cách trực tiếp. Chính xác hơn, mỗi “bằng chứng” (giả sử trường hợp có độ khó tối đa là chứng minh một L2 thành một L2 khác) sẽ chứa:

  • Một nhánh Merkle chứng minh gốc trạng thái của L2 nắm giữ kho khóa, dựa trên gốc trạng thái gần đây nhất của Ethereum mà L2 biết. Gốc trạng thái của L2 chứa kho khóa được lưu trữ tại một khe lưu trữ đã biết của một địa chỉ đã biết (hợp đồng trên L1 đại diện cho L2) và do đó đường dẫn xuyên qua cây có thể được mã hóa cứng.
  • Nhánh Merkle chứng minh các khóa xác minh hiện tại, dựa trên gốc trạng thái của L2 giữ kho khóa. Ở đây một lần nữa, khóa xác minh được lưu trữ tại một khe lưu trữ đã biết của một địa chỉ đã biết, do đó đường dẫn có thể được mã hóa cứng.

Thật không may, bằng chứng trạng thái Ethereum rất phức tạp, nhưng vẫn tồn tại các thư viện để xác minh chúng và nếu bạn sử dụng các thư viện này, cơ chế này không quá phức tạp để thực hiện.

Vấn đề lớn hơn là chi phí. Bằng chứng Merkle rất dài và không may là cây Patricia dài hơn ~ 3,9 lần so với mức cần thiết (chính xác: bằng chứng Merkle lý tưởng cho một cây chứa N đối tượng dài 32 log2(N) byte và vì cây Patricia của Ethereum có 16 lá cho mỗi cây con nên bằng chứng đối với những cây đó dài 32 15 log16(N) ~= 125 log2(N) byte). Ở trạng thái có khoảng 250 triệu (~22⁸) tài khoản, điều này tạo ra mỗi bằng chứng 125 * 28 = 3500 byte, hoặc khoảng 56.000 gas, cộng thêm chi phí cho việc giải mã và xác minh giá trị băm.

Hai bằng chứng cùng nhau sẽ tiêu tốn khoảng 100.000 đến 150.000 gas (không bao gồm xác minh chữ ký nếu điều này được sử dụng cho mỗi giao dịch) - cao hơn đáng kể so với mức 21.000 gas cơ bản hiện tại cho mỗi giao dịch. Nhưng sự chênh lệch sẽ trở nên tồi tệ hơn nếu bằng chứng được xác minh trên L2. Việc tính toán bên trong L2 rất rẻ vì việc tính toán được thực hiện ngoài chuỗi và trong một hệ sinh thái có ít nút hơn nhiều so với L1. Mặt khác, dữ liệu phải được đưa lên L1. Do đó, sự so sánh không phải là 21000 gas so với 150.000 gas; đó là 21.000 khí L2 so với 100.000 khí L1.

Chúng ta có thể tính toán điều này có nghĩa là gì bằng cách xem xét so sánh giữa chi phí gas L1 và chi phí gas L2:

L1 hiện đắt hơn khoảng 15-25 lần so với L2 đối với các lần gửi đơn giản và đắt hơn 20-50 lần đối với các giao dịch hoán đổi mã thông báo. Việc gửi đơn giản tương đối nặng về dữ liệu, nhưng việc hoán đổi lại nặng về mặt tính toán hơn nhiều. Do đó, hoán đổi là một chuẩn mực tốt hơn để ước tính chi phí tính toán L1 so với tính toán L2. Nếu tính đến tất cả những điều này, nếu chúng ta giả định tỷ lệ chi phí là 30 lần giữa chi phí tính toán L1 và chi phí tính toán L2, thì điều này dường như ngụ ý rằng việc đưa bằng chứng Merkle lên L2 sẽ có chi phí tương đương với khoảng 50 giao dịch thông thường.

Tất nhiên, việc sử dụng cây Merkle nhị phân có thể cắt giảm chi phí ~ 4 lần, nhưng thậm chí, chi phí trong hầu hết các trường hợp sẽ quá cao - và nếu chúng ta sẵn sàng hy sinh việc không còn tương thích với hệ thập lục phân hiện tại của Ethereum cây trạng thái, chúng ta cũng có thể tìm kiếm những lựa chọn tốt hơn nữa.

Bằng chứng ZK-SNARK sẽ hoạt động như thế nào?

Về mặt khái niệm, việc sử dụng ZK-SNARK cũng dễ hiểu: bạn chỉ cần thay thế bằng chứng Merkle trong sơ đồ trên bằng ZK-SNARK chứng minh rằng những bằng chứng Merkle đó tồn tại. Một ZK-SNARK tốn ~400.000 gas tính toán và khoảng 400 byte (so sánh: 21.000 gas và 100 byte cho một giao dịch cơ bản, trong tương lai có thể giảm xuống ~25 byte khi nén). Do đó, từ góc độ tính toán, ZK-SNARK có giá gấp 19 lần chi phí của một giao dịch cơ bản ngày nay và từ góc độ dữ liệu, ZK-SNARK có giá gấp 4 lần so với một giao dịch cơ bản ngày nay và gấp 16 lần chi phí của một giao dịch cơ bản trong tương lai.

Những con số này là một cải tiến lớn so với bằng chứng Merkle, nhưng chúng vẫn khá đắt. Có hai cách để cải thiện điều này: (i) bằng chứng KZG cho mục đích đặc biệt hoặc (ii) tổng hợp, tương tự như tổng hợp ERC-4337 nhưng sử dụng phép toán lạ mắt hơn. Chúng ta có thể xem xét cả hai.

Bằng chứng KZG có mục đích đặc biệt sẽ hoạt động như thế nào?

Cảnh báo, phần này mang tính toán học nhiều hơn các phần khác. Điều này là do chúng tôi đang vượt xa các công cụ có mục đích chung và xây dựng thứ gì đó có mục đích đặc biệt để rẻ hơn, vì vậy chúng tôi phải “đi sâu” hơn nữa. Nếu bạn không thích toán sâu, hãy chuyển thẳng sang phần tiếp theo.

Đầu tiên, tóm tắt về cách thức hoạt động của các cam kết KZG:

  • Chúng ta có thể biểu diễn một tập hợp dữ liệu [D_1 … D_n] bằng bằng chứng KZG về đa thức bắt nguồn từ dữ liệu: cụ thể là đa thức P trong đó P(w) = D_1, P(w²) = D_2 … P(wⁿ) = D_n . w ở đây là “gốc của sự thống nhất”, một giá trị trong đó wᴺ = 1 đối với một số miền đánh giá có kích thước N (tất cả điều này được thực hiện trong một trường hữu hạn).
  • Để “cam kết” với P, chúng ta tạo một điểm trên đường cong elip com(P) = P₀ G + P₁ S₁ + … + Pₖ * Sₖ. Đây:
    • G là điểm tạo của đường cong
    • Pᵢ là hệ số bậc i của đa thức P
    • Sᵢ là điểm thứ i trong thiết lập tin cậy
  • Để chứng minh P(z) = a, chúng ta tạo một đa thức thương Q = (P - a) / (X - z), và tạo một cam kết com(Q) cho nó. Chỉ có thể tạo ra đa thức như vậy nếu P(z) thực sự bằng a.
  • Để kiểm chứng một chứng minh, chúng ta kiểm tra phương trình Q * (X - z) = P - a bằng cách thực hiện kiểm tra đường cong elip trên chứng minh com(Q) và cam kết đa thức com(P): chúng ta kiểm tra e(com(Q) , com(X - z)) ?= e(com(P) - com(a), com(1))

Một số thuộc tính quan trọng cần hiểu là:

  • Bằng chứng chỉ là giá trị com(Q), tức là 48 byte
  • com(P₁) + com(P₂) = com(P₁ + P₂)
  • Điều này cũng có nghĩa là bạn có thể “chỉnh sửa” một giá trị thành một cam kết hiện có. Giả sử rằng chúng ta biết rằng D_i hiện là a, chúng ta muốn đặt nó thành b và cam kết hiện có với D là com(P). Cam kết “P, nhưng với P(wⁱ) = b và không có đánh giá nào khác thay đổi”, thì chúng tôi đặt com(new_P) = com(P) + (ba) * com(Lᵢ), trong đó Lᵢ là “ Đa thức Lagrange” bằng 1 tại wⁱ và 0 tại các điểm wʲ khác.
  • Để thực hiện các cập nhật này một cách hiệu quả, tất cả N cam kết đối với đa thức Lagrange (com(Lᵢ)) có thể được tính toán trước và lưu trữ bởi mỗi khách hàng. Trong một hợp đồng trực tuyến, có thể sẽ quá nhiều để lưu trữ tất cả N cam kết, vì vậy thay vào đó, bạn có thể thực hiện cam kết KZG với tập hợp các giá trị com(L_i) (hoặc hash(com(L_i)), để bất cứ khi nào ai đó cần cập nhật cây trên chuỗi, họ có thể chỉ cần cung cấp com(L_i) thích hợp bằng chứng về tính chính xác của nó.

Do đó, chúng tôi có một cấu trúc nơi chúng tôi có thể tiếp tục thêm các giá trị vào cuối danh sách ngày càng phát triển, mặc dù với một giới hạn kích thước nhất định (trên thực tế, hàng trăm triệu có thể khả thi). Sau đó, chúng tôi sử dụng cấu trúc dữ liệu đó để quản lý (i) cam kết đối với danh sách các khóa trên mỗi L2, được lưu trữ trên L2 đó và được phản ánh tới L1, và (ii) cam kết đối với danh sách các cam kết khóa L2, được lưu trữ trên Ethereum L1 và được phản chiếu tới từng L2.

Việc cập nhật các cam kết có thể trở thành một phần của logic L2 cốt lõi hoặc có thể được triển khai mà không cần thay đổi giao thức lõi L2 thông qua cầu gửi và rút tiền.

Do đó, một bằng chứng đầy đủ sẽ yêu cầu:

  • Com(danh sách khóa) mới nhất trên L2 giữ kho khóa (48 byte)
  • Bằng chứng KZG về com(danh sách khóa) là một giá trị bên trong com(mirror_list), cam kết đối với danh sách tất cả các cam kết của danh sách khóa (48 byte)
  • Bằng chứng KZG về khóa của bạn trong com(danh sách khóa) (48 byte, cộng thêm 4 byte cho chỉ mục)

Trên thực tế, có thể hợp nhất hai bằng chứng KZG thành một, vì vậy chúng tôi nhận được tổng kích thước chỉ 100 byte.

Lưu ý một điều tinh tế: vì danh sách khóa là một danh sách chứ không phải bản đồ khóa/giá trị như trạng thái, nên danh sách khóa sẽ phải gán các vị trí một cách tuần tự. Hợp đồng cam kết khóa sẽ chứa cơ quan đăng ký nội bộ của chính nó ánh xạ từng kho khóa tới một ID và đối với mỗi khóa, nó sẽ lưu trữ hàm băm (khóa, địa chỉ của kho khóa) thay vì chỉ khóa, để giao tiếp rõ ràng với các L2 khác về kho khóa mà một mục nhập cụ thể là nói về.

Ưu điểm của kỹ thuật này là nó hoạt động rất tốt trên L2. Dữ liệu là 100 byte, ngắn hơn ~ 4 lần so với ZK-SNARK và ngắn hơn so với bằng chứng Merkle. Chi phí tính toán phần lớn là một séc ghép đôi cỡ 2, hoặc khoảng 119.000 gas. Trên L1, dữ liệu ít quan trọng hơn tính toán và thật không may, KZG có phần đắt hơn bằng chứng Merkle.

Cây Verkle sẽ hoạt động như thế nào?

Về cơ bản, cây Verkle liên quan đến việc xếp chồng các cam kết KZG (hoặc cam kết IPA, có thể hiệu quả hơn và sử dụng mật mã đơn giản hơn) chồng lên nhau: để lưu trữ 2⁴⁸ giá trị, bạn có thể thực hiện cam kết KZG với danh sách 22⁴ giá trị, mỗi giá trị đều là chính nó là cam kết của KZG với 22⁴ giá trị. Cây Verkle đang được<a href="https://notes.ethereum.org/ @vbuterin /verkle_tree_eip">phát triển mạnh mẽ được xem xét cho cây trạng thái Ethereum, vì cây Verkle có thể được sử dụng để chứa các bản đồ khóa-giá trị chứ không chỉ các danh sách (về cơ bản, bạn có thể tạo cây có kích thước 2²⁵⁶ nhưng bắt đầu trống, chỉ điền vào các phần cụ thể của cây khi bạn thực sự cần điền chúng).

Cây Verkle trông như thế nào. Trong thực tế, bạn có thể cấp cho mỗi nút chiều rộng là 256 == 2⁸ đối với cây dựa trên IPA hoặc 2²⁴ đối với cây dựa trên KZG.

Chứng minh trong cây Verkle dài hơn KZG một chút; chúng có thể dài vài trăm byte. Chúng cũng khó xác minh, đặc biệt nếu bạn cố gắng tổng hợp nhiều bằng chứng thành một.

Trên thực tế, cây Verkle nên được coi là giống như cây Merkle, nhưng khả thi hơn khi không có SNARKing (vì chi phí dữ liệu thấp hơn) và rẻ hơn với SNARKing (vì chi phí chứng minh thấp hơn).

Ưu điểm lớn nhất của cây Verkle là khả năng hài hòa các cấu trúc dữ liệu: Bằng chứng Verkle có thể được sử dụng trực tiếp trên trạng thái L1 hoặc L2, không cần cấu trúc lớp phủ và sử dụng cơ chế giống hệt nhau cho L1 và L2. Khi máy tính lượng tử trở thành vấn đề hoặc khi chứng minh được các nhánh Merkle trở nên đủ hiệu quả, cây Verkle có thể được thay thế tại chỗ bằng cây băm nhị phân có hàm băm thân thiện với SNARK phù hợp.

Tổng hợp

Nếu N người dùng thực hiện N giao dịch (hoặc thực tế hơn là N ERC-4337 UserOperations) cần chứng minh N xác nhận quyền sở hữu chuỗi chéo, chúng tôi có thể tiết kiệm rất nhiều gas bằng cách tổng hợp các bằng chứng đó: người xây dựng sẽ kết hợp các giao dịch đó thành một khối hoặc gói đi vào một khối có thể tạo ra một bằng chứng duy nhất chứng minh đồng thời tất cả các tuyên bố đó.

Điều này có thể có nghĩa là:

Trong cả ba trường hợp, mỗi lần chứng minh sẽ chỉ tốn vài trăm nghìn xăng. Người xây dựng sẽ cần tạo một trong những thứ này trên mỗi L2 cho người dùng trong L2 đó; do đó, để việc xây dựng điều này trở nên hữu ích, toàn bộ sơ đồ cần phải có đủ mức sử dụng để thường có ít nhất một vài giao dịch trong cùng một khối trên nhiều L2 chính.

Nếu ZK-SNARK được sử dụng, chi phí cận biên chính chỉ đơn giản là “logic kinh doanh” của việc chuyển các con số giữa các hợp đồng, do đó có thể là vài nghìn L2 gas cho mỗi người dùng. Nếu sử dụng nhiều bằng chứng KZG, người chứng minh sẽ cần thêm 48 khí cho mỗi L2 chứa kho khóa được sử dụng trong khối đó, do đó, chi phí cận biên của sơ đồ cho mỗi người dùng sẽ thêm ~800 khí L1 khác cho mỗi L2 (không phải cho mỗi người dùng) ở trên cùng. Nhưng những chi phí này thấp hơn nhiều so với chi phí không tổng hợp, chắc chắn liên quan đến hơn 10.000 L1 khí và hàng trăm nghìn khí L2 cho mỗi người dùng. Đối với cây Verkle, bạn có thể sử dụng trực tiếp Verkle multi-proofs, thêm khoảng 100-200 byte cho mỗi người dùng hoặc bạn có thể tạo ZK-SNARK của Verkle multi-proofs, có chi phí tương tự như ZK-SNARK của các nhánh Merkle nhưng rẻ hơn đáng kể để chứng minh.

Từ góc độ triển khai, có lẽ tốt nhất nên có các trình đóng gói tổng hợp các bằng chứng chuỗi chéo thông qua tiêu chuẩn trừu tượng hóa tài khoản ERC-4337 . ERC-4337 đã có cơ chế để người xây dựng tổng hợp các phần của UserOperations theo cách tùy chỉnh. Thậm chí còn <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> việc triển khai tính năng này cho việc tổng hợp chữ ký BLS, có thể giảm chi phí gas trên L2 từ 1,5 lần đến 3 lần tùy thuộc vào các hình thức nén khác bao gồm.

Sơ đồ từ <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> bài đăng triển khai ví BLS hiển thị quy trình làm việc của chữ ký tổng hợp BLS trong phiên bản ERC-4337 cũ hơn. Quy trình tổng hợp các bằng chứng chuỗi chéo có thể sẽ rất giống nhau.

Đọc trạng thái trực tiếp

Một khả năng cuối cùng và một khả năng chỉ có thể sử dụng được cho L2 đọc L1 (chứ không phải L1 đọc L2), là sửa đổi L2 để cho phép chúng thực hiện lệnh gọi tĩnh trực tiếp đến các hợp đồng trên L1.

Điều này có thể được thực hiện bằng opcode hoặc tiền biên dịch, cho phép các cuộc gọi đến L1 nơi bạn cung cấp địa chỉ đích, gas và dữ liệu cuộc gọi, đồng thời nó trả về kết quả đầu ra, tuy nhiên, vì các lệnh gọi này là lệnh gọi tĩnh nên chúng thực sự không thể thay đổi bất kỳ trạng thái L1 nào. L2 phải biết về L1 để xử lý tiền gửi, vì vậy không có gì cơ bản ngăn cản việc thực hiện điều đó; đây chủ yếu là một thách thức triển khai kỹ thuật (xem: RFP này từ Optimism để hỗ trợ các lệnh gọi tĩnh vào L1).

Lưu ý rằng nếu kho khóa nằm trên L1 và L2 tích hợp chức năng gọi tĩnh L1 thì không cần phải có bằng chứng nào cả! Tuy nhiên, nếu L2 không tích hợp các lệnh gọi tĩnh L1 hoặc nếu kho khóa nằm trên L2 (điều này cuối cùng có thể phải như vậy, một khi L1 trở nên quá đắt để người dùng sử dụng dù chỉ một chút), thì sẽ cần phải có bằng chứng.

L2 tìm hiểu trạng thái gốc Ethereum gần đây như thế nào?

Tất cả các sơ đồ trên đều yêu cầu L2 truy cập vào gốc trạng thái L1 gần đây hoặc toàn bộ trạng thái L1 gần đây. May mắn thay, tất cả các L2 đều có một số chức năng để truy cập trạng thái L1 gần đây. Điều này là do họ cần chức năng như vậy để xử lý các tin nhắn đến từ L1 đến L2, đáng chú ý nhất là tiền gửi.

Và thực sự, nếu L2 có tính năng gửi tiền thì bạn có thể sử dụng L2 đó để chuyển gốc trạng thái L1 sang hợp đồng trên L2: chỉ cần có hợp đồng trên L1, gọi opcode BLOCKHASH và chuyển nó sang L2 dưới dạng tin nhắn gửi tiền. Có thể nhận được tiêu đề khối đầy đủ và trích xuất gốc trạng thái của nó ở phía L2. Tuy nhiên, sẽ tốt hơn nhiều nếu mọi L2 có một cách rõ ràng để truy cập trực tiếp vào trạng thái L1 gần đây đầy đủ hoặc gốc trạng thái L1 gần đây.

Thách thức chính với việc tối ưu hóa cách L2 nhận được các gốc trạng thái L1 gần đây là đồng thời đạt được độ an toàn và độ trễ thấp:

  • Nếu L2 triển khai chức năng “đọc trực tiếp L1” một cách lười biếng, chỉ đọc các gốc trạng thái L1 đã hoàn thiện thì độ trễ thường sẽ là 15 phút, nhưng trong trường hợp cực đoan là rò rỉ không hoạt động (mà bạn phải chấp nhận), độ trễ có thể được vài tuần.
  • L2 hoàn toàn có thể được thiết kế để đọc các gốc trạng thái L1 gần đây hơn nhiều, nhưng vì L1 có thể hoàn nguyên (ngay cả với tính hữu hạn của một khe, việc hoàn nguyên có thể xảy ra trong quá trình rò rỉ không hoạt động), L2 cũng cần có khả năng hoàn nguyên. Đây là một thách thức về mặt kỹ thuật từ góc độ kỹ thuật phần mềm, nhưng ít nhất Optimism đã có khả năng này.
  • Nếu bạn sử dụng cầu gửi tiền để đưa gốc trạng thái L1 vào L2 thì khả năng tồn tại kinh tế đơn giản có thể cần một khoảng thời gian dài giữa các lần cập nhật tiền gửi: nếu toàn bộ chi phí của khoản tiền gửi là 100.000 gas và chúng tôi giả định ETH ở mức 1800 đô la và phí là ở mức 200 gwei và rễ L1 được đưa vào L2 một lần mỗi ngày, chi phí sẽ là 36 USD mỗi L2 mỗi ngày hoặc 13148 USD mỗi L2 mỗi năm để duy trì hệ thống. Với độ trễ một giờ, con số đó sẽ lên tới 315.569 USD mỗi L2 mỗi năm. Trong trường hợp tốt nhất, một lượng nhỏ người dùng giàu có thiếu kiên nhẫn sẽ trả phí cập nhật và cập nhật hệ thống cho những người khác. Trong trường hợp xấu nhất, một số người có lòng vị tha sẽ phải tự mình trả tiền cho việc đó.
  • “Oracles” (ít nhất, loại công nghệ mà một số người defi gọi là “oracles”) không phải là một giải pháp có thể chấp nhận được ở đây: quản lý khóa ví là một chức năng cấp thấp rất quan trọng về bảo mật và do đó, nó tối đa phải phụ thuộc vào một một vài phần của cơ sở hạ tầng cấp thấp rất đơn giản, không tin cậy về mặt mật mã.

Ngoài ra, theo hướng ngược lại (L1s đọc L2):

  • Trong các lần tổng hợp tích cực, các gốc tiểu bang phải mất một tuần để đạt L1 do sự chậm trễ trong việc chứng minh gian lận. Hiện tại, trên các bản tổng hợp ZK phải mất vài giờ do sự kết hợp giữa thời gian chứng minh và giới hạn kinh tế, mặc dù công nghệ trong tương lai sẽ giảm bớt điều này.
  • Xác nhận trước (từ trình sắp xếp thứ tự, người chứng thực, v.v.) không phải là giải pháp có thể chấp nhận được để đọc L1 L2. Quản lý ví là một chức năng cấp thấp rất quan trọng về bảo mật và do đó mức độ bảo mật của giao tiếp L2 -> L1 phải tuyệt đối: thậm chí không thể đẩy gốc trạng thái L1 sai bằng cách chiếm lấy bộ xác thực L2 . Các gốc trạng thái duy nhất mà L1 nên tin tưởng là các gốc trạng thái đã được chấp nhận là cuối cùng theo hợp đồng nắm giữ gốc trạng thái của L2 trên L1.

Một số tốc độ đối với các hoạt động chuỗi chéo không đáng tin cậy này chậm đến mức không thể chấp nhận được đối với nhiều trường hợp sử dụng defi; đối với những trường hợp đó, bạn cần có cầu nối nhanh hơn với các mô hình bảo mật không hoàn hảo hơn. Tuy nhiên, đối với trường hợp sử dụng cập nhật khóa ví, độ trễ lâu hơn sẽ được chấp nhận hơn: bạn không trì hoãn giao dịch theo giờ, bạn đang trì hoãn các thay đổi chính. Bạn sẽ phải giữ chìa khóa cũ lâu hơn. Nếu bạn đang thay đổi khóa vì khóa bị đánh cắp thì bạn sẽ có một khoảng thời gian dễ bị tổn thương đáng kể, nhưng điều này có thể được giảm thiểu, chẳng hạn như. bởi ví có chức năng đóng băng.

Cuối cùng, giải pháp giảm thiểu độ trễ tốt nhất là các L2 thực hiện đọc trực tiếp các gốc trạng thái L1 theo cách tối ưu, trong đó mỗi khối L2 (hoặc nhật ký tính toán gốc trạng thái) chứa một con trỏ tới khối L1 gần đây nhất, vì vậy nếu L1 hoàn nguyên , L2 cũng có thể hoàn nguyên. Hợp đồng kho khóa nên được đặt trên mạng chính hoặc trên L2 là ZK-rollup và do đó có thể nhanh chóng cam kết với L1.

Các khối của chuỗi L2 có thể phụ thuộc vào không chỉ các khối L2 trước đó mà còn phụ thuộc vào khối L1. Nếu L1 hoàn nguyên qua liên kết như vậy thì L2 cũng hoàn nguyên. Điều đáng chú ý là đây cũng là cách hoạt động của phiên bản sharding trước đó (trước Dank); xem ở đây để biết mã.

Một chuỗi khác cần bao nhiêu kết nối với Ethereum để giữ các ví có kho khóa bắt nguồn từ Ethereum hoặc L2?

Đáng ngạc nhiên là không nhiều lắm. Trên thực tế, nó thậm chí không cần phải là một bản tổng hợp: nếu đó là L3 hoặc một validium thì bạn có thể giữ ví ở đó, miễn là bạn giữ kho khóa trên L1 hoặc trên bản tổng hợp ZK. Điều bạn thực sự cần là chuỗi có quyền truy cập trực tiếp vào nguồn gốc trạng thái Ethereum cũng như cam kết về mặt kỹ thuật và xã hội để sẵn sàng tổ chức lại nếu Ethereum tổ chức lại và hard fork nếu Ethereum hard fork.

Một vấn đề nghiên cứu thú vị là xác định xem một chuỗi có thể có hình thức kết nối này với nhiều chuỗi khác ở mức độ nào (ví dụ: Ethereum và Zcash). Làm điều đó một cách ngây thơ là có thể: chuỗi của bạn có thể đồng ý tổ chức lại nếu Ethereum hoặc Zcash tổ chức lại (và hard fork nếu hard fork Ethereum hoặc Zcash), nhưng sau đó các nhà khai thác nút và cộng đồng của bạn nói chung có sự phụ thuộc gấp đôi về mặt kỹ thuật và chính trị. Do đó, kỹ thuật như vậy có thể được sử dụng để kết nối với một số chuỗi khác nhưng với chi phí ngày càng tăng. Các kế hoạch dựa trên cầu nối ZK có các đặc tính kỹ thuật hấp dẫn, nhưng chúng có điểm yếu chính là không đủ mạnh để chống lại các cuộc tấn công 51% hoặc hard fork. Có thể có nhiều giải pháp thông minh hơn.

Bảo vệ sự riêng tư

Lý tưởng nhất là chúng tôi cũng muốn bảo vệ sự riêng tư. Nếu bạn có nhiều ví được quản lý bởi cùng một kho khóa thì chúng tôi muốn đảm bảo:

  • Người ta không biết công khai rằng những chiếc ví đó đều được kết nối với nhau.
  • Những người giám hộ phục hồi xã hội không biết địa chỉ mà họ đang bảo vệ là gì.

Điều này tạo ra một số vấn đề:

  • Chúng tôi không thể sử dụng bằng chứng Merkle trực tiếp vì chúng không bảo vệ quyền riêng tư.
  • Nếu chúng tôi sử dụng KZG hoặc SNARK thì bằng chứng cần cung cấp phiên bản ẩn của khóa xác minh mà không tiết lộ vị trí của khóa xác minh.
  • Nếu chúng ta sử dụng tính năng tổng hợp thì trình tổng hợp sẽ không tìm hiểu vị trí trong văn bản gốc; đúng hơn, người tổng hợp sẽ nhận được bằng chứng mù quáng và có cách tổng hợp những bằng chứng đó.
  • Chúng tôi không thể sử dụng “phiên bản nhẹ” (chỉ sử dụng bằng chứng chuỗi chéo để cập nhật khóa), vì nó tạo ra rò rỉ quyền riêng tư: nếu nhiều ví được cập nhật cùng lúc do quy trình cập nhật, thời gian sẽ rò rỉ thông tin đó những chiếc ví đó có thể có liên quan. Vì vậy, chúng tôi phải sử dụng “phiên bản nặng” (bằng chứng chuỗi chéo cho mỗi giao dịch).

Với SNARK, các giải pháp dễ dàng về mặt khái niệm: bằng chứng được ẩn thông tin theo mặc định và trình tổng hợp cần tạo SNARK đệ quy để chứng minh SNARK.

Thách thức chính của phương pháp này hiện nay là việc tổng hợp yêu cầu trình tổng hợp tạo ra SNARK đệ quy, hiện khá chậm.

Với KZG, chúng tôi có thể sử dụng<a href="https://notes.ethereum.org/ @vbuterin /non_index_revealing_proof">điều này làm việc trên các bằng chứng KZG không tiết lộ chỉ mục (xem thêm: một phiên bản chính thức hơn của công việc đó trong bài báo Caulk ) làm điểm khởi đầu. Tuy nhiên, việc tổng hợp các bằng chứng mù là một vấn đề mở cần được quan tâm nhiều hơn.

Thật không may, việc đọc trực tiếp L1 từ bên trong L2 không đảm bảo quyền riêng tư, mặc dù việc triển khai chức năng đọc trực tiếp vẫn rất hữu ích, vừa để giảm thiểu độ trễ vừa vì tiện ích của nó cho các ứng dụng khác.

Tóm tắt

  • Để có ví khôi phục xã hội chuỗi chéo, quy trình làm việc thực tế nhất là ví duy trì kho khóa ở một vị trí và ví ở nhiều vị trí, trong đó ví đọc kho khóa (i) để cập nhật chế độ xem cục bộ của khóa xác minh hoặc (ii) trong quá trình xác minh từng giao dịch.
  • Một thành phần quan trọng để biến điều này thành hiện thực là bằng chứng chuỗi chéo. Chúng ta cần phải tối ưu hóa những bằng chứng này một cách chăm chỉ. ZK-SNARK đang chờ bằng chứng của Verkle hoặc giải pháp KZG được xây dựng tùy chỉnh, có vẻ như là những lựa chọn tốt nhất.
  • Về lâu dài, các giao thức tổng hợp trong đó các trình đóng gói tạo ra bằng chứng tổng hợp như một phần của việc tạo một gói gồm tất cả các Hoạt động của người dùng đã được người dùng gửi sẽ là cần thiết để giảm thiểu chi phí. Điều này có lẽ nên được tích hợp vào hệ sinh thái ERC-4337, mặc dù có thể sẽ cần phải thay đổi ERC-4337.
  • Các L2 nên được tối ưu hóa để giảm thiểu độ trễ khi đọc trạng thái L1 (hoặc ít nhất là gốc trạng thái) từ bên trong L2. L2 đọc trực tiếp trạng thái L1 là lý tưởng và có thể tiết kiệm không gian kiểm chứng.
  • Ví không chỉ có trên L2; bạn cũng có thể đặt ví trên các hệ thống có mức kết nối với Ethereum thấp hơn (L3 hoặc thậm chí các chuỗi riêng biệt chỉ đồng ý bao gồm các gốc trạng thái Ethereum và reorg hoặc hard fork khi Ethereum tổ chức lại hoặc phân nhánh cứng).
  • Tuy nhiên, kho khóa phải ở trên L1 hoặc trên ZK-rollup L2 có độ bảo mật cao. Ở trên L1 giúp tiết kiệm rất nhiều sự phức tạp, mặc dù về lâu dài, thậm chí điều đó có thể quá đắt, do đó cần có kho khóa trên L2.
  • Việc bảo vệ quyền riêng tư sẽ đòi hỏi phải làm thêm và khiến một số lựa chọn trở nên khó khăn hơn. Tuy nhiên, có lẽ chúng ta nên hướng tới các giải pháp bảo vệ quyền riêng tư và ít nhất hãy đảm bảo rằng mọi thứ chúng tôi đề xuất đều tương thích về phía trước với việc bảo vệ quyền riêng tư.

Tuyên bố từ chối trách nhiệm:

  1. Bài viết này được in lại từ [Vitalik], Mọi bản quyền thuộc về tác giả gốc [Vitalik Buterin]. Nếu có ý kiến phản đối việc tái bản này, vui lòng liên hệ với nhóm Gate Learn , họ sẽ xử lý kịp thời.
  2. Tuyên bố miễn trừ trách nhiệm pháp lý: Các quan điểm và ý kiến trình bày trong bài viết này chỉ là của tác giả và không cấu thành bất kỳ lời khuyên đầu tư nào.
  3. Việc dịch bài viết sang các ngôn ngữ khác được thực hiện bởi nhóm Gate Learn. Trừ khi được đề cập, việc sao chép, phân phối hoặc đạo văn các bài viết đã dịch đều bị cấm.

Tìm hiểu sâu hơn về cách đọc chéo L2 cho ví và các trường hợp sử dụng khác

Nâng caoFeb 29, 2024
Trong bài viết này, Vitalik trực tiếp đề cập đến khía cạnh kỹ thuật cụ thể của một bài toán con: cách đọc từ L2 sang L1, từ L1 đến L2 hoặc từ L2 này sang L2 khác dễ dàng hơn. Giải quyết vấn đề này là rất quan trọng để đạt được kiến trúc phân tách tài sản/khóa, nhưng nó cũng có các trường hợp sử dụng có giá trị trong các lĩnh vực khác, đáng chú ý nhất là tối ưu hóa các cuộc gọi chéo L2 đáng tin cậy, bao gồm các trường hợp sử dụng như di chuyển tài sản giữa L1 và L2.
Tìm hiểu sâu hơn về cách đọc chéo L2 cho ví và các trường hợp sử dụng khác

Đặc biệt cảm ơn Yoav Weiss, Dan Finlay, Martin Koppelmann và các nhóm Arbitrum, Optimism, Polygon, Scroll và SoulWallet đã phản hồi và đánh giá.

Trong bài đăng này về Ba lần chuyển đổi, tôi đã nêu ra một số lý do chính tại sao việc bắt đầu suy nghĩ rõ ràng về hỗ trợ L1 + chéo L2, bảo mật ví và quyền riêng tư như các tính năng cơ bản cần thiết của hệ sinh thái là rất có giá trị, thay vì xây dựng từng thứ này như các tiện ích bổ sung có thể được thiết kế riêng biệt theo từng ví riêng lẻ.

Bài đăng này sẽ tập trung trực tiếp hơn vào các khía cạnh kỹ thuật của một vấn đề phụ cụ thể: cách đọc L1 từ L2, L2 từ L1 hoặc L2 từ L2 khác dễ dàng hơn. Việc giải quyết vấn đề này là rất quan trọng để triển khai kiến trúc phân tách nội dung/kho khóa, nhưng nó cũng có các trường hợp sử dụng có giá trị trong các lĩnh vực khác, đáng chú ý nhất là tối ưu hóa các cuộc gọi chéo L2 đáng tin cậy, bao gồm các trường hợp sử dụng như di chuyển nội dung giữa L1 và L2.

Các bài đọc trước được đề xuất

Mục lục

Mục tiêu là gì?

Khi L2 trở nên phổ biến hơn, người dùng sẽ có tài sản trên nhiều L2 và có thể cả L1 nữa. Khi ví hợp đồng thông minh (multisig, social recovery hay cách khác) trở thành xu hướng phổ biến, các khóa cần thiết để truy cập vào một số tài khoản sẽ thay đổi theo thời gian và các khóa cũ sẽ không còn hiệu lực nữa. Khi cả hai điều này xảy ra, người dùng sẽ cần có cách thay đổi khóa có quyền truy cập vào nhiều tài khoản sống ở nhiều nơi khác nhau mà không cần thực hiện số lượng giao dịch cực cao.

Đặc biệt, chúng tôi cần một cách để xử lý các địa chỉ phản thực tế: các địa chỉ chưa được “đăng ký” trên chuỗi theo bất kỳ cách nào, tuy nhiên vẫn cần nhận và giữ tiền một cách an toàn. Tất cả chúng ta đều phụ thuộc vào các địa chỉ giả định: khi bạn sử dụng Ethereum lần đầu tiên, bạn có thể tạo một địa chỉ ETH mà ai đó có thể sử dụng để thanh toán cho bạn mà không cần “đăng ký” địa chỉ trên chuỗi (điều này sẽ yêu cầu phải trả phí tx và do đó đã nắm giữ một số ETH).

Với EOA, tất cả các địa chỉ đều bắt đầu dưới dạng địa chỉ phản thực tế. Với ví hợp đồng thông minh, các địa chỉ giả vẫn có thể thực hiện được, phần lớn là nhờ CREATE2, cho phép bạn có địa chỉ ETH chỉ có thể được điền bằng hợp đồng thông minh có mã khớp với một hàm băm cụ thể.

Thuật toán tính toán địa chỉ EIP-1014 (CREATE2) .

Tuy nhiên, ví hợp đồng thông minh đưa ra một thách thức mới: khả năng thay đổi khóa truy cập. Địa chỉ là hàm băm của initcode, chỉ có thể chứa khóa xác minh ban đầu của ví. Khóa xác minh hiện tại sẽ được lưu trữ trong bộ lưu trữ của ví, nhưng bản ghi lưu trữ đó không được truyền sang các L2 khác một cách kỳ diệu.

Nếu người dùng có nhiều địa chỉ trên nhiều L2, bao gồm cả các địa chỉ mà (vì chúng phản thực) mà L2 mà họ đang sử dụng không biết, thì có vẻ như chỉ có một cách duy nhất để cho phép người dùng thay đổi khóa của họ: assets / keystore kiến trúc tách biệt. Mỗi người dùng có (i) một “hợp đồng kho khóa” (trên L1 hoặc trên một L2 cụ thể), lưu trữ khóa xác minh cho tất cả các ví cùng với các quy tắc thay đổi khóa và (ii) “hợp đồng ví” trên L1 và nhiều ví khác. L2, đọc chuỗi chéo để lấy khóa xác minh.

Có hai cách để thực hiện điều này:

  • Phiên bản nhẹ (chỉ kiểm tra để cập nhật khóa): mỗi ví lưu trữ khóa xác minh cục bộ và chứa một chức năng có thể được gọi để kiểm tra bằng chứng chuỗi chéo về trạng thái hiện tại của kho khóa và cập nhật khóa xác minh được lưu trữ cục bộ cho phù hợp. Khi một ví được sử dụng lần đầu tiên trên một L2 cụ thể, việc gọi hàm đó để lấy khóa xác minh hiện tại từ kho khóa là bắt buộc.
    • Ưu điểm: sử dụng bằng chứng chuỗi chéo một cách tiết kiệm, vì vậy sẽ không sao nếu bằng chứng chuỗi chéo đắt tiền. Tất cả số tiền chỉ có thể được chi tiêu bằng các khóa hiện tại, vì vậy nó vẫn an toàn.
    • Nhược điểm: Để thay đổi khóa xác minh, bạn phải thực hiện thay đổi khóa trên chuỗi ở cả kho khóa và trong mọi ví đã được khởi tạo (mặc dù không phải là ví tiền giả). Điều này có thể tốn rất nhiều xăng.
  • Phiên bản nặng (kiểm tra mọi tx): bằng chứng chuỗi chéo hiển thị khóa hiện có trong kho khóa là cần thiết cho mỗi giao dịch.
    • Ưu điểm: độ phức tạp hệ thống ít hơn và cập nhật kho khóa rẻ.
    • Nhược điểm: đắt tiền trên mỗi tx, do đó đòi hỏi nhiều kỹ thuật hơn để tạo ra bằng chứng chuỗi chéo có giá rẻ ở mức chấp nhận được. Cũng không dễ tương thích với ERC-4337, hiện không hỗ trợ đọc hợp đồng chéo các đối tượng có thể thay đổi trong quá trình xác thực.

Bằng chứng chuỗi chéo trông như thế nào?

Để thể hiện toàn bộ sự phức tạp, chúng ta sẽ khám phá trường hợp khó khăn nhất: kho khóa nằm trên một L2 và ví nằm trên một L2 khác. Nếu kho khóa hoặc ví nằm trên L1 thì chỉ cần một nửa thiết kế này.

Giả sử kho khóa nằm trên Linea và ví nằm trên Kakarot. Bằng chứng đầy đủ về chìa khóa của ví bao gồm:

  • Một bằng chứng chứng minh trạng thái gốc Linea hiện tại, dựa trên trạng thái gốc Ethereum hiện tại mà Kakarot biết về
  • Bằng chứng chứng minh các khóa hiện tại trong kho khóa, dựa trên gốc trạng thái Linea hiện tại

Có hai câu hỏi triển khai phức tạp chính ở đây:

  1. Chúng ta sử dụng loại bằng chứng nào? (Có phải bằng chứng Merkle không? thứ gì khác?)
  2. Làm thế nào để L2 tìm hiểu gốc trạng thái L1 (Ethereum) gần đây (hoặc, như chúng ta sẽ thấy, có thể là trạng thái L1 đầy đủ) ngay từ đầu? Và cách khác, L1 học gốc trạng thái L2 như thế nào?
    • Trong cả hai trường hợp, độ trễ giữa điều gì đó xảy ra ở một bên và điều đó có thể được chứng minh đối với bên kia là bao lâu?

Chúng ta có thể sử dụng những loại sơ đồ chứng minh nào?

Có năm lựa chọn chính:

  • Bằng chứng Merkle
  • ZK-SNARK đa năng
  • Bằng chứng cho mục đích đặc biệt (ví dụ. với KZG)
  • Bằng chứng Verkle nằm giữa KZG và ZK-SNARK về cả khối lượng công việc và chi phí cơ sở hạ tầng.
  • Không có bằng chứng và dựa vào việc đọc trạng thái trực tiếp

Về công việc cơ sở hạ tầng cần thiết và chi phí cho người dùng, tôi xếp hạng đại khái như sau:

“Tập hợp” đề cập đến ý tưởng tổng hợp tất cả bằng chứng do người dùng cung cấp trong mỗi khối thành một siêu bằng chứng lớn kết hợp tất cả chúng. Điều này có thể áp dụng cho SNARK và KZG, nhưng không áp dụng cho các nhánh Merkle (bạn có thể kết hợp các nhánh Merkle một chút, nhưng nó chỉ giúp bạn tiết kiệm nhật ký (txs mỗi khối)/log (tổng số kho khóa), có thể là 15-30% trong thực tế, vì vậy nó có thể không đáng giá).

Việc tổng hợp chỉ có giá trị khi lược đồ có số lượng người dùng đáng kể, vì vậy trên thực tế, việc triển khai phiên bản 1 có thể loại bỏ tính năng tổng hợp và triển khai tính năng tổng hợp đó cho phiên bản 2.

Bằng chứng Merkle sẽ hoạt động như thế nào?

Cách này rất đơn giản: hãy làm theo sơ đồ trong phần trước một cách trực tiếp. Chính xác hơn, mỗi “bằng chứng” (giả sử trường hợp có độ khó tối đa là chứng minh một L2 thành một L2 khác) sẽ chứa:

  • Một nhánh Merkle chứng minh gốc trạng thái của L2 nắm giữ kho khóa, dựa trên gốc trạng thái gần đây nhất của Ethereum mà L2 biết. Gốc trạng thái của L2 chứa kho khóa được lưu trữ tại một khe lưu trữ đã biết của một địa chỉ đã biết (hợp đồng trên L1 đại diện cho L2) và do đó đường dẫn xuyên qua cây có thể được mã hóa cứng.
  • Nhánh Merkle chứng minh các khóa xác minh hiện tại, dựa trên gốc trạng thái của L2 giữ kho khóa. Ở đây một lần nữa, khóa xác minh được lưu trữ tại một khe lưu trữ đã biết của một địa chỉ đã biết, do đó đường dẫn có thể được mã hóa cứng.

Thật không may, bằng chứng trạng thái Ethereum rất phức tạp, nhưng vẫn tồn tại các thư viện để xác minh chúng và nếu bạn sử dụng các thư viện này, cơ chế này không quá phức tạp để thực hiện.

Vấn đề lớn hơn là chi phí. Bằng chứng Merkle rất dài và không may là cây Patricia dài hơn ~ 3,9 lần so với mức cần thiết (chính xác: bằng chứng Merkle lý tưởng cho một cây chứa N đối tượng dài 32 log2(N) byte và vì cây Patricia của Ethereum có 16 lá cho mỗi cây con nên bằng chứng đối với những cây đó dài 32 15 log16(N) ~= 125 log2(N) byte). Ở trạng thái có khoảng 250 triệu (~22⁸) tài khoản, điều này tạo ra mỗi bằng chứng 125 * 28 = 3500 byte, hoặc khoảng 56.000 gas, cộng thêm chi phí cho việc giải mã và xác minh giá trị băm.

Hai bằng chứng cùng nhau sẽ tiêu tốn khoảng 100.000 đến 150.000 gas (không bao gồm xác minh chữ ký nếu điều này được sử dụng cho mỗi giao dịch) - cao hơn đáng kể so với mức 21.000 gas cơ bản hiện tại cho mỗi giao dịch. Nhưng sự chênh lệch sẽ trở nên tồi tệ hơn nếu bằng chứng được xác minh trên L2. Việc tính toán bên trong L2 rất rẻ vì việc tính toán được thực hiện ngoài chuỗi và trong một hệ sinh thái có ít nút hơn nhiều so với L1. Mặt khác, dữ liệu phải được đưa lên L1. Do đó, sự so sánh không phải là 21000 gas so với 150.000 gas; đó là 21.000 khí L2 so với 100.000 khí L1.

Chúng ta có thể tính toán điều này có nghĩa là gì bằng cách xem xét so sánh giữa chi phí gas L1 và chi phí gas L2:

L1 hiện đắt hơn khoảng 15-25 lần so với L2 đối với các lần gửi đơn giản và đắt hơn 20-50 lần đối với các giao dịch hoán đổi mã thông báo. Việc gửi đơn giản tương đối nặng về dữ liệu, nhưng việc hoán đổi lại nặng về mặt tính toán hơn nhiều. Do đó, hoán đổi là một chuẩn mực tốt hơn để ước tính chi phí tính toán L1 so với tính toán L2. Nếu tính đến tất cả những điều này, nếu chúng ta giả định tỷ lệ chi phí là 30 lần giữa chi phí tính toán L1 và chi phí tính toán L2, thì điều này dường như ngụ ý rằng việc đưa bằng chứng Merkle lên L2 sẽ có chi phí tương đương với khoảng 50 giao dịch thông thường.

Tất nhiên, việc sử dụng cây Merkle nhị phân có thể cắt giảm chi phí ~ 4 lần, nhưng thậm chí, chi phí trong hầu hết các trường hợp sẽ quá cao - và nếu chúng ta sẵn sàng hy sinh việc không còn tương thích với hệ thập lục phân hiện tại của Ethereum cây trạng thái, chúng ta cũng có thể tìm kiếm những lựa chọn tốt hơn nữa.

Bằng chứng ZK-SNARK sẽ hoạt động như thế nào?

Về mặt khái niệm, việc sử dụng ZK-SNARK cũng dễ hiểu: bạn chỉ cần thay thế bằng chứng Merkle trong sơ đồ trên bằng ZK-SNARK chứng minh rằng những bằng chứng Merkle đó tồn tại. Một ZK-SNARK tốn ~400.000 gas tính toán và khoảng 400 byte (so sánh: 21.000 gas và 100 byte cho một giao dịch cơ bản, trong tương lai có thể giảm xuống ~25 byte khi nén). Do đó, từ góc độ tính toán, ZK-SNARK có giá gấp 19 lần chi phí của một giao dịch cơ bản ngày nay và từ góc độ dữ liệu, ZK-SNARK có giá gấp 4 lần so với một giao dịch cơ bản ngày nay và gấp 16 lần chi phí của một giao dịch cơ bản trong tương lai.

Những con số này là một cải tiến lớn so với bằng chứng Merkle, nhưng chúng vẫn khá đắt. Có hai cách để cải thiện điều này: (i) bằng chứng KZG cho mục đích đặc biệt hoặc (ii) tổng hợp, tương tự như tổng hợp ERC-4337 nhưng sử dụng phép toán lạ mắt hơn. Chúng ta có thể xem xét cả hai.

Bằng chứng KZG có mục đích đặc biệt sẽ hoạt động như thế nào?

Cảnh báo, phần này mang tính toán học nhiều hơn các phần khác. Điều này là do chúng tôi đang vượt xa các công cụ có mục đích chung và xây dựng thứ gì đó có mục đích đặc biệt để rẻ hơn, vì vậy chúng tôi phải “đi sâu” hơn nữa. Nếu bạn không thích toán sâu, hãy chuyển thẳng sang phần tiếp theo.

Đầu tiên, tóm tắt về cách thức hoạt động của các cam kết KZG:

  • Chúng ta có thể biểu diễn một tập hợp dữ liệu [D_1 … D_n] bằng bằng chứng KZG về đa thức bắt nguồn từ dữ liệu: cụ thể là đa thức P trong đó P(w) = D_1, P(w²) = D_2 … P(wⁿ) = D_n . w ở đây là “gốc của sự thống nhất”, một giá trị trong đó wᴺ = 1 đối với một số miền đánh giá có kích thước N (tất cả điều này được thực hiện trong một trường hữu hạn).
  • Để “cam kết” với P, chúng ta tạo một điểm trên đường cong elip com(P) = P₀ G + P₁ S₁ + … + Pₖ * Sₖ. Đây:
    • G là điểm tạo của đường cong
    • Pᵢ là hệ số bậc i của đa thức P
    • Sᵢ là điểm thứ i trong thiết lập tin cậy
  • Để chứng minh P(z) = a, chúng ta tạo một đa thức thương Q = (P - a) / (X - z), và tạo một cam kết com(Q) cho nó. Chỉ có thể tạo ra đa thức như vậy nếu P(z) thực sự bằng a.
  • Để kiểm chứng một chứng minh, chúng ta kiểm tra phương trình Q * (X - z) = P - a bằng cách thực hiện kiểm tra đường cong elip trên chứng minh com(Q) và cam kết đa thức com(P): chúng ta kiểm tra e(com(Q) , com(X - z)) ?= e(com(P) - com(a), com(1))

Một số thuộc tính quan trọng cần hiểu là:

  • Bằng chứng chỉ là giá trị com(Q), tức là 48 byte
  • com(P₁) + com(P₂) = com(P₁ + P₂)
  • Điều này cũng có nghĩa là bạn có thể “chỉnh sửa” một giá trị thành một cam kết hiện có. Giả sử rằng chúng ta biết rằng D_i hiện là a, chúng ta muốn đặt nó thành b và cam kết hiện có với D là com(P). Cam kết “P, nhưng với P(wⁱ) = b và không có đánh giá nào khác thay đổi”, thì chúng tôi đặt com(new_P) = com(P) + (ba) * com(Lᵢ), trong đó Lᵢ là “ Đa thức Lagrange” bằng 1 tại wⁱ và 0 tại các điểm wʲ khác.
  • Để thực hiện các cập nhật này một cách hiệu quả, tất cả N cam kết đối với đa thức Lagrange (com(Lᵢ)) có thể được tính toán trước và lưu trữ bởi mỗi khách hàng. Trong một hợp đồng trực tuyến, có thể sẽ quá nhiều để lưu trữ tất cả N cam kết, vì vậy thay vào đó, bạn có thể thực hiện cam kết KZG với tập hợp các giá trị com(L_i) (hoặc hash(com(L_i)), để bất cứ khi nào ai đó cần cập nhật cây trên chuỗi, họ có thể chỉ cần cung cấp com(L_i) thích hợp bằng chứng về tính chính xác của nó.

Do đó, chúng tôi có một cấu trúc nơi chúng tôi có thể tiếp tục thêm các giá trị vào cuối danh sách ngày càng phát triển, mặc dù với một giới hạn kích thước nhất định (trên thực tế, hàng trăm triệu có thể khả thi). Sau đó, chúng tôi sử dụng cấu trúc dữ liệu đó để quản lý (i) cam kết đối với danh sách các khóa trên mỗi L2, được lưu trữ trên L2 đó và được phản ánh tới L1, và (ii) cam kết đối với danh sách các cam kết khóa L2, được lưu trữ trên Ethereum L1 và được phản chiếu tới từng L2.

Việc cập nhật các cam kết có thể trở thành một phần của logic L2 cốt lõi hoặc có thể được triển khai mà không cần thay đổi giao thức lõi L2 thông qua cầu gửi và rút tiền.

Do đó, một bằng chứng đầy đủ sẽ yêu cầu:

  • Com(danh sách khóa) mới nhất trên L2 giữ kho khóa (48 byte)
  • Bằng chứng KZG về com(danh sách khóa) là một giá trị bên trong com(mirror_list), cam kết đối với danh sách tất cả các cam kết của danh sách khóa (48 byte)
  • Bằng chứng KZG về khóa của bạn trong com(danh sách khóa) (48 byte, cộng thêm 4 byte cho chỉ mục)

Trên thực tế, có thể hợp nhất hai bằng chứng KZG thành một, vì vậy chúng tôi nhận được tổng kích thước chỉ 100 byte.

Lưu ý một điều tinh tế: vì danh sách khóa là một danh sách chứ không phải bản đồ khóa/giá trị như trạng thái, nên danh sách khóa sẽ phải gán các vị trí một cách tuần tự. Hợp đồng cam kết khóa sẽ chứa cơ quan đăng ký nội bộ của chính nó ánh xạ từng kho khóa tới một ID và đối với mỗi khóa, nó sẽ lưu trữ hàm băm (khóa, địa chỉ của kho khóa) thay vì chỉ khóa, để giao tiếp rõ ràng với các L2 khác về kho khóa mà một mục nhập cụ thể là nói về.

Ưu điểm của kỹ thuật này là nó hoạt động rất tốt trên L2. Dữ liệu là 100 byte, ngắn hơn ~ 4 lần so với ZK-SNARK và ngắn hơn so với bằng chứng Merkle. Chi phí tính toán phần lớn là một séc ghép đôi cỡ 2, hoặc khoảng 119.000 gas. Trên L1, dữ liệu ít quan trọng hơn tính toán và thật không may, KZG có phần đắt hơn bằng chứng Merkle.

Cây Verkle sẽ hoạt động như thế nào?

Về cơ bản, cây Verkle liên quan đến việc xếp chồng các cam kết KZG (hoặc cam kết IPA, có thể hiệu quả hơn và sử dụng mật mã đơn giản hơn) chồng lên nhau: để lưu trữ 2⁴⁸ giá trị, bạn có thể thực hiện cam kết KZG với danh sách 22⁴ giá trị, mỗi giá trị đều là chính nó là cam kết của KZG với 22⁴ giá trị. Cây Verkle đang được<a href="https://notes.ethereum.org/ @vbuterin /verkle_tree_eip">phát triển mạnh mẽ được xem xét cho cây trạng thái Ethereum, vì cây Verkle có thể được sử dụng để chứa các bản đồ khóa-giá trị chứ không chỉ các danh sách (về cơ bản, bạn có thể tạo cây có kích thước 2²⁵⁶ nhưng bắt đầu trống, chỉ điền vào các phần cụ thể của cây khi bạn thực sự cần điền chúng).

Cây Verkle trông như thế nào. Trong thực tế, bạn có thể cấp cho mỗi nút chiều rộng là 256 == 2⁸ đối với cây dựa trên IPA hoặc 2²⁴ đối với cây dựa trên KZG.

Chứng minh trong cây Verkle dài hơn KZG một chút; chúng có thể dài vài trăm byte. Chúng cũng khó xác minh, đặc biệt nếu bạn cố gắng tổng hợp nhiều bằng chứng thành một.

Trên thực tế, cây Verkle nên được coi là giống như cây Merkle, nhưng khả thi hơn khi không có SNARKing (vì chi phí dữ liệu thấp hơn) và rẻ hơn với SNARKing (vì chi phí chứng minh thấp hơn).

Ưu điểm lớn nhất của cây Verkle là khả năng hài hòa các cấu trúc dữ liệu: Bằng chứng Verkle có thể được sử dụng trực tiếp trên trạng thái L1 hoặc L2, không cần cấu trúc lớp phủ và sử dụng cơ chế giống hệt nhau cho L1 và L2. Khi máy tính lượng tử trở thành vấn đề hoặc khi chứng minh được các nhánh Merkle trở nên đủ hiệu quả, cây Verkle có thể được thay thế tại chỗ bằng cây băm nhị phân có hàm băm thân thiện với SNARK phù hợp.

Tổng hợp

Nếu N người dùng thực hiện N giao dịch (hoặc thực tế hơn là N ERC-4337 UserOperations) cần chứng minh N xác nhận quyền sở hữu chuỗi chéo, chúng tôi có thể tiết kiệm rất nhiều gas bằng cách tổng hợp các bằng chứng đó: người xây dựng sẽ kết hợp các giao dịch đó thành một khối hoặc gói đi vào một khối có thể tạo ra một bằng chứng duy nhất chứng minh đồng thời tất cả các tuyên bố đó.

Điều này có thể có nghĩa là:

Trong cả ba trường hợp, mỗi lần chứng minh sẽ chỉ tốn vài trăm nghìn xăng. Người xây dựng sẽ cần tạo một trong những thứ này trên mỗi L2 cho người dùng trong L2 đó; do đó, để việc xây dựng điều này trở nên hữu ích, toàn bộ sơ đồ cần phải có đủ mức sử dụng để thường có ít nhất một vài giao dịch trong cùng một khối trên nhiều L2 chính.

Nếu ZK-SNARK được sử dụng, chi phí cận biên chính chỉ đơn giản là “logic kinh doanh” của việc chuyển các con số giữa các hợp đồng, do đó có thể là vài nghìn L2 gas cho mỗi người dùng. Nếu sử dụng nhiều bằng chứng KZG, người chứng minh sẽ cần thêm 48 khí cho mỗi L2 chứa kho khóa được sử dụng trong khối đó, do đó, chi phí cận biên của sơ đồ cho mỗi người dùng sẽ thêm ~800 khí L1 khác cho mỗi L2 (không phải cho mỗi người dùng) ở trên cùng. Nhưng những chi phí này thấp hơn nhiều so với chi phí không tổng hợp, chắc chắn liên quan đến hơn 10.000 L1 khí và hàng trăm nghìn khí L2 cho mỗi người dùng. Đối với cây Verkle, bạn có thể sử dụng trực tiếp Verkle multi-proofs, thêm khoảng 100-200 byte cho mỗi người dùng hoặc bạn có thể tạo ZK-SNARK của Verkle multi-proofs, có chi phí tương tự như ZK-SNARK của các nhánh Merkle nhưng rẻ hơn đáng kể để chứng minh.

Từ góc độ triển khai, có lẽ tốt nhất nên có các trình đóng gói tổng hợp các bằng chứng chuỗi chéo thông qua tiêu chuẩn trừu tượng hóa tài khoản ERC-4337 . ERC-4337 đã có cơ chế để người xây dựng tổng hợp các phần của UserOperations theo cách tùy chỉnh. Thậm chí còn <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> việc triển khai tính năng này cho việc tổng hợp chữ ký BLS, có thể giảm chi phí gas trên L2 từ 1,5 lần đến 3 lần tùy thuộc vào các hình thức nén khác bao gồm.

Sơ đồ từ <a href="https://hackmd.io/@voltrevo/BJ0QBy3zi"> bài đăng triển khai ví BLS hiển thị quy trình làm việc của chữ ký tổng hợp BLS trong phiên bản ERC-4337 cũ hơn. Quy trình tổng hợp các bằng chứng chuỗi chéo có thể sẽ rất giống nhau.

Đọc trạng thái trực tiếp

Một khả năng cuối cùng và một khả năng chỉ có thể sử dụng được cho L2 đọc L1 (chứ không phải L1 đọc L2), là sửa đổi L2 để cho phép chúng thực hiện lệnh gọi tĩnh trực tiếp đến các hợp đồng trên L1.

Điều này có thể được thực hiện bằng opcode hoặc tiền biên dịch, cho phép các cuộc gọi đến L1 nơi bạn cung cấp địa chỉ đích, gas và dữ liệu cuộc gọi, đồng thời nó trả về kết quả đầu ra, tuy nhiên, vì các lệnh gọi này là lệnh gọi tĩnh nên chúng thực sự không thể thay đổi bất kỳ trạng thái L1 nào. L2 phải biết về L1 để xử lý tiền gửi, vì vậy không có gì cơ bản ngăn cản việc thực hiện điều đó; đây chủ yếu là một thách thức triển khai kỹ thuật (xem: RFP này từ Optimism để hỗ trợ các lệnh gọi tĩnh vào L1).

Lưu ý rằng nếu kho khóa nằm trên L1 và L2 tích hợp chức năng gọi tĩnh L1 thì không cần phải có bằng chứng nào cả! Tuy nhiên, nếu L2 không tích hợp các lệnh gọi tĩnh L1 hoặc nếu kho khóa nằm trên L2 (điều này cuối cùng có thể phải như vậy, một khi L1 trở nên quá đắt để người dùng sử dụng dù chỉ một chút), thì sẽ cần phải có bằng chứng.

L2 tìm hiểu trạng thái gốc Ethereum gần đây như thế nào?

Tất cả các sơ đồ trên đều yêu cầu L2 truy cập vào gốc trạng thái L1 gần đây hoặc toàn bộ trạng thái L1 gần đây. May mắn thay, tất cả các L2 đều có một số chức năng để truy cập trạng thái L1 gần đây. Điều này là do họ cần chức năng như vậy để xử lý các tin nhắn đến từ L1 đến L2, đáng chú ý nhất là tiền gửi.

Và thực sự, nếu L2 có tính năng gửi tiền thì bạn có thể sử dụng L2 đó để chuyển gốc trạng thái L1 sang hợp đồng trên L2: chỉ cần có hợp đồng trên L1, gọi opcode BLOCKHASH và chuyển nó sang L2 dưới dạng tin nhắn gửi tiền. Có thể nhận được tiêu đề khối đầy đủ và trích xuất gốc trạng thái của nó ở phía L2. Tuy nhiên, sẽ tốt hơn nhiều nếu mọi L2 có một cách rõ ràng để truy cập trực tiếp vào trạng thái L1 gần đây đầy đủ hoặc gốc trạng thái L1 gần đây.

Thách thức chính với việc tối ưu hóa cách L2 nhận được các gốc trạng thái L1 gần đây là đồng thời đạt được độ an toàn và độ trễ thấp:

  • Nếu L2 triển khai chức năng “đọc trực tiếp L1” một cách lười biếng, chỉ đọc các gốc trạng thái L1 đã hoàn thiện thì độ trễ thường sẽ là 15 phút, nhưng trong trường hợp cực đoan là rò rỉ không hoạt động (mà bạn phải chấp nhận), độ trễ có thể được vài tuần.
  • L2 hoàn toàn có thể được thiết kế để đọc các gốc trạng thái L1 gần đây hơn nhiều, nhưng vì L1 có thể hoàn nguyên (ngay cả với tính hữu hạn của một khe, việc hoàn nguyên có thể xảy ra trong quá trình rò rỉ không hoạt động), L2 cũng cần có khả năng hoàn nguyên. Đây là một thách thức về mặt kỹ thuật từ góc độ kỹ thuật phần mềm, nhưng ít nhất Optimism đã có khả năng này.
  • Nếu bạn sử dụng cầu gửi tiền để đưa gốc trạng thái L1 vào L2 thì khả năng tồn tại kinh tế đơn giản có thể cần một khoảng thời gian dài giữa các lần cập nhật tiền gửi: nếu toàn bộ chi phí của khoản tiền gửi là 100.000 gas và chúng tôi giả định ETH ở mức 1800 đô la và phí là ở mức 200 gwei và rễ L1 được đưa vào L2 một lần mỗi ngày, chi phí sẽ là 36 USD mỗi L2 mỗi ngày hoặc 13148 USD mỗi L2 mỗi năm để duy trì hệ thống. Với độ trễ một giờ, con số đó sẽ lên tới 315.569 USD mỗi L2 mỗi năm. Trong trường hợp tốt nhất, một lượng nhỏ người dùng giàu có thiếu kiên nhẫn sẽ trả phí cập nhật và cập nhật hệ thống cho những người khác. Trong trường hợp xấu nhất, một số người có lòng vị tha sẽ phải tự mình trả tiền cho việc đó.
  • “Oracles” (ít nhất, loại công nghệ mà một số người defi gọi là “oracles”) không phải là một giải pháp có thể chấp nhận được ở đây: quản lý khóa ví là một chức năng cấp thấp rất quan trọng về bảo mật và do đó, nó tối đa phải phụ thuộc vào một một vài phần của cơ sở hạ tầng cấp thấp rất đơn giản, không tin cậy về mặt mật mã.

Ngoài ra, theo hướng ngược lại (L1s đọc L2):

  • Trong các lần tổng hợp tích cực, các gốc tiểu bang phải mất một tuần để đạt L1 do sự chậm trễ trong việc chứng minh gian lận. Hiện tại, trên các bản tổng hợp ZK phải mất vài giờ do sự kết hợp giữa thời gian chứng minh và giới hạn kinh tế, mặc dù công nghệ trong tương lai sẽ giảm bớt điều này.
  • Xác nhận trước (từ trình sắp xếp thứ tự, người chứng thực, v.v.) không phải là giải pháp có thể chấp nhận được để đọc L1 L2. Quản lý ví là một chức năng cấp thấp rất quan trọng về bảo mật và do đó mức độ bảo mật của giao tiếp L2 -> L1 phải tuyệt đối: thậm chí không thể đẩy gốc trạng thái L1 sai bằng cách chiếm lấy bộ xác thực L2 . Các gốc trạng thái duy nhất mà L1 nên tin tưởng là các gốc trạng thái đã được chấp nhận là cuối cùng theo hợp đồng nắm giữ gốc trạng thái của L2 trên L1.

Một số tốc độ đối với các hoạt động chuỗi chéo không đáng tin cậy này chậm đến mức không thể chấp nhận được đối với nhiều trường hợp sử dụng defi; đối với những trường hợp đó, bạn cần có cầu nối nhanh hơn với các mô hình bảo mật không hoàn hảo hơn. Tuy nhiên, đối với trường hợp sử dụng cập nhật khóa ví, độ trễ lâu hơn sẽ được chấp nhận hơn: bạn không trì hoãn giao dịch theo giờ, bạn đang trì hoãn các thay đổi chính. Bạn sẽ phải giữ chìa khóa cũ lâu hơn. Nếu bạn đang thay đổi khóa vì khóa bị đánh cắp thì bạn sẽ có một khoảng thời gian dễ bị tổn thương đáng kể, nhưng điều này có thể được giảm thiểu, chẳng hạn như. bởi ví có chức năng đóng băng.

Cuối cùng, giải pháp giảm thiểu độ trễ tốt nhất là các L2 thực hiện đọc trực tiếp các gốc trạng thái L1 theo cách tối ưu, trong đó mỗi khối L2 (hoặc nhật ký tính toán gốc trạng thái) chứa một con trỏ tới khối L1 gần đây nhất, vì vậy nếu L1 hoàn nguyên , L2 cũng có thể hoàn nguyên. Hợp đồng kho khóa nên được đặt trên mạng chính hoặc trên L2 là ZK-rollup và do đó có thể nhanh chóng cam kết với L1.

Các khối của chuỗi L2 có thể phụ thuộc vào không chỉ các khối L2 trước đó mà còn phụ thuộc vào khối L1. Nếu L1 hoàn nguyên qua liên kết như vậy thì L2 cũng hoàn nguyên. Điều đáng chú ý là đây cũng là cách hoạt động của phiên bản sharding trước đó (trước Dank); xem ở đây để biết mã.

Một chuỗi khác cần bao nhiêu kết nối với Ethereum để giữ các ví có kho khóa bắt nguồn từ Ethereum hoặc L2?

Đáng ngạc nhiên là không nhiều lắm. Trên thực tế, nó thậm chí không cần phải là một bản tổng hợp: nếu đó là L3 hoặc một validium thì bạn có thể giữ ví ở đó, miễn là bạn giữ kho khóa trên L1 hoặc trên bản tổng hợp ZK. Điều bạn thực sự cần là chuỗi có quyền truy cập trực tiếp vào nguồn gốc trạng thái Ethereum cũng như cam kết về mặt kỹ thuật và xã hội để sẵn sàng tổ chức lại nếu Ethereum tổ chức lại và hard fork nếu Ethereum hard fork.

Một vấn đề nghiên cứu thú vị là xác định xem một chuỗi có thể có hình thức kết nối này với nhiều chuỗi khác ở mức độ nào (ví dụ: Ethereum và Zcash). Làm điều đó một cách ngây thơ là có thể: chuỗi của bạn có thể đồng ý tổ chức lại nếu Ethereum hoặc Zcash tổ chức lại (và hard fork nếu hard fork Ethereum hoặc Zcash), nhưng sau đó các nhà khai thác nút và cộng đồng của bạn nói chung có sự phụ thuộc gấp đôi về mặt kỹ thuật và chính trị. Do đó, kỹ thuật như vậy có thể được sử dụng để kết nối với một số chuỗi khác nhưng với chi phí ngày càng tăng. Các kế hoạch dựa trên cầu nối ZK có các đặc tính kỹ thuật hấp dẫn, nhưng chúng có điểm yếu chính là không đủ mạnh để chống lại các cuộc tấn công 51% hoặc hard fork. Có thể có nhiều giải pháp thông minh hơn.

Bảo vệ sự riêng tư

Lý tưởng nhất là chúng tôi cũng muốn bảo vệ sự riêng tư. Nếu bạn có nhiều ví được quản lý bởi cùng một kho khóa thì chúng tôi muốn đảm bảo:

  • Người ta không biết công khai rằng những chiếc ví đó đều được kết nối với nhau.
  • Những người giám hộ phục hồi xã hội không biết địa chỉ mà họ đang bảo vệ là gì.

Điều này tạo ra một số vấn đề:

  • Chúng tôi không thể sử dụng bằng chứng Merkle trực tiếp vì chúng không bảo vệ quyền riêng tư.
  • Nếu chúng tôi sử dụng KZG hoặc SNARK thì bằng chứng cần cung cấp phiên bản ẩn của khóa xác minh mà không tiết lộ vị trí của khóa xác minh.
  • Nếu chúng ta sử dụng tính năng tổng hợp thì trình tổng hợp sẽ không tìm hiểu vị trí trong văn bản gốc; đúng hơn, người tổng hợp sẽ nhận được bằng chứng mù quáng và có cách tổng hợp những bằng chứng đó.
  • Chúng tôi không thể sử dụng “phiên bản nhẹ” (chỉ sử dụng bằng chứng chuỗi chéo để cập nhật khóa), vì nó tạo ra rò rỉ quyền riêng tư: nếu nhiều ví được cập nhật cùng lúc do quy trình cập nhật, thời gian sẽ rò rỉ thông tin đó những chiếc ví đó có thể có liên quan. Vì vậy, chúng tôi phải sử dụng “phiên bản nặng” (bằng chứng chuỗi chéo cho mỗi giao dịch).

Với SNARK, các giải pháp dễ dàng về mặt khái niệm: bằng chứng được ẩn thông tin theo mặc định và trình tổng hợp cần tạo SNARK đệ quy để chứng minh SNARK.

Thách thức chính của phương pháp này hiện nay là việc tổng hợp yêu cầu trình tổng hợp tạo ra SNARK đệ quy, hiện khá chậm.

Với KZG, chúng tôi có thể sử dụng<a href="https://notes.ethereum.org/ @vbuterin /non_index_revealing_proof">điều này làm việc trên các bằng chứng KZG không tiết lộ chỉ mục (xem thêm: một phiên bản chính thức hơn của công việc đó trong bài báo Caulk ) làm điểm khởi đầu. Tuy nhiên, việc tổng hợp các bằng chứng mù là một vấn đề mở cần được quan tâm nhiều hơn.

Thật không may, việc đọc trực tiếp L1 từ bên trong L2 không đảm bảo quyền riêng tư, mặc dù việc triển khai chức năng đọc trực tiếp vẫn rất hữu ích, vừa để giảm thiểu độ trễ vừa vì tiện ích của nó cho các ứng dụng khác.

Tóm tắt

  • Để có ví khôi phục xã hội chuỗi chéo, quy trình làm việc thực tế nhất là ví duy trì kho khóa ở một vị trí và ví ở nhiều vị trí, trong đó ví đọc kho khóa (i) để cập nhật chế độ xem cục bộ của khóa xác minh hoặc (ii) trong quá trình xác minh từng giao dịch.
  • Một thành phần quan trọng để biến điều này thành hiện thực là bằng chứng chuỗi chéo. Chúng ta cần phải tối ưu hóa những bằng chứng này một cách chăm chỉ. ZK-SNARK đang chờ bằng chứng của Verkle hoặc giải pháp KZG được xây dựng tùy chỉnh, có vẻ như là những lựa chọn tốt nhất.
  • Về lâu dài, các giao thức tổng hợp trong đó các trình đóng gói tạo ra bằng chứng tổng hợp như một phần của việc tạo một gói gồm tất cả các Hoạt động của người dùng đã được người dùng gửi sẽ là cần thiết để giảm thiểu chi phí. Điều này có lẽ nên được tích hợp vào hệ sinh thái ERC-4337, mặc dù có thể sẽ cần phải thay đổi ERC-4337.
  • Các L2 nên được tối ưu hóa để giảm thiểu độ trễ khi đọc trạng thái L1 (hoặc ít nhất là gốc trạng thái) từ bên trong L2. L2 đọc trực tiếp trạng thái L1 là lý tưởng và có thể tiết kiệm không gian kiểm chứng.
  • Ví không chỉ có trên L2; bạn cũng có thể đặt ví trên các hệ thống có mức kết nối với Ethereum thấp hơn (L3 hoặc thậm chí các chuỗi riêng biệt chỉ đồng ý bao gồm các gốc trạng thái Ethereum và reorg hoặc hard fork khi Ethereum tổ chức lại hoặc phân nhánh cứng).
  • Tuy nhiên, kho khóa phải ở trên L1 hoặc trên ZK-rollup L2 có độ bảo mật cao. Ở trên L1 giúp tiết kiệm rất nhiều sự phức tạp, mặc dù về lâu dài, thậm chí điều đó có thể quá đắt, do đó cần có kho khóa trên L2.
  • Việc bảo vệ quyền riêng tư sẽ đòi hỏi phải làm thêm và khiến một số lựa chọn trở nên khó khăn hơn. Tuy nhiên, có lẽ chúng ta nên hướng tới các giải pháp bảo vệ quyền riêng tư và ít nhất hãy đảm bảo rằng mọi thứ chúng tôi đề xuất đều tương thích về phía trước với việc bảo vệ quyền riêng tư.

Tuyên bố từ chối trách nhiệm:

  1. Bài viết này được in lại từ [Vitalik], Mọi bản quyền thuộc về tác giả gốc [Vitalik Buterin]. Nếu có ý kiến phản đối việc tái bản này, vui lòng liên hệ với nhóm Gate Learn , họ sẽ xử lý kịp thời.
  2. Tuyên bố miễn trừ trách nhiệm pháp lý: Các quan điểm và ý kiến trình bày trong bài viết này chỉ là của tác giả và không cấu thành bất kỳ lời khuyên đầu tư nào.
  3. Việc dịch bài viết sang các ngôn ngữ khác được thực hiện bởi nhóm Gate Learn. Trừ khi được đề cập, việc sao chép, phân phối hoặc đạo văn các bài viết đã dịch đều bị cấm.
Bắt đầu giao dịch
Đăng ký và giao dịch để nhận phần thưởng USDTEST trị giá
$100
$5500