تخطي إلى المحتوى الرئيسي

التفاعل مع العقود الأخرى من ⁦Solidity⁩

العقود الذكية
solidity
remix
النشر
قابلية التركيب
متقدم
jdourlens
5 أبريل 2020
4 دقيقة للقراءة
تعديل الصفحة (opens in a new tab)

في البرامج التعليمية السابقة، تعلمنا الكثير حول كيفية نشر أول عقد ذكي لك وإضافة بعض الميزات إليه مثل التحكم في الوصول باستخدام المُعدِّلات (opens in a new tab) أو معالجة الأخطاء في ⁦Solidity⁩ (opens in a new tab). في هذا البرنامج التعليمي، سنتعلم كيفية نشر عقد ذكي من عقد موجود والتفاعل معه.

سنقوم بإنشاء عقد يمكّن أي شخص من امتلاك عقد ذكي Counter خاص به عن طريق إنشاء مصنع له، وسيكون اسمه CounterFactory. أولاً، إليك كود العقد الذكي Counter الأولي الخاص بنا:

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

لهذا أضفنا أيضًا مُعدِّل onlyFactory للتأكد من أن دالة تغيير الحالة لا يمكن استدعاؤها إلا بواسطة المصنع الذي سيمرر المتصل الأصلي كمعلمة.

داخل CounterFactory الجديد الخاص بنا والذي سيدير جميع العدادات الأخرى، سنضيف تعيينًا (mapping) يربط المالك بعنوان عقد العداد الخاص به:

mapping(address => Counter) _counters;

في إيثيريوم، التعيينات (mappings) تعادل الكائنات (objects) في JavaScript، فهي تتيح تعيين مفتاح من النوع A إلى قيمة من النوع B. في هذه الحالة، نقوم بتعيين عنوان المالك مع نسخة العداد الخاصة به.

سيبدو إنشاء نسخة جديدة من العداد لشخص ما هكذا:

  function createCounter() public {
      require (_counters[msg.sender] == Counter(0));
      _counters[msg.sender] = new Counter(msg.sender);
  }

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

للحصول على عدد عداد معين، سيبدو الأمر هكذا:

function getCount(address account) public view returns (uint256) {
    require (_counters[account] != Counter(0));
    return (_counters[account].getCount());
}

function getMyCount() public view returns (uint256) {
    return (getCount(msg.sender));
}

تتحقق الدالة الأولى مما إذا كان عقد العداد موجودًا لعنوان معين ثم تستدعي طريقة getCount من النسخة. الدالة الثانية: getMyCount هي مجرد اختصار لتمرير msg.sender مباشرة إلى دالة getCount.

دالة increment مشابهة تمامًا ولكنها تمرر مرسل المعاملة الأصلي إلى عقد Counter:

function increment() public {
      require (_counters[msg.sender] != Counter(0));
      Counter(_counters[msg.sender]).increment(msg.sender);
  }

لاحظ أنه إذا تم استدعاؤه مرات عديدة، فقد يقع العداد الخاص بنا ضحية تجاوز السعة. يجب عليك استخدام مكتبة SafeMath (opens in a new tab) قدر الإمكان للحماية من هذه الحالة المحتملة.

لنشر العقد الخاص بنا، ستحتاج إلى توفير كود كل من CounterFactory و Counter. عند النشر على سبيل المثال في Remix، ستحتاج إلى تحديد CounterFactory.

إليك الكود الكامل:

بعد التصريف، في قسم النشر في Remix، ستحدد المصنع الذي سيتم نشره:

Selecting the factory to be deployed in Remix

ثم يمكنك تجربة مصنع العقود الخاص بك والتحقق من تغير القيمة. إذا كنت ترغب في استدعاء العقد الذكي من عنوان مختلف، فستحتاج إلى تغيير العنوان في قائمة تحديد الحساب (Account) في Remix.

آخر تحديث للصفحة: 3 مارس 2026