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

سمارٹ کنٹریکٹس کی ٹیسٹنگ

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

ان وجوہات کی بناء پر، مین نیٹ پر تعینات کرنے سے پہلے سمارٹ کنٹریکٹس کی ٹیسٹنگ سیکیورٹی کے لیے کم از کم ضرورت ہے۔ کنٹریکٹس کی ٹیسٹنگ اور کوڈ کی درستگی کا جائزہ لینے کے لیے بہت سی تکنیکیں موجود ہیں؛ آپ کیا منتخب کرتے ہیں اس کا انحصار آپ کی ضروریات پر ہے۔ بہر حال، مختلف ٹولز اور طریقوں پر مشتمل ایک ٹیسٹ سویٹ کنٹریکٹ کوڈ میں معمولی اور بڑی دونوں سیکیورٹی خامیوں کو پکڑنے کے لیے مثالی ہے۔

پیشگی شرائط

یہ صفحہ بتاتا ہے کہ ایتھیریم نیٹ ورک پر تعینات کرنے سے پہلے سمارٹ کنٹریکٹس کی ٹیسٹنگ کیسے کی جائے۔ یہ فرض کرتا ہے کہ آپ سمارٹ کنٹریکٹس سے واقف ہیں۔

سمارٹ کنٹریکٹ ٹیسٹنگ کیا ہے؟

سمارٹ کنٹریکٹ ٹیسٹنگ اس بات کی تصدیق کرنے کا عمل ہے کہ سمارٹ کنٹریکٹ کا کوڈ توقع کے مطابق کام کرتا ہے۔ ٹیسٹنگ یہ جانچنے کے لیے مفید ہے کہ آیا کوئی خاص سمارٹ کنٹریکٹ قابل اعتمادی، افادیت اور سیکیورٹی کی ضروریات کو پورا کرتا ہے۔

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

سمارٹ کنٹریکٹس کی ٹیسٹنگ کیوں ضروری ہے؟

چونکہ سمارٹ کنٹریکٹس اکثر اعلیٰ مالیت کے مالیاتی اثاثوں کا انتظام کرتے ہیں، اس لیے پروگرامنگ کی معمولی غلطیاں صارفین کے لیے بڑے نقصانات (opens in a new tab) کا سبب بن سکتی ہیں اور اکثر بنتی ہیں۔ تاہم، سخت ٹیسٹنگ آپ کو سمارٹ کنٹریکٹ کے کوڈ میں موجود نقائص اور مسائل کو جلد دریافت کرنے اور مین نیٹ پر لانچ کرنے سے پہلے انہیں ٹھیک کرنے میں مدد کر سکتی ہے۔

اگرچہ کسی بگ کے دریافت ہونے پر کنٹریکٹ کو اپ گریڈ کرنا ممکن ہے، لیکن اپ گریڈ پیچیدہ ہوتے ہیں اور اگر انہیں غلط طریقے سے سنبھالا جائے تو غلطیوں کا نتیجہ (opens in a new tab) نکل سکتا ہے۔ کنٹریکٹ کو اپ گریڈ کرنا ناقابلیتِ تبدیلی کے اصول کی مزید نفی کرتا ہے اور صارفین پر اضافی اعتماد کے مفروضے کا بوجھ ڈالتا ہے۔ اس کے برعکس، آپ کے کنٹریکٹ کی ٹیسٹنگ کا ایک جامع منصوبہ سمارٹ کنٹریکٹ کے سیکیورٹی خطرات کو کم کرتا ہے اور تعیناتی کے بعد پیچیدہ لاجک اپ گریڈ کرنے کی ضرورت کو کم کرتا ہے۔

سمارٹ کنٹریکٹس کی ٹیسٹنگ کے طریقے

ایتھیریم سمارٹ کنٹریکٹس کی ٹیسٹنگ کے طریقے دو وسیع زمروں میں آتے ہیں: خودکار ٹیسٹنگ (automated testing) اور دستی ٹیسٹنگ (manual testing)۔ خودکار ٹیسٹنگ اور دستی ٹیسٹنگ منفرد فوائد اور سمجھوتے پیش کرتے ہیں، لیکن آپ اپنے کنٹریکٹس کا تجزیہ کرنے کے لیے ایک مضبوط منصوبہ بنانے کے لیے دونوں کو ملا سکتے ہیں۔

خودکار ٹیسٹنگ

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

خودکار ٹیسٹنگ خاص طور پر اس وقت مفید ہوتی ہے جب ٹیسٹ بار بار ہونے والے اور وقت طلب ہوں؛ دستی طور پر انجام دینا مشکل ہو؛ انسانی غلطی کا شکار ہو سکتے ہوں؛ یا ان میں اہم کنٹریکٹ فنکشنز کا جائزہ لینا شامل ہو۔ لیکن خودکار ٹیسٹنگ ٹولز کی خامیاں بھی ہو سکتی ہیں—وہ کچھ بگز کو چھوڑ سکتے ہیں اور بہت سے غلط مثبت (false positives) (opens in a new tab) پیدا کر سکتے ہیں۔ لہذا، سمارٹ کنٹریکٹس کے لیے خودکار ٹیسٹنگ کو دستی ٹیسٹنگ کے ساتھ جوڑنا مثالی ہے۔

دستی ٹیسٹنگ

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

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

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

سمارٹ کنٹریکٹس کے لیے خودکار ٹیسٹنگ

یونٹ ٹیسٹنگ

یونٹ ٹیسٹنگ کنٹریکٹ کے فنکشنز کا الگ الگ جائزہ لیتی ہے اور چیک کرتی ہے کہ ہر جزو صحیح طریقے سے کام کرتا ہے۔ اچھے یونٹ ٹیسٹ سادہ، چلانے میں تیز ہونے چاہئیں اور اگر ٹیسٹ فیل ہو جائیں تو اس بات کا واضح خیال فراہم کریں کہ کیا غلط ہوا۔

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

سمارٹ کنٹریکٹس کی یونٹ ٹیسٹنگ کے لیے رہنما خطوط

1. اپنے کنٹریکٹ کی بزنس لاجک اور ورک فلو کو سمجھیں

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

یہ ایک سادہ نیلامی کنٹریکٹ ہے جسے بولی لگانے کی مدت کے دوران بولیاں وصول کرنے کے لیے ڈیزائن کیا گیا ہے۔ اگر highestBid بڑھتی ہے، تو پچھلے سب سے زیادہ بولی لگانے والے کو اس کی رقم مل جاتی ہے؛ ایک بار جب بولی لگانے کی مدت ختم ہو جاتی ہے، تو beneficiary اپنی رقم حاصل کرنے کے لیے کنٹریکٹ کو کال کرتا ہے۔

اس طرح کے کنٹریکٹ کے لیے یونٹ ٹیسٹ ان مختلف فنکشنز کا احاطہ کریں گے جنہیں صارف کنٹریکٹ کے ساتھ تعامل کرتے وقت کال کر سکتا ہے۔ ایک مثال ایک یونٹ ٹیسٹ ہو گی جو یہ چیک کرتا ہے کہ آیا صارف نیلامی جاری رہنے کے دوران بولی لگا سکتا ہے (یعنی، bid() کی کالز کامیاب ہوتی ہیں) یا وہ جو یہ چیک کرتا ہے کہ آیا صارف موجودہ highestBid سے زیادہ بولی لگا سکتا ہے۔

کنٹریکٹ کے آپریشنل ورک فلو کو سمجھنے سے ایسے یونٹ ٹیسٹ لکھنے میں بھی مدد ملتی ہے جو یہ چیک کرتے ہیں کہ آیا عمل درآمد ضروریات کو پورا کرتا ہے۔ مثال کے طور پر، نیلامی کا کنٹریکٹ یہ بتاتا ہے کہ نیلامی ختم ہونے پر صارفین بولیاں نہیں لگا سکتے (یعنی، جب auctionEndTime، block.timestamp سے کم ہو)۔ اس طرح، ایک ڈویلپر ایک یونٹ ٹیسٹ چلا سکتا ہے جو یہ چیک کرتا ہے کہ نیلامی ختم ہونے پر (یعنی، جب auctionEndTime > block.timestamp ہو) bid() فنکشن کی کالز کامیاب ہوتی ہیں یا فیل ہوتی ہیں۔

2. کنٹریکٹ کے عمل درآمد سے متعلق تمام مفروضوں کا جائزہ لیں

کنٹریکٹ کے عمل درآمد کے بارے میں کسی بھی مفروضے کو دستاویزی شکل دینا اور ان مفروضوں کی درستگی کی تصدیق کے لیے یونٹ ٹیسٹ لکھنا ضروری ہے۔ غیر متوقع عمل درآمد کے خلاف تحفظ فراہم کرنے کے علاوہ، ٹیسٹنگ کی تصدیقیں آپ کو ان کارروائیوں کے بارے میں سوچنے پر مجبور کرتی ہیں جو سمارٹ کنٹریکٹ کے سیکیورٹی ماڈل کو توڑ سکتی ہیں۔ ایک مفید ٹپ یہ ہے کہ "ہیپی یوزر ٹیسٹس" سے آگے بڑھیں اور منفی ٹیسٹ لکھیں جو یہ چیک کریں کہ آیا کوئی فنکشن غلط ان پٹس کے لیے فیل ہوتا ہے۔

بہت سے یونٹ ٹیسٹنگ فریم ورکس آپ کو تصدیقیں (assertions) بنانے کی اجازت دیتے ہیں—سادہ بیانات جو یہ بتاتے ہیں کہ کنٹریکٹ کیا کر سکتا ہے اور کیا نہیں کر سکتا—اور یہ دیکھنے کے لیے ٹیسٹ چلاتے ہیں کہ آیا وہ تصدیقیں عمل درآمد کے تحت برقرار رہتی ہیں۔ پہلے بیان کیے گئے نیلامی کنٹریکٹ پر کام کرنے والا ایک ڈویلپر منفی ٹیسٹ چلانے سے پہلے اس کے رویے کے بارے میں درج ذیل تصدیقیں کر سکتا ہے:

  • جب نیلامی ختم ہو چکی ہو یا شروع نہ ہوئی ہو تو صارفین بولیاں نہیں لگا سکتے۔

  • اگر بولی قابل قبول حد سے کم ہو تو نیلامی کا کنٹریکٹ ریورٹ (revert) ہو جاتا ہے۔

  • جو صارفین بولی جیتنے میں ناکام رہتے ہیں انہیں ان کے فنڈز واپس کر دیے جاتے ہیں۔

نوٹ: مفروضوں کی ٹیسٹنگ کا ایک اور طریقہ ایسے ٹیسٹ لکھنا ہے جو کنٹریکٹ میں فنکشن موڈیفائرز (opens in a new tab) کو متحرک کرتے ہیں، خاص طور پر require، assert، اور if…else سٹیٹمنٹس۔

3. کوڈ کوریج کی پیمائش کریں

کوڈ کوریج (opens in a new tab) ایک ٹیسٹنگ میٹرک ہے جو ٹیسٹ کے دوران چلائی گئی آپ کے کوڈ میں برانچز، لائنز اور سٹیٹمنٹس کی تعداد کو ٹریک کرتا ہے۔ غیر ٹیسٹ شدہ کمزوریوں کے خطرے کو کم کرنے کے لیے ٹیسٹس کی کوڈ کوریج اچھی ہونی چاہیے۔ کافی کوریج کے بغیر، آپ غلطی سے یہ فرض کر سکتے ہیں کہ آپ کا کنٹریکٹ محفوظ ہے کیونکہ تمام ٹیسٹ پاس ہو جاتے ہیں، جبکہ غیر ٹیسٹ شدہ کوڈ پاتھس میں کمزوریاں اب بھی موجود ہوتی ہیں۔ تاہم، اعلیٰ کوڈ کوریج ریکارڈ کرنا اس بات کی یقین دہانی کراتا ہے کہ سمارٹ کنٹریکٹ میں تمام سٹیٹمنٹس/فنکشنز کی درستگی کے لیے کافی حد تک ٹیسٹنگ کی گئی تھی۔

4. اچھی طرح سے تیار کردہ ٹیسٹنگ فریم ورکس کا استعمال کریں

آپ کے سمارٹ کنٹریکٹس کے لیے یونٹ ٹیسٹ چلانے میں استعمال ہونے والے ٹولز کا معیار بہت اہم ہے۔ ایک مثالی ٹیسٹنگ فریم ورک وہ ہے جسے باقاعدگی سے برقرار رکھا جاتا ہو؛ مفید خصوصیات فراہم کرتا ہو (جیسے، لاگنگ اور رپورٹنگ کی صلاحیتیں)؛ اور اسے دوسرے ڈویلپرز کے ذریعے وسیع پیمانے پر استعمال اور جانچا گیا ہو۔

Solidity سمارٹ کنٹریکٹس کے لیے یونٹ ٹیسٹنگ فریم ورکس مختلف زبانوں (زیادہ تر JavaScript، Python، اور Rust) میں آتے ہیں۔ مختلف ٹیسٹنگ فریم ورکس کے ساتھ یونٹ ٹیسٹ چلانا شروع کرنے کے طریقے کے بارے میں معلومات کے لیے ذیل میں کچھ گائیڈز دیکھیں:

انٹیگریشن ٹیسٹنگ

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

انٹیگریشن ٹیسٹنگ اس وقت مفید ہوتی ہے جب آپ کا کنٹریکٹ ماڈیولر فن تعمیر کو اپناتا ہے یا عمل درآمد کے دوران دیگر آن چین کنٹریکٹس کے ساتھ انٹرفیس کرتا ہے۔ انٹیگریشن ٹیسٹ چلانے کا ایک طریقہ یہ ہے کہ ایک مخصوص اونچائی پر (Forge (opens in a new tab) یا Hardhat (opens in a new tab) جیسے ٹول کا استعمال کرتے ہوئے) اور آپ کے کنٹریکٹ اور تعینات کردہ کنٹریکٹس کے درمیان تعاملات کی نقل کریں۔

فورک شدہ بلاک چین مین نیٹ کی طرح برتاؤ کرے گی اور اس میں متعلقہ حالتوں اور بیلنس کے ساتھ اکاؤنٹس ہوں گے۔ لیکن یہ صرف ایک سینڈ باکسڈ مقامی ترقیاتی ماحول کے طور پر کام کرتا ہے، جس کا مطلب ہے کہ آپ کو ٹرانزیکشنز کے لیے حقیقی ETH کی ضرورت نہیں ہوگی، مثال کے طور پر، اور نہ ہی آپ کی تبدیلیاں حقیقی ایتھیریم پروٹوکول کو متاثر کریں گی۔

پراپرٹی پر مبنی ٹیسٹنگ

پراپرٹی پر مبنی ٹیسٹنگ یہ جانچنے کا عمل ہے کہ آیا سمارٹ کنٹریکٹ کسی متعین پراپرٹی کو پورا کرتا ہے۔ پراپرٹیز کنٹریکٹ کے رویے کے بارے میں ان حقائق کی تصدیق کرتی ہیں جن کے مختلف منظرناموں میں درست رہنے کی توقع کی جاتی ہے—سمارٹ کنٹریکٹ پراپرٹی کی ایک مثال یہ ہو سکتی ہے کہ "کنٹریکٹ میں ریاضی کے عمل کبھی اوور فلو یا انڈر فلو نہیں ہوتے۔"

سٹیٹک تجزیہ (Static analysis) اور متحرک تجزیہ (dynamic analysis) پراپرٹی پر مبنی ٹیسٹنگ کو انجام دینے کی دو عام تکنیکیں ہیں، اور دونوں اس بات کی تصدیق کر سکتی ہیں کہ کسی پروگرام کا کوڈ (اس معاملے میں ایک سمارٹ کنٹریکٹ) کسی پہلے سے طے شدہ پراپرٹی کو پورا کرتا ہے۔ کچھ پراپرٹی پر مبنی ٹیسٹنگ ٹولز متوقع کنٹریکٹ پراپرٹیز کے بارے میں پہلے سے طے شدہ اصولوں کے ساتھ آتے ہیں اور ان اصولوں کے خلاف کوڈ کو چیک کرتے ہیں، جبکہ دیگر آپ کو سمارٹ کنٹریکٹ کے لیے حسب ضرورت پراپرٹیز بنانے کی اجازت دیتے ہیں۔

سٹیٹک تجزیہ

ایک سٹیٹک اینالائزر سمارٹ کنٹریکٹ کے سورس کوڈ کو ان پٹ کے طور پر لیتا ہے اور ایسے نتائج نکالتا ہے جو یہ بتاتے ہیں کہ آیا کنٹریکٹ کسی پراپرٹی کو پورا کرتا ہے یا نہیں۔ متحرک تجزیہ کے برعکس، سٹیٹک تجزیہ میں درستگی کے لیے اس کا تجزیہ کرنے کے لیے کنٹریکٹ کو چلانا شامل نہیں ہے۔ اس کے بجائے سٹیٹک تجزیہ ان تمام ممکنہ راستوں کے بارے میں استدلال کرتا ہے جو ایک سمارٹ کنٹریکٹ عمل درآمد کے دوران لے سکتا ہے (یعنی، سورس کوڈ کی ساخت کا جائزہ لے کر یہ تعین کرنے کے لیے کہ رن ٹائم پر کنٹریکٹ کے آپریشن کے لیے اس کا کیا مطلب ہوگا)۔

کنٹریکٹس پر سٹیٹک تجزیہ چلانے کے لیے لنٹنگ (Linting) (opens in a new tab) اور سٹیٹک ٹیسٹنگ (opens in a new tab) عام طریقے ہیں۔ دونوں کے لیے کنٹریکٹ کے عمل درآمد کی نچلی سطح کی نمائندگیوں کا تجزیہ کرنے کی ضرورت ہوتی ہے جیسے کہ کمپائلر کے ذریعے آؤٹ پٹ کیے گئے ایبسٹریکٹ سنٹیکس ٹریز (abstract syntax trees) (opens in a new tab) اور کنٹرول فلو گرافس (control flow graphs) (opens in a new tab)۔

زیادہ تر معاملات میں، سٹیٹک تجزیہ حفاظتی مسائل کا پتہ لگانے کے لیے مفید ہے جیسے غیر محفوظ تعمیرات کا استعمال، نحو کی غلطیاں، یا کنٹریکٹ کے کوڈ میں کوڈنگ کے معیارات کی خلاف ورزیاں۔ تاہم، سٹیٹک اینالائزرز عام طور پر گہری کمزوریوں کا پتہ لگانے میں غیر معتبر سمجھے جاتے ہیں، اور ضرورت سے زیادہ غلط مثبت (false positives) پیدا کر سکتے ہیں۔

متحرک تجزیہ

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

فزنگ (Fuzzing) (opens in a new tab) سمارٹ کنٹریکٹس میں صوابدیدی پراپرٹیز کی تصدیق کے لیے متحرک تجزیہ کی تکنیک کی ایک مثال ہے۔ ایک فزر (fuzzer) ہدف کنٹریکٹ میں متعین ان پٹ ویلیو کی بے ترتیب یا خراب تغیرات کے ساتھ فنکشنز کو طلب کرتا ہے۔ اگر سمارٹ کنٹریکٹ کسی خرابی کی حالت میں داخل ہوتا ہے (مثلاً، وہ جہاں کوئی تصدیق فیل ہو جاتی ہے)، تو مسئلے کو نشان زد کیا جاتا ہے اور وہ ان پٹس جو عمل درآمد کو کمزور راستے کی طرف لے جاتے ہیں ایک رپورٹ میں پیش کیے جاتے ہیں۔

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

  1. بہت سے منظرناموں کا احاطہ کرنے کے لیے ٹیسٹ کیسز لکھنا مشکل ہے۔ پراپرٹی ٹیسٹ کے لیے صرف یہ ضروری ہے کہ آپ ایک رویے اور اس رویے کو جانچنے کے لیے ڈیٹا کی ایک رینج کی وضاحت کریں—پروگرام خود بخود متعین پراپرٹی کی بنیاد پر ٹیسٹ کیسز تیار کرتا ہے۔

  2. ہو سکتا ہے کہ آپ کا ٹیسٹ سویٹ پروگرام کے اندر تمام ممکنہ راستوں کا کافی حد تک احاطہ نہ کرے۔ 100% کوریج کے باوجود، ایج کیسز کا چھوٹ جانا ممکن ہے۔

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

سمارٹ کنٹریکٹس کے لیے پراپرٹی پر مبنی ٹیسٹنگ چلانے کے لیے رہنما خطوط

پراپرٹی پر مبنی ٹیسٹنگ چلانا عام طور پر ایک پراپرٹی (مثلاً، انٹیجر اوور فلو (opens in a new tab) کی عدم موجودگی) یا پراپرٹیز کے مجموعے کی وضاحت کرنے سے شروع ہوتا ہے جس کی آپ سمارٹ کنٹریکٹ میں تصدیق کرنا چاہتے ہیں۔ پراپرٹی ٹیسٹ لکھتے وقت آپ کو اقدار کی ایک رینج کی وضاحت کرنے کی بھی ضرورت پڑ سکتی ہے جس کے اندر پروگرام ٹرانزیکشن ان پٹس کے لیے ڈیٹا تیار کر سکتا ہے۔

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

سمارٹ کنٹریکٹس کے لیے دستی ٹیسٹنگ

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

مقامی بلاک چین پر کنٹریکٹس کی ٹیسٹنگ

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

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

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

ترقیاتی نیٹ ورکس کے بارے میں مزید۔

آزمائشی نیٹ ورکس پر کنٹریکٹس کی ٹیسٹنگ

ایک ٹیسٹ نیٹ ورک یا آزمائشی نیٹ ورک بالکل ایتھیریم مین نیٹ کی طرح کام کرتا ہے، سوائے اس کے کہ یہ ایتھر (ETH) کا استعمال کرتا ہے جس کی کوئی حقیقی دنیا کی قدر نہیں ہوتی۔ اپنے کنٹریکٹ کو آزمائشی نیٹ ورک پر تعینات کرنے کا مطلب ہے کہ کوئی بھی فنڈز کو خطرے میں ڈالے بغیر اس کے ساتھ تعامل کر سکتا ہے (مثلاً، غیر مرکزی ایپلی کیشن (dapp) کے فرنٹ اینڈ کے ذریعے)۔

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

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

ایتھیریم آزمائشی نیٹ ورکس کے بارے میں مزید۔

ٹیسٹنگ بمقابلہ رسمی تصدیق

اگرچہ ٹیسٹنگ اس بات کی تصدیق کرنے میں مدد کرتی ہے کہ ایک کنٹریکٹ کچھ ڈیٹا ان پٹس کے لیے متوقع نتائج واپس کرتا ہے، لیکن یہ ٹیسٹ کے دوران استعمال نہ ہونے والے ان پٹس کے لیے حتمی طور پر ایسا ثابت نہیں کر سکتی۔ لہذا، سمارٹ کنٹریکٹ کی ٹیسٹنگ "فنکشنل درستگی" کی ضمانت نہیں دے سکتی (یعنی، یہ یہ نہیں دکھا سکتی کہ ایک پروگرام ان پٹ اقدار کے تمام سیٹس کے لیے ضرورت کے مطابق برتاؤ کرتا ہے)۔

رسمی تصدیق سافٹ ویئر کی درستگی کا اندازہ لگانے کا ایک طریقہ ہے جس میں یہ چیک کیا جاتا ہے کہ آیا پروگرام کا رسمی ماڈل رسمی تصریح (formal specification) سے میل کھاتا ہے۔ ایک رسمی ماڈل پروگرام کی ایک تجریدی ریاضیاتی نمائندگی ہے، جبکہ ایک رسمی تصریح پروگرام کی خصوصیات کی وضاحت کرتی ہے (یعنی، پروگرام کے عمل درآمد کے بارے میں منطقی تصدیقیں)۔

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

ٹیسٹنگ کے برعکس، رسمی تصدیق کا استعمال اس بات کی تصدیق کے لیے کیا جا سکتا ہے کہ سمارٹ کنٹریکٹ کا عمل درآمد تمام عمل درآمد کے لیے ایک رسمی تصریح کو پورا کرتا ہے (یعنی، اس میں کوئی بگز نہیں ہیں) بغیر اسے نمونہ ڈیٹا کے ساتھ چلانے کی ضرورت کے۔ اس سے نہ صرف درجنوں یونٹ ٹیسٹ چلانے میں صرف ہونے والا وقت کم ہوتا ہے، بلکہ یہ چھپی ہوئی کمزوریوں کو پکڑنے میں بھی زیادہ موثر ہے۔ اس کے باوجود، رسمی تصدیق کی تکنیکیں ان کے نفاذ کی دشواری اور افادیت کے لحاظ سے ایک سپیکٹرم پر واقع ہیں۔

سمارٹ کنٹریکٹس کے لیے رسمی تصدیق کے بارے میں مزید۔

ٹیسٹنگ بمقابلہ آڈٹ اور بگ باؤنٹیز

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

پھر بھی، آپ ایک آزاد کوڈ ریویو حاصل کر کے کنٹریکٹ کی کمزوریوں کو پکڑنے کے امکان کو مزید بڑھا سکتے ہیں۔ سمارٹ کنٹریکٹ آڈٹس (opens in a new tab) اور بگ باؤنٹیز (opens in a new tab) دوسروں سے اپنے کنٹریکٹس کا تجزیہ کروانے کے دو طریقے ہیں۔

آڈٹ ان آڈیٹرز کے ذریعے کیے جاتے ہیں جو سمارٹ کنٹریکٹس میں سیکیورٹی خامیوں اور ناقص ترقیاتی طریقوں کے معاملات تلاش کرنے کا تجربہ رکھتے ہیں۔ ایک آڈٹ میں عام طور پر ٹیسٹنگ (اور ممکنہ طور پر رسمی تصدیق) کے ساتھ ساتھ پورے کوڈ بیس کا دستی جائزہ شامل ہوگا۔

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

بڑا فرق یہ ہے کہ بگ باؤنٹی پروگرام وسیع تر ڈویلپر/ہیکر کمیونٹی کے لیے کھلے ہیں اور منفرد مہارتوں اور تجربے کے حامل اخلاقی ہیکرز اور آزاد سیکیورٹی پیشہ ور افراد کی ایک وسیع کلاس کو راغب کرتے ہیں۔ یہ سمارٹ کنٹریکٹ آڈٹس پر ایک فائدہ ہو سکتا ہے جو بنیادی طور پر ان ٹیموں پر انحصار کرتے ہیں جن کے پاس محدود یا تنگ مہارت ہو سکتی ہے۔

ٹیسٹنگ ٹولز اور لائبریریاں

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

  • solidity-coverage (opens in a new tab) - Solidity میں لکھے گئے سمارٹ کنٹریکٹس کے لیے کوڈ کوریج ٹول۔

  • Waffle (opens in a new tab) - اعلی درجے کی سمارٹ کنٹریکٹ کی ترقی اور ٹیسٹنگ کے لیے فریم ورک (Ethers.js پر مبنی)۔

  • Remix Tests (opens in a new tab) - Solidity سمارٹ کنٹریکٹس کی ٹیسٹنگ کے لیے ٹول۔ Remix IDE "Solidity Unit Testing" پلگ ان کے تحت کام کرتا ہے جو کنٹریکٹ کے لیے ٹیسٹ کیسز لکھنے اور چلانے کے لیے استعمال ہوتا ہے۔

  • OpenZeppelin Test Helpers (opens in a new tab) - ایتھیریم سمارٹ کنٹریکٹ ٹیسٹنگ کے لیے تصدیقی لائبریری۔ یقینی بنائیں کہ آپ کے کنٹریکٹس توقع کے مطابق برتاؤ کرتے ہیں!

  • Brownie یونٹ ٹیسٹنگ فریم ورک (opens in a new tab) - Brownie Pytest کا استعمال کرتا ہے، جو ایک خصوصیت سے بھرپور ٹیسٹ فریم ورک ہے جو آپ کو کم سے کم کوڈ کے ساتھ چھوٹے ٹیسٹ لکھنے دیتا ہے، بڑے پروجیکٹس کے لیے اچھی طرح سکیل کرتا ہے، اور انتہائی قابل توسیع ہے۔

  • Foundry Tests (opens in a new tab) - Foundry Forge پیش کرتا ہے، جو ایک تیز اور لچکدار ایتھیریم ٹیسٹنگ فریم ورک ہے جو سادہ یونٹ ٹیسٹ، گیس آپٹیمائزیشن چیکس، اور کنٹریکٹ فزنگ کو انجام دینے کی صلاحیت رکھتا ہے۔

  • Hardhat Tests (opens in a new tab) - Ethers.js، Mocha، اور Chai پر مبنی سمارٹ کنٹریکٹس کی ٹیسٹنگ کے لیے فریم ورک۔

  • ApeWorx (opens in a new tab) - ایتھیریم ورچوئل مشین کو نشانہ بنانے والے سمارٹ کنٹریکٹس کے لیے Python پر مبنی ترقی اور ٹیسٹنگ فریم ورک۔

  • Wake (opens in a new tab) - بہترین صارف کے تجربے اور کارکردگی کے لیے pytest اور Anvil کا استعمال کرتے ہوئے، مضبوط ڈیبگنگ صلاحیتوں اور کراس چین ٹیسٹنگ سپورٹ کے ساتھ یونٹ ٹیسٹنگ اور فزنگ کے لیے Python پر مبنی فریم ورک۔

پراپرٹی پر مبنی ٹیسٹنگ ٹولز

سٹیٹک تجزیہ ٹولز

  • سلدر (opens in a new tab) - کمزوریوں کو تلاش کرنے، کوڈ کی سمجھ کو بڑھانے، اور سمارٹ کنٹریکٹس کے لیے حسب ضرورت تجزیے لکھنے کے لیے Python پر مبنی Solidity سٹیٹک تجزیہ فریم ورک۔

  • Ethlint (opens in a new tab) - Solidity سمارٹ کنٹریکٹ پروگرامنگ زبان کے لیے سٹائل اور سیکیورٹی کے بہترین طریقوں کو نافذ کرنے کے لیے لنٹر۔

  • Cyfrin Aderyn (opens in a new tab) - خاص طور پر Web3 سمارٹ کنٹریکٹ سیکیورٹی اور ترقی کے لیے ڈیزائن کیا گیا Rust پر مبنی سٹیٹک اینالائزر۔

  • Wake (opens in a new tab) - کمزوری اور کوڈ کے معیار کے ڈیٹیکٹرز، کوڈ سے مفید معلومات نکالنے کے لیے پرنٹرز اور حسب ضرورت ذیلی ماڈیولز لکھنے کے لیے سپورٹ کے ساتھ Python پر مبنی سٹیٹک تجزیہ فریم ورک۔

  • Slippy (opens in a new tab) - Solidity کے لیے ایک سادہ اور طاقتور لنٹر۔

متحرک تجزیہ ٹولز

  • ایکڈنا (opens in a new tab) - پراپرٹی پر مبنی ٹیسٹنگ کے ذریعے سمارٹ کنٹریکٹس میں کمزوریوں کا پتہ لگانے کے لیے تیز کنٹریکٹ فزر۔

  • Diligence Fuzzing (opens in a new tab) - سمارٹ کنٹریکٹ کوڈ میں پراپرٹی کی خلاف ورزیوں کا پتہ لگانے کے لیے مفید خودکار فزنگ ٹول۔

  • مینٹیکور (opens in a new tab) - EVM بائٹ کوڈ کا تجزیہ کرنے کے لیے متحرک علامتی عمل درآمد کا فریم ورک۔

  • Mythril (opens in a new tab) - ٹینٹ تجزیہ (taint analysis)، کونکولک تجزیہ (concolic analysis)، اور کنٹرول فلو چیکنگ کا استعمال کرتے ہوئے کنٹریکٹ کی کمزوریوں کا پتہ لگانے کے لیے EVM بائٹ کوڈ اسسمنٹ ٹول۔

  • Diligence Scribble (opens in a new tab) - Scribble ایک تصریح کی زبان اور رن ٹائم تصدیق کا ٹول ہے جو آپ کو سمارٹ کنٹریکٹس کو ان پراپرٹیز کے ساتھ تشریح کرنے کی اجازت دیتا ہے جو آپ کو Diligence Fuzzing یا MythX جیسے ٹولز کے ساتھ خود بخود کنٹریکٹس کی ٹیسٹنگ کرنے کی اجازت دیتی ہیں۔

مزید مطالعہ

ٹیوٹوریلز: ایتھیریم پر سمارٹ کنٹریکٹ کی ٹیسٹنگ