บทนำ:
เร็ว ๆ นี้ วิทาลิคและนักวิชาการหลายคนได้ร่วมกันเผยแพร่บทความใหม่ซึ่งสัมผัสถึงวิธีการ Tornado Cash ใช้แผนการป้องกันการฟอกเงินของตน (ซึ่งทำให้ผู้ถอนสามารถพิสูจน์ได้ว่าประวัติการฝากของพวกเขาเป็นส่วนหนึ่งของเซ็ตที่ไม่รวมเงินที่ได้รับมลพิษ) อย่างไรก็ตาม บทความนั้นขาดการอธิบายเนื้อหาทางธุรกิจและหลักการของ Tornado Cash ที่ซับซ้อน ซึ่งส่งผลให้บางผู้อ่านเข้าใจเพียงอย่างพื้นผิวเท่านั้น
ควรทราบว่าโครงการเช่น Tornado ซึ่งเป็นผลิตภัณฑ์ที่เน้นความเป็นส่วนตัวใช้ประโยชน์จากด้านการรู้เพียงของอัลกอริทึม ZK-SNARK อย่างแท้จริง ในขณะเดียวกัน โซลูชันส่วนใหญ่ที่เสนอแบรนด์ ZK เช่น Rollups เพียงแค่ใช้ความกระชับของ ZK-SNARK เท่านั้น บ่อยครั้ง ผู้คนมักสับสน Proof ความถูกต้องกับ ZK และ Tornado เป็นตัวอย่างที่ยอดเยี่ยมที่ช่วยอธิบายการใช้งานในโลกแห่งความจริงของ ZK ได้อย่างชัดเจน
ผู้เขียนบทความนี้ได้เขียนบทความเกี่ยวกับหลักการของพายฤษีในปี 2022 สำหรับการวิจัย Web3Caff วันนี้เราได้แยกและขยายของส่วนบางของงานเดิมนั้นเพื่อให้เข้าใจได้อย่างเป็นระบบเกี่ยวกับ Tornado Cash
ลิงก์บทความเดิม:https://research.web3caff.com/th/archives/2663?ref=157
Tornado Cash ใช้ zero-knowledge proof เป็นโปรโตคอลในการผสมข้อมูล ในขณะที่เวอร์ชันเก่าถูกเปิดตัวในปี 2019 เวอร์ชันเบต้าของโมเดลที่อัปเดตเปิดตัวในปลายปี 2021 เวอร์ชันก่อนหน้าของ Tornado สามารถบรรลุระดับความกระจายที่ดีด้วยสัญญา on-chain ที่เปิดเป็นโค้ดฟรีและปลอดภัยจากการควบคุมด้วยลายมือหลายรายการ อย่างไรก็ตาม โค้ด frontend เปิดเป็นโค้ดฟรีและถูกสำรองข้อมูลบนเครือข่าย IPFS เนื่องจากความง่ายของเวอร์ชัน Tornado เวอร์ชันเก่านี้ บทความนี้เน้นอธิบายมัน
วิธีการหลักของ Tornado คือการผสมการทำธุรกรรมการฝากและการถอนหลายรายการรวมกัน หลังจากฝากโทเค็นเข้าสู่ Tornado ผู้ฝากจะนำ ZK Proof มายืนยันการฝากก่อนหน้าและจากนั้นถอนโดยใช้ที่อยู่ใหม่ ซึ่งทำให้ไม่สามารถติดตามความเชื่อมโยงระหว่างที่อยู่การฝากและการถอน
ให้นึกถึง Tornado ในรูปแบบที่กระชับกว่าว่าเป็นกล่องแก้วที่เต็มไปด้วยเหรียญ (เหรียญ) ซึ่งถูกฝากโดยบุคคลหลายคน เราสามารถเห็นว่าใครฝากเหรียญไว้ แต่เหรียญเหล่านี้มีคุณสมบัติที่เหมือนกันมาก หากมีคนที่ไม่รู้จักมาเอาเหรียญจากกล่อง เราจะพบว่ายากที่จะติดตามว่าใครกำหนดให้เหรียญนั้นไว้
(ภาพที่มา: rareskills)
สถานการณ์ดังกล่าวดูเหมือนเป็นเรื่องธรรมดา เมื่อเรา SWAP ETHs สองสามรายการจากพูล Uniswap เป็นไปไม่ได้ที่จะระบุว่าเราได้รับ ETH ของใครเนื่องจากผู้ให้บริการสภาพคล่องจํานวนมากให้กับ Uniswap อย่างไรก็ตามความแตกต่างอยู่ในกระบวนการ ด้วย Uniswap การแลกเปลี่ยนโทเค็นต้องใช้โทเค็นอื่นเป็นมูลค่าเทียบเท่าและไม่สามารถโอนเงิน "ส่วนตัว" ได้ ในทางตรงกันข้ามเครื่องผสมเพียงแค่ต้องการให้ผู้ถอนเงินแสดงใบเสร็จรับเงินมัดจํา
เพื่อให้การทำฝากเงินและถอนเงินดูเหมือนเป็นสิ่งเดียวกัน สระว่ายน้ำ Tornado รักษาความสม่ำเสมอในการฝากเงินและถอนเงิน ตัวอย่างเช่น หากมีผู้ฝากเงิน 100 คนและผู้ถอนเงิน 100 คน แม้ว่าการกระทำจะเป็นสาธารณะ แต่ดูเหมือนว่าไม่มีความสัมพันธ์กัน ทุกคนฝากเงินและถอนเงินในจำนวนเงินเท่ากัน ทำให้ยากต่อการติดตามการเคลื่อนไหวของเงิน ดังนั้น มันเป็นประโยชน์ที่เกิดขึ้นอย่างรู้เท่าใจสำหรับการฟอกเงิน
คำถามสำคัญเกิดขึ้น: เมื่อถอนเงิน จะต้องพิสูจน์การฝากล่วงหน้าอย่างไร? ที่อยู่ที่เริ่มต้นการถอนเงินไม่ได้เชื่อมโยงกับที่อยู่ของการฝากเงินใด จึงต้องการให้ใครบางคนรับรองสิทธิในการถอนเงินได้อย่างไร? วิธีที่เป็นที่ตรงไปตรงมาสุดคือการให้ผู้ถอนเงินเปิดเผยบันทึกการฝากเงินของตน แต่นั้นจะเปิดเผยตัวตนของพวกเขา นี่คือจุดที่ zero-knowledge proofs เข้ามาเล่นบทบาท
ด้วย ZK Proof, ผู้ถอนเงินสามารถยืนยันได้ว่าพวกเขามีบัญชีฝากเงินในสัญญาพายุฝุ่น และว่าการฝากเงินนี้ยังไม่ได้ถูกถอน ความสวยงามของพิสูจน์ทศนิยมศูนย์คือพวกเขาสงวนความเป็นส่วนตัว สาธารณะทราบเพียงว่าผู้ถอนเงินได้ทำการฝากเงินแต่ไม่สามารถระบุตัวตนของพวกเขาได้
เพื่อพิสูจน์ว่า “ฉันฝากในสระ Tornado” สามารถแปลเป็น “บันทึกการฝากของฉันสามารถพบได้ในสัญญา Tornado” หาก Cn หมายถึง บันทึกการฝาก แล้วหากให้เซ็ตบันทึกการฝากของ Tornado เป็น {C1, C2,…C100…} แล้ว Bob ต้องพิสูจน์ว่าเขาใช้กุญแจส่วนตัวเพื่อสร้างบันทึกในเซ็ตนี้โดยไม่เปิดเผยว่า Cn ที่เฉพาะเจาะจงคือ Cn ไหน ซึ่งใช้ประโยชน์จากคุณสมบัติที่ไม่ซ้ำกันของ Merkle Proof
บันทึกการฝากของ Tornado ทั้งหมดถูกรวมรวบรวมเข้าไปในต้นไม้ Merkle ที่สร้างขึ้นบนเชน ส่วนใหญ่ของใบเหลียมเหล่านี้ (ประมาณ 2^20, มากกว่า 1 ล้าน) ยังคงว่างเปล่า (ด้วยค่าเริ่มต้น) การฝากใหม่แต่ละรายการจะอัปเดตใบการสนธิแอคทีฟที่สอดคล้องกันและจากนั้นรากของต้นไม้
ตัวอย่างเช่น หากการฝากของบ็อบเป็นการฝากครั้งที่ 10,000 ในประวัติของ Tornado ค่าที่เกี่ยวข้อง Cn จะเป็นใบที่ 10,000 ของต้นไม้ นั่นคือ C10000 = Cn สัญญาจะคำนวณ Root ใหม่โดยอัตโนมัติ
(ภาพที่มา: RareSkills)
Merkle Proof มีความกระชับและมีประสิทธิภาพ เพื่อพิสูจน์ว่าธุรกรรม TD มีอยู่ใน Merkle Tree จะต้องให้ Merkle Proof ที่เกี่ยวข้องซึ่งยังคงกระชับแม้ว่า Merkle Tree จะกว้างใหญ่
เพื่อตรวจสอบว่าธุรกรรม เช่น H3 ได้รวมอยู่ใน Merkle Tree จริง ๆ ผู้ใดต้องพิสูจน์ว่าโดยใช้ H3 และข้อมูลอื่น ๆ จาก Merkle Tree สามารถสร้าง Root ได้ ข้อมูลนี้ (รวมถึง Td) ประกอบด้วย Merkle Proof ขณะที่บ็อบต้องการถอนเงินเขาต้องตรวจสอบสองสิ่ง:
·Cn อยู่ในต้นไม้ Merkle ที่สร้างขึ้นบนเชื่อมโยงโดย Tornado ซึ่งเขาสามารถสร้างพิสูจน์ Merkle ที่มี Cn
·Cn เกี่ยวข้องกับใบฝากของบ็อบ
ในโค้ดฝั่งหน้าของอินเตอร์เฟซของ Tornado มีการทำฟังก์ชันหลายอย่างไว้ล่วงหน้า เมื่อผู้ฝากเปิดหน้าเว็บ Tornado Cash และคลิกที่ปุ่มฝาก โค้ดฝั่งหน้าที่แนบมาจะสร้างตัวเลขสุ่มสองตัวคือ K และ r ขึ้นที่เครื่องเครง จากนั้นจึงคำนวณค่า Cn=Hash(K, r) โดยส่ง Cn (ที่เรียกว่าคอมมิตเมนต์ในแผนภาพด้านล่าง) เข้าสู่สัญญา Tornado เพื่อรวมเข้าใน Merkle Tree โดยง่ายๆ แล้ว K และ r ทำหน้าที่เหมือนกุญแจส่วนตัว พวกเขาสำคัญและผู้ใช้ควรเก็บรักษาไว้อย่างปลอดภัย เนื่องจากจะถูกต้องใช้ใหม่อีกครั้งในขั้นตอนการถอนเงิน
"encryptedNote" เป็นคุณสมบัติเสริมที่ช่วยให้ผู้ใช้สามารถเข้ารหัสข้อมูลประจําตัว K และ r ด้วยคีย์ส่วนตัวและเก็บไว้ในห่วงโซ่เพื่อป้องกันการลืม
ควรระวังว่าทุกการดำเนินการข้างต้นเกิดขึ้นนอกเชื่อมต่อ ซึ่งหมายความว่าทั้งสัญญา Tornado และผู้สังเกตแบบภายนอกไม่รู้จัก K และ r หาก K และ r ถูกเปิดเผย มันเหมือนกับการถูกขโมยกุญแจส่วนตัวของกระเป๋าเงิน
เมื่อได้รับเงินฝากของผู้ใช้และคํานวณ Cn = Hash (K, r) สัญญา Tornado จะวาง Cn ไว้ที่ระดับฐานของ Merkle Tree เปลี่ยนเป็นโหนดใบใหม่และอัปเดตค่าของรากในภายหลัง อย่างไรก็ตาม สิ่งสําคัญคือต้องเข้าใจว่าใบของ Merkle Tree นี้ไม่ได้ถูกบันทึกไว้ในสถานะของสัญญา แต่จะถูกบันทึกเป็นพารามิเตอร์เหตุการณ์ในบล็อกที่ผ่านมาเท่านั้น สัญญาทอร์นาโดบันทึกเฉพาะรากเมอร์เคิลเท่านั้น ในระหว่างการถอนเงินผู้ใช้สามารถพิสูจน์ผ่าน Merkle Proof ว่าบันทึกการฝากเงินสอดคล้องกับรากของ Merkle ในปัจจุบันซึ่งเป็นแนวคิดที่ค่อนข้างคล้ายกับการถอนสะพานข้ามสายโซ่ของลูกค้าเบา การออกแบบนี้แสดงให้เห็นถึงความเฉลียวฉลาดของ Tornado: เพื่อประหยัดค่าก๊าซต้นไม้ Merkle เต็มรูปแบบไม่ได้ถูกบันทึกไว้ในสถานะของสัญญามีเพียงรากของมันเท่านั้น ใบของต้นไม้ถูกบันทึกไว้ในบันทึกบล็อกประวัติศาสตร์ซึ่งเป็นกลไกที่ค่อนข้างคล้ายกับหลักการประหยัดก๊าซของ Rollup (แม้ว่ารายละเอียดจะแตกต่างกัน)
ในขั้นตอนการถอนเงิน ผู้ถอนจะกรอกข้อมูลประจำตัว/กุญแจส่วนตัว (หมายเลขสุ่ม K และ r ที่สร้างขึ้นระหว่างการฝาก) บนหน้าเว็บไซต์ด้านหน้า รหัสหน้าตา Tornado Cash ใช้ K และ r Cn=Hash(K, r) และ Merkle Proof ที่สอดคล้องกับ Cn เพื่อสร้าง ZK Proof ซึ่งยืนยันว่า Cn สอดคล้องกับบันทึกการฝากบนต้นไม้ Merkle และ K และ r เป็นข้อมูลประจำตัวที่ถูกต้องสำหรับ Cn ขั้นตอนนี้หลักฐานให้เห็นว่ามีความรู้เกี่ยวกับคีย์บันทึกการฝากบนต้นไม้ Merkle เมื่อ ZK Proof ถูกส่งให้สัญญา Tornado ทุกพารามิเตอร์ 4 ตัวจะถูกปกปิดเพื่อให้ผู้ต่างชาติรวมถึงสัญญา Tornado เองไม่รู้ต่าง ซึ่งนั้นเสราคุ้มครองความเป็นส่วนตัวของผู้ใช้
รายละเอียดที่น่าสนใจคือการดำเนินการฝากใช้หมายเลขสุ่มสองตัว คือ K และ r เพื่อสร้าง Cn แทนการใช้หมายเลขสุ่มตัวเดียวเพราะหมายเลขสุ่มตัวเดียวอาจไม่มีความปลอดภัยเพียงพอและอาจถูกบังคับใช้โดยบังคับ
เกี่ยวกับสัญลักษณ์ “A” ในภาพประกอบ มันแทนที่อยู่ที่ได้รับการถอนและถูกให้โดยผู้ถอน ในขณะเดียวกัน “nf” เป็นตัวระบุที่ถูกตั้งขึ้นเพื่อป้องกันการโจมตีที่เล่นซ้ำ ค่าของมันถูกกำหนดเป็น nf=Hash(K) ที่ K เป็นหนึ่งในจำนวนสองตัวเลขสุ่ม (K และ r) ที่ใช้ในขณะฝากเงินเพื่อสร้าง Cn ดังนั้น แต่ละ Cn มี nf ที่สอดคล้องกัน และทั้งสองตัวเป็นที่เชื่อมโยงอย่างไม่ซ้ำกัน
ทำไมต้องป้องกันการโจมตีแบบซ้ำซ้อน? เนื่องจากลักษณะการออกแบบของตัวผสม ในขณะที่ถอนเงิน ไม่ชัดเจนว่าฝากเงินใดใน Merkle Tree สอดคล้องกับเงินที่ถอน โดยการเชื่อมต่อระหว่างผู้ฝากเงินและจำนวนเงินที่ถอนยังคงมัวแหลก ผู้ใช้ที่มีความผิดตัวอาจใช้ช่องโหว่นี้และถอนเงินอย่างต่อเนื่องจากตัวผสม ซึ่งทำให้เหลือเพียงส่วนเล็กน้อยของโทเค็นในพูล
ที่นี่ตัวระบุ nf ทำหน้าที่เช่นเดียวกับตัวนับธุรกรรม "nonce" ที่เชื่อมโยงกับทุกที่อยู่ Ethereum เพื่อป้องกันการทำรายการซ้ำ ในการขอถอนเงิน ผู้ใช้ต้องส่ง nf ระบบจะตรวจสอบว่า nf นี้เคยถูกใช้ไปหรือยัง หากถูกใช้แล้วการถอนเงินจะถูกยกเลิก ถ้ายังไม่เคยถูกใช้ถอนเงินจะดำเนินไป และ nf จะถูกบันทึกเพื่อให้มั่นใจว่าการใช้ภายหลังจะทำให้ถูกยกเลิก
บางคนอาจสงสัย: ใครสามารถปลอมแปลง nf ที่สัญญายังไม่ได้บันทึกไว้? นั่นเป็นสิ่งที่น่าจะไม่เป็นไปได้ ระหว่างกระบวนการสร้าง ZK Proof มันเป็นสิ่งสำคัญที่จะให้แน่ใจว่า nf=Hash(K) และตัวเลขสุ่ม K เชื่อมโยงกับบันทึกเงินฝาก Cn ถ้ามีใครสร้าง nf อย่างสุ่มสามารถ มันจะไม่ตรงกับการฝากเงินที่ถูกบันทึกไว้ ทำให้กระบวนการสร้าง ZK Proof ที่ถูกต้องเป็นไปไม่ได้ จนกระทั้งทำให้กระบวนการถอนเงินไม่สามารถดำเนินไปได้
บางคนอาจสงสัย: มีวิธีหนึ่งๆ ที่สามารถทำได้อีกไหมโดยไม่ต้องใช้ nf โดยการถอนจะต้องส่ง ZK Proof ซึ่งยืนยันความเชื่อมโยงของพวกเขากับ Cn ที่เฉพาะเจาะจง จะไม่มีปัญหาหรือไม่ถ้าเราตรวจสอบว่า ZK Proof ที่เกี่ยวข้องถูกบันทึกอยู่ในเครือข่ายอยู่แล้วหรือไม่? อย่างไรก็ตามค่าใช้จ่ายที่เกี่ยวข้องกับวิธีการเช่นนี้มีมูลค่ามากเนื่องจากสัญญา Tornado Cash ไม่เก็บ ZK Proofs ที่ส่งมาก่อนอย่างต่อเนื่องเพื่อหลีกเลี่ยงการสูญเสียพื้นที่จัดเก็บ การเปรียบเทียบ ZK Proof ใหม่ทุกๆ รายการกับที่มีเพื่อให้แน่ใจว่าเหมือนกันเป็นการใช้ทรัพยากรมากกว่าการบันทึกตัวระบุอย่างกระชับเช่น nf
ตามตัวอย่างโค้ดฟังก์ชันการถอน พารามิเตอร์ที่จำเป็นและตรรกะธุรกิจคือ ผู้ใช้ส่ง ZK Proof, nf (NullifierHash) = Hash(K), และกำหนดที่อยู่ผู้รายไว้สำหรับการถอนเงิน ZK Proof ซ่อนค่าของ Cn, K, และ r ทำให้โลกภายนอกไม่สามารถระบุตัวตนของผู้ใช้ได้ โดยทั่วไปแล้วผู้รับจะระบุที่อยู่ใหม่ที่สะอาดเพื่อป้องกันการเปิดเผยข้อมูลส่วนตัว
อย่างไรก็ตาม มีความท้าทายเล็ก ๆ น้อย ๆ ที่เกิดขึ้น: เมื่อผู้ใช้ถอนเงิน เพื่อความไม่สามารถติดตาม พวกเขามักใช้ที่อยู่ที่สร้างขึ้นใหม่เพื่อเริ่มต้นธุรกรรมการถอนเงิน ในเวลาเช่นนั้น ที่อยู่ใหม่เหล่านี้ขาด ETH เพื่อครอบคลุมค่าธรรมเนียมการเผาก๊าส ดังนั้น ระหว่างการถอนเงิน ที่อยู่ต้องประกาศเรียกรับเก็บเงินเผาก๊าสโดยชัดเจน ต่อมา สัญญาผสมผสานลดส่วนหนึ่งจากการถอนของผู้ใช้เพื่อชดเชยผู้เรียกรับเงิน
สรุปได้ว่า Tornado Cash สามารถปิดบังการเชื่อมต่อระหว่างผู้ฝากและผู้ถอนเงินได้ เมื่อมีฐานผู้ใช้ขนาดใหญ่ก็คล้ายกับอาชญากรที่ผสมผสานเข้ากับฝูงชนที่พลุกพล่านทําให้เจ้าหน้าที่ติดตามได้ยาก กระบวนการถอนเงินใช้ ZK-SNARK โดยมีส่วน "พยาน" ที่ปกปิดไว้ซึ่งมีข้อมูลสําคัญเกี่ยวกับผู้ถอน นี่เป็นคุณสมบัติที่สําคัญที่สุดของมิกเซอร์ ปัจจุบัน Tornado อาจเป็นหนึ่งในแอปพลิเคชั่นที่ฉลาดที่สุดที่เกี่ยวข้องกับ ZK
บทนำ:
เร็ว ๆ นี้ วิทาลิคและนักวิชาการหลายคนได้ร่วมกันเผยแพร่บทความใหม่ซึ่งสัมผัสถึงวิธีการ Tornado Cash ใช้แผนการป้องกันการฟอกเงินของตน (ซึ่งทำให้ผู้ถอนสามารถพิสูจน์ได้ว่าประวัติการฝากของพวกเขาเป็นส่วนหนึ่งของเซ็ตที่ไม่รวมเงินที่ได้รับมลพิษ) อย่างไรก็ตาม บทความนั้นขาดการอธิบายเนื้อหาทางธุรกิจและหลักการของ Tornado Cash ที่ซับซ้อน ซึ่งส่งผลให้บางผู้อ่านเข้าใจเพียงอย่างพื้นผิวเท่านั้น
ควรทราบว่าโครงการเช่น Tornado ซึ่งเป็นผลิตภัณฑ์ที่เน้นความเป็นส่วนตัวใช้ประโยชน์จากด้านการรู้เพียงของอัลกอริทึม ZK-SNARK อย่างแท้จริง ในขณะเดียวกัน โซลูชันส่วนใหญ่ที่เสนอแบรนด์ ZK เช่น Rollups เพียงแค่ใช้ความกระชับของ ZK-SNARK เท่านั้น บ่อยครั้ง ผู้คนมักสับสน Proof ความถูกต้องกับ ZK และ Tornado เป็นตัวอย่างที่ยอดเยี่ยมที่ช่วยอธิบายการใช้งานในโลกแห่งความจริงของ ZK ได้อย่างชัดเจน
ผู้เขียนบทความนี้ได้เขียนบทความเกี่ยวกับหลักการของพายฤษีในปี 2022 สำหรับการวิจัย Web3Caff วันนี้เราได้แยกและขยายของส่วนบางของงานเดิมนั้นเพื่อให้เข้าใจได้อย่างเป็นระบบเกี่ยวกับ Tornado Cash
ลิงก์บทความเดิม:https://research.web3caff.com/th/archives/2663?ref=157
Tornado Cash ใช้ zero-knowledge proof เป็นโปรโตคอลในการผสมข้อมูล ในขณะที่เวอร์ชันเก่าถูกเปิดตัวในปี 2019 เวอร์ชันเบต้าของโมเดลที่อัปเดตเปิดตัวในปลายปี 2021 เวอร์ชันก่อนหน้าของ Tornado สามารถบรรลุระดับความกระจายที่ดีด้วยสัญญา on-chain ที่เปิดเป็นโค้ดฟรีและปลอดภัยจากการควบคุมด้วยลายมือหลายรายการ อย่างไรก็ตาม โค้ด frontend เปิดเป็นโค้ดฟรีและถูกสำรองข้อมูลบนเครือข่าย IPFS เนื่องจากความง่ายของเวอร์ชัน Tornado เวอร์ชันเก่านี้ บทความนี้เน้นอธิบายมัน
วิธีการหลักของ Tornado คือการผสมการทำธุรกรรมการฝากและการถอนหลายรายการรวมกัน หลังจากฝากโทเค็นเข้าสู่ Tornado ผู้ฝากจะนำ ZK Proof มายืนยันการฝากก่อนหน้าและจากนั้นถอนโดยใช้ที่อยู่ใหม่ ซึ่งทำให้ไม่สามารถติดตามความเชื่อมโยงระหว่างที่อยู่การฝากและการถอน
ให้นึกถึง Tornado ในรูปแบบที่กระชับกว่าว่าเป็นกล่องแก้วที่เต็มไปด้วยเหรียญ (เหรียญ) ซึ่งถูกฝากโดยบุคคลหลายคน เราสามารถเห็นว่าใครฝากเหรียญไว้ แต่เหรียญเหล่านี้มีคุณสมบัติที่เหมือนกันมาก หากมีคนที่ไม่รู้จักมาเอาเหรียญจากกล่อง เราจะพบว่ายากที่จะติดตามว่าใครกำหนดให้เหรียญนั้นไว้
(ภาพที่มา: rareskills)
สถานการณ์ดังกล่าวดูเหมือนเป็นเรื่องธรรมดา เมื่อเรา SWAP ETHs สองสามรายการจากพูล Uniswap เป็นไปไม่ได้ที่จะระบุว่าเราได้รับ ETH ของใครเนื่องจากผู้ให้บริการสภาพคล่องจํานวนมากให้กับ Uniswap อย่างไรก็ตามความแตกต่างอยู่ในกระบวนการ ด้วย Uniswap การแลกเปลี่ยนโทเค็นต้องใช้โทเค็นอื่นเป็นมูลค่าเทียบเท่าและไม่สามารถโอนเงิน "ส่วนตัว" ได้ ในทางตรงกันข้ามเครื่องผสมเพียงแค่ต้องการให้ผู้ถอนเงินแสดงใบเสร็จรับเงินมัดจํา
เพื่อให้การทำฝากเงินและถอนเงินดูเหมือนเป็นสิ่งเดียวกัน สระว่ายน้ำ Tornado รักษาความสม่ำเสมอในการฝากเงินและถอนเงิน ตัวอย่างเช่น หากมีผู้ฝากเงิน 100 คนและผู้ถอนเงิน 100 คน แม้ว่าการกระทำจะเป็นสาธารณะ แต่ดูเหมือนว่าไม่มีความสัมพันธ์กัน ทุกคนฝากเงินและถอนเงินในจำนวนเงินเท่ากัน ทำให้ยากต่อการติดตามการเคลื่อนไหวของเงิน ดังนั้น มันเป็นประโยชน์ที่เกิดขึ้นอย่างรู้เท่าใจสำหรับการฟอกเงิน
คำถามสำคัญเกิดขึ้น: เมื่อถอนเงิน จะต้องพิสูจน์การฝากล่วงหน้าอย่างไร? ที่อยู่ที่เริ่มต้นการถอนเงินไม่ได้เชื่อมโยงกับที่อยู่ของการฝากเงินใด จึงต้องการให้ใครบางคนรับรองสิทธิในการถอนเงินได้อย่างไร? วิธีที่เป็นที่ตรงไปตรงมาสุดคือการให้ผู้ถอนเงินเปิดเผยบันทึกการฝากเงินของตน แต่นั้นจะเปิดเผยตัวตนของพวกเขา นี่คือจุดที่ zero-knowledge proofs เข้ามาเล่นบทบาท
ด้วย ZK Proof, ผู้ถอนเงินสามารถยืนยันได้ว่าพวกเขามีบัญชีฝากเงินในสัญญาพายุฝุ่น และว่าการฝากเงินนี้ยังไม่ได้ถูกถอน ความสวยงามของพิสูจน์ทศนิยมศูนย์คือพวกเขาสงวนความเป็นส่วนตัว สาธารณะทราบเพียงว่าผู้ถอนเงินได้ทำการฝากเงินแต่ไม่สามารถระบุตัวตนของพวกเขาได้
เพื่อพิสูจน์ว่า “ฉันฝากในสระ Tornado” สามารถแปลเป็น “บันทึกการฝากของฉันสามารถพบได้ในสัญญา Tornado” หาก Cn หมายถึง บันทึกการฝาก แล้วหากให้เซ็ตบันทึกการฝากของ Tornado เป็น {C1, C2,…C100…} แล้ว Bob ต้องพิสูจน์ว่าเขาใช้กุญแจส่วนตัวเพื่อสร้างบันทึกในเซ็ตนี้โดยไม่เปิดเผยว่า Cn ที่เฉพาะเจาะจงคือ Cn ไหน ซึ่งใช้ประโยชน์จากคุณสมบัติที่ไม่ซ้ำกันของ Merkle Proof
บันทึกการฝากของ Tornado ทั้งหมดถูกรวมรวบรวมเข้าไปในต้นไม้ Merkle ที่สร้างขึ้นบนเชน ส่วนใหญ่ของใบเหลียมเหล่านี้ (ประมาณ 2^20, มากกว่า 1 ล้าน) ยังคงว่างเปล่า (ด้วยค่าเริ่มต้น) การฝากใหม่แต่ละรายการจะอัปเดตใบการสนธิแอคทีฟที่สอดคล้องกันและจากนั้นรากของต้นไม้
ตัวอย่างเช่น หากการฝากของบ็อบเป็นการฝากครั้งที่ 10,000 ในประวัติของ Tornado ค่าที่เกี่ยวข้อง Cn จะเป็นใบที่ 10,000 ของต้นไม้ นั่นคือ C10000 = Cn สัญญาจะคำนวณ Root ใหม่โดยอัตโนมัติ
(ภาพที่มา: RareSkills)
Merkle Proof มีความกระชับและมีประสิทธิภาพ เพื่อพิสูจน์ว่าธุรกรรม TD มีอยู่ใน Merkle Tree จะต้องให้ Merkle Proof ที่เกี่ยวข้องซึ่งยังคงกระชับแม้ว่า Merkle Tree จะกว้างใหญ่
เพื่อตรวจสอบว่าธุรกรรม เช่น H3 ได้รวมอยู่ใน Merkle Tree จริง ๆ ผู้ใดต้องพิสูจน์ว่าโดยใช้ H3 และข้อมูลอื่น ๆ จาก Merkle Tree สามารถสร้าง Root ได้ ข้อมูลนี้ (รวมถึง Td) ประกอบด้วย Merkle Proof ขณะที่บ็อบต้องการถอนเงินเขาต้องตรวจสอบสองสิ่ง:
·Cn อยู่ในต้นไม้ Merkle ที่สร้างขึ้นบนเชื่อมโยงโดย Tornado ซึ่งเขาสามารถสร้างพิสูจน์ Merkle ที่มี Cn
·Cn เกี่ยวข้องกับใบฝากของบ็อบ
ในโค้ดฝั่งหน้าของอินเตอร์เฟซของ Tornado มีการทำฟังก์ชันหลายอย่างไว้ล่วงหน้า เมื่อผู้ฝากเปิดหน้าเว็บ Tornado Cash และคลิกที่ปุ่มฝาก โค้ดฝั่งหน้าที่แนบมาจะสร้างตัวเลขสุ่มสองตัวคือ K และ r ขึ้นที่เครื่องเครง จากนั้นจึงคำนวณค่า Cn=Hash(K, r) โดยส่ง Cn (ที่เรียกว่าคอมมิตเมนต์ในแผนภาพด้านล่าง) เข้าสู่สัญญา Tornado เพื่อรวมเข้าใน Merkle Tree โดยง่ายๆ แล้ว K และ r ทำหน้าที่เหมือนกุญแจส่วนตัว พวกเขาสำคัญและผู้ใช้ควรเก็บรักษาไว้อย่างปลอดภัย เนื่องจากจะถูกต้องใช้ใหม่อีกครั้งในขั้นตอนการถอนเงิน
"encryptedNote" เป็นคุณสมบัติเสริมที่ช่วยให้ผู้ใช้สามารถเข้ารหัสข้อมูลประจําตัว K และ r ด้วยคีย์ส่วนตัวและเก็บไว้ในห่วงโซ่เพื่อป้องกันการลืม
ควรระวังว่าทุกการดำเนินการข้างต้นเกิดขึ้นนอกเชื่อมต่อ ซึ่งหมายความว่าทั้งสัญญา Tornado และผู้สังเกตแบบภายนอกไม่รู้จัก K และ r หาก K และ r ถูกเปิดเผย มันเหมือนกับการถูกขโมยกุญแจส่วนตัวของกระเป๋าเงิน
เมื่อได้รับเงินฝากของผู้ใช้และคํานวณ Cn = Hash (K, r) สัญญา Tornado จะวาง Cn ไว้ที่ระดับฐานของ Merkle Tree เปลี่ยนเป็นโหนดใบใหม่และอัปเดตค่าของรากในภายหลัง อย่างไรก็ตาม สิ่งสําคัญคือต้องเข้าใจว่าใบของ Merkle Tree นี้ไม่ได้ถูกบันทึกไว้ในสถานะของสัญญา แต่จะถูกบันทึกเป็นพารามิเตอร์เหตุการณ์ในบล็อกที่ผ่านมาเท่านั้น สัญญาทอร์นาโดบันทึกเฉพาะรากเมอร์เคิลเท่านั้น ในระหว่างการถอนเงินผู้ใช้สามารถพิสูจน์ผ่าน Merkle Proof ว่าบันทึกการฝากเงินสอดคล้องกับรากของ Merkle ในปัจจุบันซึ่งเป็นแนวคิดที่ค่อนข้างคล้ายกับการถอนสะพานข้ามสายโซ่ของลูกค้าเบา การออกแบบนี้แสดงให้เห็นถึงความเฉลียวฉลาดของ Tornado: เพื่อประหยัดค่าก๊าซต้นไม้ Merkle เต็มรูปแบบไม่ได้ถูกบันทึกไว้ในสถานะของสัญญามีเพียงรากของมันเท่านั้น ใบของต้นไม้ถูกบันทึกไว้ในบันทึกบล็อกประวัติศาสตร์ซึ่งเป็นกลไกที่ค่อนข้างคล้ายกับหลักการประหยัดก๊าซของ Rollup (แม้ว่ารายละเอียดจะแตกต่างกัน)
ในขั้นตอนการถอนเงิน ผู้ถอนจะกรอกข้อมูลประจำตัว/กุญแจส่วนตัว (หมายเลขสุ่ม K และ r ที่สร้างขึ้นระหว่างการฝาก) บนหน้าเว็บไซต์ด้านหน้า รหัสหน้าตา Tornado Cash ใช้ K และ r Cn=Hash(K, r) และ Merkle Proof ที่สอดคล้องกับ Cn เพื่อสร้าง ZK Proof ซึ่งยืนยันว่า Cn สอดคล้องกับบันทึกการฝากบนต้นไม้ Merkle และ K และ r เป็นข้อมูลประจำตัวที่ถูกต้องสำหรับ Cn ขั้นตอนนี้หลักฐานให้เห็นว่ามีความรู้เกี่ยวกับคีย์บันทึกการฝากบนต้นไม้ Merkle เมื่อ ZK Proof ถูกส่งให้สัญญา Tornado ทุกพารามิเตอร์ 4 ตัวจะถูกปกปิดเพื่อให้ผู้ต่างชาติรวมถึงสัญญา Tornado เองไม่รู้ต่าง ซึ่งนั้นเสราคุ้มครองความเป็นส่วนตัวของผู้ใช้
รายละเอียดที่น่าสนใจคือการดำเนินการฝากใช้หมายเลขสุ่มสองตัว คือ K และ r เพื่อสร้าง Cn แทนการใช้หมายเลขสุ่มตัวเดียวเพราะหมายเลขสุ่มตัวเดียวอาจไม่มีความปลอดภัยเพียงพอและอาจถูกบังคับใช้โดยบังคับ
เกี่ยวกับสัญลักษณ์ “A” ในภาพประกอบ มันแทนที่อยู่ที่ได้รับการถอนและถูกให้โดยผู้ถอน ในขณะเดียวกัน “nf” เป็นตัวระบุที่ถูกตั้งขึ้นเพื่อป้องกันการโจมตีที่เล่นซ้ำ ค่าของมันถูกกำหนดเป็น nf=Hash(K) ที่ K เป็นหนึ่งในจำนวนสองตัวเลขสุ่ม (K และ r) ที่ใช้ในขณะฝากเงินเพื่อสร้าง Cn ดังนั้น แต่ละ Cn มี nf ที่สอดคล้องกัน และทั้งสองตัวเป็นที่เชื่อมโยงอย่างไม่ซ้ำกัน
ทำไมต้องป้องกันการโจมตีแบบซ้ำซ้อน? เนื่องจากลักษณะการออกแบบของตัวผสม ในขณะที่ถอนเงิน ไม่ชัดเจนว่าฝากเงินใดใน Merkle Tree สอดคล้องกับเงินที่ถอน โดยการเชื่อมต่อระหว่างผู้ฝากเงินและจำนวนเงินที่ถอนยังคงมัวแหลก ผู้ใช้ที่มีความผิดตัวอาจใช้ช่องโหว่นี้และถอนเงินอย่างต่อเนื่องจากตัวผสม ซึ่งทำให้เหลือเพียงส่วนเล็กน้อยของโทเค็นในพูล
ที่นี่ตัวระบุ nf ทำหน้าที่เช่นเดียวกับตัวนับธุรกรรม "nonce" ที่เชื่อมโยงกับทุกที่อยู่ Ethereum เพื่อป้องกันการทำรายการซ้ำ ในการขอถอนเงิน ผู้ใช้ต้องส่ง nf ระบบจะตรวจสอบว่า nf นี้เคยถูกใช้ไปหรือยัง หากถูกใช้แล้วการถอนเงินจะถูกยกเลิก ถ้ายังไม่เคยถูกใช้ถอนเงินจะดำเนินไป และ nf จะถูกบันทึกเพื่อให้มั่นใจว่าการใช้ภายหลังจะทำให้ถูกยกเลิก
บางคนอาจสงสัย: ใครสามารถปลอมแปลง nf ที่สัญญายังไม่ได้บันทึกไว้? นั่นเป็นสิ่งที่น่าจะไม่เป็นไปได้ ระหว่างกระบวนการสร้าง ZK Proof มันเป็นสิ่งสำคัญที่จะให้แน่ใจว่า nf=Hash(K) และตัวเลขสุ่ม K เชื่อมโยงกับบันทึกเงินฝาก Cn ถ้ามีใครสร้าง nf อย่างสุ่มสามารถ มันจะไม่ตรงกับการฝากเงินที่ถูกบันทึกไว้ ทำให้กระบวนการสร้าง ZK Proof ที่ถูกต้องเป็นไปไม่ได้ จนกระทั้งทำให้กระบวนการถอนเงินไม่สามารถดำเนินไปได้
บางคนอาจสงสัย: มีวิธีหนึ่งๆ ที่สามารถทำได้อีกไหมโดยไม่ต้องใช้ nf โดยการถอนจะต้องส่ง ZK Proof ซึ่งยืนยันความเชื่อมโยงของพวกเขากับ Cn ที่เฉพาะเจาะจง จะไม่มีปัญหาหรือไม่ถ้าเราตรวจสอบว่า ZK Proof ที่เกี่ยวข้องถูกบันทึกอยู่ในเครือข่ายอยู่แล้วหรือไม่? อย่างไรก็ตามค่าใช้จ่ายที่เกี่ยวข้องกับวิธีการเช่นนี้มีมูลค่ามากเนื่องจากสัญญา Tornado Cash ไม่เก็บ ZK Proofs ที่ส่งมาก่อนอย่างต่อเนื่องเพื่อหลีกเลี่ยงการสูญเสียพื้นที่จัดเก็บ การเปรียบเทียบ ZK Proof ใหม่ทุกๆ รายการกับที่มีเพื่อให้แน่ใจว่าเหมือนกันเป็นการใช้ทรัพยากรมากกว่าการบันทึกตัวระบุอย่างกระชับเช่น nf
ตามตัวอย่างโค้ดฟังก์ชันการถอน พารามิเตอร์ที่จำเป็นและตรรกะธุรกิจคือ ผู้ใช้ส่ง ZK Proof, nf (NullifierHash) = Hash(K), และกำหนดที่อยู่ผู้รายไว้สำหรับการถอนเงิน ZK Proof ซ่อนค่าของ Cn, K, และ r ทำให้โลกภายนอกไม่สามารถระบุตัวตนของผู้ใช้ได้ โดยทั่วไปแล้วผู้รับจะระบุที่อยู่ใหม่ที่สะอาดเพื่อป้องกันการเปิดเผยข้อมูลส่วนตัว
อย่างไรก็ตาม มีความท้าทายเล็ก ๆ น้อย ๆ ที่เกิดขึ้น: เมื่อผู้ใช้ถอนเงิน เพื่อความไม่สามารถติดตาม พวกเขามักใช้ที่อยู่ที่สร้างขึ้นใหม่เพื่อเริ่มต้นธุรกรรมการถอนเงิน ในเวลาเช่นนั้น ที่อยู่ใหม่เหล่านี้ขาด ETH เพื่อครอบคลุมค่าธรรมเนียมการเผาก๊าส ดังนั้น ระหว่างการถอนเงิน ที่อยู่ต้องประกาศเรียกรับเก็บเงินเผาก๊าสโดยชัดเจน ต่อมา สัญญาผสมผสานลดส่วนหนึ่งจากการถอนของผู้ใช้เพื่อชดเชยผู้เรียกรับเงิน
สรุปได้ว่า Tornado Cash สามารถปิดบังการเชื่อมต่อระหว่างผู้ฝากและผู้ถอนเงินได้ เมื่อมีฐานผู้ใช้ขนาดใหญ่ก็คล้ายกับอาชญากรที่ผสมผสานเข้ากับฝูงชนที่พลุกพล่านทําให้เจ้าหน้าที่ติดตามได้ยาก กระบวนการถอนเงินใช้ ZK-SNARK โดยมีส่วน "พยาน" ที่ปกปิดไว้ซึ่งมีข้อมูลสําคัญเกี่ยวกับผู้ถอน นี่เป็นคุณสมบัติที่สําคัญที่สุดของมิกเซอร์ ปัจจุบัน Tornado อาจเป็นหนึ่งในแอปพลิเคชั่นที่ฉลาดที่สุดที่เกี่ยวข้องกับ ZK