اسمارٹ کنٹریکٹس کا تجزیہ
صفحہ کی آخری تازہ کاری: 23 فروری، 2026
اسمارٹ کنٹریکٹ ایک پروگرام ہے جو Ethereum پر ایک ایڈریس پر چلتا ہے۔ یہ ڈیٹا اور فنکشنز سے بنے ہوتے ہیں جو ٹرانزیکشن ملنے پر عمل میں آسکتے ہیں۔ اسمارٹ کنٹریکٹ کن چیزوں سے مل کر بنتا ہے اس کا ایک جائزہ یہاں پیش ہے۔
شرائط
پہلے یہ یقینی بنائیں کہ آپ نے اسمارٹ کنٹریکٹس کے بارے میں پڑھا ہے۔ یہ دستاویز یہ مان کر چلتی ہے کہ آپ پہلے ہی JavaScript یا Python جیسی پروگرامنگ زبانوں سے واقف ہیں۔
ڈیٹا
کسی بھی کنٹریکٹ ڈیٹا کو ایک مقام پر تفویض کیا جانا چاہیے: یا تو storage میں یا memory میں۔ اسمارٹ کنٹریکٹ میں اسٹوریج میں ترمیم کرنا مہنگا ہے لہذا آپ کو یہ غور کرنے کی ضرورت ہے کہ آپ کا ڈیٹا کہاں رہنا چاہیے۔
اسٹوریج
مستقل ڈیٹا کو اسٹوریج کہا جاتا ہے اور اسے اسٹیٹ متغیرات سے ظاہر کیا جاتا ہے۔ یہ قدریں بلاک چین پر مستقل طور پر محفوظ ہو جاتی ہیں۔ آپ کو ٹائپ کا اعلان کرنے کی ضرورت ہے تاکہ کنٹریکٹ یہ ٹریک رکھ سکے کہ اسے کمپائل کرتے وقت بلاک چین پر کتنے اسٹوریج کی ضرورت ہے۔
1// Solidity کی مثال2contract SimpleStorage {3 uint storedData; // اسٹیٹ متغیر4 // ...5}1# Vyper کی مثال2storedData: int128اگر آپ پہلے ہی آبجیکٹ اورینٹڈ زبانوں میں پروگرامنگ کر چکے ہیں، تو آپ شاید زیادہ تر ٹائپس سے واقف ہوں گے۔ تاہم، اگر آپ Ethereum ڈیولپمنٹ میں نئے ہیں تو address آپ کے لیے نیا ہونا چاہیے۔
ایک address ٹائپ ایک Ethereum ایڈریس رکھ سکتا ہے جو 20 بائٹس یا 160 بٹس کے برابر ہے۔ یہ ایک سرکردہ 0x کے ساتھ ہیکسا ڈیسیمل نوٹیشن میں واپس آتا ہے۔
دیگر ٹائپس میں شامل ہیں:
- بولین
- انٹیجر
- فکسڈ پوائنٹ نمبرز
- فکسڈ سائز بائٹ ایریز
- متحرک سائز کے بائٹ ایریز
- ریشنل اور انٹیجر لٹرلز
- سٹرنگ لٹرلز
- ہیکسا ڈیسیمل لٹرلز
- اینمز
مزید وضاحت کے لیے، دستاویزات پر ایک نظر ڈالیں:
میموری
وہ قدریں جو صرف کنٹریکٹ فنکشن کے عمل کی مدت کے لیے محفوظ کی جاتی ہیں، میموری متغیرات کہلاتی ہیں۔ چونکہ یہ بلاک چین پر مستقل طور پر محفوظ نہیں ہوتے ہیں، اس لیے ان کا استعمال بہت سستا ہوتا ہے۔
Solidity دستاویزات (opens in a new tab) میں EVM ڈیٹا (اسٹوریج، میموری، اور اسٹیک) کو کیسے اسٹور کرتا ہے اس کے بارے میں مزید جانیں۔
انوائرمنٹ متغیرات
آپ کے کنٹریکٹ پر آپ کے ذریعے بیان کردہ متغیرات کے علاوہ، کچھ خاص عالمی متغیرات بھی ہوتے ہیں۔ وہ بنیادی طور پر بلاک چین یا موجودہ ٹرانزیکشن کے بارے میں معلومات فراہم کرنے کے لیے استعمال ہوتے ہیں۔
مثالیں:
| پراپ | اسٹیٹ متغیر | تفصیل |
|---|---|---|
block.timestamp | uint256 | موجودہ بلاک ایپوک ٹائم اسٹیمپ |
msg.sender | ایڈریس | پیغام بھیجنے والا (موجودہ کال) |
فنکشنز
آسان ترین الفاظ میں، فنکشنز آنے والے ٹرانزیکشنز کے جواب میں معلومات حاصل کر سکتے ہیں یا معلومات سیٹ کر سکتے ہیں۔
فنکشن کالز کی دو اقسام ہیں:
internal– یہ EVM کال نہیں بناتے- اندرونی فنکشنز اور اسٹیٹ متغیرات تک صرف اندرونی طور پر رسائی حاصل کی جا سکتی ہے (یعنی موجودہ کنٹریکٹ کے اندر سے یا اس سے ماخوذ کنٹریکٹس سے)
external– یہ EVM کال بناتے ہیں- ایکسٹرنل فنکشنز کنٹریکٹ انٹرفیس کا حصہ ہیں، جس کا مطلب ہے کہ انہیں دوسرے کنٹریکٹس سے اور ٹرانزیکشنز کے ذریعے کال کیا جا سکتا ہے۔ ایک بیرونی فنکشن
fکو اندرونی طور پر کال نہیں کیا جا سکتا (یعنی،f()کام نہیں کرتا، لیکنthis.f()کام کرتا ہے)۔
- ایکسٹرنل فنکشنز کنٹریکٹ انٹرفیس کا حصہ ہیں، جس کا مطلب ہے کہ انہیں دوسرے کنٹریکٹس سے اور ٹرانزیکشنز کے ذریعے کال کیا جا سکتا ہے۔ ایک بیرونی فنکشن
وہ public یا private بھی ہو سکتے ہیں
publicفنکشنز کو کنٹریکٹ کے اندر سے اندرونی طور پر یا پیغامات کے ذریعے بیرونی طور پر کال کیا جا سکتا ہے۔privateفنکشنز صرف اس کنٹریکٹ کے لیے نظر آتے ہیں جس میں ان کی تعریف کی گئی ہے اور ماخوذ کنٹریکٹس میں نہیں۔
فنکشنز اور اسٹیٹ متغیرات دونوں کو پبلک یا پرائیویٹ بنایا جا سکتا ہے۔
یہاں ایک کنٹریکٹ پر اسٹیٹ متغیر کو اپ ڈیٹ کرنے کے لیے ایک فنکشن ہے:
1// Solidity کی مثال2function update_name(string value) public {3 dapp_name = value;4}stringٹائپ کا پیرامیٹرvalueفنکشن میں پاس کیا جاتا ہے:update_name- اسے
publicقرار دیا گیا ہے، یعنی کوئی بھی اس تک رسائی حاصل کر سکتا ہے - اسے
viewقرار نہیں دیا گیا ہے، اس لیے یہ کنٹریکٹ اسٹیٹ میں ترمیم کر سکتا ہے
ویو فنکشنز
یہ فنکشنز کنٹریکٹ کے ڈیٹا کی اسٹیٹ میں ترمیم نہ کرنے کا وعدہ کرتے ہیں۔ عام مثالیں "گیٹر" فنکشنز ہیں – آپ اسے مثال کے طور پر صارف کا بیلنس حاصل کرنے کے لیے استعمال کر سکتے ہیں۔
1// Solidity کی مثال2function balanceOf(address _owner) public view returns (uint256 _balance) {3 return ownerPizzaCount[_owner];4}1dappName: public(string)23@view4@public5def readName() -> string:6 return dappNameاسٹیٹ میں ترمیم کرنا کیا سمجھا جاتا ہے:
- اسٹیٹ متغیرات میں لکھنا۔
- ایونٹس کا اخراج (opens in a new tab)۔
- دوسرے کنٹریکٹس بنانا (opens in a new tab)۔
selfdestructکا استعمال۔- کالز کے ذریعے ایتھر بھیجنا۔
- کسی بھی ایسے فنکشن کو کال کرنا جس پر
viewیاpureکا نشان نہ ہو۔ - نچلی سطح کی کالز کا استعمال۔
- ان لائن اسمبلی کا استعمال جس میں کچھ آپ کوڈز ہوں۔
کنسٹرکٹر فنکشنز
constructor فنکشنز صرف ایک بار عمل میں آتے ہیں جب کنٹریکٹ پہلی بار تعینات ہوتا ہے۔ بہت سی کلاس پر مبنی پروگرامنگ زبانوں میں constructor کی طرح، یہ فنکشنز اکثر اسٹیٹ متغیرات کو ان کی مخصوص قدروں پر شروع کرتے ہیں۔
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-properties9 owner = msg.sender;10}سب دکھائیں1# Vyper کی مثال23@external4def __init__(_beneficiary: address, _bidding_time: uint256):5 self.beneficiary = _beneficiary6 self.auctionStart = block.timestamp7 self.auctionEnd = self.auctionStart + _bidding_timeبلٹ ان فنکشنز
آپ کے کنٹریکٹ پر آپ کے ذریعے بیان کردہ متغیرات اور فنکشنز کے علاوہ، کچھ خاص بلٹ ان فنکشنز بھی ہیں۔ سب سے واضح مثال ہے:
address.send()– Soliditysend(address)– Vyper
یہ کنٹریکٹس کو دوسرے اکاؤنٹس میں ETH بھیجنے کی اجازت دیتے ہیں۔
فنکشنز لکھنا
آپ کے فنکشن کو ضرورت ہے:
- پیرامیٹر متغیر اور ٹائپ (اگر یہ پیرامیٹرز قبول کرتا ہے)
- اندرونی/بیرونی کا اعلان
- pure/view/payable کا اعلان
- ریٹرنز ٹائپ (اگر یہ قدر واپس کرتا ہے)
1pragma solidity >=0.4.0 <=0.6.0;23contract ExampleDapp {4 string dapp_name; // اسٹیٹ متغیر56 // جب کنٹریکٹ تعینات ہوتا ہے تو کال کیا جاتا ہے اور قدر کو شروع کرتا ہے7 constructor() public {8 dapp_name = "My Example dapp";9 }1011 // فنکشن حاصل کریں12 function read_name() public view returns(string) {13 return dapp_name;14 }1516 // فنکشن سیٹ کریں17 function update_name(string value) public {18 dapp_name = value;19 }20}سب دکھائیںایک مکمل کنٹریکٹ کچھ اس طرح نظر آ سکتا ہے۔ یہاں constructor فنکشن dapp_name متغیر کے لیے ایک ابتدائی قدر فراہم کرتا ہے۔
ایونٹس اور لاگز
ایونٹس آپ کے اسمارٹ کنٹریکٹ کو آپ کے فرنٹ اینڈ یا دیگر سبسکرائب کرنے والی ایپلی کیشنز کے ساتھ بات چیت کرنے کے قابل بناتے ہیں۔ ایک بار جب ٹرانزیکشن کی توثیق ہو جاتی ہے اور اسے بلاک میں شامل کر دیا جاتا ہے، تو اسمارٹ کنٹریکٹس ایونٹس خارج کر سکتے ہیں اور معلومات لاگ کر سکتے ہیں، جسے فرنٹ اینڈ پھر پراسیس اور استعمال کر سکتا ہے۔
تشریح شدہ مثالیں
یہ Solidity میں لکھی گئی کچھ مثالیں ہیں۔ اگر آپ کوڈ کے ساتھ کھیلنا چاہتے ہیں، تو آپ Remix (opens in a new tab) میں ان کے ساتھ بات چیت کر سکتے ہیں۔
ہیلو ورلڈ
1// سیمنٹک ورژننگ کا استعمال کرتے ہوئے، Solidity کا ورژن بیان کرتا ہے۔2// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma3pragma solidity ^0.5.10;45// `HelloWorld` نامی ایک کنٹریکٹ کی تعریف کرتا ہے۔6// ایک کنٹریکٹ فنکشنز اور ڈیٹا (اس کی اسٹیٹ) کا مجموعہ ہوتا ہے۔7// ایک بار تعینات ہونے کے بعد، ایک کنٹریکٹ Ethereum بلاک چین پر ایک مخصوص ایڈریس پر رہتا ہے۔8// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html9contract HelloWorld {1011 // `string` ٹائپ کا ایک اسٹیٹ متغیر `message` کا اعلان کرتا ہے۔12 // اسٹیٹ متغیرات وہ متغیرات ہیں جن کی قدریں مستقل طور پر کنٹریکٹ اسٹوریج میں محفوظ کی جاتی ہیں۔13 // کلیدی لفظ `public` متغیرات کو کنٹریکٹ کے باہر سے قابل رسائی بناتا ہے14 // اور ایک ایسا فنکشن بناتا ہے جسے دوسرے کنٹریکٹس یا کلائنٹس قدر تک رسائی کے لیے کال کر سکتے ہیں۔15 string public message;1617 // بہت سی کلاس پر مبنی آبجیکٹ اورینٹڈ زبانوں کی طرح، ایک کنسٹرکٹر18 // ایک خاص فنکشن ہے جو صرف کنٹریکٹ کی تخلیق پر عمل میں آتا ہے۔19 // کنسٹرکٹرز کنٹریکٹ کے ڈیٹا کو شروع کرنے کے لیے استعمال ہوتے ہیں۔20 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors21 constructor(string memory initMessage) public {22 // ایک سٹرنگ آرگومنٹ `initMessage` کو قبول کرتا ہے اور قدر کو23 // کنٹریکٹ کے `message` اسٹوریج متغیر میں سیٹ کرتا ہے)۔24 message = initMessage;25 }2627 // ایک پبلک فنکشن جو ایک سٹرنگ آرگومنٹ قبول کرتا ہے28 // اور `message` اسٹوریج متغیر کو اپ ڈیٹ کرتا ہے۔29 function update(string memory newMessage) public {30 message = newMessage;31 }32}سب دکھائیںٹوکن
1pragma solidity ^0.5.10;23contract Token {4 // ایک `address` ای میل ایڈریس کے مترادف ہے - یہ Ethereum پر ایک اکاؤنٹ کی شناخت کے لیے استعمال ہوتا ہے۔5 // ایڈریس ایک اسمارٹ کنٹریکٹ یا بیرونی (صارف) اکاؤنٹس کی نمائندگی کر سکتے ہیں۔6 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#address7 address public owner;89 // ایک `mapping` بنیادی طور پر ایک ہیش ٹیبل ڈیٹا اسٹرکچر ہے۔10 // یہ `mapping` ایک غیر دستخط شدہ انٹیجر (ٹوکن بیلنس) کو ایک ایڈریس (ٹوکن ہولڈر) کو تفویض کرتا ہے۔11 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types12 mapping (address => uint) public balances;1314 // ایونٹس بلاک چین پر سرگرمی کی لاگنگ کی اجازت دیتے ہیں۔15 // Ethereum کلائنٹس کنٹریکٹ اسٹیٹ کی تبدیلیوں پر ردعمل ظاہر کرنے کے لیے ایونٹس سن سکتے ہیں۔16 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events17 event Transfer(address from, address to, uint amount);1819 // کنٹریکٹ کے ڈیٹا کو شروع کرتا ہے، `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-properties26 owner = msg.sender;27 }2829 // نئے ٹوکنز کی ایک مقدار بناتا ہے اور انہیں ایک ایڈریس پر بھیجتا ہے۔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-exceptions3536 // صرف کنٹریکٹ کا مالک ہی اس فنکشن کو کال کر سکتا ہے37 require(msg.sender == owner, "You are not the owner.");3839 // ٹوکنز کی زیادہ سے زیادہ مقدار نافذ کرتا ہے40 require(amount < 1e60, "Maximum issuance exceeded");4142 // `receiver` کے بیلنس کو `amount` سے بڑھاتا ہے43 balances[receiver] += amount;44 }4546 // کسی بھی کال کرنے والے سے ایک ایڈریس پر موجودہ ٹوکنز کی ایک مقدار بھیجتا ہے۔47 function transfer(address receiver, uint amount) public {48 // بھیجنے والے کے پاس بھیجنے کے لیے کافی ٹوکنز ہونے چاہئیں49 require(amount <= balances[msg.sender], "Insufficient balance.");5051 // دو ایڈریس کے ٹوکن بیلنس کو ایڈجسٹ کرتا ہے52 balances[msg.sender] -= amount;53 balances[receiver] += amount;5455 // پہلے بیان کردہ ایونٹ کو خارج کرتا ہے56 emit Transfer(msg.sender, receiver, amount);57 }58}سب دکھائیںمنفرد ڈیجیٹل اثاثہ
1pragma solidity ^0.5.10;23// دیگر فائلوں سے علامتوں کو موجودہ کنٹریکٹ میں درآمد کرتا ہے۔4// اس معاملے میں، OpenZeppelin سے مددگار کنٹریکٹس کا ایک سلسلہ۔5// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files67import "../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";1112// `is` کلیدی لفظ بیرونی کنٹریکٹس سے فنکشنز اور کلیدی الفاظ کو وراثت میں لینے کے لیے استعمال ہوتا ہے۔13// اس معاملے میں، `CryptoPizza` `IERC721` اور `ERC165` کنٹریکٹس سے وراثت میں لیتا ہے۔14// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance15contract CryptoPizza is IERC721, ERC165 {16 // حسابی کارروائیوں کو محفوظ طریقے سے انجام دینے کے لیے OpenZeppelin کی SafeMath لائبریری کا استعمال کرتا ہے۔17 // مزید جانیں: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath18 using SafeMath for uint256;1920 // Solidity میں مستقل اسٹیٹ متغیرات دیگر زبانوں کی طرح ہیں21 // لیکن آپ کو ایک ایسے اظہار سے تفویض کرنا چاہیے جو کمپائل وقت پر مستقل ہو۔22 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables23 uint256 constant dnaDigits = 10;24 uint256 constant dnaModulus = 10 ** dnaDigits;25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;2627 // Struct ٹائپس آپ کو اپنی قسم کی تعریف کرنے دیتے ہیں28 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs29 struct Pizza {30 string name;31 uint256 dna;32 }3334 // Pizza structs کا ایک خالی سرنی بناتا ہے35 Pizza[] public pizzas;3637 // پیزا آئی ڈی سے اس کے مالک کے ایڈریس تک میپنگ38 mapping(uint256 => address) public pizzaToOwner;3940 // مالک کے ایڈریس سے ملکیت والے ٹوکن کی تعداد تک میپنگ41 mapping(address => uint256) public ownerPizzaCount;4243 // ٹوکن آئی ڈی سے منظور شدہ ایڈریس تک میپنگ44 mapping(uint256 => address) pizzaApprovals;4546 // آپ میپنگس کو نیسٹ کر سکتے ہیں، یہ مثال مالک کو آپریٹر کی منظوریوں سے میپ کرتی ہے47 mapping(address => mapping(address => bool)) private operatorApprovals;4849 // سٹرنگ (نام) اور DNA سے ایک بے ترتیب پیزا بنانے کے لیے اندرونی فنکشن50 function _createPizza(string memory _name, uint256 _dna)51 // `internal` کلیدی لفظ کا مطلب ہے کہ یہ فنکشن صرف52 // اس کنٹریکٹ اور اس کنٹریکٹ سے ماخوذ کنٹریکٹس کے اندر نظر آتا ہے53 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters54 internal55 // `isUnique` ایک فنکشن موڈیفائر ہے جو یہ چیک کرتا ہے کہ آیا پیزا پہلے سے موجود ہے56 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers57 isUnique(_name, _dna)58 {59 // پیزا کو پیزا کی سرنی میں شامل کرتا ہے اور آئی ڈی حاصل کرتا ہے60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);6162 // چیک کرتا ہے کہ پیزا کا مالک موجودہ صارف کے جیسا ہی ہے63 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions6465 // نوٹ کریں کہ ایڈریس(0) صفر ایڈریس ہے،66 // جو اس بات کی نشاندہی کرتا ہے کہ pizza[id] ابھی تک کسی خاص صارف کو مختص نہیں کیا گیا ہے۔6768 assert(pizzaToOwner[id] == address(0));6970 // پیزا کو مالک سے میپ کرتا ہے71 pizzaToOwner[id] = msg.sender;72 ownerPizzaCount[msg.sender] = SafeMath.add(73 ownerPizzaCount[msg.sender],74 175 );76 }7778 // سٹرنگ (نام) سے ایک بے ترتیب پیزا بناتا ہے79 function createRandomPizza(string memory _name) public {80 uint256 randDna = generateRandomDna(_name, msg.sender);81 _createPizza(_name, randDna);82 }8384 // سٹرنگ (نام) اور مالک (بنانے والے) کے ایڈریس سے بے ترتیب DNA بناتا ہے85 function generateRandomDna(string memory _str, address _owner)86 public87 // `pure` کے طور پر نشان زد فنکشنز اسٹیٹ سے پڑھنے یا اس میں ترمیم نہ کرنے کا وعدہ کرتے ہیں88 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions89 pure90 returns (uint256)91 {92 // سٹرنگ (نام) + ایڈریس (مالک) سے بے ترتیب uint بناتا ہے93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +94 uint256(_owner);95 rand = rand % dnaModulus;96 return rand;97 }9899 // مالک کے ذریعہ پائے گئے پیزا کی سرنی واپس کرتا ہے100 function getPizzasByOwner(address _owner)101 public102 // `view` کے طور پر نشان زد فنکشنز اسٹیٹ میں ترمیم نہ کرنے کا وعدہ کرتے ہیں103 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions104 view105 returns (uint256[] memory)106 {107 // صرف اس فنکشن کال کے لائف سائیکل کے لیے قدروں کو اسٹور کرنے کے لیے `memory` اسٹوریج مقام کا استعمال کرتا ہے۔108 // مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack109 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);110 uint256 counter = 0;111 for (uint256 i = 0; i < pizzas.length; i++) {112 if (pizzaToOwner[i] == _owner) {113 result[counter] = i;114 counter++;115 }116 }117 return result;118 }119120 // پیزا اور ملکیت دوسرے ایڈریس پر منتقل کرتا ہے121 function transferFrom(address _from, address _to, uint256 _pizzaId) public {122 require(_from != address(0) && _to != address(0), "Invalid address.");123 require(_exists(_pizzaId), "Pizza does not exist.");124 require(_from != _to, "Cannot transfer to the same address.");125 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");126127 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);128 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);129 pizzaToOwner[_pizzaId] = _to;130131 // درآمد شدہ IERC721 کنٹریکٹ میں بیان کردہ ایونٹ کو خارج کرتا ہے132 emit Transfer(_from, _to, _pizzaId);133 _clearApproval(_to, _pizzaId);134 }135136 /**137 * دیے گئے ٹوکن آئی ڈی کی ملکیت کو محفوظ طریقے سے دوسرے ایڈریس پر منتقل کرتا ہے138 * اگر ہدف ایڈریس ایک کنٹریکٹ ہے، تو اسے `onERC721Received` کو نافذ کرنا ہوگا،139 * جسے ایک محفوظ منتقلی پر کال کیا جاتا ہے، اور جادوئی قدر واپس کرنا ہوگا140 * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`؛141 * بصورت دیگر، منتقلی واپس کر دی جاتی ہے۔142 */143 function safeTransferFrom(address from, address to, uint256 pizzaId)144 public145 {146 // solium-disable-next-line arg-overflow147 this.safeTransferFrom(from, to, pizzaId, "");148 }149150 /**151 * دیے گئے ٹوکن آئی ڈی کی ملکیت کو محفوظ طریقے سے دوسرے ایڈریس پر منتقل کرتا ہے152 * اگر ہدف ایڈریس ایک کنٹریکٹ ہے، تو اسے `onERC721Received` کو نافذ کرنا ہوگا،153 * جسے ایک محفوظ منتقلی پر کال کیا جاتا ہے، اور جادوئی قدر واپس کرنا ہوگا154 * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`؛155 * بصورت دیگر، منتقلی واپس کر دی جاتی ہے۔156 */157 function safeTransferFrom(158 address from,159 address to,160 uint256 pizzaId,161 bytes memory _data162 ) public {163 this.transferFrom(from, to, pizzaId);164 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");165 }166167 /**168 * ہدف ایڈریس پر `onERC721Received` کو کال کرنے کے لیے اندرونی فنکشن169 * کال اس وقت عمل میں نہیں آتی جب ہدف ایڈریس ایک کنٹریکٹ نہ ہو170 */171 function _checkOnERC721Received(172 address from,173 address to,174 uint256 pizzaId,175 bytes memory _data176 ) internal returns (bool) {177 if (!isContract(to)) {178 return true;179 }180181 bytes4 retval = IERC721Receiver(to).onERC721Received(182 msg.sender,183 from,184 pizzaId,185 _data186 );187 return (retval == _ERC721_RECEIVED);188 }189190 // ایک پیزا کو جلاتا ہے - ٹوکن کو مکمل طور پر تباہ کرتا ہے191 // `external` فنکشن موڈیفائر کا مطلب ہے کہ یہ فنکشن192 // کنٹریکٹ انٹرفیس کا حصہ ہے اور دوسرے کنٹریکٹس اسے کال کر سکتے ہیں193 function burn(uint256 _pizzaId) external {194 require(msg.sender != address(0), "Invalid address.");195 require(_exists(_pizzaId), "Pizza does not exist.");196 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");197198 ownerPizzaCount[msg.sender] = SafeMath.sub(199 ownerPizzaCount[msg.sender],200 1201 );202 pizzaToOwner[_pizzaId] = address(0);203 }204205 // ایڈریس کے لحاظ سے پیزا کی تعداد واپس کرتا ہے206 function balanceOf(address _owner) public view returns (uint256 _balance) {207 return ownerPizzaCount[_owner];208 }209210 // آئی ڈی کے ذریعہ پائے گئے پیزا کا مالک واپس کرتا ہے211 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {212 address owner = pizzaToOwner[_pizzaId];213 require(owner != address(0), "Invalid Pizza ID.");214 return owner;215 }216217 // پیزا کی ملکیت منتقل کرنے کے لیے دوسرے ایڈریس کو منظور کرتا ہے218 function approve(address _to, uint256 _pizzaId) public {219 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");220 pizzaApprovals[_pizzaId] = _to;221 emit Approval(msg.sender, _to, _pizzaId);222 }223224 // مخصوص پیزا کے لیے منظور شدہ ایڈریس واپس کرتا ہے225 function getApproved(uint256 _pizzaId)226 public227 view228 returns (address operator)229 {230 require(_exists(_pizzaId), "Pizza does not exist.");231 return pizzaApprovals[_pizzaId];232 }233234 /**235 * دیے گئے ٹوکن آئی ڈی کی موجودہ منظوری کو صاف کرنے کے لیے نجی فنکشن236 * اگر دیا گیا ایڈریس واقعی ٹوکن کا مالک نہیں ہے تو واپس کرتا ہے237 */238 function _clearApproval(address owner, uint256 _pizzaId) private {239 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");240 require(_exists(_pizzaId), "Pizza does not exist.");241 if (pizzaApprovals[_pizzaId] != address(0)) {242 pizzaApprovals[_pizzaId] = address(0);243 }244 }245246 /*247 * دیے گئے آپریٹر کی منظوری کو سیٹ یا ان سیٹ کرتا ہے248 * ایک آپریٹر کو ان کی طرف سے بھیجنے والے کے تمام ٹوکنز منتقل کرنے کی اجازت ہے249 */250 function setApprovalForAll(address to, bool approved) public {251 require(to != msg.sender, "Cannot approve own address");252 operatorApprovals[msg.sender][to] = approved;253 emit ApprovalForAll(msg.sender, to, approved);254 }255256 // بتاتا ہے کہ آیا کوئی آپریٹر دیے گئے مالک کے ذریعہ منظور شدہ ہے257 function isApprovedForAll(address owner, address operator)258 public259 view260 returns (bool)261 {262 return operatorApprovals[owner][operator];263 }264265 // پیزا کی ملکیت لیتا ہے - صرف منظور شدہ صارفین کے لیے266 function takeOwnership(uint256 _pizzaId) public {267 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");268 address owner = this.ownerOf(_pizzaId);269 this.transferFrom(owner, msg.sender, _pizzaId);270 }271272 // چیک کرتا ہے کہ آیا پیزا موجود ہے273 function _exists(uint256 pizzaId) internal view returns (bool) {274 address owner = pizzaToOwner[pizzaId];275 return owner != address(0);276 }277278 // چیک کرتا ہے کہ آیا ایڈریس مالک ہے یا پیزا منتقل کرنے کے لیے منظور شدہ ہے279 function _isApprovedOrOwner(address spender, uint256 pizzaId)280 internal281 view282 returns (bool)283 {284 address owner = pizzaToOwner[pizzaId];285 // Disable solium check because of286 // https://github.com/duaraghav8/Solium/issues/175287 // solium-disable-next-line operator-whitespace288 return (spender == owner ||289 this.getApproved(pizzaId) == spender ||290 this.isApprovedForAll(owner, spender));291 }292293 // چیک کریں کہ آیا پیزا منفرد ہے اور ابھی تک موجود نہیں ہے294 modifier isUnique(string memory _name, uint256 _dna) {295 bool result = true;296 for (uint256 i = 0; i < pizzas.length; i++) {297 if (298 keccak256(abi.encodePacked(pizzas[i].name)) ==299 keccak256(abi.encodePacked(_name)) &&300 pizzas[i].dna == _dna301 ) {302 result = false;303 }304 }305 require(result, "Pizza with such name already exists.");306 _;307 }308309 // واپس کرتا ہے کہ آیا ہدف ایڈریس ایک کنٹریکٹ ہے310 function isContract(address account) internal view returns (bool) {311 uint256 size;312 // فی الحال کسی ایڈریس میں کنٹریکٹ ہے یا نہیں یہ چیک کرنے کا اس سے بہتر کوئی طریقہ نہیں ہے313 // کہ اس ایڈریس پر کوڈ کا سائز چیک کیا جائے۔314 // یہ کیسے کام کرتا ہے اس کے بارے میں مزید تفصیلات کے لیے https://ethereum.stackexchange.com/a/14016/36603315 // دیکھیں۔316 // TODO Serenity ریلیز سے پہلے اسے دوبارہ چیک کریں، کیونکہ تمام ایڈریس317 // تب کنٹریکٹ ہوں گے۔318 // solium-disable-next-line security/no-inline-assembly319 assembly {320 size := extcodesize(account)321 }322 return size > 0;323 }324}سب دکھائیںمزید پڑھیں
اسمارٹ کنٹریکٹس کے مزید مکمل جائزہ کے لیے Solidity اور Vyper کی دستاویزات دیکھیں۔
متعلقہ موضوعات
متعلقہ ٹیوٹوریلز
- کنٹریکٹ سائز کی حد سے لڑنے کے لیے کنٹریکٹس کو چھوٹا کرنا – اپنے اسمارٹ کنٹریکٹ کا سائز کم کرنے کے لیے کچھ عملی نکات۔
- ایونٹس کے ساتھ اسمارٹ کنٹریکٹس سے ڈیٹا لاگ کرنا – اسمارٹ کنٹریکٹ ایونٹس کا ایک تعارف اور آپ انہیں ڈیٹا لاگ کرنے کے لیے کیسے استعمال کر سکتے ہیں۔
- Solidity سے دوسرے کنٹریکٹس کے ساتھ تعامل کریں – موجودہ کنٹریکٹ سے اسمارٹ کنٹریکٹ کو کیسے تعینات کریں اور اس کے ساتھ تعامل کریں۔