
في المقال الأخير
"وكلاء الحكم الذاتي" أو ننفذ التعليمات البرمجية في نظام التشفير المفتوح Obyte ، تحدثنا عن ماهية وكلاء الحكم الذاتي ومقارنتهم بعقود Ethereum الذكية. دعنا الآن نكتب أول وكيل مستقل (AA) باستخدام مثال لعبة 51٪ Attack. وفي نهاية المقال ، سنحلل طرق تحسينه: كيفية حماية اللاعبين من خسارة / خسارة الأموال وكيفية تحسين الخوارزمية لتقليل تأثير "الحيتان" ذات الرواسب الكبيرة على نتيجة اللعبة.
تتوفر دائمًا نسخة أصلية من كلا الوكلاء
المستقلين في
محرر كود Oscript عبر الإنترنت في شكل قوالب ، ما
عليك سوى تحديدهما من القائمة المنسدلة:
"لعبة الهجوم بنسبة 51٪" و
"وكيل جمع التبرعات".قبل أن تبدأ في كتابة AA في Oscript ، أوصي بشدة بقراءة "
دليل بدء الاستخدام" (eng) في وثائقنا للتعرف بسرعة على المبادئ الأساسية لكتابة AA.
جوهر اللعبة
تتنافس عدة فرق في وقت واحد مع بعضها البعض من أجل الحق في جمع مجموعة الأموال المجمعة بأكملها. يقوم لاعبو الفريق بعمل ودائع ، وبالتالي زيادة المبلغ الإجمالي للمجمع. الفريق الذي حقق ودائع بنسبة 51 ٪ على الأقل من جميع الأموال التي تم جمعها وتمسك به كقائد لمدة يوم واحد على الأقل يفوز. يتم توزيع المجموعة بين لاعبي الفريق الفائز بما يتناسب مع المساهمة المقدمة ، وبالتالي يمكن لكل مشارك أن يضاعف استثماراته.
بمجرد أن يجمع أي من الفرق> = 51٪ من إجمالي الأموال ، تم إعلانه سابقًا على أنه الفائز ولم يعد بإمكان المشتركين تقديم الودائع. لكن جميع الفرق الأخرى لديها 24 ساعة لتجاوز الفريق الفائز. بمجرد حدوث ذلك ، يصبح فريق التجاوز الآن هو الفائز ويبدأ المؤقت العد التنازلي مرة أخرى.
سيقوم تطبيقنا بإصدار "مشاركات" لكل مودع مقابل وحدات البايت بنسبة 1 إلى 1 ، والتي إذا فاز الفريق ، يمكن للمشارك استبدال حصة في المجموعة التي تم ربحها. الأسهم هي أحد الأصول على منصة Obyte ، تم إصدارها خصيصًا لكل فريق. يمكن تحويلها / تداولها ، مثل أي أصل ، لبيع أرباحها المحتملة لأشخاص آخرين. يعتمد سعر السهم على تقييم السوق لفرص الفريق في الفوز.
يمكن لأي شخص إنشاء فريق. يمكن لمبدع الفريق تعيين لجنة للفوز ، والتي ستتم محاسبتها من كل عضو في الفريق في حالة النصر.
سنطبق أيضًا شهادة AA الثانية في لعبتنا ، نيابةً عن منشئ الفريق ، الذي "سيجمع الأموال" بالمبلغ الضروري ، وفقط إذا تحقق ذلك (في مثالنا ، عندما يصل إلى> 51٪ من تجمع اللعبة) ، فسوف يرسل جميع الأموال التي تم جمعها إلى العنوان AA الألعاب ، وإلا يمكن أن تؤخذ الأموال بحرية.
كتابة رمز Oscript
اسمح لي أن أذكرك بأنه يتم استدعاء رمز AA في كل مرة تصل فيها أي معاملة إلى عنوان هذا AA ، ما يسمى المعاملات الزناد. في الواقع ، AA هي رمز ، استجابة للمدخلات (البيانات في معاملة التشغيل والحالة الحالية لـ AA نفسها ، المخزّنة في متغيرات الحالة) يولد الإخراج (معاملة "استجابة" أخرى) ، أو يغير حالته. مهمتنا هي برمجة قواعد استجابة AA لبيانات الإدخال. أي معاملات في Obyte هي مجموعة من الرسائل ، وغالبًا ما تكون رسائل "دفع" أو رسائل "بيانات" ، إلخ.
التهيئة
أولا ، نحن تهيئة AA لدينا. تسمى كتلة init في كل مرة يبدأ فيها AA ، في البداية. في ذلك سنقوم بتعيين الثوابت المحلية للوصول أكثر ملاءمة للقيم.
{ init: `{ $team_creation_fee = 5000; $challenging_period = 24*3600; $bFinished = var['finished']; }`, messages: { cases: [ ] } }
String
$ bFinished = var ['finished']؛ يقرأ المتغير
النهائي من الحالة AA.
سيتم تأطير مجموعة من الرسائل الناتجة
بالحالات: {} block ، وهو يشبه كتلة
switch / case / default المعتادة ، استنادًا إلى الشروط في حالة وجود كتل فرعية ، سيتم اختيار واحدة فقط من الرسائل ، أو إذا
كانت الإجابة بلا
إذا تم إرجاع الكتل بشكل
صحيح ، فسيتم آخر رسالة تم اختيارها
نخلق فريق
لذلك ، ستقوم الكتلة الأولى بمعالجة المعاملات لإنشاء أمر جديد:
كما نرى ، فإن شرط تنفيذ هذه الكتلة هو الأول في كتلة if وهو التحقق من أن معاملة المشغل تحتوي على رسالة تحتوي على نوع البيانات (
trigger.data.create_team ) ، والذي يحتوي على مفتاح يسمى
create_team وهو اللعبة لم تنته بعد (
! $ bFinished ). يمكن الوصول إلى الثابت المحلي
$ bFinished من أي مكان في الكود إذا تمت تهيئته في كتلة init. إذا لم يتم استيفاء واحد على الأقل من هذه الشروط ، فستستمر مجموعة الحالات الأصل في التنفيذ والتحقق من شروط الرسائل التالية ، متخطية هذه الحالة.
في كتلة
التهيئة التالية ، لا نقوم بتهيئة أي شيء ، لكننا نتحقق من الشروط اللازمة ، والتي بدونها تعتبر المعاملة المشغلة خاطئة:
if (var['team_' || trigger.address || '_asset']) bounce('you already have a team'); if (trigger.output[[asset=base]] < $team_creation_fee) bounce('not enough to pay for team creation');
نحن هنا نسلسل (باستخدام ||) السلسلة مع المتغير من مشغل المعاملة ونحاول معرفة ما إذا كان هناك متغير يسمى
'team_' || trigger.address || "_asset" في قصة AA لدينا.
تستدعي المكالمة
المرتدّة () أي تغييرات تم إجراؤها حتى اللحظة الحالية وتقوم بإرجاع خطأ للمتصل.
لاحظ أيضًا كيفية إجراء البحث داخل معاملة المشغل:
trigger.output [[أصل = أساسي]] تبحث عن مخرجات مع
الأصل == الأساس ، والتي ستُرجع المبلغ بالبايت (الأصل الأساسي = البايت) الذي تم تحديده في معاملة المشغل. وإذا لم يكن هذا المبلغ كافيًا لإنشاء فريق جديد ، فإننا ندعو bounce () ، ونأكل بصمت جميع البايتات الواردة ناقص bounce_fee ، والتي تكون افتراضيًا 10000 بايت.
بعد ذلك ، يبدأ الجزء الأكبر من كود بناء الفريق. باختصار ، الخوارزمية هي كما يلي:
- الرسالة الأولى تطلق مادة عرض جديدة ( التطبيق: "مادة عرض" )
- تُرجع الرسالة الثانية كل ما هو أكثر من العدد المطلوب من وحدات البايت لإنشاء الأمر ( التطبيق: "الدفع" ). تحقق من كتلة إذا هنا. إذا كان هذا الشرط خاطئًا (أرسل المنشئ بالضبط العدد المطلوب من البايتات) ، فلن يتم تضمين هذه الرسالة في المعاملة الناتجة ، ولكن سيتم طرحها ببساطة.
- تغيّر الرسالة الثالثة حالة AA ( التطبيق: 'state' ): اكتب founder_tax الذي تم تمريره كوسيطة ، أو قم بتعيينه على 0 إذا لم يتم تمريره إلى معاملة المشغل. بناء var1 وإلا var2 بإرجاع var1 إذا تم تحويلها إلى true ، وإلا فإنها ترجع var2. نحن هنا نواجه متغير response_unit ، والذي يحتوي دائمًا على تجزئة الوحدة الناتجة. في هذه الحالة ، لأن ستنشئ الوحدة الناتجة أصلًا جديدًا يسمى الأصول - أ وستكون عنصر تجزئة وحدة الإنشاء. استجابة السلسلة ['team_asset'] = response_unit تكتب ببساطة نفس التجزئة (أو الأصل للأمر المحدد) إلى صفيف responseVars في الوحدة النهائية. يمكن أيضًا قراءة صفيف الاستجابة للشخص الذي أجرى معاملة الزناد ، وكذلك في مستمعي الأحداث المشتركين في الأحداث مع AA.
نحن نقبل الودائع
بعد الانتهاء من إنشاء الفريق ، انتقل إلى المجموعة التالية - معالجة الودائع من أعضاء الفريق.
من الجديد الذي نلتقي هنا هو إصدار الرموز المميزة لأصل الفريق المختار إلى مشاركه في مقابل إيداعه بالبايت:
asset: `{var['team_' || trigger.data.team || '_asset']}`, outputs: [{address: "{trigger.address}", amount: "{trigger.output[[asset=base]]}"}
كما نذكر ، متغير الدولة
'team_' || trigger.data.team || لقد قمنا بحفظ
"_asset" في مرحلة إنشاء الفريق ، ويتم تخزين تجزئة الوحدة فيه ، حيث أنشأنا الأصل لهذا الفريق ، أي اسم هذا الأصل
في نفس الكتلة ، يتم التحقق من الشرط الرئيسي بنسبة 51 ٪:
if (var['team_' || trigger.data.team || '_amount'] > balance[base]*0.51){ var['winner'] = trigger.data.team; var['challenging_period_start_ts'] = timestamp; }
إذا تجاوز رصيد الفريق المحدد بعد هذه الصفقة المشغلة 51٪ ، فسيتم إعلان فوز الفريق ونقوم بتسجيل الطابع الزمني الحالي لنظام يونكس (بدء الموقت).
سيتم فحص هذا الطابع الزمني في المربع الثالث عندما نتلقى معاملة تشغيل مع محاولة إنهاء اللعبة:
نحن ندفع جائزة
والكتلة الأخيرة ، والأكثر إمتاعاً ، هي دفع الوديعة بالكامل للفائزين:
تعتبر كتلة التهيئة مثيرة للاهتمام هنا ، حيث نحسب القيم اللازمة مقدمًا:
$share = $asset_amount / var['team_' || $winner || '_amount']; $founder_tax = var['team_' || $winner || '_founder_tax']; $amount = round(( $share * (1-$founder_tax) + (trigger.address == $winner AND !var['founder_tax_paid'] ? $founder_tax : 0) ) * var['total']);
يتم دفع جميع المشاركين في الفريق ، باستثناء منشئه ، مبلغًا يتناسب مع مساهمتهم الأولية (1 - 1 - بايت في مقابل رموز الأصول المرسلة في معاملة المشغل). يتم دفع عمولة المنشئ أيضًا (يتم التحقق من أن عنوان
الشخص الذي أرسل معاملة المشغل مساوٍ لعنوان منشئ الفريق الفائز
trigger.address == $ Winner ). من المهم ألا ننسى أن العمولة يجب أن تدفع مرة واحدة فقط ، ويمكن للمنشئ أن يرسل عددًا لا نهائي من المعاملات المشغلة ، لذلك نحن ننقذ العلم في الحالة AA.
ابدأ اللعبة
لذلك ، الرمز جاهز. هنا قائمة كاملة منه:
رمز AA الكامل { init: `{ $team_creation_fee = 5000; $challenging_period = 24*3600; $bFinished = var['finished']; }`, messages: { cases: [ {
دعونا التحقق من صحة رمز ومحاولة نشره في testnet.
- انتقل إلى المحرر عبر الإنترنت: https://testnet.oscript.org
- الصق رمزنا وانقر فوق التحقق من الصحة. إذا كان كل شيء صحيحًا ، فسنرى حسابًا لتعقيد الشفرة: التحقق من صحة AA ، التعقيد = 27 ، العمليات = 176 . ops هنا هو عدد العمليات في الكود الخاص بنا ، والتعقيد هو تعقيد الكود. لا تحتوي دورات Obyte AA على دورات ، لكن حتى هذا لا يتيح حماية بنسبة 100٪ للشبكة من AAs الخبيثة التي تحتوي على كود غير صحيح. لذلك ، يكون لكل AAs الحد الأعلى من التعقيد ، التعقيد = 100. يتم حساب تعقيد الشفرة في وقت النشر ، وتؤخذ جميع فروع الشفرة في الاعتبار. بعض العمليات سهلة نسبيًا ، مثل ± وغيرها ، فهي لا تضيف تعقيدًا. غيرها ، مثل الوصول إلى قاعدة البيانات (تعديل الحالة) أو الحسابات المعقدة (استدعاء بعض الوظائف) إضافة التعقيد. لمعرفة أي العمليات سهلة وأيها معقدة ، راجع مرجع اللغة .
- انقر فوق نشر. نحن نرى شيئا مماثلا ل
Check in explorer: https://testnetexplorer.obyte.org/#DiuxsmIijzkfAVgabS9chJm5Mflr74lZkTGud4PM1vI= Agent address: 6R7SF6LTCNSPLYLIJWDF57BTQVZ7HT5N
أنصحك باتباع الرابط في المستكشف والتأكد من نشر الوحدة التي تحمل شهادة AA على الشبكة. يعرض المستكشف أيضًا الرمز الكامل لـ AA الخاص بنا جميع AAs على شبكة Obyte مفتوحة المصدر. يمكنك دراسة رمز أي وكيل في عنوانه.
تمويل الجماعي
والآن إلى التحسينات الموعودة. في التطبيق الحالي ، يرسل كل لاعب الأموال فورًا إلى عنوان AA الخاص باللعبة ، مع الإشارة إلى فريقه. في الوقت نفسه ، قد لا يصبح الفريق قائدًا ، وتم إرسال الأموال بالفعل. يمكننا تحسين عملية جمع الأموال وتجنب الموقف الذي نرسل فيه الأموال إلى فريق لن يصبح الفائز أبدًا. يمكن القيام بذلك باستخدام AA الثانية ، وترتيب ما يسمى التمويل الجماعي للأموال من خلال تحديد هدف ديناميكي لكمية الأموال التي تم جمعها تساوي 51 ٪ من المبلغ في اللعبة.
في Oscript ، يمكننا قراءة حالة أي AA أخرى ، لذلك لدينا الفرصة لتحديد هدف ديناميكي في AA التمويل الجماعي لدينا.
ستكون الخوارزمية كما يلي: يطلب من خالق الفريق من اللاعبين إرسال أموال ليس إلى عنوان اللعبة ، ولكن إلى عنوان وكيل يقوم بتنفيذ وظيفة التمويل الجماعي. سيقوم هذا العامل بتخزين الكمية التي تم جمعها من وحدات البايت في المنزل وإرسالها إلى اللعبة فقط إذا كان يجمع> = 51٪ من المبلغ في اللعبة. وعلى الفور يصبح هذا الفريق قائدًا. إذا لم يتم جمع المبلغ اللازم ، فسيتم ببساطة إعادة الأموال إلى اللاعبين. في مرحلة جمع التبرعات ، لن يحصل اللاعبون على رموز لعبة جماعية ، ولكن الرموز المميزة للتمويل الجماعي ، والتي يمكن ردها في المستقبل أو استبدالها برموز اللعبة ، إذا نجحت.
في المقالة التالية ، نطبق هذه الوظيفة.
نحن نجمع ليس بايت ، ولكن الشهادات
في أبسط أشكال لعبة "Attack 51٪" نتحدث عن مبالغ الأموال التي تم جمعها. وبالتالي ، يمكن أن "الحيتان" مع محافظ كبيرة تأخذ معظم المكاسب.
لجعل اللعبة أكثر صدقًا لجميع المشاركين ، سنحاول حساب عدد وحدات البايت المرسلة ، ولكن ليس عدد المشاركين في الفرق. الفريق الذي كان قادرًا على جذب أكبر عدد ممكن من المشاركين يفوز. سيستثمر كل لاعب مبلغًا ثابتًا ، على سبيل المثال 1 غيغابايت ، ويتم احتسابه كوحدة في تجمع الفريق. ولكن لا شيء يمنعنا من إنشاء عدد لا حصر له من العناوين الجديدة ، وبالتالي فإن الشرط الحرج هو أنه لا يُسمح إلا بالعناوين المرتبطة ببعض المعرّفات الأخرى في اللعبة ، والتي تُحترم فيها قاعدة "شخص واحد - معرف واحد". مثل هذا الربط يسمى
الشهادة . مثال على شهادة هو مرور إجراء KYC ، وبعد ذلك يتم إرسال رسالة إلى DAG حول الاتصال بين عنوان Obyte وتجزئة البيانات الشخصية (يتم تخزين البيانات الشخصية نفسها في محفظة المستخدم ، ويمكنه الكشف عنها لأطراف مقابلة فردية إذا أراد ، ولكن هذه المهمة ليست ضرورية. فقط حقيقة ملزمة). مثال آخر على الشهادة ، هو شهادة البريد الإلكتروني على المجالات حيث يتم احترام قاعدة "شخص واحد - بريد إلكتروني واحد" ، على سبيل المثال ، في مجالات بعض الجامعات والشركات والبلدان. وبالتالي ، سيتم احتساب شخص حقيقي مرة واحدة فقط.
يمكن للوكلاء المستقلين طلب حالة التصديق على العناوين على الشبكة ، لذلك سيكون هناك حد أدنى لعدد التغييرات في الكود.
أقترح على القراء في التعليقات أن يقترحوا أي الأماكن وكيف يجب تغيير أسطر الكود الخاصة بالإصدار الحالي للعبة بدقة من أجل تنفيذ ذلك. للمساعدة ، كما هو الحال دائمًا ،
مرجع لغة Oscript .
لدينا
الشقاق وتويتر