
Cách tồn tại của ZKVM: Bài viết chi tiết về cuộc tranh luận giữa các phe phái
Tuyển chọn TechFlowTuyển chọn TechFlow

Cách tồn tại của ZKVM: Bài viết chi tiết về cuộc tranh luận giữa các phe phái
Năm 2022 vừa qua, trọng tâm thảo luận về rollup dường như đều tập trung vào ZkEVM, nhưng đừng quên rằng ZkVM cũng là một phương tiện mở rộng khác.
Tác giả: Bryan, IOSG Ventures
Cảm ơn Xin Gao, Boyuan từ p0xeidon, Daniel từ Taiko và Sin7Y đã hỗ trợ và góp ý chỉnh sửa bài viết này!
Mục lục
Triển khai hệ thống chứng minh ZKP – Dựa trên mạch (circuit-based) VS Dựa trên máy ảo (vm-based)
Nguyên tắc thiết kế ZKVM
So sánh các máy ảo dựa trên STARK
Tại sao Risc0 lại đáng kỳ vọng
Mở đầu:
Trong năm 2022 vừa qua, phần lớn các thảo luận về rollup dường như đều tập trung vào ZkEVM, nhưng đừng quên rằng ZkVM cũng là một phương pháp mở rộng khác. Mặc dù ZkEVM không phải trọng tâm của bài viết này, nhưng vẫn đáng để so sánh một vài khía cạnh khác biệt giữa ZkVM và ZkEVM:
1. Tương thích: Mặc dù cả hai đều nhằm mục đích mở rộng quy mô, nhưng trọng tâm lại khác nhau. ZkEVM nhấn mạnh vào việc tương thích trực tiếp với EVM hiện có, trong khi ZkVM hướng đến việc tối ưu hóa hoàn toàn khả năng mở rộng, tức là cải thiện logic và hiệu suất của dapp lên mức tối ưu, còn tính tương thích không phải là ưu tiên hàng đầu. Khi nền tảng cơ sở được xây dựng vững chắc, việc tương thích với EVM cũng có thể đạt được sau đó.
2. Hiệu suất: Cả hai đều gặp phải những điểm nghẽn hiệu suất nhất định. ZkEVM chủ yếu bị ảnh hưởng bởi chi phí dư thừa do phải tương thích với EVM – vốn không được thiết kế để hoạt động hiệu quả trong hệ thống chứng minh ZK. Trong khi đó, điểm nghẽn của ZkVM nằm ở việc giới thiệu bộ lệnh ISA, dẫn đến các ràng buộc đầu ra trở nên phức tạp hơn.
3. Trải nghiệm nhà phát triển: Type II ZkEVM (như Scroll, Taiko) tập trung vào việc tương thích với Bytecode EVM, nói cách khác, mọi mã EVM ở cấp độ bytecode hoặc cao hơn đều có thể tạo bằng chứng kiến thức không thông qua ZkEVM. Đối với ZkVM, có hai hướng đi: một là xây dựng ngôn ngữ DSL riêng (như Cairo), hai là hướng tới tương thích với các ngôn ngữ phổ biến sẵn có như C++/Rust (như Risc0). Trong tương lai, chúng tôi dự đoán rằng các nhà phát triển Solidity gốc trên Ethereum sẽ có thể chuyển đổi sang ZkEVM mà không tốn chi phí, trong khi các ứng dụng mới và mạnh mẽ hơn sẽ chạy trên ZkVM.

Nhiều người hẳn còn nhớ hình ảnh này — bản chất lý do CairoVM đứng ngoài cuộc chiến phái hệ ZkEVM chính là sự khác biệt trong tư duy thiết kế.
Trước khi thảo luận về ZkVM, chúng ta cần suy nghĩ trước tiên về cách triển khai hệ thống chứng minh ZK trong blockchain. Về cơ bản, có hai cách thực hiện mạch – dựa trên mạch (circuit based) và dựa trên máy ảo (vm-based).
Đầu tiên, hệ thống dựa trên mạch chuyển đổi chương trình (program) trực tiếp thành các ràng buộc (constraints) rồi đưa vào hệ thống chứng minh (proving system); trong khi hệ thống dựa trên máy ảo thực thi chương trình thông qua bộ lệnh ISA, đồng thời tạo ra dấu vết thực thi (execution trace). Dấu vết này sau đó được ánh xạ thành các ràng buộc và đưa vào hệ thống chứng minh.
Với hệ thống dựa trên mạch, phép tính của chương trình được ràng buộc bởi từng máy thực thi chương trình. Với hệ thống dựa trên máy ảo, ISA được nhúng vào trình tạo mạch (circuit generator), từ đó sinh ra các ràng buộc cho chương trình. Đồng thời, trình tạo mạch này có các giới hạn về bộ lệnh, chu kỳ hoạt động, bộ nhớ v.v. Máy ảo mang lại tính phổ quát: bất kỳ máy nào cũng có thể chạy một chương trình miễn là điều kiện vận hành của chương trình đó nằm trong các giới hạn nêu trên.
Trong máy ảo, một chương trình ZKP trải qua quy trình như sau:

Nguồn ảnh: Bryan, IOSG Ventures
Ưu và nhược điểm:
- Từ góc nhìn nhà phát triển (developer): Việc phát triển trên hệ thống dựa trên mạch thường đòi hỏi hiểu biết sâu sắc về chi phí của từng ràng buộc. Trong khi đó, với lập trình máy ảo, mạch là tĩnh, nhà phát triển chỉ cần quan tâm nhiều hơn đến các lệnh (instructions).
- Từ góc nhìn bên xác minh (verifier): Giả sử dùng cùng loại SNARK thuần làm backend, hệ thống dựa trên mạch và máy ảo khác nhau rất lớn về tính phổ quát của mạch. Hệ thống mạch tạo ra một mạch khác nhau cho mỗi chương trình, còn máy ảo thì dùng chung một mạch cho mọi chương trình. Điều này nghĩa là trong một rollup, hệ thống mạch cần triển khai nhiều hợp đồng xác minh (verifier contract) trên L1.
- Từ góc nhìn ứng dụng (application): Máy ảo làm logic ứng dụng trở nên phức tạp hơn nhờ tích hợp mô hình bộ nhớ (memory) vào thiết kế, trong khi hệ thống mạch hướng đến mục tiêu nâng cao hiệu suất chương trình.
- Từ góc nhìn độ phức tạp hệ thống (complexity): Máy ảo đưa thêm nhiều yếu tố phức tạp vào hệ thống như mô hình bộ nhớ, giao tiếp giữa host và guest, v.v., trong khi hệ thống mạch đơn giản và gọn nhẹ hơn.
Dưới đây là tổng quan về các dự án hiện tại trên L1/L2 theo hai hướng dựa trên mạch và dựa trên máy ảo:

Nguồn ảnh: Bryan, IOSG Ventures
Nguyên tắc thiết kế máy ảo
Trong máy ảo, có hai nguyên tắc thiết kế then chốt:
Thứ nhất, đảm bảo chương trình được thực thi đúng. Nói cách khác, đầu ra (output) (tức là ràng buộc - constraint) phải khớp chính xác với đầu vào (input) (tức là chương trình - program). Thông thường điều này được thực hiện thông qua bộ lệnh ISA.
Thứ hai, đảm bảo trình biên dịch (compiler) hoạt động chính xác khi chuyển đổi từ ngôn ngữ cấp cao sang định dạng ràng buộc phù hợp.
1. Bộ lệnh ISA
ISA quy định cách thức hoạt động của trình tạo mạch. Nhiệm vụ chính của nó là ánh xạ chính xác các lệnh (instructions) sang các ràng buộc (constraint), sau đó đưa vào hệ thống chứng minh (proving system). Các hệ thống zk hiện nay đều sử dụng RISC (bộ lệnh rút gọn). Có hai lựa chọn ISA:
Lựa chọn thứ nhất là tự xây dựng ISA tùy chỉnh (custom ISA), điều này có thể thấy rõ trong thiết kế của Cairo. Nói chung, có bốn loại logic ràng buộc như sau.

Thiết kế ISA tùy chỉnh tập trung vào việc giảm thiểu số lượng ràng buộc càng nhiều càng tốt, nhằm giúp việc thực thi và xác minh chương trình diễn ra nhanh chóng.
Lựa chọn thứ hai là tận dụng ISA hiện có (existing ISA), như được áp dụng trong thiết kế của Risc0. Ngoài mục tiêu thời gian thực thi ngắn gọn, ISA hiện có (như Risc-V) còn mang lại lợi ích bổ sung như thân thiện với ngôn ngữ phía trước (front-end language) và phần cứng phía sau (backend hardware). Một vấn đề tiềm năng (còn đang chờ giải quyết) là liệu ISA hiện có có bị tụt hậu về thời gian xác minh hay không (vì thời gian xác minh không phải là mục tiêu thiết kế chính của Risc-V).
2. Trình biên dịch (Compiler)
Nói một cách khái quát, trình biên dịch dần dần dịch ngôn ngữ lập trình sang mã máy. Trong môi trường ZK, điều này ám chỉ việc biên dịch các ngôn ngữ cấp cao như C, C++, Rust sang biểu diễn mã cấp thấp cho hệ thống ràng buộc (R1CS, QAP, AIR, v.v.). Có hai phương pháp:
Thiết kế một trình biên dịch dựa trên các biểu diễn mạch zk hiện có (existing circuit representations) – ví dụ, trong ZK, biểu diễn mạch bắt đầu từ các thư viện (library) có thể gọi trực tiếp như Bellman và các ngôn ngữ cấp thấp như Circom. Để tập hợp các biểu diễn khác nhau, các trình biên dịch như Zokrates (đồng thời cũng là một DSL) nhằm cung cấp một lớp trừu tượng có thể biên dịch sang bất kỳ biểu diễn cấp thấp nào.
Xây dựng dựa trên cơ sở hạ tầng trình biên dịch (compiler infrastructure) hiện có. Nguyên lý cơ bản là tận dụng một biểu diễn trung gian (intermediate representation) phục vụ nhiều frontend và backend.
Trình biên dịch của Risc0 dựa trên multi-level intermediate representation (MLIR), có thể sinh ra nhiều IR (tương tự như LLVM). Các IR khác nhau mang lại sự linh hoạt cho nhà phát triển vì mỗi IR có trọng tâm thiết kế riêng, ví dụ một số IR được tối ưu đặc biệt cho phần cứng, cho phép nhà phát triển lựa chọn theo nhu cầu. Ý tưởng tương tự cũng xuất hiện trong vnTinyRAM và TinyRAM sử dụng GCC. ZkSync cũng là một ví dụ khác sử dụng cơ sở hạ tầng trình biên dịch.
Ngoài ra, bạn cũng có thể thấy một số cơ sở hạ tầng trình biên dịch dành riêng cho zk như CirC, cũng mượn một số ý tưởng thiết kế từ LLVM.
Ngoài hai bước thiết kế then chốt trên, còn một vài yếu tố cân nhắc khác:
1. Cân bằng giữa độ an toàn (security) và chi phí xác minh (verifier cost)
Số bit hệ thống sử dụng càng cao (tức là độ an toàn càng lớn), đồng nghĩa chi phí xác minh càng cao. Độ an toàn thể hiện ở bộ sinh khóa (ví dụ trong SNARK là đường cong elliptic).
2. Tính tương thích (compatibility) với frontend và backend
Tính tương thích phụ thuộc vào hiệu lực của biểu diễn trung gian (intermediate representation) cho mạch. IR cần cân bằng giữa tính đúng đắn (đầu ra có khớp với đầu vào + đầu ra có phù hợp với hệ thống chứng minh) và tính linh hoạt (hỗ trợ nhiều frontend và backend). Nếu IR ban đầu được thiết kế để giải quyết các hệ thống ràng buộc bậc thấp như R1CS, thì việc tương thích với các hệ thống ràng buộc bậc cao hơn như AIR sẽ rất khó khăn.
3. Cần thiết kế mạch thủ công (hand-crafted circuits) để nâng cao hiệu quả
Nhược điểm của mô hình dùng chung (general purpose) là kém hiệu quả đối với các thao tác đơn giản không cần lệnh phức tạp.
Tóm tắt một vài lý thuyết trước đây:
Trước giao thức Pinocchio: Đạt được tính toán có thể xác minh, nhưng thời gian xác minh rất chậm.
Giao thức Pinocchio: Đưa ra khả năng thực tiễn về mặt lý thuyết trong tính xác minh và tỷ lệ thành công (tức là thời gian xác minh ngắn hơn thời gian thực thi chương trình), là hệ thống dựa trên mạch.
Giao thức TinyRAM: So với Pinocchio, TinyRAM giống một máy ảo hơn khi giới thiệu ISA, từ đó vượt qua một số giới hạn như truy cập bộ nhớ (RAM), luồng điều khiển (control flow), v.v.
Giao thức vnTinyRAM: Làm cho việc sinh khóa (key generation) không phụ thuộc vào từng chương trình, mang lại tính phổ quát bổ sung. Mở rộng trình tạo mạch để xử lý các chương trình lớn hơn.
Tất cả các mô hình trên đều dùng SNARK làm hệ thống chứng minh backend, tuy nhiên đặc biệt khi xử lý máy ảo, STARK và Plonk dường như là lựa chọn backend phù hợp hơn, về cơ bản là do hệ thống ràng buộc của chúng thích hợp hơn để hiện thực logic kiểu CPU.
Tiếp theo, bài viết sẽ giới thiệu ba máy ảo dựa trên STARK – Risc0, MidenVM, CairoVM. Tóm lại, ngoài việc cùng dùng STARK làm hệ thống chứng minh, chúng có những điểm khác biệt riêng:
Risc0 sử dụng Risc-V để đạt được sự đơn giản trong bộ lệnh. R0 được biên dịch qua MLIR, một biến thể của LLVM-IR, nhằm hỗ trợ nhiều ngôn ngữ lập trình phổ biến hiện có như Rust, C++. Risc-V còn mang lại lợi ích bổ sung như thân thiện với phần cứng.
Miden hướng tới tương thích với Máy ảo Ethereum (EVM), về bản chất là một rollup của EVM. Hiện tại Miden có ngôn ngữ lập trình riêng, nhưng đang hướng tới hỗ trợ Move trong tương lai.
Cairo VM do Starkware phát triển. Hệ thống chứng minh STARK được sử dụng bởi ba hệ thống này do Eli Ben-Sasson phát minh, hiện là chủ tịch của Starkware.
Hãy tìm hiểu sâu hơn về sự khác biệt giữa chúng:

*Cách đọc bảng trên? Một vài chú thích…
● Kích thước từ (Word size): Vì các máy ảo này dựa trên hệ thống ràng buộc AIR, chức năng tương tự kiến trúc CPU. Do đó, lựa chọn kích thước từ CPU (32/64 bit) là hợp lý.
● Truy cập bộ nhớ (Memory access): Risc0 sử dụng thanh ghi (register) chủ yếu vì bộ lệnh Risc-V dựa trên thanh ghi. Miden chủ yếu dùng ngăn xếp (stack) để lưu trữ dữ liệu vì chức năng của AIR tương tự ngăn xếp. CairoVM không dùng thanh ghi đa dụng (general-purpose register) vì chi phí truy cập bộ nhớ chính (main memory) trong mô hình Cairo khá thấp.
● Thực thi chương trình (Program feed): Các phương pháp khác nhau có sự đánh đổi riêng. Ví dụ, phương pháp mast root yêu cầu giải mã khi xử lý lệnh, do đó chi phí cho bên chứng minh tăng cao khi chương trình có nhiều bước thực thi. Phương pháp Bootloading cố gắng cân bằng giữa chi phí bên chứng minh và bên xác minh, đồng thời giữ được tính riêng tư.
● Tính bất định (Non-determinism): Tính bất định là thuộc tính quan trọng của các bài toán NP-complete. Việc tận dụng tính bất định giúp xác minh nhanh các lần thực thi trước đó. Ngược lại, điều này làm tăng thêm các ràng buộc, do đó phải có sự thỏa hiệp trong quá trình xác minh.
● Tăng tốc các thao tác phức tạp (Acceleration on complex operations): Một số phép tính chạy chậm trên CPU. Ví dụ, thao tác bit như XOR và AND, các chương trình băm như ECDSA, kiểm tra phạm vi (range-check)... phần lớn là các phép toán bản địa của blockchain/mật mã nhưng không phải bản địa của CPU (trừ thao tác bit). Việc thực hiện trực tiếp các phép toán này qua DSL dễ khiến vòng chứng minh (cycle) bị cạn kiệt.
● Hoán vị/đa tập hợp (Permutation/multiset): Được sử dụng rộng rãi trong hầu hết các zkVM, với hai mục đích – 1. Giảm chi phí xác minh bằng cách giảm việc lưu trữ đầy đủ dấu vết thực thi (execution trace) 2. Chứng minh rằng bên xác minh biết toàn bộ dấu vết thực thi.
Cuối bài viết, tác giả muốn chia sẻ về tình hình phát triển hiện tại của Risc0 và lý do vì sao nó khiến tôi cảm thấy hào hứng.
Tình hình phát triển hiện tại của R0:
a. Cơ sở hạ tầng trình biên dịch tự phát triển “Zirgen” đang trong quá trình xây dựng. Sẽ rất thú vị nếu so sánh hiệu năng của Zirgen với một số trình biên dịch zk chuyên dụng hiện có.
b. Một số sáng tạo thú vị, như mở rộng trường (field extension), giúp đạt được các tham số bảo mật chắc chắn hơn và thao tác trên các số nguyên lớn hơn.
c. Nhận diện được thách thức trong việc tích hợp giữa các công ty phần cứng ZK và phần mềm ZK, Risc0 sử dụng một lớp trừu tượng phần cứng để phát triển tốt hơn về mặt phần cứng.
d. Vẫn đang trong quá trình phát triển! Còn đang tiến hành!
- Hỗ trợ các mạch được thiết kế thủ công (hand-crafted circuits), hỗ trợ nhiều thuật toán băm. Hiện tại, mạch SHA256 chuyên dụng đã được triển khai, nhưng vẫn chưa đáp ứng hết nhu cầu. Tác giả tin rằng lựa chọn mạch nào để tối ưu phụ thuộc vào các trường hợp sử dụng (use case) mà Risc0 hướng tới. SHA256 là một điểm khởi đầu rất tốt. Mặt khác, định vị của ZKVM mang lại tính linh hoạt, ví dụ, họ có thể hoàn toàn không cần quan tâm đến Keccak nếu họ không muốn :)
- Đệ quy (recursion): Đây là chủ đề lớn, tác giả thiên về việc không đi sâu vào báo cáo này. Cần biết rằng khi Risc0 hướng tới hỗ trợ các trường hợp sử dụng/chương trình phức tạp hơn, nhu cầu về đệ quy ngày càng bức thiết. Để hỗ trợ thêm cho đệ quy, hiện họ đang nghiên cứu một giải pháp tăng tốc GPU ở phía phần cứng.
- Xử lý tính bất định (non-determinism): Đây là thuộc tính mà ZKVM phải xử lý, trong khi máy ảo truyền thống không gặp phải vấn đề này. Tính bất định có thể giúp máy ảo thực thi nhanh hơn. MLIR tương đối giỏi trong việc xử lý các vấn đề của máy ảo truyền thống, và điều đáng mong đợi là Risc0 sẽ tích hợp tính bất định vào thiết kế hệ thống ZKVM như thế nào.
ĐIỀU KHIẾN TÔI HỨNG KHỞI:
a. Đơn giản và có thể xác minh!
Trong các hệ thống phân tán, PoW đòi hỏi mức độ dư thừa cao vì con người không tin tưởng lẫn nhau, do đó cần lặp lại cùng một phép tính để đạt được sự đồng thuận. Nhưng bằng cách tận dụng bằng chứng kiến thức không, việc đạt trạng thái nên dễ dàng như việc đồng ý rằng 1+1=2.
b. Nhiều trường hợp sử dụng thực tế hơn:
Ngoài việc mở rộng quy mô trực tiếp nhất, nhiều trường hợp sử dụng thú vị hơn sẽ trở nên khả thi, ví dụ như học máy kiến thức không, phân tích dữ liệu, v.v. So với các ngôn ngữ ZK chuyên biệt như Cairo, Rust/C++ có chức năng phổ quát và mạnh mẽ hơn, nhiều ứng dụng web2 sẽ chạy trên Risc0 VM.
c. Cộng đồng nhà phát triển bao gồm hơn/bền vững hơn:
Các nhà phát triển quan tâm đến STARK và blockchain không cần phải học lại một DSL mới, mà có thể dùng luôn Rust/C++.
Chào mừng tham gia cộng đồng chính thức TechFlow
Nhóm Telegram:https://t.me/TechFlowDaily
Tài khoản Twitter chính thức:https://x.com/TechFlowPost
Tài khoản Twitter tiếng Anh:https://x.com/BlockFlow_News













