یلو پیپر کی EVM تفصیلات کو سمجھنا
یلو پیپر (opens in a new tab) ایتھیریم کے لیے باضابطہ تفصیلات ہے۔ سوائے ان جگہوں کے جہاں EIP عمل کے ذریعے ترمیم کی گئی ہو، اس میں ہر چیز کے کام کرنے کے طریقے کی قطعی وضاحت موجود ہے۔ یہ ایک ریاضیاتی مقالے کے طور پر لکھا گیا ہے، جس میں ایسی اصطلاحات شامل ہیں جن سے پروگرامرز شاید واقف نہ ہوں۔ اس مقالے میں آپ اسے پڑھنا سیکھیں گے، اور اس کی توسیع کے طور پر دیگر متعلقہ ریاضیاتی مقالے بھی۔
کون سا یلو پیپر؟
ایتھیریم میں تقریباً ہر دوسری چیز کی طرح، یلو پیپر بھی وقت کے ساتھ ساتھ ارتقاء پذیر ہوتا ہے۔ کسی مخصوص ورژن کا حوالہ دینے کے قابل ہونے کے لیے، میں نے لکھتے وقت کا موجودہ ورژن اپ لوڈ کر دیا ہے۔ میں جو سیکشن، صفحہ، اور مساوات کے نمبر استعمال کروں گا وہ اسی ورژن کا حوالہ دیں گے۔ اس دستاویز کو پڑھتے وقت اسے کسی دوسری ونڈو میں کھلا رکھنا ایک اچھا خیال ہے۔
EVM کیوں؟
اصل یلو پیپر ایتھیریم کی ترقی کے بالکل آغاز میں لکھا گیا تھا۔ یہ اصل ثبوتِ کار (PoW) پر مبنی اتفاق رائے کا طریقہ کار بیان کرتا ہے جو اصل میں نیٹ ورک کو محفوظ بنانے کے لیے استعمال کیا گیا تھا۔ تاہم، ایتھیریم نے ثبوتِ کار (PoW) کو بند کر دیا اور September 2022 میں حصہ داری کا ثبوت (PoS) پر مبنی اتفاق رائے کا استعمال شروع کر دیا۔ یہ ٹیوٹوریل یلو پیپر کے ان حصوں پر توجہ مرکوز کرے گا جو ایتھیریم ورچوئل مشین کی وضاحت کرتے ہیں۔ EVM حصہ داری کا ثبوت (PoS) کی طرف منتقلی سے غیر تبدیل شدہ رہا (سوائے DIFFICULTY آپ کوڈ کی واپسی کی قدر کے)۔
9 عمل درآمد کا ماڈل
اس سیکشن (صفحہ 12-14) میں EVM کی زیادہ تر تعریف شامل ہے۔
اصطلاح سسٹم کی حالت میں وہ سب کچھ شامل ہے جو آپ کو سسٹم کو چلانے کے لیے اس کے بارے میں جاننے کی ضرورت ہے۔ ایک عام کمپیوٹر میں، اس کا مطلب میموری، رجسٹرز کا مواد وغیرہ ہے۔
ایک ٹیورنگ مشین (opens in a new tab) ایک کمپیوٹیشنل ماڈل ہے۔ بنیادی طور پر، یہ کمپیوٹر کا ایک سادہ ورژن ہے، جس کے بارے میں ثابت ہو چکا ہے کہ اس میں حساب کتاب چلانے کی وہی صلاحیت ہے جو ایک عام کمپیوٹر میں ہوتی ہے (ہر وہ چیز جس کا حساب ایک کمپیوٹر لگا سکتا ہے، ایک ٹیورنگ مشین بھی اس کا حساب لگا سکتی ہے اور اس کے برعکس)۔ یہ ماڈل اس بارے میں مختلف نظریات کو ثابت کرنا آسان بناتا ہے کہ کیا قابلِ حساب ہے اور کیا نہیں۔
اصطلاح ٹیورنگ-مکمل (opens in a new tab) کا مطلب ایک ایسا کمپیوٹر ہے جو ٹیورنگ مشین کی طرح ہی حساب کتاب چلا سکتا ہے۔ ٹیورنگ مشینیں لامحدود لوپس میں پھنس سکتی ہیں، اور EVM ایسا نہیں کر سکتی کیونکہ اس کی گیس ختم ہو جائے گی، اس لیے یہ صرف نیم-ٹیورنگ-مکمل ہے۔
9.1 بنیادی باتیں
یہ سیکشن EVM کی بنیادی باتیں فراہم کرتا ہے اور یہ بتاتا ہے کہ اس کا دیگر کمپیوٹیشنل ماڈلز سے کیسے موازنہ کیا جاتا ہے۔
ایک اسٹیک مشین (opens in a new tab) ایک ایسا کمپیوٹر ہے جو درمیانی ڈیٹا کو رجسٹرز میں نہیں، بلکہ ایک اسٹیک (opens in a new tab) میں محفوظ کرتا ہے۔ یہ ورچوئل مشینوں کے لیے ترجیحی فن تعمیر ہے کیونکہ اسے نافذ کرنا آسان ہے جس کا مطلب ہے کہ بگز اور سیکیورٹی کے خطرات کا امکان بہت کم ہوتا ہے۔ اسٹیک میں میموری کو 256-bit الفاظ میں تقسیم کیا گیا ہے۔ اسے اس لیے منتخب کیا گیا تھا کیونکہ یہ ایتھیریم کے بنیادی کرپٹوگرافک آپریشنز جیسے کیچاک-۲۵۶ ہیشنگ اور بیضوی منحنی کے حساب کتاب کے لیے آسان ہے۔ اسٹیک کا زیادہ سے زیادہ سائز 1024 آئٹمز (1024 x 256 bits) ہے۔ جب آپ کوڈز پر عمل درآمد کیا جاتا ہے تو وہ عام طور پر اپنے پیرامیٹرز اسٹیک سے حاصل کر رہے ہوتے ہیں۔ اسٹیک میں عناصر کو دوبارہ ترتیب دینے کے لیے خاص طور پر آپ کوڈز موجود ہیں جیسے POP (اسٹیک کے اوپری حصے سے آئٹم کو ہٹاتا ہے)، DUP_N (اسٹیک میں N ویں آئٹم کی نقل بناتا ہے)، وغیرہ۔
EVM میں ایک غیر مستقل جگہ بھی ہوتی ہے جسے میموری کہا جاتا ہے جو عمل درآمد کے دوران ڈیٹا کو محفوظ کرنے کے لیے استعمال ہوتی ہے۔ یہ میموری 32-byte الفاظ میں ترتیب دی گئی ہے۔ تمام میموری کے مقامات کو صفر پر شروع کیا جاتا ہے۔ اگر آپ میموری میں ایک لفظ شامل کرنے کے لیے اس Yul (opens in a new tab) کوڈ پر عمل درآمد کرتے ہیں، تو یہ لفظ میں خالی جگہ کو صفر سے بھر کر میموری کے 32 bytes کو پُر کر دے گا، یعنی یہ ایک لفظ بناتا ہے - جس میں مقامات 0-29 پر صفر، 30 پر 0x60، اور 31 پر 0xA7 ہوتا ہے۔
mstore(0, 0x60A7)
mstore ان تین آپ کوڈز میں سے ایک ہے جو EVM میموری کے ساتھ تعامل کے لیے فراہم کرتا ہے - یہ میموری میں ایک لفظ لوڈ کرتا ہے۔ دیگر دو mstore8 ہیں جو میموری میں ایک بائٹ لوڈ کرتا ہے، اور mload جو میموری سے اسٹیک میں ایک لفظ منتقل کرتا ہے۔
EVM میں ایک الگ غیر متزلزل اسٹوریج ماڈل بھی ہے جسے سسٹم کی حالت کے حصے کے طور پر برقرار رکھا جاتا ہے - یہ میموری الفاظ کی صفوں (اسٹیک میں ورڈ-ایڈریس ایبل بائٹ صفوں کے برعکس) میں ترتیب دی گئی ہے۔ یہ اسٹوریج وہ جگہ ہے جہاں کنٹریکٹس مستقل ڈیٹا رکھتے ہیں - ایک کنٹریکٹ صرف اپنے اسٹوریج کے ساتھ تعامل کر سکتا ہے۔ اسٹوریج کو کلید-قدر کی میپنگز میں ترتیب دیا گیا ہے۔
اگرچہ یلو پیپر کے اس حصے میں اس کا ذکر نہیں کیا گیا ہے، لیکن یہ جاننا بھی مفید ہے کہ میموری کی ایک چوتھی قسم بھی ہے۔ کال ڈیٹا بائٹ-ایڈریس ایبل صرف پڑھنے کے قابل میموری ہے جو ٹرانزیکشن کے data پیرامیٹر کے ساتھ پاس کی گئی قدر کو محفوظ کرنے کے لیے استعمال ہوتی ہے۔ EVM کے پاس calldata کو منظم کرنے کے لیے مخصوص آپ کوڈز ہیں۔ calldatasize ڈیٹا کا سائز واپس کرتا ہے۔ calldataload ڈیٹا کو اسٹیک میں لوڈ کرتا ہے۔ calldatacopy ڈیٹا کو میموری میں کاپی کرتا ہے۔
معیاری وان نیومین فن تعمیر (opens in a new tab) کوڈ اور ڈیٹا کو ایک ہی میموری میں محفوظ کرتا ہے۔ EVM سیکیورٹی وجوہات کی بنا پر اس معیار کی پیروی نہیں کرتا ہے - غیر مستقل میموری کا اشتراک پروگرام کوڈ کو تبدیل کرنا ممکن بناتا ہے۔ اس کے بجائے، کوڈ کو اسٹوریج میں محفوظ کیا جاتا ہے۔
صرف دو صورتیں ہیں جن میں کوڈ پر میموری سے عمل درآمد کیا جاتا ہے:
- جب ایک کنٹریکٹ دوسرا کنٹریکٹ بناتا ہے (
CREATE(opens in a new tab) یاCREATE2(opens in a new tab) کا استعمال کرتے ہوئے)، تو کنٹریکٹ کنسٹرکٹر کا کوڈ میموری سے آتا ہے۔ - کسی بھی کنٹریکٹ کی تخلیق کے دوران، کنسٹرکٹر کوڈ چلتا ہے اور پھر اصل کنٹریکٹ کے کوڈ کے ساتھ واپس آتا ہے، وہ بھی میموری سے۔
اصطلاح غیر معمولی عمل درآمد کا مطلب ایک ایسی استثنا ہے جو موجودہ کنٹریکٹ کے عمل درآمد کو روکنے کا سبب بنتی ہے۔
9.2 فیس کا جائزہ
یہ سیکشن بتاتا ہے کہ گیس کی فیس کا حساب کیسے لگایا جاتا ہے۔ اس کی تین لاگتیں ہیں:
آپ کوڈ کی لاگت
مخصوص آپ کوڈ کی موروثی لاگت۔ یہ قدر حاصل کرنے کے لیے، ضمیمہ H (صفحہ 28، مساوات (327) کے تحت) میں آپ کوڈ کا لاگت گروپ تلاش کریں، اور مساوات (324) میں لاگت گروپ تلاش کریں۔ یہ آپ کو ایک لاگت کا فنکشن دیتا ہے، جو زیادہ تر معاملات میں ضمیمہ G (صفحہ 27) سے پیرامیٹرز استعمال کرتا ہے۔
مثال کے طور پر، آپ کوڈ CALLDATACOPY (opens in a new tab) گروپ Wcopy کا رکن ہے۔ اس گروپ کے لیے آپ کوڈ کی لاگت Gverylow+Gcopy×⌈μs[2]÷32⌉ ہے۔ ضمیمہ G کو دیکھتے ہوئے، ہم دیکھتے ہیں کہ دونوں مستقل 3 ہیں، جو ہمیں 3+3×⌈μs[2]÷32⌉ دیتا ہے۔
ہمیں ابھی بھی اظہار ⌈μs[2]÷32⌉ کو سمجھنے کی ضرورت ہے۔ سب سے بیرونی حصہ، ⌈ <value> ⌉ سیلنگ فنکشن ہے، ایک ایسا فنکشن جو کسی قدر کے دیے جانے پر سب سے چھوٹا عدد واپس کرتا ہے جو اس قدر سے چھوٹا نہیں ہوتا۔ مثال کے طور پر، ⌈2.5⌉ = ⌈3⌉ = 3۔ اندرونی حصہ μs[2]÷32 ہے۔ صفحہ 3 پر سیکشن 3 (روایات) کو دیکھتے ہوئے، μ مشین کی حالت ہے۔ مشین کی حالت کی تعریف صفحہ 13 پر سیکشن 9.4.1 میں کی گئی ہے۔ اس سیکشن کے مطابق، مشین کی حالت کے پیرامیٹرز میں سے ایک اسٹیک کے لیے s ہے۔ ان سب کو ملا کر، ایسا لگتا ہے کہ μs[2] اسٹیک میں مقام #2 ہے۔ آپ کوڈ (opens in a new tab) کو دیکھتے ہوئے، اسٹیک میں مقام #2 بائٹس میں ڈیٹا کا سائز ہے۔ گروپ Wcopy میں دیگر آپ کوڈز، CODECOPY (opens in a new tab) اور RETURNDATACOPY (opens in a new tab) کو دیکھتے ہوئے، ان کے پاس بھی اسی مقام پر ڈیٹا کا سائز ہوتا ہے۔ لہذا ⌈μs[2]÷32⌉ کاپی کیے جانے والے ڈیٹا کو محفوظ کرنے کے لیے درکار 32 byte الفاظ کی تعداد ہے۔ ہر چیز کو ملا کر، CALLDATACOPY (opens in a new tab) کی موروثی لاگت 3 گیس کے علاوہ کاپی کیے جانے والے ڈیٹا کے فی لفظ 3 ہے۔
چلانے کی لاگت
اس کوڈ کو چلانے کی لاگت جسے ہم کال کر رہے ہیں۔
CREATE(opens in a new tab) اورCREATE2(opens in a new tab) کے معاملے میں، نئے کنٹریکٹ کے لیے کنسٹرکٹر۔CALL(opens in a new tab)،CALLCODE(opens in a new tab)،STATICCALL(opens in a new tab)، یاDELEGATECALL(opens in a new tab) کے معاملے میں، وہ کنٹریکٹ جسے ہم کال کرتے ہیں۔
میموری کو بڑھانے کی لاگت
میموری کو بڑھانے کی لاگت (اگر ضروری ہو)۔
مساوات 324 میں، یہ قدر Cmem(μi')-Cmem(μi) کے طور پر لکھی گئی ہے۔ سیکشن 9.4.1 کو دوبارہ دیکھتے ہوئے، ہم دیکھتے ہیں کہ μi میموری میں الفاظ کی تعداد ہے۔ لہذا μi آپ کوڈ سے پہلے میموری میں الفاظ کی تعداد ہے اور μi' آپ کوڈ کے بعد میموری میں الفاظ کی تعداد ہے۔
فنکشن Cmem کی تعریف مساوات 326 میں کی گئی ہے: Cmem(a) = Gmemory × a + ⌊a2 ÷ 512⌋۔ ⌊x⌋ فلور فنکشن ہے، ایک ایسا فنکشن جو کسی قدر کے دیے جانے پر سب سے بڑا عدد واپس کرتا ہے جو اس قدر سے بڑا نہیں ہوتا۔ مثال کے طور پر، ⌊2.5⌋ = ⌊2⌋ = 2۔ جب a < √512، a2 < 512، اور فلور فنکشن کا نتیجہ صفر ہوتا ہے۔ لہذا پہلے 22 الفاظ (704 bytes) کے لیے، لاگت درکار میموری الفاظ کی تعداد کے ساتھ لکیری طور پر بڑھتی ہے۔ اس مقام کے بعد ⌊a2 ÷ 512⌋ مثبت ہے۔ جب درکار میموری کافی زیادہ ہو تو گیس کی لاگت میموری کی مقدار کے مربع کے متناسب ہوتی ہے۔
نوٹ کریں کہ یہ عوامل صرف موروثی گیس کی لاگت کو متاثر کرتے ہیں - یہ فیس مارکیٹ یا توثیق کاروں کو دی جانے والی ٹپس کو مدنظر نہیں رکھتا جو یہ طے کرتے ہیں کہ آخری صارف کو کتنی ادائیگی کرنی ہے - یہ صرف EVM پر کسی خاص آپریشن کو چلانے کی خام لاگت ہے۔
9.3 عمل درآمد کا ماحول
عمل درآمد کا ماحول ایک ٹپل، I ہے، جس میں ایسی معلومات شامل ہیں جو بلاک چین کی حالت یا EVM کا حصہ نہیں ہیں۔
| پیرامیٹر | ڈیٹا تک رسائی کے لیے آپ کوڈ | ڈیٹا تک رسائی کے لیے Solidity کوڈ |
|---|---|---|
| Ia | ADDRESS (opens in a new tab) | address(this) |
| Io | ORIGIN (opens in a new tab) | tx.origin |
| Ip | GASPRICE (opens in a new tab) | tx.gasprice |
| Id | CALLDATALOAD (opens in a new tab)، وغیرہ۔ | msg.data |
| Is | CALLER (opens in a new tab) | msg.sender |
| Iv | CALLVALUE (opens in a new tab) | msg.value |
| Ib | CODECOPY (opens in a new tab) | address(this).code |
| IH | بلاک ہیڈر فیلڈز، جیسے NUMBER (opens in a new tab) اور DIFFICULTY (opens in a new tab) | block.number، block.difficulty، وغیرہ۔ |
| Ie | کنٹریکٹس کے درمیان کالز کے لیے کال اسٹیک کی گہرائی (بشمول کنٹریکٹ کی تخلیق) | |
| Iw | کیا EVM کو حالت تبدیل کرنے کی اجازت ہے، یا یہ جامد طور پر چل رہا ہے |
سیکشن 9 کے باقی حصے کو سمجھنے کے لیے کچھ اور پیرامیٹرز ضروری ہیں:
| پیرامیٹر | سیکشن میں بیان کردہ | معنی |
|---|---|---|
| σ | 2 (صفحہ 2، مساوات 1) | بلاک چین کی حالت |
| g | 9.3 (صفحہ 13) | باقی ماندہ گیس |
| A | 6.1 (صفحہ 8) | جمع شدہ ذیلی حالت (ٹرانزیکشن ختم ہونے پر طے شدہ تبدیلیاں) |
| o | 9.3 (صفحہ 13) | آؤٹ پٹ - اندرونی ٹرانزیکشن (جب ایک کنٹریکٹ دوسرے کو کال کرتا ہے) اور ویو فنکشنز کی کالز (جب آپ صرف معلومات مانگ رہے ہوتے ہیں، اس لیے ٹرانزیکشن کا انتظار کرنے کی ضرورت نہیں ہوتی) کے معاملے میں واپس کیا گیا نتیجہ |
9.4 عمل درآمد کا جائزہ
اب جب کہ ہمارے پاس تمام ابتدائی معلومات ہیں، ہم آخر کار اس پر کام شروع کر سکتے ہیں کہ EVM کیسے کام کرتا ہے۔
مساوات 137-142 ہمیں EVM چلانے کے لیے ابتدائی شرائط فراہم کرتی ہیں:
| علامت | ابتدائی قدر | معنی |
|---|---|---|
| μg | g | باقی ماندہ گیس |
| μpc | 0 | پروگرام کاؤنٹر، عمل درآمد کے لیے اگلی ہدایت کا پتہ |
| μm | (0, 0, ...) | میموری، تمام صفر پر شروع کی گئی |
| μi | 0 | استعمال شدہ سب سے اعلیٰ میموری کا مقام |
| μs | () | اسٹیک، ابتدائی طور پر خالی |
| μo | ∅ | آؤٹ پٹ، خالی سیٹ جب تک کہ ہم واپسی کے ڈیٹا کے ساتھ (RETURN (opens in a new tab) یا REVERT (opens in a new tab)) یا اس کے بغیر (STOP (opens in a new tab) یا SELFDESTRUCT (opens in a new tab)) نہ رکیں۔ |
مساوات 143 ہمیں بتاتی ہے کہ عمل درآمد کے دوران ہر وقت چار ممکنہ شرائط ہوتی ہیں، اور ان کے ساتھ کیا کرنا ہے:
Z(σ,μ,A,I)۔ Z ایک ایسے فنکشن کی نمائندگی کرتا ہے جو یہ جانچتا ہے کہ آیا کوئی آپریشن ایک غلط حالت کی منتقلی پیدا کرتا ہے (غیر معمولی رکاوٹ دیکھیں)۔ اگر یہ درست (True) ثابت ہوتا ہے، تو نئی حالت پرانی حالت جیسی ہی ہوتی ہے (سوائے اس کے کہ گیس جل جاتی ہے) کیونکہ تبدیلیاں نافذ نہیں کی گئی ہیں۔- اگر عمل درآمد کیا جانے والا آپ کوڈ
REVERT(opens in a new tab) ہے، تو نئی حالت پرانی حالت جیسی ہی ہوتی ہے، کچھ گیس ضائع ہو جاتی ہے۔ - اگر آپریشنز کی ترتیب ختم ہو گئی ہے، جیسا کہ
RETURN(opens in a new tab) سے ظاہر ہوتا ہے)، تو حالت کو نئی حالت میں اپ ڈیٹ کر دیا جاتا ہے۔ - اگر ہم اختتامی شرائط 1-3 میں سے کسی ایک پر نہیں ہیں، تو چلنا جاری رکھیں۔
9.4.1 مشین کی حالت
یہ سیکشن مشین کی حالت کو مزید تفصیل سے بیان کرتا ہے۔ یہ بتاتا ہے کہ w موجودہ آپ کوڈ ہے۔ اگر μpc کوڈ کی لمبائی ||Ib|| سے کم ہے، تو وہ بائٹ (Ib[μpc]) آپ کوڈ ہے۔ بصورت دیگر، آپ کوڈ کو STOP (opens in a new tab) کے طور پر بیان کیا جاتا ہے۔
چونکہ یہ ایک اسٹیک مشین (opens in a new tab) ہے، اس لیے ہمیں ہر آپ کوڈ کے ذریعے نکالے گئے (δ) اور ڈالے گئے (α) آئٹمز کی تعداد کا ٹریک رکھنے کی ضرورت ہے۔
9.4.2 غیر معمولی رکاوٹ
یہ سیکشن Z فنکشن کی تعریف کرتا ہے، جو یہ بتاتا ہے کہ کب ہمارے پاس غیر معمولی اختتام ہوتا ہے۔ یہ ایک بولین (opens in a new tab) فنکشن ہے، اس لیے یہ منطقی 'یا' (or) کے لیے ∨ (opens in a new tab) اور منطقی 'اور' (and) کے لیے ∧ (opens in a new tab) استعمال کرتا ہے۔
ہمارے پاس ایک غیر معمولی رکاوٹ ہوتی ہے اگر ان میں سے کوئی بھی شرط درست ہو:
-
μg < C(σ,μ,A,I) جیسا کہ ہم نے سیکشن 9.2 میں دیکھا، C وہ فنکشن ہے جو گیس کی لاگت بتاتا ہے۔ اگلے آپ کوڈ کو کور کرنے کے لیے کافی گیس نہیں بچی ہے۔
-
δw=∅ اگر کسی آپ کوڈ کے لیے نکالے گئے آئٹمز کی تعداد غیر متعین ہے، تو آپ کوڈ خود غیر متعین ہے۔
-
|| μs || < δw اسٹیک انڈر فلو، موجودہ آپ کوڈ کے لیے اسٹیک میں کافی آئٹمز نہیں ہیں۔
-
w = JUMP ∧ μs[0]∉D(Ib) آپ کوڈ
JUMP(opens in a new tab) ہے اور پتہJUMPDEST(opens in a new tab) نہیں ہے۔ جمپس صرف اس وقت درست ہوتے ہیں جب منزلJUMPDEST(opens in a new tab) ہو۔ -
w = JUMPI ∧ μs[1]≠0 ∧ μs[0] ∉ D(Ib) آپ کوڈ
JUMPI(opens in a new tab) ہے، شرط درست ہے (غیر صفر) اس لیے جمپ ہونا چاہیے، اور پتہJUMPDEST(opens in a new tab) نہیں ہے۔ جمپس صرف اس وقت درست ہوتے ہیں جب منزلJUMPDEST(opens in a new tab) ہو۔ -
w = RETURNDATACOPY ∧ μs[1]+μs[2]>|| μo || آپ کوڈ
RETURNDATACOPY(opens in a new tab) ہے۔ اس آپ کوڈ میں اسٹیک عنصر μs[1] ریٹرن ڈیٹا بفر میں پڑھنے کے لیے آفسیٹ ہے، اور اسٹیک عنصر μs[2] ڈیٹا کی لمبائی ہے۔ یہ شرط اس وقت پیش آتی ہے جب آپ ریٹرن ڈیٹا بفر کے اختتام سے آگے پڑھنے کی کوشش کرتے ہیں۔ نوٹ کریں کہ کال ڈیٹا یا خود کوڈ کے لیے ایسی کوئی شرط نہیں ہے۔ جب آپ ان بفرز کے اختتام سے آگے پڑھنے کی کوشش کرتے ہیں تو آپ کو صرف صفر ملتے ہیں۔ -
|| μs || - δw + αw > 1024
اسٹیک اوور فلو۔ اگر آپ کوڈ چلانے کے نتیجے میں اسٹیک میں 1024 سے زیادہ آئٹمز ہو جائیں گے، تو منسوخ کر دیں۔
-
¬Iw ∧ W(w,μ) کیا ہم جامد طور پر چل رہے ہیں (¬ نفی ہے (opens in a new tab) اور Iw اس وقت درست ہوتا ہے جب ہمیں بلاک چین کی حالت تبدیل کرنے کی اجازت ہوتی ہے)؟ اگر ایسا ہے، اور ہم حالت تبدیل کرنے والے آپریشن کی کوشش کر رہے ہیں، تو یہ نہیں ہو سکتا۔
فنکشن W(w,μ) کی تعریف بعد میں مساوات 150 میں کی گئی ہے۔ W(w,μ) درست ہے اگر ان میں سے کوئی ایک شرط درست ہو:
-
w ∈ {CREATE, CREATE2, SSTORE, SELFDESTRUCT} یہ آپ کوڈز حالت کو تبدیل کرتے ہیں، یا تو نیا کنٹریکٹ بنا کر، کوئی قدر محفوظ کر کے، یا موجودہ کنٹریکٹ کو خود تلفی کر کے۔
-
LOG0≤w ∧ w≤LOG4 اگر ہمیں جامد طور پر کال کیا جاتا ہے تو ہم لاگ اندراجات خارج نہیں کر سکتے۔ لاگ آپ کوڈز تمام
LOG0(A0) (opens in a new tab) اورLOG4(A4) (opens in a new tab) کے درمیان کی حد میں ہیں۔ لاگ آپ کوڈ کے بعد کا نمبر بتاتا ہے کہ لاگ اندراج میں کتنے موضوعات شامل ہیں۔ -
w=CALL ∧ μs[2]≠0 جب آپ جامد ہوں تو آپ کسی دوسرے کنٹریکٹ کو کال کر سکتے ہیں، لیکن اگر آپ ایسا کرتے ہیں تو آپ اسے ETH منتقل نہیں کر سکتے۔
-
-
w = SSTORE ∧ μg ≤ Gcallstipend آپ
SSTORE(opens in a new tab) نہیں چلا سکتے جب تک کہ آپ کے پاس Gcallstipend (ضمیمہ G میں 2300 کے طور پر بیان کیا گیا ہے) سے زیادہ گیس نہ ہو۔
9.4.3 جمپ کی منزل کا درست ہونا
یہاں ہم باضابطہ طور پر بیان کرتے ہیں کہ JUMPDEST (opens in a new tab) آپ کوڈز کیا ہیں۔ ہم صرف بائٹ ویلیو 0x5B کو نہیں دیکھ سکتے، کیونکہ یہ PUSH کے اندر ہو سکتا ہے (اور اس لیے ڈیٹا ہو سکتا ہے نہ کہ آپ کوڈ)۔
مساوات (153) میں ہم ایک فنکشن، N(i,w) کی تعریف کرتے ہیں۔ پہلا پیرامیٹر، i، آپ کوڈ کا مقام ہے۔ دوسرا، w، خود آپ کوڈ ہے۔ اگر w∈[PUSH1, PUSH32] ہے تو اس کا مطلب ہے کہ آپ کوڈ ایک PUSH ہے (مربع بریکٹ ایک ایسی حد کی وضاحت کرتے ہیں جس میں اختتامی مقامات شامل ہوتے ہیں)۔ اس صورت میں اگلا آپ کوڈ i+2+(w−PUSH1) پر ہے۔ PUSH1 (opens in a new tab) کے لیے ہمیں دو بائٹس (خود PUSH اور ایک بائٹ ویلیو) آگے بڑھنے کی ضرورت ہے، PUSH2 (opens in a new tab) کے لیے ہمیں تین بائٹس آگے بڑھنے کی ضرورت ہے کیونکہ یہ دو بائٹ ویلیو ہے، وغیرہ۔ دیگر تمام EVM آپ کوڈز صرف ایک بائٹ لمبے ہیں، اس لیے دیگر تمام صورتوں میں N(i,w)=i+1 ہے۔
یہ فنکشن مساوات (152) میں DJ(c,i) کی تعریف کرنے کے لیے استعمال ہوتا ہے، جو کوڈ c میں تمام درست جمپ منزلوں کا سیٹ (opens in a new tab) ہے، جو آپ کوڈ کے مقام i سے شروع ہوتا ہے۔ اس فنکشن کی تعریف تکراری طور پر کی گئی ہے۔ اگر i≥||c|| ہے، تو اس کا مطلب ہے کہ ہم کوڈ کے اختتام پر یا اس کے بعد ہیں۔ ہمیں مزید کوئی جمپ منزلیں نہیں ملنے والی ہیں، اس لیے بس خالی سیٹ واپس کر دیں۔
دیگر تمام صورتوں میں ہم اگلے آپ کوڈ پر جا کر اور اس سے شروع ہونے والا سیٹ حاصل کر کے باقی کوڈ کو دیکھتے ہیں۔ c[i] موجودہ آپ کوڈ ہے، اس لیے N(i,c[i]) اگلے آپ کوڈ کا مقام ہے۔ لہذا DJ(c,N(i,c[i])) درست جمپ منزلوں کا سیٹ ہے جو اگلے آپ کوڈ سے شروع ہوتا ہے۔ اگر موجودہ آپ کوڈ JUMPDEST نہیں ہے، تو بس وہ سیٹ واپس کر دیں۔ اگر یہ JUMPDEST ہے، تو اسے رزلٹ سیٹ میں شامل کریں اور اسے واپس کریں۔
9.4.4 عام رکاوٹ
رکاوٹ کا فنکشن H، تین قسم کی قدریں واپس کر سکتا ہے۔
- اگر ہم ہالٹ آپ کوڈ میں نہیں ہیں، تو ∅، خالی سیٹ واپس کریں۔ روایت کے مطابق، اس قدر کی تشریح بولین غلط (false) کے طور پر کی جاتی ہے۔
- اگر ہمارے پاس ایک ہالٹ آپ کوڈ ہے جو آؤٹ پٹ پیدا نہیں کرتا ہے (یا تو
STOP(opens in a new tab) یاSELFDESTRUCT(opens in a new tab))، تو واپسی کی قدر کے طور پر صفر بائٹس کے سائز کی ترتیب واپس کریں۔ نوٹ کریں کہ یہ خالی سیٹ سے بہت مختلف ہے۔ اس قدر کا مطلب ہے کہ EVM واقعی رک گیا تھا، بس پڑھنے کے لیے کوئی واپسی کا ڈیٹا نہیں ہے۔ - اگر ہمارے پاس ایک ہالٹ آپ کوڈ ہے جو آؤٹ پٹ پیدا کرتا ہے (یا تو
RETURN(opens in a new tab) یاREVERT(opens in a new tab))، تو اس آپ کوڈ کے ذریعے بتائی گئی بائٹس کی ترتیب واپس کریں۔ یہ ترتیب میموری سے لی گئی ہے، اسٹیک کے اوپری حصے کی قدر (μs[0]) پہلی بائٹ ہے، اور اس کے بعد کی قدر (μs[1]) لمبائی ہے۔
H.2 ہدایات کا سیٹ
EVM کے آخری ذیلی حصے، 9.5 پر جانے سے پہلے، آئیے خود ہدایات پر نظر ڈالتے ہیں۔ ان کی تعریف ضمیمہ H.2 میں کی گئی ہے جو صفحہ 29 سے شروع ہوتا ہے۔ کوئی بھی چیز جس کے بارے میں یہ نہیں بتایا گیا کہ وہ اس مخصوص آپ کوڈ کے ساتھ تبدیل ہو رہی ہے، اس کے ویسے ہی رہنے کی توقع ہے۔ جو متغیرات تبدیل ہوتے ہیں انہیں <something>′ کے طور پر بیان کیا جاتا ہے۔
مثال کے طور پر، آئیے ADD (opens in a new tab) آپ کوڈ کو دیکھتے ہیں۔
| قدر | یادداشت | δ | α | تفصیل |
|---|---|---|---|---|
| 0x01 | ADD | 2 | 1 | اضافے کا آپریشن۔ |
| μ′s[0] ≡ μs[0] + μs[1] |
δ ان قدروں کی تعداد ہے جو ہم اسٹیک سے نکالتے ہیں۔ اس صورت میں دو، کیونکہ ہم اوپر کی دو قدروں کو جوڑ رہے ہیں۔
α ان قدروں کی تعداد ہے جو ہم واپس ڈالتے ہیں۔ اس صورت میں ایک، مجموعہ۔
لہذا نیا اسٹیک ٹاپ (μ′s[0]) پرانے اسٹیک ٹاپ (μs[0]) اور اس کے نیچے پرانی قدر (μs[1]) کا مجموعہ ہے۔
ایک "آنکھیں چندھیا دینے والی فہرست" کے ساتھ تمام آپ کوڈز پر جانے کے بجائے، یہ مضمون صرف ان آپ کوڈز کی وضاحت کرتا ہے جو کچھ نیا متعارف کراتے ہیں۔
| قدر | یادداشت | δ | α | تفصیل |
|---|---|---|---|---|
| 0x20 | KECCAK256 | 2 | 1 | کیچاک-۲۵۶ ہیش کا حساب لگائیں۔ |
| μ′s[0] ≡ KEC(μm[μs[0] . . . (μs[0] + μs[1] − 1)]) | ||||
| μ′i ≡ M(μi,μs[0],μs[1]) |
یہ پہلا آپ کوڈ ہے جو میموری تک رسائی حاصل کرتا ہے (اس صورت میں، صرف پڑھنے کے لیے)۔ تاہم، یہ میموری کی موجودہ حدود سے آگے بڑھ سکتا ہے، اس لیے ہمیں μi کو اپ ڈیٹ کرنے کی ضرورت ہے۔ ہم یہ صفحہ 29 پر مساوات 328 میں بیان کردہ M فنکشن کا استعمال کرتے ہوئے کرتے ہیں۔
| قدر | یادداشت | δ | α | تفصیل |
|---|---|---|---|---|
| 0x31 | BALANCE | 1 | 1 | دیے گئے اکاؤنٹ کا بیلنس حاصل کریں۔ |
| ... |
وہ پتہ جس کا بیلنس ہمیں تلاش کرنے کی ضرورت ہے وہ μs[0] mod 2160 ہے۔ اسٹیک کا اوپری حصہ پتہ ہے، لیکن چونکہ پتے صرف 160 bits کے ہوتے ہیں، اس لیے ہم قدر ماڈیولو (opens in a new tab) 2160 کا حساب لگاتے ہیں۔
اگر σ[μs[0] mod 2160] ≠ ∅ ہے، تو اس کا مطلب ہے کہ اس پتے کے بارے میں معلومات موجود ہیں۔ اس صورت میں، σ[μs[0] mod 2160]b اس پتے کا بیلنس ہے۔ اگر σ[μs[0] mod 2160] = ∅ ہے، تو اس کا مطلب ہے کہ یہ پتہ غیر شروع شدہ ہے اور بیلنس صفر ہے۔ آپ صفحہ 4 پر سیکشن 4.1 میں اکاؤنٹ کی معلومات کے فیلڈز کی فہرست دیکھ سکتے ہیں۔
دوسری مساوات، A'a ≡ Aa ∪ {μs[0] mod 2160}، گرم اسٹوریج (وہ اسٹوریج جس تک حال ہی میں رسائی حاصل کی گئی ہے اور جس کے کیش ہونے کا امکان ہے) اور کولڈ اسٹوریج (وہ اسٹوریج جس تک رسائی حاصل نہیں کی گئی ہے اور جس کے سست اسٹوریج میں ہونے کا امکان ہے جسے بازیافت کرنا زیادہ مہنگا ہے) تک رسائی کے درمیان لاگت کے فرق سے متعلق ہے۔ Aa ان پتوں کی فہرست ہے جن تک ٹرانزیکشن کے ذریعے پہلے رسائی حاصل کی گئی تھی، اس لیے ان تک رسائی سستی ہونی چاہیے، جیسا کہ صفحہ 8 پر سیکشن 6.1 میں بیان کیا گیا ہے۔ آپ اس موضوع کے بارے میں EIP-2929 (opens in a new tab) میں مزید پڑھ سکتے ہیں۔
| قدر | یادداشت | δ | α | تفصیل |
|---|---|---|---|---|
| 0x8F | DUP16 | 16 | 17 | 16 ویں اسٹیک آئٹم کی نقل بنائیں۔ |
| μ′s[0] ≡ μs[15] |
نوٹ کریں کہ کسی بھی اسٹیک آئٹم کو استعمال کرنے کے لیے، ہمیں اسے نکالنے کی ضرورت ہے، جس کا مطلب ہے کہ ہمیں اس کے اوپر موجود تمام اسٹیک آئٹمز کو بھی نکالنے کی ضرورت ہے۔ DUP<n> (opens in a new tab) اور SWAP<n> (opens in a new tab) کے معاملے میں، اس کا مطلب ہے کہ سولہ قدروں تک کو نکالنا اور پھر ڈالنا پڑتا ہے۔
9.5 عمل درآمد کا چکر
اب جب کہ ہمارے پاس تمام حصے ہیں، ہم آخر کار سمجھ سکتے ہیں کہ EVM کے عمل درآمد کے چکر کو کیسے دستاویزی شکل دی گئی ہے۔
مساوات (155) کہتی ہے کہ دی گئی حالت میں:
- σ (عالمی بلاک چین کی حالت)
- μ (EVM کی حالت)
- A (ذیلی حالت، ٹرانزیکشن ختم ہونے پر ہونے والی تبدیلیاں)
- I (عمل درآمد کا ماحول)
نئی حالت (σ', μ', A', I') ہے۔
مساوات (156)-(158) اسٹیک اور آپ کوڈ (μs) کی وجہ سے اس میں ہونے والی تبدیلی کی وضاحت کرتی ہیں۔ مساوات (159) گیس میں تبدیلی (μg) ہے۔ مساوات (160) پروگرام کاؤنٹر میں تبدیلی (μpc) ہے۔ آخر میں، مساوات (161)-(164) بتاتی ہیں کہ دیگر پیرامیٹرز ویسے ہی رہتے ہیں، جب تک کہ آپ کوڈ کے ذریعے واضح طور پر تبدیل نہ کیے جائیں۔
اس کے ساتھ EVM کی مکمل تعریف ہو جاتی ہے۔
نتیجہ
ریاضیاتی اشارے قطعی ہیں اور انہوں نے یلو پیپر کو ایتھیریم کی ہر تفصیل بتانے کی اجازت دی ہے۔ تاہم، اس کی کچھ خامیاں ہیں:
- اسے صرف انسان ہی سمجھ سکتے ہیں، جس کا مطلب ہے کہ تعمیل کے ٹیسٹ (opens in a new tab) دستی طور پر لکھے جانے چاہئیں۔
- پروگرامرز کمپیوٹر کوڈ کو سمجھتے ہیں۔ وہ ریاضیاتی اشارے کو سمجھ بھی سکتے ہیں اور نہیں بھی۔
شاید انہی وجوہات کی بنا پر، نئی اتفاق رائے کی تہہ کی تفصیلات (opens in a new tab) Python میں لکھی گئی ہیں۔ Python میں عمل درآمد کی تہہ کی تفصیلات (opens in a new tab) موجود ہیں، لیکن وہ مکمل نہیں ہیں۔ جب تک کہ پورا یلو پیپر بھی Python یا اس جیسی کسی زبان میں ترجمہ نہیں ہو جاتا، یلو پیپر سروس میں رہے گا، اور اسے پڑھنے کے قابل ہونا مددگار ہے۔