
لقد طبقنا نموذجًا أوليًا للمعاملات مجهولة المصدر استنادًا إلى zkSNARK لضمان المعاملات السرية على Waves blockchain. في تطبيقنا ، نستخدم نظام الأدلة Groth16 على منحنى BN254 و DSL circom .
نفسر كيف يعمل.
zkSNARKs
zkSNARK هو بدائي تشفير يؤكد معرفة مجموعة (أدلة) بيانات خاصة تتوافق مع مجموعة المعادلات التالية (نظام القيد):
⟨ai,w⟩⟨bi,w⟩+⟨ci,w⟩=0
جزء من الأدلة خاص. يسمح لنا هذا البناء بإثبات ، على سبيل المثال ، معرفة صورة معكوس التجزئة دون الكشف عن الصورة العكسية. يمكن استخدامه أيضًا في آلية المعاملة الخاصة لطراز UTXO ( مخرجات المعاملة غير المنفقة (TX)) ، حيث يتم نشر تجزئة UTXO فقط ، وتثبت صحة المعاملة داخل zkSNARK (إثبات الملكية ، إثبات توفير المبلغ).
zkSNARK هي تقنية غير تفاعلية للإفصاح الصفري ، وهذا لا يعني وجود بروتوكول للتفاعل بين المشاركين يتم تطبيقه لإثبات المعرفة. في تقنية zkSNARK ، يبني prover الدليل ويرسله إلى Prover - لا يلزم تفاعلات إضافية. يمكن للفاحص التحقق من صحة وصحة استخدام بيانات الأدلة دون اللجوء إلى معلومات إضافية. في البداية ، تم إنشاء zkSNARKs كبروتوكول "للحوسبة السرية": عند حساب النتيجة ، لا يتم الكشف عن البيانات المشاركة في العمليات الحسابية.
باستخدام تقنية zkSNARK ، يمكن تنفيذ مخطط للكشف عن الالتزام: يقوم المحتسب بحساب التجزئة ويعطيها للمصدر ويقدم دليلًا خاصًا على أنه يعرف الصورة العكسية للتجزئة x. عن طريق استبدال قيم x والتجزئة في الصيغة ، وتمرير هذه الصيغة والإثبات إلى المدقق ، يمكن أن يتحقق المدقق من معرفة الموحد x. هذا هو أساس المعاملات المجهولة: نحن نعرف المفتاح الخاص وبعض المدخلات المحددة (UTXO غير المنفقة) مع مبلغ محدد أنشأه المستخدم بموجب العقد الذكي. دون الكشف عن هذه البيانات ، يمكن للمستخدم أن يؤكد بعقد ذكي أن هذا هو مدخلاته ، وأنه يمكن أن يتخلص منها ويعطيها لشخص ما للاستخدام.
الآن لا يتم استخدام التكنولوجيا في كل مكان ، لأنه يتم إنشاء الدليل لعدة دقائق ، وهو ليس مناسبًا جدًا للمستخدم.
تعرّف على المزيد حول برمجة zkSNARKs في مقالة Vitalik Buterin "البرامج الحسابية التربيعية: من الصفر إلى البطل" وفي مقالة Iden3 عن تصميم الدوائر circom.
نموذج الحساب
للمعاملات في Waves ، عادة ما يستخدمون المفاتيح والعناوين بناءً على curve25519
. هذا المنحنى ليس صديقًا لـ zkSNARK ، لذلك بالنسبة للمعاملات مجهولة الهوية ، نستخدم مجموعة Edwards الفرعية ذات المنحنيات الملتوية من BabyJubJub
. بالإضافة إلى ذلك ، نستخدم المفاتيح العامة كعناوين ، لأنه عند الإرسال ، تحتاج إلى تشفير البيانات للمستلم.
نموذج UTXO
في نموذجنا ، يتم تمثيل UTXO بمجموعة من 3 معلمات: التوازن والمفتاح العام للمالك والسرية الفريدة. يحتوي blockchain على تجزئات فقط دون تشفير إضافي. يتم تمثيل المالك بواسطة مفتاح عام ، وكما ذكرنا سابقًا ، لا نستخدم المفاتيح العامة على المنحنى curve25519
، ولكن على منحنى BabyJubJub
الصديق لـ BabyJubJub
. يجب إنشاء معرف UTXO بشكل عشوائي ، لأنه إذا حدد المستخدم معرفين متطابقين ، فيمكنه التقاط (إنفاق) UTXO على واحد منهم فقط. في هذه الحالة ، سيتم حظر UTXO فقط مع معرف المقابلة للمستخدم الحالي ، ولكن ليس للبقية. من مصلحة المستخدم اختيار المعرف باستخدام مولد الأرقام العشوائية (يتم تخصيص 253 بت على المعرف ، لذلك يصعب الحصول على تصادم).
لقضاء UTXO ، يجب عليك نشر nullifier ، وهي وظيفة حتمية لـ UTXO ، والمعروفة باسم hash (secret، owner_privkey). هذه القيمة حتمية وفريدة من نوعها لكل UTXO ؛ فقط المالك يعرفها. بصرف النظر عن المالك ، لا يمكن لأحد أن يربط UTXO مع nullifier المطابق.
يتم تخزين UTXOs داخل خريطة التجزئة dApp ، أي في نمط العقد. على blockchain ، يتم تشفير UTXOs. من أجل أن يأخذ أمواله ، يجب على المستخدم مسح blockchain ومحاولة فك تشفير كل UTXO.
الدولة dapp
يحتوي نمط dApp على خرائط تجزئة تمثل مجموعتين:
وبالتالي ، يمكن dApp التحقق من وجود مجموعة مجهولة UTXO وتفرد nullifiers. هذا يكفي لمعالجة التحويلات مجهولة المصدر مع الحماية ضد تزوير الأصول الجديدة ومضاعفة الإنفاق.
لدى DApp 3 طرق تتوافق مع الأنواع الأساسية للمعاملات:
لتحويل الأموال وسحبها ، نستخدم أدوات التحقق الخاصة بنا والتي تضمن تفاعل dApp مع حسابات مجهولة خاصة بناءً على منحنى BabyJubJub. تتم معالجة الودائع من حسابات الأمواج العادية.
لجنة
لتجديد الحساب ، يتم فرض رسوم من حساب curve25519
. بالنسبة لعمليات النقل والسحب ، يتم خصم العمولة من الحساب المجهول. على مستوى dApp ، يبدو كما يلي:
dApp يدفع للمعاملة نفسها ، أي الرمز المميز الذي ينفق على دفع العمولة يتم خصمه من رصيده
بين المداخل والمخارج ، يتم حرق جزء من العمولة لإلغاء الأصول المقابلة للأصول الحقيقية في العقد الذكي
على مستوى UTXO ، نحرق مبلغًا معينًا كعمولة عند معالجة معاملة.
المعاملات
عملية الإيداع عملية بسيطة ، حيث يضيف كل إيداع عنصرًا جديدًا إلى UTXO.

تعتمد التحويلات على الترجمة من 2 إلى 2.

بعض المدخلات والمخرجات قد تكون صفرا. كمثال جزئي على مثل هذا البناء ، يمكن تمثيل أي نوع من أنواع الترجمة البسيطة (الانضمام والانقسام والتحويلات الأخرى ، باستثناء المبادلات الذرية).
تعمل الاستنتاجات مثل المعاملات الأخرى ، فقط بدلاً من إنشاء UTXO الثاني ، فهي تتيح للمستخدم سحب UTXO من dApp. يمكن أن يكون هناك اثنين من UTXOs عند المدخلات ، UTXOs عند الخروج مع بقية الأموال والسحب ، والتي يتم نشرها على blockchain.

عند السحب أو النقل ، يتحقق dApp من أنه لم يتم العثور على القيم الخالية المقابلة في مكدسها.
باستخدام zkSNARK ، يمكننا حساب أن مجموع مدخلات المعاملات يساوي مجموع المخرجات. عند تنفيذ معاملة ، ننفقها على UTXO وبعض صفري UTXO ، وهو ليس في شجرة ميركل. لقضاء UTXO ، تحتاج إلى إثبات معرفة المفتاح الخاص لصاحبها. تحقق من أن المفتاح الخاص ، عند ضربه بمولد المجموعة ، ينتج عنه مفتاح عمومي. وفقًا لذلك ، دون معرفة المفتاح الخاص ، لا يمكن إكمال المعاملة.
مجموعة مجهولة
نحن نستخدم مجموعة مجهولة من 8 عناصر. يتم تحديد العنصر الهدف بشكل خاص من المجموعة الممثلة في المدخلات العامة zkSNARK. تتيح لك هذه الطريقة تشويش الرسم البياني للمعاملات (إذا كان من الممكن استعادة الرسم البياني التفاعلي UTXO ، فهناك إمكانية لإلغاء هوية المعاملات).
علاوة على ذلك ، يمكن استبدال أداة تجميع بسيطة مكونة من 8 عناصر بمجمع أشجار Merkle. يخفي النهج الرسم البياني للمعاملة.
لإنشاء معاملة صالحة ، نثبت أننا ننفق بعض UTXO من مجموعة UTXO. نضع بروفات الميركل zkSNARK وبيانات UTXO في المدخلات الخاصة وتجزئة الجذر في المدخل العام. وبالتالي ، باستخدام SNARK ، نثبت أننا نعرف UTXO.

حماية الإنفاق المزدوج
للحماية من الإنفاق المزدوج ، نستخدم nullifiers - وظائف حتمية لا تعتمد بشكل مباشر على علامة التجزئة UTXO. لحساب nullifier ، نأخذ الوظيفة من المفتاح الخاص ، وقد ثبت أنها مطابقة للمفتاح العمومي ، والمعرف وتجزئة UTXO. لكل UTXO ، هناك nullifier واحد فقط.
لكل معاملة ، يجب تقديم nullifier مخرجات UTXO المستهلكة كإدخال عام لـ zkSNARK. داخل دائرة zkSNARK ، يجب أيضًا تأكيد أنه ينتمي إلى UTXO المستهلك.
إذا تلقى عقد dApp قيمة nullifier غير فريدة ، فسيتم رفض المعاملة. وبالتالي ، يتم ضمان أن كل UTXO يتم إنفاقه مرة واحدة.
بعد أن قضوا UTXO ، يتم نشر nullifier في قائمة nullifiers المستهلك في مقالة dApp. هذا هو ، في خريطة التجزئة ، مقابل هذا nullifier ، تم تعيين "صواب". قبل نشر nullifier في المقالة ، نتحقق من عدم استخدام nullifier بعد ، مما يعني أنه يمكن إنفاق UTXO مع هذا المعرف.