! [تفسير كامل لقواعد نحوية محسنة لـ Starknet] (https://img-cdn.gateio.im/resized-social/moments-69a80767fe-553ed1d6a1-dd1a6f-7649e1)
ملخص
يقدم الإصدار 2 من مترجم القاهرة تغييرات في بناء جملة Starknet لجعل الشفرة أكثر وضوحًا وأمانًا. يتم تعريف الواجهة العامة للعقد الذكي باستخدام السمات ، ويتم الوصول إلى التخزين من خلال سمة ContractState. يجب تحديد الأساليب الخاصة بتطبيق مختلف عن الواجهة العامة. يتم الآن تعريف الأحداث على أنها تعدادات ، حيث يكون كل متغير عبارة عن بنية تحمل الاسم نفسه.
إخلاء المسؤولية: تشير المصطلحات المستخدمة هنا إلى إصدارات مختلفة من مترجم القاهرة ، والصياغة مؤقتة لأن مجتمع Starknet لا يزال يناقش حول أفضل مصطلح يمكن استخدامه. بمجرد تحديدها ، سيتم تحديث هذه المقالة وفقًا لذلك.
المترجم v2.0
في الأسبوع الماضي فقط ، تم إطلاق إصدار رئيسي جديد 2.0.0-rc0 من مترجم القاهرة على جيثب. يوفر المترجم الجديد تحسينات كبيرة على المكون الإضافي Starknet ، مما يجعل الكود الخاص بنا أكثر أمانًا وأكثر وضوحًا وقابلية لإعادة الاستخدام. لاحظ أن هذا الإصدار الجديد من المترجم غير مدعوم بعد على ** Starknet testnet أو mainnet ** لأنه لا يزال قيد العمل في البيئة المتكاملة.
الهدف من هذه المقالة هو توضيح كيفية إعادة كتابة عقد Starknet الذكي الذي تم إنشاؤه لمجمع القاهرة الإصدار 1.x في عقد ذكي متوافق مع الإصدار 2.x. نقطة البداية لدينا هي العقد الذكي Ownable الذي تم إنشاؤه في المقالة السابقة ، وهو متوافق مع برنامج التحويل البرمجي Cario الإصدار 1.x.
[contract] mod الملكية {use starknet :: ContractAddress ؛ استخدم starknet :: get \ _caller \ _address؛
[external] fn transfer \ _ownership (new \ _owner: ContractAddress) {only \ _owner ()؛ let previous \ _owner = owner :: read ()؛ owner :: write (new \ _owner)؛ نقل الملكية (السابق \ _المالك والجديد \ _المالك) ؛}
fn only \ _owner () {let caller = get \ _caller \ _address ()؛ تأكيد (caller == owner :: read ()، 'Caller ليس المالك')؛
إعدادات المشروع
نظرًا لأن Protostar لا يدعم المترجم v2 بعد ، فستعتمد هذه المقالة على الإصدار التجريبي من Scarb (الإصدار 0.5.0-alpha.1) الذي يدعمه. لتثبيت هذا الإصدار المحدد من Scarb ، يمكنك استخدام الأمر التالي.
بعد اكتمال الإعداد ، يمكننا التوجه إلى src / lib.cairo والبدء في كتابة العقود الذكية.
التخزين والمنشئ
في الإصدار 2 من برنامج التحويل البرمجي للقاهرة ، لا تزال العقود الذكية تُحدد من خلال وحدات مشروحة بسمة العقد ، ولكن هذه المرة فقط يتم تسمية السمة على اسم الملحق الذي يحددها ، في هذه الحالة starknet.
[starknet :: contract] mod تملكها {}
لا يزال يتم تعريف التخزين الداخلي على أنه بنية يجب أن تسمى التخزين ، ولكن هذه المرة فقط يجب أن يتم التعليق عليها بسمة تخزين.
[starknet :: Contract] mod Ownable {use super :: ContractAddress؛ # [storage] تخزين هيكلي {owner: ContractAddress،
لتعريف المُنشئ ، قمنا بتعليق الدالة بخاصية المُنشئ ، كما فعلنا في v1 ، والميزة هي أنه يمكن الآن أن يكون للوظيفة أي اسم ، ولا يلزم أن يُطلق عليها اسم "المُنشئ" كما هو الحال في v1. على الرغم من أنه ليس مطلوبًا ، ما زلت أشير إلى الوظيفة على أنها "مُنشئ" خارج الاصطلاح ، ولكن يمكنك تسميتها بشكل مختلف.
تغيير مهم آخر هو أن المُنشئ الآن يقوم تلقائيًا بتمرير مرجع إلى ContractState ، والذي يعمل كوسيط لتخزين المتغيرات ، في هذه الحالة "مالك".
لاحظ أن بنية تخزين الكتابة والقراءة قد تغيرت منذ الإصدار 1. قبل أن نكتب المالك :: write () ، نقوم الآن بكتابة self.owner.write (). الأمر نفسه ينطبق على القراءة من التخزين.
بالمناسبة ، لا يلزم إدخال نوع ContractState يدويًا في النطاق ، فهو مدرج في المقدمة.
الطرق العامة
هناك اختلاف مهم عن الإصدار 1 من مترجم القاهرة وهو أننا نحتاج الآن إلى تحديد الواجهة العامة للعقد الذكي بشكل صريح باستخدام السمات المشروحة بخاصية starknet :: interface.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: contract] mod تملكها {...}
إذا كنت تتذكر الرمز الأصلي من الإصدار 1 ، فإن عقدنا الذكي له طريقتان "عامة" (get \ _owner and transfer \ _ Owership) وطريقة واحدة "خاصة" (فقط \ _المالك). هذه الميزة تتعامل فقط مع الطرق العامة ، ولا تعتمد على السمات "الخارجية" أو "العرض" للإشارة إلى الطرق التي يمكنها تعديل حالة العقد والطرق التي لا يمكنها ذلك. بدلاً من ذلك ، يتم توضيح ذلك الآن من خلال نوع المعلمة self.
إذا كانت الطريقة تتطلب مرجعًا إلى ContractStorage (وهو ما يفعله T العام بمجرد تنفيذه) ، فإن هذه الطريقة قادرة على تعديل الحالة الداخلية للعقد الذكي. هذا ما اعتدنا أن نسميه طريقة "خارجية". من ناحية أخرى ، إذا كانت الطريقة تتطلب لقطة من ContractStorage ، فيمكنها قراءتها فقط ، وليس تعديلها. هذا ما اعتدنا أن نسميه طريقة "العرض".
يمكننا الآن إنشاء تنفيذ للسمة التي حددناها للتو باستخدام الكلمة الأساسية الضمنية. تذكر أن القاهرة تختلف عن روست في أن التطبيقات لها أسماء.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {let prev \ _owner = self.owner.read () ؛ self.owner.write (جديد \ _المالك) ؛ }
fn get \ _owner (self:ContractState) -> ContractAddress {self.owner.read ()}
نقوم بإنشاء تنفيذ لسماتنا داخل الوحدة النمطية التي تحدد العقد الذكي ، وتمرير النوع ContractState كنوع عام T بحيث يمكن الوصول إلى التخزين مثل المُنشئ.
تم شرح تنفيذنا بالسمة الخارجية (v0). الإصدار 0 في السمة يعني أن المحدد مشتق فقط من اسم الطريقة ، كما كان الحال في الماضي. الجانب السلبي هو أنك إذا حددت تطبيقًا آخر لسمة مختلفة لعقدك الذكي ، وحدثت سمتان تستخدمان نفس الاسم لإحدى طريقتهما ، فسيرمي المترجم خطأ بسبب المحدِّد المكرر.
قد يضيف الإصدار المستقبلي من هذه الخاصية طريقة جديدة لتقييم المحددات لمنع التعارضات ، ولكن هذا لا يعمل حتى الآن. حاليًا ، يمكننا فقط استخدام الإصدار 0 من الخصائص الخارجية.
الطرق الخاصة
نحتاج أيضًا إلى تحديد طريقة أخرى للعقد الذكي ، فقط \ _المالك. تتحقق هذه الطريقة مما إذا كان الشخص الذي يتصل بها يجب أن يكون صاحب العقد الذكي.
نظرًا لأن هذه طريقة خاصة لا يُسمح باستدعاؤها من الخارج ، فلا يمكن تعريفها كجزء من OwnableTrait (الواجهة العامة للعقد الذكي). بدلاً من ذلك ، سنستخدم السمة create \ _trait لإنشاء تطبيق جديد للسمة المُنشأة تلقائيًا.
... # [starknet :: contract] mod ملكية {... # [إنشاء \ _trait] ضمنيًا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {let caller = get \ _caller \ _address ()؛ تأكيد (caller == self.owner.read () ، "المتصل ليس المالك") ؛ }
يمكن الآن استخدام طريقة \ _owner فقط عن طريق استدعاء self.only \ _owner () عند الحاجة.
[starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {self.only \ _owner () ؛ ...} ...}
[create \ _trait] ضمنا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {...}
حدث
في الإصدار 1 من القاهرة ، كان الحدث مجرد وظيفة بدون جسم وتم التعليق عليه بسمة الحدث ، بينما في الإصدار 2 ، يكون الحدث عبارة عن تعداد توضيحي بنفس السمة ، ولكن يتم تنفيذه الآن باستخدام اشتقاق بعض الميزات الإضافية.
... # [starknet :: contract] mod تملكها {... # [event] # [derive (Drop، starknet :: Event)] تعداد الحدث {OwnershipTransferred: OwnershipTransferred،}
يجب أن يكون كل متغير من تعداد الأحداث بنية بنفس الاسم. في هذه البنية ، نستخدم سمة المفتاح الاختيارية لتحديد جميع القيم التي نريد إصدارها ، لإبلاغ النظام بالقيم التي نريد أن يقوم Starknet بفهرستها ، حتى يتمكن المفهرس من البحث والاسترداد بشكل أسرع. في هذه الحالة ، نريد فهرسة قيمتين (prev \ _owner and new \ _owner).
تحدد سمة ContractState طريقة إرسال يمكن استخدامها لإصدار الأحداث.
... # [starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {.. . self.emit (Event :: OwnershipTransferred (OwnershipTransferred {prev \ _owner: prev \ _owner، new \ _owner: new \ _owner،}))؛ } ...} ...}
مع هذه الميزة النهائية ، أكملنا ترحيل العقد الذكي Ownable من الإصدار 1 إلى الإصدار 2. يظهر الرمز الكامل أدناه.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: Contract] mod Ownable {use super :: ContractAddress؛ استخدم starknet :: get \ _caller \ _address؛
[external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {self.only \ _owner ()؛ اسمحوا prev \ _owner = self.owner.read () ؛ self.owner.write (جديد \ _المالك) ؛ self.emit (Event :: OwnershipTransferred (OwnershipTransferred {prev \ _owner: prev \ _owner، new \ _owner: new \ _owner،})) ؛ }
fn get \ _owner (self:ContractState) -> ContractAddress {self.owner.read ()}}
[create \ _trait] ضمنا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {let caller = get \ _caller \ _address ()؛ تأكيد (caller == self.owner.read () ، "المتصل ليس المالك") ؛ }
يمكنك أيضًا العثور على هذا الرمز على جيثب.
ختاماً
الإصدار 2 من مترجم القاهرة يجلب بنية جديدة إلى Starknet تجعل كود العقد الذكي يبدو أكثر اتساقًا مع القاهرة نفسها ، وبالتالي ، أكثر شبهاً بصدأ. حتى على حساب رمز أكثر تعقيدًا ، فإن مزايا الأمان تستحق المقايضة.
في هذه المقالة ، لم نتطرق إلى كل شيء يتعلق بالصيغة الجديدة ، لا سيما كيفية تفاعلها مع العقود الذكية الأخرى ، ولكن يمكنك قراءة سجل التغيير الخاص بالمترجم ، أو قراءة هذا المنشور على المنتدى ، أو مشاهدة مقطع فيديو على قناة StarkWare على YouTube لمعرفة المزيد حول هذا الموضوع.لمعرفة المزيد من المعلومات.
سيكون هذا الإصدار الجديد من المترجم متاحًا على testnet الخاص بـ Starknet في غضون بضعة أسابيع و mainnet في غضون بضعة أسابيع ، لذلك لا تحاول نشر هذا الكود الآن ، فهو لن يعمل بعد.
القاهرة تتحسن باستمرار.
** المورد **
بناء جملة العقد - دليل الترحيل
القاهرة 1: بناء جملة العقد آخذ في التطور
شاهد النسخة الأصلية
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
التفسير الكامل لقواعد Starknet المحسنة
الأصل: تحسين تركيب Starknet
الترجمة والتدقيق اللغوي: "مجتمع ستاركنت الصيني"
! [تفسير كامل لقواعد نحوية محسنة لـ Starknet] (https://img-cdn.gateio.im/resized-social/moments-69a80767fe-553ed1d6a1-dd1a6f-7649e1)
ملخص
يقدم الإصدار 2 من مترجم القاهرة تغييرات في بناء جملة Starknet لجعل الشفرة أكثر وضوحًا وأمانًا. يتم تعريف الواجهة العامة للعقد الذكي باستخدام السمات ، ويتم الوصول إلى التخزين من خلال سمة ContractState. يجب تحديد الأساليب الخاصة بتطبيق مختلف عن الواجهة العامة. يتم الآن تعريف الأحداث على أنها تعدادات ، حيث يكون كل متغير عبارة عن بنية تحمل الاسم نفسه.
إخلاء المسؤولية: تشير المصطلحات المستخدمة هنا إلى إصدارات مختلفة من مترجم القاهرة ، والصياغة مؤقتة لأن مجتمع Starknet لا يزال يناقش حول أفضل مصطلح يمكن استخدامه. بمجرد تحديدها ، سيتم تحديث هذه المقالة وفقًا لذلك.
المترجم v2.0
في الأسبوع الماضي فقط ، تم إطلاق إصدار رئيسي جديد 2.0.0-rc0 من مترجم القاهرة على جيثب. يوفر المترجم الجديد تحسينات كبيرة على المكون الإضافي Starknet ، مما يجعل الكود الخاص بنا أكثر أمانًا وأكثر وضوحًا وقابلية لإعادة الاستخدام. لاحظ أن هذا الإصدار الجديد من المترجم غير مدعوم بعد على ** Starknet testnet أو mainnet ** لأنه لا يزال قيد العمل في البيئة المتكاملة.
الهدف من هذه المقالة هو توضيح كيفية إعادة كتابة عقد Starknet الذكي الذي تم إنشاؤه لمجمع القاهرة الإصدار 1.x في عقد ذكي متوافق مع الإصدار 2.x. نقطة البداية لدينا هي العقد الذكي Ownable الذي تم إنشاؤه في المقالة السابقة ، وهو متوافق مع برنامج التحويل البرمجي Cario الإصدار 1.x.
[contract] mod الملكية {use starknet :: ContractAddress ؛ استخدم starknet :: get \ _caller \ _address؛
[event] fn OwnershipTransferred (previous \ _owner: ContractAddress، new \ _owner: ContractAddress) {}
تخزين هيكلي {owner: ContractAddress،}
[constructor] fn constructor () {letloyer = get \ _caller \ _address ()؛ owner :: write (publisher)؛}
[view] fn get \ _owner () -> ContractAddress {owner :: read ()}
[external] fn transfer \ _ownership (new \ _owner: ContractAddress) {only \ _owner ()؛ let previous \ _owner = owner :: read ()؛ owner :: write (new \ _owner)؛ نقل الملكية (السابق \ _المالك والجديد \ _المالك) ؛}
fn only \ _owner () {let caller = get \ _caller \ _address ()؛ تأكيد (caller == owner :: read ()، 'Caller ليس المالك')؛
إعدادات المشروع
نظرًا لأن Protostar لا يدعم المترجم v2 بعد ، فستعتمد هذه المقالة على الإصدار التجريبي من Scarb (الإصدار 0.5.0-alpha.1) الذي يدعمه. لتثبيت هذا الإصدار المحدد من Scarb ، يمكنك استخدام الأمر التالي.
$ --proto '= https' --tlsv1.2 -sSf | bash -s - -v 0.5.0-alpha.1
بعد اكتمال التثبيت ، تحقق من أن لديك الإصدار الصحيح.
Scarb $ - الإصدار >>> Scarb 0.5.0-alpha.1 (546dad33d 2023-06-19) القاهرة: 2.0.0-rc3 ()
يمكن الآن إنشاء مشروع Scarb.
سكارب القاهرة الجديدة 1 \ _v2 $ cdcairo1 \ _v2
يجب أن تحصل على هيكل مجلد كما هو موضح أدناه.
شجرة $. >>>. ├── Scarb.toml└── src└──lib.cairo
لكي يقوم Scarb بتجميع عقود Starknet الذكية ، يجب تمكين المكون الإضافي Starknet كعنصر تبعية.
// Scarb.toml ... [dependencies] ستاركنت = "2.0.0-rc3"
بعد اكتمال الإعداد ، يمكننا التوجه إلى src / lib.cairo والبدء في كتابة العقود الذكية.
التخزين والمنشئ
في الإصدار 2 من برنامج التحويل البرمجي للقاهرة ، لا تزال العقود الذكية تُحدد من خلال وحدات مشروحة بسمة العقد ، ولكن هذه المرة فقط يتم تسمية السمة على اسم الملحق الذي يحددها ، في هذه الحالة starknet.
[starknet :: contract] mod تملكها {}
لا يزال يتم تعريف التخزين الداخلي على أنه بنية يجب أن تسمى التخزين ، ولكن هذه المرة فقط يجب أن يتم التعليق عليها بسمة تخزين.
[starknet :: Contract] mod Ownable {use super :: ContractAddress؛ # [storage] تخزين هيكلي {owner: ContractAddress،
لتعريف المُنشئ ، قمنا بتعليق الدالة بخاصية المُنشئ ، كما فعلنا في v1 ، والميزة هي أنه يمكن الآن أن يكون للوظيفة أي اسم ، ولا يلزم أن يُطلق عليها اسم "المُنشئ" كما هو الحال في v1. على الرغم من أنه ليس مطلوبًا ، ما زلت أشير إلى الوظيفة على أنها "مُنشئ" خارج الاصطلاح ، ولكن يمكنك تسميتها بشكل مختلف.
تغيير مهم آخر هو أن المُنشئ الآن يقوم تلقائيًا بتمرير مرجع إلى ContractState ، والذي يعمل كوسيط لتخزين المتغيرات ، في هذه الحالة "مالك".
[starknet :: Contract] mod Ownable {use super :: ContractAddress؛ # [storage] تخزين هيكلي {owner: ContractAddress،} # [constructor] fn constructor (ref self: ContractState) {letloyer = get \ _caller \ _address ()؛ self.owner.write (publisher)؛
لاحظ أن بنية تخزين الكتابة والقراءة قد تغيرت منذ الإصدار 1. قبل أن نكتب المالك :: write () ، نقوم الآن بكتابة self.owner.write (). الأمر نفسه ينطبق على القراءة من التخزين.
بالمناسبة ، لا يلزم إدخال نوع ContractState يدويًا في النطاق ، فهو مدرج في المقدمة.
الطرق العامة
هناك اختلاف مهم عن الإصدار 1 من مترجم القاهرة وهو أننا نحتاج الآن إلى تحديد الواجهة العامة للعقد الذكي بشكل صريح باستخدام السمات المشروحة بخاصية starknet :: interface.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: contract] mod تملكها {...}
إذا كنت تتذكر الرمز الأصلي من الإصدار 1 ، فإن عقدنا الذكي له طريقتان "عامة" (get \ _owner and transfer \ _ Owership) وطريقة واحدة "خاصة" (فقط \ _المالك). هذه الميزة تتعامل فقط مع الطرق العامة ، ولا تعتمد على السمات "الخارجية" أو "العرض" للإشارة إلى الطرق التي يمكنها تعديل حالة العقد والطرق التي لا يمكنها ذلك. بدلاً من ذلك ، يتم توضيح ذلك الآن من خلال نوع المعلمة self.
إذا كانت الطريقة تتطلب مرجعًا إلى ContractStorage (وهو ما يفعله T العام بمجرد تنفيذه) ، فإن هذه الطريقة قادرة على تعديل الحالة الداخلية للعقد الذكي. هذا ما اعتدنا أن نسميه طريقة "خارجية". من ناحية أخرى ، إذا كانت الطريقة تتطلب لقطة من ContractStorage ، فيمكنها قراءتها فقط ، وليس تعديلها. هذا ما اعتدنا أن نسميه طريقة "العرض".
يمكننا الآن إنشاء تنفيذ للسمة التي حددناها للتو باستخدام الكلمة الأساسية الضمنية. تذكر أن القاهرة تختلف عن روست في أن التطبيقات لها أسماء.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {let prev \ _owner = self.owner.read () ؛ self.owner.write (جديد \ _المالك) ؛ }
fn get \ _owner (self:ContractState) -> ContractAddress {self.owner.read ()}
نقوم بإنشاء تنفيذ لسماتنا داخل الوحدة النمطية التي تحدد العقد الذكي ، وتمرير النوع ContractState كنوع عام T بحيث يمكن الوصول إلى التخزين مثل المُنشئ.
تم شرح تنفيذنا بالسمة الخارجية (v0). الإصدار 0 في السمة يعني أن المحدد مشتق فقط من اسم الطريقة ، كما كان الحال في الماضي. الجانب السلبي هو أنك إذا حددت تطبيقًا آخر لسمة مختلفة لعقدك الذكي ، وحدثت سمتان تستخدمان نفس الاسم لإحدى طريقتهما ، فسيرمي المترجم خطأ بسبب المحدِّد المكرر.
قد يضيف الإصدار المستقبلي من هذه الخاصية طريقة جديدة لتقييم المحددات لمنع التعارضات ، ولكن هذا لا يعمل حتى الآن. حاليًا ، يمكننا فقط استخدام الإصدار 0 من الخصائص الخارجية.
الطرق الخاصة
نحتاج أيضًا إلى تحديد طريقة أخرى للعقد الذكي ، فقط \ _المالك. تتحقق هذه الطريقة مما إذا كان الشخص الذي يتصل بها يجب أن يكون صاحب العقد الذكي.
نظرًا لأن هذه طريقة خاصة لا يُسمح باستدعاؤها من الخارج ، فلا يمكن تعريفها كجزء من OwnableTrait (الواجهة العامة للعقد الذكي). بدلاً من ذلك ، سنستخدم السمة create \ _trait لإنشاء تطبيق جديد للسمة المُنشأة تلقائيًا.
... # [starknet :: contract] mod ملكية {... # [إنشاء \ _trait] ضمنيًا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {let caller = get \ _caller \ _address ()؛ تأكيد (caller == self.owner.read () ، "المتصل ليس المالك") ؛ }
يمكن الآن استخدام طريقة \ _owner فقط عن طريق استدعاء self.only \ _owner () عند الحاجة.
[starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {self.only \ _owner () ؛ ...} ...}
[create \ _trait] ضمنا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {...}
حدث
في الإصدار 1 من القاهرة ، كان الحدث مجرد وظيفة بدون جسم وتم التعليق عليه بسمة الحدث ، بينما في الإصدار 2 ، يكون الحدث عبارة عن تعداد توضيحي بنفس السمة ، ولكن يتم تنفيذه الآن باستخدام اشتقاق بعض الميزات الإضافية.
... # [starknet :: contract] mod تملكها {... # [event] # [derive (Drop، starknet :: Event)] تعداد الحدث {OwnershipTransferred: OwnershipTransferred،}
[derive (Drop، starknet :: Event)] Struct OwnershipTransferred {# [key] prev \ _owner: ContractAddress، # [key] المالك الجديد: ContractAddress ،
يجب أن يكون كل متغير من تعداد الأحداث بنية بنفس الاسم. في هذه البنية ، نستخدم سمة المفتاح الاختيارية لتحديد جميع القيم التي نريد إصدارها ، لإبلاغ النظام بالقيم التي نريد أن يقوم Starknet بفهرستها ، حتى يتمكن المفهرس من البحث والاسترداد بشكل أسرع. في هذه الحالة ، نريد فهرسة قيمتين (prev \ _owner and new \ _owner).
تحدد سمة ContractState طريقة إرسال يمكن استخدامها لإصدار الأحداث.
... # [starknet :: contract] mod Ownable {... # [external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {.. . self.emit (Event :: OwnershipTransferred (OwnershipTransferred {prev \ _owner: prev \ _owner، new \ _owner: new \ _owner،}))؛ } ...} ...}
مع هذه الميزة النهائية ، أكملنا ترحيل العقد الذكي Ownable من الإصدار 1 إلى الإصدار 2. يظهر الرمز الكامل أدناه.
استخدام starknet :: ContractAddress ؛
[starknet :: interface] سمة OwnableTrait {fn transfer \ _ownership (ref self: T، new \ _owner: ContractAddress)؛ fn get \ _owner (self:T) -> ContractAddress ؛}
[starknet :: Contract] mod Ownable {use super :: ContractAddress؛ استخدم starknet :: get \ _caller \ _address؛
[event] # [derive (Drop، starknet :: Event)] تعداد الحدث {OwnershipTransferred: OwnershipTransferred،}
[derive (Drop، starknet :: Event)] Struct OwnershipTransferred {# [key] prev \ _owner: ContractAddress، # [key] المالك الجديد: ContractAddress ،}
[storage] تخزين هيكلي {owner: ContractAddress،}
[constructor] fn constructor (ref self: ContractState) {letloyer = get \ _caller \ _address ()؛ self.owner.write (النشر) ؛ }
[external (v0)] impl OwnableImpl of super :: OwnableTrait {fn transfer \ _ownership (ref self: ContractState، new \ _owner: ContractAddress) {self.only \ _owner ()؛ اسمحوا prev \ _owner = self.owner.read () ؛ self.owner.write (جديد \ _المالك) ؛ self.emit (Event :: OwnershipTransferred (OwnershipTransferred {prev \ _owner: prev \ _owner، new \ _owner: new \ _owner،})) ؛ }
fn get \ _owner (self:ContractState) -> ContractAddress {self.owner.read ()}}
[create \ _trait] ضمنا PrivateMethods of PrivateMethodsTrait {fn only \ _owner (self:ContractState) {let caller = get \ _caller \ _address ()؛ تأكيد (caller == self.owner.read () ، "المتصل ليس المالك") ؛ }
يمكنك أيضًا العثور على هذا الرمز على جيثب.
ختاماً
الإصدار 2 من مترجم القاهرة يجلب بنية جديدة إلى Starknet تجعل كود العقد الذكي يبدو أكثر اتساقًا مع القاهرة نفسها ، وبالتالي ، أكثر شبهاً بصدأ. حتى على حساب رمز أكثر تعقيدًا ، فإن مزايا الأمان تستحق المقايضة.
في هذه المقالة ، لم نتطرق إلى كل شيء يتعلق بالصيغة الجديدة ، لا سيما كيفية تفاعلها مع العقود الذكية الأخرى ، ولكن يمكنك قراءة سجل التغيير الخاص بالمترجم ، أو قراءة هذا المنشور على المنتدى ، أو مشاهدة مقطع فيديو على قناة StarkWare على YouTube لمعرفة المزيد حول هذا الموضوع.لمعرفة المزيد من المعلومات.
سيكون هذا الإصدار الجديد من المترجم متاحًا على testnet الخاص بـ Starknet في غضون بضعة أسابيع و mainnet في غضون بضعة أسابيع ، لذلك لا تحاول نشر هذا الكود الآن ، فهو لن يعمل بعد.
القاهرة تتحسن باستمرار.
** المورد **