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

اسمارٹ کانٹریکٹس کی ساخت

صفحہ کی آخری اپ ڈیٹ: 23 فروری، 2026

اسمارٹ کانٹریکٹ ایک پروگرام ہے جو ایتھیریم پر ایک ایڈریس پر چلتا ہے۔ یہ ڈیٹا اور فنکشنز پر مشتمل ہوتے ہیں جو ٹرانزیکشن موصول ہونے پر عمل میں آ سکتے ہیں۔ یہاں اسمارٹ کانٹریکٹ کے اجزاء کا ایک جائزہ دیا گیا ہے۔

بنیادی شرائط

یقینی بنائیں کہ آپ نے پہلے اسمارٹ کانٹریکٹس کے بارے میں پڑھ لیا ہے۔ یہ دستاویز فرض کرتی ہے کہ آپ پہلے ہی JavaScript یا Python جیسی پروگرامنگ زبانوں سے واقف ہیں۔

ڈیٹا

کسی بھی کانٹریکٹ کے ڈیٹا کو ایک مقام تفویض کیا جانا چاہیے: یا تو storage یا memory۔ اسمارٹ کانٹریکٹ میں اسٹوریج کو تبدیل کرنا مہنگا ہوتا ہے، اس لیے آپ کو غور کرنا چاہیے کہ آپ کا ڈیٹا کہاں رہنا چاہیے۔

اسٹوریج

مستقل ڈیٹا کو اسٹوریج کہا جاتا ہے اور اسے اسٹیٹ ویری ایبلز کے ذریعے ظاہر کیا جاتا ہے۔ یہ قدریں بلاک چین پر مستقل طور پر محفوظ ہو جاتی ہیں۔ آپ کو اس کی قسم (type) کا اعلان کرنے کی ضرورت ہوتی ہے تاکہ کانٹریکٹ مرتب (compile) ہوتے وقت یہ حساب رکھ سکے کہ اسے بلاک چین پر کتنی اسٹوریج درکار ہے۔

1// Solidity کی مثال
2contract SimpleStorage {
3 uint storedData; // اسٹیٹ ویری ایبل
4 // ...
5}
1# Vyper کی مثال
2storedData: int128

اگر آپ نے پہلے ہی آبجیکٹ اورینٹڈ زبانوں میں پروگرامنگ کی ہے، تو آپ ممکنہ طور پر زیادہ تر اقسام سے واقف ہوں گے۔ تاہم، اگر آپ Ethereum ڈیولپمنٹ میں نئے ہیں تو address آپ کے لیے نیا ہونا چاہیے۔

ایک address ٹائپ ایتھیریم ایڈریس کو محفوظ کر سکتی ہے جو 20 بائٹس یا 160 بٹس کے برابر ہوتا ہے۔ یہ ہیکسا ڈیسیمل (hexadecimal) شکل میں واپس آتا ہے جس کے شروع میں 0x ہوتا ہے۔

دیگر اقسام میں شامل ہیں:

  • boolean
  • integer
  • fixed point numbers
  • fixed-size byte arrays
  • dynamically sized byte arrays
  • rational and integer literals
  • string literals
  • hexadecimal literals
  • enums

مزید وضاحت کے لیے، دستاویزات دیکھیں:

میموری

وہ قدریں جو صرف کانٹریکٹ فنکشن کے چلنے کی مدت تک محفوظ رہتی ہیں، میموری ویری ایبلز کہلاتی ہیں۔ چونکہ یہ بلاک چین پر مستقل طور پر محفوظ نہیں ہوتیں، اس لیے ان کا استعمال بہت سستا ہوتا ہے۔

EVM ڈیٹا کو کیسے محفوظ کرتا ہے (اسٹوریج، میموری، اور اسٹیک) اس بارے میں مزید جاننے کے لیے Solidity کی دستاویزات (opens in a new tab) دیکھیں۔

انوائرنمنٹ ویری ایبلز

آپ کے کانٹریکٹ میں بیان کردہ ویری ایبلز کے علاوہ، کچھ خاص گلوبل ویری ایبلز بھی ہوتے ہیں۔ یہ بنیادی طور پر بلاک چین یا موجودہ ٹرانزیکشن کے بارے میں معلومات فراہم کرنے کے لیے استعمال ہوتے ہیں۔

مثالیں:

پراپرٹیاسٹیٹ ویری ایبلتفصیل
block.timestampuint256موجودہ بلاک کا ایپوک ٹائم اسٹیمپ
msg.senderaddressپیغام بھیجنے والا (موجودہ کال)

فنکشنز

آسان ترین الفاظ میں، فنکشنز آنے والی ٹرانزیکشنز کے جواب میں معلومات حاصل کر سکتے ہیں یا معلومات سیٹ کر سکتے ہیں۔

فنکشن کالز کی دو اقسام ہیں:

  • internal – یہ EVM کال نہیں بناتے
    • انٹرنل فنکشنز اور اسٹیٹ ویری ایبلز تک صرف اندرونی طور پر رسائی حاصل کی جا سکتی ہے (یعنی موجودہ کانٹریکٹ یا اس سے اخذ کردہ کانٹریکٹس کے اندر سے)
  • external – یہ EVM کال بناتے ہیں
    • ایکسٹرنل فنکشنز کانٹریکٹ انٹرفیس کا حصہ ہوتے ہیں، جس کا مطلب ہے کہ انہیں دوسرے کانٹریکٹس سے اور ٹرانزیکشنز کے ذریعے کال کیا جا سکتا ہے۔ ایک ایکسٹرنل فنکشن f کو اندرونی طور پر کال نہیں کیا جا سکتا (یعنی f() کام نہیں کرتا، لیکن this.f() کام کرتا ہے)۔

یہ public یا private بھی ہو سکتے ہیں

  • public فنکشنز کو کانٹریکٹ کے اندر سے اندرونی طور پر یا پیغامات کے ذریعے بیرونی طور پر کال کیا جا سکتا ہے
  • private فنکشنز صرف اسی کانٹریکٹ کے لیے نظر آتے ہیں جس میں ان کی تعریف کی گئی ہو اور اخذ کردہ (derived) کانٹریکٹس میں نہیں

فنکشنز اور اسٹیٹ ویری ایبلز دونوں کو پبلک یا پرائیویٹ بنایا جا سکتا ہے

یہاں کانٹریکٹ پر اسٹیٹ ویری ایبل کو اپ ڈیٹ کرنے کے لیے ایک فنکشن دیا گیا ہے:

1// Solidity کی مثال
2function update_name(string value) public {
3 dapp_name = value;
4}
  • string ٹائپ کا پیرامیٹر value فنکشن میں پاس کیا جاتا ہے: update_name
  • اسے public قرار دیا گیا ہے، جس کا مطلب ہے کہ کوئی بھی اس تک رسائی حاصل کر سکتا ہے
  • اسے view قرار نہیں دیا گیا، اس لیے یہ کانٹریکٹ کی اسٹیٹ کو تبدیل کر سکتا ہے

ویو فنکشنز (View functions)

یہ فنکشنز کانٹریکٹ کے ڈیٹا کی اسٹیٹ کو تبدیل نہ کرنے کا وعدہ کرتے ہیں۔ عام مثالیں "getter" فنکشنز ہیں – مثال کے طور پر آپ اسے صارف کا بیلنس حاصل کرنے کے لیے استعمال کر سکتے ہیں۔

1// Solidity کی مثال
2function balanceOf(address _owner) public view returns (uint256 _balance) {
3 return ownerPizzaCount[_owner];
4}
1dappName: public(string)
2
3@view
4@public
5def readName() -> string:
6 return dappName

اسٹیٹ کو تبدیل کرنا کیا سمجھا جاتا ہے:

  1. اسٹیٹ ویری ایبلز میں لکھنا۔
  2. ایونٹس کا اخراج (Emitting events) (opens in a new tab)۔
  3. دوسرے کانٹریکٹس بنانا (opens in a new tab)۔
  4. selfdestruct کا استعمال۔
  5. کالز کے ذریعے ایتھر (ether) بھیجنا۔
  6. کسی ایسے فنکشن کو کال کرنا جس پر view یا pure کا نشان نہ ہو۔
  7. لو-لیول (low-level) کالز کا استعمال۔
  8. ان لائن اسمبلی (inline assembly) کا استعمال جس میں مخصوص اوپ کوڈز (opcodes) شامل ہوں۔

کنسٹرکٹر فنکشنز (Constructor functions)

constructor فنکشنز صرف ایک بار چلتے ہیں جب کانٹریکٹ پہلی بار ڈیپلائے (deploy) ہوتا ہے۔ بہت سی کلاس پر مبنی پروگرامنگ زبانوں میں constructor کی طرح، یہ فنکشنز اکثر اسٹیٹ ویری ایبلز کو ان کی مخصوص قدروں کے ساتھ شروع (initialize) کرتے ہیں۔

1// Solidity کی مثال
2// کانٹریکٹ کا ڈیٹا انیشلائز کرتا ہے، `owner` کو سیٹ کرتا ہے
3// کانٹریکٹ بنانے والے کے ایڈریس پر۔
4constructor() public {
5 // تمام سمارٹ کانٹریکٹس اپنے فنکشنز کو متحرک کرنے کے لیے بیرونی ٹرانزیکشنز پر انحصار کرتے ہیں۔
6 // `msg` ایک گلوبل ویری ایبل ہے جس میں دی گئی ٹرانزیکشن کا متعلقہ ڈیٹا شامل ہوتا ہے،
7 // جیسے بھیجنے والے کا ایڈریس اور ٹرانزیکشن میں شامل ETH کی ویلیو۔
8 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
9 owner = msg.sender;
10}
سب دکھائیں
1# Vyper کی مثال
2
3@external
4def __init__(_beneficiary: address, _bidding_time: uint256):
5 self.beneficiary = _beneficiary
6 self.auctionStart = block.timestamp
7 self.auctionEnd = self.auctionStart + _bidding_time

بلٹ ان فنکشنز (Built-in functions)

آپ کے کانٹریکٹ میں بیان کردہ ویری ایبلز اور فنکشنز کے علاوہ، کچھ خاص بلٹ ان فنکشنز بھی ہوتے ہیں۔ سب سے واضح مثال یہ ہے:

  • address.send() – Solidity
  • send(address) – Vyper

یہ کانٹریکٹس کو دوسرے اکاؤنٹس میں ETH بھیجنے کی اجازت دیتے ہیں۔

فنکشنز لکھنا

آپ کے فنکشن کو درج ذیل کی ضرورت ہوتی ہے:

  • پیرامیٹر ویری ایبل اور ٹائپ (اگر یہ پیرامیٹرز قبول کرتا ہے)
  • internal/external کا اعلان
  • pure/view/payable کا اعلان
  • ریٹرنز ٹائپ (اگر یہ کوئی قدر واپس کرتا ہے)
1pragma solidity >=0.4.0 <=0.6.0;
2
3contract ExampleDapp {
4 string dapp_name; // اسٹیٹ ویری ایبل
5
6 // جب کانٹریکٹ ڈیپلائے ہوتا ہے تو اسے کال کیا جاتا ہے اور یہ ویلیو کو انیشلائز کرتا ہے
7 constructor() public {
8 dapp_name = "My Example dapp";
9 }
10
11 // Get فنکشن
12 function read_name() public view returns(string) {
13 return dapp_name;
14 }
15
16 // Set فنکشن
17 function update_name(string value) public {
18 dapp_name = value;
19 }
20}
سب دکھائیں

ایک مکمل کانٹریکٹ کچھ اس طرح کا نظر آ سکتا ہے۔ یہاں constructor فنکشن dapp_name ویری ایبل کے لیے ابتدائی قدر فراہم کرتا ہے۔

ایونٹس اور لاگز

ایونٹس آپ کے اسمارٹ کانٹریکٹ کو آپ کے فرنٹ اینڈ یا دیگر سبسکرائب کرنے والی ایپلیکیشنز کے ساتھ بات چیت کرنے کے قابل بناتے ہیں۔ ایک بار جب ٹرانزیکشن کی توثیق ہو جاتی ہے اور اسے بلاک میں شامل کر دیا جاتا ہے، تو اسمارٹ کانٹریکٹس ایونٹس خارج کر سکتے ہیں اور معلومات لاگ کر سکتے ہیں، جنہیں پھر فرنٹ اینڈ پروسیس اور استعمال کر سکتا ہے۔

تشریح شدہ مثالیں

یہ Solidity میں لکھی گئی کچھ مثالیں ہیں۔ اگر آپ کوڈ کے ساتھ تجربہ کرنا چاہتے ہیں، تو آپ Remix (opens in a new tab) میں ان کے ساتھ تعامل کر سکتے ہیں۔

Hello world

1// سیمینٹک ورژننگ کا استعمال کرتے ہوئے، Solidity کا ورژن متعین کرتا ہے۔
2// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma
3pragma solidity ^0.5.10;
4
5// `HelloWorld` نامی کانٹریکٹ کی وضاحت کرتا ہے۔
6// کانٹریکٹ فنکشنز اور ڈیٹا (اس کی اسٹیٹ) کا مجموعہ ہوتا ہے۔
7// ایک بار ڈیپلائے ہونے کے بعد، کانٹریکٹ ایتھیریم بلاک چین پر ایک مخصوص ایڈریس پر موجود ہوتا ہے۔
8// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html
9contract HelloWorld {
10
11 // `string` ٹائپ کا ایک اسٹیٹ ویری ایبل `message` ڈکلیئر کرتا ہے۔
12 // اسٹیٹ ویری ایبلز وہ ویری ایبلز ہوتے ہیں جن کی ویلیوز کانٹریکٹ کی اسٹوریج میں مستقل طور پر محفوظ ہوتی ہیں۔
13 // `public` کی ورڈ ویری ایبلز کو کانٹریکٹ کے باہر سے قابل رسائی بناتا ہے
14 // اور ایک ایسا فنکشن بناتا ہے جسے دوسرے کانٹریکٹس یا کلائنٹس ویلیو تک رسائی کے لیے کال کر سکتے ہیں۔
15 string public message;
16
17 // بہت سی کلاس پر مبنی آبجیکٹ اورینٹڈ زبانوں کی طرح، کنسٹرکٹر ایک
18 // خاص فنکشن ہوتا ہے جو صرف کانٹریکٹ بننے پر ہی ایگزیکیوٹ ہوتا ہے۔
19 // کنسٹرکٹرز کانٹریکٹ کے ڈیٹا کو انیشلائز کرنے کے لیے استعمال ہوتے ہیں۔
20 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors
21 constructor(string memory initMessage) public {
22 // ایک سٹرنگ آرگیومنٹ `initMessage` قبول کرتا ہے اور ویلیو کو
23 // کانٹریکٹ کے `message` اسٹوریج ویری ایبل میں سیٹ کرتا ہے)۔
24 message = initMessage;
25 }
26
27 // ایک پبلک فنکشن جو سٹرنگ آرگیومنٹ قبول کرتا ہے
28 // اور `message` اسٹوریج ویری ایبل کو اپ ڈیٹ کرتا ہے۔
29 function update(string memory newMessage) public {
30 message = newMessage;
31 }
32}
سب دکھائیں

Token

1pragma solidity ^0.5.10;
2
3contract Token {
4 // ایک `address` ای میل ایڈریس کے مترادف ہے - یہ ایتھیریم پر اکاؤنٹ کی شناخت کے لیے استعمال ہوتا ہے۔
5 // ایڈریسز کسی سمارٹ کانٹریکٹ یا بیرونی (صارف) اکاؤنٹس کی نمائندگی کر سکتے ہیں۔
6 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#address
7 address public owner;
8
9 // ایک `mapping` بنیادی طور پر ایک ہیش ٹیبل ڈیٹا سٹرکچر ہے۔
10 // یہ `mapping` ایک ان سائنڈ انٹیجر (ٹوکن بیلنس) کو ایک ایڈریس (ٹوکن ہولڈر) کے ساتھ تفویض کرتی ہے۔
11 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types
12 mapping (address => uint) public balances;
13
14 // ایونٹس بلاک چین پر سرگرمیوں کی لاگنگ کی اجازت دیتے ہیں۔
15 // ایتھیریم کلائنٹس کانٹریکٹ کی اسٹیٹ میں تبدیلیوں پر ردعمل ظاہر کرنے کے لیے ایونٹس کو سن سکتے ہیں۔
16 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events
17 event Transfer(address from, address to, uint amount);
18
19 // کانٹریکٹ کا ڈیٹا انیشلائز کرتا ہے، `owner` کو سیٹ کرتا ہے
20 // کانٹریکٹ بنانے والے کے ایڈریس پر۔
21 constructor() public {
22 // تمام سمارٹ کانٹریکٹس اپنے فنکشنز کو متحرک کرنے کے لیے بیرونی ٹرانزیکشنز پر انحصار کرتے ہیں۔
23 // `msg` ایک گلوبل ویری ایبل ہے جس میں دی گئی ٹرانزیکشن کا متعلقہ ڈیٹا شامل ہوتا ہے،
24 // جیسے بھیجنے والے کا ایڈریس اور ٹرانزیکشن میں شامل ETH کی ویلیو۔
25 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties
26 owner = msg.sender;
27 }
28
29 // نئے ٹوکنز کی ایک مقدار بناتا ہے اور انہیں ایک ایڈریس پر بھیجتا ہے۔
30 function mint(address receiver, uint amount) public {
31 // `require` ایک کنٹرول سٹرکچر ہے جو کچھ شرائط کو نافذ کرنے کے لیے استعمال ہوتا ہے۔
32 // اگر `require` اسٹیٹمنٹ `false` ہو جائے، تو ایک ایکسیپشن ٹرگر ہوتی ہے،
33 // جو موجودہ کال کے دوران اسٹیٹ میں کی گئی تمام تبدیلیوں کو ریورٹ (واپس) کر دیتی ہے۔
34 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
35
36 // صرف کانٹریکٹ کا مالک ہی اس فنکشن کو کال کر سکتا ہے
37 require(msg.sender == owner, "You are not the owner.");
38
39 // ٹوکنز کی زیادہ سے زیادہ مقدار کو نافذ کرتا ہے
40 require(amount < 1e60, "Maximum issuance exceeded");
41
42 // `receiver` کے بیلنس میں `amount` کا اضافہ کرتا ہے
43 balances[receiver] += amount;
44 }
45
46 // کسی بھی کالر سے موجودہ ٹوکنز کی ایک مقدار کسی ایڈریس پر بھیجتا ہے۔
47 function transfer(address receiver, uint amount) public {
48 // بھیجنے والے کے پاس بھیجنے کے لیے کافی ٹوکنز ہونے چاہئیں
49 require(amount <= balances[msg.sender], "Insufficient balance.");
50
51 // دونوں ایڈریسز کے ٹوکن بیلنس کو ایڈجسٹ کرتا ہے
52 balances[msg.sender] -= amount;
53 balances[receiver] += amount;
54
55 // پہلے سے بیان کردہ ایونٹ کو ایمٹ (emit) کرتا ہے
56 emit Transfer(msg.sender, receiver, amount);
57 }
58}
سب دکھائیں

Unique digital asset

1pragma solidity ^0.5.10;
2
3// دوسری فائلوں سے سمبلز کو موجودہ کانٹریکٹ میں امپورٹ کرتا ہے۔
4// اس صورت میں، OpenZeppelin سے ہیلپر کانٹریکٹس کا ایک سلسلہ۔
5// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files
6
7import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";
8import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
9import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";
10import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";
11
12// `is` کی ورڈ بیرونی کانٹریکٹس سے فنکشنز اور کی ورڈز کو وراثت (inherit) میں لینے کے لیے استعمال ہوتا ہے۔
13// اس صورت میں، `CryptoPizza` کو `IERC721` اور `ERC165` کانٹریکٹس سے وراثت ملتی ہے۔
14// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance
15contract CryptoPizza is IERC721, ERC165 {
16 // ریاضی کے آپریشنز کو محفوظ طریقے سے انجام دینے کے لیے OpenZeppelin کی SafeMath لائبریری کا استعمال کرتا ہے۔
17 // مزید جانیں: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath
18 using SafeMath for uint256;
19
20 // Solidity میں کانسٹنٹ اسٹیٹ ویری ایبلز دوسری زبانوں کی طرح ہی ہوتے ہیں
21 // لیکن آپ کو ایک ایسے ایکسپریشن سے تفویض کرنا ہوگا جو کمپائل ٹائم پر کانسٹنٹ ہو۔
22 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables
23 uint256 constant dnaDigits = 10;
24 uint256 constant dnaModulus = 10 ** dnaDigits;
25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
26
27 // Struct ٹائپس آپ کو اپنی ٹائپ خود بیان کرنے کی اجازت دیتی ہیں
28 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs
29 struct Pizza {
30 string name;
31 uint256 dna;
32 }
33
34 // Pizza اسٹرکٹس کی ایک خالی ایرے (array) بناتا ہے
35 Pizza[] public pizzas;
36
37 // پیزا ID سے اس کے مالک کے ایڈریس تک میپنگ
38 mapping(uint256 => address) public pizzaToOwner;
39
40 // مالک کے ایڈریس سے ملکیتی ٹوکنز کی تعداد تک میپنگ
41 mapping(address => uint256) public ownerPizzaCount;
42
43 // ٹوکن ID سے منظور شدہ ایڈریس تک میپنگ
44 mapping(uint256 => address) pizzaApprovals;
45
46 // آپ میپنگز کو نیسٹ (nest) کر سکتے ہیں، یہ مثال مالک کو آپریٹر کی منظوریوں سے میپ کرتی ہے
47 mapping(address => mapping(address => bool)) private operatorApprovals;
48
49 // سٹرنگ (نام) اور DNA سے ایک رینڈم پیزا بنانے کے لیے انٹرنل فنکشن
50 function _createPizza(string memory _name, uint256 _dna)
51 // `internal` کی ورڈ کا مطلب ہے کہ یہ فنکشن صرف نظر آتا ہے
52 // اس کانٹریکٹ اور ان کانٹریکٹس کے اندر جو اس کانٹریکٹ سے اخذ (derive) کیے گئے ہیں
53 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters
54 internal
55 // `isUnique` ایک فنکشن موڈیفائر ہے جو چیک کرتا ہے کہ آیا پیزا پہلے سے موجود ہے
56 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers
57 isUnique(_name, _dna)
58 {
59 // پیزا کو پیزا کی ایرے میں شامل کرتا ہے اور id حاصل کرتا ہے
60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);
61
62 // چیک کرتا ہے کہ پیزا کا مالک وہی ہے جو موجودہ صارف ہے
63 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions
64
65 // نوٹ کریں کہ address(0) زیرو ایڈریس ہے،
66 // جو ظاہر کرتا ہے کہ pizza[id] ابھی تک کسی خاص صارف کو الاٹ نہیں کیا گیا ہے۔
67
68 assert(pizzaToOwner[id] == address(0));
69
70 // پیزا کو مالک سے میپ کرتا ہے
71 pizzaToOwner[id] = msg.sender;
72 ownerPizzaCount[msg.sender] = SafeMath.add(
73 ownerPizzaCount[msg.sender],
74 1
75 );
76 }
77
78 // سٹرنگ (نام) سے ایک رینڈم پیزا بناتا ہے
79 function createRandomPizza(string memory _name) public {
80 uint256 randDna = generateRandomDna(_name, msg.sender);
81 _createPizza(_name, randDna);
82 }
83
84 // سٹرنگ (نام) اور مالک (بنانے والے) کے ایڈریس سے رینڈم DNA تیار کرتا ہے
85 function generateRandomDna(string memory _str, address _owner)
86 public
87 // `pure` کے طور پر مارک کیے گئے فنکشنز اسٹیٹ کو نہ پڑھنے اور نہ ہی تبدیل کرنے کا وعدہ کرتے ہیں
88 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions
89 pure
90 returns (uint256)
91 {
92 // سٹرنگ (نام) + ایڈریس (مالک) سے رینڈم uint تیار کرتا ہے
93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +
94 uint256(_owner);
95 rand = rand % dnaModulus;
96 return rand;
97 }
98
99 // مالک کے پائے گئے پیزا کی ایرے واپس کرتا ہے
100 function getPizzasByOwner(address _owner)
101 public
102 // `view` کے طور پر مارک کیے گئے فنکشنز اسٹیٹ کو تبدیل نہ کرنے کا وعدہ کرتے ہیں
103 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions
104 view
105 returns (uint256[] memory)
106 {
107 // `memory` اسٹوریج لوکیشن کا استعمال کرتا ہے تاکہ ویلیوز کو صرف
108 // اس فنکشن کال کے لائف سائیکل کے لیے اسٹور کیا جا سکے۔
109 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack
110 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);
111 uint256 counter = 0;
112 for (uint256 i = 0; i < pizzas.length; i++) {
113 if (pizzaToOwner[i] == _owner) {
114 result[counter] = i;
115 counter++;
116 }
117 }
118 return result;
119 }
120
121 // پیزا اور ملکیت کو دوسرے ایڈریس پر منتقل کرتا ہے
122 function transferFrom(address _from, address _to, uint256 _pizzaId) public {
123 require(_from != address(0) && _to != address(0), "Invalid address.");
124 require(_exists(_pizzaId), "Pizza does not exist.");
125 require(_from != _to, "Cannot transfer to the same address.");
126 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
127
128 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);
129 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);
130 pizzaToOwner[_pizzaId] = _to;
131
132 // امپورٹ کیے گئے IERC721 کانٹریکٹ میں بیان کردہ ایونٹ کو ایمٹ کرتا ہے
133 emit Transfer(_from, _to, _pizzaId);
134 _clearApproval(_to, _pizzaId);
135 }
136
137 /* *
138 * دیے گئے ٹوکن ID کی ملکیت کو محفوظ طریقے سے دوسرے ایڈریس پر منتقل کرتا ہے
139 * اگر ٹارگٹ ایڈریس ایک کانٹریکٹ ہے، تو اسے `onERC721Received` کو لاگو کرنا چاہیے،
140 * جسے محفوظ منتقلی پر کال کیا جاتا ہے، اور میجک ویلیو واپس کرنی چاہیے
141 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
142 * بصورت دیگر، منتقلی ریورٹ ہو جاتی ہے۔ */
143 function safeTransferFrom(address from, address to, uint256 pizzaId)
144 public
145 {
146 // solium-disable-next-line arg-overflow
147 this.safeTransferFrom(from, to, pizzaId, "");
148 }
149
150 /* *
151 * دیے گئے ٹوکن ID کی ملکیت کو محفوظ طریقے سے دوسرے ایڈریس پر منتقل کرتا ہے
152 * اگر ٹارگٹ ایڈریس ایک کانٹریکٹ ہے، تو اسے `onERC721Received` کو لاگو کرنا چاہیے،
153 * جسے محفوظ منتقلی پر کال کیا جاتا ہے، اور میجک ویلیو واپس کرنی چاہیے
154 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`;
155 * بصورت دیگر، منتقلی ریورٹ ہو جاتی ہے۔ */
156 function safeTransferFrom(
157 address from,
158 address to,
159 uint256 pizzaId,
160 bytes memory _data
161 ) public {
162 this.transferFrom(from, to, pizzaId);
163 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");
164 }
165
166 /* *
167 * ٹارگٹ ایڈریس پر `onERC721Received` کو کال کرنے کے لیے انٹرنل فنکشن
168 * اگر ٹارگٹ ایڈریس کانٹریکٹ نہیں ہے تو کال ایگزیکیوٹ نہیں ہوتی */
169 function _checkOnERC721Received(
170 address from,
171 address to,
172 uint256 pizzaId,
173 bytes memory _data
174 ) internal returns (bool) {
175 if (!isContract(to)) {
176 return true;
177 }
178
179 bytes4 retval = IERC721Receiver(to).onERC721Received(
180 msg.sender,
181 from,
182 pizzaId,
183 _data
184 );
185 return (retval == _ERC721_RECEIVED);
186 }
187
188 // پیزا کو برن (burn) کرتا ہے - ٹوکن کو مکمل طور پر تباہ کر دیتا ہے
189 // `external` فنکشن موڈیفائر کا مطلب ہے کہ یہ فنکشن
190 // کانٹریکٹ انٹرفیس کا حصہ ہے اور دوسرے کانٹریکٹس اسے کال کر سکتے ہیں
191 function burn(uint256 _pizzaId) external {
192 require(msg.sender != address(0), "Invalid address.");
193 require(_exists(_pizzaId), "Pizza does not exist.");
194 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
195
196 ownerPizzaCount[msg.sender] = SafeMath.sub(
197 ownerPizzaCount[msg.sender],
198 1
199 );
200 pizzaToOwner[_pizzaId] = address(0);
201 }
202
203 // ایڈریس کے لحاظ سے پیزا کی تعداد واپس کرتا ہے
204 function balanceOf(address _owner) public view returns (uint256 _balance) {
205 return ownerPizzaCount[_owner];
206 }
207
208 // id کے ذریعے پائے گئے پیزا کا مالک واپس کرتا ہے
209 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {
210 address owner = pizzaToOwner[_pizzaId];
211 require(owner != address(0), "Invalid Pizza ID.");
212 return owner;
213 }
214
215 // پیزا کی ملکیت منتقل کرنے کے لیے دوسرے ایڈریس کو منظور کرتا ہے
216 function approve(address _to, uint256 _pizzaId) public {
217 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");
218 pizzaApprovals[_pizzaId] = _to;
219 emit Approval(msg.sender, _to, _pizzaId);
220 }
221
222 // مخصوص پیزا کے لیے منظور شدہ ایڈریس واپس کرتا ہے
223 function getApproved(uint256 _pizzaId)
224 public
225 view
226 returns (address operator)
227 {
228 require(_exists(_pizzaId), "Pizza does not exist.");
229 return pizzaApprovals[_pizzaId];
230 }
231
232 /* *
233 * دیے گئے ٹوکن ID کی موجودہ منظوری کو کلیئر کرنے کے لیے پرائیویٹ فنکشن
234 * اگر دیا گیا ایڈریس واقعی ٹوکن کا مالک نہیں ہے تو ریورٹ کر دیتا ہے */
235 function _clearApproval(address owner, uint256 _pizzaId) private {
236 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");
237 require(_exists(_pizzaId), "Pizza does not exist.");
238 if (pizzaApprovals[_pizzaId] != address(0)) {
239 pizzaApprovals[_pizzaId] = address(0);
240 }
241 }
242
243 /* * کسی دیے گئے آپریٹر کی منظوری کو سیٹ یا ان سیٹ کرتا ہے
244 * ایک آپریٹر کو بھیجنے والے کی جانب سے اس کے تمام ٹوکنز منتقل کرنے کی اجازت ہوتی ہے */
245 function setApprovalForAll(address to, bool approved) public {
246 require(to != msg.sender, "Cannot approve own address");
247 operatorApprovals[msg.sender][to] = approved;
248 emit ApprovalForAll(msg.sender, to, approved);
249 }
250
251 // بتاتا ہے کہ آیا کسی آپریٹر کو دیے گئے مالک کی طرف سے منظور کیا گیا ہے
252 function isApprovedForAll(address owner, address operator)
253 public
254 view
255 returns (bool)
256 {
257 return operatorApprovals[owner][operator];
258 }
259
260 // پیزا کی ملکیت لیتا ہے - صرف منظور شدہ صارفین کے لیے
261 function takeOwnership(uint256 _pizzaId) public {
262 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");
263 address owner = this.ownerOf(_pizzaId);
264 this.transferFrom(owner, msg.sender, _pizzaId);
265 }
266
267 // چیک کرتا ہے کہ آیا پیزا موجود ہے
268 function _exists(uint256 pizzaId) internal view returns (bool) {
269 address owner = pizzaToOwner[pizzaId];
270 return owner != address(0);
271 }
272
273 // چیک کرتا ہے کہ آیا ایڈریس مالک ہے یا پیزا منتقل کرنے کے لیے منظور شدہ ہے
274 function _isApprovedOrOwner(address spender, uint256 pizzaId)
275 internal
276 view
277 returns (bool)
278 {
279 address owner = pizzaToOwner[pizzaId];
280 // solium چیک کو غیر فعال کریں کیونکہ
281 // https://github.com/duaraghav8/Solium/issues/175
282 // solium-disable-next-line operator-whitespace
283 return (spender == owner ||
284 this.getApproved(pizzaId) == spender ||
285 this.isApprovedForAll(owner, spender));
286 }
287
288 // چیک کریں کہ آیا پیزا منفرد ہے اور ابھی تک موجود نہیں ہے
289 modifier isUnique(string memory _name, uint256 _dna) {
290 bool result = true;
291 for (uint256 i = 0; i < pizzas.length; i++) {
292 if (
293 keccak256(abi.encodePacked(pizzas[i].name)) ==
294 keccak256(abi.encodePacked(_name)) &&
295 pizzas[i].dna == _dna
296 ) {
297 result = false;
298 }
299 }
300 require(result, "Pizza with such name already exists.");
301 _;
302 }
303
304 // واپس کرتا ہے کہ آیا ٹارگٹ ایڈریس ایک کانٹریکٹ ہے
305 function isContract(address account) internal view returns (bool) {
306 uint256 size;
307 // فی الحال یہ چیک کرنے کا کوئی بہتر طریقہ نہیں ہے کہ آیا کسی ایڈریس میں کوئی کانٹریکٹ موجود ہے
308 // سوائے اس کے کہ اس ایڈریس پر کوڈ کا سائز چیک کیا جائے۔
309 // دیکھیں https://ethereum.stackexchange.com/a/14016/36603
310 // اس بارے میں مزید تفصیلات کے لیے کہ یہ کیسے کام کرتا ہے۔
311 // TODO Serenity ریلیز سے پہلے اسے دوبارہ چیک کریں، کیونکہ تب تمام ایڈریسز
312 // کانٹریکٹس ہوں گے۔
313 // solium-disable-next-line security/no-inline-assembly
314 assembly {
315 size := extcodesize(account)
316 }
317 return size > 0;
318 }
319}
سب دکھائیں

مزید مطالعہ

اسمارٹ کانٹریکٹس کے مزید مکمل جائزے کے لیے Solidity اور Vyper کی دستاویزات دیکھیں:

کیا یہ مضمون مددگار تھا؟