البلوكتشين والعقود الذكية

كيف يمكنك الاستماع إلى الأحداث باستخدام الWebster؟

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

IMG 20240407 174834 704
صورة 124

على سبيل المثال في النسخة الأصل عندما يتم رمزها في كل مرة يتم فيها نقل رمز مميز من عنوان إلى أمر يتم إصدار حدث النقل emit transfer(sender,recipient,amount))

صورة 125

سنوضح الآن كيف يمكننا الاستماع إلى بعض الأكواد، نقوم بإعداد واجهة برمجية فارغة كالمعتاد، وفي الواجهة اليمينية نقوم بفتح عقدنا الذكي بكتابة:

M contracts/Mycontract.sol

وسيظهر العقد الذكي الخاص بنا.

أولاً حددنا الحدث وكل مجالاته بحيث يحتوي على ثلاث حقول.

Event MyEvent(

Unit indexed id,

Unit indexed data,

String value

);

صورة 126

الحقل الأول يمثل رقماً صحيحاً، والحقل الثاني يمثل التاريخ لأنه في تواريخ الصلابة يتم تمثيلها على أنها عدد صحيح، والحقل الثالث عبارة عن سلسلة.

ولدينا بعد القوس الأخير من الكود السابق نجد: unit nextid;

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

Emit myevent(nextid, now , value);

الآن سنقوم بفتح ملف التسلل بكتابة: index.js في نهاية الواجهة اليمينية.

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

لذلك نحتاج بهذه الطريقة إلى تنفيذ وظيفة حدث الإرسال لعقدنا, وسنكتب تابع الانتظار في طريقة نقطة العقد t ونضع كوسيطة سلسلة نصية, وسنقوم بالتمرير مباشرة بعد كلمة مرحباً, ونحتاج إلى إرسال معاملة باستخدام طريقة الإرسال , ومن المهم جداً أن نفهم أننا بحاجة إلى استخدام طريقة الإرسال وليس استدعاء طريقة إرسال معاملة, ووضع معاملة هي الطريقة الوحيدة لإنشاء الحدث فعلياً على البلوكتشين, لذا وبعد تابع الانتظار مباشرة نحدد عنوان الإرسال, وقبل كلمة await سنضع إيصال(const receipt) هذه المعاملة في Aris في متغير, ولآن سنسمح لconsole.log لتلقي أحداث النقطة على ما يرام.

Console.log(receipt.events).

صورة 127

وبالانتقال للواجهة اليسارية سنبدأ في الكمأة بكتابة: truffle develop.

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

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

صورة 128

يمكنك أن ترى جميع المعلومات حول حدثك الخاص بمعاملة كتلة عنوان العقد الذكي، ولكن الشيء الأكثر إثارة للاهتمام هي نقطة الإرجاع return values, حتى تتمكن من رؤية كل مجال الحدث الخاص بك كمؤشرات للأرقام ولكن يمكنك أيضاً رؤية الاسم من الحقل كسلسلة عادية، وبعدها تاريخ ال IDE, وبعدها يمكنك أن ترى القيمة value.

صورة 129

لذلك عادة ما يكون هذا الجزء من إيصال المعاملة الذي تريد استخراجه.

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

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

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

صورة 130

وبالانتقال لتنفيذ النص مرة أخرى بكتابة: node index.js لنرى ما حصلنا عليه، يمكننا رؤية اسم الحدث event: ‘MyEvent’ ;

إنه الحدث الخاص بي، ويمكن أن نرى الترحيب (مرحبا) value: ‘hey hey’.

صورة 131

ولكن لا يمكننا أن نرى فقط كلمة مرحباً، ولكننا نرى كلمتي مرحبا متتاليتين.

بالعودة إلى السيناريو الخاص بنا, هي هذين القوسين {} يمكننا تمرير عامل تصفية أو فلتر يكون أحد الحقول هو الكتلة التي نريد قراءة الحدث منها, لذا إذا لم نحدد أي كتلة بشكل افتراضي فستأخذ أحدث كتلة من البلوكتشين, والكتلة الأحدث هي المعاملة, ولكن هذا يعني أنك ستحصل على حدث واحد فقط, لذا إذا كنت ترغب في الحصول على كل الأحداث فأنت بحاجة إلى وضع الحظر عند نشر العقد الفوري حتى تتمكن من الحصول على رقم الكتلة هذا في معاملتك المستلمة عند نشر موقع عقدك الخاص, ولكن يمكنك جعله أكثر بساطة والحصول على الحدث من الكتلة الأولى من البلوكتشين, والعيب الوحيد هو أنه إذا لم يتم تعديله يمكن أن يصبح أبطأ إذا قمت بذلك لأن عقة الإيثيريوم الآن يجب أن تفحص كل البلوكتشين منذ البداية, لذلك نقوم بكتابة كود ضمن القوسين التاليين{} لنشير إلى أننا نريد القراءة من الكتلة صفر.

{from Block: 0}.

ونبدأ بتنفيذ البرنامج النصي مرة أخرى بكتابة: node index.js في الواجهة اليمينية.

وهذه المرة من المفترض أن نرى حدثين، ولكننا وجدنا لدينا أكثر من حدث لأننا أنشأنا بعض الأحداث قبل ذلك.

سنعود لتشغيل مثيل ganache الخاص بنا، وبالتالي سيكون لدينا مثيل جديد لعقدنا الفوري، سنقوم بنشره وذلك بكتابة: migrate –reset وذلك بنهاية الواجهة اليسارية.

وبالعودة للواجهة اليمينية سنقوم بتنفيذ ال ute البرنامج النصي الخاص بنا مرة أخرى.

صورة 132

من الصورة السابقة وفي الواجهة اليمينية يمكن أن نرى قيمة الإرجاع return values: result {, ويمكن أن نرى للأسفل قليلاً قيمتنا المرجعة: value: ‘hey’، وإذا تم استدعاؤها فيمكننا رؤية الحدث الأخر باستخدام كلمة مرحبا مكررة مرتين.

صورة 133

وكل شيء يعمل بشكل جيد.

ويوجد خدعة أخرى وهي في الواقع يمكنك تحديد مفتاح أخر في الفلتر الخاص بك {} لتصفية بعض الأحداث المحددة التي تحتوي على بعض الحقول المحددة, سنقوم بتحديد ذلك باستخدام مفتاح التصفية filter: {  وضمن هذا المفتاح ستحدد الحقل الذي تريد تصفيته وعلى سبيل المثال يمكننا التصفية حسب القيمة وبعد أن تضع القيمة التي تريد التصفية عليها ( يمكن أن تكون هذه القيمة فرضا كلمة مرحبا) و إذا أردت التصفية في حقل آخر على سبيل المثال التاريخ date يمكن أن يكون لدي طابع زمني محدد, وهذا يعني أنني أريد كل الحدث من المدونة صفر حيث يكون حقل القيمة مساوياً لها.

الاحتمال الآخر لتحديد عامل التصفية الخاص بك بدلاً من قيمة ألا وهو إمكانية تحديد مصفوفة [] للقيمة value لذلك إذا قمت بوضع القيمة التالية كالآتي:

Value: [ ‘hey’, ‘hey hey’ ],

فهذا يعني شرطاً شفيهاً.

صورة 134

أريد جميع الأحداث التي يكون حقل القيمة إما مهلاً أو a ولكن لديك أيضاً شرط النهاية.

لذلك سنعود للتصفية على قيمة hey فقط

Value: ‘hey’ 

لقد علمنا قبل أن نحتاج إلى شرح الكلمة الأساسية للفهرس indexed ولذلك نحتاج إلى وضع الكلمة الرئيسية للفهرس إذا كنت تريد استخدام الحقل في مرشح لحقل السلسلة، فنحن ليس لدينا مؤشر للفهرس، لذا لا يمكننا وضعه في مرشح لذلك سنقوم بإضافة كلمة مفتاح الفهرس بين كلمتي string   وvalue كالآتي: string index value

صورة 135

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

ننفذ البرنامج النصي في الواجهة اليمينية node index.js.

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

صورة 136

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

Contract.events.MyEvent({})

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

On (‘data’, event → console.log(event)); ثم ستتلقى الاثنين، ولكن لتظهر لك ميزة الوقت سنقوم بحذف الكود التالي:

صورة 137

وسنقوم بإنشاء الحدث الثاني:

Await contract.methods

.emitEvent(‘hey hey’)

.send({

From: addresses[0]

});

وفيما بين ذلك سنقوم بنشر النص باستخدام وظيفة  keystone, وسنقوم بإنشاء وعد جديد promise وسنحدد الوقت الذي أكون فيه بالخارج set time out وثم استدعاء وظيفة الحل resolve ثم ننتظر ثانيتين 2000 على سبيل المثال.

صورة 138

ولآن نبدأ في تشغيل الحدث الأول للبرنامج النصي الثاني node index.js.

صورة 139

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

صورة 140

وهنا لدينا حدثنا الثاني مع كائن القيمة المرتجعة.

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

صورة 141
Add a subheading 970 × 150

مقالات ذات صلة

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني.

زر الذهاب إلى الأعلى