يشارك المطور كريستوف فيردوت تجربته في الحصول على الدورة التدريبية عبر الإنترنت
"Mastering Web 3.0 مع Waves" .
ما هي خلفيتك؟ ما الذي دفعك لاتخاذ الدورة؟لقد كنت مطور ويب لمدة 15 عامًا تقريبًا ، وأعمل في الغالب كصحفي مستقل.
بالعمل على تطوير تطبيق ويب مستدام للسجل للبلدان الناشئة ، بتمويل من مجموعة مصرفية ، سُئلت ذات مرة عن إمكانية تطبيق شهادة blockchain في السجل. في ذلك الوقت ، لم أكن أعرف الكثير عن شهادة blockchain على الرغم من أنني كنت في التشفير لفترة من الوقت ، معظمها من جانب المستثمر.
لم نتقدم في تطبيق هذه الميزة على هذا التطبيق المحدد ولكن فكرة أن المؤسسات والبنوك كانت تسأل عن تطبيق مثل هذه التقنيات في تطبيقاتها جعلتني أقوم بالكثير من الدراسة والبحث في الموضوع ثم أبدأ
سلسلة Signature Chain المشروع.
لقد قمت بتطوير نسخة تجريبية موجودة بالفعل على Mainnet. في ذلك الوقت [لغة برمجة Waves] لم تكن Ride جاهزة بعد ، لذلك قمت بتطويرها بأبسط الطرق ، باستخدام معاملات التحويل مع JSON المرفقة. لكن الهدف الرئيسي كان دائمًا تقديم ميزات أكثر تقدمًا بمجرد توفر Ride. وكان هذا هو السبب الرئيسي بالنسبة لي لأخذ الدورة ، لأن الخطوة التالية المخطط لها للمشروع هي تحويله إلى تطبيق لامركزي (dApp).
ما هي جوانب الدورة التي وجدت الأسهل والأصعب؟كان الجانب الأسهل هو أنه كان لدينا متسع من الوقت للقيام بذلك ، وكان الأمر يتعلق فقط بالتعلم بدلاً من التنافس على أن نكون الأفضل. كما تم شرحه بشكل جيد ، مع الرسوم التوضيحية البسيطة ولكن الصريحة التي ساعدت كثيرا في تصور وفهم مواضيع مختلفة.
في التحديات ، تم دفعنا للتفكير بمفردنا وفي بعض الأحيان القيام ببعض الأبحاث ، والتي هي أفضل طريقة للتعلم والحصول على فهم أقوى للمفاهيم من الدرس.
عدة مرات ، لم يكن لدي فهم واضح من جزء المحاضرة حتى وصلت إلى الكود ومرت بالتحدي. لم يُسمح بـ "نسخ / لصق" ، مما أجبرنا على كتابة رمز التحدي بالكامل ، وكانت هذه نقطة مهمة أخرى في تعزيز التفاهم.
الجزء الأصعب كان في بعض الأحيان أن الأسئلة متعددة الخيارات في جزء التحدي لم تكن واضحة. أعني ، لغتي الإنجليزية ليست ممتازة ، وقد كتب الأسئلة من قبل متحدثي اللغة الإنجليزية غير الأم ، لذلك كان هناك فجوة في الفهم في بعض الأحيان.
ربما ، كنت أرغب في معرفة المزيد من أقسام أوراكل و NFT. ولكن ، على أي حال ، تهدف هذه الدورة التدريبية بشكل أساسي إلى ربط المطورين ، وستحتاج بالتأكيد إلى قضاء بعض الوقت في اللعب بها وممارسة التمارين لاحقًا للحصول على فهم كامل لكل الجوانب والتفاصيل.
هل يمكن أن تناقش بالتفصيل الحل الذي عملت عليه خلال الدورة - "كوبون بازار"؟ هل يمكن أن تقدم أيضًا أمثلة على الكود؟لقد عملنا على "كوبون بازار" ، وهو في الأساس سوق حيث يقوم الناس بشراء وبيع كوبونات الخصم للسلع والخدمات بسعر منخفض. وتم تمثيل كل قسيمة بأصل رقمي ، وهو يمثل أيضًا خصمًا خاصًا مقدم من الموردين.

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

تمت إضافة العديد من الميزات الإضافية أيضًا أثناء الدورة التدريبية ، بما في ذلك نظام التصويت وميزة للتحقق والموردين من القائمة السوداء.
لقد مررنا أولاً بالاختلافات بين الأصول الذكية والحسابات الذكية وحسابات dApp وأساسيات العمل مع وظائف المدقق. تسمح وظائف Verifier بتغيير السلوك الافتراضي للحساب. بشكل افتراضي ، يتحققون من توقيعات المعاملات ، لكن وظيفة المدقق تسمح لك بتعيين "قاعدة" أخرى.
{-# STDLIB_VERSION 3 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} letownerPublicKey = base58'H8ndsHjBha6oJBQQx33zqbP5wi8sQP7hwgjzWUv3q95M' @Verifier(tx) funcverify() = { matchtx { cases: SetScriptTransaction=>sigVerify(tx.bodyBytes, tx.proofs[0], ownerPublicKey) cased: DataTransaction=>true case_ =>false } }
ثم بدأنا في إضافة العناصر. استخدمنا واحدة من أهم الميزات لتطوير dApp الذي يسمح بتسجيل أي نوع من البيانات على blockchain كأزواج ذات قيمة رئيسية ، ومعاملة البيانات. قمنا بدمجها مع معاملة جديدة ، invokeScript ، تستخدم لاستدعاء وظيفة قابلة للاستدعاء في dApp من الخارج.
كان أحد أنواع معاملات البيانات التي استخدمناها في الدورة التدريبية للموردين هو إضافة عناصر إلى السوق:
letdatajson = { "title": "t-shirt with , vote 1", "coupon_price": 10000000, "old_price": 1000000000, "new_price": 100000000, "address": "Universe", "description": "I want you to make love, not war, i know you've heard it before", "image": "https://bit.ly/2EXTghg" } it('add item', asyncfunction(){ letts = invokeScript({ dApp: dappAddress, call:{ function:"addItem", args:[ { type:"string", value: datajson.title }, { type:"integer", value: datajson.coupon_price }, { type:"string", value: JSON.stringify(datajson) } ]}, payment: [] }, accountSupplierSeed) lettx = awaitbroadcast(ts) awaitwaitForTx(tx.id) })
لمعالجة عملية البيانات هذه من خلال وظيفة addItem وتطوير خيارات شراء وخيارات أخرى في وقت لاحق ، مررنا بالوظيفة القابلة للاستدعاء ، والتي يمكن الاتصال بها من قبل المستخدمين من الخارج. ونتيجة لذلك ، يمكن أن يؤدي مهام مختلفة ، مثل بدء تحويل الأموال أو كتابة أو تحديث البيانات في تخزين بيانات dApp ، إلخ.
هنا مثال على وظيفة قابلة للاستدعاء. يتم استخدامه لوظيفة addItem:
@Callable(i) funcaddItem(title: String, price: Int, data: String) = { letsupplierAddress = toBase58String(i.caller.bytes) letitem = getKeyItem(supplierAddress, title) if( price <= 0) thenthrow("purchase amount cannot be less than item price") elseif( getValueItemSupplier(item) !=NONE ) thenthrow("an item is already exist") else{ WriteSet([ DataEntry(getKeyItemSupplier(item), supplierAddress), DataEntry(getKeyItemPrice(item), price), DataEntry(getKeyItemData(item), data) ]) } }
لقد عملنا لاحقًا على نظام التصويت للسماح للمستخدمين بالتصويت للترويج أو إزالة بعض المنتجات. لقد استخدمت مخطط "الالتزام بالكشف" لتجنب التأثير الخارجي أثناء عملية التصويت.
تم استخدام خطوة الالتزام لجمع الأصوات المشفرة مع وظيفة التجزئة والملح.
الخطوة تكشف لجمع الأصوات فك تشفير ومقارنة التجزئة الخاصة بهم.
فيما يلي مثال على وظيفة يمكن استخدامها في هذه الميزة:
@Callable(i) funcvoteCommit(item: String, hash: String) = { letuser = toBase58String(i.caller.bytes) letcommits = getValueCommitsCount(item) letstatus = getValueItemStatus(item) if( commits >=VOTERS) thenthrow("reached max num of voters") elseif(getValueCommit(item, user) !=NONE) thenthrow("user has already participated") elseif(getKeyItemSupplier(item) ==NONE) thenthrow("item does not exist") elseif(status !=NONE && status !=VOTING) thenthrow("voting is not possible") else{ WriteSet([ DataEntry(getKeyCommit(item, user), hash), DataEntry(getKeyCommitsCount(item), commits +1), DataEntry(getKeyItemStatus(item),if(commits ==VOTERS) thenREVEAL elseVOTING) ]) } }
ماذا تعلمت من الدورة؟كما تطرقت الدورة إلى الرموز الرمزية وغير القابلة للفطريات - الرموز المميزة التي تمثل شيئًا فريدًا وبالتالي لا يمكن استبدالها.
ركزت الطبقة الأخيرة على استخدام الأوراكل. نظرًا لعدم تمكن blockchain من الوصول إلى البيانات من العالم الخارجي ، نحتاج إلى استخدام oracles التي ترسل بيانات العالم الحقيقي إلى blockchain.
في نطاق سوقنا ، استخدمنا أوراكل للتحقق من ، وإذا لزم الأمر ، وضع قائمة سوداء لمورد لم يقبل ، على سبيل المثال ، قسيمة تم بيعها مسبقًا.
هنا مثال على الكود:
funcgetExtValueItemWhiteListStatus(item:String) = { item +"_verifier_status" } letverifier = "3Mx9qgMyMhHt7WUZr6PsaXNfmydxMG7YMxv" letVERIFIED = "verified" letBLACKLISTED = "blacklist" @Callable(i) funcsetstatus(supplier: String, status: String) = { letaccount = toBase58String(i.caller.bytes) if( account !=verifier ) thenthrow("only oracle verifier are able to manage whitelist") elseif( status !=VERIFIED && status !=BLACKLISTED) thenthrow("wrong status") else{ WriteSet([ DataEntry(getExtValueItemWhiteListStatus(supplier), status) ]) } }
ما جزء (أجزاء) الدورة التدريبية التي وجدتها مفيدة للغاية؟الجزء الأكثر فائدة هو التحديات. جعلوا المحاضرات أوضح وعززت معرفتي المكتسبة حديثًا عن طريق التجربة والخطأ. ممارسة مع
IDE ،
المستكشف و
oracles كانت مفيدة حقا.
كيف تخطط لاستخدام ما تعلمته من الدورة؟من البداية ، كان من المفترض أن تساعد هذه الدورة في الارتقاء بمشروعي إلى المستوى التالي. لذا ، فإن الفكرة الآن هي لإعادة كتابة
sign-web.app على ركوب. يقدم الإصدار الحالي بالفعل ميزات عمل لإصدار الشهادات للوثائق ، ولكن بالتأكيد سيتم تعزيزه بإصدار Ride في المستقبل. سيتيح المزيد من المرونة والوضوح والمزيد من الميزات ، بما في ذلك شهادة البريد الإلكتروني ، والاتفاق متعدد الأطراف ، إلخ.
كانت الدورة أيضًا رائعة للغاية ، وبدأت العديد من الأفكار في الظهور في ذهني. أنا متأكد من أن المزيد سيخرج منه في المستقبل.