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

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

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

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

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

عناوين الإيثريوم

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

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

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

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

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

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

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

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

كود التشغيل CREATE2

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

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


حيث:

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

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

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

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

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

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

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

قرار نهائي

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

تم إعداده أصلاً بواسطة:

  • وظيفة الحصول على الملح 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:]


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

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

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


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

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

المؤلف بافل كوندراتنكوف، متخصص في الإيثريوم

المصدر: www.habr.com

إضافة تعليق