كيفية تحديد عنوان العقد الذكي قبل النشر: استخدام CREATE2 لتبادل التشفير

لا يتوقف موضوع blockchain عن كونه مصدرًا لكل أنواع الضجيج فحسب ، بل أيضًا عن أفكار ذات قيمة كبيرة من الناحية التكنولوجية. لذلك ، لم تتجاوز سكان المدينة المشمسة. يتطلع الناس ويدرسون ويحاولون تحويل خبراتهم في التحليل المعلوماتي التقليدي إلى أنظمة blockchain. حتى الآن ، مجرد نقطة واحدة: واحدة من التطورات Rostelecom-Solar هي قادرة على التحقق من أمان البرنامج على أساس blockchain. وعلى طول الطريق ، تنشأ بعض الأفكار حول حل المشكلات المطبقة في مجتمع blockchain. واحد من هذه الاختراقات الحياة - كيفية تحديد عنوان عقد ذكي قبل النشر باستخدام CREATE2 - اليوم أريد أن أشاطركم تحت خفض.

صورة
تمت إضافة شفرة التشغيل CREATE2 إلى مفترق الطرق في القسطنطينية في 28 فبراير من هذا العام. كما هو موضح في EIP ، تم تقديم شفرة التشغيل هذه في المقام الأول لقنوات الحالة. ومع ذلك ، استخدمناها لحل مشكلة أخرى.

هناك مستخدمون على التبادل مع الأرصدة. يجب أن نزود كل مستخدم بعنوان Ethereum بحيث يمكن لأي شخص إرسال الرموز ، وبالتالي تجديد حسابه. دعنا نسمي هذه العناوين "محافظ". عندما تأتي الرموز إلى محافظ ، يجب أن نرسلها إلى محفظة واحدة (hotwallet).

في الأقسام التالية ، أقوم بتحليل حلول هذه المشكلة دون CREATE2 وأشرح سبب تخلينا عنها. إذا كنت مهتمًا بالنتيجة النهائية ، فيمكنك العثور عليها في قسم "الحل النهائي".

عناوين Ethereum


الحل الأسهل هو إنشاء عناوين ethereum جديدة للمستخدمين الجدد. هذه العناوين ستكون محافظ. من أجل نقل الرموز المميزة من المحفظة إلى hotwallet ، تحتاج إلى توقيع المعاملة عن طريق استدعاء وظيفة transfer () مع المفتاح الخاص للمحفظة من الواجهة الخلفية.

هذا النهج لديه المزايا التالية:

  • انها فقط
  • تكلفة نقل الرموز المميزة من المحفظة إلى hotwallet تساوي سعر استدعاء وظيفة transfer ()

ومع ذلك ، فقد تخلينا عن هذا النهج لأنه يحتوي على عيب واحد كبير: تحتاج إلى تخزين المفاتيح الخاصة في مكان ما. وهذه النقطة ليست فقط أنها يمكن أن تضيع ، ولكن أيضًا تحتاج إلى التحكم بعناية في الوصول إلى هذه المفاتيح. إذا تم اختراق أحدها على الأقل ، فلن تصل الرموز المميزة لمستخدم معين إلى محفظة ساخنة.

صورة

إنشاء عقد ذكي منفصل لكل مستخدم


إن نشر عقد ذكي منفصل لكل مستخدم يلغي الحاجة إلى تخزين مفاتيح المحفظة الخاصة على الخادم. ستستدعي البورصة هذا العقد الذكي لنقل الرموز إلى hotwallet.

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

شفرة التشغيل CREATE2


لحل مشكلة الطريقة السابقة ، قررنا استخدام شفرة التشغيل CREATE2. يتيح لك CREATE2 تحديد العنوان الذي سيتم نشر العقد الذكي عليه مسبقًا. يتم حساب العنوان باستخدام الصيغة التالية:

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:] 

حيث:
  • العنوان - عنوان العقد الذكي الذي سيتصل بـ CREATE2
  • ملح - قيمة عشوائية
  • init_code - رمز العقد الذكي للنشر

هذا يضمن أن العنوان الذي نوفره للمستخدم سيحتوي بالفعل على الكود المطلوب. بالإضافة إلى ذلك ، يمكن نشر هذا العقد الذكي عندما نحتاج. على سبيل المثال ، عندما يقرر المستخدم استخدام محفظته للمرة الأولى.
صورة
علاوة على ذلك ، يمكنك حساب عنوان العقد الذكي في كل مرة بدلاً من تخزينه ، حيث:

  • العنوان في الصيغة ثابت ، لأن هذا هو عنوان مصنعنا للمحفظة
  • الملح - تجزئة user_id
  • init_code مستمر لأننا نستخدم نفس المحفظة

المزيد من التحسينات


لا يزال لدى الحل السابق عيب واحد: عليك أن تدفع لنشر عقد ذكي. ومع ذلك ، يمكنك التخلص من هذا. للقيام بذلك ، يمكنك استدعاء وظيفة transfer () ، ثم التدمير الذاتي () في مُنشئ المحفظة. ثم سيتم إرجاع الغاز لنشر العقد الذكي.

على عكس الاعتقاد الشائع ، يمكنك نشر عقد ذكي في العنوان نفسه عدة مرات باستخدام شفرة التشغيل CREATE2. وذلك لأن CREATE2 يتحقق من أن nonce لعنوان الوجهة هو صفر (يتم تعيين القيمة "1" في بداية المنشئ). في نفس الوقت ، تقوم الدالة selfdestruct () بإعادة تعيين عناوين nonce في كل مرة. وبالتالي ، إذا اتصلت بـ CREATE2 مرة أخرى بنفس الوسيطات ، فسيتم اجتياز التحقق من nonce.

لاحظ أن هذا الحل مشابه لخيار عنوان الأثير ، ولكن دون الحاجة إلى تخزين المفاتيح الخاصة. تكلفة تحويل الأموال من محفظة إلى hotwallet تساوي تقريبًا تكلفة استدعاء وظيفة transfer () ، نظرًا لأننا لا ندفع مقابل نشر عقد ذكي.

القرار النهائي


صورة

أعد في البداية بواسطة:

  • وظيفة للحصول على الملح بواسطة user_id
  • عقد ذكي يستدعي شفرة تشغيل CREATE2 بالملح المناسب (أي مصنع المحفظة)
  • رمز محفظة البايت المطابق للعقد مع المُنشئ التالي:

 constructor () { address hotWallet = 0x…; address token = 0x…; token.transfer (hotWallet, token.balanceOf (address (this))); selfdestruct (address (0)); } 

لكل مستخدم جديد ، نعرض عنوان محفظته / حسابها من خلال الحساب

 keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:] 

عندما ينقل المستخدم الرموز المميزة إلى عنوان المحفظة المقابلة ، ترى الواجهة الخلفية لحدث النقل مع المعلمة _to مساوية لعنوان المحفظة. في هذه المرحلة ، من الممكن بالفعل زيادة رصيد المستخدم في البورصة قبل نشر المحفظة.

عندما يتراكم عدد كاف من الرموز في عنوان المحفظة ، يمكننا نقلها جميعًا مرة واحدة إلى hotwallet. للقيام بذلك ، تقوم الواجهة الخلفية باستدعاء وظيفة مصنع العقد الذكي ، والتي تقوم بتنفيذ الإجراءات التالية:

 function deployWallet ( uint256) { bytes memory walletBytecode =…; // invoke CREATE2 with wallet bytecode and salt } 

وبالتالي ، يسمى مُنشئ عقد المحفظة الذكية ، والذي ينقل جميع الرموز إلى عنوان hotwallet ثم يدمر نفسه.

يمكن العثور على الرمز الكامل هنا . يرجى ملاحظة أن هذا ليس رمز الإنتاج الخاص بنا ، لأننا قررنا تحسين رمز الكود للمحفظة وكتابته في الأكواد.

أرسلت بواسطة بافل كوندراتنكوف ، أخصائي علم النفس

Source: https://habr.com/ru/post/ar475496/


All Articles