مرکزی مواد پر جائیں

Solidity سے دوسرے کنٹریکٹس کے ساتھ تعامل کریں

سمارٹ کنٹریکٹس
Solidity
Remix
ڈیپلائنگ
کمپوزیبلٹی
ایڈوانسڈ
jdourlens
5 اپریل، 2020
5 منٹ کی پڑھائی

پچھلے ٹیوٹوریلز میں ہم نے بہت کچھ سیکھا کہ اپنا پہلا سمارٹ کنٹریکٹ کیسے ڈیپلائے کریں اور اس میں کچھ فیچرز کیسے شامل کریں جیسے موڈیفائرز کے ساتھ رسائی کو کنٹرول کرنا (opens in a new tab) یا Solidity میں ایرر ہینڈلنگ (opens in a new tab)۔ اس ٹیوٹوریل میں ہم سیکھیں گے کہ موجودہ کنٹریکٹ سے سمارٹ کنٹریکٹ کو کیسے ڈیپلائے کیا جائے اور اس کے ساتھ کیسے تعامل کیا جائے۔

ہم ایک ایسا کنٹریکٹ بنائیں گے جو کسی کو بھی اس کے لیے ایک فیکٹری بنا کر اپنا Counter سمارٹ کنٹریکٹ رکھنے کے قابل بناتا ہے، اس کا نام CounterFactory ہوگا۔ سب سے پہلے ہمارے ابتدائی Counter سمارٹ کنٹریکٹ کا کوڈ یہ ہے:

1pragma solidity 0.5.17;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
سب دکھائیں

نوٹ کریں کہ ہم نے فیکٹری کے ایڈریس اور کنٹریکٹ کے مالک کے ایڈریس کا ٹریک رکھنے کے لیے کنٹریکٹ کے کوڈ میں تھوڑی سی ترمیم کی ہے۔ جب آپ کسی دوسرے کنٹریکٹ سے کنٹریکٹ کوڈ کو کال کرتے ہیں، تو msg.sender ہماری کنٹریکٹ فیکٹری کے ایڈریس کا حوالہ دے گا۔ یہ سمجھنے کے لیے واقعی ایک اہم نکتہ ہے کیونکہ دوسرے کنٹریکٹس کے ساتھ تعامل کرنے کے لیے کنٹریکٹ کا استعمال ایک عام رواج ہے۔ اس لیے آپ کو پیچیدہ معاملات میں اس بات کا خیال رکھنا چاہیے کہ بھیجنے والا کون ہے۔

اس کے لیے ہم نے ایک onlyFactory موڈیفائر بھی شامل کیا ہے جو اس بات کو یقینی بناتا ہے کہ سٹیٹ تبدیل کرنے والے فنکشن کو صرف فیکٹری کے ذریعے کال کیا جا سکتا ہے جو اصل کالر کو پیرامیٹر کے طور پر پاس کرے گی۔

ہماری نئی CounterFactory کے اندر جو دیگر تمام Counters کا انتظام کرے گی، ہم ایک میپنگ شامل کریں گے جو ایک مالک کو اس کے کاؤنٹر کنٹریکٹ کے ایڈریس سے منسلک کرے گی:

1mapping(address => Counter) _counters;

Ethereum میں، میپنگ javascript میں آبجیکٹس کے مساوی ہیں، وہ ٹائپ A کی کلید کو ٹائپ B کی ویلیو سے میپ کرنے کے قابل بناتے ہیں۔ اس صورت میں ہم مالک کے ایڈریس کو اس کے Counter کی مثال (instance) کے ساتھ میپ کرتے ہیں۔

کسی کے لیے نیا Counter شروع کرنا کچھ اس طرح نظر آئے گا:

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

ہم سب سے پہلے چیک کرتے ہیں کہ آیا اس شخص کے پاس پہلے سے ہی کاؤنٹر ہے۔ اگر اس کے پاس کاؤنٹر نہیں ہے تو ہم اس کا ایڈریس Counter کنسٹرکٹر کو پاس کر کے ایک نیا کاؤنٹر شروع کرتے ہیں اور نئی بنائی گئی مثال کو میپنگ کے لیے تفویض کرتے ہیں۔

کسی مخصوص Counter کی گنتی حاصل کرنے کے لیے یہ کچھ اس طرح نظر آئے گا:

1function getCount(address account) public view returns (uint256) {
2 require (_counters[account] != Counter(0));
3 return (_counters[account].getCount());
4}
5
6function getMyCount() public view returns (uint256) {
7 return (getCount(msg.sender));
8}

پہلا فنکشن چیک کرتا ہے کہ آیا دیے گئے ایڈریس کے لیے Counter کنٹریکٹ موجود ہے اور پھر مثال سے getCount طریقہ کار کو کال کرتا ہے۔ دوسرا فنکشن: getMyCount صرف msg.sender کو براہ راست getCount فنکشن میں پاس کرنے کا ایک مختصر طریقہ ہے۔

increment فنکشن بالکل یکساں ہے لیکن اصل ٹرانزیکشن بھیجنے والے کو Counter کنٹریکٹ میں پاس کرتا ہے:

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

نوٹ کریں کہ اگر بہت زیادہ بار کال کیا جائے تو، ہمارا کاؤنٹر ممکنہ طور پر اوور فلو کا شکار ہو سکتا ہے۔ اس ممکنہ صورتحال سے بچنے کے لیے آپ کو زیادہ سے زیادہ SafeMath لائبریری (opens in a new tab) کا استعمال کرنا چاہیے۔

ہمارے کنٹریکٹ کو ڈیپلائے کرنے کے لیے، آپ کو CounterFactory اور Counter دونوں کا کوڈ فراہم کرنے کی ضرورت ہوگی۔ مثال کے طور پر Remix میں ڈیپلائے کرتے وقت آپ کو CounterFactory کو منتخب کرنے کی ضرورت ہوگی۔

مکمل کوڈ یہ ہے:

1pragma solidity 0.5.17;
2
3contract Counter {
4
5 uint256 private _count;
6 address private _owner;
7 address private _factory;
8
9
10 modifier onlyOwner(address caller) {
11 require(caller == _owner, "You're not the owner of the contract");
12 _;
13 }
14
15 modifier onlyFactory() {
16 require(msg.sender == _factory, "You need to use the factory");
17 _;
18 }
19
20 constructor(address owner) public {
21 _owner = owner;
22 _factory = msg.sender;
23 }
24
25 function getCount() public view returns (uint256) {
26 return _count;
27 }
28
29 function increment(address caller) public onlyFactory onlyOwner(caller) {
30 _count++;
31 }
32
33}
34
35contract CounterFactory {
36
37 mapping(address => Counter) _counters;
38
39 function createCounter() public {
40 require (_counters[msg.sender] == Counter(0));
41 _counters[msg.sender] = new Counter(msg.sender);
42 }
43
44 function increment() public {
45 require (_counters[msg.sender] != Counter(0));
46 Counter(_counters[msg.sender]).increment(msg.sender);
47 }
48
49 function getCount(address account) public view returns (uint256) {
50 require (_counters[account] != Counter(0));
51 return (_counters[account].getCount());
52 }
53
54 function getMyCount() public view returns (uint256) {
55 return (getCount(msg.sender));
56 }
57
58}
سب دکھائیں

مرتب (compile) کرنے کے بعد، Remix ڈیپلائے سیکشن میں آپ ڈیپلائے کی جانے والی فیکٹری کو منتخب کریں گے:

Remix میں ڈیپلائے کی جانے والی فیکٹری کا انتخاب کرنا

پھر آپ اپنی کنٹریکٹ فیکٹری کے ساتھ کھیل سکتے ہیں اور تبدیل ہونے والی ویلیو کو چیک کر سکتے ہیں۔ اگر آپ سمارٹ کنٹریکٹ کو کسی مختلف ایڈریس سے کال کرنا چاہتے ہیں تو آپ کو Remix کے اکاؤنٹ سلیکٹ میں ایڈریس تبدیل کرنے کی ضرورت ہوگی۔

صفحہ کی آخری اپ ڈیٹ: 15 اگست، 2023

کیا یہ ٹیوٹوریل مددگار تھا؟