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

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

صفحہ کی آخری تازہ کاری: 26 فروری، 2026

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

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

اگرچہ اعداد و شمار مختلف ہوتے ہیں، لیکن یہ اندازہ لگایا گیا ہے کہ اسمارٹ کنٹریکٹس میں سیکیورٹی نقائص کی وجہ سے چوری یا ضائع ہونے والی کل رقم آسانی سے 1 بلین ڈالر سے زیادہ ہے۔ DAO ہیک (opens in a new tab) (3.6M ETH چوری ہوئے، آج کی قیمتوں میں $1B سے زیادہ)، Parity ملٹی سِگ والیٹ ہیک (opens in a new tab) ($30M ہیکرز کے ہاتھوں ضائع ہوئے)، اور Parity منجمد والیٹ کا مسئلہ (opens in a new tab) ($300M سے زیادہ ETH ہمیشہ کے لیے لاک ہو گئے)۔

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

شرائط

سیکیورٹی سے نمٹنے سے پہلے یقینی بنائیں کہ آپ اسمارٹ کنٹریکٹ ڈیولپمنٹ کے بنیادی اصولوں سے واقف ہیں۔

محفوظ Ethereum اسمارٹ کنٹریکٹس بنانے کے لیے رہنما خطوط

1۔ مناسب رسائی کنٹرولز ڈیزائن کریں

اسمارٹ کنٹریکٹس میں، public یا external کے طور پر نشان زد فنکشنز کو کسی بھی بیرونی ملکیت والے اکاؤنٹس (EOAs) یا کنٹریکٹ اکاؤنٹس کے ذریعے کال کیا جاسکتا ہے۔ اگر آپ چاہتے ہیں کہ دوسرے آپ کے کنٹریکٹ کے ساتھ تعامل کریں تو فنکشنز کے لیے عوامی مرئیت کی وضاحت کرنا ضروری ہے۔ تاہم، private کے طور پر نشان زد فنکشنز کو صرف اسمارٹ کنٹریکٹ کے اندر موجود فنکشنز کے ذریعے کال کیا جاسکتا ہے، نہ کہ بیرونی اکاؤنٹس کے ذریعے۔ ہر نیٹ ورک شریک کو کنٹریکٹ فنکشنز تک رسائی دینا مسائل پیدا کرسکتا ہے، خاص طور پر اگر اس کا مطلب یہ ہے کہ کوئی بھی حساس آپریشنز (مثلاً، نئے ٹوکنز بنانا) انجام دے سکتا ہے۔

اسمارٹ کنٹریکٹ فنکشنز کے غیر مجاز استعمال کو روکنے کے لیے، محفوظ رسائی کنٹرولز کو نافذ کرنا ضروری ہے۔ رسائی کنٹرول میکانزم ایک اسمارٹ کنٹریکٹ میں کچھ فنکشنز کے استعمال کی صلاحیت کو منظور شدہ اداروں تک محدود کرتے ہیں، جیسے کہ کنٹریکٹ کا انتظام کرنے کے لیے ذمہ دار اکاؤنٹس۔ Ownable پیٹرن اور کردار پر مبنی کنٹرول اسمارٹ کنٹریکٹس میں رسائی کنٹرول کو نافذ کرنے کے لیے دو مفید پیٹرن ہیں:

Ownable پیٹرن

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

کردار پر مبنی رسائی کنٹرول

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

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

ملٹی سگنیچر والیٹس کا استعمال

محفوظ رسائی کنٹرول کو نافذ کرنے کا ایک اور طریقہ کنٹریکٹ کا انتظام کرنے کے لیے ملٹی سگنیچر اکاؤنٹ کا استعمال کرنا ہے۔ ایک باقاعدہ EOA کے برعکس، ملٹی سگنیچر اکاؤنٹس متعدد اداروں کی ملکیت ہوتے ہیں اور لین دین کو انجام دینے کے لیے کم از کم تعداد میں اکاؤنٹس — مثلاً 5 میں سے 3 — کے دستخطوں کی ضرورت ہوتی ہے۔

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

2۔ کنٹریکٹ آپریشنز کی حفاظت کے لیے require(), assert(), اور revert() اسٹیٹمنٹس کا استعمال کریں

جیسا کہ ذکر کیا گیا ہے، ایک بار جب آپ کا اسمارٹ کنٹریکٹ بلاک چین پر تعینات ہوجاتا ہے، تو کوئی بھی اس میں موجود عوامی فنکشنز کو کال کرسکتا ہے۔ چونکہ آپ پہلے سے یہ نہیں جان سکتے کہ بیرونی اکاؤنٹس کسی کنٹریکٹ کے ساتھ کیسے تعامل کریں گے، اس لیے تعیناتی سے پہلے پریشان کن آپریشنز کے خلاف اندرونی حفاظتی اقدامات نافذ کرنا مثالی ہے۔ آپ اسمارٹ کنٹریکٹس میں درست رویے کو نافذ کرنے کے لیے require()، assert()، اور revert() اسٹیٹمنٹس کا استعمال کرکے استثنیٰ کو متحرک کرسکتے ہیں اور اگر عمل درآمد کچھ ضروریات کو پورا کرنے میں ناکام رہتا ہے تو اسٹیٹ کی تبدیلیوں کو واپس کرسکتے ہیں۔

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

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

revert(): revert() کا استعمال if-else اسٹیٹمنٹ میں کیا جاسکتا ہے جو اگر مطلوبہ شرط پوری نہ ہو تو ایک استثنیٰ کو متحرک کرتا ہے۔ نیچے دیا گیا نمونہ کنٹریکٹ فنکشنز کے عمل درآمد کی حفاظت کے لیے revert() کا استعمال کرتا ہے:

1pragma solidity ^0.8.4;
2
3contract VendingMachine {
4 address owner;
5 error Unauthorized();
6 function buy(uint amount) public payable {
7 if (amount > msg.value / 2 ether)
8 revert("Not enough Ether provided.");
9 // Perform the purchase.
10 }
11 function withdraw() public {
12 if (msg.sender != owner)
13 revert Unauthorized();
14
15 payable(msg.sender).transfer(address(this).balance);
16 }
17}
سب دکھائیں

3۔ اسمارٹ کنٹریکٹس کی جانچ کریں اور کوڈ کی درستگی کی تصدیق کریں

Ethereum Virtual Machine میں چلنے والے کوڈ کی ناقابل تغیر نوعیت کا مطلب ہے کہ اسمارٹ کنٹریکٹس ڈیولپمنٹ کے مرحلے کے دوران اعلیٰ سطح کی کوالٹی کی تشخیص کا مطالبہ کرتے ہیں۔ اپنے کنٹریکٹ کی وسیع پیمانے پر جانچ کرنا اور کسی بھی غیر متوقع نتائج کے لیے اس کا مشاہدہ کرنا سیکیورٹی کو بہت بہتر بنائے گا اور طویل مدت میں آپ کے صارفین کی حفاظت کرے گا۔

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

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

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

رسمی تصدیق اسمارٹ کنٹریکٹس میں سیکیورٹی خصوصیات کی تصدیق کے لیے ایک اور تکنیک ہے۔ باقاعدہ ٹیسٹنگ کے برعکس، رسمی تصدیق ایک اسمارٹ کنٹریکٹ میں غلطیوں کی عدم موجودگی کو حتمی طور پر ثابت کر سکتی ہے۔ یہ ایک رسمی تفصیلات بنا کر حاصل کیا جاتا ہے جو مطلوبہ سیکیورٹی خصوصیات کو حاصل کرتی ہے اور یہ ثابت کرتی ہے کہ کنٹریکٹس کا ایک رسمی ماڈل اس تفصیلات پر عمل کرتا ہے۔

4. اپنے کوڈ کا ایک آزاد جائزہ طلب کریں

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

آڈٹس

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

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

بگ باؤنٹیز

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

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

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

5. اسمارٹ کنٹریکٹ ڈیولپمنٹ کے دوران بہترین طریقوں پر عمل کریں

آڈٹس اور بگ باؤنٹیز کا وجود اعلیٰ معیار کا کوڈ لکھنے کی آپ کی ذمہ داری سے بری نہیں کرتا۔ اچھی اسمارٹ کنٹریکٹ سیکیورٹی مناسب ڈیزائن اور ڈیولپمنٹ کے عمل پر عمل کرنے سے شروع ہوتی ہے:

  • تمام کوڈ کو ایک ورژن کنٹرول سسٹم میں اسٹور کریں، جیسے کہ git

  • تمام کوڈ میں ترمیمات پل ریکویسٹس کے ذریعے کریں

  • یقینی بنائیں کہ پل ریکویسٹس کا کم از کم ایک آزاد جائزہ لینے والا ہو—اگر آپ کسی پروجیکٹ پر اکیلے کام کررہے ہیں، تو دوسرے ڈیولپرز کو تلاش کرنے اور کوڈ کے جائزوں کا تبادلہ کرنے پر غور کریں۔

  • اسمارٹ کنٹریکٹس کی جانچ، کمپائلنگ، اور تعیناتی کے لیے ایک ڈیولپمنٹ ماحول کا استعمال کریں۔

  • اپنے کوڈ کو بنیادی کوڈ تجزیہ کے ٹولز، جیسے Cyfrin Aderyn (opens in a new tab)، Mythril اور Slither کے ذریعے چلائیں۔ مثالی طور پر، آپ کو یہ ہر پل ریکویسٹ کے ضم ہونے سے پہلے کرنا چاہئے اور آؤٹ پٹ میں فرق کا موازنہ کرنا چاہئے۔

  • یقینی بنائیں کہ آپ کا کوڈ بغیر کسی غلطی کے کمپائل ہو، اور Solidity کمپائلر کوئی انتباہ جاری نہ کرے۔

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

6. مضبوط ڈیزاسٹر ریکوری پلانز نافذ کریں

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

کنٹریکٹ اپ گریڈز

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

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

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

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

معاہدوں کو اپ گریڈ کرنے پر مزید.

ایمرجنسی اسٹاپس

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

آخری آپشن ایک "ایمرجنسی اسٹاپ" فنکشن کو نافذ کرنا ہے جو کسی معاہدے میں کمزور فنکشنز کی کالز کو بلاک کرتا ہے۔ ایمرجنسی اسٹاپس میں عام طور پر درج ذیل اجزاء شامل ہوتے ہیں:

  1. ایک عالمی بولین متغیر جو اس بات کی نشاندہی کرتا ہے کہ آیا اسمارٹ معاہدہ رکی ہوئی حالت میں ہے یا نہیں۔ معاہدہ ترتیب دیتے وقت یہ متغیر false پر سیٹ ہوتا ہے، لیکن معاہدہ رک جانے کے بعد true پر واپس آجاتا ہے۔

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

  3. ایک ایسی ہستی جس کی ایمرجنسی اسٹاپ فنکشن تک رسائی ہو، جو بولین متغیر کو true پر سیٹ کرتی ہے۔ بدنیتی پر مبنی کارروائیوں کو روکنے کے لیے، اس فنکشن کی کالز کو ایک قابل اعتماد پتے (مثلاً، معاہدے کا مالک) تک محدود کیا جا سکتا ہے۔

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

1// اس کوڈ کا پیشہ ورانہ طور پر آڈٹ نہیں کیا گیا ہے اور یہ حفاظت یا درستگی کے بارے میں کوئی وعدہ نہیں کرتا ہے۔ اپنے رسک پر استعمال کریں۔
2
3contract EmergencyStop {
4
5 bool isStopped = false;
6
7 modifier stoppedInEmergency {
8 require(!isStopped);
9 _;
10 }
11
12 modifier onlyWhenStopped {
13 require(isStopped);
14 _;
15 }
16
17 modifier onlyAuthorized {
18 // یہاں msg.sender کی اجازت کی جانچ کریں
19 _;
20 }
21
22 function stopContract() public onlyAuthorized {
23 isStopped = true;
24 }
25
26 function resumeContract() public onlyAuthorized {
27 isStopped = false;
28 }
29
30 function deposit() public payable stoppedInEmergency {
31 // یہاں ڈپازٹ کی منطق ہو رہی ہے
32 }
33
34 function emergencyWithdraw() public onlyWhenStopped {
35 // یہاں ایمرجنسی ودڈرال ہو رہا ہے
36 }
37}
سب دکھائیں

یہ مثال ایمرجنسی اسٹاپس کی بنیادی خصوصیات کو ظاہر کرتی ہے:

  • isStopped ایک بولین ہے جو شروع میں false اور جب معاہدہ ایمرجنسی موڈ میں داخل ہوتا ہے تو true کا جائزہ لیتا ہے۔

  • فنکشن موڈیفائرز onlyWhenStopped اور stoppedInEmergency متغیر isStopped کی جانچ کرتے ہیں۔ stoppedInEmergency کا استعمال ان فنکشنز کو کنٹرول کرنے کے لیے کیا جاتا ہے جو معاہدے کے کمزور ہونے پر ناقابل رسائی ہونے چاہئیں (مثلاً، deposit())۔ ان فنکشنز کی کالز بس واپس ہو جائیں گی۔

onlyWhenStopped کا استعمال ان فنکشنز کے لیے کیا جاتا ہے جو ایمرجنسی کے دوران قابلِ کال ہونے چاہئیں (مثلاً، emergencyWithdraw())۔ اس طرح کے فنکشنز صورت حال کو حل کرنے میں مدد کر سکتے ہیں، لہذا انہیں "محدود فنکشنز" کی فہرست سے خارج کیا گیا ہے۔

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

ایونٹ کی نگرانی

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

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

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

7. محفوظ گورننس سسٹمز ڈیزائن کریں

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

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

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

مشترکہ لنکس میں محفوظ گورننس سسٹمز ڈیزائن کرنے (opens in a new tab)، DAOs میں مختلف ووٹنگ میکانزم (opens in a new tab)، اور DeFi کا فائدہ اٹھاتے ہوئے عام DAO حملے کے ویکٹرز (opens in a new tab) کے بارے میں مزید۔

8۔ کوڈ میں پیچیدگی کو کم سے کم کریں

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

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

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

9۔ عام اسمارٹ کنٹریکٹ کی کمزوریوں سے دفاع کریں

دوبارہ داخلہ

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

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

ایک سادہ اسمارٹ کنٹریکٹ ('Victim') پر غور کریں جو کسی کو بھی ایتھر جمع کرنے اور نکالنے کی اجازت دیتا ہے:

1// یہ کنٹریکٹ کمزور ہے۔ پروڈکشن میں استعمال نہ کریں۔
2
3contract Victim {
4 mapping (address => uint256) public balances;
5
6 function deposit() external payable {
7 balances[msg.sender] += msg.value;
8 }
9
10 function withdraw() external {
11 uint256 amount = balances[msg.sender];
12 (bool success, ) = msg.sender.call.value(amount)("");
13 require(success);
14 balances[msg.sender] = 0;
15 }
16}
سب دکھائیں

یہ کنٹریکٹ صارفین کو کنٹریکٹ میں پہلے سے جمع شدہ ETH نکالنے کی اجازت دینے کے لیے ایک withdraw() فنکشن فراہم کرتا ہے۔ نکالنے کی کارروائی کرتے وقت، کنٹریکٹ درج ذیل آپریشنز انجام دیتا ہے:

  1. صارف کا ETH بیلنس چیک کرتا ہے
  2. کال کرنے والے ایڈریس پر فنڈز بھیجتا ہے
  3. ان کا بیلنس 0 پر ری سیٹ کرتا ہے، صارف سے مزید نکالنے کو روکتا ہے

Victim کنٹریکٹ میں withdraw() فنکشن "چیکس-انٹریکشنز-ایفیکٹس" پیٹرن کی پیروی کرتا ہے۔ یہ چیک کرتا ہے کہ آیا عمل درآمد کے لیے ضروری شرائط پوری ہوئی ہیں (یعنی، صارف کا مثبت ETH بیلنس ہے) اور کالر کے ایڈریس پر ETH بھیج کر انٹریکشن انجام دیتا ہے، اس سے پہلے کہ لین دین کے اثرات کو لاگو کرے (یعنی، صارف کا بیلنس کم کرنا)۔

اگر withdraw() کو ایک بیرونی ملکیت والے اکاؤنٹ (EOA) سے کال کیا جاتا ہے، تو فنکشن توقع کے مطابق عمل درآمد کرتا ہے: msg.sender.call.value() کالر کو ETH بھیجتا ہے۔ تاہم، اگر msg.sender ایک اسمارٹ کنٹریکٹ اکاؤنٹ ہے جو withdraw() کو کال کرتا ہے، تو msg.sender.call.value() کا استعمال کرکے فنڈز بھیجنا اس ایڈریس پر اسٹور کردہ کوڈ کو بھی چلائے گا۔

تصور کریں کہ یہ کوڈ کنٹریکٹ ایڈریس پر تعینات ہے:

1 contract Attacker {
2 function beginAttack() external payable {
3 Victim(victim_address).deposit.value(1 ether)();
4 Victim(victim_address).withdraw();
5 }
6
7 function() external payable {
8 if (gasleft() > 40000) {
9 Victim(victim_address).withdraw();
10 }
11 }
12}
سب دکھائیں

یہ کنٹریکٹ تین کام کرنے کے لیے ڈیزائن کیا گیا ہے:

  1. دوسرے اکاؤنٹ (ممکنہ طور پر حملہ آور کا EOA) سے ڈپازٹ قبول کریں
  2. Victim کنٹریکٹ میں 1 ETH جمع کریں
  3. اسمارٹ کنٹریکٹ میں اسٹور کردہ 1 ETH نکالیں

یہاں کوئی غلطی نہیں ہے، سوائے اس کے کہ Attacker کے پاس ایک اور فنکشن ہے جو Victim میں دوبارہ withdraw() کو کال کرتا ہے اگر آنے والے msg.sender.call.value سے بچا ہوا گیس 40,000 سے زیادہ ہو۔ یہ Attacker کو Victim میں دوبارہ داخل ہونے اور withdraw کی پہلی درخواست مکمل ہونے سے پہلے مزید فنڈز نکالنے کی صلاحیت دیتا ہے۔ یہ چکر اس طرح لگتا ہے:

1- حملہ آور کا EOA 1 ETH کے ساتھ `Attacker.beginAttack()` کو کال کرتا ہے
2- `Attacker.beginAttack()` `Victim` میں 1 ETH جمع کرتا ہے
3- `Attacker` `Victim` میں `withdraw()` کو کال کرتا ہے
4- `Victim` `Attacker` کا بیلنس چیک کرتا ہے (1 ETH)
5- `Victim` `Attacker` کو 1 ETH بھیجتا ہے (جو ڈیفالٹ فنکشن کو متحرک کرتا ہے)
6- `Attacker` دوبارہ `Victim.withdraw()` کو کال کرتا ہے (نوٹ کریں کہ `Victim` نے پہلی نکالی سے `Attacker` کا بیلنس کم نہیں کیا ہے)
7- `Victim` `Attacker` کا بیلنس چیک کرتا ہے (جو اب بھی 1 ETH ہے کیونکہ اس نے پہلی کال کے اثرات لاگو نہیں کیے ہیں)
8- `Victim` `Attacker` کو 1 ETH بھیجتا ہے (جو ڈیفالٹ فنکشن کو متحرک کرتا ہے اور `Attacker` کو `withdraw` فنکشن میں دوبارہ داخل ہونے کی اجازت دیتا ہے)
9- یہ عمل اس وقت تک دہرایا جاتا ہے جب تک کہ `Attacker` کا گیس ختم نہ ہو جائے، جس کے بعد `msg.sender.call.value` اضافی نکالی کو متحرک کیے بغیر واپس آجاتا ہے
10- `Victim` آخر میں پہلی لین دین (اور بعد کی) کے نتائج کو اپنی اسٹیٹ پر لاگو کرتا ہے، لہذا `Attacker` کا بیلنس 0 پر سیٹ ہو جاتا ہے
سب دکھائیں

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

دوبارہ داخلے کے حملوں کو کیسے روکا جائے

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

چیکس-ایفیکٹ-انٹریکشن پیٹرن Victim کنٹریکٹ کے نظر ثانی شدہ ورژن میں استعمال ہوتا ہے جو نیچے دکھایا گیا ہے:

1contract NoLongerAVictim {
2 function withdraw() external {
3 uint256 amount = balances[msg.sender];
4 balances[msg.sender] = 0;
5 (bool success, ) = msg.sender.call.value(amount)("");
6 require(success);
7 }
8}

یہ کنٹریکٹ صارف کے بیلنس پر ایک چیک کرتا ہے، withdraw() فنکشن کے اثرات کو لاگو کرتا ہے (صارف کا بیلنس 0 پر ری سیٹ کرکے)، اور انٹریکشن انجام دینے کے لیے آگے بڑھتا ہے (صارف کے ایڈریس پر ETH بھیجنا)۔ یہ یقینی بناتا ہے کہ کنٹریکٹ بیرونی کال سے پہلے اپنے اسٹوریج کو اپ ڈیٹ کرے، جس سے دوبارہ داخلے کی شرط ختم ہو جاتی ہے جس نے پہلے حملے کو ممکن بنایا تھا۔ Attacker کنٹریکٹ اب بھی NoLongerAVictim میں واپس کال کرسکتا ہے، لیکن چونکہ balances[msg.sender] کو 0 پر سیٹ کردیا گیا ہے، اس لیے اضافی نکالی ایک خرابی پیدا کرے گی۔

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

1pragma solidity ^0.7.0;
2
3contract MutexPattern {
4 bool locked = false;
5 mapping(address => uint256) public balances;
6
7 modifier noReentrancy() {
8 require(!locked, "Blocked from reentrancy.");
9 locked = true;
10 _;
11 locked = false;
12 }
13 // This function is protected by a mutex, so reentrant calls from within `msg.sender.call` cannot call `withdraw` again.
14 // The `return` statement evaluates to `true` but still evaluates the `locked = false` statement in the modifier
15 function withdraw(uint _amount) public payable noReentrancy returns(bool) {
16 require(balances[msg.sender] >= _amount, "No balance to withdraw.");
17
18 balances[msg.sender] -= _amount;
19 (bool success, ) = msg.sender.call{value: _amount}("");
20 require(success);
21
22 return true;
23 }
24}
سب دکھائیں

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

انٹیجر انڈر فلوز اور اوور فلوز

ایک انٹیجر اوور فلو اس وقت ہوتا ہے جب ایک حسابی عمل کے نتائج قابل قبول قدروں کی حد سے باہر ہوجاتے ہیں، جس کی وجہ سے یہ سب سے کم نمائندگی کے قابل قدر پر "رول اوور" ہوجاتا ہے۔ مثال کے طور پر، ایک uint8 صرف 2^8-1=255 تک کی قدریں اسٹور کرسکتا ہے۔ وہ حسابی عمل جن کے نتیجے میں 255 سے زیادہ قدریں آتی ہیں، اوور فلو ہو جائیں گے اور uint کو 0 پر ری سیٹ کر دیں گے، اسی طرح جیسے کار کا اوڈومیٹر زیادہ سے زیادہ مائلیج (999999) تک پہنچنے پر 0 پر ری سیٹ ہوجاتا ہے۔

انٹیجر انڈر فلوز اسی طرح کی وجوہات کی بنا پر ہوتے ہیں: ایک حسابی عمل کے نتائج قابل قبول حد سے نیچے آجاتے ہیں۔ فرض کریں کہ آپ نے uint8 میں 0 کو کم کرنے کی کوشش کی، تو نتیجہ صرف زیادہ سے زیادہ نمائندگی کے قابل قدر (255) پر رول اوور ہوجائے گا۔

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

1pragma solidity ^0.7.6;
2
3// یہ کنٹریکٹ ایک ٹائم والٹ کے طور پر کام کرنے کے لیے ڈیزائن کیا گیا ہے۔
4// صارف اس کنٹریکٹ میں جمع تو کرسکتا ہے لیکن کم از کم ایک ہفتے تک نکال نہیں سکتا۔
5// صارف 1 ہفتے کے انتظار کی مدت سے آگے بھی انتظار کا وقت بڑھا سکتا ہے۔
6
7/*
81. TimeLock تعینات کریں۔
92. TimeLock کے ایڈریس کے ساتھ Attack تعینات کریں۔
103. 1 ایتھر بھیج کر Attack.attack کو کال کریں۔ آپ فوری طور پر اپنا
11 ایتھر نکال سکیں گے۔
12
13کیا ہوا؟
14حملے نے TimeLock.lockTime کو اوور فلو کردیا اور 1 ہفتے کی انتظار کی مدت سے پہلے
15نکالنے میں کامیاب رہا۔
16*/
17
18contract TimeLock {
19 mapping(address => uint) public balances;
20 mapping(address => uint) public lockTime;
21
22 function deposit() external payable {
23 balances[msg.sender] += msg.value;
24 lockTime[msg.sender] = block.timestamp + 1 weeks;
25 }
26
27 function increaseLockTime(uint _secondsToIncrease) public {
28 lockTime[msg.sender] += _secondsToIncrease;
29 }
30
31 function withdraw() public {
32 require(balances[msg.sender] > 0, "Insufficient funds");
33 require(block.timestamp > lockTime[msg.sender], "Lock time not expired");
34
35 uint amount = balances[msg.sender];
36 balances[msg.sender] = 0;
37
38 (bool sent, ) = msg.sender.call{value: amount}("");
39 require(sent, "Failed to send Ether");
40 }
41}
42
43contract Attack {
44 TimeLock timeLock;
45
46 constructor(TimeLock _timeLock) {
47 timeLock = TimeLock(_timeLock);
48 }
49
50 fallback() external payable {}
51
52 function attack() public payable {
53 timeLock.deposit{value: msg.value}();
54 /*
55 اگر t = موجودہ لاک ٹائم ہے تو ہمیں x تلاش کرنے کی ضرورت ہے اس طرح کہ
56 x + t = 2**256 = 0
57 تو x = -t
58 2**256 = type(uint).max + 1
59 تو x = type(uint).max + 1 - t
60 */
61 timeLock.increaseLockTime(
62 type(uint).max + 1 - timeLock.lockTime(address(this))
63 );
64 timeLock.withdraw();
65 }
66}
سب دکھائیں
انٹیجر انڈر فلوز اور اوور فلوز کو کیسے روکا جائے

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

اوریکل ہیرا پھیری

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

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

ایک متعلقہ سیکیورٹی تشویش ایک آن چین اوریکل، جیسے کہ ایک غیر مرکزی ایکسچینج، کا استعمال کرکے کسی اثاثے کی اسپاٹ قیمت حاصل کرنا ہے۔ غیر مرکزی فنانس (DeFi) صنعت میں قرض دینے والے پلیٹ فارمز اکثر یہ کام صارف کے کولیٹرل کی قدر کا تعین کرنے کے لیے کرتے ہیں تاکہ یہ تعین کیا جاسکے کہ وہ کتنا قرض لے سکتے ہیں۔

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

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

اوریکل ہیرا پھیری کو کیسے روکا جائے

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

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

ڈیولپرز کے لیے اسمارٹ کنٹریکٹ سیکیورٹی وسائل

اسمارٹ کنٹریکٹس کا تجزیہ کرنے اور کوڈ کی درستگی کی تصدیق کے لیے ٹولز

  • ٹیسٹنگ ٹولز اور لائبریریاں - اسمارٹ کنٹریکٹس پر یونٹ ٹیسٹ، اسٹیٹک تجزیہ، اور ڈائنامک تجزیہ کرنے کے لیے صنعت کے معیاری ٹولز اور لائبریریوں کا مجموعہ۔

  • رسمی تصدیق کے ٹولز - اسمارٹ کنٹریکٹس میں فنکشنل درستگی کی تصدیق کرنے اور انویرینٹس کی جانچ کے لیے ٹولز۔

  • اسمارٹ کنٹریکٹ آڈٹ کرنے کی خدمات - Ethereum ڈیولپمنٹ پروجیکٹس کے لیے اسمارٹ کنٹریکٹ آڈٹ کرنے کی خدمات فراہم کرنے والی تنظیموں کی فہرست۔

  • بگ باؤنٹی پلیٹ فارمز - بگ باؤنٹیز کو مربوط کرنے اور اسمارٹ کنٹریکٹس میں اہم کمزوریوں کے ذمہ دارانہ انکشاف پر انعام دینے کے لیے پلیٹ فارمز۔

  • Fork Checker (opens in a new tab) - ایک فورک شدہ کنٹریکٹ کے بارے میں تمام دستیاب معلومات کی جانچ کے لیے ایک مفت آن لائن ٹول۔

  • ABI Encoder (opens in a new tab) - آپ کے Solidity کنٹریکٹ فنکشنز اور کنسٹرکٹر دلائل کو انکوڈ کرنے کے لیے ایک مفت آن لائن سروس۔

  • Aderyn (opens in a new tab) - Solidity اسٹیٹک اینالائزر، جو ایبسٹریکٹ سنٹیکس ٹریز (AST) سے گزر کر مشتبہ کمزوریوں کی نشاندہی کرتا ہے اور مسائل کو ایک آسان استعمال کے لیے مارک ڈاؤن فارمیٹ میں پرنٹ کرتا ہے۔

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

اسمارٹ کنٹریکٹس کی محفوظ انتظامیہ کے لیے ٹولز

  • Safe (opens in a new tab) - Ethereum پر چلنے والا اسمارٹ کنٹریکٹ والیٹ جس میں کسی لین دین کے ہونے سے پہلے کم از کم تعداد میں لوگوں کی منظوری کی ضرورت ہوتی ہے (M-of-N)۔

  • OpenZeppelin Contracts (opens in a new tab) - انتظامی خصوصیات کو نافذ کرنے کے لیے کنٹریکٹ لائبریریاں، بشمول کنٹریکٹ کی ملکیت، اپ گریڈ، رسائی کنٹرول، گورننس، توقف پذیری، اور مزید۔

اسمارٹ کنٹریکٹ آڈٹ کرنے کی خدمات

  • ConsenSys Diligence (opens in a new tab) - اسمارٹ کنٹریکٹ آڈٹ کرنے کی سروس جو بلاک چین ایکو سسٹم میں پروجیکٹس کو یہ یقینی بنانے میں مدد کرتی ہے کہ ان کے پروٹوکول لانچ کے لیے تیار ہیں اور صارفین کی حفاظت کے لیے بنائے گئے ہیں۔

  • CertiK (opens in a new tab) - بلاک چین سیکیورٹی فرم جو اسمارٹ کنٹریکٹس اور بلاک چین نیٹ ورکس پر جدید ترین رسمی تصدیق کی ٹیکنالوجی کے استعمال میں پیش پیش ہے۔

  • Trail of Bits (opens in a new tab) - سائبر سیکیورٹی کمپنی جو خطرے کو کم کرنے اور کوڈ کو مضبوط کرنے کے لیے سیکیورٹی تحقیق کو حملہ آور کی ذہنیت کے ساتھ جوڑتی ہے۔

  • PeckShield (opens in a new tab) - بلاک چین سیکیورٹی کمپنی جو پورے بلاک چین ایکو سسٹم کی سیکیورٹی، رازداری اور استعمال کے لیے مصنوعات اور خدمات پیش کرتی ہے۔

  • QuantStamp (opens in a new tab) - سیکیورٹی اور رسک اسسمنٹ خدمات کے ذریعے بلاک چین ٹیکنالوجی کو مرکزی دھارے میں لانے میں سہولت فراہم کرنے والی آڈٹ سروس۔

  • OpenZeppelin (opens in a new tab) - اسمارٹ کنٹریکٹ سیکیورٹی کمپنی جو تقسیم شدہ سسٹمز کے لیے سیکیورٹی آڈٹ فراہم کرتی ہے۔

  • Runtime Verification (opens in a new tab) - سیکیورٹی کمپنی جو اسمارٹ کنٹریکٹس کی رسمی ماڈلنگ اور تصدیق میں مہارت رکھتی ہے۔

  • Hacken (opens in a new tab) - Web3 سائبر سیکیورٹی آڈیٹر جو بلاک چین سیکیورٹی کے لیے 360 ڈگری کا نقطہ نظر لاتا ہے۔

  • Nethermind (opens in a new tab) - Solidity اور Cairo آڈٹ خدمات، جو Ethereum اور Starknet پر اسمارٹ کنٹریکٹس کی سالمیت اور صارفین کی حفاظت کو یقینی بناتی ہیں۔

  • HashEx (opens in a new tab) - HashEx کرپٹو کرنسیوں کی سیکیورٹی کو یقینی بنانے کے لیے بلاک چین اور اسمارٹ کنٹریکٹ آڈٹ پر توجہ مرکوز کرتا ہے، جس میں اسمارٹ کنٹریکٹ ڈیولپمنٹ، پینیٹریشن ٹیسٹنگ، بلاک چین کنسلٹنگ جیسی خدمات فراہم کی جاتی ہیں۔

  • Code4rena (opens in a new tab) - مسابقتی آڈٹ پلیٹ فارم جو اسمارٹ کنٹریکٹ سیکیورٹی ماہرین کو کمزوریاں تلاش کرنے اور ویب 3 کو زیادہ محفوظ بنانے میں مدد کرنے کی ترغیب دیتا ہے۔

  • CodeHawks (opens in a new tab) - مسابقتی آڈٹ پلیٹ فارم جو سیکیورٹی محققین کے لیے اسمارٹ کنٹریکٹس آڈٹ کے مقابلوں کی میزبانی کرتا ہے۔

  • Cyfrin (opens in a new tab) - Web3 سیکیورٹی کا پاور ہاؤس، جو مصنوعات اور اسمارٹ کنٹریکٹ آڈٹ خدمات کے ذریعے کرپٹو سیکیورٹی کو فروغ دیتا ہے۔

  • ImmuneBytes (opens in a new tab) - Web3 سیکیورٹی فرم جو تجربہ کار آڈیٹرز اور بہترین ٹولز کی ایک ٹیم کے ذریعے بلاک چین سسٹمز کے لیے سیکیورٹی آڈٹ پیش کرتی ہے۔

  • Oxorio (opens in a new tab) - کرپٹو فرموں اور DeFi پروجیکٹس کے لیے EVM, Solidity, ZK, کراس چین ٹیک میں مہارت کے ساتھ اسمارٹ کنٹریکٹ آڈٹ اور بلاک چین سیکیورٹی خدمات۔

  • Inference (opens in a new tab) - _سیکیورٹی آڈٹ کمپنی، جو EVM پر مبنی بلاک چینز کے لیے اسمارٹ کنٹریکٹ آڈٹ میں مہارت رکھتی ہے۔ اس کے ماہر آڈیٹرز کی بدولت وہ ممکنہ مسائل کی نشاندہی کرتے ہیں اور تعیناتی سے پہلے انہیں ٹھیک کرنے کے لیے قابل عمل حل تجویز کرتے ہیں۔

بگ باؤنٹی پلیٹ فارمز

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

  • HackerOne (opens in a new tab) - کمزوریوں کو مربوط کرنے اور بگ باؤنٹی پلیٹ فارم جو کاروباروں کو پینیٹریشن ٹیسٹرز اور سائبر سیکیورٹی محققین سے جوڑتا ہے۔

  • HackenProof (opens in a new tab) - کرپٹو پروجیکٹس (DeFi، اسمارٹ کنٹریکٹس، والیٹس، CEX اور مزید) کے لیے ماہر بگ باؤنٹی پلیٹ فارم، جہاں سیکیورٹی پروفیشنلز ٹرائی ایج خدمات فراہم کرتے ہیں اور محققین کو متعلقہ، تصدیق شدہ بگ رپورٹس کے لیے ادائیگی ملتی ہے۔

  • Sherlock (opens in a new tab) - ویب 3 میں اسمارٹ کنٹریکٹ سیکیورٹی کے لیے انڈر رائٹر، جس میں آڈیٹرز کے لیے ادائیگیوں کا انتظام اسمارٹ کنٹریکٹس کے ذریعے کیا جاتا ہے تاکہ یہ یقینی بنایا جاسکے کہ متعلقہ بگز کی منصفانہ ادائیگی کی جائے۔

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

معروف اسمارٹ کنٹریکٹ کی کمزوریوں اور استحصال کی اشاعتیں

اسمارٹ کنٹریکٹ سیکیورٹی سیکھنے کے لیے چیلنجز

اسمارٹ کنٹریکٹس کو محفوظ بنانے کے لیے بہترین طریقے

اسمارٹ کنٹریکٹ سیکیورٹی پر ٹیوٹوریلز

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