Tác giả gốc: Vitalik Buterin Bản dịch gốc: Nian Yin Si Tang, Odaily
Ngay từ khi bắt đầu dự án Ethereum, đã có một triết lý mạnh mẽ là cố gắng làm cho Ethereum cốt lõi trở nên đơn giản nhất có thể và đạt được điều này nhiều nhất có thể bằng cách xây dựng các giao thức trên đó. Trong không gian blockchain, cuộc tranh luận “xây dựng trên L1” và “tập trung vào L2” thường được coi chủ yếu là về việc mở rộng quy mô, nhưng trên thực tế, có những vấn đề tương tự trong việc đáp ứng nhu cầu của nhiều người dùng Ethereum: Trao đổi tài sản kỹ thuật số, quyền riêng tư , tên người dùng, mã hóa nâng cao, bảo mật tài khoản, khả năng chống kiểm duyệt, bảo vệ chạy trước, v.v. Tuy nhiên, gần đây đã có một số nỗ lực thận trọng nhằm đưa nhiều tính năng này vào giao thức Ethereum cốt lõi.
Bài viết này sẽ đi sâu vào một số lý luận triết học đằng sau triết lý đóng gói tối thiểu ban đầu, cũng như một số cách suy nghĩ gần đây về những ý tưởng này. Mục tiêu là bắt đầu xây dựng một khuôn khổ để xác định tốt hơn các mục tiêu khả thi mà việc đóng gói một số chức năng nhất định có thể đáng để cân nhắc.
Triết lý ban đầu về chủ nghĩa tối giản giao thức
Trong lịch sử ban đầu của cái mà khi đó được gọi là “Ethereum 2.0”, người ta mong muốn mạnh mẽ tạo ra một giao thức sạch, đơn giản và đẹp mắt, cố gắng xây dựng càng ít càng tốt và để lại hầu hết công việc này cho người dùng. Trong điều kiện lý tưởng, giao thức chỉ là một máy ảo và việc xác minh khối chỉ là một lệnh gọi máy ảo.
“Hàm chuyển đổi trạng thái” (hàm xử lý khối) sẽ chỉ là một lệnh gọi VM duy nhất và mọi logic khác sẽ diễn ra thông qua hợp đồng: một số hợp đồng cấp hệ thống, nhưng chủ yếu là hợp đồng do người dùng cung cấp. Một tính năng thực sự tuyệt vời của mô hình này là ngay cả một hard fork hoàn chỉnh cũng có thể được mô tả như một giao dịch duy nhất đối với hợp đồng xử lý khối, sẽ được chấp thuận bởi quản trị ngoài chuỗi hoặc trên chuỗi và sau đó chạy với các quyền được nâng cấp.
Những cuộc thảo luận năm 2015 này đặc biệt áp dụng cho hai lĩnh vực mà chúng tôi xem xét: trừu tượng hóa tài khoản và mở rộng quy mô. Trong trường hợp mở rộng quy mô, ý tưởng là cố gắng tạo ra một dạng mở rộng trừu tượng tối đa giống như phần mở rộng tự nhiên của sơ đồ trên. Hợp đồng có thể gọi dữ liệu không được lưu trữ bởi hầu hết các nút Ethereum và giao thức sẽ phát hiện dữ liệu này và giải quyết lệnh gọi thông qua một số hàm tính toán mở rộng rất chung. Theo góc nhìn của VM, lệnh gọi sẽ đi vào một hệ thống con riêng biệt và sau đó sẽ trả về câu trả lời đúng một cách kỳ diệu sau một thời gian.
Chúng tôi đã khám phá sơ qua dòng suy nghĩ này nhưng nhanh chóng từ bỏ vì quá tập trung vào việc chứng minh rằng bất kỳ loại khả năng mở rộng blockchain nào cũng có thể thực hiện được. Mặc dù như chúng ta sẽ thấy sau, sự kết hợp giữa lấy mẫu dữ liệu khả dụng và ZK-EVM có nghĩa là một tương lai có thể xảy ra để mở rộng quy mô Ethereum thực sự trông khá gần với tầm nhìn này! Mặt khác, với việc trừu tượng hóa tài khoản, ngay từ đầu chúng tôi đã biết rằng có thể thực hiện được một số loại triển khai, vì vậy chúng tôi đã ngay lập tức bắt đầu nghiên cứu để cố gắng tạo ra thứ gì đó gần nhất có thể với điểm khởi đầu thuần túy của "giao dịch chỉ là một cuộc gọi".
Có rất nhiều mã chuẩn giữa quá trình xử lý giao dịch và thực hiện các cuộc gọi EVM cơ bản thực tế từ địa chỉ người gửi và sẽ còn nhiều mã chuẩn hơn nữa trong tương lai. Làm thế nào chúng ta có thể giảm mã này xuống mức gần bằng không nhất có thể?
Một trong những mã chính ở đây là validate_transaction(state, tx), có chức năng kiểm tra xem nonce và chữ ký của giao dịch có chính xác hay không. Ngay từ đầu, mục tiêu thực sự của việc trừu tượng hóa tài khoản là cho phép người dùng thay thế xác minh cơ bản không gia tăng và ECDSA bằng logic xác minh của riêng họ, để người dùng có thể dễ dàng sử dụng các tính năng như phục hồi xã hội và ví đa chữ ký. Do đó, việc tìm cách tái thiết kế apply_transaction thành một lệnh gọi EVM đơn giản không chỉ là nhiệm vụ "làm cho mã sạch hơn vì mục đích làm cho mã sạch hơn"; mà là chuyển logic vào mã tài khoản của người dùng, mang đến cho người dùng sự linh hoạt mà họ cần.
Tuy nhiên, việc khăng khăng bắt apply_transaction chứa càng ít logic cố định càng tốt lại gây ra rất nhiều thách thức. Chúng ta có thể xem xét một trong những đề xuất trừu tượng hóa tài khoản sớm nhất, EIP-86.
Nếu EIP-86 được đưa vào như hiện tại, nó sẽ làm giảm độ phức tạp của EVM nhưng lại làm tăng độ phức tạp đáng kể ở các phần khác của ngăn xếp Ethereum, về cơ bản yêu cầu phải viết cùng một mã chính xác ở những nơi khác, ngoài ra còn đưa vào các lớp kỳ lạ hoàn toàn mới, chẳng hạn như khả năng cùng một giao dịch với cùng một hàm băm có thể xuất hiện nhiều lần trong chuỗi, chưa kể đến vấn đề vô hiệu hóa nhiều lần.
Vấn đề vô hiệu hóa nhiều lần trong trừu tượng hóa tài khoản. Một giao dịch được đưa vào chuỗi có thể làm mất hiệu lực hàng nghìn giao dịch khác trong mempool, khiến việc tràn ngập mempool trở nên dễ dàng với chi phí thấp.
Kể từ đó, việc trừu tượng hóa tài khoản đã phát triển theo từng giai đoạn. EIP-86 sau đó trở thành EIP-208 và cuối cùng EIP-2938 thực tế đã xuất hiện.
Tuy nhiên, EIP-2938 không hề tối giản. Nội dung của nó bao gồm:
Các loại giao dịch mới
Ba biến toàn cầu mới có phạm vi giao dịch
Hai mã lệnh mới, bao gồm mã lệnh PAYgas rất khó sử dụng để xử lý giá gas và kiểm tra giới hạn gas, làm điểm dừng thực thi EVM và để lưu trữ tạm thời ETH cho các khoản thanh toán phí một lần
Một tập hợp phức tạp các chiến lược khai thác và chuyển tiếp, bao gồm danh sách các mã lệnh bị cấm trong giai đoạn xác thực giao dịch
Để đạt được sự trừu tượng hóa tài khoản mà không cần sự tham gia của các nhà phát triển cốt lõi Ethereum (những người tập trung vào việc tối ưu hóa máy khách Ethereum và triển khai việc hợp nhất), EIP-2938 cuối cùng đã được thiết kế lại thành ERC-4337, hoàn toàn nằm ngoài giao thức.
Vì đây là ERC nên nó không yêu cầu phải hard fork và về mặt kỹ thuật thì nó tồn tại “bên ngoài giao thức Ethereum”. Vậy...vấn đề đã được giải quyết chưa? Thực tế thì không phải vậy. Lộ trình trung hạn hiện tại cho ERC-4337 thực sự bao gồm việc biến các phần lớn của ERC-4337 thành một loạt các tính năng giao thức, đây là một ví dụ hướng dẫn hữu ích về lý do tại sao con đường này có thể được xem xét.
Gói ERC-4337
Một số lý do chính đã được thảo luận để cuối cùng đưa ERC-4337 trở lại giao thức:
Hiệu quả sử dụng gas: Bất kỳ hoạt động nào được thực hiện bên trong EVM đều phát sinh một số chi phí phụ cho máy ảo, bao gồm tình trạng kém hiệu quả khi sử dụng các tính năng tốn gas như khe lưu trữ. Hiện nay, những thiếu hiệu quả này làm tăng thêm ít nhất 20.000 chi phí gas, thậm chí còn nhiều hơn. Việc đưa những thành phần này vào giao thức là cách dễ nhất để loại bỏ những vấn đề này.
Rủi ro lỗi mã: Nếu "hợp đồng điểm vào" ERC-4337 có lỗi đủ nghiêm trọng, tất cả các ví tương thích với ERC-4337 đều có thể bị rút hết tiền. Việc thay thế hợp đồng bằng tính năng trong giao thức sẽ tạo ra trách nhiệm ngầm định là phải sửa lỗi mã thông qua hard fork, do đó loại bỏ nguy cơ tiền của người dùng bị rút hết.
Hỗ trợ các mã lệnh EVM như txt.origin. Bản thân ERC-4337 khiến txt.origin trả về địa chỉ của "bundler" đóng gói một tập hợp các hoạt động của người dùng thành một giao dịch. Tính năng trừu tượng hóa tài khoản gốc có thể giải quyết vấn đề này bằng cách khiến txt.origin trỏ đến tài khoản thực tế đã gửi giao dịch, khiến nó hoạt động giống như EOA.
Chống kiểm duyệt: Một trong những thách thức của việc tách biệt người đề xuất/người xây dựng là việc kiểm duyệt các giao dịch riêng lẻ trở nên dễ dàng hơn. Trong thế giới mà giao thức Ethereum có thể xác định các giao dịch riêng lẻ, vấn đề này có thể được giảm bớt đáng kể nhờ danh sách bao gồm, cho phép người đề xuất chỉ định danh sách các giao dịch phải được đưa vào hai vị trí tiếp theo trong hầu hết mọi trường hợp. Tuy nhiên, ERC-4337 bên ngoài giao thức đóng gói "hoạt động của người dùng" trong một giao dịch duy nhất, khiến hoạt động của người dùng trở nên mờ đục đối với giao thức Ethereum; do đó, danh sách bao gồm do giao thức Ethereum cung cấp sẽ không thể cung cấp khả năng chống kiểm duyệt cho các hoạt động của người dùng ERC-4337. Việc gói ERC-4337 và biến hành động của người dùng thành một loại giao dịch "phù hợp" sẽ giải quyết được vấn đề này.
Điều đáng nói là ở dạng hiện tại, ERC-4337 đắt hơn đáng kể so với các giao dịch Ethereum “cơ bản”: giao dịch có giá 21.000 gas, trong khi ERC-4337 có giá khoảng 42.000 gas.
Về mặt lý thuyết, có thể điều chỉnh hệ thống chi phí gas EVM cho đến khi chi phí trong giao thức và chi phí truy cập lưu trữ bên ngoài giao thức bằng nhau; không có lý do gì mà việc chuyển ETH phải tốn 9000 gas khi các loại hoạt động chỉnh sửa lưu trữ khác rẻ hơn. Trên thực tế, hai EIP liên quan đến quá trình chuyển đổi cây Verkle sắp tới thực sự cố gắng thực hiện điều này. Nhưng ngay cả khi chúng ta làm điều đó, vẫn có một lý do rõ ràng tại sao, bất kể EVM có hiệu quả đến đâu, chức năng giao thức được gói gọn chắc chắn sẽ rẻ hơn nhiều so với mã EVM: mã được gói gọn không cần phải trả phí để được tải trước.
Ví ERC-4337 có chức năng đầy đủ thường có kích thước lớn, với quá trình biên dịch và đẩy lên chuỗi chiếm khoảng 12.800 byte. Tất nhiên, bạn có thể triển khai mã này một lần và sử dụng DELEGATECALL để cho phép từng ví riêng lẻ gọi mã đó, nhưng mã vẫn cần phải có thể truy cập được trong mọi khối sử dụng mã đó. Theo chi phí gas của cây Verkle EIP, 12.800 byte sẽ được nhóm thành 413 khối và việc truy cập vào các khối này sẽ yêu cầu phải trả gấp đôi chi phí nhánh chứng kiến (tổng cộng là 3.800 gas) và gấp 413 lần chi phí khối chứng kiến (tổng cộng là 82.600 gas). Điều này thậm chí còn chưa đề cập đến điểm vào ERC-4337, trong phiên bản 0.6.0, có 23.689 byte trên chuỗi (khoảng 158.700 gas để tải theo các quy tắc EIP của cây Verkle).
Điều này dẫn đến một vấn đề: chi phí gas để thực sự truy cập mã này phải được khấu hao trong suốt giao dịch theo một cách nào đó. Phương pháp hiện tại được ERC-4337 sử dụng không thực sự hiệu quả: giao dịch đầu tiên trong một gói tiêu tốn chi phí lưu trữ/lấy mã một lần, khiến nó đắt hơn nhiều so với các giao dịch khác. Việc đóng gói giao thức sẽ cho phép các thư viện chia sẻ công khai này trở thành một phần của giao thức, cho phép mọi người truy cập miễn phí.
Chúng ta có thể học được gì từ ví dụ này và khi nào thì nên tóm tắt một cách tổng quát hơn?
Trong ví dụ này, chúng ta đã thấy một số lý do khác nhau để đóng gói các khía cạnh trừu tượng của tài khoản trong giao thức.
Các phương pháp tiếp cận dựa trên thị trường “đẩy sự phức tạp lên mức tối đa” rất có thể sẽ thất bại khi chi phí cố định cao. Trên thực tế, lộ trình trừu tượng hóa tài khoản dài hạn có vẻ như sẽ có rất nhiều chi phí cố định cho mỗi khối. 244, 100 gas để tải mã ví chuẩn hóa là một chuyện; nhưng tổng hợp có thể thêm hàng trăm nghìn gas để xác minh ZK-SNARK, cũng như chi phí xác minh bằng chứng trên chuỗi. Không có cách nào để tính phí người dùng cho những chi phí này mà không gây ra tình trạng thiếu hiệu quả nghiêm trọng trên thị trường, và việc biến một số tính năng này thành các tính năng giao thức mà mọi người đều có thể truy cập miễn phí sẽ giải quyết tốt vấn đề này.
Phản hồi của toàn cộng đồng về lỗi mã. Nếu một đoạn mã nào đó được tất cả người dùng hoặc nhiều người dùng sử dụng, thì cộng đồng blockchain thường sẽ chịu trách nhiệm thực hiện hard fork để sửa mọi lỗi phát sinh. ERC-4337 giới thiệu một lượng lớn mã được chia sẻ trên toàn cầu. Về lâu dài, chắc chắn sẽ hợp lý hơn khi sửa lỗi trong mã thông qua hard fork hơn là khiến người dùng mất một lượng lớn ETH.
Đôi khi, có thể triển khai một hình thức giao thức mạnh hơn bằng cách khai thác trực tiếp chức năng của nó. Ví dụ chính ở đây là các tính năng chống kiểm duyệt trong giao thức như danh sách include: danh sách include trong giao thức có thể cung cấp khả năng chống kiểm duyệt tốt hơn so với các phương pháp ngoài giao thức và để các hoạt động ở cấp độ người dùng thực sự được hưởng lợi từ danh sách include trong giao thức, các hoạt động ở cấp độ người dùng riêng lẻ cần phải "có thể đọc được" theo giao thức. Một ví dụ ít được biết đến khác là thiết kế Ethereum Proof of Stake năm 2017 với tính trừu tượng của tài khoản dành cho khóa đặt cược đã bị loại bỏ để chuyển sang Wrapper BLS vì BLS hỗ trợ cơ chế "tổng hợp" phải được triển khai ở cấp độ giao thức và mạng, có thể giúp xử lý số lượng lớn chữ ký hiệu quả hơn.
Nhưng điều quan trọng cần nhớ là ngay cả việc trừu tượng hóa tài khoản trong giao thức bao bọc vẫn là một sự tách biệt đóng gói lớn so với hiện trạng. Ngày nay, các giao dịch Ethereum cấp cao nhất chỉ có thể được khởi tạo từ các tài khoản do bên ngoài sở hữu (EOA), được xác minh bằng một chữ ký đường cong elip secp 256 k 1 duy nhất. Việc trừu tượng hóa tài khoản sẽ loại bỏ điều này và để người dùng tự xác định các điều kiện xác thực. Do đó, trong câu chuyện về trừu tượng hóa tài khoản này, chúng ta cũng thấy lý do lớn nhất chống lại việc đóng gói: tính linh hoạt trong việc đáp ứng nhu cầu của những người dùng khác nhau.
Chúng ta hãy làm rõ hơn câu chuyện này bằng cách xem xét một số ví dụ khác về các tính năng đã được xem xét để đóng gói gần đây. Chúng tôi sẽ tập trung cụ thể vào: ZK-EVM, tách biệt người đề xuất và người xây dựng, nhóm bộ nhớ riêng, đặt cược thanh khoản và biên dịch trước mới.
Gói ZK-EVM
Chúng ta hãy chuyển sự chú ý sang một mục tiêu đóng gói tiềm năng khác cho giao thức Ethereum: ZK-EVM. Hiện tại, chúng tôi có một số lượng lớn ZK-rollup, tất cả đều phải viết mã khá giống nhau để xác minh việc thực thi các khối Ethereum tương tự trong ZK-SNARK. Có một hệ sinh thái khá đa dạng các triển khai độc lập: PSE ZK-EVM, Kakarot, Polygon ZK-EVM, Linea, Zeth và nhiều hơn nữa.
Một cuộc tranh cãi gần đây trong không gian EVM ZK-rollup liên quan đến cách xử lý các lỗi có thể xảy ra trong mã ZK. Hiện tại, tất cả các hệ thống đang chạy này đều có một số dạng cơ chế “hội đồng bảo mật” kiểm soát hệ thống kiểm tra trong trường hợp có lỗi. Năm ngoái, tôi đã tìm cách tạo ra một khuôn khổ chuẩn hóa để khuyến khích các dự án làm rõ mức độ tin tưởng mà họ đặt vào các hệ thống chứng nhận và Hội đồng Bảo an, đồng thời giảm dần quyền lực đối với tổ chức đó theo thời gian.
Trong trung hạn, việc hợp nhất có thể dựa vào nhiều hệ thống chứng nhận, trong đó Hội đồng Bảo an chỉ có thẩm quyền trong trường hợp cực đoan xảy ra bất đồng giữa hai hệ thống chứng nhận khác nhau.
Tuy nhiên, có cảm giác rằng một số công việc này có vẻ thừa thãi. Chúng tôi đã có lớp cơ sở Ethereum, có EVM và chúng tôi đã có cơ chế hoạt động để xử lý lỗi trong quá trình triển khai: nếu có lỗi, máy khách sẽ được cập nhật để sửa lỗi và chuỗi sẽ tiếp tục hoạt động. Theo góc nhìn của khách hàng có lỗi, các khối dường như đã hoàn tất sẽ không còn được xác nhận nữa, nhưng ít nhất chúng ta sẽ không thấy người dùng mất tiền. Tương tự như vậy, nếu rollup chỉ muốn duy trì vai trò tương đương với EVM, thì chúng cần triển khai cơ chế quản trị riêng để liên tục thay đổi các quy tắc ZK-EVM nội bộ để phù hợp với các bản nâng cấp lên lớp cơ sở Ethereum, điều này nghe có vẻ không đúng vì về cơ bản, chúng được xây dựng dựa trên chính lớp cơ sở Ethereum, lớp này biết khi nào cần nâng cấp và theo những quy tắc mới nào.
Vì các ZK-EVM L2 này về cơ bản sử dụng chính xác cùng một EVM như Ethereum, liệu chúng ta có thể kết hợp "xác minh việc thực thi EVM trong ZK" vào chức năng giao thức và xử lý các bất thường như lỗi và nâng cấp bằng cách áp dụng sự đồng thuận xã hội của Ethereum, giống như chúng ta đã làm đối với chính việc thực thi EVM ở lớp cơ sở không?
Đây là một chủ đề quan trọng và đầy thách thức.
Một chủ đề có thể gây tranh cãi liên quan đến tính khả dụng của dữ liệu trong ZK-EVM gốc là trạng thái. Nếu ZK-EVM không cần phải mang theo dữ liệu “nhân chứng”, chúng sẽ hiệu quả hơn nhiều về dữ liệu. Nghĩa là, nếu một phần dữ liệu cụ thể đã được đọc hoặc ghi trong khối trước đó, chúng ta có thể cho rằng trình chứng minh có quyền truy cập vào phần dữ liệu đó và không cần phải cung cấp lại nữa. Điều này không chỉ đơn thuần là không tải lại bộ nhớ và mã; mà nếu một bản tổng hợp nén dữ liệu đúng cách, nén có trạng thái có thể tiết kiệm dữ liệu gấp 3 lần so với nén không trạng thái.
Điều này có nghĩa là đối với bản biên dịch trước ZK-EVM, chúng ta có hai lựa chọn:
1. Tiền biên dịch yêu cầu tất cả dữ liệu phải có sẵn trong cùng một khối. Điều này có nghĩa là trình chứng minh có thể không có trạng thái, nhưng cũng có nghĩa là sử dụng ZK-rollup được biên dịch trước như vậy sẽ tốn kém hơn nhiều so với việc sử dụng mã tùy chỉnh.
2. Biên dịch trước cho phép con trỏ trỏ tới dữ liệu được sử dụng hoặc tạo ra bởi lần thực thi trước đó. Điều này làm cho ZK-rollup gần đạt đến mức tối ưu, nhưng phức tạp hơn và đưa ra trạng thái mới phải được trình chứng minh lưu trữ.
Chúng ta có thể học được gì từ điều này? Có một lý do chính đáng để gói gọn xác minh ZK-EVM theo một cách nào đó: các rollup đã xây dựng các phiên bản tùy chỉnh của riêng họ và có vẻ không đúng khi Ethereum sẵn sàng đặt sức nặng của nhiều triển khai và sự đồng thuận xã hội ngoài chuỗi vào việc thực hiện L1 của EVM, nhưng một L2 thực hiện chính xác công việc tương tự sẽ phải triển khai các tiện ích phức tạp liên quan đến Hội đồng bảo mật. Nhưng mặt khác, có một chi tiết quan trọng: có nhiều phiên bản ZK-EVM khác nhau và chúng có chi phí và lợi ích khác nhau. Sự phân biệt có trạng thái/không có trạng thái chỉ là bề nổi; những nỗ lực hỗ trợ “gần như EVM” khi mã tùy chỉnh đã được chứng minh là phù hợp với các hệ thống khác có thể mở ra không gian thiết kế lớn hơn nhiều. Do đó, việc đóng gói ZK-EVM mang lại cả triển vọng và thách thức.
Tách biệt người đề xuất và người xây dựng gói (ePBS)
Sự phát triển của MEV đã biến hoạt động sản xuất khối thành một hoạt động kinh tế quy mô lớn, với các tác nhân tinh vi có thể tạo ra các khối tạo ra nhiều doanh thu hơn so với thuật toán mặc định, vốn chỉ quan sát nhóm bộ nhớ giao dịch và bao gồm chúng. Cho đến nay, cộng đồng Ethereum đã cố gắng giải quyết vấn đề này bằng cách sử dụng các chương trình tách biệt người đề xuất-người xây dựng ngoài giao thức như MEV-Boost, cho phép những người xác thực thông thường (“người đề xuất”) thuê ngoài việc xây dựng khối cho những người tham gia chuyên biệt (“người xây dựng”).
Tuy nhiên, MEV-Boost đưa ra giả định về độ tin cậy đối với một nhóm người tham gia mới, được gọi là rơle. Trong hai năm qua, đã có nhiều đề xuất tạo ra một "PBS đóng gói". Lợi ích của việc làm này là gì? Trong trường hợp này, câu trả lời rất đơn giản: PBS được xây dựng bằng cách sử dụng trực tiếp các hàm giao thức sẽ mạnh hơn (theo nghĩa có giả định tin cậy yếu hơn) so với PBS được xây dựng mà không sử dụng chúng. Điều này tương tự như trường hợp của các oracle về giá trong các giao thức wrapper — mặc dù trong trường hợp này cũng có những phản đối mạnh mẽ.
Đóng gói nhóm bộ nhớ riêng
Khi người dùng gửi giao dịch, giao dịch đó sẽ ngay lập tức được công khai và mọi người đều có thể nhìn thấy, ngay cả trước khi giao dịch được đưa vào chuỗi. Điều này khiến người dùng nhiều ứng dụng dễ bị tấn công kinh tế, chẳng hạn như tấn công chạy trước.
Gần đây, có một số dự án dành riêng cho việc tạo ra "nhóm bộ nhớ riêng" (hoặc "nhóm bộ nhớ được mã hóa"), mã hóa các giao dịch của người dùng cho đến khi chúng được chấp nhận không thể đảo ngược vào một khối.
Tuy nhiên, vấn đề là một chương trình như vậy đòi hỏi một loại mã hóa đặc biệt: để ngăn người dùng làm tràn ngập hệ thống và giải mã trước, mã hóa phải được giải mã tự động sau khi giao dịch thực sự được chấp nhận và không thể đảo ngược.
Để đạt được hình thức mã hóa này, có nhiều kỹ thuật khác nhau với những sự đánh đổi khác nhau. Jon Charbonneau đã mô tả rất hay:
Mã hóa cho các nhà điều hành tập trung, chẳng hạn như Flashbots Protect.
Mã hóa khóa thời gian, là một dạng mã hóa có thể được giải mã bởi bất kỳ ai sau một chuỗi các bước tính toán nhất định và không thể song song hóa;
Mã hóa ngưỡng, tin tưởng vào một ủy ban đa số trung thực để giải mã dữ liệu. Xem khái niệm Chuỗi đèn hiệu đóng để biết các gợi ý cụ thể.
Phần cứng đáng tin cậy, chẳng hạn như SGX.
Thật không may, mỗi phương pháp mã hóa đều có điểm yếu khác nhau. Mặc dù mọi giải pháp đều có một nhóm người dùng sẵn sàng tin tưởng, nhưng không có giải pháp nào đủ tin cậy để thực sự được Lớp 1 chấp nhận. Do đó, ít nhất là cho đến khi mã hóa độ trễ được hoàn thiện hoặc có một bước đột phá công nghệ nào đó xảy ra, việc đóng gói chức năng chống chạy trước ở Lớp 1 có vẻ là một đề xuất khó khăn, ngay cả khi đây là một tính năng đủ giá trị khiến nhiều giải pháp ứng dụng đã xuất hiện.
Staking thanh khoản được đóng gói
Một nhu cầu chung của người dùng Ethereum DeFi là khả năng sử dụng ETH của họ để staking cũng như làm tài sản thế chấp trong các ứng dụng khác. Một yêu cầu phổ biến khác chỉ đơn giản là vì sự tiện lợi: người dùng muốn có thể đặt cược mà không cần phải trải qua sự phức tạp khi phải chạy một nút và luôn giữ nút đó trực tuyến (và bảo vệ khóa đặt cược trực tuyến).
Cho đến nay, “giao diện” staking đơn giản nhất đáp ứng được cả hai nhu cầu chỉ là một token ERC 20: chuyển đổi ETH của bạn thành “ETH đã staking”, nắm giữ và sau đó chuyển đổi lại. Trên thực tế, các nhà cung cấp dịch vụ đặt cược thanh khoản như Lido và Rocket Pool đã bắt đầu thực hiện việc này. Tuy nhiên, có một số cơ chế tập trung tự nhiên khi thực hiện staking thanh khoản: mọi người thường đổ xô vào staking phiên bản ETH lớn nhất vì đây là loại staking quen thuộc và thanh khoản nhất.
Mỗi phiên bản staking ETH đều yêu cầu một số cơ chế để xác định ai có thể trở thành người vận hành nút cơ bản. Không thể không giới hạn vì khi đó kẻ tấn công có thể tham gia và khuếch đại cuộc tấn công bằng tiền của người dùng. Hiện tại, hai nền tảng đứng đầu là Lido, có các nhà điều hành nút được DAO đưa vào danh sách trắng, và Rocket Pool, cho phép bất kỳ ai cũng có thể chạy một nút với khoản tiền gửi là 8 ETH. Hai cách tiếp cận này có những rủi ro khác nhau: cách tiếp cận của Rocket Pool cho phép kẻ tấn công thực hiện cuộc tấn công 51% vào mạng lưới và buộc người dùng phải trả phần lớn chi phí; còn đối với cách tiếp cận của DAO, nếu một token được đặt cược nhất định trở nên chiếm ưu thế, điều này sẽ dẫn đến việc một tiện ích quản trị duy nhất có khả năng bị tấn công kiểm soát phần lớn tất cả các trình xác thực Ethereum. Chắc chắn, các giao thức như Lido đã triển khai các biện pháp phòng ngừa, nhưng một lớp phòng thủ có thể là không đủ.
Trong ngắn hạn, một giải pháp là khuyến khích những người tham gia hệ sinh thái sử dụng nhiều nhà cung cấp dịch vụ đặt cược thanh khoản khác nhau để giảm khả năng xảy ra rủi ro hệ thống do một nhà cung cấp thống trị duy nhất gây ra. Tuy nhiên, về lâu dài đây là sự cân bằng không ổn định và việc quá phụ thuộc vào áp lực đạo đức để giải quyết vấn đề là rất nguy hiểm. Một câu hỏi tự nhiên nảy sinh: liệu có hợp lý khi đóng gói một số loại chức năng trong giao thức để làm cho việc đặt cược thanh khoản ít tập trung hơn không?
Câu hỏi chính ở đây là: chức năng trong giao thức là gì? Vấn đề với việc chỉ đơn giản tạo ra một token “ETH được đặt cược” có thể thay thế trong giao thức là nó phải có một lớp bao bọc xung quanh quyền quản trị trên toàn Ethereum để chọn người điều hành các nút hoặc phải mở, điều này sẽ biến nó thành công cụ cho những kẻ tấn công.
Một ý tưởng thú vị là bài viết của Dankrad Feist về việc tối đa hóa việc đặt cược thanh khoản. Trước tiên, chúng ta hãy nghiến răng và nhận ra rằng nếu Ethereum bị tấn công bởi 51%, thì chỉ có 5% số ETH bị tấn công có thể bị tịch thu. Đây là một sự đánh đổi hợp lý; với hơn 26 triệu ETH hiện đang được đặt cược, chi phí tấn công một phần ba trong số đó (~8 triệu ETH) sẽ là quá cao, đặc biệt là khi xem xét có bao nhiêu cuộc tấn công "ngoài mô hình" có thể được thực hiện với chi phí thấp hơn nhiều. Trên thực tế, những sự đánh đổi tương tự đã được khám phá trong đề xuất của "siêu ủy ban" nhằm thực hiện mục tiêu cuối cùng là một suất duy nhất.
Nếu chúng ta chấp nhận rằng chỉ có 5% ETH bị tấn công bị cắt giảm, thì hơn 90% ETH được đặt cược sẽ không bị ảnh hưởng bởi việc cắt giảm, do đó chúng có thể được sử dụng làm token đặt cược thanh khoản có thể thay thế trong giao thức và sau đó được các ứng dụng khác sử dụng.
Con đường mòn này thật thú vị. Nhưng vẫn còn câu hỏi: chính xác thì cái gì được đóng gói? Rocket Pool hoạt động theo cách rất giống nhau: mỗi nhà điều hành nút cung cấp một số tiền và những người đặt cược thanh khoản cung cấp phần còn lại. Chúng ta có thể chỉ cần điều chỉnh một số hằng số để giới hạn mức phạt cắt giảm tối đa là 2 ETH và rETH hiện tại của Rocket Pool sẽ trở nên không có rủi ro.
Chúng ta cũng có thể làm nhiều điều thông minh khác bằng cách điều chỉnh giao thức đơn giản. Ví dụ, giả sử chúng ta muốn một hệ thống có hai "lớp" staking: người vận hành nút (yêu cầu thế chấp cao) và người gửi tiền (không yêu cầu thế chấp tối thiểu, có thể tham gia và rời đi bất kỳ lúc nào), nhưng chúng ta vẫn muốn ngăn chặn sự tập trung của người vận hành nút bằng cách trao quyền cho một ủy ban người gửi tiền được lấy mẫu ngẫu nhiên, chẳng hạn như đề xuất danh sách các giao dịch phải được đưa vào (vì lý do chống kiểm duyệt), kiểm soát lựa chọn fork trong quá trình rò rỉ không hoạt động hoặc yêu cầu chữ ký trên các khối. Điều này có thể đạt được theo cách chủ yếu là không theo giao thức bằng cách điều chỉnh giao thức để yêu cầu mỗi trình xác thực cung cấp (i) một khóa đặt cược thông thường và (ii) một địa chỉ ETH có thể được gọi giữa mỗi khe để đưa ra khóa đặt cược thứ cấp. Giao thức sẽ cấp quyền cho cả hai khóa, nhưng cơ chế chọn khóa thứ hai trong mỗi khe có thể do giao thức nhóm đặt cược quyết định. Có lẽ vẫn tốt hơn nếu đóng gói trực tiếp một số chức năng, nhưng cần lưu ý rằng có tồn tại loại không gian thiết kế "bao gồm một số thứ và để lại những thứ khác cho người dùng".
Đóng gói nhiều hơn được biên dịch trước
Hợp đồng biên dịch trước (hay "hợp đồng biên dịch trước") là hợp đồng Ethereum triển khai các hoạt động mã hóa phức tạp, trong đó logic được triển khai gốc trong mã máy khách thay vì trong mã hợp đồng thông minh EVM. Tiền mã hóa là một sự thỏa hiệp được áp dụng khi bắt đầu phát triển Ethereum: vì chi phí của máy ảo quá lớn đối với một số mã rất phức tạp và có tính chuyên môn cao, nên chúng ta có thể triển khai một số hoạt động chính có giá trị đối với các ứng dụng quan trọng trong mã gốc để giúp chúng chạy nhanh hơn. Ngày nay, về cơ bản, điều này liên quan đến một số hàm băm chuyên biệt và các phép toán đường cong elip.
Hiện tại đang có một nỗ lực nhằm thêm bản biên dịch trước cho secp 256 r 1, một đường cong elip hơi khác so với secp 256 k 1 được sử dụng cho các tài khoản ethereum cơ bản, vì nó được hỗ trợ tốt bởi các mô-đun phần cứng đáng tin cậy, do đó việc sử dụng rộng rãi có thể cải thiện tính bảo mật của ví. Trong những năm gần đây, cộng đồng cũng đã thúc đẩy việc bổ sung các bản biên dịch trước cho BLS-12-377, BW 6-761, ghép nối tổng quát và các tính năng khác.
Một phản biện cho những lời kêu gọi về nhiều tệp biên dịch trước hơn là nhiều tệp biên dịch trước đã được thêm vào trước đó (như RIPEMD và BLAKE) cuối cùng lại có lượng sử dụng ít hơn nhiều so với dự kiến và chúng ta nên học hỏi từ điều này. Thay vì thêm nhiều biên dịch trước cho các hoạt động cụ thể, có lẽ chúng ta nên tập trung vào một cách tiếp cận khiêm tốn hơn dựa trên các ý tưởng như EVM-MAX và các đề xuất SIMD không hoạt động nhưng luôn có thể tiếp tục, cho phép triển khai EVM thực thi một lớp mã rộng với chi phí thấp hơn. Có lẽ ngay cả các chương trình biên dịch trước ít được sử dụng hiện tại cũng có thể bị loại bỏ và thay thế bằng các triển khai mã EVM (chắc chắn là kém hiệu quả hơn) của cùng các chức năng đó. Tuy nhiên, vẫn có khả năng có những hoạt động mã hóa cụ thể có giá trị đủ để được tăng tốc đến mức có thể thêm chúng dưới dạng biên dịch trước.
Chúng ta đã học được gì từ tất cả những điều này?
Mong muốn đóng gói càng ít càng tốt là điều dễ hiểu và tốt; nó xuất phát từ truyền thống triết lý Unix là tạo ra phần mềm tối giản có thể dễ dàng thích ứng với các nhu cầu khác nhau của người dùng và tránh được tình trạng phần mềm phình to. Tuy nhiên, blockchain không phải là hệ điều hành máy tính cá nhân mà là một hệ thống xã hội. Điều này có nghĩa là việc đóng gói một số chức năng nhất định vào trong một giao thức là có ý nghĩa.
Trong nhiều trường hợp, những ví dụ khác này tương tự như những gì chúng ta đã thấy với việc trừu tượng hóa tài khoản. Nhưng chúng tôi cũng học được một số bài học mới:
Việc đóng gói chức năng có thể giúp tránh rủi ro tập trung ở các khu vực khác của ngăn xếp:
Thông thường, việc duy trì giao thức cơ bản ở mức tối thiểu và đơn giản sẽ đẩy tính phức tạp vào một số hệ sinh thái bên ngoài giao thức. Theo quan điểm triết lý Unix thì điều này là tốt. Tuy nhiên, đôi khi có nguy cơ hệ sinh thái ngoài giao thức sẽ trở nên tập trung, thường (nhưng không chỉ vậy) là do chi phí cố định cao. Đôi khi, việc đóng gói có thể làm giảm sự tập trung thực tế.
Việc đóng gói quá nhiều có thể làm tăng gánh nặng về lòng tin và quản trị của giao thức:
Đây là chủ đề của bài viết trước về “Đừng quá tải sự đồng thuận của Ethereum”: nếu việc đóng gói một chức năng cụ thể làm suy yếu mô hình tin cậy và khiến Ethereum nói chung trở nên “chủ quan” hơn, thì điều này cũng làm suy yếu tính trung lập đáng tin cậy của Ethereum. Trong những trường hợp này, tốt hơn là triển khai chức năng cụ thể như một cơ chế trên Ethereum thay vì cố gắng đưa nó vào chính Ethereum. Mempool được mã hóa là ví dụ tốt nhất ở đây và có thể hơi khó để đóng gói, ít nhất là cho đến khi công nghệ mã hóa chậm được cải thiện.
Việc đóng gói quá nhiều thứ có thể khiến giao thức trở nên quá phức tạp:
Độ phức tạp của giao thức là một rủi ro hệ thống và việc thêm quá nhiều tính năng vào một giao thức sẽ làm tăng rủi ro này. Tiền biên dịch là ví dụ tốt nhất.
Về lâu dài, việc đóng gói chức năng có thể phản tác dụng vì nhu cầu của người dùng là không thể đoán trước:
Một tính năng mà nhiều người cho là quan trọng và được nhiều người dùng sử dụng có thể không được dùng thường xuyên trong thực tế.
Ngoài ra, các trường hợp đặt cược thanh khoản, ZK-EVM và tiền biên dịch cho thấy khả năng có một con đường trung gian: bảo quản khả thi tối thiểu. Các giao thức không cần phải bao gồm toàn bộ chức năng, nhưng có thể chứa các phần cụ thể giải quyết các thách thức chính, giúp chức năng đó dễ triển khai mà không quá hoang tưởng hay quá hẹp. Các ví dụ bao gồm:
Thay vì đóng gói một hệ thống staking thanh khoản hoàn chỉnh, tốt hơn là nên thay đổi các quy tắc phạt staking để khiến việc staking thanh khoản không cần tin cậy trở nên khả thi hơn;
Thay vì gói nhiều trình biên dịch trước hơn, hãy gói EVM-MAX và/hoặc SIMD để tạo ra một lớp hoạt động rộng hơn, dễ triển khai hiệu quả hơn;
Thay vì gói gọn toàn bộ khái niệm về rollup, người ta có thể chỉ gói gọn xác minh EVM.
Chúng ta có thể mở rộng sơ đồ trước như sau:
Đôi khi việc đóng gói một cái gì đó lại có ý nghĩa, ví dụ như việc loại bỏ phần biên dịch trước ít khi sử dụng. Như đã đề cập trước đó, việc trừu tượng hóa toàn bộ tài khoản cũng là một hình thức quan trọng của việc giải mã. Nếu chúng tôi muốn hỗ trợ khả năng tương thích ngược cho người dùng hiện tại, cơ chế này thực sự có thể rất giống với cơ chế giải nén các bản biên dịch trước: một trong những đề xuất là EIP-5003, cho phép EOA chuyển đổi tài khoản của họ thành hợp đồng có chức năng tương tự (hoặc tốt hơn).
Đây là một hành động cân bằng phức tạp khi quyết định tính năng nào sẽ được đưa vào giao thức và tính năng nào sẽ được để lại cho các tầng khác của hệ sinh thái. Hy vọng rằng sự đánh đổi này sẽ tiếp tục được cải thiện theo thời gian khi chúng ta hiểu rõ hơn về nhu cầu của người dùng cũng như các ý tưởng và công nghệ hiện có.
