zk-SNARK là một công cụ mã hóa mạnh mẽ đã trở thành một phần ngày càng thiết yếu của cả ứng dụng blockchain và ứng dụng không dựa trên blockchain. Sự phức tạp của chúng thể hiện rõ ở cả việc hiểu cách chúng hoạt động và cách chúng có thể được sử dụng một cách hiệu quả. Bài viết này đi sâu vào cách zk-SNARK thích ứng với các ứng dụng hiện tại, cung cấp các ví dụ về những gì chúng có thể và không thể đạt được, đồng thời đưa ra các hướng dẫn chung về thời điểm zk-SNARK phù hợp cho các ứng dụng cụ thể. Sự nhấn mạnh đặc biệt sẽ là vai trò của họ trong việc đảm bảo quyền riêng tư.
Hãy tưởng tượng có một đầu vào công khai x, một đầu vào riêng w và một hàm (công khai) f(x,w) → {True,False}, xác thực các đầu vào. Với zk-SNARK, người ta có thể chứng minh rằng họ biết aw, sao cho với f và x cho trước, f(x,w) = True, tất cả đều không tiết lộ w thực sự là gì. Hơn nữa, người xác minh có thể xác thực bằng chứng nhanh hơn nhiều so với việc họ tính f(x,w) ngay cả khi họ biết w.
Điều này mang lại cho zk-SNARK hai thuộc tính: quyền riêng tư và khả năng mở rộng. Như đã đề cập, các ví dụ của chúng tôi trong bài viết này sẽ chủ yếu tập trung vào khía cạnh quyền riêng tư.
Giả sử bạn có ví Ethereum và bạn muốn chứng minh rằng ví này đã được đăng ký theo hệ thống bằng chứng nhân loại mà không tiết lộ cá nhân đã đăng ký thực sự là ai. Hàm này có thể được mô tả toán học như sau:
Đầu vào riêng (w): Địa chỉ của bạn A, địa chỉ của bạn khóa riêng k
Đầu vào công khai (x): Tập hợp địa chỉ của tất cả hồ sơ bằng chứng nhân loại đã được xác minh {H1…Hn}
Hàm xác minh f(x,w):
Diễn giải w dưới dạng một cặp (A, σ) và x dưới dạng danh sách cấu hình hợp lệ {H1…Hn}
Xác minh A là một trong các địa chỉ trong {H1…Hn}
Xác nhận privtoaddr(k) = A
Nếu cả hai lần xác minh đều được thông qua, hãy trả về True. Nếu bất kỳ một trong số chúng không thành công, hãy trả về Sai.
Người chứng minh tạo địa chỉ A của họ và khóa liên quan k, cung cấp w=(A,k) làm đầu vào riêng cho f. Họ nhận được đầu vào công khai, là tập hợp các hồ sơ bằng chứng nhân loại đã được xác minh hiện tại {H1…Hn}, từ chuỗi. Sau đó, họ chạy thuật toán chứng minh zk-SNARK, thuật toán này (giả sử dữ liệu đầu vào là chính xác) sẽ tạo ra bằng chứng. Bằng chứng này được gửi đến người xác minh, cùng với chiều cao khối nơi họ tìm nạp danh sách hồ sơ đã được xác minh.
Người xác minh cũng đọc chuỗi, lấy danh sách {H1…Hn} từ độ cao được chỉ định bởi người chứng minh và kiểm tra bằng chứng. Nếu quá trình xác minh thành công, người xác minh tin rằng người chứng minh sở hữu hồ sơ bằng chứng về con người đã được xác minh.
Trước khi đi sâu vào các ví dụ phức tạp hơn, tôi thực sự khuyên bạn nên hiểu đầy đủ về ví dụ trên.
Một nhược điểm của hệ thống chứng minh nói trên là người xác minh cần phải biết toàn bộ bộ hồ sơ {H1…Hn}, yêu cầu thời gian O(n) để “nhập” bộ này vào cơ chế zk-SNARK. Vấn đề này có thể được giải quyết bằng cách sử dụng root Merkle trên chuỗi, bao gồm tất cả các cấu hình, làm đầu vào công khai (có thể chỉ là root trạng thái). Chúng tôi thêm một đầu vào riêng tư khác, bằng chứng Merkle M, xác nhận rằng tài khoản A của người chứng minh nằm ở phần thích hợp của cây.
Một giải pháp thay thế mới đây và hiệu quả hơn cho bằng chứng Merkle cho bằng chứng thành viên ZK là Caulk. Trong tương lai, một số trường hợp sử dụng này có thể chuyển sang các giải pháp tương tự như Caulk.
Các dự án như Zcash và Tornado.cash cho phép chúng tôi sở hữu các loại tiền tệ bảo vệ quyền riêng tư. Bây giờ, người ta có thể nghĩ rằng họ có thể sử dụng “bằng chứng con người ZK” đã đề cập, nhưng đó không phải là việc chứng minh quyền truy cập vào bằng chứng hồ sơ con người; đó là về việc chứng minh quyền truy cập vào tiền xu. Ở đây có một vấn đề: chúng ta phải giải quyết đồng thời cả quyền riêng tư và chi tiêu gấp đôi. Tức là chúng ta không nên tiêu cùng một đồng xu hai lần.
Đây là cách chúng tôi giải quyết: Bất kỳ ai sở hữu một đồng xu đều có một “s” bí mật riêng tư. Họ tính toán một “lá” L=hash(s,1) cục bộ, được xuất bản trên chuỗi, trở thành một phần của trạng thái, N=hash(s,2), mà chúng tôi gọi là bộ vô hiệu hóa. Trạng thái được lưu trữ trong cây Merkle.
Để tiêu xu, người gửi phải tạo ZK-SNARK trong đó:
Đầu vào công khai bao gồm bộ vô hiệu hóa N, gốc Merkle R hiện tại hoặc gần đây và một lá mới L' (dành cho người nhận có bí mật s' được chuyển cho người gửi dưới dạng L'=hash(s',1)).
Đầu vào riêng bao gồm một bí mật s, một lá L và một nhánh Merkle M.
Chức năng xác minh kiểm tra:
M là nhánh Merkle hợp lệ, chứng tỏ L là lá của cây có gốc tại R, trong đó R là gốc Merkle của trạng thái hiện tại.
hàm băm(s,1)=L và hàm băm(s,2)=N.
Giao dịch chứa bộ vô hiệu hóa N và lá mới L'. Thực tế chúng tôi không chứng minh bất cứ điều gì về L' mà được “trộn” vào bằng chứng để ngăn chặn sự sửa đổi của bên thứ ba trong quá trình giao dịch. Để xác thực giao dịch, chuỗi sẽ xác minh ZK-SNARK và kiểm tra xem N đã được sử dụng trong các giao dịch trước đó hay chưa. Nếu thành công, N sẽ được thêm vào tập hợp các bộ vô hiệu hóa đã sử dụng, khiến nó không thể sử dụng được nữa. L' được thêm vào cây Merkle.
Bằng cách sử dụng ZK-SNARK, chúng tôi liên kết hai giá trị: L (xuất hiện trên chuỗi khi đồng xu được đúc) và N (xuất hiện khi chi tiêu), mà không tiết lộ L nào kết nối với N nào. Mối liên hệ giữa L và N chỉ rõ ràng khi bạn biết bí mật tạo ra chúng. Mỗi đồng xu được đúc có thể được sử dụng một lần (vì chỉ có một N hợp lệ cho mỗi L), nhưng đồng xu cụ thể được sử dụng bất kỳ lúc nào vẫn được giấu kín.
Đây là một nguyên tắc quan trọng cần nắm bắt. Nhiều cơ chế chúng tôi mô tả dưới đây dựa trên điều này, mặc dù với nhiều mục đích khác nhau.
Những điều trên có thể dễ dàng mở rộng sang các đồng tiền có số dư tùy ý. Chúng tôi duy trì khái niệm về “đồng xu”, nhưng mỗi đồng xu đều có số dư (riêng tư). Một cách đơn giản để đạt được điều này là mỗi đồng xu phải có chuỗi lưu trữ, không chỉ với lá L mà còn với số dư được mã hóa. Mỗi giao dịch sẽ tiêu tốn hai đồng xu và tạo ra hai đồng tiền mới, thêm hai cặp (lá, số dư được mã hóa) vào trạng thái. ZK-SNARK cũng xác minh rằng tổng số dư đầu vào bằng tổng số dư đầu ra và cả hai số dư đầu ra đều không âm.
Một công cụ chống DOS hấp dẫn: Hãy tưởng tượng bạn có một số danh tính trên chuỗi không dễ dàng tạo ra; đó có thể là hồ sơ do con người chứng minh hoặc trình xác thực 32 ETH hoặc chỉ là một tài khoản có số dư ETH khác 0. Chúng tôi có thể tạo ra một mạng ngang hàng chống DOS tốt hơn bằng cách chỉ chấp nhận các tin nhắn chứng minh người gửi có hồ sơ. Mỗi hồ sơ sẽ được phép gửi tối đa 1000 tin nhắn mỗi giờ. Nếu người gửi gian lận, hồ sơ của họ sẽ bị xóa khỏi danh sách. Nhưng làm thế nào để chúng tôi đảm bảo sự riêng tư?
Đầu tiên, thiết lập: đặt k là khóa riêng của người dùng và A=privtoaddr(k) địa chỉ tương ứng. Danh sách các địa chỉ hợp lệ được công khai (ví dụ: sổ đăng ký trên chuỗi). Cho đến nay, điều này phản ánh ví dụ có thể kiểm chứng của con người: bạn phải chứng minh rằng bạn nắm giữ khóa riêng của một địa chỉ mà không tiết lộ địa chỉ nào. Nhưng chúng tôi không chỉ muốn bằng chứng cho thấy bạn có tên trong danh sách. Chúng tôi cần một giao thức cho phép bạn chứng minh mình có tên trong danh sách nhưng hạn chế bằng chứng của bạn.
Chúng ta sẽ chia thời gian thành các khoảng thời gian: mỗi khoảng thời gian kéo dài 3,6 giây (thực hiện 1000 khoảng thời gian mỗi giờ). Mục tiêu của chúng tôi là cho phép mỗi người dùng chỉ gửi một tin nhắn mỗi kỳ; nếu họ gửi hai người cùng lúc, họ sẽ bị bắt. Để cho phép xảy ra các đợt bùng phát không thường xuyên, họ có thể sử dụng các khoảng thời gian gần đây. Vì vậy, nếu người dùng có 500 khoảng thời gian chưa sử dụng, họ có thể gửi tất cả 500 tin nhắn cùng một lúc.
Hãy bắt đầu với phiên bản cơ bản sử dụng bộ vô hiệu hóa. Người dùng tạo bộ vô hiệu hóa với (N = \text{hash}(k, e)) trong đó (k) là khóa của họ và (e) là số kỷ nguyên, sau đó xuất bản nó với thông báo (m). ZK-SNARK sau đó làm xáo trộn (\text{hash}(m)). Không có gì về (m) được xác minh trong quá trình này, do đó buộc bằng chứng vào một thông báo duy nhất. Nếu người dùng liên kết hai bằng chứng với hai thông báo riêng biệt bằng cách sử dụng cùng một bộ vô hiệu hóa, họ có nguy cơ bị phát hiện.
Bây giờ, chúng ta chuyển sang một phiên bản phức tạp hơn. Trong trường hợp này, giao thức tiếp theo sẽ tiết lộ khóa riêng của họ thay vì chỉ xác nhận xem ai đó đã sử dụng cùng một kỷ nguyên hai lần hay chưa. Kỹ thuật then chốt của chúng tôi xoay quanh nguyên tắc “hai điểm xác định một đường”. Để lộ một điểm trên một đường sẽ tiết lộ rất ít, nhưng để lộ hai điểm sẽ tiết lộ toàn bộ đường.
Với mỗi kỷ nguyên (e), chúng ta chọn một dòng (L_e(x) = \text{hash}(k, e) \times x + k). Độ dốc của đường thẳng là (\text{hash}(k, e)) và giao điểm y là (k), cả hai đều không được công chúng biết đến. Để tạo chứng chỉ cho tin nhắn (m), người gửi cung cấp (y = L_e(\text{hash}(m)) = \text{hash}(k, e) \times \text{hash}(m) + k ), cùng với bằng chứng ZK-SNARK cho thấy phép tính (y) là chính xác.
Tóm tắt, ZK-SNARK như sau:
({A_1…A_n}): Danh sách các tài khoản hợp lệ
(M): Thông báo đang được xác thực bởi chứng chỉ
(E): Số kỷ nguyên của chứng chỉ
(Y): Đánh giá chức năng đường
Kiểm tra xem (\text{privtoaddr}(k)) có tồn tại trong ({A_1…A_n})
Xác nhận (y = \text{hash}(k, e) \times \text{hash}(m) + k)
Nhưng nếu ai đó sử dụng một kỷ nguyên hai lần thì sao? Chúng sẽ tiết lộ hai giá trị (m_1) và (m_2) cùng với các giá trị chứng chỉ của chúng (y_1 = \text{hash}(k, e) \times \text{hash}(m_1) + k) và (y_2 = \text{hash}(k, e) \times \text{hash}(m_2) + k). Sau đó, chúng ta có thể sử dụng hai điểm này để khôi phục dòng và sau đó là chặn y, là khóa riêng.
Vì vậy, nếu ai đó sử dụng lại một kỷ nguyên, họ sẽ vô tình tiết lộ khóa riêng của mình cho mọi người. Tùy thuộc vào ngữ cảnh, điều này có thể dẫn đến hành vi trộm tiền hoặc chỉ đơn thuần là phát tán khóa riêng tư và tích hợp nó vào hợp đồng thông minh, dẫn đến việc xóa địa chỉ liên quan.
Một hệ thống chống từ chối dịch vụ ẩn danh ngoài chuỗi khả thi, phù hợp với mạng ngang hàng blockchain, ứng dụng trò chuyện và các hệ thống tương tự, không yêu cầu bằng chứng công việc. Dự án RLN về cơ bản tập trung vào khái niệm này, mặc dù có những thay đổi nhỏ (cụ thể là chúng sử dụng cả bộ vô hiệu hóa và kỹ thuật đường hai điểm, giúp việc phát hiện các trường hợp trong đó một kỷ nguyên được sử dụng lại trở nên đơn giản hơn).
Hãy tưởng tượng việc thành lập 0chan, một diễn đàn trực tuyến như 4chan cung cấp tính năng ẩn danh hoàn toàn (bạn thậm chí không có tên cố định) nhưng có hệ thống danh tiếng để quảng bá nội dung chất lượng cao hơn. Một hệ thống như vậy có thể có DAO quản trị để gắn cờ các bài đăng vi phạm các quy tắc hệ thống, đưa ra cơ chế ba lần tấn công.
Hệ thống danh tiếng có thể phục vụ cho danh tiếng tích cực hoặc tiêu cực; tuy nhiên, việc giải quyết danh tiếng tiêu cực đòi hỏi cơ sở hạ tầng bổ sung. Điều này yêu cầu người dùng kết hợp tất cả dữ liệu danh tiếng vào bằng chứng của họ, ngay cả khi nó tiêu cực. Chúng tôi sẽ chủ yếu tập trung vào trường hợp sử dụng đầy thách thức này, giống như những gì Unirep Social hướng tới thực hiện.
Bất kỳ ai cũng có thể đăng bài bằng cách truyền tin nhắn trên chuỗi có chứa bài đăng, kèm theo ZK-SNARK. ZK-SNARK này đóng vai trò là bằng chứng cho thấy (i) bạn sở hữu một danh tính bên ngoài duy nhất cấp cho bạn quyền tạo tài khoản hoặc (ii) trước đây bạn đã xuất bản các bài đăng cụ thể. Cụ thể, ZK-SNARK hoạt động như sau:
Chất vô hiệu hóa, N
Gốc trạng thái blockchain gần đây nhất, R
Nội dung bài đăng ('trộn' vào bằng chứng để liên kết nó với bài đăng mà không có bất kỳ tính toán nào trên đó)
Khóa riêng của bạn, k
Một danh tính bên ngoài (địa chỉ A) hoặc bộ vô hiệu hóa, Nprev, được sử dụng trong bài viết trước
Bằng chứng Merkle, M, rằng chuỗi chứa A hoặc Nprev
Bài đăng thứ i bạn đã xuất bản bằng tài khoản này
Xác nhận rằng M là nhánh Merkle hợp lệ, chứng minh rằng (A hoặc Nprev, tùy theo điều kiện nào được cung cấp) là một lá của cây có gốc R.
Xác minh N = enc(i, k) trong đó enc là hàm mã hóa (ví dụ: AES).
Nếu i=0, hãy xác minh A=privtoaddr(k), nếu không thì hãy xác minh Nprev=enc(i−1,k).
Bên cạnh việc xác thực bằng chứng, chuỗi cũng kiểm tra (i) rằng R thực sự là một trạng thái gốc gần đây và (ii) rằng bộ vô hiệu hóa N chưa được sử dụng trước đó. Cho đến thời điểm này, nó giống với các đồng tiền bảo vệ quyền riêng tư được mô tả trước đây, nhưng chúng tôi đã thêm quy trình 'đúc' tài khoản mới và loại bỏ khả năng 'gửi' tài khoản của bạn tới các khóa khác nhau. Thay vào đó, tất cả các bộ vô hiệu hóa được tạo bằng khóa gốc. Chúng tôi sử dụng enc ở đây để làm cho bộ vô hiệu hóa có thể đảo ngược. Nếu bạn có khóa k, bạn có thể giải mã bất kỳ bộ vô hiệu hóa cụ thể nào trên chuỗi; nếu kết quả là một chỉ mục hợp lệ chứ không phải là vô nghĩa ngẫu nhiên (ví dụ: chúng ta chỉ có thể kiểm tra dec(N) < 2^64), thì bạn sẽ biết bộ vô hiệu hóa được tạo bằng khóa k.
Trong kế hoạch này, danh tiếng là trực tuyến và rõ ràng. Một số hợp đồng thông minh có một phương thức gọi là addReputation, phương thức này lấy bộ vô hiệu hóa được phát hành cùng với một bài đăng và số lượng đơn vị danh tiếng sẽ được cộng hoặc trừ làm đầu vào.
Chúng tôi đã mở rộng dữ liệu được lưu trữ trên chuỗi cho mỗi bài đăng. Thay vì chỉ lưu trữ bộ vô hiệu hóa N, chúng tôi lưu trữ {N, h¯, u¯} trong đó:
h¯ = hash(h, r) trong đó h đại diện cho chiều cao khối của gốc trạng thái được tham chiếu trong bằng chứng.
u¯ = hash(u, r) trong đó u là điểm danh tiếng của tài khoản (bắt đầu từ 0 đối với tài khoản mới).
R ở đây là một giá trị ngẫu nhiên được thêm vào để ngăn không cho h và u được tìm thấy thông qua tìm kiếm vũ phu. Theo thuật ngữ mật mã, việc thêm R làm cho hàm băm trở thành một cam kết bị che giấu.
Giả sử bài đăng sử dụng root R và lưu trữ {N, h¯, u¯}. Trong bằng chứng của nó, nó liên kết đến bài đăng trước đó đã lưu trữ dữ liệu {Nprev, h¯prev, u¯prev}. Bằng chứng của bài đăng cũng phải duyệt qua tất cả các mục danh tiếng được đăng giữa hprev và h. Đối với mỗi bộ vô hiệu hóa N, hàm xác minh sẽ giải mã N bằng khóa k của người dùng. Nếu quá trình giải mã tạo ra một chỉ mục hợp lệ, nó sẽ áp dụng bản cập nhật danh tiếng. Nếu tổng tất cả các cập nhật danh tiếng bằng δ thì điều đó chứng tỏ u = uprev + δ.
Nếu chúng tôi muốn triển khai quy tắc “ba lần đình công và bạn bị loại”, ZK-SNARK cũng sẽ đảm bảo u > -3. Nếu chúng tôi muốn có quy tắc trong đó một bài đăng có đại diện ≥ 100 nhận được thẻ “bài đăng có uy tín cao” đặc biệt, điều đó cũng có thể được thực hiện.
Để nâng cao khả năng mở rộng của hệ thống này, chúng ta có thể chia nó thành hai loại tin nhắn: Bài đăng và RCA. Một bài đăng sẽ nằm ngoài chuỗi, mặc dù nó yêu cầu phải trỏ đến một RCA được thực hiện trong tuần qua. RCA sẽ được đưa vào chuỗi, vượt qua tất cả các bản cập nhật danh tiếng kể từ RCA trước đó của nhà xuất bản. Bằng cách này, tải trên chuỗi sẽ giảm xuống còn một giao dịch trên mỗi bài đăng mỗi tuần, cộng thêm một giao dịch cho mỗi thông báo danh tiếng.
Đôi khi, cần phải thiết kế một hệ thống với một “người vận hành” tập trung. Lý do cho điều này có thể khác nhau: đôi khi, đó là vì khả năng mở rộng và đôi khi, đó là vì quyền riêng tư, đặc biệt là quyền riêng tư của dữ liệu do nhà điều hành nắm giữ. Ví dụ: hệ thống bỏ phiếu chống cưỡng chế MACI yêu cầu cử tri gửi phiếu bầu của họ trực tuyến, được mã hóa bằng khóa do một nhà điều hành tập trung nắm giữ. Toán tử này giải mã tất cả các phiếu bầu trên chuỗi, kiểm đếm chúng và hiển thị kết quả cuối cùng. Họ sử dụng ZK-SNARK để chứng minh rằng mọi thứ họ làm đều chính xác. Sự phức tạp bổ sung này rất quan trọng để đảm bảo quyền riêng tư mạnh mẽ (được gọi là phản kháng cưỡng chế): người dùng không thể chứng minh cho bất kỳ ai biết họ đã bỏ phiếu như thế nào, ngay cả khi họ muốn. Nhờ blockchain và ZK-SNARK, mức độ tin cậy của chúng tôi đối với nhà điều hành vẫn ở mức tối thiểu. Các nhà khai thác độc hại có thể vi phạm sự phản kháng cưỡng chế, nhưng vì phiếu bầu được đăng trên blockchain nên họ không thể gian lận bằng cách kiểm duyệt phiếu bầu. Và vì họ phải cung cấp ZK-SNARK nên họ không thể gian lận bằng cách tính toán sai kết quả.
Việc sử dụng ZK-SNARK nâng cao hơn là trong các tính toán cần có bằng chứng, với dữ liệu đầu vào được phân phối giữa hai hoặc nhiều bên và chúng tôi không muốn bất kỳ bên nào tìm hiểu về dữ liệu đầu vào của bên khác. Trong kịch bản hai bên, các mạch bị cắt xén có thể đáp ứng các yêu cầu về quyền riêng tư; đối với N bên, có thể sử dụng các giao thức tính toán phức tạp hơn của nhiều bên. ZK-SNARK có thể được tích hợp với các giao thức này để thực hiện các tính toán có thể kiểm chứng được của nhiều bên. Điều này cho phép các hệ thống danh tiếng tiên tiến, cho phép nhiều người tham gia thực hiện các phép tính chung trên đầu vào riêng của họ. Bài toán để đạt được điều này một cách hiệu quả vẫn còn ở giai đoạn đầu.
ZK-SNARK có hiệu quả cao trong việc tạo ra các hệ thống nơi người dùng có trạng thái riêng tư. Tuy nhiên, nó không thể duy trì trạng thái riêng tư mà không ai biết. Để thông tin được chứng minh, người chứng minh phải biết thông tin đó ở dạng bản rõ. Uniswap là một ví dụ khó tư nhân hóa. Trong Uniswap, có một “thực thể” logic trung tâm – tài khoản của nhà cung cấp thanh khoản, không thuộc sở hữu của bất kỳ ai và tất cả các giao dịch Uniswap đều diễn ra với tài khoản này. Bạn không thể ẩn trạng thái của tài khoản này vì ai đó cần giữ trạng thái này ở dạng văn bản gốc để chứng minh và mỗi giao dịch sẽ cần có sự tham gia tích cực của họ. Bạn có thể sử dụng các mạch bị cắt xén của ZK-SNARK để tạo một phiên bản Uniswap tập trung, an toàn, riêng tư, nhưng không rõ liệu lợi ích có lớn hơn chi phí hay không. Nó thậm chí có thể không mang lại bất kỳ lợi ích thực sự nào: hợp đồng cần thông báo cho người dùng về giá tài sản và sự thay đổi giá trên mỗi khối có thể tiết lộ hoạt động giao dịch. Blockchain có thể toàn cầu hóa thông tin trạng thái và ZK-SNARK có thể tư nhân hóa thông tin đó, nhưng không có phương pháp vững chắc nào để toàn cầu hóa và tư nhân hóa thông tin trạng thái đồng thời.
Trong các phần trên, chúng ta đã thấy các ví dụ về các công cụ mạnh mẽ nhưng cũng có thể đóng vai trò là nền tảng cho các ứng dụng khác. Nullifiers, quan trọng đối với tiền tệ, hiện xuất hiện trở lại trong các trường hợp sử dụng khác. Kỹ thuật “liên kết cưỡng chế” được sử dụng trong phần danh tiếng tiêu cực có ứng dụng rộng rãi. Tính năng này có hiệu quả cao đối với nhiều ứng dụng trong đó “hồ sơ” của người dùng thay đổi theo thời gian theo những cách phức tạp và bạn muốn buộc người dùng tuân theo các quy tắc hệ thống trong khi vẫn đảm bảo quyền riêng tư. Người dùng thậm chí có thể được giao nhiệm vụ thể hiện “trạng thái” nội bộ của họ bằng cách sử dụng cây Merkle riêng tư hoàn toàn. Công cụ “nhóm cam kết” được đề cập có thể được xây dựng bằng ZK-SNARK. Nếu một số ứng dụng nhất định không thể hoạt động hoàn toàn trên chuỗi và yêu cầu người vận hành tập trung thì các kỹ thuật tương tự có thể giúp người vận hành trung thực. ZK-SNARK là một công cụ mạnh mẽ, kết hợp giữa lợi ích về trách nhiệm giải trình và quyền riêng tư. Mặc dù chúng có những hạn chế nhưng trong một số trường hợp, các thiết kế ứng dụng thông minh có thể vượt qua những hạn chế này. Tôi hy vọng sẽ thấy nhiều ứng dụng hơn áp dụng ZK-SNARK và cuối cùng xây dựng các ứng dụng kết hợp ZK-SNARK với các hình thức mã hóa khác trong những năm tới.
zk-SNARK là một công cụ mã hóa mạnh mẽ đã trở thành một phần ngày càng thiết yếu của cả ứng dụng blockchain và ứng dụng không dựa trên blockchain. Sự phức tạp của chúng thể hiện rõ ở cả việc hiểu cách chúng hoạt động và cách chúng có thể được sử dụng một cách hiệu quả. Bài viết này đi sâu vào cách zk-SNARK thích ứng với các ứng dụng hiện tại, cung cấp các ví dụ về những gì chúng có thể và không thể đạt được, đồng thời đưa ra các hướng dẫn chung về thời điểm zk-SNARK phù hợp cho các ứng dụng cụ thể. Sự nhấn mạnh đặc biệt sẽ là vai trò của họ trong việc đảm bảo quyền riêng tư.
Hãy tưởng tượng có một đầu vào công khai x, một đầu vào riêng w và một hàm (công khai) f(x,w) → {True,False}, xác thực các đầu vào. Với zk-SNARK, người ta có thể chứng minh rằng họ biết aw, sao cho với f và x cho trước, f(x,w) = True, tất cả đều không tiết lộ w thực sự là gì. Hơn nữa, người xác minh có thể xác thực bằng chứng nhanh hơn nhiều so với việc họ tính f(x,w) ngay cả khi họ biết w.
Điều này mang lại cho zk-SNARK hai thuộc tính: quyền riêng tư và khả năng mở rộng. Như đã đề cập, các ví dụ của chúng tôi trong bài viết này sẽ chủ yếu tập trung vào khía cạnh quyền riêng tư.
Giả sử bạn có ví Ethereum và bạn muốn chứng minh rằng ví này đã được đăng ký theo hệ thống bằng chứng nhân loại mà không tiết lộ cá nhân đã đăng ký thực sự là ai. Hàm này có thể được mô tả toán học như sau:
Đầu vào riêng (w): Địa chỉ của bạn A, địa chỉ của bạn khóa riêng k
Đầu vào công khai (x): Tập hợp địa chỉ của tất cả hồ sơ bằng chứng nhân loại đã được xác minh {H1…Hn}
Hàm xác minh f(x,w):
Diễn giải w dưới dạng một cặp (A, σ) và x dưới dạng danh sách cấu hình hợp lệ {H1…Hn}
Xác minh A là một trong các địa chỉ trong {H1…Hn}
Xác nhận privtoaddr(k) = A
Nếu cả hai lần xác minh đều được thông qua, hãy trả về True. Nếu bất kỳ một trong số chúng không thành công, hãy trả về Sai.
Người chứng minh tạo địa chỉ A của họ và khóa liên quan k, cung cấp w=(A,k) làm đầu vào riêng cho f. Họ nhận được đầu vào công khai, là tập hợp các hồ sơ bằng chứng nhân loại đã được xác minh hiện tại {H1…Hn}, từ chuỗi. Sau đó, họ chạy thuật toán chứng minh zk-SNARK, thuật toán này (giả sử dữ liệu đầu vào là chính xác) sẽ tạo ra bằng chứng. Bằng chứng này được gửi đến người xác minh, cùng với chiều cao khối nơi họ tìm nạp danh sách hồ sơ đã được xác minh.
Người xác minh cũng đọc chuỗi, lấy danh sách {H1…Hn} từ độ cao được chỉ định bởi người chứng minh và kiểm tra bằng chứng. Nếu quá trình xác minh thành công, người xác minh tin rằng người chứng minh sở hữu hồ sơ bằng chứng về con người đã được xác minh.
Trước khi đi sâu vào các ví dụ phức tạp hơn, tôi thực sự khuyên bạn nên hiểu đầy đủ về ví dụ trên.
Một nhược điểm của hệ thống chứng minh nói trên là người xác minh cần phải biết toàn bộ bộ hồ sơ {H1…Hn}, yêu cầu thời gian O(n) để “nhập” bộ này vào cơ chế zk-SNARK. Vấn đề này có thể được giải quyết bằng cách sử dụng root Merkle trên chuỗi, bao gồm tất cả các cấu hình, làm đầu vào công khai (có thể chỉ là root trạng thái). Chúng tôi thêm một đầu vào riêng tư khác, bằng chứng Merkle M, xác nhận rằng tài khoản A của người chứng minh nằm ở phần thích hợp của cây.
Một giải pháp thay thế mới đây và hiệu quả hơn cho bằng chứng Merkle cho bằng chứng thành viên ZK là Caulk. Trong tương lai, một số trường hợp sử dụng này có thể chuyển sang các giải pháp tương tự như Caulk.
Các dự án như Zcash và Tornado.cash cho phép chúng tôi sở hữu các loại tiền tệ bảo vệ quyền riêng tư. Bây giờ, người ta có thể nghĩ rằng họ có thể sử dụng “bằng chứng con người ZK” đã đề cập, nhưng đó không phải là việc chứng minh quyền truy cập vào bằng chứng hồ sơ con người; đó là về việc chứng minh quyền truy cập vào tiền xu. Ở đây có một vấn đề: chúng ta phải giải quyết đồng thời cả quyền riêng tư và chi tiêu gấp đôi. Tức là chúng ta không nên tiêu cùng một đồng xu hai lần.
Đây là cách chúng tôi giải quyết: Bất kỳ ai sở hữu một đồng xu đều có một “s” bí mật riêng tư. Họ tính toán một “lá” L=hash(s,1) cục bộ, được xuất bản trên chuỗi, trở thành một phần của trạng thái, N=hash(s,2), mà chúng tôi gọi là bộ vô hiệu hóa. Trạng thái được lưu trữ trong cây Merkle.
Để tiêu xu, người gửi phải tạo ZK-SNARK trong đó:
Đầu vào công khai bao gồm bộ vô hiệu hóa N, gốc Merkle R hiện tại hoặc gần đây và một lá mới L' (dành cho người nhận có bí mật s' được chuyển cho người gửi dưới dạng L'=hash(s',1)).
Đầu vào riêng bao gồm một bí mật s, một lá L và một nhánh Merkle M.
Chức năng xác minh kiểm tra:
M là nhánh Merkle hợp lệ, chứng tỏ L là lá của cây có gốc tại R, trong đó R là gốc Merkle của trạng thái hiện tại.
hàm băm(s,1)=L và hàm băm(s,2)=N.
Giao dịch chứa bộ vô hiệu hóa N và lá mới L'. Thực tế chúng tôi không chứng minh bất cứ điều gì về L' mà được “trộn” vào bằng chứng để ngăn chặn sự sửa đổi của bên thứ ba trong quá trình giao dịch. Để xác thực giao dịch, chuỗi sẽ xác minh ZK-SNARK và kiểm tra xem N đã được sử dụng trong các giao dịch trước đó hay chưa. Nếu thành công, N sẽ được thêm vào tập hợp các bộ vô hiệu hóa đã sử dụng, khiến nó không thể sử dụng được nữa. L' được thêm vào cây Merkle.
Bằng cách sử dụng ZK-SNARK, chúng tôi liên kết hai giá trị: L (xuất hiện trên chuỗi khi đồng xu được đúc) và N (xuất hiện khi chi tiêu), mà không tiết lộ L nào kết nối với N nào. Mối liên hệ giữa L và N chỉ rõ ràng khi bạn biết bí mật tạo ra chúng. Mỗi đồng xu được đúc có thể được sử dụng một lần (vì chỉ có một N hợp lệ cho mỗi L), nhưng đồng xu cụ thể được sử dụng bất kỳ lúc nào vẫn được giấu kín.
Đây là một nguyên tắc quan trọng cần nắm bắt. Nhiều cơ chế chúng tôi mô tả dưới đây dựa trên điều này, mặc dù với nhiều mục đích khác nhau.
Những điều trên có thể dễ dàng mở rộng sang các đồng tiền có số dư tùy ý. Chúng tôi duy trì khái niệm về “đồng xu”, nhưng mỗi đồng xu đều có số dư (riêng tư). Một cách đơn giản để đạt được điều này là mỗi đồng xu phải có chuỗi lưu trữ, không chỉ với lá L mà còn với số dư được mã hóa. Mỗi giao dịch sẽ tiêu tốn hai đồng xu và tạo ra hai đồng tiền mới, thêm hai cặp (lá, số dư được mã hóa) vào trạng thái. ZK-SNARK cũng xác minh rằng tổng số dư đầu vào bằng tổng số dư đầu ra và cả hai số dư đầu ra đều không âm.
Một công cụ chống DOS hấp dẫn: Hãy tưởng tượng bạn có một số danh tính trên chuỗi không dễ dàng tạo ra; đó có thể là hồ sơ do con người chứng minh hoặc trình xác thực 32 ETH hoặc chỉ là một tài khoản có số dư ETH khác 0. Chúng tôi có thể tạo ra một mạng ngang hàng chống DOS tốt hơn bằng cách chỉ chấp nhận các tin nhắn chứng minh người gửi có hồ sơ. Mỗi hồ sơ sẽ được phép gửi tối đa 1000 tin nhắn mỗi giờ. Nếu người gửi gian lận, hồ sơ của họ sẽ bị xóa khỏi danh sách. Nhưng làm thế nào để chúng tôi đảm bảo sự riêng tư?
Đầu tiên, thiết lập: đặt k là khóa riêng của người dùng và A=privtoaddr(k) địa chỉ tương ứng. Danh sách các địa chỉ hợp lệ được công khai (ví dụ: sổ đăng ký trên chuỗi). Cho đến nay, điều này phản ánh ví dụ có thể kiểm chứng của con người: bạn phải chứng minh rằng bạn nắm giữ khóa riêng của một địa chỉ mà không tiết lộ địa chỉ nào. Nhưng chúng tôi không chỉ muốn bằng chứng cho thấy bạn có tên trong danh sách. Chúng tôi cần một giao thức cho phép bạn chứng minh mình có tên trong danh sách nhưng hạn chế bằng chứng của bạn.
Chúng ta sẽ chia thời gian thành các khoảng thời gian: mỗi khoảng thời gian kéo dài 3,6 giây (thực hiện 1000 khoảng thời gian mỗi giờ). Mục tiêu của chúng tôi là cho phép mỗi người dùng chỉ gửi một tin nhắn mỗi kỳ; nếu họ gửi hai người cùng lúc, họ sẽ bị bắt. Để cho phép xảy ra các đợt bùng phát không thường xuyên, họ có thể sử dụng các khoảng thời gian gần đây. Vì vậy, nếu người dùng có 500 khoảng thời gian chưa sử dụng, họ có thể gửi tất cả 500 tin nhắn cùng một lúc.
Hãy bắt đầu với phiên bản cơ bản sử dụng bộ vô hiệu hóa. Người dùng tạo bộ vô hiệu hóa với (N = \text{hash}(k, e)) trong đó (k) là khóa của họ và (e) là số kỷ nguyên, sau đó xuất bản nó với thông báo (m). ZK-SNARK sau đó làm xáo trộn (\text{hash}(m)). Không có gì về (m) được xác minh trong quá trình này, do đó buộc bằng chứng vào một thông báo duy nhất. Nếu người dùng liên kết hai bằng chứng với hai thông báo riêng biệt bằng cách sử dụng cùng một bộ vô hiệu hóa, họ có nguy cơ bị phát hiện.
Bây giờ, chúng ta chuyển sang một phiên bản phức tạp hơn. Trong trường hợp này, giao thức tiếp theo sẽ tiết lộ khóa riêng của họ thay vì chỉ xác nhận xem ai đó đã sử dụng cùng một kỷ nguyên hai lần hay chưa. Kỹ thuật then chốt của chúng tôi xoay quanh nguyên tắc “hai điểm xác định một đường”. Để lộ một điểm trên một đường sẽ tiết lộ rất ít, nhưng để lộ hai điểm sẽ tiết lộ toàn bộ đường.
Với mỗi kỷ nguyên (e), chúng ta chọn một dòng (L_e(x) = \text{hash}(k, e) \times x + k). Độ dốc của đường thẳng là (\text{hash}(k, e)) và giao điểm y là (k), cả hai đều không được công chúng biết đến. Để tạo chứng chỉ cho tin nhắn (m), người gửi cung cấp (y = L_e(\text{hash}(m)) = \text{hash}(k, e) \times \text{hash}(m) + k ), cùng với bằng chứng ZK-SNARK cho thấy phép tính (y) là chính xác.
Tóm tắt, ZK-SNARK như sau:
({A_1…A_n}): Danh sách các tài khoản hợp lệ
(M): Thông báo đang được xác thực bởi chứng chỉ
(E): Số kỷ nguyên của chứng chỉ
(Y): Đánh giá chức năng đường
Kiểm tra xem (\text{privtoaddr}(k)) có tồn tại trong ({A_1…A_n})
Xác nhận (y = \text{hash}(k, e) \times \text{hash}(m) + k)
Nhưng nếu ai đó sử dụng một kỷ nguyên hai lần thì sao? Chúng sẽ tiết lộ hai giá trị (m_1) và (m_2) cùng với các giá trị chứng chỉ của chúng (y_1 = \text{hash}(k, e) \times \text{hash}(m_1) + k) và (y_2 = \text{hash}(k, e) \times \text{hash}(m_2) + k). Sau đó, chúng ta có thể sử dụng hai điểm này để khôi phục dòng và sau đó là chặn y, là khóa riêng.
Vì vậy, nếu ai đó sử dụng lại một kỷ nguyên, họ sẽ vô tình tiết lộ khóa riêng của mình cho mọi người. Tùy thuộc vào ngữ cảnh, điều này có thể dẫn đến hành vi trộm tiền hoặc chỉ đơn thuần là phát tán khóa riêng tư và tích hợp nó vào hợp đồng thông minh, dẫn đến việc xóa địa chỉ liên quan.
Một hệ thống chống từ chối dịch vụ ẩn danh ngoài chuỗi khả thi, phù hợp với mạng ngang hàng blockchain, ứng dụng trò chuyện và các hệ thống tương tự, không yêu cầu bằng chứng công việc. Dự án RLN về cơ bản tập trung vào khái niệm này, mặc dù có những thay đổi nhỏ (cụ thể là chúng sử dụng cả bộ vô hiệu hóa và kỹ thuật đường hai điểm, giúp việc phát hiện các trường hợp trong đó một kỷ nguyên được sử dụng lại trở nên đơn giản hơn).
Hãy tưởng tượng việc thành lập 0chan, một diễn đàn trực tuyến như 4chan cung cấp tính năng ẩn danh hoàn toàn (bạn thậm chí không có tên cố định) nhưng có hệ thống danh tiếng để quảng bá nội dung chất lượng cao hơn. Một hệ thống như vậy có thể có DAO quản trị để gắn cờ các bài đăng vi phạm các quy tắc hệ thống, đưa ra cơ chế ba lần tấn công.
Hệ thống danh tiếng có thể phục vụ cho danh tiếng tích cực hoặc tiêu cực; tuy nhiên, việc giải quyết danh tiếng tiêu cực đòi hỏi cơ sở hạ tầng bổ sung. Điều này yêu cầu người dùng kết hợp tất cả dữ liệu danh tiếng vào bằng chứng của họ, ngay cả khi nó tiêu cực. Chúng tôi sẽ chủ yếu tập trung vào trường hợp sử dụng đầy thách thức này, giống như những gì Unirep Social hướng tới thực hiện.
Bất kỳ ai cũng có thể đăng bài bằng cách truyền tin nhắn trên chuỗi có chứa bài đăng, kèm theo ZK-SNARK. ZK-SNARK này đóng vai trò là bằng chứng cho thấy (i) bạn sở hữu một danh tính bên ngoài duy nhất cấp cho bạn quyền tạo tài khoản hoặc (ii) trước đây bạn đã xuất bản các bài đăng cụ thể. Cụ thể, ZK-SNARK hoạt động như sau:
Chất vô hiệu hóa, N
Gốc trạng thái blockchain gần đây nhất, R
Nội dung bài đăng ('trộn' vào bằng chứng để liên kết nó với bài đăng mà không có bất kỳ tính toán nào trên đó)
Khóa riêng của bạn, k
Một danh tính bên ngoài (địa chỉ A) hoặc bộ vô hiệu hóa, Nprev, được sử dụng trong bài viết trước
Bằng chứng Merkle, M, rằng chuỗi chứa A hoặc Nprev
Bài đăng thứ i bạn đã xuất bản bằng tài khoản này
Xác nhận rằng M là nhánh Merkle hợp lệ, chứng minh rằng (A hoặc Nprev, tùy theo điều kiện nào được cung cấp) là một lá của cây có gốc R.
Xác minh N = enc(i, k) trong đó enc là hàm mã hóa (ví dụ: AES).
Nếu i=0, hãy xác minh A=privtoaddr(k), nếu không thì hãy xác minh Nprev=enc(i−1,k).
Bên cạnh việc xác thực bằng chứng, chuỗi cũng kiểm tra (i) rằng R thực sự là một trạng thái gốc gần đây và (ii) rằng bộ vô hiệu hóa N chưa được sử dụng trước đó. Cho đến thời điểm này, nó giống với các đồng tiền bảo vệ quyền riêng tư được mô tả trước đây, nhưng chúng tôi đã thêm quy trình 'đúc' tài khoản mới và loại bỏ khả năng 'gửi' tài khoản của bạn tới các khóa khác nhau. Thay vào đó, tất cả các bộ vô hiệu hóa được tạo bằng khóa gốc. Chúng tôi sử dụng enc ở đây để làm cho bộ vô hiệu hóa có thể đảo ngược. Nếu bạn có khóa k, bạn có thể giải mã bất kỳ bộ vô hiệu hóa cụ thể nào trên chuỗi; nếu kết quả là một chỉ mục hợp lệ chứ không phải là vô nghĩa ngẫu nhiên (ví dụ: chúng ta chỉ có thể kiểm tra dec(N) < 2^64), thì bạn sẽ biết bộ vô hiệu hóa được tạo bằng khóa k.
Trong kế hoạch này, danh tiếng là trực tuyến và rõ ràng. Một số hợp đồng thông minh có một phương thức gọi là addReputation, phương thức này lấy bộ vô hiệu hóa được phát hành cùng với một bài đăng và số lượng đơn vị danh tiếng sẽ được cộng hoặc trừ làm đầu vào.
Chúng tôi đã mở rộng dữ liệu được lưu trữ trên chuỗi cho mỗi bài đăng. Thay vì chỉ lưu trữ bộ vô hiệu hóa N, chúng tôi lưu trữ {N, h¯, u¯} trong đó:
h¯ = hash(h, r) trong đó h đại diện cho chiều cao khối của gốc trạng thái được tham chiếu trong bằng chứng.
u¯ = hash(u, r) trong đó u là điểm danh tiếng của tài khoản (bắt đầu từ 0 đối với tài khoản mới).
R ở đây là một giá trị ngẫu nhiên được thêm vào để ngăn không cho h và u được tìm thấy thông qua tìm kiếm vũ phu. Theo thuật ngữ mật mã, việc thêm R làm cho hàm băm trở thành một cam kết bị che giấu.
Giả sử bài đăng sử dụng root R và lưu trữ {N, h¯, u¯}. Trong bằng chứng của nó, nó liên kết đến bài đăng trước đó đã lưu trữ dữ liệu {Nprev, h¯prev, u¯prev}. Bằng chứng của bài đăng cũng phải duyệt qua tất cả các mục danh tiếng được đăng giữa hprev và h. Đối với mỗi bộ vô hiệu hóa N, hàm xác minh sẽ giải mã N bằng khóa k của người dùng. Nếu quá trình giải mã tạo ra một chỉ mục hợp lệ, nó sẽ áp dụng bản cập nhật danh tiếng. Nếu tổng tất cả các cập nhật danh tiếng bằng δ thì điều đó chứng tỏ u = uprev + δ.
Nếu chúng tôi muốn triển khai quy tắc “ba lần đình công và bạn bị loại”, ZK-SNARK cũng sẽ đảm bảo u > -3. Nếu chúng tôi muốn có quy tắc trong đó một bài đăng có đại diện ≥ 100 nhận được thẻ “bài đăng có uy tín cao” đặc biệt, điều đó cũng có thể được thực hiện.
Để nâng cao khả năng mở rộng của hệ thống này, chúng ta có thể chia nó thành hai loại tin nhắn: Bài đăng và RCA. Một bài đăng sẽ nằm ngoài chuỗi, mặc dù nó yêu cầu phải trỏ đến một RCA được thực hiện trong tuần qua. RCA sẽ được đưa vào chuỗi, vượt qua tất cả các bản cập nhật danh tiếng kể từ RCA trước đó của nhà xuất bản. Bằng cách này, tải trên chuỗi sẽ giảm xuống còn một giao dịch trên mỗi bài đăng mỗi tuần, cộng thêm một giao dịch cho mỗi thông báo danh tiếng.
Đôi khi, cần phải thiết kế một hệ thống với một “người vận hành” tập trung. Lý do cho điều này có thể khác nhau: đôi khi, đó là vì khả năng mở rộng và đôi khi, đó là vì quyền riêng tư, đặc biệt là quyền riêng tư của dữ liệu do nhà điều hành nắm giữ. Ví dụ: hệ thống bỏ phiếu chống cưỡng chế MACI yêu cầu cử tri gửi phiếu bầu của họ trực tuyến, được mã hóa bằng khóa do một nhà điều hành tập trung nắm giữ. Toán tử này giải mã tất cả các phiếu bầu trên chuỗi, kiểm đếm chúng và hiển thị kết quả cuối cùng. Họ sử dụng ZK-SNARK để chứng minh rằng mọi thứ họ làm đều chính xác. Sự phức tạp bổ sung này rất quan trọng để đảm bảo quyền riêng tư mạnh mẽ (được gọi là phản kháng cưỡng chế): người dùng không thể chứng minh cho bất kỳ ai biết họ đã bỏ phiếu như thế nào, ngay cả khi họ muốn. Nhờ blockchain và ZK-SNARK, mức độ tin cậy của chúng tôi đối với nhà điều hành vẫn ở mức tối thiểu. Các nhà khai thác độc hại có thể vi phạm sự phản kháng cưỡng chế, nhưng vì phiếu bầu được đăng trên blockchain nên họ không thể gian lận bằng cách kiểm duyệt phiếu bầu. Và vì họ phải cung cấp ZK-SNARK nên họ không thể gian lận bằng cách tính toán sai kết quả.
Việc sử dụng ZK-SNARK nâng cao hơn là trong các tính toán cần có bằng chứng, với dữ liệu đầu vào được phân phối giữa hai hoặc nhiều bên và chúng tôi không muốn bất kỳ bên nào tìm hiểu về dữ liệu đầu vào của bên khác. Trong kịch bản hai bên, các mạch bị cắt xén có thể đáp ứng các yêu cầu về quyền riêng tư; đối với N bên, có thể sử dụng các giao thức tính toán phức tạp hơn của nhiều bên. ZK-SNARK có thể được tích hợp với các giao thức này để thực hiện các tính toán có thể kiểm chứng được của nhiều bên. Điều này cho phép các hệ thống danh tiếng tiên tiến, cho phép nhiều người tham gia thực hiện các phép tính chung trên đầu vào riêng của họ. Bài toán để đạt được điều này một cách hiệu quả vẫn còn ở giai đoạn đầu.
ZK-SNARK có hiệu quả cao trong việc tạo ra các hệ thống nơi người dùng có trạng thái riêng tư. Tuy nhiên, nó không thể duy trì trạng thái riêng tư mà không ai biết. Để thông tin được chứng minh, người chứng minh phải biết thông tin đó ở dạng bản rõ. Uniswap là một ví dụ khó tư nhân hóa. Trong Uniswap, có một “thực thể” logic trung tâm – tài khoản của nhà cung cấp thanh khoản, không thuộc sở hữu của bất kỳ ai và tất cả các giao dịch Uniswap đều diễn ra với tài khoản này. Bạn không thể ẩn trạng thái của tài khoản này vì ai đó cần giữ trạng thái này ở dạng văn bản gốc để chứng minh và mỗi giao dịch sẽ cần có sự tham gia tích cực của họ. Bạn có thể sử dụng các mạch bị cắt xén của ZK-SNARK để tạo một phiên bản Uniswap tập trung, an toàn, riêng tư, nhưng không rõ liệu lợi ích có lớn hơn chi phí hay không. Nó thậm chí có thể không mang lại bất kỳ lợi ích thực sự nào: hợp đồng cần thông báo cho người dùng về giá tài sản và sự thay đổi giá trên mỗi khối có thể tiết lộ hoạt động giao dịch. Blockchain có thể toàn cầu hóa thông tin trạng thái và ZK-SNARK có thể tư nhân hóa thông tin đó, nhưng không có phương pháp vững chắc nào để toàn cầu hóa và tư nhân hóa thông tin trạng thái đồng thời.
Trong các phần trên, chúng ta đã thấy các ví dụ về các công cụ mạnh mẽ nhưng cũng có thể đóng vai trò là nền tảng cho các ứng dụng khác. Nullifiers, quan trọng đối với tiền tệ, hiện xuất hiện trở lại trong các trường hợp sử dụng khác. Kỹ thuật “liên kết cưỡng chế” được sử dụng trong phần danh tiếng tiêu cực có ứng dụng rộng rãi. Tính năng này có hiệu quả cao đối với nhiều ứng dụng trong đó “hồ sơ” của người dùng thay đổi theo thời gian theo những cách phức tạp và bạn muốn buộc người dùng tuân theo các quy tắc hệ thống trong khi vẫn đảm bảo quyền riêng tư. Người dùng thậm chí có thể được giao nhiệm vụ thể hiện “trạng thái” nội bộ của họ bằng cách sử dụng cây Merkle riêng tư hoàn toàn. Công cụ “nhóm cam kết” được đề cập có thể được xây dựng bằng ZK-SNARK. Nếu một số ứng dụng nhất định không thể hoạt động hoàn toàn trên chuỗi và yêu cầu người vận hành tập trung thì các kỹ thuật tương tự có thể giúp người vận hành trung thực. ZK-SNARK là một công cụ mạnh mẽ, kết hợp giữa lợi ích về trách nhiệm giải trình và quyền riêng tư. Mặc dù chúng có những hạn chế nhưng trong một số trường hợp, các thiết kế ứng dụng thông minh có thể vượt qua những hạn chế này. Tôi hy vọng sẽ thấy nhiều ứng dụng hơn áp dụng ZK-SNARK và cuối cùng xây dựng các ứng dụng kết hợp ZK-SNARK với các hình thức mã hóa khác trong những năm tới.