
في هذه المقالة ، سننظر في مثالين حول كيفية كتابة عقد ذكي في C ++ باستخدام
WASM بناءً على شبكة
Ontchain blockchain . واليوم ، بعد عدة أشهر من التشغيل المستقر في وضع الاختبار ،
أطلقت شركة Ontology WASM على الشبكة الرئيسية ، مما يسمح بنقل عقود dApp مع منطق الأعمال المعقدة إلى blockchain دون ألم وبتكلفة أقل ، وبالتالي إثراء النظام الإيكولوجي dApp بشكل ملحوظ.
يدعم برنامج Ontology Wasm أيضًا إنشاء عقود ذكية بلغة الصدأ ، ويمكنك أن تقرأ عنها
هنا .
فيما يلي مثالان لعقد ذكي: أولاً ، اكتب "Hello world!" ثم قم بإنشاء ظرف أموال افتراضي يمكن إرساله إلى صديق كهدية.
تطوير عقد WASM باستخدام C ++
مثال 1. مرحبا العالم
لنبدأ مع Hello World:
#include<ontiolib/ontio.hpp> #include<stdio.h> using namespace ontio; class hello:public contract { public: using contract::contract: void sayHello(){ printf("hello world!"); } }; ONTIO_DISPATCH(hello, (sayHello));
إنشاء العقد
يحتوي برنامج التحويل البرمجي
Ontology Wasm CDT على نقطة إدخال ومعلمات تحليل ، لذلك لا يحتاج المطورون إلى إعادة تعريف طرق الإدخال. علاوة على ذلك ، لكتابة منطق الخدمة ، يمكنك استدعاء أساليب API لعقد ذكي.
ONTIO_DISPATCH(hello, (sayHello));
في المثال أعلاه ، نحن ندعم فقط sayHello حتى الآن:
printf("hello world!");
"مرحبا العالم!" سيتم عرضه في سجل عقدة التصحيح. عند كتابة عقد ذكي مباشرة ، لا يمكن استخدام printf إلا للتصحيح ، لأن العقد الذكي نفسه يحتوي على أوامر أكثر وظيفية.
عقد API الذكية
يوفر Ontology Wasm واجهات برمجة التطبيقات التالية للتفاعل مع blockchain الخادم:

مثال 2: المغلف المال
الآن دعونا نلقي نظرة على مثال أكثر تعقيدًا باستخدام واجهة برمجة تطبيقات عقد Wasm الذكية.
في هذا المثال ، سوف نكتب مغلفًا افتراضيًا للأموال ، يعد التناظرية للمغلف الأحمر (hongbao) ميزة شائعة لبرنامج Messenger Wechat الصيني ، والذي يسمح لك بإرسال الأموال إلى الأصدقاء في دردشة. يتلقى المستخدم رسالة في شكل مظروف أحمر ، يفتحها ويتم إضافة الأموال تلقائيًا إلى رصيد الحساب.
كجزء من عقد ذكي ، يمكن للمستخدمين استخدام هذا العقد لإرسال رموز ONT أو ONG أو OEP-4 باستخدام مظاريف أموال افتراضية لأصدقائهم ، والذين يمكنهم بعد ذلك نقل الرموز المميزة إلى محافظ blockchain الخاصة بهم.
التحضير لإنشاء العقد
أولاً ، قم بإنشاء ملف العقد المصدر وقم بتسميته redEnvelope.cpp. بعد ذلك ، نحتاج إلى ثلاثة واجهات برمجة تطبيقات لهذا العقد:
- createRedEnvelope : إنشاء مغلف المال
- queryEnvelope : طلب معلومات المغلف
- claimEnvelope : افتح مظروفًا واحصل على المال
#include<ontiolib/ontio.hpp> using namespace ontio; class redEnvlope: public contract{ } ONTIO_DISPATCH(redEnvlope, (createRedEnvlope)(queryEnvlope)(claimEnvelope));
الآن نحن بحاجة إلى حفظ مفتاح القيمة. في عقد ذكي ، يتم تخزين البيانات في سياق العقد كقيمة أساسية ، ونحن بحاجة إلى إضافة بادئة إلى بيانات KEY لطلب لاحق.
نحدد أدناه ثلاث بادئات سنستخدمها:
std::string rePrefix = "RE_PREFIX_"; std::string sentPrefix = "SENT_COUNT_"; std::string claimPrefix = "CLAIM_PREFIX_";
نظرًا لأن العقد يدعم كلاً من الرمزان Ontology - ONT و ONG ، يمكننا تحديد عنوان عقدهما مقدمًا. على عكس العقد الذكي القياسي ، فإن عنوان عقد شركة Entology ثابت ولا يتم اشتقاقه من علامة تجزئة العقد.
address ONTAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; address ONGAddress = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2};
بعد ذلك ، ستحتاج إلى حفظ معلومات حول الرمز المميز المستخدم في العقد: عنوان الرمز المميز للعقد ، والمبلغ الإجمالي للمغلف وعدد المغلفات.
struct receiveRecord{ address account;
فيما يلي عملية الماكرو المحددة بواسطة Ontology Wasm CDT ، والتي تُستخدم للتسلسل قبل هيكلة البيانات.
ONTLIB_SERIALIZE(receiveRecord,(account)(amount))
خلق مغلف
الآن وبعد أن أكملنا الاستعدادات اللازمة ، سنبدأ في تطوير منطق واجهة برمجة التطبيقات.
1. عند إنشاء مظروف نقدي ، من الضروري الإشارة إلى عنوان المالك وعدد المغلفات ومقدارها ، بالإضافة إلى عنوان الرمز المميز:
bool createRedEnvlope(address owner,asset packcount, asset amount,address tokenAddr ){ return true; }
2. تحقق من توقيع المالك ، وإلا فإننا سنراجع (نراجع المعاملة) ونخرج:
ontio_assert(check_witness(owner),"checkwitness failed");
ملاحظة : ontio_assert (expr ، errormsg): false expr يُرجع خطأ وينهي العقد.
3. إذا تم استخدام رمز ONT في مغلف ، فمن المهم أن تتذكر أنه لا يتم تجزئة ONT (على الأقل 1 ONT). بعد ذلك ، يجب أن يكون المبلغ الإجمالي للمغلف النقدي أكبر من أو يساوي عدد الرموز المميزة لضمان وجود واحد على الأقل من كل مغلف:
if (isONTToken(tokenAddr)){ ontio_assert(amount >= packcount,"ont amount should greater than packcount"); }
4. بعد ذلك ، نحدد لحامل الظرف إجمالي عدد مظاريف المال التي يرسلها:
key sentkey = make_key(sentPrefix,owner.tohexstring()); asset sentcount = 0; storage_get(sentkey,sentcount); sentcount += 1; storage_put(sentkey,sentcount);
5. توليد تجزئة المغلف - المعرف الذي يحدد هذا المغلف:
H256 hash ; hash256(make_key(owner,sentcount),hash) ; key rekey = make_key(rePrefix,hash256ToHexstring(hash));
6. سوف نقوم بترجمة الرموز في العقد. نكتشف عنوان العقد الذي يتم تنفيذه حاليًا باستخدام الأمر self_address () ، ثم سنقوم بنقل الكمية المخصصة من الرموز إلى العقد بناءً على نوع الرموز المميزة:
address selfaddr = self_address(); if (isONTToken(tokenAddr)){ bool result = ont::transfer(owner,selfaddr ,amount); ontio_assert(result,"transfer native token failed!"); }else if (isONGToken(tokenAddr)){ bool result = ong::transfer(owner,selfaddr ,amount); ontio_assert(result,"transfer native token failed!"); }else{ std::vector<char> params = pack(std::string("transfer"),owner,selfaddr,amount); bool res; call_contract(tokenAddr,params, res ); ontio_assert(res,"transfer oep4 token failed!"); }
ملاحظة 1: بالنسبة إلى ONT و ONG ، يوفر Ontology Wasm CDT واجهة برمجة التطبيقات ont :: transfer لنقل الرموز ؛ يجب إرسال الرموز المميزة OEP-4 باستخدام طريقة الاتصال التقليدية عبر العقود.
ملاحظة 2: مثل عنوان المحفظة العادية ، يمكن أن يقبل عنوان العقد أي نوع من الرمز المميز. ومع ذلك ، يتم إنشاء عنوان العقد بواسطة تجزئة ثنائية مجمّعة وبالتالي لا يحتوي على مفتاح خاص مناظر ولا يمكن استخدام الرموز المميزة للعقد. إذا لم تقم بإعداد مفتاح خاص ، فلن تتمكن من إدارة هذه الرموز المميزة.
7. احفظ المعلومات حول العقد في مستودع البيانات:
struct envlopeStruct es ; es.tokenAddress = tokenAddr; es.totalAmount = amount; es.totalPackageCount = packcount; es.remainAmount = amount; es.remainPackageCount = packcount; es.records = {}; storage_put(rekey, es);
8. إرسال إشعار حول إنشاء المغلف. هذه عملية غير متزامنة لاستدعاء عقد ذكي ، كما سيرسل العقد إشعارًا بنتيجة التنفيذ. يمكن تحديد تنسيق التنفيذ من قبل مؤلف العقد.
char buffer [100]; sprintf(buffer, "{\"states\":[\"%s\", \"%s\", \"%s\"]}","createEnvlope",owner.tohexstring().c_str(),hash256ToHexstring(hash).c_str()); notify(buffer); return true;
الصيحة ، المغلف المال جاهز تقريبا. الآن دعونا نرى كيفية طلب معلومات المغلف.
مغلف الاستعلام (استعلام
منطق الطلب بسيط للغاية ، تحتاج فقط إلى الحصول على المعلومات والتنسيق من مخزن البيانات ، ثم الإخراج:
std::string queryEnvlope(std::string hash){ key rekey = make_key(rePrefix,hash); struct envlopeStruct es; storage_get(rekey,es); return formatEnvlope(es); }
ملاحظة: بالنسبة لعمليات العقود الذكية للقراءة فقط (مثل الاستعلام) ، يمكنك التحقق من النتيجة من خلال تنفيذ ما قبل التنفيذ. على عكس مكالمة العقد العادية ، لا يتطلب تطبيق pre-exec توقيع محفظة ، وبالتالي لا يتطلب عمولة في ONG. بعد القيام بذلك ، يمكن للمستخدمين الآخرين الآن التقدم بطلب للحصول على المغلف إذا كان لديهم تجزئة مغلف (معرف مغلف).
تلقي المغلف
في هذه المرحلة ، قمنا بالفعل بنقل الرموز المميزة إلى عقد ذكي ، والآن ، حتى يتمكن أصدقاؤك من المطالبة بنجاح بحصة في الظرف ، يجب أن ترسل إليهم معرف المغلف (التجزئة).
1. لتلقي مظروف ، يجب إدخال عنوان حسابك وتجزئة المظروف:
bool claimEnvlope(address account, std::string hash){ return true; }
2. بعد ذلك ، سوف يتحقق العقد من توقيع حسابك للتأكد من أنك مالكه. يمكن لكل حساب التقدم بطلب لمغلف مرة واحدة فقط:
ontio_assert(check_witness(account),"checkwitness failed"); key claimkey = make_key(claimPrefix,hash,account); asset claimed = 0 ; storage_get(claimkey,claimed); ontio_assert(claimed == 0,"you have claimed this envlope!");
3. تحقق مما إذا كان قد تم استلام المظروف وفقًا لمعلومات التجزئة الواردة من المتجر:
key rekey = make_key(rePrefix,hash); struct envlopeStruct es; storage_get(rekey,es); ontio_assert(es.remainAmount > 0, "the envlope has been claimed over!"); ontio_assert(es.remainPackageCount > 0, "the envlope has been claimed over!");
4. إنشاء سجل مطالبة:
struct receiveRecord record ; record.account = account; asset claimAmount = 0;
5. حساب المبلغ لكل مقدم مغلف.
بالنسبة لآخر مشارك ، يتم تحديد مبلغ الرصيد ، وبالنسبة لأي شخص آخر ، يتم تحديد المبلغ المعلن بواسطة رقم عشوائي محسوب بواسطة تجزئة الكتلة الحالية والمعلومات الحالية حول المغلف:
if (es.remainPackageCount == 1){ claimAmount = es.remainAmount; record.amount = claimAmount; }else{ H256 random = current_blockhash() ; char part[8]; memcpy(part,&random,8); uint64_t random_num = *(uint64_t*)part; uint32_t percent = random_num % 100 + 1; claimAmount = es.remainAmount * percent / 100;
6. الاعتمادات المالية
يتم نقل المبلغ المقابل من الرموز إلى حساب المتقدمين المغلف وفقا لنتيجة الحساب:
address selfaddr = self_address(); if (isONTToken(es.tokenAddress)){ bool result = ont::transfer(selfaddr,account ,claimAmount); ontio_assert(result,"transfer ont token failed!"); } else if (isONGToken(es.tokenAddress)){ bool result = ong::transfer(selfaddr,account ,claimAmount); ontio_assert(result,"transfer ong token failed!"); } else{ std::vector<char> params = pack(std::string("transfer"),selfaddr,account,claimAmount); bool res = false; call_contract(es.tokenAddress,params, res ); ontio_assert(res,"transfer oep4 token failed!"); }
7. سنقوم بتدوين معلومات حول استلام الأموال والمعلومات المحدّثة عن الظرف في القبو وإرسال إشعار بشأن الوفاء بالعقد:
storage_put(claimkey,claimAmount); storage_put(rekey,es); char buffer [100]; std::sprintf(buffer, "{\"states\":[\"%s\",\"%s\",\"%s\",\"%lld\"]}","claimEnvlope",hash.c_str(),account.tohexstring().c_str(),claimAmount); notify(buffer); return true;
كما هو مذكور أعلاه ، يمكن لهذا العقد إرسال الرموز المميزة من العقد من خلال claimEnvelope API. هذا يضمن أمان الرموز أثناء وجودها في الظرف ، لأنه لا يمكن لأحد سحب الأصول دون الوفاء بالمتطلبات اللازمة.
القيام به! لقد كتبت أول عقد ذكي لك. يمكن العثور على رمز العقد الكامل على GitHub
هنا .
اختبار العقد
هناك طريقتان للتحقق من العقد:
- استخدم CLI
- استخدم Golang SDK
استنتاج
في هذه المقالة ، تحدثنا عن كيفية كتابة عقد ذكي لـ Ontolgy Wasm باستخدام API blockchain. يبقى حل مشكلة الخصوصية بحيث يتحول العقد الذكي إلى منتج متكامل. في هذه المرحلة من الكود ، يمكن لأي شخص الحصول على تجزئة من المغلف الأحمر من خلال تتبع سجلات العقد ، مما يعني أنه يمكن لأي شخص المطالبة بحصة في المغلف. يمكن حل هذه المشكلة ببساطة - فنحن نحدد قائمة بالحسابات التي يمكن أن تتقدم بطلب للحصول على مظروف عند إنشائه. إذا رغبت في ذلك ، يمكن أيضا اختبار هذه الوظيفة.
الحصول على منحة علم الوجود لتطوير dApp من 20،000 دولار
التقديم لبرنامج موهبة الطالب الأنطولوجيا
هل أنت مطور؟ انضم إلى مجتمع التكنولوجيا الخاص بنا على
Discord . بالإضافة إلى ذلك ، ألق نظرة على
مركز المطور على موقعنا ، حيث يمكنك العثور على أدوات مطور البرامج والوثائق وغير ذلك الكثير.
علم الوجود