Giới thiệu: Gần đây, Vitalik và một số học giả đã đồng xuất bản một bài báo mới, đề cập đến cách Tornado Cash thực hiện kế hoạch chống rửa tiền (về cơ bản cho phép người rút tiền chứng minh rằng hồ sơ tiền gửi của họ thuộc về một bộ không chứa tiền bẩn), nhưng bài báo thiếu cách giải thích chi tiết về logic và nguyên tắc kinh doanh của Tornado Cash, khiến một số độc giả bối rối.
Đáng đề cập rằng các dự án về quyền riêng tư được đại diện bởi Tornado là những dự án thực sự sử dụng tính chất không biết của thuật toán ZK-SNARK, trong khi hầu hết các dự án được gắn nhãn ZK chỉ sử dụng tính gọn nhẹ của ZK-SNARK. Người ta thường nhầm lẫn sự khác biệt giữa Chứng minh Đúng đắn và ZK, và Tornado đóng vai trò như một trường hợp xuất sắc để hiểu về ứng dụng của ZK. Tác giả của bài viết này đã viết về nguyên tắc của Tornado vào năm 2022 cho Web3Caff Research, và hôm nay chọn lựa và mở rộng một số phần từ bài viết đó, tổ chức thành bài viết này để hiểu Tornado Cash một cách hệ thống.
Liên kết bài viết gốc: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash sử dụng giao thức trộn tiền xu dựa trên bằng chứng không có kiến thức, với phiên bản cũ hơn ra mắt vào năm 2019 và phiên bản beta mới được phát hành vào cuối năm 2021. Phiên bản cũ hơn của Tornado đạt được mức độ phân cấp cao, với các hợp đồng trên chuỗi của nó là mã nguồn mở và không được kiểm soát bởi bất kỳ cơ chế đa chữ ký nào, và mã giao diện người dùng của nó cũng là mã nguồn mở và được sao lưu trên mạng IPFS. Do cấu trúc đơn giản và dễ hiểu hơn của phiên bản Tornado cũ, bài viết này tập trung vào việc giải thích nó. Ý tưởng chính đằng sau Tornado là kết hợp một số lượng lớn các hành động gửi và rút tiền với nhau. Sau khi gửi mã thông báo vào Tornado, người gửi tiền xuất trình Bằng chứng ZK để chứng minh họ đã gửi tiền và sau đó rút tiền đến một địa chỉ mới, do đó cắt đứt liên kết giữa địa chỉ gửi và rút tiền.
Cụ thể hơn, Tornado hoạt động như một hòm kính đựng đầy tiền được nhiều người gửi. Chúng ta có thể thấy ai đã gửi tiền, nhưng vì tiền được pha trộn cao, việc truy vết xem đồng tiền nào được gửi bởi ai nếu ai đó không quen thuộc rút một đồng tiền là khó khăn.
(Nguồn: rareskills)Kịch bản này hơi phổ biến; ví dụ: khi chúng tôi hoán đổi ETH trong nhóm Uniswap, chúng tôi không thể biết chúng tôi đang nhận được ETH của ai vì nhiều người đã cung cấp thanh khoản cho Uniswap. Tuy nhiên, điểm khác biệt là mỗi khi hoán đổi token trên Uniswap, bạn cần sử dụng các token khác làm chi phí tương đương, và bạn không thể "riêng tư" chuyển tiền cho người khác; Trong khi đó, với máy trộn, bạn chỉ cần xuất trình bằng chứng tiền gửi để rút tiền. Để làm cho các hành động gửi và rút tiền có vẻ đồng nhất, mọi khoản tiền gửi vào nhóm Tornado và mọi lần rút tiền từ nó đều được giữ nhất quán về số tiền. Ví dụ: nếu có 100 người gửi tiền và 100 người rút tiền trong một nhóm, mặc dù có thể nhìn thấy, họ dường như không được liên kết và số tiền gửi và rút của mỗi người là như nhau.
Điều này có thể làm mờ tính khả năng theo dõi của việc chuyển tiền, mang lại sự tiện lợi tự nhiên cho các giao dịch ẩn danh. Câu hỏi quan trọng là: người rút tiền làm thế nào để chứng minh họ đã thực hiện một khoản gửi tiền?
Địa chỉ thực hiện rút tiền không liên kết với bất kỳ địa chỉ nạp tiền nào, vì vậy làm thế nào để xác định khả năng rút tiền của họ? Phương pháp trực tiếp nhất dường như là cho người rút tiền tiết lộ bản ghi nạp tiền nào là của họ, nhưng điều này sẽ tiết lộ trực tiếp danh tính của họ. Đây là nơi mà bằng chứng không cần biết đến. Bằng cách trình bày một Bằng chứng không cần biết rằng họ có một bản ghi nạp tiền trong hợp đồng Tornado mà chưa được rút, người rút tiền có thể khởi tạo thành công một khoản rút. Bằng chứng không cần biết bản thân bảo vệ quyền riêng tư, chỉ tiết lộ rằng người đó thực sự đã nạp tiền vào hồ bơi quỹ, mà không tiết lộ người nạp tiền họ tương ứng với.
Để chứng minh "Tôi đã gửi tiền vào nhóm quỹ Tornado" có thể được dịch thành "Hồ sơ tiền gửi của tôi có thể được tìm thấy trong hợp đồng Tornado." Nếu chúng ta sử dụng Cn để đại diện cho một bản ghi tiền gửi, vấn đề trở thành: cho rằng bộ hồ sơ tiền gửi của Tornado là {C1, C2, ... C100...}, người rút tiền, Bob, chứng minh rằng anh ta đã sử dụng khóa của mình để tạo ra một số Cn trong hồ sơ gửi tiền mà không tiết lộ đó là Cn cụ thể nào. Điều này liên quan đến tài sản đặc biệt của Merkle Proof. Tất cả các hồ sơ tiền gửi của Tornado được tích hợp vào một Merkle Tree được xây dựng trên chuỗi, với các bản ghi này là các nút lá cấp dưới cùng của nó. Tổng số lá là khoảng 2 ^ 20 > 1 triệu, hầu hết trong số đó ở trạng thái trống (được gán giá trị ban đầu). Bất cứ khi nào một khoản tiền gửi mới xảy ra, hợp đồng sẽ ghi lại giá trị duy nhất của nó, Cam kết, vào một chiếc lá và sau đó cập nhật gốc của Merkle Tree.
Ví dụ, nếu tiền gửi của Bob là giao dịch thứ 10,000 trong lịch sử của Tornado, giá trị đặc trưng Cn liên kết với tiền gửi này sẽ được nhập vào nút lá thứ 10,000 của cây Merkle, tức là C10000 = Cn. Hợp đồng sau đó tự động tính toán một Root mới và cập nhật nó. Để tiết kiệm tài nguyên tính toán, hợp đồng Tornado lưu trữ tạm thời dữ liệu từ một nhóm các nút đã thay đổi trước đó, như Fs1, Fs2 và Fs0 trong sơ đồ dưới đây.
(Nguồn: RareSkills)
Chứng minh Merkle, bản chất của nó, rất súc tích và nhẹ nhàng, tận dụng sự đơn giản của cấu trúc dữ liệu cây trong quá trình tìm kiếm/theo dõi. Để chứng minh rằng một giao dịch TD tồn tại trong một Cây Merkle, chỉ cần cung cấp một Chứng minh Merkle tương ứng với Gốc, điều này khá đơn giản. Nếu Cây Merkle đặc biệt lớn, với 2^20 lá ở mức dưới cùng (tức là, 1 triệu bản ghi gửi tiền), một Chứng minh Merkle chỉ cần bao gồm các giá trị của 21 nút, điều này rất ngắn gọn.
Để chứng minh rằng giao dịch H3 thực sự nằm trong Mạng cây Merkle, người ta phải chứng minh rằng bằng cách sử dụng H3 và các phần khác của dữ liệu trên Mạng cây Merkle, có thể tạo ra Gốc, và dữ liệu cần thiết để tạo ra Gốc (bao gồm cả Td) chiếm phần chứng minh Merkle. Khi Bob rút tiền, anh ấy cần chứng minh rằng chứng chỉ của anh ấy tương ứng với một hash gửi tiền Cn được ghi lại trên Mạng cây Merkle trong sổ cái của Tornado. Nói cách khác, anh ấy phải chứng minh hai điều: Cn tồn tại trong Mạng cây Merkle tưởng tượng trên chuỗi, cụ thể bằng cách xây dựng một chứng minh Merkle chứa Cn; Cn được liên kết với chứng chỉ gửi tiền của Bob.
Trong mã frontend của giao diện người dùng Tornado, nhiều chức năng được triển khai trước. Khi người gửi tiền mở trang web Tornado Cash và nhấp vào nút gửi tiền, mã giao diện người dùng đi kèm sẽ tạo ra hai số ngẫu nhiên, K và r, cục bộ. Sau đó, nó tính toán giá trị của Cn = Hash (K, r) và chuyển Cn (được gọi là cam kết trong sơ đồ bên dưới) vào hợp đồng Tornado, chèn nó vào Merkle Tree được ghi lại bởi hợp đồng sau. Về cơ bản, K và r hoạt động như khóa riêng. Chúng rất quan trọng và hệ thống nhắc người dùng lưu chúng một cách an toàn. K và r là cần thiết một lần nữa trong quá trình rút tiền.
(Tùy chọn mã hóaNote cho phép người dùng mã hóa thông tin đăng nhập K và r bằng khóa riêng và lưu trữ nó trên blockchain để tránh quên) Điều quan trọng là tất cả các hoạt động này xảy ra ngoài chuỗi, có nghĩa là hợp đồng Tornado và các nhà quan sát bên ngoài không biết về K và r. Nếu K và r bị rò rỉ, nó giống như hành vi trộm cắp khóa riêng của ví.
Khi nhận được khoản tiền gửi từ người dùng và sự nộp Cn=Hash(K, r), hợp đồng Tornado ghi lại Cn ở lớp dưới cùng của cây Merkle như một nút lá mới, cũng cập nhật giá trị Gốc. Do đó, Cn trực tiếp liên kết với hành động gửi tiền của người dùng, cho phép người ngoài biết được người dùng nào tương ứng với mỗi Cn, ai đã gửi token vào máy trộn, và ghi lại Cn của mỗi người gửi tiền.
Trong quá trình rút tiền, người rút tiền nhập thông tin xác thực / khóa riêng (các số ngẫu nhiên K và r được tạo trong quá trình gửi tiền) trên trang web giao diện người dùng. Chương trình trong mã frontend Tornado Cash sử dụng K và r, Cn = Hash (K, r) và Merkle Proof tương ứng với Cn làm tham số đầu vào để tạo ZK Proof. Điều này chứng tỏ rằng Cn tồn tại trong Merkle Tree dưới dạng bản ghi tiền gửi, và K và r là các thông tin tương ứng với Cn. Bước này về cơ bản chứng minh: Tôi biết chìa khóa tương ứng với hồ sơ tiền gửi trên Cây Merkle. Khi ZK Proof được đệ trình lên hợp đồng Tornado, bốn thông số này được che giấu, bảo vệ quyền riêng tư. Việc tạo ZK Proof bao gồm các tham số bổ sung, bao gồm gốc Merkle được ghi trong hợp đồng Tornado tại thời điểm rút tiền, địa chỉ người nhận tùy chỉnh A và số nhận dạng nf để ngăn chặn các cuộc tấn công phát lại. Ba thông số này được đăng công khai trên blockchain, không ảnh hưởng đến quyền riêng tư.
Một chi tiết cần lưu ý là việc sử dụng hai số ngẫu nhiên, K và r, để tạo ra Cn thay vì một số ngẫu nhiên duy nhất, tạo ra tính bảo mật tăng lên chống lại các va chạm. A đại diện cho địa chỉ người nhận rút tiền, do người rút tiền lựa chọn. Bộ xác định nf, được thiết kế để ngăn chặn các cuộc tấn công phát lại, được tính toán như nf=Hash(K), trong đó K là một trong hai số ngẫu nhiên được sử dụng trong bước gửi tiền để tạo ra Cn. Điều này liên kết nf trực tiếp với Cn, thiết lập mối liên hệ một-một giữa mỗi Cn và nf tương ứng của nó. Mục đích của việc ngăn chặn các cuộc tấn công phát lại là do tính năng thiết kế của máy trộn, giữ cho mối liên kết giữa số tiền rút và các lá cây Merkle cụ thể (Cn) không biết đến, cho phép việc lạm dụng tiềm năng của các lần rút tiền lặp lại cho đến khi nguồn quỹ cạn kiệt.
Bộ nhận dạng nf hoạt động tương tự như số nonce được liên kết với mỗi địa chỉ Ethereum, ngăn chặn việc tái phát giao dịch. Khi rút tiền, một kiểm tra đảm bảo rằng nf đã được sử dụng trước đó; nếu chưa sử dụng, việc rút tiền là hợp lệ và nf được ghi lại. Bất kỳ cố gắng tạo ra một nf không liên kết với bất kỳ khoản tiền gửi Cn nào được ghi lại sẽ không thể tạo ra một Chứng minh ZK hợp lệ, làm cho việc rút tiền không thành công.
Nếu ai đó tạo ngẫu nhiên một hợp đồng không thể thay thế (nf) không được ghi lại, nó có hoạt động không? Tất nhiên là không. Khi người rút tiền tạo ra Bằng chứng không có kiến thức (ZK Proof), họ phải đảm bảo rằng nf bằng Hash (K), trong đó số ngẫu nhiên K được liên kết với bản ghi tiền gửi Cn. Điều này có nghĩa là nf được liên kết với một khoản tiền gửi được ghi lại Cn. Nếu ai đó chế tạo nf một cách tùy tiện, nf này sẽ không khớp với bất kỳ hồ sơ tiền gửi nào, khiến bạn không thể tạo Bằng chứng ZK hợp lệ. Do đó, quá trình rút tiền không thể hoàn tất thành công và thao tác rút tiền sẽ không thành công. Một số người có thể hỏi: Có thể tiến hành mà không cần nf không? Vì người rút tiền cần gửi bằng chứng ZK trong quá trình rút tiền để chứng minh sự liên kết của họ với một Cn nhất định, tại sao không chỉ kiểm tra xem Bằng chứng ZK tương ứng đã được gửi đến blockchain mỗi khi rút tiền xảy ra hay chưa? Tuy nhiên, cách tiếp cận này rất tốn kém vì hợp đồng Tornado Cash không lưu trữ vĩnh viễn ZK Proofs trước đây do lãng phí không gian lưu trữ đáng kể. So sánh mọi Bằng chứng ZK mới được gửi đến blockchain với các bằng chứng hiện có kém hiệu quả hơn so với việc đặt một số nhận dạng nhỏ như nf và lưu trữ vĩnh viễn nó.
Theo ví dụ mã code của chức năng rút tiền, các tham số cần thiết và logic kinh doanh như sau: Người dùng gửi một chứng minh ZK và nf (NullifierHash) = Hash (K), chỉ định một địa chỉ người nhận cho việc rút tiền, và chứng minh ZK che giấu các giá trị của Cn, K và r, làm cho người ngoài không thể xác định danh tính của người dùng. Người nhận thường sử dụng một địa chỉ mới, sạch sẽ không tiết lộ thông tin cá nhân.
Tuy nhiên, có một vấn đề nhỏ: khi người dùng rút tiền để không bị truy tìm, họ thường khởi tạo giao dịch rút tiền từ một địa chỉ mới tạo ra. Lúc này, địa chỉ mới thiếu ETH để thanh toán phí gas. Do đó, khi khởi tạo một giao dịch rút tiền, địa chỉ rút tiền phải rõ ràng tuyên bố một người chuyển tiền để thanh toán phí gas thay mặt. Sau đó, hợp đồng trộn trừ một phần từ số tiền rút của người dùng để bồi thường cho người chuyển tiền.
Tóm lại, Tornado Cash có thể che khuất kết nối giữa người rút tiền và người gửi tiền. Trong các tình huống có lượng người dùng lớn, nó giống như một tên tội phạm trà trộn vào đám đông trong một khu vực đông đúc, khiến cảnh sát khó theo dõi. Quá trình rút tiền liên quan đến việc sử dụng ZK-SNARK, với phần nhân chứng ẩn chứa thông tin quan trọng về bộ rút, đây là một khía cạnh quan trọng của toàn bộ máy trộn. Hiện tại, Tornado dường như là một trong những dự án lớp ứng dụng khéo léo nhất liên quan đến ZK.
Partilhar
Giới thiệu: Gần đây, Vitalik và một số học giả đã đồng xuất bản một bài báo mới, đề cập đến cách Tornado Cash thực hiện kế hoạch chống rửa tiền (về cơ bản cho phép người rút tiền chứng minh rằng hồ sơ tiền gửi của họ thuộc về một bộ không chứa tiền bẩn), nhưng bài báo thiếu cách giải thích chi tiết về logic và nguyên tắc kinh doanh của Tornado Cash, khiến một số độc giả bối rối.
Đáng đề cập rằng các dự án về quyền riêng tư được đại diện bởi Tornado là những dự án thực sự sử dụng tính chất không biết của thuật toán ZK-SNARK, trong khi hầu hết các dự án được gắn nhãn ZK chỉ sử dụng tính gọn nhẹ của ZK-SNARK. Người ta thường nhầm lẫn sự khác biệt giữa Chứng minh Đúng đắn và ZK, và Tornado đóng vai trò như một trường hợp xuất sắc để hiểu về ứng dụng của ZK. Tác giả của bài viết này đã viết về nguyên tắc của Tornado vào năm 2022 cho Web3Caff Research, và hôm nay chọn lựa và mở rộng một số phần từ bài viết đó, tổ chức thành bài viết này để hiểu Tornado Cash một cách hệ thống.
Liên kết bài viết gốc: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash sử dụng giao thức trộn tiền xu dựa trên bằng chứng không có kiến thức, với phiên bản cũ hơn ra mắt vào năm 2019 và phiên bản beta mới được phát hành vào cuối năm 2021. Phiên bản cũ hơn của Tornado đạt được mức độ phân cấp cao, với các hợp đồng trên chuỗi của nó là mã nguồn mở và không được kiểm soát bởi bất kỳ cơ chế đa chữ ký nào, và mã giao diện người dùng của nó cũng là mã nguồn mở và được sao lưu trên mạng IPFS. Do cấu trúc đơn giản và dễ hiểu hơn của phiên bản Tornado cũ, bài viết này tập trung vào việc giải thích nó. Ý tưởng chính đằng sau Tornado là kết hợp một số lượng lớn các hành động gửi và rút tiền với nhau. Sau khi gửi mã thông báo vào Tornado, người gửi tiền xuất trình Bằng chứng ZK để chứng minh họ đã gửi tiền và sau đó rút tiền đến một địa chỉ mới, do đó cắt đứt liên kết giữa địa chỉ gửi và rút tiền.
Cụ thể hơn, Tornado hoạt động như một hòm kính đựng đầy tiền được nhiều người gửi. Chúng ta có thể thấy ai đã gửi tiền, nhưng vì tiền được pha trộn cao, việc truy vết xem đồng tiền nào được gửi bởi ai nếu ai đó không quen thuộc rút một đồng tiền là khó khăn.
(Nguồn: rareskills)Kịch bản này hơi phổ biến; ví dụ: khi chúng tôi hoán đổi ETH trong nhóm Uniswap, chúng tôi không thể biết chúng tôi đang nhận được ETH của ai vì nhiều người đã cung cấp thanh khoản cho Uniswap. Tuy nhiên, điểm khác biệt là mỗi khi hoán đổi token trên Uniswap, bạn cần sử dụng các token khác làm chi phí tương đương, và bạn không thể "riêng tư" chuyển tiền cho người khác; Trong khi đó, với máy trộn, bạn chỉ cần xuất trình bằng chứng tiền gửi để rút tiền. Để làm cho các hành động gửi và rút tiền có vẻ đồng nhất, mọi khoản tiền gửi vào nhóm Tornado và mọi lần rút tiền từ nó đều được giữ nhất quán về số tiền. Ví dụ: nếu có 100 người gửi tiền và 100 người rút tiền trong một nhóm, mặc dù có thể nhìn thấy, họ dường như không được liên kết và số tiền gửi và rút của mỗi người là như nhau.
Điều này có thể làm mờ tính khả năng theo dõi của việc chuyển tiền, mang lại sự tiện lợi tự nhiên cho các giao dịch ẩn danh. Câu hỏi quan trọng là: người rút tiền làm thế nào để chứng minh họ đã thực hiện một khoản gửi tiền?
Địa chỉ thực hiện rút tiền không liên kết với bất kỳ địa chỉ nạp tiền nào, vì vậy làm thế nào để xác định khả năng rút tiền của họ? Phương pháp trực tiếp nhất dường như là cho người rút tiền tiết lộ bản ghi nạp tiền nào là của họ, nhưng điều này sẽ tiết lộ trực tiếp danh tính của họ. Đây là nơi mà bằng chứng không cần biết đến. Bằng cách trình bày một Bằng chứng không cần biết rằng họ có một bản ghi nạp tiền trong hợp đồng Tornado mà chưa được rút, người rút tiền có thể khởi tạo thành công một khoản rút. Bằng chứng không cần biết bản thân bảo vệ quyền riêng tư, chỉ tiết lộ rằng người đó thực sự đã nạp tiền vào hồ bơi quỹ, mà không tiết lộ người nạp tiền họ tương ứng với.
Để chứng minh "Tôi đã gửi tiền vào nhóm quỹ Tornado" có thể được dịch thành "Hồ sơ tiền gửi của tôi có thể được tìm thấy trong hợp đồng Tornado." Nếu chúng ta sử dụng Cn để đại diện cho một bản ghi tiền gửi, vấn đề trở thành: cho rằng bộ hồ sơ tiền gửi của Tornado là {C1, C2, ... C100...}, người rút tiền, Bob, chứng minh rằng anh ta đã sử dụng khóa của mình để tạo ra một số Cn trong hồ sơ gửi tiền mà không tiết lộ đó là Cn cụ thể nào. Điều này liên quan đến tài sản đặc biệt của Merkle Proof. Tất cả các hồ sơ tiền gửi của Tornado được tích hợp vào một Merkle Tree được xây dựng trên chuỗi, với các bản ghi này là các nút lá cấp dưới cùng của nó. Tổng số lá là khoảng 2 ^ 20 > 1 triệu, hầu hết trong số đó ở trạng thái trống (được gán giá trị ban đầu). Bất cứ khi nào một khoản tiền gửi mới xảy ra, hợp đồng sẽ ghi lại giá trị duy nhất của nó, Cam kết, vào một chiếc lá và sau đó cập nhật gốc của Merkle Tree.
Ví dụ, nếu tiền gửi của Bob là giao dịch thứ 10,000 trong lịch sử của Tornado, giá trị đặc trưng Cn liên kết với tiền gửi này sẽ được nhập vào nút lá thứ 10,000 của cây Merkle, tức là C10000 = Cn. Hợp đồng sau đó tự động tính toán một Root mới và cập nhật nó. Để tiết kiệm tài nguyên tính toán, hợp đồng Tornado lưu trữ tạm thời dữ liệu từ một nhóm các nút đã thay đổi trước đó, như Fs1, Fs2 và Fs0 trong sơ đồ dưới đây.
(Nguồn: RareSkills)
Chứng minh Merkle, bản chất của nó, rất súc tích và nhẹ nhàng, tận dụng sự đơn giản của cấu trúc dữ liệu cây trong quá trình tìm kiếm/theo dõi. Để chứng minh rằng một giao dịch TD tồn tại trong một Cây Merkle, chỉ cần cung cấp một Chứng minh Merkle tương ứng với Gốc, điều này khá đơn giản. Nếu Cây Merkle đặc biệt lớn, với 2^20 lá ở mức dưới cùng (tức là, 1 triệu bản ghi gửi tiền), một Chứng minh Merkle chỉ cần bao gồm các giá trị của 21 nút, điều này rất ngắn gọn.
Để chứng minh rằng giao dịch H3 thực sự nằm trong Mạng cây Merkle, người ta phải chứng minh rằng bằng cách sử dụng H3 và các phần khác của dữ liệu trên Mạng cây Merkle, có thể tạo ra Gốc, và dữ liệu cần thiết để tạo ra Gốc (bao gồm cả Td) chiếm phần chứng minh Merkle. Khi Bob rút tiền, anh ấy cần chứng minh rằng chứng chỉ của anh ấy tương ứng với một hash gửi tiền Cn được ghi lại trên Mạng cây Merkle trong sổ cái của Tornado. Nói cách khác, anh ấy phải chứng minh hai điều: Cn tồn tại trong Mạng cây Merkle tưởng tượng trên chuỗi, cụ thể bằng cách xây dựng một chứng minh Merkle chứa Cn; Cn được liên kết với chứng chỉ gửi tiền của Bob.
Trong mã frontend của giao diện người dùng Tornado, nhiều chức năng được triển khai trước. Khi người gửi tiền mở trang web Tornado Cash và nhấp vào nút gửi tiền, mã giao diện người dùng đi kèm sẽ tạo ra hai số ngẫu nhiên, K và r, cục bộ. Sau đó, nó tính toán giá trị của Cn = Hash (K, r) và chuyển Cn (được gọi là cam kết trong sơ đồ bên dưới) vào hợp đồng Tornado, chèn nó vào Merkle Tree được ghi lại bởi hợp đồng sau. Về cơ bản, K và r hoạt động như khóa riêng. Chúng rất quan trọng và hệ thống nhắc người dùng lưu chúng một cách an toàn. K và r là cần thiết một lần nữa trong quá trình rút tiền.
(Tùy chọn mã hóaNote cho phép người dùng mã hóa thông tin đăng nhập K và r bằng khóa riêng và lưu trữ nó trên blockchain để tránh quên) Điều quan trọng là tất cả các hoạt động này xảy ra ngoài chuỗi, có nghĩa là hợp đồng Tornado và các nhà quan sát bên ngoài không biết về K và r. Nếu K và r bị rò rỉ, nó giống như hành vi trộm cắp khóa riêng của ví.
Khi nhận được khoản tiền gửi từ người dùng và sự nộp Cn=Hash(K, r), hợp đồng Tornado ghi lại Cn ở lớp dưới cùng của cây Merkle như một nút lá mới, cũng cập nhật giá trị Gốc. Do đó, Cn trực tiếp liên kết với hành động gửi tiền của người dùng, cho phép người ngoài biết được người dùng nào tương ứng với mỗi Cn, ai đã gửi token vào máy trộn, và ghi lại Cn của mỗi người gửi tiền.
Trong quá trình rút tiền, người rút tiền nhập thông tin xác thực / khóa riêng (các số ngẫu nhiên K và r được tạo trong quá trình gửi tiền) trên trang web giao diện người dùng. Chương trình trong mã frontend Tornado Cash sử dụng K và r, Cn = Hash (K, r) và Merkle Proof tương ứng với Cn làm tham số đầu vào để tạo ZK Proof. Điều này chứng tỏ rằng Cn tồn tại trong Merkle Tree dưới dạng bản ghi tiền gửi, và K và r là các thông tin tương ứng với Cn. Bước này về cơ bản chứng minh: Tôi biết chìa khóa tương ứng với hồ sơ tiền gửi trên Cây Merkle. Khi ZK Proof được đệ trình lên hợp đồng Tornado, bốn thông số này được che giấu, bảo vệ quyền riêng tư. Việc tạo ZK Proof bao gồm các tham số bổ sung, bao gồm gốc Merkle được ghi trong hợp đồng Tornado tại thời điểm rút tiền, địa chỉ người nhận tùy chỉnh A và số nhận dạng nf để ngăn chặn các cuộc tấn công phát lại. Ba thông số này được đăng công khai trên blockchain, không ảnh hưởng đến quyền riêng tư.
Một chi tiết cần lưu ý là việc sử dụng hai số ngẫu nhiên, K và r, để tạo ra Cn thay vì một số ngẫu nhiên duy nhất, tạo ra tính bảo mật tăng lên chống lại các va chạm. A đại diện cho địa chỉ người nhận rút tiền, do người rút tiền lựa chọn. Bộ xác định nf, được thiết kế để ngăn chặn các cuộc tấn công phát lại, được tính toán như nf=Hash(K), trong đó K là một trong hai số ngẫu nhiên được sử dụng trong bước gửi tiền để tạo ra Cn. Điều này liên kết nf trực tiếp với Cn, thiết lập mối liên hệ một-một giữa mỗi Cn và nf tương ứng của nó. Mục đích của việc ngăn chặn các cuộc tấn công phát lại là do tính năng thiết kế của máy trộn, giữ cho mối liên kết giữa số tiền rút và các lá cây Merkle cụ thể (Cn) không biết đến, cho phép việc lạm dụng tiềm năng của các lần rút tiền lặp lại cho đến khi nguồn quỹ cạn kiệt.
Bộ nhận dạng nf hoạt động tương tự như số nonce được liên kết với mỗi địa chỉ Ethereum, ngăn chặn việc tái phát giao dịch. Khi rút tiền, một kiểm tra đảm bảo rằng nf đã được sử dụng trước đó; nếu chưa sử dụng, việc rút tiền là hợp lệ và nf được ghi lại. Bất kỳ cố gắng tạo ra một nf không liên kết với bất kỳ khoản tiền gửi Cn nào được ghi lại sẽ không thể tạo ra một Chứng minh ZK hợp lệ, làm cho việc rút tiền không thành công.
Nếu ai đó tạo ngẫu nhiên một hợp đồng không thể thay thế (nf) không được ghi lại, nó có hoạt động không? Tất nhiên là không. Khi người rút tiền tạo ra Bằng chứng không có kiến thức (ZK Proof), họ phải đảm bảo rằng nf bằng Hash (K), trong đó số ngẫu nhiên K được liên kết với bản ghi tiền gửi Cn. Điều này có nghĩa là nf được liên kết với một khoản tiền gửi được ghi lại Cn. Nếu ai đó chế tạo nf một cách tùy tiện, nf này sẽ không khớp với bất kỳ hồ sơ tiền gửi nào, khiến bạn không thể tạo Bằng chứng ZK hợp lệ. Do đó, quá trình rút tiền không thể hoàn tất thành công và thao tác rút tiền sẽ không thành công. Một số người có thể hỏi: Có thể tiến hành mà không cần nf không? Vì người rút tiền cần gửi bằng chứng ZK trong quá trình rút tiền để chứng minh sự liên kết của họ với một Cn nhất định, tại sao không chỉ kiểm tra xem Bằng chứng ZK tương ứng đã được gửi đến blockchain mỗi khi rút tiền xảy ra hay chưa? Tuy nhiên, cách tiếp cận này rất tốn kém vì hợp đồng Tornado Cash không lưu trữ vĩnh viễn ZK Proofs trước đây do lãng phí không gian lưu trữ đáng kể. So sánh mọi Bằng chứng ZK mới được gửi đến blockchain với các bằng chứng hiện có kém hiệu quả hơn so với việc đặt một số nhận dạng nhỏ như nf và lưu trữ vĩnh viễn nó.
Theo ví dụ mã code của chức năng rút tiền, các tham số cần thiết và logic kinh doanh như sau: Người dùng gửi một chứng minh ZK và nf (NullifierHash) = Hash (K), chỉ định một địa chỉ người nhận cho việc rút tiền, và chứng minh ZK che giấu các giá trị của Cn, K và r, làm cho người ngoài không thể xác định danh tính của người dùng. Người nhận thường sử dụng một địa chỉ mới, sạch sẽ không tiết lộ thông tin cá nhân.
Tuy nhiên, có một vấn đề nhỏ: khi người dùng rút tiền để không bị truy tìm, họ thường khởi tạo giao dịch rút tiền từ một địa chỉ mới tạo ra. Lúc này, địa chỉ mới thiếu ETH để thanh toán phí gas. Do đó, khi khởi tạo một giao dịch rút tiền, địa chỉ rút tiền phải rõ ràng tuyên bố một người chuyển tiền để thanh toán phí gas thay mặt. Sau đó, hợp đồng trộn trừ một phần từ số tiền rút của người dùng để bồi thường cho người chuyển tiền.
Tóm lại, Tornado Cash có thể che khuất kết nối giữa người rút tiền và người gửi tiền. Trong các tình huống có lượng người dùng lớn, nó giống như một tên tội phạm trà trộn vào đám đông trong một khu vực đông đúc, khiến cảnh sát khó theo dõi. Quá trình rút tiền liên quan đến việc sử dụng ZK-SNARK, với phần nhân chứng ẩn chứa thông tin quan trọng về bộ rút, đây là một khía cạnh quan trọng của toàn bộ máy trộn. Hiện tại, Tornado dường như là một trong những dự án lớp ứng dụng khéo léo nhất liên quan đến ZK.