diff --git a/public/content/translations/ur/developers/docs/transactions/index.md b/public/content/translations/ur/developers/docs/transactions/index.md new file mode 100644 index 00000000000..b1e028603be --- /dev/null +++ b/public/content/translations/ur/developers/docs/transactions/index.md @@ -0,0 +1,231 @@ +--- +title: "ٹرانزیکشنز" +description: "ایتھیریم ٹرانزیکشنز کا ایک جائزہ – وہ کیسے کام کرتے ہیں، ان کا ڈیٹا اسٹرکچر، اور انہیں کسی ایپلیکیشن کے ذریعے کیسے بھیجا جائے۔" +lang: ur-in +--- + +ٹرانزیکشنز اکاؤنٹس سے بھیجی گئی کرپٹوگرافک طور پر دستخط شدہ ہدایات ہیں۔ ایک اکاؤنٹ ایتھیریم نیٹ ورک کی حالت کو اپ ڈیٹ کرنے کے لیے ایک ٹرانزیکشن شروع کرے گا۔ سب سے آسان ٹرانزیکشن ایک اکاؤنٹ سے دوسرے اکاؤنٹ میں ETH منتقل کرنا ہے۔ + +## شرائط {#prerequisites} + +اس صفحہ کو بہتر طور پر سمجھنے میں آپ کی مدد کرنے کے لیے، ہم تجویز کرتے ہیں کہ آپ پہلے [اکاؤنٹس](/developers/docs/accounts/) اور ہمارا [ایتھیریم کا تعارف](/developers/docs/intro-to-ethereum/) پڑھیں۔ + +## ٹرانزیکشن کیا ہے؟ {#whats-a-transaction} + +ایتھیریم ٹرانزیکشن سے مراد ایک بیرونی ملکیت والے اکاؤنٹ کے ذریعے شروع کی گئی کارروائی ہے، دوسرے الفاظ میں ایک ایسا اکاؤنٹ جسے انسان کے ذریعے منظم کیا جاتا ہے، نہ کہ کسی کنٹریکٹ کے ذریعے۔ مثال کے طور پر، اگر باب ایلس کو 1 ETH بھیجتا ہے، تو باب کے اکاؤنٹ سے ڈیبٹ ہونا چاہیے اور ایلس کے اکاؤنٹ میں کریڈٹ ہونا چاہیے۔ یہ حالت بدلنے والی کارروائی ایک ٹرانزیکشن کے اندر ہوتی ہے۔ + +![ٹرانزیکشن کی وجہ سے حالت میں تبدیلی کو ظاہر کرنے والا ڈایاگرام](./tx.png) +_[ایتھیریم EVM کی تصویری وضاحت](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) سے لیا گیا ڈایاگرام_ + +ٹرانزیکشنز، جو EVM کی حالت کو تبدیل کرتی ہیں، کو پورے نیٹ ورک پر براڈکاسٹ کرنے کی ضرورت ہوتی ہے۔ کوئی بھی نوڈ EVM پر ٹرانزیکشن کو انجام دینے کی درخواست کو براڈکاسٹ کر سکتا ہے؛ اس کے بعد، ایک ویلیڈیٹر ٹرانزیکشن کو انجام دے گا اور نتیجے میں ہونے والی حالت کی تبدیلی کو باقی نیٹ ورک تک پھیلائے گا۔ + +ٹرانزیکشنز کے لیے فیس درکار ہوتی ہے اور انہیں ایک توثیق شدہ بلاک میں شامل کیا جانا چاہیے۔ اس جائزے کو آسان بنانے کے لیے ہم گیس فیس اور توثیق کو کہیں اور کور کریں گے۔ + +جمع کرائی گئی ٹرانزیکشن میں درج ذیل معلومات شامل ہوتی ہیں: + +- `from` – بھیجنے والے کا پتہ، جو ٹرانزیکشن پر دستخط کرے گا۔ یہ ایک بیرونی ملکیت والا اکاؤنٹ ہوگا کیونکہ کنٹریکٹ اکاؤنٹس ٹرانزیکشن نہیں بھیج سکتے۔ +- `to` – وصول کرنے والا پتہ (اگر ایک بیرونی ملکیت والا اکاؤنٹ ہے، تو ٹرانزیکشن قدر منتقل کرے گا۔ اگر ایک کنٹریکٹ اکاؤنٹ ہے، تو ٹرانزیکشن کنٹریکٹ کوڈ کو انجام دے گی) +- `signature` – بھیجنے والے کی شناخت کنندہ۔ یہ اس وقت پیدا ہوتا ہے جب بھیجنے والے کی نجی کلید ٹرانزیکشن پر دستخط کرتی ہے اور تصدیق کرتی ہے کہ بھیجنے والے نے اس ٹرانزیکشن کی اجازت دی ہے۔ +- `nonce` - ایک ترتیب سے بڑھنے والا کاؤنٹر جو اکاؤنٹ سے ٹرانزیکشن نمبر کی نشاندہی کرتا ہے۔ +- `value` – بھیجنے والے سے وصول کنندہ کو منتقل کی جانے والی ETH کی رقم (WEI میں ظاہر کی گئی، جہاں 1ETH برابر ہے 1e+18wei کے) +- `input data` – صوابدیدی ڈیٹا شامل کرنے کے لیے اختیاری فیلڈ۔ +- `gasLimit` – گیس یونٹس کی زیادہ سے زیادہ مقدار جو ٹرانزیکشن کے ذریعے استعمال کی جا سکتی ہے۔ [EVM](/developers/docs/evm/opcodes) ہر حسابی مرحلے کے لیے درکار گیس کی اکائیوں کی وضاحت کرتا ہے۔ +- `maxPriorityFeePerGas` - استعمال شدہ گیس کی زیادہ سے زیادہ قیمت جو ویلیڈیٹر کو ٹپ کے طور پر شامل کی جائے گی۔ +- `maxFeePerGas` - ٹرانزیکشن کے لیے ادا کی جانے والی فی یونٹ گیس کی زیادہ سے زیادہ فیس (`baseFeePerGas` اور `maxPriorityFeePerGas` سمیت)۔ + +گیس اس حساب کا حوالہ ہے جو ایک ویلیڈیٹر کے ذریعے ٹرانزیکشن پر کارروائی کرنے کے لیے درکار ہوتا ہے۔ صارفین کو اس حساب کے لیے فیس ادا کرنی ہوتی ہے۔ `gasLimit`، اور `maxPriorityFeePerGas` ویلیڈیٹر کو ادا کی جانے والی زیادہ سے زیادہ ٹرانزیکشن فیس کا تعین کرتے ہیں۔ [گیس پر مزید](/developers/docs/gas/). + +ٹرانزیکشن آبجیکٹ کچھ اس طرح نظر آئے گا: + +```js +{ + from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8", + to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a", + gasLimit: "21000", + maxFeePerGas: "300", + maxPriorityFeePerGas: "10", + nonce: "0", + value: "10000000000" +} +``` + +لیکن ایک ٹرانزیکشن آبجیکٹ کو بھیجنے والے کی نجی کلید کا استعمال کرتے ہوئے دستخط کرنے کی ضرورت ہوتی ہے۔ یہ ثابت کرتا ہے کہ ٹرانزیکشن صرف بھیجنے والے کی طرف سے آسکتی تھی اور دھوکہ دہی سے نہیں بھیجی گئی تھی۔ + +ایک ایتھیریم کلائنٹ جیسے Geth اس دستخطی عمل کو سنبھالے گا۔ + +مثال [JSON-RPC](/developers/docs/apis/json-rpc) کال: + +```json +{ + "id": 2, + "jsonrpc": "2.0", + "method": "account_signTransaction", + "params": [ + { + "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db", + "gas": "0x55555", + "maxFeePerGas": "0x1234", + "maxPriorityFeePerGas": "0x1234", + "input": "0xabcd", + "nonce": "0x0", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234" + } + ] +} +``` + +مثال کے طور پر جواب: + +```json +{ + "jsonrpc": "2.0", + "id": 2, + "result": { + "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "tx": { + "nonce": "0x0", + "maxFeePerGas": "0x1234", + "maxPriorityFeePerGas": "0x1234", + "gas": "0x55555", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234", + "input": "0xabcd", + "v": "0x26", + "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e", + "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e" + } + } +} +``` + +- `raw` دستخط شدہ ٹرانزیکشن ہے [ریکرسیو لینتھ پریفکس (RLP)](/developers/docs/data-structures-and-encoding/rlp) انکوڈ شدہ شکل میں۔ +- `tx` دستخط شدہ ٹرانزیکشن JSON شکل میں ہے۔ + +دستخطی ہیش کے ساتھ، ٹرانزیکشن کو کرپٹوگرافک طور پر ثابت کیا جا سکتا ہے کہ یہ بھیجنے والے کی طرف سے آئی ہے اور نیٹ ورک پر جمع کرائی گئی ہے۔ + +### ڈیٹا فیلڈ {#the-data-field} + +ٹرانزیکشنز کی بڑی اکثریت ایک بیرونی ملکیت والے اکاؤنٹ سے ایک کنٹریکٹ تک رسائی حاصل کرتی ہے۔ +زیادہ تر کنٹریکٹس Solidity میں لکھے جاتے ہیں اور اپنے ڈیٹا فیلڈ کی تشریح [ایپلیکیشن بائنری انٹرفیس (ABI)](/glossary/#abi) کے مطابق کرتے ہیں۔ + +پہلے چار بائٹس یہ بتاتے ہیں کہ کون سا فنکشن کال کرنا ہے، فنکشن کے نام اور دلائل کے ہیش کا استعمال کرتے ہوئے۔ +آپ کبھی کبھی [اس ڈیٹا بیس](https://www.4byte.directory/signatures/) کا استعمال کرتے ہوئے سلیکٹر سے فنکشن کی شناخت کر سکتے ہیں۔ + +باقی کال ڈیٹا دلائل ہیں، [ABI کی خصوصیات میں بیان کردہ کے مطابق انکوڈ شدہ](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding)۔ + +مثال کے طور پر، آئیے [اس ٹرانزیکشن](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1) کو دیکھتے ہیں۔ +کال ڈیٹا دیکھنے کے لیے **مزید دیکھنے کے لیے کلک کریں** استعمال کریں۔ + +فنکشن سلیکٹر `0xa9059cbb` ہے۔ اس دستخط کے ساتھ کئی [معروف فنکشنز](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb) ہیں۔ +اس صورت میں [کنٹریکٹ کا سورس کوڈ](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) Etherscan پر اپ لوڈ کیا گیا ہے، لہذا ہم جانتے ہیں کہ فنکشن `transfer(address,uint256)` ہے۔ + +باقی ڈیٹا یہ ہے: + +``` +0000000000000000000000004f6742badb049791cd9a37ea913f2bac38d01279 +000000000000000000000000000000000000000000000000000000003b0559f4 +``` + +ABI کی خصوصیات کے مطابق، انٹیجر ویلیوز (جیسے کہ ایڈریس، جو 20 بائٹ انٹیجرز ہیں) ABI میں 32 بائٹ کے الفاظ کے طور پر ظاہر ہوتے ہیں، جن کے سامنے صفر کے ساتھ پیڈنگ کی جاتی ہے۔ +لہذا ہم جانتے ہیں کہ `to` ایڈریس [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279) ہے۔ +`value` 0x3b0559f4 = 990206452 ہے۔ + +## ٹرانزیکشنز کی اقسام {#types-of-transactions} + +ایتھیریم پر چند مختلف قسم کی ٹرانزیکشنز ہوتی ہیں: + +- باقاعدہ ٹرانزیکشنز: ایک اکاؤنٹ سے دوسرے اکاؤنٹ میں ایک ٹرانزیکشن۔ +- کنٹریکٹ کی تعیناتی کی ٹرانزیکشنز: ایک 'to' ایڈریس کے بغیر ایک ٹرانزیکشن، جہاں ڈیٹا فیلڈ کنٹریکٹ کوڈ کے لیے استعمال ہوتا ہے۔ +- کنٹریکٹ کا نفاذ: ایک ٹرانزیکشن جو ایک تعینات شدہ اسمارٹ کنٹریکٹ کے ساتھ تعامل کرتی ہے۔ اس صورت میں، 'to' ایڈریس اسمارٹ کنٹریکٹ ایڈریس ہے۔ + +### گیس پر {#on-gas} + +جیسا کہ ذکر کیا گیا ہے، ٹرانزیکشنز کو انجام دینے کے لیے [گیس](/developers/docs/gas/) کی لاگت آتی ہے۔ سادہ منتقلی کی ٹرانزیکشنز کے لیے 21000 یونٹ گیس درکار ہوتی ہے۔ + +لہذا باب کو ایلس کو 190 gwei کے `baseFeePerGas` اور 10 gwei کے `maxPriorityFeePerGas` پر 1 ETH بھیجنے کے لیے، باب کو درج ذیل فیس ادا کرنی ہوگی: + +``` +(190 + 10) * 21000 = 4,200,000 gwei +--or-- +0.0042 ETH +``` + +باب کے اکاؤنٹ سے **-1.0042 ETH** ڈیبٹ کیا جائے گا (ایلس کے لیے 1 ETH + گیس فیس میں 0.0042 ETH) + +ایلس کے اکاؤنٹ میں **+1.0 ETH** کریڈٹ کیا جائے گا۔ + +بیس فیس **-0.00399 ETH** جلا دی جائے گی۔ + +ویلیڈیٹر ٹپ **+0.000210 ETH** رکھتا ہے۔ + +![ڈایاگرام جس میں دکھایا گیا ہے کہ غیر استعمال شدہ گیس کیسے واپس کی جاتی ہے](./gas-tx.png) +_[ایتھیریم EVM کی تصویری وضاحت](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) سے لیا گیا ڈایاگرام_ + +کسی ٹرانزیکشن میں استعمال نہ ہونے والی کوئی بھی گیس صارف کے اکاؤنٹ میں واپس کر دی جاتی ہے۔ + +### اسمارٹ کنٹریکٹ کے تعاملات {#smart-contract-interactions} + +کسی بھی ٹرانزیکشن کے لیے گیس درکار ہے جس میں اسمارٹ کنٹریکٹ شامل ہو۔ + +اسمارٹ کنٹریکٹس میں [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) یا [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions) فنکشنز کے نام سے جانے جانے والے فنکشنز بھی شامل ہو سکتے ہیں، جو کنٹریکٹ کی حالت کو تبدیل نہیں کرتے ہیں۔ اس طرح، EOA سے ان فنکشنز کو کال کرنے کے لیے کسی گیس کی ضرورت نہیں ہوگی۔ اس منظر نامے کے لیے بنیادی RPC کال [`eth_call`](/developers/docs/apis/json-rpc#eth_call) ہے۔ + +`eth_call` کا استعمال کرتے ہوئے رسائی حاصل کرنے کے برعکس، یہ `view` یا `pure` فنکشنز عام طور پر اندرونی طور پر بھی کال کیے جاتے ہیں (یعنی، خود کنٹریکٹ سے یا کسی دوسرے کنٹریکٹ سے) جس پر گیس کی لاگت آتی ہے۔ + +## ٹرانزیکشن لائف سائیکل {#transaction-lifecycle} + +ایک بار ٹرانزیکشن جمع ہو جانے کے بعد درج ذیل ہوتا ہے: + +1. ایک ٹرانزیکشن ہیش کرپٹوگرافک طور پر تیار کیا جاتا ہے: + `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017` +2. اس کے بعد ٹرانزیکشن کو نیٹ ورک پر براڈکاسٹ کیا جاتا ہے اور ایک ٹرانزیکشن پول میں شامل کیا جاتا ہے جس میں دیگر تمام زیر التواء نیٹ ورک ٹرانزیکشنز شامل ہوتے ہیں۔ +3. ایک ویلیڈیٹر کو آپ کی ٹرانزیکشن کو منتخب کرنا ہوگا اور اسے ٹرانزیکشن کی تصدیق کرنے اور اسے "کامیاب" سمجھنے کے لیے ایک بلاک میں شامل کرنا ہوگا۔ +4. جیسے جیسے وقت گزرتا ہے آپ کی ٹرانزیکشن پر مشتمل بلاک کو "جواز" پھر "حتمی" میں اپ گریڈ کر دیا جائے گا۔ یہ اپ گریڈ اس بات کو بہت زیادہ یقینی بناتے ہیں کہ آپ کی ٹرانزیکشن کامیاب تھی اور اسے کبھی تبدیل نہیں کیا جائے گا۔ ایک بار جب کوئی بلاک "حتمی" ہو جاتا ہے تو اسے صرف ایک نیٹ ورک سطح کے حملے سے ہی تبدیل کیا جا سکتا ہے جس پر کئی بلین ڈالر لاگت آئے گی۔ + +## ایک بصری ڈیمو {#a-visual-demo} + +آسٹن کو ٹرانزیکشنز، گیس، اور مائننگ کے بارے میں بتاتے ہوئے دیکھیں۔ + + + +## ٹائپ شدہ ٹرانزیکشن انویلپ {#typed-transaction-envelope} + +ایتھیریم میں اصل میں ٹرانزیکشنز کے لیے ایک ہی فارمیٹ تھا۔ ہر ٹرانزیکشن میں ایک نانس، گیس کی قیمت، گیس کی حد، ٹو ایڈریس، ویلیو، ڈیٹا، v، r، اور s شامل ہوتے تھے۔ یہ فیلڈز [RLP-انکوڈڈ](/developers/docs/data-structures-and-encoding/rlp/) ہیں، جو کچھ اس طرح نظر آتے ہیں: + +`RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])` + +ایتھیریم نے کئی قسم کی ٹرانزیکشنز کو سپورٹ کرنے کے لیے ترقی کی ہے تاکہ ایکسیس لسٹ اور [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) جیسی نئی خصوصیات کو پرانے ٹرانزیکشن فارمیٹس کو متاثر کیے بغیر نافذ کیا جا سکے۔ + +[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) وہی ہے جو اس طرز عمل کی اجازت دیتا ہے۔ ٹرانزیکشنز کی تشریح اس طرح کی جاتی ہے: + +`TransactionType || TransactionPayload` + +جہاں فیلڈز کی تعریف اس طرح کی گئی ہے: + +- `TransactionType` - 0 اور 0x7f کے درمیان ایک عدد، کل 128 ممکنہ ٹرانزیکشن اقسام کے لیے۔ +- `TransactionPayload` - ٹرانزیکشن کی قسم کے ذریعے بیان کردہ ایک صوابدیدی بائٹ ارے۔ + +`TransactionType` قدر کی بنیاد پر، ایک ٹرانزیکشن کو اس طرح درجہ بندی کیا جا سکتا ہے: + +1. **قسم 0 (لیگیسی) ٹرانزیکشنز:** ایتھیریم کے آغاز کے بعد سے استعمال ہونے والا اصل ٹرانزیکشن فارمیٹ۔ ان میں [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) کی خصوصیات شامل نہیں ہیں جیسے ڈائنامک گیس فیس کا حساب یا اسمارٹ کنٹریکٹس کے لیے ایکسیس لسٹ۔ لیگیسی ٹرانزیکشنز میں ان کی سیریلائزڈ شکل میں ان کی قسم کی نشاندہی کرنے والے ایک مخصوص پریفکس کی کمی ہوتی ہے، جو [ریکرسیو لینتھ پریفکس (RLP)](/developers/docs/data-structures-and-encoding/rlp) انکوڈنگ کا استعمال کرتے وقت بائٹ `0xf8` سے شروع ہوتی ہے۔ ان ٹرانزیکشنز کے لیے TransactionType کی قدر `0x0` ہے۔ + +2. **قسم 1 ٹرانزیکشنز:** ایتھیریم کے [برلن اپ گریڈ](/ethereum-forks/#berlin) کے حصے کے طور پر [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) میں متعارف کرائی گئیں، ان ٹرانزیکشنز میں ایک `accessList` پیرامیٹر شامل ہے۔ یہ فہرست ان پتوں اور اسٹوریج کیز کی وضاحت کرتی ہے جن تک ٹرانزیکشن رسائی کی توقع رکھتی ہے، جو اسمارٹ کنٹریکٹس پر مشتمل پیچیدہ ٹرانزیکشنز کے لیے ممکنہ طور پر [گیس](/developers/docs/gas/) کے اخراجات کو کم کرنے میں مدد کرتی ہے۔ EIP-1559 فیس مارکیٹ کی تبدیلیاں قسم 1 کی ٹرانزیکشنز میں شامل نہیں ہیں۔ قسم 1 کی ٹرانزیکشنز میں ایک `yParity` پیرامیٹر بھی شامل ہوتا ہے، جو یا تو `0x0` یا `0x1` ہو سکتا ہے، جو secp256k1 دستخط کی y-value کی پیریٹی کی نشاندہی کرتا ہے۔ ان کی شناخت بائٹ `0x01` سے شروع ہونے سے ہوتی ہے، اور ان کی TransactionType کی قدر `0x1` ہے۔ + +3. **قسم 2 ٹرانزیکشنز**، جنہیں عام طور پر EIP-1559 ٹرانزیکشنز کہا جاتا ہے، وہ ٹرانزیکشنز ہیں جو ایتھیریم کے [لندن اپ گریڈ](/ethereum-forks/#london) میں، [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) میں متعارف کرائی گئی ہیں۔ وہ ایتھیریم نیٹ ورک پر معیاری ٹرانزیکشن کی قسم بن گئے ہیں۔ یہ ٹرانزیکشنز ایک نیا فیس مارکیٹ میکانزم متعارف کراتے ہیں جو ٹرانزیکشن فیس کو ایک بیس فیس اور ایک ترجیحی فیس میں الگ کرکے پیشین گوئی کو بہتر بناتا ہے۔ وہ بائٹ `0x02` سے شروع ہوتے ہیں اور ان میں `maxPriorityFeePerGas` اور `maxFeePerGas` جیسے فیلڈز شامل ہوتے ہیں۔ قسم 2 کی ٹرانزیکشنز اب ان کی لچک اور کارکردگی کی وجہ سے ڈیفالٹ ہیں، خاص طور پر زیادہ نیٹ ورک کی بھیڑ کے دوران ان کی صارفین کو ٹرانزیکشن فیس کو زیادہ پیشین گوئی کے ساتھ منظم کرنے میں مدد کرنے کی صلاحیت کی وجہ سے پسند کی جاتی ہیں۔ ان ٹرانزیکشنز کے لیے TransactionType کی قدر `0x2` ہے۔ + +4. **قسم 3 (بلاب) ٹرانزیکشنز** ایتھیریم کے [Dencun اپ گریڈ](/ethereum-forks/#dencun) کے حصے کے طور پر [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) میں متعارف کرائی گئیں۔ یہ ٹرانزیکشنز "blob" ڈیٹا (بائنری لارج آبجیکٹس) کو زیادہ مؤثر طریقے سے ہینڈل کرنے کے لیے ڈیزائن کی گئی ہیں، خاص طور پر Layer 2 رول اپس کو کم قیمت پر ایتھیریم نیٹ ورک پر ڈیٹا پوسٹ کرنے کا ایک طریقہ فراہم کرکے فائدہ پہنچاتی ہیں۔ بلاب ٹرانزیکشنز میں اضافی فیلڈز جیسے `blobVersionedHashes`، `maxFeePerBlobGas`، اور `blobGasPrice` شامل ہیں۔ وہ بائٹ `0x03` سے شروع ہوتے ہیں، اور ان کی TransactionType کی قدر `0x3` ہے۔ بلاب ٹرانزیکشنز ایتھیریم کی ڈیٹا کی دستیابی اور اسکیلنگ کی صلاحیتوں میں ایک اہم بہتری کی نمائندگی کرتی ہیں۔ + +5. **قسم 4 ٹرانزیکشنز** ایتھیریم کے [Pectra اپ گریڈ](/roadmap/pectra/) کے حصے کے طور پر [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) میں متعارف کرائی گئیں۔ یہ ٹرانزیکشنز اکاؤنٹ ابسٹریکشن کے ساتھ فارورڈ-کمپیٹیبل ہونے کے لیے ڈیزائن کی گئی ہیں۔ وہ EOAs کو اپنی اصل فعالیت پر سمجھوتہ کیے بغیر عارضی طور پر اسمارٹ کنٹریکٹ اکاؤنٹس کی طرح برتاؤ کرنے کی اجازت دیتے ہیں۔ ان میں ایک `authorization_list` پیرامیٹر شامل ہوتا ہے، جو اس اسمارٹ کنٹریکٹ کی وضاحت کرتا ہے جس پر EOA اپنے اختیار کو تفویض کرتا ہے۔ ٹرانزیکشن کے بعد، EOA کے کوڈ فیلڈ میں تفویض کردہ اسمارٹ کنٹریکٹ کا پتہ ہوگا۔ + +## مزید پڑھیں {#further-reading} + +- [EIP-2718: ٹائپ شدہ ٹرانزیکشن انویلپ](https://eips.ethereum.org/EIPS/eip-2718) + +_کسی کمیونٹی وسیلے کے بارے میں جانتے ہیں جس نے آپ کی مدد کی ہو؟ اس صفحہ میں ترمیم کریں اور اسے شامل کریں!_ + +## متعلقہ موضوعات {#related-topics} + +- [اکاؤنٹس](/developers/docs/accounts/) +- [ایتھیریم ورچوئل مشین (EVM)](/developers/docs/evm/) +- [گیس](/developers/docs/gas/) diff --git a/public/content/translations/ur/developers/docs/web2-vs-web3/index.md b/public/content/translations/ur/developers/docs/web2-vs-web3/index.md new file mode 100644 index 00000000000..34be732efcf --- /dev/null +++ b/public/content/translations/ur/developers/docs/web2-vs-web3/index.md @@ -0,0 +1,62 @@ +--- +title: "ویب 2 بمقابلہ ویب 3" +description: "ایتھیریم بلاک چین ٹیکنالوجی پر مبنی مرکزی ویب 2 خدمات کا غیر مرکزی ویب 3 ایپلیکیشنز سے موازنہ کریں۔" +lang: ur-in +--- + +ویب 2 سے مراد انٹرنیٹ کا وہ ورژن ہے جسے آج ہم میں سے بیشتر جانتے ہیں۔ ایک ایسا انٹرنیٹ جس پر ایسی کمپنیوں کا غلبہ ہے جو آپ کے ذاتی ڈیٹا کے بدلے خدمات فراہم کرتی ہیں۔ ویب 3، ایتھیریم کے تناظر میں، ان غیر مرکزی ایپس سے مراد ہے جو بلاک چین پر چلتی ہیں۔ یہ وہ ایپس ہیں جو کسی کو بھی ان کے ذاتی ڈیٹا سے پیسہ کمائے بغیر حصہ لینے کی اجازت دیتی ہیں۔ + +کیا آپ مبتدیوں کے لیے زیادہ موزوں وسیلہ تلاش کر رہے ہیں؟ ہمارا [ویب 3 کا تعارف](/web3/) دیکھیں۔ + +## ویب 3 کے فوائد {#web3-benefits} + +بہت سے ویب 3 ڈیولپرز نے ایتھیریم کی موروثی غیر مرکزیت کی وجہ سے ڈی ایپس بنانے کا انتخاب کیا ہے: + +- نیٹ ورک پر موجود ہر شخص کو سروس استعمال کرنے کی اجازت ہے – یا دوسرے لفظوں میں، اجازت کی ضرورت نہیں ہے۔ +- کوئی بھی آپ کو بلاک نہیں کر سکتا یا سروس تک رسائی سے انکار نہیں کر سکتا۔ +- ادائیگیاں مقامی ٹوکن، ایتھر (ETH) کے ذریعے اس میں شامل ہیں۔ +- ایتھیریم ٹیورنگ-کمپلیٹ ہے، جس کا مطلب ہے کہ آپ تقریباً کچھ بھی پروگرام کر سکتے ہیں۔ + +## عملی موازنے {#practical-comparisons} + +| ویب 2 | Web3 | +| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | +| ٹویٹر کسی بھی اکاؤنٹ یا ٹویٹ کو سنسر کر سکتا ہے | ویب 3 ٹویٹس کو سنسر نہیں کیا جا سکے گا کیونکہ کنٹرول غیر مرکزی ہوتا ہے | +| ادائیگی کی سروس کچھ خاص قسم کے کاموں کے لیے ادائیگیوں کی اجازت نہ دینے کا فیصلہ کر سکتی ہے | ویب 3 ادائیگی ایپس کو کسی ذاتی ڈیٹا کی ضرورت نہیں ہوتی اور وہ ادائیگیوں کو نہیں روک سکتیں | +| گگ اکانومی ایپس کے سرورز ڈاؤن ہو سکتے ہیں اور کارکنوں کی آمدنی کو متاثر کر سکتے ہیں | ویب 3 سرورز ڈاؤن نہیں ہو سکتے – وہ اپنے بیک اینڈ کے طور پر ایتھیریم، جو ہزاروں کمپیوٹرز کا ایک غیر مرکزی نیٹ ورک ہے، کا استعمال کرتے ہیں | + +اس کا مطلب یہ نہیں ہے کہ تمام خدمات کو ڈی ایپ میں تبدیل کرنے کی ضرورت ہے۔ یہ مثالیں ویب 2 اور ویب 3 خدمات کے درمیان اہم فرق کو واضح کرتی ہیں۔ + +## ویب 3 کی حدود {#web3-limitations} + +ویب 3 کی ابھی کچھ حدود ہیں: + +- اسکیل ایبلیٹی – ویب 3 پر ٹرانزیکشنز سست ہیں کیونکہ وہ غیر مرکزی ہیں۔ حالت میں تبدیلیوں، جیسے کہ ادائیگی، کو ایک نوڈ کے ذریعے پراسیس کرنے اور پورے نیٹ ورک میں پھیلانے کی ضرورت ہوتی ہے۔ +- یو ایکس – ویب 3 ایپلیکیشنز کے ساتھ تعامل کرنے کے لیے اضافی اقدامات، سافٹ ویئر، اور تعلیم کی ضرورت ہو سکتی ہے۔ یہ اپنانے میں ایک رکاوٹ ہو سکتی ہے۔ +- رسائی – جدید ویب براؤزرز میں انضمام کی کمی ویب 3 کو زیادہ تر صارفین کے لیے کم قابل رسائی بناتی ہے۔ +- لاگت – زیادہ تر کامیاب ڈی ایپس اپنے کوڈ کے بہت چھوٹے حصے بلاک چین پر ڈالتی ہیں کیونکہ یہ مہنگا ہے۔ + +## مرکزیت بمقابلہ غیر مرکزیت {#centralization-vs-decentralization} + +نیچے دی گئی جدول میں، ہم مرکزی اور غیر مرکزی ڈیجیٹل نیٹ ورکس کے کچھ بڑے فوائد اور نقصانات کی فہرست دیتے ہیں۔ + +| مرکزی نظام | غیر مرکزی نظام | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| کم نیٹ ورک ڈایامیٹر (تمام شرکاء ایک مرکزی اتھارٹی سے جڑے ہوئے ہیں)؛ معلومات تیزی سے پھیلتی ہے، کیونکہ پھیلاؤ کو بہت سے کمپیوٹیشنل وسائل والی ایک مرکزی اتھارٹی سنبھالتی ہے۔ | نیٹ ورک پر سب سے دور کے شرکاء ممکنہ طور پر ایک دوسرے سے کئی ایجز دور ہو سکتے ہیں۔ نیٹ ورک کے ایک طرف سے نشر کی گئی معلومات کو دوسری طرف پہنچنے میں کافی وقت لگ سکتا ہے۔ | +| عام طور پر اعلیٰ کارکردگی (اعلیٰ تھروپٹ، کم کل کمپیوٹیشنل وسائل خرچ ہوتے ہیں) اور نافذ کرنا آسان۔ | عام طور پر کم کارکردگی (کم تھروپٹ، زیادہ کل کمپیوٹیشنل وسائل خرچ ہوتے ہیں) اور نافذ کرنا زیادہ پیچیدہ۔ | +| متضاد ڈیٹا کی صورت میں، حل واضح اور آسان ہے: سچائی کا حتمی ذریعہ مرکزی اتھارٹی ہے۔ | تنازعات کے حل کے لیے ایک پروٹوکول (اکثر پیچیدہ) کی ضرورت ہوتی ہے، اگر پیئرز اس ڈیٹا کی حالت کے بارے میں متضاد دعوے کرتے ہیں جس پر شرکاء کو ہم آہنگ ہونا ہوتا ہے۔ | +| ناکامی کا واحد نقطہ: بدنیتی پر مبنی اداکار مرکزی اتھارٹی کو نشانہ بنا کر نیٹ ورک کو ڈاؤن کر سکتے ہیں۔ | ناکامی کا کوئی واحد نقطہ نہیں: نیٹ ورک پھر بھی کام کر سکتا ہے چاہے شرکاء کے ایک بڑے حصے پر حملہ ہو/انہیں نکال دیا جائے۔ | +| نیٹ ورک کے شرکاء کے درمیان ہم آہنگی بہت آسان ہے، اور اسے ایک مرکزی اتھارٹی سنبھالتی ہے۔ مرکزی اتھارٹی نیٹ ورک کے شرکاء کو بہت کم رگڑ کے ساتھ اپ گریڈ، پروٹوکول اپ ڈیٹس وغیرہ کو اپنانے پر مجبور کر سکتی ہے۔ | ہم آہنگی اکثر مشکل ہوتی ہے، کیونکہ نیٹ ورک کی سطح کے فیصلوں، پروٹوکول اپ گریڈز وغیرہ میں کسی ایک ایجنٹ کا حتمی فیصلہ نہیں ہوتا۔ بدترین صورت میں، جب پروٹوکول کی تبدیلیوں پر اختلافات ہوں تو نیٹ ورک ٹوٹ پھوٹ کا شکار ہو سکتا ہے۔ | +| مرکزی اتھارٹی ڈیٹا کو سنسر کر سکتی ہے، ممکنہ طور پر نیٹ ورک کے کچھ حصوں کو باقی نیٹ ورک کے ساتھ تعامل کرنے سے روک سکتی ہے۔ | سنسرشپ بہت مشکل ہے، کیونکہ معلومات کے پاس پورے نیٹ ورک میں پھیلنے کے کئی طریقے ہوتے ہیں۔ | +| نیٹ ورک میں شرکت مرکزی اتھارٹی کے ذریعے کنٹرول کی جاتی ہے۔ | کوئی بھی نیٹ ورک میں حصہ لے سکتا ہے؛ کوئی "گیٹ کیپرز" نہیں ہیں۔ مثالی طور پر، شرکت کی لاگت بہت کم ہے۔ | + +نوٹ کریں کہ یہ عمومی نمونے ہیں جو ہر نیٹ ورک میں درست ثابت نہیں ہو سکتے۔ مزید برآں، حقیقت میں کسی نیٹ ورک کی مرکزیت/غیر مرکزیت کی ڈگری ایک اسپیکٹرم پر ہوتی ہے؛ کوئی بھی نیٹ ورک مکمل طور پر مرکزی یا مکمل طور پر غیر مرکزی نہیں ہوتا ہے۔ + +## مزید پڑھیں {#further-reading} + +- [ویب 3 کیا ہے؟](/web3/) - _ethereum.org_ +- [The Architecture of a Web 3.0 application](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) - _Preethi Kasireddy_ +- [غیر مرکزیت کا مطلب](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) _6 فروری، 2017 - وائٹلک بٹیرن_ +- [غیر مرکزیت کیوں اہمیت رکھتی ہے](https://onezero.medium.com/why-decentralization-matters-5e3f79f7638e) _18 فروری، 2018 - کرس ڈکسن_ +- [ویب 3.0 کیا ہے اور یہ کیوں اہمیت رکھتا ہے](https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b) _31 دسمبر، 2019 - میکس مرش اور رچرڈ موئرہیڈ_ +- [ہمیں ویب 3.0 کی ضرورت کیوں ہے](https://gavofyork.medium.com/why-we-need-web-3-0-5da4f2bf95ab) _12 ستمبر، 2018 - گیون ووڈ_ diff --git a/public/content/translations/ur/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/ur/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md new file mode 100644 index 00000000000..657e1a5fcb7 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -0,0 +1,300 @@ +--- +title: "ایک پائتھن ڈیولپر کے لیے ایتھیریم کا تعارف، حصہ 1" +description: "ایتھیریم ڈیولپمنٹ کا تعارف، خاص طور پر ان لوگوں کے لیے مفید ہے جنہیں پائتھن پروگرامنگ زبان کا علم ہے۔" +author: Marc Garreau +lang: ur-in +tags: [ "python", "web3.py" ] +skill: beginner +published: 2020-09-08 +source: Snake charmers +sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/ +--- + +تو، آپ نے اس ایتھیریم نامی چیز کے بارے میں سنا ہے اور کیا آپ اس کی گہرائی میں جانے کے لیے تیار ہیں؟ یہ پوسٹ جلد ہی کچھ بلاک چین کی بنیادی باتوں کا احاطہ کرے گی، پھر آپ کو ایک سیمولیٹیڈ ایتھیریم نوڈ کے ساتھ تعامل کرائے گی – بلاک ڈیٹا پڑھنا، اکاؤنٹ بیلنس چیک کرنا، اور ٹرانزیکشن بھیجنا۔ اس دوران، ہم ایپس بنانے کے روایتی طریقوں اور اس نئے ڈی سینٹرلائزڈ پیراڈائم کے درمیان فرق کو اجاگر کریں گے۔ + +## (غیر سخت) پیشگی شرائط {#soft-prerequisites} + +اس پوسٹ کا مقصد ڈیولپرز کی ایک وسیع رینج کے لیے قابل رسائی ہونا ہے۔ [پائتھن ٹولز](/developers/docs/programming-languages/python/) شامل ہوں گے، لیکن وہ صرف خیالات کے لیے ایک ذریعہ ہیں – اگر آپ پائتھن ڈیولپر نہیں ہیں تو کوئی مسئلہ نہیں۔ تاہم، میں اس بارے میں صرف چند مفروضے کروں گا کہ آپ پہلے سے کیا جانتے ہیں، تاکہ ہم جلد ہی ایتھیریم سے متعلق مخصوص چیزوں پر آگے بڑھ سکیں۔ + +مفروضے: + +- آپ ٹرمینل میں کام کر سکتے ہیں، +- آپ نے پائتھن کوڈ کی چند لائنیں لکھی ہیں، +- آپ کی مشین پر پائتھن ورژن 3.6 یا اس سے زیادہ انسٹال ہے ([ورچوئل اینوائرمنٹ](https://realpython.com/effective-python-environment/#virtual-environments) کے استعمال کی سختی سے حوصلہ افزائی کی جاتی ہے)، اور +- آپ نے `pip`، پائتھن کا پیکیج انسٹالر استعمال کیا ہے۔ + دوبارہ، اگر ان میں سے کوئی بھی بات غلط ہے، یا آپ اس مضمون میں کوڈ کو دوبارہ بنانے کا ارادہ نہیں رکھتے ہیں، تو بھی آپ غالباً ٹھیک سے عمل کر سکتے ہیں۔ + +## بلاک چینز، مختصراً {#blockchains-briefly} + +ایتھیریم کو بیان کرنے کے بہت سے طریقے ہیں، لیکن اس کے مرکز میں ایک بلاک چین ہے۔ بلاک چینز بلاکس کی ایک سیریز سے بنے ہیں، تو آئیے وہیں سے شروع کرتے ہیں۔ سادہ ترین الفاظ میں، ایتھیریم بلاک چین پر ہر بلاک صرف کچھ میٹا ڈیٹا اور ٹرانزیکشنز کی ایک فہرست ہے۔ JSON فارمیٹ میں، یہ کچھ اس طرح نظر آتا ہے: + +```json +{ + "number": 1234567, + "hash": "0xabc123...", + "parentHash": "0xdef456...", + ..., + "transactions": [...] +} +``` + +ہر [بلاک](/developers/docs/blocks/) میں اس سے پہلے آنے والے بلاک کا ایک حوالہ ہوتا ہے؛ `parentHash` صرف پچھلے بلاک کا ہیش ہے۔ + +نوٹ: ایتھیریم مقررہ سائز کی ویلیوز (“ہیشز”) تیار کرنے کے لیے باقاعدگی سے ہیش فنکشنز کا استعمال کرتا ہے۔ ہیشز ایتھیریم میں ایک اہم کردار ادا کرتے ہیں، لیکن آپ فی الحال انہیں محفوظ طریقے سے منفرد IDs کے طور پر سوچ سکتے ہیں۔ + +![ایک ڈایاگرام جو ہر بلاک کے اندر ڈیٹا سمیت ایک بلاک چین کو دکھاتا ہے](./blockchain-diagram.png) + +_ایک بلاک چین بنیادی طور پر ایک لنکڈ لسٹ ہے؛ ہر بلاک میں پچھلے بلاک کا ایک حوالہ ہوتا ہے۔_ + +یہ ڈیٹا اسٹرکچر کوئی نئی چیز نہیں ہے، لیکن وہ اصول (یعنی، پیئر-ٹو-پیئر پروٹوکولز) جو نیٹ ورک کو چلاتے ہیں، وہ نئے ہیں۔ کوئی مرکزی اتھارٹی نہیں ہے؛ پیئرز کے نیٹ ورک کو نیٹ ورک کو برقرار رکھنے کے لیے تعاون کرنا چاہیے، اور یہ فیصلہ کرنے کے لیے مقابلہ کرنا چاہیے کہ اگلے بلاک میں کون سے ٹرانزیکشن شامل کیے جائیں۔ لہذا، جب آپ کسی دوست کو کچھ رقم بھیجنا چاہتے ہیں، تو آپ کو اس ٹرانزیکشن کو نیٹ ورک پر براڈکاسٹ کرنے کی ضرورت ہوگی، پھر اس کے آنے والے بلاک میں شامل ہونے کا انتظار کرنا ہوگا۔ + +بلاک چین کے لیے یہ تصدیق کرنے کا واحد طریقہ کہ رقم واقعی ایک صارف سے دوسرے کو بھیجی گئی تھی، یہ ہے کہ اس بلاک چین کی مقامی کرنسی (یعنی، جو اس بلاک چین کے ذریعے بنائی اور چلائی جاتی ہے) کا استعمال کیا جائے۔ ایتھیریم میں، اس کرنسی کو ایتھر کہا جاتا ہے، اور ایتھیریم بلاک چین اکاؤنٹ بیلنس کا واحد سرکاری ریکارڈ رکھتا ہے۔ + +## ایک نیا پیراڈائم {#a-new-paradigm} + +اس نئے ڈی سینٹرلائزڈ ٹیک اسٹیک نے نئے ڈیولپر ٹولز کو جنم دیا ہے۔ ایسے ٹولز بہت سی پروگرامنگ زبانوں میں موجود ہیں، لیکن ہم اسے پائتھن کے نظریے سے دیکھیں گے۔ دوبارہ بتاتا چلوں: چاہے پائتھن آپ کی پسند کی زبان نہ بھی ہو، اس کے ساتھ چلنے میں زیادہ پریشانی نہیں ہونی چاہیے۔ + +پائتھن ڈیولپرز جو ایتھیریم کے ساتھ تعامل کرنا چاہتے ہیں وہ ممکنہ طور پر [Web3.py](https://web3py.readthedocs.io/) کا استعمال کریں گے۔ Web3.py ایک لائبریری ہے جو آپ کے ایتھیریم نوڈ سے جڑنے کے طریقے کو بہت آسان بناتی ہے، پھر اس سے ڈیٹا بھیجتی اور وصول کرتی ہے۔ + +نوٹ: “ایتھیریم نوڈ” اور “ایتھیریم کلائنٹ” ایک دوسرے کی جگہ پر استعمال ہوتے ہیں۔ دونوں صورتوں میں، یہ اس سافٹ ویئر سے مراد ہے جسے ایتھیریم نیٹ ورک میں ایک شریک چلاتا ہے۔ یہ سافٹ ویئر بلاک ڈیٹا پڑھ سکتا ہے، جب چین میں نئے بلاکس شامل کیے جاتے ہیں تو اپ ڈیٹس وصول کر سکتا ہے، نئے ٹرانزیکشنز کو براڈکاسٹ کر سکتا ہے، اور بہت کچھ۔ تکنیکی طور پر، کلائنٹ سافٹ ویئر ہے، نوڈ وہ کمپیوٹر ہے جو سافٹ ویئر چلا رہا ہے۔ + +[ایتھیریم کلائنٹس](/developers/docs/nodes-and-clients/) کو [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP، یا Websockets کے ذریعے قابل رسائی ہونے کے لیے کنفیگر کیا جا سکتا ہے، لہذا Web3.py کو اس کنفیگریشن کو مرر کرنے کی ضرورت ہوگی۔ Web3.py ان کنکشن آپشنز کو **پرووائیڈرز** کے طور پر حوالہ دیتا ہے۔ آپ کو Web3.py انسٹنس کو اپنے نوڈ کے ساتھ لنک کرنے کے لیے تین پرووائیڈرز میں سے ایک کا انتخاب کرنا ہوگا۔ + +![ایک ڈایاگرام جو دکھاتا ہے کہ web3.py آپ کی ایپلیکیشن کو ایک ایتھیریم نوڈ سے جوڑنے کے لیے IPC کا استعمال کیسے کرتا ہے](./web3py-and-nodes.png) + +_ایتھیریم نوڈ اور Web3.py کو ایک ہی پروٹوکول کے ذریعے کمیونیکیٹ کرنے کے لیے کنفیگر کریں، مثال کے طور پر، اس ڈایاگرام میں IPC۔_ + +ایک بار جب Web3.py صحیح طریقے سے کنفیگر ہو جاتا ہے، تو آپ بلاک چین کے ساتھ تعامل شروع کر سکتے ہیں۔ یہاں Web3.py کے استعمال کی چند مثالیں ہیں جو آنے والی چیزوں کے پیش منظر کے طور پر ہیں: + +```python +# بلاک ڈیٹا پڑھیں: +w3.eth.get_block('latest') + +# ایک ٹرانزیکشن بھیجیں: +w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) +``` + +## انسٹالیشن {#installation} + +اس واک تھرو میں، ہم صرف ایک پائتھن انٹرپریٹر کے اندر کام کریں گے۔ ہم کوئی ڈائریکٹریز، فائلیں، کلاسز یا فنکشنز نہیں بنائیں گے۔ + +نوٹ: نیچے دی گئی مثالوں میں، `$` سے شروع ہونے والی کمانڈز ٹرمینل میں چلانے کے لیے ہیں۔ ( `$` ٹائپ نہ کریں، یہ صرف لائن کے آغاز کی نشاندہی کرتا ہے۔) + +سب سے پہلے، [IPython](https://ipython.org/) کو ایک صارف دوست ماحول کے لیے انسٹال کریں جس میں کھوج کی جا سکے۔ IPython دیگر خصوصیات کے علاوہ ٹیب کی تکمیل کی پیشکش کرتا ہے، جس سے یہ دیکھنا بہت آسان ہو جاتا ہے کہ Web3.py کے اندر کیا ممکن ہے۔ + +```bash +pip install ipython +``` + +Web3.py `web3` نام کے تحت شائع ہوتا ہے۔ اسے اس طرح انسٹال کریں: + +```bash +pip install web3 +``` + +ایک اور بات – ہم بعد میں ایک بلاک چین کو سیمولیٹ کرنے جا رہے ہیں, جس کے لیے کچھ اور ڈیپینڈنسیز کی ضرورت ہے۔ آپ انہیں اس کے ذریعے انسٹال کر سکتے ہیں: + +```bash +pip install 'web3[tester]' +``` + +آپ جانے کے لیے پوری طرح تیار ہیں! + +نوٹ: `web3[tester]` پیکیج Python 3.10.xx تک کام کرتا ہے + +## ایک سینڈ باکس شروع کریں {#spin-up-a-sandbox} + +اپنے ٹرمینل میں `ipython` چلا کر ایک نیا پائتھن ماحول کھولیں۔ یہ `python` چلانے کے مترادف ہے، لیکن اس میں مزید خصوصیات ہیں۔ + +```bash +ipython +``` + +یہ آپ کے چل رہے پائتھن اور IPython کے ورژنز کے بارے میں کچھ معلومات پرنٹ کرے گا، پھر آپ کو ان پٹ کا انتظار کرتے ہوئے ایک پرامپٹ نظر آنا چاہیے: + +```python +In [1]: +``` + +اب آپ ایک انٹرایکٹو پائتھن شیل دیکھ رہے ہیں۔ بنیادی طور پر، یہ کھیلنے کے لیے ایک سینڈ باکس ہے۔ اگر آپ یہاں تک پہنچ گئے ہیں، تو Web3.py کو امپورٹ کرنے کا وقت آ گیا ہے: + +```python +In [1]: from web3 import Web3 +``` + +## Web3 ماڈیول کا تعارف {#introducing-the-web3-module} + +ایتھیریم کا گیٹ وے ہونے کے علاوہ، [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) ماڈیول کچھ سہولتی فنکشنز پیش کرتا ہے۔ آئیے چند کو کھوجتے ہیں۔ + +ایک ایتھیریم ایپلیکیشن میں، آپ کو عام طور پر کرنسی کی ڈینامینیشنز کو تبدیل کرنے کی ضرورت ہوگی۔ Web3 ماڈیول صرف اس کے لیے کچھ ہیلپر میتھڈز فراہم کرتا ہے: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) اور [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei)۔ + + +نوٹ: کمپیوٹرز اعشاریہ کی ریاضی کو سنبھالنے میں بدنام زمانہ خراب ہیں۔ اس سے بچنے کے لیے، ڈیولپرز اکثر ڈالر کی رقم کو سینٹ میں اسٹور کرتے ہیں۔ مثال کے طور پر، $5.99 کی قیمت والی کوئی چیز ڈیٹا بیس میں 599 کے طور پر اسٹور کی جا سکتی ہے۔ + +جب ایتھر میں ٹرانزیکشنز کو سنبھالتے ہیں تو اسی طرح کا ایک پیٹرن استعمال کیا جاتا ہے۔ تاہم، دو اعشاریہ پوائنٹس کے بجائے، ایتھر کے 18 ہوتے ہیں! ایتھر کی سب سے چھوٹی ڈینامینیشن کو wei کہا جاتا ہے، لہذا یہ وہ ویلیو ہے جو ٹرانزیکشن بھیجتے وقت بتائی جاتی ہے۔ + +1 ایتھر = 1000000000000000000 wei + +1 wei = 0.000000000000000001 ایتھر + + + +کچھ ویلیوز کو wei میں اور wei سے تبدیل کرنے کی کوشش کریں۔ نوٹ کریں کہ ایتھر اور wei کے درمیان [بہت سی ڈینامینیشنز کے نام ہیں](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations)۔ ان میں سے ایک بہتر جانا جاتا **gwei** ہے، کیونکہ اکثر ٹرانزیکشن فیس اسی طرح ظاہر کی جاتی ہے۔ + +```python +In [2]: Web3.to_wei(1, 'ether') +Out[2]: 1000000000000000000 + +In [3]: Web3.from_wei(500000000, 'gwei') +Out[3]: Decimal('0.5') +``` + +Web3 ماڈیول پر دیگر یوٹیلیٹی میتھڈز میں ڈیٹا فارمیٹ کنورٹرز (مثلاً، [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex))، ایڈریس ہیلپرز (مثلاً، [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress))، اور ہیش فنکشنز (مثلاً، [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)) شامل ہیں۔ ان میں سے بہت سے سیریز میں بعد میں کور کیے جائیں گے۔ تمام دستیاب میتھڈز اور پراپرٹیز کو دیکھنے کے لیے، `Web3` ٹائپ کرکے IPython کی آٹو-کمپلیٹ کا استعمال کریں۔ اور پیریڈ کے بعد دو بار ٹیب کی کو دبائیں۔ + +## چین سے بات کریں {#talk-to-the-chain} + +سہولتی میتھڈز بہت اچھے ہیں، لیکن آئیے بلاک چین کی طرف بڑھتے ہیں۔ اگلا قدم Web3.py کو ایک ایتھیریم نوڈ کے ساتھ کمیونیکیٹ کرنے کے لیے کنفیگر کرنا ہے۔ یہاں ہمارے پاس IPC, HTTP، یا Websocket پرووائیڈرز استعمال کرنے کا آپشن ہے۔ + +ہم اس راستے پر نہیں جائیں گے، لیکن HTTP پرووائیڈر کا استعمال کرتے ہوئے ایک مکمل ورک فلو کی مثال کچھ اس طرح نظر آسکتی ہے: + +- ایک ایتھیریم نوڈ ڈاؤن لوڈ کریں، جیسے، [Geth](https://geth.ethereum.org/)۔ +- ایک ٹرمینل ونڈو میں Geth شروع کریں اور اس کے نیٹ ورک کو سنک کرنے کا انتظار کریں۔ ڈیفالٹ HTTP پورٹ `8545` ہے، لیکن اسے کنفیگر کیا جا سکتا ہے۔ +- Web3.py کو بتائیں کہ نوڈ سے HTTP کے ذریعے `localhost:8545` پر جڑیں۔ + `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` +- نوڈ کے ساتھ تعامل کے لیے `w3` انسٹنس کا استعمال کریں۔ + +جبکہ یہ اسے کرنے کا ایک "حقیقی" طریقہ ہے، سنکنگ کے عمل میں گھنٹوں لگتے ہیں اور اگر آپ صرف ایک ڈیولپمنٹ ماحول چاہتے ہیں تو یہ غیر ضروری ہے۔ Web3.py اس مقصد کے لیے ایک چوتھا پرووائیڈر فراہم کرتا ہے، **EthereumTesterProvider**۔ یہ ٹیسٹر پرووائیڈر ایک سیمولیٹیڈ ایتھیریم نوڈ سے جڑتا ہے جس میں نرم اجازتیں اور کھیلنے کے لیے جعلی کرنسی ہوتی ہے۔ + +![ایک ڈایاگرام جو دکھاتا ہے کہ EthereumTesterProvider آپ کی web3.py ایپلیکیشن کو ایک سیمولیٹیڈ ایتھیریم نوڈ سے جوڑتا ہے](./ethereumtesterprovider.png) + +_EthereumTesterProvider ایک سیمولیٹیڈ نوڈ سے جڑتا ہے اور فوری ڈیولپمنٹ ماحول کے لیے کارآمد ہے۔_ + +اس سیمولیٹیڈ نوڈ کو [eth-tester](https://github.com/ethereum/eth-tester) کہا جاتا ہے اور ہم نے اسے `pip install web3[tester]` کمانڈ کے حصے کے طور پر انسٹال کیا تھا۔ اس ٹیسٹر پرووائیڈر کو استعمال کرنے کے لیے Web3.py کو کنفیگر کرنا اتنا ہی آسان ہے جتنا کہ: + +```python +In [4]: w3 = Web3(Web3.EthereumTesterProvider()) +``` + +اب آپ چین پر سرفنگ کے لیے تیار ہیں! یہ وہ بات نہیں ہے جو لوگ کہتے ہیں۔ یہ میں نے ابھی بنایا ہے۔ آئیے ایک مختصر دورہ کرتے ہیں۔ + +## مختصر دورہ {#the-quick-tour} + +سب سے پہلے، ایک سینیٹی چیک: + +```python +In [5]: w3.is_connected() +Out[5]: True +``` + +چونکہ ہم ٹیسٹر پرووائیڈر کا استعمال کر رہے ہیں، یہ ایک بہت قیمتی ٹیسٹ نہیں ہے، لیکن اگر یہ ناکام ہو جاتا ہے، تو امکان ہے کہ آپ نے `w3` متغیر کو انسٹینشیئیٹ کرتے وقت کچھ غلط ٹائپ کیا ہو۔ دوبارہ چیک کریں کہ آپ نے اندرونی قوسین شامل کیے ہیں، یعنی `Web3.EthereumTesterProvider()`۔ + +## ٹور اسٹاپ #1: [اکاؤنٹس](/developers/docs/accounts/) {#tour-stop-1-accounts} + +سہولت کے طور پر، ٹیسٹر پرووائیڈر نے کچھ اکاؤنٹس بنائے اور انہیں ٹیسٹ ایتھر سے پہلے سے لوڈ کر دیا۔ + +سب سے پہلے، آئیے ان اکاؤنٹس کی ایک فہرست دیکھتے ہیں: + +```python +In [6]: w3.eth.accounts +Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF', + '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] +``` + +اگر آپ یہ کمانڈ چلاتے ہیں، تو آپ کو دس سٹرنگز کی ایک فہرست نظر آنی چاہیے جو `0x` سے شروع ہوتی ہیں۔ ہر ایک ایک **پبلک ایڈریس** ہے اور، کچھ طریقوں سے، چیکنگ اکاؤنٹ پر اکاؤنٹ نمبر کے مترادف ہے۔ آپ یہ ایڈریس کسی ایسے شخص کو فراہم کریں گے جو آپ کو ایتھر بھیجنا چاہتا ہے۔ + +جیسا کہ ذکر کیا گیا ہے، ٹیسٹر پرووائیڈر نے ان میں سے ہر ایک اکاؤنٹ کو کچھ ٹیسٹ ایتھر سے پہلے سے لوڈ کیا ہے۔ آئیے معلوم کرتے ہیں کہ پہلے اکاؤنٹ میں کتنی رقم ہے: + +```python +In [7]: w3.eth.get_balance(w3.eth.accounts[0]) +Out[7]: 1000000000000000000000000 +``` + +یہ بہت سارے صفر ہیں! اس سے پہلے کہ آپ جعلی بینک تک ہنستے ہوئے جائیں، کرنسی کی ڈینامینیشنز کے بارے میں پہلے والا سبق یاد کریں۔ ایتھر کی ویلیوز سب سے چھوٹی ڈینامینیشن، wei میں ظاہر کی جاتی ہیں۔ اسے ایتھر میں تبدیل کریں: + +```python +In [8]: w3.from_wei(1000000000000000000000000, 'ether') +Out[8]: Decimal('1000000') +``` + +ایک ملین ٹیسٹ ایتھر - اب بھی بہت اچھا ہے۔ + +## ٹور اسٹاپ #2: بلاک ڈیٹا {#tour-stop-2-block-data} + +آئیے اس سیمولیٹیڈ بلاک چین کی حالت پر ایک نظر ڈالتے ہیں: + +```python +In [9]: w3.eth.get_block('latest') +Out[9]: AttributeDict({ + 'number': 0, + 'hash': HexBytes('0x9469878...'), + 'parentHash': HexBytes('0x0000000...'), + ... + 'transactions': [] +}) +``` + +ایک بلاک کے بارے میں بہت سی معلومات واپس آتی ہیں، لیکن یہاں صرف چند چیزوں کی نشاندہی کرنی ہے: + +- بلاک نمبر صفر ہے - چاہے آپ نے کتنی ہی دیر پہلے ٹیسٹر پرووائیڈر کو کنفیگر کیا ہو۔ حقیقی ایتھیریم نیٹ ورک کے برعکس، جو ہر 12 سیکنڈ میں ایک نیا بلاک شامل کرتا ہے، یہ سیمولیشن اس وقت تک انتظار کرے گا جب تک آپ اسے کرنے کے لیے کچھ کام نہ دیں۔ +- `transactions` ایک خالی فہرست ہے، اسی وجہ سے: ہم نے ابھی تک کچھ نہیں کیا ہے۔ یہ پہلا بلاک ایک **خالی بلاک** ہے، صرف چین کو شروع کرنے کے لیے۔ +- نوٹ کریں کہ `parentHash` صرف خالی بائٹس کا ایک گچھا ہے۔ یہ اس بات کی نشاندہی کرتا ہے کہ یہ چین میں پہلا بلاک ہے، جسے **جینیسس بلاک** بھی کہا جاتا ہے۔ + +## ٹور اسٹاپ #3: [ٹرانزیکشنز](/developers/docs/transactions/) {#tour-stop-3-transactions} + +ہم بلاک صفر پر پھنسے ہوئے ہیں جب تک کہ کوئی پینڈنگ ٹرانزیکشن نہ ہو، تو آئیے اسے ایک دیتے ہیں۔ ایک اکاؤنٹ سے دوسرے اکاؤنٹ میں چند ٹیسٹ ایتھر بھیجیں: + +```python +In [10]: tx_hash = w3.eth.send_transaction({ + 'from': w3.eth.accounts[0], + 'to': w3.eth.accounts[1], + 'value': w3.to_wei(3, 'ether'), + 'gas': 21000 +}) +``` + +یہ عام طور پر وہ نقطہ ہے جہاں آپ اپنے ٹرانزیکشن کو ایک نئے بلاک میں شامل ہونے کے لیے کئی سیکنڈ انتظار کریں گے۔ پورا عمل کچھ اس طرح ہوتا ہے: + +1. ایک ٹرانزیکشن جمع کریں اور ٹرانزیکشن ہیش کو پکڑے رہیں۔ جب تک ٹرانزیکشن پر مشتمل بلاک بن کر براڈکاسٹ نہیں ہو جاتا، ٹرانزیکشن “پینڈنگ” رہتا ہے۔ + `tx_hash = w3.eth.send_transaction({ … })` +2. ٹرانزیکشن کو ایک بلاک میں شامل ہونے کا انتظار کریں: + `w3.eth.wait_for_transaction_receipt(tx_hash)` +3. ایپلیکیشن لاجک جاری رکھیں۔ کامیاب ٹرانزیکشن کو دیکھنے کے لیے: + `w3.eth.get_transaction(tx_hash)` + +ہمارا سیمولیٹیڈ ماحول فوری طور پر ایک نئے بلاک میں ٹرانزیکشن شامل کر دے گا، لہذا ہم فوری طور پر ٹرانزیکشن دیکھ سکتے ہیں: + +```python +In [11]: w3.eth.get_transaction(tx_hash) +Out[11]: AttributeDict({ + 'hash': HexBytes('0x15e9fb95dc39...'), + 'blockNumber': 1, + 'transactionIndex': 0, + 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF', + 'value': 3000000000000000000, + ... +}) +``` + +آپ کو یہاں کچھ جانی پہچانی تفصیلات نظر آئیں گی: `from`، `to`، اور `value` فیلڈز ہمارے `send_transaction` کال کے ان پٹس سے مماثل ہونے چاہئیں۔ دوسری تسلی بخش بات یہ ہے کہ یہ ٹرانزیکشن بلاک نمبر 1 کے اندر پہلے ٹرانزیکشن (`'transactionIndex': 0`) کے طور پر شامل کیا گیا تھا۔ + +ہم اس ٹرانزیکشن کی کامیابی کی تصدیق دونوں ملوث اکاؤنٹس کے بیلنس چیک کر کے بھی آسانی سے کر سکتے ہیں۔ تین ایتھر کو ایک سے دوسرے میں منتقل ہونا چاہیے تھا۔ + +```python +In [12]: w3.eth.get_balance(w3.eth.accounts[0]) +Out[12]: 999996999979000000000000 + +In [13]: w3.eth.get_balance(w3.eth.accounts[1]) +Out[13]: 1000003000000000000000000 +``` + +بعد والا اچھا لگ رہا ہے! بیلنس 1,000,000 سے 1,000,003 ایتھر ہو گیا۔ لیکن پہلے اکاؤنٹ کا کیا ہوا؟ ایسا لگتا ہے کہ اس نے تین ایتھر سے تھوڑا زیادہ کھو دیا ہے۔ افسوس، زندگی میں کچھ بھی مفت نہیں ہے، اور ایتھیریم پبلک نیٹ ورک کا استعمال کرنے کے لیے آپ کو اپنے پیئرز کو ان کے معاون کردار کے لیے معاوضہ دینا ہوگا۔ ٹرانزیکشن جمع کرانے والے اکاؤنٹ سے ایک چھوٹی ٹرانزیکشن فیس کاٹی گئی - یہ فیس جلائی گئی گیس کی مقدار ہے (ETH ٹرانسفر کے لیے 21000 یونٹ گیس) جسے نیٹ ورک کی سرگرمی کے مطابق بدلنے والی ایک بیس فیس سے ضرب دیا جاتا ہے اور اس کے ساتھ ایک ٹپ شامل ہوتی ہے جو اس ویلیڈیٹر کو جاتی ہے جو ٹرانزیکشن کو ایک بلاک میں شامل کرتا ہے۔ + +[گیس](/developers/docs/gas/#post-london) پر مزید + +نوٹ: پبلک نیٹ ورک پر، ٹرانزیکشن فیس نیٹ ورک کی ڈیمانڈ اور آپ کتنی جلدی ایک ٹرانزیکشن پروسیس کرنا چاہتے ہیں، کی بنیاد پر متغیر ہوتی ہے۔ اگر آپ فیس کا حساب لگانے کے طریقے کی تفصیل میں دلچسپی رکھتے ہیں، تو میری پچھلی پوسٹ دیکھیں جس کا عنوان ہے بلاک میں ٹرانزیکشنز کیسے شامل کی جاتی ہیں۔ + +## اور سانس لیں {#and-breathe} + +ہم اس پر تھوڑی دیر سے کام کر رہے ہیں، لہذا یہ وقفہ لینے کے لیے کسی بھی جگہ کی طرح اچھی جگہ لگتی ہے۔ گہرائی کا سلسلہ جاری ہے، اور ہم اس سیریز کے دوسرے حصے میں کھوج جاری رکھیں گے۔ آنے والے کچھ تصورات: ایک حقیقی نوڈ سے جڑنا، اسمارٹ کانٹریکٹس، اور ٹوکنز۔ کیا آپ کے پاس مزید سوالات ہیں؟ مجھے بتائیں! آپ کی رائے اس بات پر اثر انداز ہوگی کہ ہم یہاں سے کہاں جاتے ہیں۔ درخواستیں [Twitter](https://twitter.com/wolovim) کے ذریعے خوش آمدید ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/ur/developers/tutorials/all-you-can-cache/index.md new file mode 100644 index 00000000000..1ea50457b41 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/all-you-can-cache/index.md @@ -0,0 +1,867 @@ +--- +title: "وہ سب کچھ جو آپ کیش کر سکتے ہیں" +description: "سستے رول اپ ٹرانزیکشنز کے لیے کیشنگ کنٹریکٹ بنانے اور استعمال کرنے کا طریقہ سیکھیں" +author: Ori Pomerantz +tags: [ "لیئر 2", "کیشنگ", "اسٹوریج" ] +skill: intermediate +published: 2022-09-15 +lang: ur-in +--- + +رول اپس کا استعمال کرتے وقت ٹرانزیکشن میں ایک بائٹ کی قیمت اسٹوریج سلاٹ کی قیمت سے کہیں زیادہ مہنگی ہوتی ہے۔ لہذا، زیادہ سے زیادہ معلومات کو آن چین کیش کرنا سمجھ میں آتا ہے۔ + +اس مضمون میں آپ یہ سیکھیں گے کہ کیشنگ کنٹریکٹ کو اس طرح کیسے بنایا اور استعمال کیا جائے کہ کوئی بھی پیرامیٹر ویلیو جس کے متعدد بار استعمال ہونے کا امکان ہو، کیش ہو جائے اور بہت کم تعداد میں بائٹس کے ساتھ (پہلی بار کے بعد) استعمال کے لیے دستیاب ہو، اور اس کیش کو استعمال کرنے والا آف چین کوڈ کیسے لکھا جائے۔ + +اگر آپ مضمون کو چھوڑنا چاہتے ہیں اور صرف سورس کوڈ دیکھنا چاہتے ہیں، تو [یہ یہاں ہے](https://github.com/qbzzt/20220915-all-you-can-cache)۔ ڈیولپمنٹ اسٹیک [Foundry](https://getfoundry.sh/introduction/installation/) ہے۔ + +## مجموعی ڈیزائن {#overall-design} + +سادگی کی خاطر ہم یہ فرض کریں گے کہ تمام ٹرانزیکشن پیرامیٹرز `uint256` ہیں، 32 بائٹس لمبے ہیں۔ جب ہمیں کوئی ٹرانزیکشن موصول ہوگا، تو ہم ہر پیرامیٹر کو اس طرح پارس کریں گے: + +1. اگر پہلا بائٹ `0xFF` ہے، تو اگلے 32 بائٹس کو پیرامیٹر ویلیو کے طور پر لیں اور اسے کیش میں لکھیں۔ + +2. اگر پہلا بائٹ `0xFE` ہے، تو اگلے 32 بائٹس کو پیرامیٹر ویلیو کے طور پر لیں لیکن اسے کیش میں _نہ_ لکھیں۔ + +3. کسی بھی دوسری ویلیو کے لیے، اوپر کے چار بٹس کو اضافی بائٹس کی تعداد کے طور پر لیں، اور نیچے کے چار بٹس کو کیش کی (key) کے سب سے اہم بٹس کے طور پر لیں۔ یہاں کچھ مثالیں ہیں: + + | کال ڈیٹا میں بائٹس | کیش کی (key) | + | :----------------- | ------------------------------: | + | 0x0F | 0x0F | + | 0x10,0x10 | 0x10 | + | 0x12,0xAC | 0x02AC | + | 0x2D,0xEA, 0xD6 | 0x0DEAD6 | + +## کیش مینیپولیشن {#cache-manipulation} + +کیش [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol) میں نافذ کیا گیا ہے۔ آئیے اس کا لائن بہ لائن جائزہ لیں۔ + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + + +contract Cache { + + bytes1 public constant INTO_CACHE = 0xFF; + bytes1 public constant DONT_CACHE = 0xFE; +``` + +یہ کونسٹنٹس ان خاص معاملات کی تشریح کے لیے استعمال ہوتے ہیں جہاں ہم تمام معلومات فراہم کرتے ہیں اور یا تو چاہتے ہیں کہ اسے کیش میں لکھا جائے یا نہیں۔ کیش میں لکھنے کے لیے پہلے سے غیر استعمال شدہ اسٹوریج سلاٹس میں دو [`SSTORE`](https://www.evm.codes/#55) آپریشنز کی ضرورت ہوتی ہے، جن میں سے ہر ایک پر 22100 گیس لاگت آتی ہے، اس لیے ہم اسے اختیاری بناتے ہیں۔ + +```solidity + + mapping(uint => uint) public val2key; +``` + +ویلیوز اور ان کی کیز (keys) کے درمیان ایک [میپنگ](https://www.geeksforgeeks.org/solidity/solidity-mappings/)۔ ٹرانزیکشن بھیجنے سے پہلے ویلیوز کو انکوڈ کرنے کے لیے یہ معلومات ضروری ہے۔ + +```solidity + // لوکیشن n میں کی (key) n+1 کے لیے ویلیو ہے، کیونکہ ہمیں صفر کو "کیش میں نہیں" کے طور پر محفوظ کرنے کی ضرورت ہے۔ + // + uint[] public key2val; +``` + +ہم کیز (keys) سے ویلیوز تک میپنگ کے لیے ایک ارے (array) کا استعمال کر سکتے ہیں کیونکہ ہم کیز (keys) تفویض کرتے ہیں، اور سادگی کے لیے ہم اسے ترتیب وار کرتے ہیں۔ + +```solidity + function cacheRead(uint _key) public view returns (uint) { + require(_key <= key2val.length, "غیر شروع شدہ کیش انٹری کو پڑھنا"); + return key2val[_key-1]; + } // cacheRead +``` + +کیش سے ایک ویلیو پڑھیں۔ + +```solidity + // اگر ویلیو پہلے سے موجود نہیں ہے تو اسے کیش میں لکھیں + // ٹیسٹ کو کام کرنے کے قابل بنانے کے لیے صرف پبلک + function cacheWrite(uint _value) public returns (uint) { + // اگر ویلیو پہلے سے ہی کیش میں ہے، تو موجودہ کی (key) واپس کریں + if (val2key[_value] != 0) { + return val2key[_value]; + } +``` + +ایک ہی ویلیو کو ایک سے زیادہ بار کیش میں ڈالنے کا کوئی فائدہ نہیں ہے۔ اگر ویلیو پہلے سے موجود ہے، تو صرف موجودہ کی (key) واپس کریں۔ + +```solidity + // چونکہ 0xFE ایک خاص کیس ہے، اس لیے سب سے بڑی کی (key) جو کیش + // رکھ سکتا ہے وہ 0x0D ہے جس کے بعد 15 0xFF's ہیں۔ اگر کیش کی لمبائی پہلے ہی اتنی + // بڑی ہے، تو ناکام ہو جائیں۔ + // 1 2 3 4 5 6 7 8 9 A B C D E F + require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + "کیش اوور فلو"); +``` + +مجھے نہیں لگتا کہ ہمیں کبھی اتنا بڑا کیش ملے گا (تقریباً 1.8\*1037 اندراجات، جسے اسٹور کرنے کے لیے تقریباً 1027 ٹی بی کی ضرورت ہوگی)۔ تاہم، میں اتنا بوڑھا ہوں کہ مجھے ["640kB ہمیشہ کافی ہوگا"](https://quoteinvestigator.com/2011/09/08/640k-enough/) یاد ہے۔ یہ ٹیسٹ بہت سستا ہے۔ + +```solidity + // اگلی کی (key) کا استعمال کرتے ہوئے ویلیو لکھیں + val2key[_value] = key2val.length+1; +``` + +ریورس لک اپ (ویلیو سے کی (key) تک) شامل کریں۔ + +```solidity + key2val.push(_value); +``` + +فارورڈ لک اپ (کی (key) سے ویلیو تک) شامل کریں۔ چونکہ ہم ویلیوز کو ترتیب وار تفویض کرتے ہیں، اس لیے ہم اسے صرف آخری ارے ویلیو کے بعد شامل کر سکتے ہیں۔ + +```solidity + return key2val.length; + } // cacheWrite +``` + +`key2val` کی نئی لمبائی واپس کریں، جو وہ سیل ہے جہاں نئی ​​ویلیو اسٹور کی گئی ہے۔ + +```solidity + function _calldataVal(uint startByte, uint length) + private pure returns (uint) +``` + +یہ فنکشن کال ڈیٹا سے کسی بھی لمبائی کی ویلیو پڑھتا ہے (32 بائٹس تک، ورڈ سائز)۔ + +```solidity + { + uint _retVal; + + require(length < 0x21, + "_calldataVal لمبائی کی حد 32 بائٹس ہے"); + require(length + startByte <= msg.data.length, + "_calldataVal کال ڈیٹا سائز سے آگے پڑھنے کی کوشش کر رہا ہے"); +``` + +یہ فنکشن اندرونی ہے، لہذا اگر باقی کوڈ صحیح طریقے سے لکھا گیا ہے تو ان ٹیسٹوں کی ضرورت نہیں ہے۔ تاہم، ان پر زیادہ لاگت نہیں آتی ہے لہذا ہم انہیں رکھ سکتے ہیں۔ + +```solidity + assembly { + _retVal := calldataload(startByte) + } +``` + +یہ کوڈ [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html) میں ہے۔ یہ کال ڈیٹا سے 32 بائٹ کی ویلیو پڑھتا ہے۔ یہ تب بھی کام کرتا ہے اگر کال ڈیٹا `startByte+32` سے پہلے رک جاتا ہے کیونکہ EVM میں غیر شروع شدہ جگہ کو صفر سمجھا جاتا ہے۔ + +```solidity + _retVal = _retVal >> (256-length*8); +``` + +ہم ضروری نہیں کہ 32 بائٹ کی ویلیو چاہتے ہیں۔ اس سے اضافی بائٹس سے چھٹکارا مل جاتا ہے۔ + +```solidity + return _retVal; + } // _calldataVal + + + // کال ڈیٹا سے ایک پیرامیٹر پڑھیں، _fromByte سے شروع ہو کر + function _readParam(uint _fromByte) internal + returns (uint _nextByte, uint _parameterValue) + { +``` + +کال ڈیٹا سے ایک پیرامیٹر پڑھیں۔ نوٹ کریں کہ ہمیں نہ صرف وہ ویلیو واپس کرنے کی ضرورت ہے جو ہم نے پڑھی ہے، بلکہ اگلے بائٹ کا مقام بھی واپس کرنے کی ضرورت ہے کیونکہ پیرامیٹرز 1 بائٹ سے لے کر 33 بائٹس تک کے ہو سکتے ہیں۔ + +```solidity + // پہلا بائٹ ہمیں بتاتا ہے کہ باقی کی تشریح کیسے کی جائے + uint8 _firstByte; + + _firstByte = uint8(_calldataVal(_fromByte, 1)); +``` + +Solidity ممکنہ طور پر خطرناک [مضمر قسم کی تبدیلیوں](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) پر پابندی لگا کر بگس کی تعداد کو کم کرنے کی کوشش کرتا ہے۔ ایک ڈاؤن گریڈ، مثال کے طور پر 256 بٹس سے 8 بٹس تک، واضح ہونا چاہیے۔ + +```solidity + + // ویلیو کو پڑھیں، لیکن اسے کیش میں نہ لکھیں + if (_firstByte == uint8(DONT_CACHE)) + return(_fromByte+33, _calldataVal(_fromByte+1, 32)); + + // ویلیو کو پڑھیں، اور اسے کیش میں لکھیں + if (_firstByte == uint8(INTO_CACHE)) { + uint _param = _calldataVal(_fromByte+1, 32); + cacheWrite(_param); + return(_fromByte+33, _param); + } + + // اگر ہم یہاں پہنچ گئے تو اس کا مطلب ہے کہ ہمیں کیش سے پڑھنے کی ضرورت ہے + + // پڑھنے کے لیے اضافی بائٹس کی تعداد + uint8 _extraBytes = _firstByte / 16; +``` + +نچلے [نببل](https://en.wikipedia.org/wiki/Nibble) کو لیں اور اسے دوسرے بائٹس کے ساتھ ملا کر کیش سے ویلیو پڑھیں۔ + +```solidity + uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) + + _calldataVal(_fromByte+1, _extraBytes); + + return (_fromByte+_extraBytes+1, cacheRead(_key)); + + } // _readParam + + + // n پیرامیٹرز پڑھیں (فنکشنز جانتے ہیں کہ وہ کتنے پیرامیٹرز کی توقع کرتے ہیں) + function _readParams(uint _paramNum) internal returns (uint[] memory) { +``` + +ہم کال ڈیٹا سے ہی پیرامیٹرز کی تعداد حاصل کر سکتے ہیں، لیکن جو فنکشنز ہمیں کال کرتے ہیں وہ جانتے ہیں کہ وہ کتنے پیرامیٹرز کی توقع کرتے ہیں۔ انہیں ہمیں بتانے دینا آسان ہے۔ + +```solidity + // جو پیرامیٹرز ہم پڑھتے ہیں + uint[] memory params = new uint[](_paramNum); + + // پیرامیٹرز بائٹ 4 سے شروع ہوتے ہیں، اس سے پہلے فنکشن کا دستخط ہوتا ہے + uint _atByte = 4; + + for(uint i=0; i<_paramNum; i++) { + (_atByte, params[i]) = _readParam(_atByte); + } +``` + +پیرامیٹرز کو اس وقت تک پڑھیں جب تک آپ کے پاس مطلوبہ تعداد نہ ہو۔ اگر ہم کال ڈیٹا کے آخر سے آگے نکل جاتے ہیں، تو `_readParams` کال کو واپس کر دے گا۔ + +```solidity + + return(params); + } // readParams + + // _readParams کی جانچ کے لیے، چار پیرامیٹرز پڑھنے کی جانچ کریں + function fourParam() public + returns (uint256,uint256,uint256,uint256) + { + uint[] memory params; + params = _readParams(4); + return (params[0], params[1], params[2], params[3]); + } // fourParam +``` + +Foundry کا ایک بڑا فائدہ یہ ہے کہ یہ Solidity میں ٹیسٹ لکھنے کی اجازت دیتا ہے ([نیچے کیش کی جانچ دیکھیں](#testing-the-cache))۔ اس سے یونٹ ٹیسٹ بہت آسان ہو جاتے ہیں۔ یہ ایک ایسا فنکشن ہے جو چار پیرامیٹرز کو پڑھتا ہے اور انہیں واپس کرتا ہے تاکہ ٹیسٹ اس بات کی تصدیق کر سکے کہ وہ درست تھے۔ + +```solidity + // ایک ویلیو حاصل کریں، وہ بائٹس واپس کریں جو اسے انکوڈ کریں گے (اگر ممکن ہو تو کیش کا استعمال کرتے ہوئے) + function encodeVal(uint _val) public view returns(bytes memory) { +``` + +`encodeVal` ایک فنکشن ہے جسے آف چین کوڈ کال کرتا ہے تاکہ کال ڈیٹا بنانے میں مدد ملے جو کیش کا استعمال کرتا ہے۔ یہ ایک ویلیو وصول کرتا ہے اور ان بائٹس کو واپس کرتا ہے جو اسے انکوڈ کرتے ہیں۔ یہ فنکشن ایک `view` ہے، لہذا اسے ٹرانزیکشن کی ضرورت نہیں ہے اور جب بیرونی طور پر کال کیا جاتا ہے تو اس پر کوئی گیس لاگت نہیں آتی ہے۔ + +```solidity + uint _key = val2key[_val]; + + // ویلیو ابھی کیش میں نہیں ہے، اسے شامل کریں + if (_key == 0) + return bytes.concat(INTO_CACHE, bytes32(_val)); +``` + +[EVM](/developers/docs/evm/) میں تمام غیر شروع شدہ اسٹوریج کو صفر سمجھا جاتا ہے۔ لہذا اگر ہم کسی ایسی ویلیو کی کی (key) تلاش کرتے ہیں جو وہاں نہیں ہے، تو ہمیں صفر ملتا ہے۔ اس صورت میں جو بائٹس اسے انکوڈ کرتے ہیں وہ `INTO_CACHE` ہیں (تاکہ یہ اگلی بار کیش ہو جائے)، اس کے بعد اصل ویلیو ہوتی ہے۔ + +```solidity + // اگر کی (key) <0x10 ہے، تو اسے ایک بائٹ کے طور پر واپس کریں + if (_key < 0x10) + return bytes.concat(bytes1(uint8(_key))); +``` + +سنگل بائٹس سب سے آسان ہیں۔ ہم صرف [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) کا استعمال کرتے ہیں تاکہ `bytes` قسم کو بائٹ ارے میں تبدیل کیا جا سکے جو کسی بھی لمبائی کا ہو سکتا ہے۔ نام کے باوجود، یہ صرف ایک آرگیومنٹ فراہم کرنے پر ٹھیک کام کرتا ہے۔ + +```solidity + // دو بائٹ ویلیو، 0x1vvv کے طور پر انکوڈ کی گئی + if (_key < 0x1000) + return bytes.concat(bytes2(uint16(_key) | 0x1000)); +``` + +جب ہمارے پاس ایک کی (key) ہوتی ہے جو 163 سے کم ہوتی ہے، تو ہم اسے دو بائٹس میں ظاہر کر سکتے ہیں۔ ہم پہلے `_key` کو، جو 256 بٹ کی ویلیو ہے، 16 بٹ کی ویلیو میں تبدیل کرتے ہیں اور پہلے بائٹ میں اضافی بائٹس کی تعداد شامل کرنے کے لیے منطقی یا (logical or) کا استعمال کرتے ہیں۔ پھر ہم اسے `bytes2` ویلیو میں ڈالتے ہیں، جسے `bytes` میں تبدیل کیا جا سکتا ہے۔ + +```solidity + // مندرجہ ذیل لائنوں کو لوپ کے طور پر کرنے کا شاید کوئی ہوشیار طریقہ ہے، + // لیکن یہ ایک ویو فنکشن ہے اس لیے میں پروگرامر کے وقت اور + // سادگی کے لیے آپٹمائز کر رہا ہوں۔ + + if (_key < 16*256**2) + return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2))); + if (_key < 16*256**3) + return bytes.concat(bytes4(uint32(_key) | (0x3 * 16 * 256**3))); + . + . + . + if (_key < 16*256**14) + return bytes.concat(bytes15(uint120(_key) | (0xE * 16 * 256**14))); + if (_key < 16*256**15) + return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15))); +``` + +دیگر ویلیوز (3 بائٹس، 4 بائٹس، وغیرہ) اسی طرح ہینڈل کی جاتی ہیں، صرف مختلف فیلڈ سائز کے ساتھ۔ + +```solidity + // اگر ہم یہاں پہنچ جاتے ہیں، تو کچھ غلط ہے۔ + revert("encodeVal میں خرابی، ایسا نہیں ہونا چاہیے"); +``` + +اگر ہم یہاں پہنچ جاتے ہیں تو اس کا مطلب ہے کہ ہمیں ایک ایسی کی (key) ملی ہے جو 16\*25615 سے کم نہیں ہے۔ لیکن `cacheWrite` کیز (keys) کو محدود کرتا ہے لہذا ہم 14\*25616 تک بھی نہیں پہنچ سکتے (جس کا پہلا بائٹ 0xFE ہوگا، لہذا یہ `DONT_CACHE` کی طرح نظر آئے گا)۔ لیکن مستقبل میں کسی پروگرامر کی طرف سے بگ متعارف کرانے کی صورت میں ٹیسٹ شامل کرنے میں ہمیں زیادہ لاگت نہیں آتی۔ + +```solidity + } // encodeVal + +} // Cache +``` + +### کیش کی جانچ {#testing-the-cache} + +Foundry کے فوائد میں سے ایک یہ ہے کہ [یہ آپ کو Solidity میں ٹیسٹ لکھنے دیتا ہے](https://getfoundry.sh/forge/tests/overview/)، جس سے یونٹ ٹیسٹ لکھنا آسان ہو جاتا ہے۔ `Cache` کلاس کے لیے ٹیسٹ [یہاں](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol) ہیں۔ چونکہ ٹیسٹنگ کوڈ بار بار ہوتا ہے، جیسا کہ ٹیسٹ ہوتے ہیں، یہ مضمون صرف دلچسپ حصوں کی وضاحت کرتا ہے۔ + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; + + +// کنسول کے لیے `forge test -vv` چلانے کی ضرورت ہے۔ +import "forge-std/console.sol"; +``` + +یہ صرف بوائلر پلیٹ ہے جو ٹیسٹ پیکیج اور `console.log` استعمال کرنے کے لیے ضروری ہے۔ + +```solidity +import "src/Cache.sol"; +``` + +ہمیں اس کنٹریکٹ کو جاننے کی ضرورت ہے جس کی ہم جانچ کر رہے ہیں۔ + +```solidity +contract CacheTest is Test { + Cache cache; + + function setUp() public { + cache = new Cache(); + } +``` + +`setUp` فنکشن ہر ٹیسٹ سے پہلے کال کیا جاتا ہے۔ اس صورت میں ہم صرف ایک نیا کیش بناتے ہیں، تاکہ ہمارے ٹیسٹ ایک دوسرے کو متاثر نہ کریں۔ + +```solidity + function testCaching() public { +``` + +ٹیسٹ وہ فنکشنز ہیں جن کے نام `test` سے شروع ہوتے ہیں۔ یہ فنکشن بنیادی کیش کی فعالیت، ویلیوز لکھنے اور انہیں دوبارہ پڑھنے کی جانچ کرتا ہے۔ + +```solidity + for(uint i=1; i<5000; i++) { + cache.cacheWrite(i*i); + } + + for(uint i=1; i<5000; i++) { + assertEq(cache.cacheRead(i), i*i); +``` + +یہ ہے کہ آپ اصل جانچ کیسے کرتے ہیں، [`assert...` فنکشنز](https://getfoundry.sh/reference/forge-std/std-assertions/) کا استعمال کرتے ہوئے۔ اس صورت میں، ہم جانچتے ہیں کہ ہم نے جو ویلیو لکھی ہے وہی ہے جو ہم نے پڑھی ہے۔ ہم `cache.cacheWrite` کے نتیجے کو مسترد کر سکتے ہیں کیونکہ ہم جانتے ہیں کہ کیش کیز (keys) لکیری طور پر تفویض کی جاتی ہیں۔ + +```solidity + } + } // testCaching + + + // ایک ہی ویلیو کو متعدد بار کیش کریں، یقینی بنائیں کہ کی (key) وہی + // رہتی ہے + function testRepeatCaching() public { + for(uint i=1; i<100; i++) { + uint _key1 = cache.cacheWrite(i); + uint _key2 = cache.cacheWrite(i); + assertEq(_key1, _key2); + } +``` + +پہلے ہم ہر ویلیو کو دو بار کیش میں لکھتے ہیں اور یقینی بناتے ہیں کہ کیز (keys) ایک جیسی ہیں (مطلب دوسری لکھائی واقعی نہیں ہوئی)۔ + +```solidity + for(uint i=1; i<100; i+=3) { + uint _key = cache.cacheWrite(i); + assertEq(_key, i); + } + } // testRepeatCaching +``` + +نظریاتی طور پر ایک ایسا بگ ہو سکتا ہے جو لگاتار کیش رائٹس کو متاثر نہیں کرتا ہے۔ لہذا یہاں ہم کچھ ایسی رائٹس کرتے ہیں جو لگاتار نہیں ہیں اور دیکھتے ہیں کہ ویلیوز اب بھی دوبارہ نہیں لکھی گئیں۔ + +```solidity + // میموری بفر سے ایک uint پڑھیں (یقینی بنانے کے لیے کہ ہمیں بھیجے گئے پیرامیٹرز + // واپس ملیں) + function toUint256(bytes memory _bytes, uint256 _start) internal pure + returns (uint256) +``` + +`bytes memory` بفر سے 256 بٹ کا ورڈ پڑھیں۔ یہ یوٹیلیٹی فنکشن ہمیں اس بات کی تصدیق کرنے دیتا ہے کہ جب ہم کیش کا استعمال کرنے والی فنکشن کال چلاتے ہیں تو ہمیں درست نتائج موصول ہوتے ہیں۔ + +```solidity + { + require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); + uint256 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x20), _start)) + } +``` + +Yul `uint256` سے آگے ڈیٹا ڈھانچے کو سپورٹ نہیں کرتا، لہذا جب آپ کسی زیادہ نفیس ڈیٹا ڈھانچے کا حوالہ دیتے ہیں، جیسے میموری بفر `_bytes`، تو آپ کو اس ڈھانچے کا ایڈریس ملتا ہے۔ Solidity `bytes memory` ویلیوز کو 32 بائٹ ورڈ کے طور پر اسٹور کرتا ہے جس میں لمبائی ہوتی ہے، اس کے بعد اصل بائٹس ہوتے ہیں، لہذا بائٹ نمبر `_start` حاصل کرنے کے لیے ہمیں `_bytes+32+_start` کا حساب لگانے کی ضرورت ہے۔ + +```solidity + + return tempUint; + } // toUint256 + + // fourParams() کے لیے فنکشن کا دستخط، بشکریہ + // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d + bytes4 constant FOUR_PARAMS = 0x3edc1e6d; + + // صرف کچھ مستقل ویلیوز یہ دیکھنے کے لیے کہ ہمیں صحیح ویلیوز واپس مل رہی ہیں + uint256 constant VAL_A = 0xDEAD60A7; + uint256 constant VAL_B = 0xBEEF; + uint256 constant VAL_C = 0x600D; + uint256 constant VAL_D = 0x600D60A7; +``` + +جانچ کے لیے ہمیں کچھ مستقل کی ضرورت ہے۔ + +```solidity + function testReadParam() public { +``` + +`fourParams()` کو کال کریں، ایک فنکشن جو `readParams` استعمال کرتا ہے، یہ جانچنے کے لیے کہ ہم پیرامیٹرز کو صحیح طریقے سے پڑھ سکتے ہیں۔ + +```solidity + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; +``` + +ہم کیش کا استعمال کرتے ہوئے کسی فنکشن کو کال کرنے کے لیے عام ABI میکانزم کا استعمال نہیں کر سکتے، اس لیے ہمیں نچلی سطح کے [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses) میکانزم کا استعمال کرنے کی ضرورت ہے۔ وہ میکانزم ان پٹ کے طور پر ایک `bytes memory` لیتا ہے، اور اسے (ساتھ ہی ایک بولین ویلیو) آؤٹ پٹ کے طور پر واپس کرتا ہے۔ + +```solidity + // پہلی کال، کیش خالی ہے + _callInput = bytes.concat( + FOUR_PARAMS, +``` + +ایک ہی کنٹریکٹ کے لیے کیشڈ فنکشنز (براہ راست ٹرانزیکشنز سے کالز کے لیے) اور نان-کیشڈ فنکشنز (دیگر اسمارٹ کنٹریکٹس سے کالز کے لیے) دونوں کو سپورٹ کرنا مفید ہے۔ ایسا کرنے کے لیے ہمیں صحیح فنکشن کو کال کرنے کے لیے Solidity میکانزم پر انحصار جاری رکھنے کی ضرورت ہے، بجائے اس کے کہ ہر چیز کو [ایک `فال بیک` فنکشن](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function) میں ڈالیں۔ ایسا کرنے سے کمپوزیبلیٹی بہت آسان ہو جاتی ہے۔ زیادہ تر معاملات میں فنکشن کی شناخت کے لیے ایک بائٹ کافی ہوگا، اس لیے ہم تین بائٹس (16\*3=48 گیس) ضائع کر رہے ہیں۔ تاہم، جیسا کہ میں یہ لکھ رہا ہوں ان 48 گیس کی قیمت 0.07 سینٹ ہے، جو آسان، کم بگ والے، کوڈ کے لیے ایک معقول قیمت ہے۔ + +```solidity + // پہلی ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), + bytes32(VAL_A), +``` + +پہلی ویلیو: ایک جھنڈا جو کہتا ہے کہ یہ ایک مکمل ویلیو ہے جسے کیش میں لکھنے کی ضرورت ہے، اس کے بعد ویلیو کے 32 بائٹس۔ دیگر تین ویلیوز بھی اسی طرح کی ہیں، سوائے اس کے کہ `VAL_B` کو کیش میں نہیں لکھا گیا اور `VAL_C` تیسرا پیرامیٹر اور چوتھا پیرامیٹر دونوں ہے۔ + +```solidity + . + . + . + ); + (_success, _callOutput) = _cacheAddr.call(_callInput); +``` + +یہ وہ جگہ ہے جہاں ہم اصل میں `Cache` کنٹریکٹ کو کال کرتے ہیں۔ + +```solidity + assertEq(_success, true); +``` + +ہمیں امید ہے کہ کال کامیاب ہوگی۔ + +```solidity + assertEq(cache.cacheRead(1), VAL_A); + assertEq(cache.cacheRead(2), VAL_C); +``` + +ہم ایک خالی کیش سے شروع کرتے ہیں اور پھر `VAL_A` کے بعد `VAL_C` شامل کرتے ہیں۔ ہم توقع کریں گے کہ پہلے والے کی کی (key) 1 ہوگی، اور دوسرے والے کی 2 ہوگی۔ + +``` + assertEq(toUint256(_callOutput,0), VAL_A); + assertEq(toUint256(_callOutput,32), VAL_B); + assertEq(toUint256(_callOutput,64), VAL_C); + assertEq(toUint256(_callOutput,96), VAL_C); +``` + +آؤٹ پٹ چار پیرامیٹرز ہیں۔ یہاں ہم اس بات کی تصدیق کرتے ہیں کہ یہ درست ہے۔ + +```solidity + // دوسری کال، ہم کیش کا استعمال کر سکتے ہیں + _callInput = bytes.concat( + FOUR_PARAMS, + + // کیش میں پہلی ویلیو + bytes1(0x01), +``` + +16 سے نیچے کیش کیز (keys) صرف ایک بائٹ کی ہوتی ہیں۔ + +```solidity + // دوسری ویلیو، اسے کیش میں شامل نہ کریں + cache.DONT_CACHE(), + bytes32(VAL_B), + + // تیسری اور چوتھی ویلیوز، ایک ہی ویلیو + bytes1(0x02), + bytes1(0x02) + ); + . + . + . + } // testReadParam +``` + +کال کے بعد کے ٹیسٹ پہلی کال کے بعد کے ٹیسٹوں کی طرح ہیں۔ + +```solidity + function testEncodeVal() public { +``` + +یہ فنکشن `testReadParam` سے ملتا جلتا ہے، سوائے اس کے کہ پیرامیٹرز کو واضح طور پر لکھنے کے بجائے ہم `encodeVal()` استعمال کرتے ہیں۔ + +```solidity + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(VAL_A), + cache.encodeVal(VAL_B), + cache.encodeVal(VAL_C), + cache.encodeVal(VAL_D) + ); + . + . + . + assertEq(_callInput.length, 4+1*4); + } // testEncodeVal +``` + +`testEncodeVal()` میں واحد اضافی ٹیسٹ یہ تصدیق کرنا ہے کہ `_callInput` کی لمبائی درست ہے۔ پہلی کال کے لیے یہ 4+33\*4 ہے۔ دوسرے کے لیے، جہاں ہر ویلیو پہلے سے ہی کیش میں ہے، یہ 4+1\*4 ہے۔ + +```solidity + // encodeVal کی جانچ کریں جب کی (key) ایک بائٹ سے زیادہ ہو + // زیادہ سے زیادہ تین بائٹس کیونکہ کیش کو چار بائٹس تک بھرنے میں + // بہت زیادہ وقت لگتا ہے۔ + function testEncodeValBig() public { + // کیش میں کئی ویلیوز ڈالیں۔ + // چیزوں کو آسان رکھنے کے لیے، ویلیو n کے لیے کی (key) n استعمال کریں۔ + for(uint i=1; i<0x1FFF; i++) { + cache.cacheWrite(i); + } +``` + +اوپر `testEncodeVal` فنکشن کیش میں صرف چار ویلیوز لکھتا ہے، اس لیے [فنکشن کا وہ حصہ جو ملٹی بائٹ ویلیوز سے نمٹتا ہے](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) چیک نہیں کیا جاتا ہے۔ لیکن وہ کوڈ پیچیدہ اور غلطی کا شکار ہے۔ + +اس فنکشن کا پہلا حصہ ایک لوپ ہے جو 1 سے 0x1FFF تک کی تمام ویلیوز کو ترتیب سے کیش میں لکھتا ہے، لہذا ہم ان ویلیوز کو انکوڈ کر سکیں گے اور جان سکیں گے کہ وہ کہاں جا رہی ہیں۔ + +```solidity + . + . + . + + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(0x000F), // ایک بائٹ 0x0F + cache.encodeVal(0x0010), // دو بائٹس 0x1010 + cache.encodeVal(0x0100), // دو بائٹس 0x1100 + cache.encodeVal(0x1000) // تین بائٹس 0x201000 + ); +``` + +ایک بائٹ، دو بائٹ، اور تین بائٹ ویلیوز کی جانچ کریں۔ ہم اس سے آگے کی جانچ نہیں کرتے ہیں کیونکہ کافی اسٹیک اندراجات لکھنے میں بہت زیادہ وقت لگے گا (کم از کم 0x10000000، تقریباً ایک چوتھائی ارب)۔ + +```solidity + . + . + . + . + } // testEncodeValBig + + + // ٹیسٹ کریں کہ ضرورت سے زیادہ چھوٹے بفر کے ساتھ ہمیں ایک ریورٹ ملتا ہے + function testShortCalldata() public { +``` + +جانچ کریں کہ غیر معمولی صورت میں کیا ہوتا ہے جہاں کافی پیرامیٹرز نہیں ہوتے ہیں۔ + +```solidity + . + . + . + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, false); + } // testShortCalldata +``` + +چونکہ یہ ریورٹ ہوتا ہے، اس لیے ہمیں جو نتیجہ ملنا چاہیے وہ `غلط` ہے۔ + +``` + // کیش کیز (keys) کے ساتھ کال کریں جو وہاں نہیں ہیں + function testNoCacheKey() public { + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + + // پہلی ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), + bytes32(VAL_A), + + // دوسری ویلیو + bytes1(0x0F), + bytes2(0x1234), + bytes11(0xA10102030405060708090A) + ); +``` + +یہ فنکشن چار بالکل جائز پیرامیٹرز حاصل کرتا ہے، سوائے اس کے کہ کیش خالی ہے لہذا وہاں پڑھنے کے لیے کوئی ویلیو نہیں ہے۔ + +```solidity + . + . + . + // ٹیسٹ کریں کہ ضرورت سے زیادہ لمبے بفر کے ساتھ سب کچھ فائل کام کرتا ہے + function testLongCalldata() public { + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; + + // پہلی کال، کیش خالی ہے + _callInput = bytes.concat( + FOUR_PARAMS, + + // پہلی ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), bytes32(VAL_A), + + // دوسری ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), bytes32(VAL_B), + + // تیسری ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), bytes32(VAL_C), + + // چوتھی ویلیو، اسے کیش میں شامل کریں + cache.INTO_CACHE(), bytes32(VAL_D), + + // اور "اچھی قسمت" کے لیے ایک اور ویلیو + bytes4(0x31112233) + ); +``` + +یہ فنکشن پانچ ویلیوز بھیجتا ہے۔ ہم جانتے ہیں کہ پانچویں ویلیو کو نظر انداز کر دیا جاتا ہے کیونکہ یہ ایک درست کیش انٹری نہیں ہے، جو اگر شامل نہ کی جاتی تو ریورٹ کا سبب بنتی۔ + +```solidity + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, true); + . + . + . + } // testLongCalldata + +} // CacheTest + +``` + +## ایک نمونہ ایپلی کیشن {#a-sample-app} + +Solidity میں ٹیسٹ لکھنا بہت اچھا ہے، لیکن دن کے آخر میں ایک dapp کو مفید ہونے کے لیے چین کے باہر سے درخواستوں پر کارروائی کرنے کے قابل ہونا چاہیے۔ یہ مضمون یہ ظاہر کرتا ہے کہ `WORM` کے ساتھ dapp میں کیشنگ کا استعمال کیسے کیا جائے، جس کا مطلب ہے "ایک بار لکھیں، کئی بار پڑھیں"۔ اگر کوئی کی (key) ابھی تک نہیں لکھی گئی ہے، تو آپ اس میں ایک ویلیو لکھ سکتے ہیں۔ اگر کی (key) پہلے سے لکھی ہوئی ہے، تو آپ کو ایک ریورٹ ملتا ہے۔ + +### کنٹریکٹ {#the-contract} + +[یہ کنٹریکٹ ہے](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol)۔ یہ زیادہ تر وہی دہراتا ہے جو ہم نے `Cache` اور `CacheTest` کے ساتھ پہلے ہی کیا ہے، لہذا ہم صرف ان حصوں کا احاطہ کرتے ہیں جو دلچسپ ہیں۔ + +```solidity +import "./Cache.sol"; + +contract WORM is Cache { +``` + +`Cache` استعمال کرنے کا سب سے آسان طریقہ یہ ہے کہ اسے اپنے کنٹریکٹ میں وراثت میں حاصل کریں۔ + +```solidity + function writeEntryCached() external { + uint[] memory params = _readParams(2); + writeEntry(params[0], params[1]); + } // writeEntryCached +``` + +یہ فنکشن اوپر `CacheTest` میں `fourParam` سے ملتا جلتا ہے۔ چونکہ ہم ABI کی تفصیلات پر عمل نہیں کرتے ہیں، اس لیے بہتر ہے کہ فنکشن میں کوئی پیرامیٹر نہ ڈکلیئر کریں۔ + +```solidity + // ہمیں کال کرنا آسان بنائیں + // writeEntryCached() کے لیے فنکشن کا دستخط، بشکریہ + // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 + bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3; +``` + +بیرونی کوڈ جو `writeEntryCached` کو کال کرتا ہے، اسے دستی طور پر کال ڈیٹا بنانا ہوگا، بجائے اس کے کہ `worm.writeEntryCached` استعمال کیا جائے، کیونکہ ہم ABI کی تفصیلات پر عمل نہیں کرتے ہیں۔ اس مستقل ویلیو کا ہونا اسے لکھنا آسان بنا دیتا ہے۔ + +نوٹ کریں کہ اگرچہ ہم `WRITE_ENTRY_CACHED` کو ایک اسٹیٹ ویری ایبل کے طور پر بیان کرتے ہیں، اسے بیرونی طور پر پڑھنے کے لیے اس کے لیے گیٹر فنکشن، `worm.WRITE_ENTRY_CACHED()` کا استعمال کرنا ضروری ہے۔ + +```solidity + function readEntry(uint key) public view + returns (uint _value, address _writtenBy, uint _writtenAtBlock) +``` + +ریڈ فنکشن ایک `view` ہے، لہذا اسے ٹرانزیکشن کی ضرورت نہیں ہے اور اس پر کوئی گیس لاگت نہیں آتی ہے۔ نتیجے کے طور پر، پیرامیٹر کے لیے کیش استعمال کرنے کا کوئی فائدہ نہیں ہے۔ ویو فنکشنز کے ساتھ معیاری میکانزم کا استعمال کرنا بہتر ہے جو آسان ہے۔ + +### جانچ کا کوڈ {#the-testing-code} + +[یہ کنٹریکٹ کے لیے جانچ کا کوڈ ہے](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol)۔ ایک بار پھر، آئیے صرف اس پر نظر ڈالتے ہیں جو دلچسپ ہے۔ + +```solidity + function testWReadWrite() public { + worm.writeEntry(0xDEAD, 0x60A7); + + vm.expectRevert(bytes("انٹری پہلے ہی لکھی جا چکی ہے")); + worm.writeEntry(0xDEAD, 0xBEEF); +``` + +[یہ (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) ہے کہ ہم Foundry ٹیسٹ میں کیسے بتاتے ہیں کہ اگلی کال ناکام ہونی چاہیے، اور ناکامی کی اطلاع دی گئی وجہ۔ یہ اس وقت لاگو ہوتا ہے جب ہم `.` کا نحو استعمال کرتے ہیں()` بجائے اس کے کہ کال ڈیٹا بنایا جائے اور کنٹریکٹ کو نچلی سطح کے انٹرفیس (`.call()`، وغیرہ) کا استعمال کرکے کال کیا جائے۔ + +```solidity + function testReadWriteCached() public { + uint cacheGoat = worm.cacheWrite(0x60A7); +``` + +یہاں ہم اس حقیقت کا استعمال کرتے ہیں کہ `cacheWrite` کیش کی (key) واپس کرتا ہے۔ یہ ایسی چیز نہیں ہے جس کی ہم پیداوار میں استعمال کی توقع کریں گے، کیونکہ `cacheWrite` اسٹیٹ کو تبدیل کرتا ہے، اور اس لیے اسے صرف ٹرانزیکشن کے دوران ہی کال کیا جا سکتا ہے۔ ٹرانزیکشنز میں واپسی کی ویلیوز نہیں ہوتی ہیں، اگر ان کے نتائج ہوتے ہیں تو ان نتائج کو ایونٹس کے طور پر خارج کیا جانا چاہیے۔ لہذا `cacheWrite` کی واپسی کی ویلیو صرف آن چین کوڈ سے قابل رسائی ہے، اور آن چین کوڈ کو پیرامیٹر کیشنگ کی ضرورت نہیں ہے۔ + +```solidity + (_success,) = address(worm).call(_callInput); +``` + +یہ ہے کہ ہم Solidity کو کیسے بتاتے ہیں کہ جب کہ `.call()` کی دو واپسی کی ویلیوز ہیں، ہم صرف پہلی کی پرواہ کرتے ہیں۔ + +```solidity + (_success,) = address(worm).call(_callInput); + assertEq(_success, false); +``` + +چونکہ ہم نچلی سطح کے `
.call()` فنکشن کا استعمال کرتے ہیں، اس لیے ہم `vm.expectRevert()` کا استعمال نہیں کر سکتے اور ہمیں کال سے ملنے والی بولین کامیابی کی ویلیو کو دیکھنا ہوگا۔ + +```solidity + event EntryWritten(uint indexed key, uint indexed value); + + . + . + . + + _callInput = bytes.concat( + worm.WRITE_ENTRY_CACHED(), worm.encodeVal(a), worm.encodeVal(b)); + vm.expectEmit(true, true, false, false); + emit EntryWritten(a, b); + (_success,) = address(worm).call(_callInput); +``` + +یہ وہ طریقہ ہے جس سے ہم تصدیق کرتے ہیں کہ کوڈ Foundry میں [ایک ایونٹ کو صحیح طریقے سے خارج کرتا ہے](https://getfoundry.sh/reference/cheatcodes/expect-emit/)۔ + +### کلائنٹ {#the-client} + +ایک چیز جو آپ کو Solidity ٹیسٹوں کے ساتھ نہیں ملتی ہے وہ ہے JavaScript کوڈ جسے آپ اپنی ایپلی کیشن میں کاٹ اور پیسٹ کر سکتے ہیں۔ اس کوڈ کو لکھنے کے لیے میں نے WORM کو [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli) پر تعینات کیا، [Optimism](https://www.optimism.io/) کا نیا ٹیسٹ نیٹ۔ یہ ایڈریس [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a) پر ہے۔ + +[آپ یہاں کلائنٹ کے لیے JavaScript کوڈ دیکھ سکتے ہیں](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js)۔ اسے استعمال کرنے کے لیے: + +1. گٹ ریپوزٹری کو کلون کریں: + + ```sh + git clone https://github.com/qbzzt/20220915-all-you-can-cache.git + ``` + +2. ضروری پیکیجز انسٹال کریں: + + ```sh + cd javascript + yarn + ``` + +3. کنفیگریشن فائل کاپی کریں: + + ```sh + cp .env.example .env + ``` + +4. اپنی کنفیگریشن کے لیے `.env` میں ترمیم کریں: + + | پیرامیٹر | قدر | + | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | MNEMONIC | ایک اکاؤنٹ کے لیے یادداشت جس میں ٹرانزیکشن کی ادائیگی کے لیے کافی ETH ہو۔ [آپ یہاں Optimism Goerli نیٹ ورک کے لیے مفت ETH حاصل کر سکتے ہیں](https://optimismfaucet.xyz/)۔ | + | OPTIMISM_GOERLI_URL | Optimism Goerli کا URL۔ عوامی اینڈ پوائنٹ، `https://goerli.optimism.io`، شرح محدود ہے لیکن یہاں ہماری ضرورت کے لیے کافی ہے | + +5. `index.js` چلائیں۔ + + ```sh + node index.js + ``` + + یہ نمونہ ایپلی کیشن پہلے WORM میں ایک انٹری لکھتی ہے، کال ڈیٹا اور Etherscan پر ٹرانزیکشن کا لنک دکھاتی ہے۔ پھر یہ اس انٹری کو واپس پڑھتا ہے، اور اس کی استعمال کردہ کی (key) اور انٹری میں ویلیوز (ویلیو، بلاک نمبر، اور مصنف) دکھاتا ہے۔ + +زیادہ تر کلائنٹ عام Dapp JavaScript ہے۔ تو ایک بار پھر ہم صرف دلچسپ حصوں پر جائیں گے۔ + +```javascript +. +. +. +const main = async () => { + const func = await worm.WRITE_ENTRY_CACHED() + + // ہر بار ایک نئی کی (key) کی ضرورت ہے + const key = await worm.encodeVal(Number(new Date())) +``` + +ایک دیئے گئے سلاٹ میں صرف ایک بار لکھا جا سکتا ہے، لہذا ہم ٹائم اسٹیمپ کا استعمال کرتے ہیں تاکہ یہ یقینی بنایا جا سکے کہ ہم سلاٹس کو دوبارہ استعمال نہ کریں۔ + +```javascript +const val = await worm.encodeVal("0x600D") + +// ایک انٹری لکھیں +const calldata = func + key.slice(2) + val.slice(2) +``` + +Ethers توقع کرتا ہے کہ کال ڈیٹا ایک ہیکس سٹرنگ ہوگا، `0x` کے بعد ہیکساڈیسیمل ہندسوں کی ایک جفت تعداد۔ چونکہ `key` اور `val` دونوں `0x` سے شروع ہوتے ہیں، ہمیں ان ہیڈرز کو ہٹانے کی ضرورت ہے۔ + +```javascript +const tx = await worm.populateTransaction.writeEntryCached() +tx.data = calldata + +sentTx = await wallet.sendTransaction(tx) +``` + +جیسا کہ Solidity ٹیسٹنگ کوڈ کے ساتھ ہے، ہم عام طور پر کیشڈ فنکشن کو کال نہیں کر سکتے۔ اس کے بجائے، ہمیں نچلی سطح کے میکانزم کا استعمال کرنے کی ضرورت ہے۔ + +```javascript + . + . + . + // ابھی لکھی گئی انٹری کو پڑھیں + const realKey = '0x' + key.slice(4) // FF فلیگ کو ہٹائیں + const entryRead = await worm.readEntry(realKey) + . + . + . +``` + +انٹریز پڑھنے کے لیے ہم عام میکانزم کا استعمال کر سکتے ہیں۔ `view` فنکشنز کے ساتھ پیرامیٹر کیشنگ استعمال کرنے کی ضرورت نہیں ہے۔ + +## نتیجہ {#conclusion} + +اس مضمون میں کوڈ تصور کا ثبوت ہے، مقصد اس خیال کو سمجھنے میں آسان بنانا ہے۔ پیداوار کے لیے تیار نظام کے لیے آپ کو کچھ اضافی فعالیت نافذ کرنے کی ضرورت پڑ سکتی ہے: + +- ان ویلیوز کو ہینڈل کریں جو `uint256` نہیں ہیں۔ مثال کے طور پر، سٹرنگز۔ +- عالمی کیش کے بجائے، شاید صارفین اور کیشز کے درمیان ایک میپنگ ہو۔ مختلف صارفین مختلف ویلیوز استعمال کرتے ہیں۔ +- ایڈریسز کے لیے استعمال ہونے والی ویلیوز دیگر مقاصد کے لیے استعمال ہونے والی ویلیوز سے الگ ہیں۔ صرف ایڈریسز کے لیے ایک علیحدہ کیش رکھنا سمجھ میں آ سکتا ہے۔ +- فی الحال، کیش کیز (keys) "پہلے آؤ، سب سے چھوٹی کی (key)" الگورتھم پر ہیں۔ پہلی سولہ ویلیوز کو ایک بائٹ کے طور پر بھیجا جا سکتا ہے۔ اگلی 4080 ویلیوز کو دو بائٹس کے طور پر بھیجا جا سکتا ہے۔ اگلی تقریباً ملین ویلیوز تین بائٹس ہیں، وغیرہ۔ ایک پروڈکشن سسٹم کو کیش اندراجات پر استعمال کے کاؤنٹرز رکھنے چاہئیں اور انہیں دوبارہ منظم کرنا چاہیے تاکہ سولہ _سب سے عام_ ویلیوز ایک بائٹ ہوں، اگلی 4080 سب سے عام ویلیوز دو بائٹس ہوں، وغیرہ۔ + + تاہم، یہ ایک ممکنہ طور پر خطرناک آپریشن ہے۔ مندرجہ ذیل واقعات کی ترتیب کا تصور کریں: + + 1. نوآم نائیو ٹوکن بھیجنے کے لیے ایڈریس کو انکوڈ کرنے کے لیے `encodeVal` کو کال کرتا ہے۔ وہ ایڈریس ایپلی کیشن پر استعمال ہونے والے پہلے ایڈریسز میں سے ایک ہے، اس لیے انکوڈ شدہ ویلیو 0x06 ہے۔ یہ ایک `view` فنکشن ہے، ٹرانزیکشن نہیں، اس لیے یہ نوآم اور اس کے استعمال کردہ نوڈ کے درمیان ہے، اور کوئی اور اس کے بارے میں نہیں جانتا + + 2. اوون اونر کیش ری آرڈرنگ آپریشن چلاتا ہے۔ بہت کم لوگ اصل میں اس ایڈریس کا استعمال کرتے ہیں، لہذا اب اسے 0x201122 کے طور پر انکوڈ کیا گیا ہے۔ ایک مختلف ویلیو، 1018، کو 0x06 تفویض کیا گیا ہے۔ + + 3. نوآم نائیو اپنے ٹوکنز 0x06 پر بھیجتا ہے۔ وہ ایڈریس `0x0000000000000000000000000de0b6b3a7640000` پر جاتے ہیں، اور چونکہ کوئی بھی اس ایڈریس کی پرائیویٹ کی (key) نہیں جانتا، وہ وہیں پھنس جاتے ہیں۔ نوآم _خوش نہیں_ ہے۔ + + اس مسئلے کو حل کرنے کے طریقے ہیں، اور کیش کی دوبارہ ترتیب کے دوران میم پول میں موجود ٹرانزیکشنز کے متعلقہ مسئلے کو بھی، لیکن آپ کو اس سے آگاہ ہونا چاہیے۔ + +میں نے یہاں Optimism کے ساتھ کیشنگ کا مظاہرہ کیا، کیونکہ میں ایک Optimism ملازم ہوں اور یہ وہ رول اپ ہے جسے میں سب سے بہتر جانتا ہوں۔ لیکن اسے کسی بھی ایسے رول اپ کے ساتھ کام کرنا چاہیے جو اندرونی پروسیسنگ کے لیے کم سے کم لاگت وصول کرتا ہو، تاکہ اس کے مقابلے میں L1 پر ٹرانزیکشن ڈیٹا لکھنا بڑا خرچ ہو۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ + diff --git a/public/content/translations/ur/developers/tutorials/app-plasma/index.md b/public/content/translations/ur/developers/tutorials/app-plasma/index.md new file mode 100644 index 00000000000..a76e13b43ce --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/app-plasma/index.md @@ -0,0 +1,1255 @@ +--- +title: "ایک ایپ کے لیے مخصوص پلازما لکھیں جو پرائیویسی کو محفوظ رکھتا ہے" +description: "اس ٹیوٹوریل میں، ہم ڈپازٹس کے لیے ایک نیم خفیہ بینک بناتے ہیں۔ بینک ایک مرکزی جزو ہے؛ یہ ہر صارف کا بیلنس جانتا ہے۔ تاہم، یہ معلومات آن چین ذخیرہ نہیں کی جاتی ہے۔ اس کے بجائے، بینک اسٹیٹ کا ایک ہیش پوسٹ کرتا ہے۔ جب بھی کوئی ٹرانزیکشن ہوتا ہے، بینک نیا ہیش پوسٹ کرتا ہے، ساتھ ہی ایک زیرو-نالج پروف بھی کہ اس کے پاس ایک دستخط شدہ ٹرانزیکشن ہے جو ہیش اسٹیٹ کو نئے میں بدل دیتا ہے۔ اس ٹیوٹوریل کو پڑھنے کے بعد، آپ نہ صرف یہ سمجھیں گے کہ زیرو-نالج پروف کا استعمال کیسے کریں، بلکہ یہ بھی کہ آپ انہیں کیوں استعمال کرتے ہیں اور اسے محفوظ طریقے سے کیسے کریں۔" +author: Ori Pomerantz +tags: [ "زیرو-نالج", "سرور", "آف چین", "رازداری" ] +skill: advanced +lang: ur-in +published: 2025-10-15 +--- + +## تعارف {#introduction} + +[رول اپس](/developers/docs/scaling/zk-rollups/) کے برعکس، [پلازما](/developers/docs/scaling/plasma) انٹیگریٹی کے لیے Ethereum مین نیٹ کا استعمال کرتے ہیں، لیکن دستیابی کے لیے نہیں۔ اس مضمون میں، ہم ایک ایسی ایپلیکیشن لکھتے ہیں جو پلازما کی طرح برتاؤ کرتی ہے، جس میں Ethereum انٹیگریٹی (کوئی غیر مجاز تبدیلیاں نہیں) کی ضمانت دیتا ہے لیکن دستیابی کی نہیں (ایک مرکزی جزو ڈاؤن ہو سکتا ہے اور پورے سسٹم کو غیر فعال کر سکتا ہے)۔ + +جو ایپلیکیشن ہم یہاں لکھتے ہیں وہ ایک پرائیویسی کو محفوظ رکھنے والا بینک ہے۔ مختلف پتوں کے پاس بیلنس والے اکاؤنٹس ہوتے ہیں، اور وہ دوسرے اکاؤنٹس میں رقم (ETH) بھیج سکتے ہیں۔ بینک اسٹیٹ (اکاؤنٹس اور ان کے بیلنس) اور ٹرانزیکشنز کے ہیش پوسٹ کرتا ہے، لیکن اصل بیلنس کو آف چین رکھتا ہے جہاں وہ نجی رہ سکتے ہیں۔ + +## ڈیزائن {#design} + +یہ پروڈکشن کے لیے تیار سسٹم نہیں ہے، بلکہ ایک تدریسی ٹول ہے۔ اس طرح، اسے کئی آسان بنانے والے مفروضوں کے ساتھ لکھا گیا ہے۔ + +- فکسڈ اکاؤنٹ پول۔ اکاؤنٹس کی ایک مخصوص تعداد ہے، اور ہر اکاؤنٹ ایک پہلے سے طے شدہ پتے سے تعلق رکھتا ہے۔ یہ ایک بہت آسان نظام بناتا ہے کیونکہ زیرو-نالج پروف میں متغیر سائز کے ڈیٹا ڈھانچے کو سنبھالنا مشکل ہے۔ پروڈکشن کے لیے تیار سسٹم کے لیے، ہم [مرکل روٹ](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) کو اسٹیٹ ہیش کے طور پر استعمال کر سکتے ہیں اور مطلوبہ بیلنس کے لیے مرکل پروف فراہم کر سکتے ہیں۔ + +- میموری اسٹوریج۔ پروڈکشن سسٹم پر، ہمیں تمام اکاؤنٹ بیلنس کو ڈسک پر لکھنے کی ضرورت ہے تاکہ انہیں دوبارہ شروع ہونے کی صورت میں محفوظ رکھا جا سکے۔ یہاں، یہ ٹھیک ہے اگر معلومات آسانی سے ضائع ہو جائیں۔ + +- صرف ٹرانسفرز۔ ایک پروڈکشن سسٹم کو بینک میں اثاثے جمع کرنے اور انہیں نکالنے کے ایک طریقے کی ضرورت ہوگی۔ لیکن یہاں مقصد صرف تصور کی وضاحت کرنا ہے، اس لیے یہ بینک صرف ٹرانسفرز تک محدود ہے۔ + +### زیرو-نالج پروفس {#zero-knowledge-proofs} + +بنیادی سطح پر، ایک زیرو-نالج پروف یہ ظاہر کرتا ہے کہ پروور کچھ ڈیٹا، _Dataprivate_ کو جانتا ہے، اس طرح کہ کچھ عوامی ڈیٹا، _Datapublic_، اور _Dataprivate_ کے درمیان ایک رشتہ _Relationship_ موجود ہے۔ تصدیق کنندہ _Relationship_ اور _Datapublic_ کو جانتا ہے۔ + +پرائیویسی کو محفوظ رکھنے کے لیے، ہمیں اسٹیٹس اور ٹرانزیکشنز کو نجی رکھنے کی ضرورت ہے۔ لیکن انٹیگریٹی کو یقینی بنانے کے لیے، ہمیں اسٹیٹس کے [کرپٹوگرافک ہیش](https://en.wikipedia.org/wiki/Cryptographic_hash_function) کو عوامی رکھنے کی ضرورت ہے۔ ان لوگوں کو ثابت کرنے کے لیے جو ٹرانزیکشنز جمع کرتے ہیں کہ وہ ٹرانزیکشنز واقعی ہوئے، ہمیں ٹرانزیکشن ہیش بھی پوسٹ کرنے کی ضرورت ہے۔ + +زیادہ تر معاملات میں، _Dataprivate_ زیرو-نالج پروف پروگرام کا ان پٹ ہے، اور _Datapublic_ آؤٹ پٹ ہے۔ + +_Dataprivate_ میں یہ فیلڈز: + +- _اسٹیٹn_، پرانی اسٹیٹ +- _اسٹیٹn+1_، نئی اسٹیٹ +- _ٹرانزیکشن_، ایک ٹرانزیکشن جو پرانی اسٹیٹ سے نئی میں بدلتا ہے۔ اس ٹرانزیکشن میں یہ فیلڈز شامل ہونے چاہئیں: + - _منزل کا پتہ_ جو ٹرانسفر وصول کرتا ہے + - ٹرانسفر کی جانے والی _رقم_ + - _نونس_ یہ یقینی بنانے کے لیے کہ ہر ٹرانزیکشن پر صرف ایک بار کارروائی کی جا سکتی ہے۔ + سورس ایڈریس کو ٹرانزیکشن میں ہونے کی ضرورت نہیں ہے، کیونکہ اسے دستخط سے بازیافت کیا جا سکتا ہے۔ +- _دستخط_، ایک دستخط جو ٹرانزیکشن انجام دینے کے لیے مجاز ہے۔ ہمارے معاملے میں، ٹرانزیکشن انجام دینے کے لیے مجاز واحد پتہ سورس ایڈریس ہے۔ چونکہ ہمارا زیرو-نالج سسٹم جس طرح سے کام کرتا ہے، ہمیں Ethereum دستخط کے علاوہ، اکاؤنٹ کی پبلک کی بھی ضرورت ہے۔ + +یہ _Datapublic_ میں فیلڈز ہیں: + +- _ہیش(اسٹیٹn)_ پرانی اسٹیٹ کا ہیش +- _ہیش(اسٹیٹn+1)_ نئی اسٹیٹ کا ہیش +- _ہیش(ٹرانزیکشن)_ اس ٹرانزیکشن کا ہیش جو اسٹیٹ کو _اسٹیٹn_ سے _اسٹیٹn+1_ میں بدلتا ہے۔ + +یہ رشتہ کئی شرائط کی جانچ کرتا ہے: + +- عوامی ہیش واقعی نجی فیلڈز کے لیے درست ہیش ہیں۔ +- ٹرانزیکشن، جب پرانی اسٹیٹ پر لاگو ہوتا ہے، تو نئی اسٹیٹ کا نتیجہ نکلتا ہے۔ +- دستخط ٹرانزیکشن کے سورس ایڈریس سے آتا ہے۔ + +کرپٹوگرافک ہیش فنکشنز کی خصوصیات کی وجہ سے، ان شرائط کو ثابت کرنا انٹیگریٹی کو یقینی بنانے کے لیے کافی ہے۔ + +### ڈیٹا کی ساختیں {#data-structures} + +بنیادی ڈیٹا ڈھانچہ سرور کے زیر اہتمام اسٹیٹ ہے۔ ہر اکاؤنٹ کے لیے، سرور اکاؤنٹ بیلنس اور ایک [نونس](https://en.wikipedia.org/wiki/Cryptographic_nonce) کا ٹریک رکھتا ہے، جو [ری پلے حملوں](https://en.wikipedia.org/wiki/Replay_attack) کو روکنے کے لیے استعمال ہوتا ہے۔ + +### اجزاء {#components} + +اس سسٹم کو دو اجزاء کی ضرورت ہے: + +- _سرور_ جو ٹرانزیکشنز وصول کرتا ہے، ان پر کارروائی کرتا ہے، اور زیرو-نالج پروفس کے ساتھ چین پر ہیش پوسٹ کرتا ہے۔ +- ایک _اسمارٹ کنٹریکٹ_ جو ہیش کو ذخیرہ کرتا ہے اور یہ یقینی بنانے کے لیے کہ اسٹیٹ کی منتقلی جائز ہے، زیرو-نالج پروفس کی تصدیق کرتا ہے۔ + +### ڈیٹا اور کنٹرول فلو {#flows} + +یہ وہ طریقے ہیں جن سے مختلف اجزاء ایک اکاؤنٹ سے دوسرے میں ٹرانسفر کرنے کے لیے مواصلت کرتے ہیں۔ + +1. ایک ویب براؤزر ایک دستخط شدہ ٹرانزیکشن جمع کرتا ہے جس میں دستخط کنندہ کے اکاؤنٹ سے ایک مختلف اکاؤنٹ میں ٹرانسفر کی درخواست کی جاتی ہے۔ + +2. سرور تصدیق کرتا ہے کہ ٹرانزیکشن درست ہے: + + - دستخط کنندہ کے پاس بینک میں کافی بیلنس والا ایک اکاؤنٹ ہے۔ + - وصول کنندہ کا بینک میں ایک اکاؤنٹ ہے۔ + +3. سرور دستخط کنندہ کے بیلنس سے منتقل کی گئی رقم کو گھٹا کر اور اسے وصول کنندہ کے بیلنس میں شامل کرکے نئی اسٹیٹ کا حساب لگاتا ہے۔ + +4. سرور ایک زیرو-نالج پروف کا حساب لگاتا ہے کہ اسٹیٹ کی تبدیلی ایک درست ہے۔ + +5. سرور Ethereum کو ایک ٹرانزیکشن جمع کرتا ہے جس میں شامل ہیں: + + - نئی اسٹیٹ ہیش + - ٹرانزیکشن ہیش (تاکہ ٹرانزیکشن بھیجنے والے کو معلوم ہو کہ اس پر کارروائی ہو چکی ہے) + - زیرو-نالج پروف جو یہ ثابت کرتا ہے کہ نئی اسٹیٹ میں منتقلی درست ہے + +6. اسمارٹ کنٹریکٹ زیرو-نالج پروف کی تصدیق کرتا ہے۔ + +7. اگر زیرو-نالج پروف چیک آؤٹ ہو جاتا ہے، تو اسمارٹ کنٹریکٹ یہ کارروائیاں کرتا ہے: + - موجودہ اسٹیٹ ہیش کو نئی اسٹیٹ ہیش میں اپ ڈیٹ کریں + - نئی اسٹیٹ ہیش اور ٹرانزیکشن ہیش کے ساتھ ایک لاگ انٹری جاری کریں + +### ٹولز {#tools} + +کلائنٹ سائڈ کوڈ کے لیے، ہم [Vite](https://vite.dev/)، [React](https://react.dev/)، [Viem](https://viem.sh/)، اور [Wagmi](https://wagmi.sh/) کا استعمال کرنے جا رہے ہیں۔ یہ انڈسٹری کے معیاری ٹولز ہیں؛ اگر آپ ان سے واقف نہیں ہیں، تو آپ [یہ ٹیوٹوریل](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) استعمال کر سکتے ہیں۔ + +سرور کا زیادہ تر حصہ [Node](https://nodejs.org/en) کا استعمال کرتے ہوئے JavaScript میں لکھا گیا ہے۔ زیرو-نالج کا حصہ [Noir](https://noir-lang.org/) میں لکھا گیا ہے۔ ہمیں ورژن `1.0.0-beta.10` کی ضرورت ہے، لہذا [ہدایت کے مطابق Noir انسٹال کرنے](https://noir-lang.org/docs/getting_started/quick_start) کے بعد، چلائیں: + +``` +noirup -v 1.0.0-beta.10 +``` + +جو بلاک چین ہم استعمال کرتے ہیں وہ `anvil` ہے، جو ایک مقامی ٹیسٹنگ بلاک چین ہے جو [Foundry](https://getfoundry.sh/introduction/installation) کا حصہ ہے۔ + +## عمل درآمد {#implementation} + +چونکہ یہ ایک پیچیدہ نظام ہے، ہم اسے مراحل میں نافذ کریں گے۔ + +### مرحلہ 1 - دستی زیرو نالج {#stage-1} + +پہلے مرحلے کے لیے، ہم براؤزر میں ایک ٹرانزیکشن پر دستخط کریں گے اور پھر دستی طور پر زیرو-نالج پروف کو معلومات فراہم کریں گے۔ زیرو-نالج کوڈ کو یہ معلومات `server/noir/Prover.toml` میں ملنے کی توقع ہے (جس کی دستاویزات [یہاں](https://noir-lang.org/docs/getting_started/project_breakdown#provertoml-1) ہیں)۔ + +اسے عمل میں دیکھنے کے لیے: + +1. یقینی بنائیں کہ آپ کے پاس [Node](https://nodejs.org/en/download) اور [Noir](https://noir-lang.org/install) انسٹال ہیں۔ ترجیحاً، انہیں UNIX سسٹم جیسے macOS، Linux، یا [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) پر انسٹال کریں۔ + +2. مرحلہ 1 کا کوڈ ڈاؤن لوڈ کریں اور کلائنٹ کوڈ کی خدمت کے لیے ویب سرور شروع کریں۔ + + ```sh + git clone https://github.com/qbzzt/250911-zk-bank.git -b 01-manual-zk + cd 250911-zk-bank + cd client + npm install + npm run dev + ``` + + آپ کو یہاں ویب سرور کی ضرورت اس لیے ہے کہ، کچھ قسم کے فراڈ کو روکنے کے لیے، بہت سے والیٹس (جیسے MetaMask) براہ راست ڈسک سے پیش کی گئی فائلوں کو قبول نہیں کرتے ہیں۔ + +3. ایک والیٹ کے ساتھ ایک براؤزر کھولیں۔ + +4. والیٹ میں، ایک نیا پاس فریز درج کریں۔ نوٹ کریں کہ یہ آپ کے موجودہ پاس فریز کو حذف کر دے گا، اس لیے _یقینی بنائیں کہ آپ کے پاس بیک اپ ہے_۔ + + پاس فریز `test test test test test test test test test test test junk` ہے، جو anvil کے لیے ڈیفالٹ ٹیسٹنگ پاس فریز ہے۔ + +5. [کلائنٹ سائڈ کوڈ](http://localhost:5173/) پر براؤز کریں۔ + +6. والیٹ سے جڑیں اور اپنا منزل کا اکاؤنٹ اور رقم منتخب کریں۔ + +7. **دستخط کریں** پر کلک کریں اور ٹرانزیکشن پر دستخط کریں۔ + +8. **Prover.toml** ہیڈنگ کے تحت، آپ کو متن ملے گا۔ `server/noir/Prover.toml` کو اس متن سے تبدیل کریں۔ + +9. زیرو-نالج پروف کو انجام دیں۔ + + ```sh + cd ../server/noir + nargo execute + ``` + + آؤٹ پٹ اس سے ملتا جلتا ہونا چاہیے + + ``` + ori@CryptoDocGuy:~/noir/250911-zk-bank/server/noir$ nargo execute + + [zkBank] Circuit witness successfully solved + [zkBank] Witness saved to target/zkBank.gz + [zkBank] Circuit output: (0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b, 0x0cfc0a67cb7308e4e9b254026b54204e34f6c8b041be207e64c5db77d95dd82d, 0x450cf9da6e180d6159290554ae3d8787, 0x6d8bc5a15b9037e52fb59b6b98722a85) + ``` + +10. آخری دو اقدار کا موازنہ اس ہیش سے کریں جو آپ ویب براؤزر پر دیکھتے ہیں یہ دیکھنے کے لیے کہ آیا پیغام درست طریقے سے ہیش کیا گیا ہے۔ + +#### `server/noir/Prover.toml` {#server-noir-prover-toml} + +[یہ فائل](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) Noir کی طرف سے متوقع معلومات کی شکل دکھاتی ہے۔ + +```toml +message="send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 500 finney (milliEth) 0 " +``` + +پیغام ٹیکسٹ فارمیٹ میں ہے، جو صارف کے لیے سمجھنا آسان بناتا ہے (جو دستخط کرتے وقت ضروری ہے) اور Noir کوڈ کے لیے پارس کرنا۔ رقم فننی میں بتائی گئی ہے تاکہ ایک طرف فریکشنل ٹرانسفرز کو فعال کیا جا سکے، اور دوسری طرف آسانی سے پڑھنے کے قابل ہو۔ آخری نمبر [نونس](https://en.wikipedia.org/wiki/Cryptographic_nonce) ہے۔ + +سٹرنگ 100 حروف طویل ہے۔ زیرو-نالج پروف متغیر سائز کے ڈیٹا کو اچھی طرح سے نہیں سنبھالتے ہیں، اس لیے اکثر ڈیٹا کو پیڈ کرنا ضروری ہوتا ہے۔ + +```toml +pubKeyX=["0x83",...,"0x75"] +pubKeyY=["0x35",...,"0xa5"] +signature=["0xb1",...,"0x0d"] +``` + +یہ تینوں پیرامیٹرز فکسڈ سائز بائٹ ارے ہیں۔ + +```toml +[[accounts]] +address="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +balance=100_000 +nonce=0 + +[[accounts]] +address="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +balance=100_000 +nonce=0 +``` + +یہ ڈھانچوں کی ایک صف کی وضاحت کرنے کا طریقہ ہے۔ ہر اندراج کے لیے، ہم پتہ، بیلنس (ملی ETH عرف میں) بتاتے ہیں۔ [فننی](https://cryptovalleyjournal.com/glossary/finney/))، اور اگلی نونس ویلیو۔ + +#### `client/src/Transfer.tsx` {#client-src-transfer-tsx} + +[یہ فائل](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/client/src/Transfer.tsx) کلائنٹ سائڈ پروسیسنگ کو نافذ کرتی ہے اور `server/noir/Prover.toml` فائل بناتی ہے (جس میں زیرو-نالج پیرامیٹرز شامل ہیں)۔ + +یہاں زیادہ دلچسپ حصوں کی وضاحت ہے۔ + +```tsx +export default attrs => { +``` + +یہ فنکشن `Transfer` React جزو بناتا ہے، جسے دوسری فائلیں امپورٹ کر سکتی ہیں۔ + +```tsx + const accounts = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + ] +``` + +یہ اکاؤنٹ کے پتے ہیں، وہ پتے جو `test ...` سے بنائے گئے ہیں۔ ٹیسٹ جنک` پاس فریز۔ اگر آپ اپنے پتے استعمال کرنا چاہتے ہیں، تو صرف اس تعریف میں ترمیم کریں۔ + +```tsx + const account = useAccount() + const wallet = createWalletClient({ + transport: custom(window.ethereum!) + }) +``` + +یہ [Wagmi ہکس](https://wagmi.sh/react/api/hooks) ہمیں [viem](https://viem.sh/) لائبریری اور والیٹ تک رسائی کی اجازت دیتے ہیں۔ + +```tsx + const message = `send ${toAccount} ${ethAmount*1000} finney (milliEth) ${nonce}`.padEnd(100, " ") +``` + +یہ پیغام ہے، جسے اسپیس سے پیڈ کیا گیا ہے۔ جب بھی [`useState`](https://react.dev/reference/react/useState) متغیرات میں سے کوئی ایک تبدیل ہوتا ہے، تو جزو دوبارہ تیار ہوتا ہے اور `message` اپ ڈیٹ ہو جاتا ہے۔ + +```tsx + const sign = async () => { +``` + +یہ فنکشن اس وقت کال ہوتا ہے جب صارف **دستخط کریں** بٹن پر کلک کرتا ہے۔ پیغام خود بخود اپ ڈیٹ ہو جاتا ہے، لیکن دستخط کے لیے والیٹ میں صارف کی منظوری کی ضرورت ہوتی ہے، اور ہم اسے اس وقت تک نہیں مانگنا چاہتے جب تک ضرورت نہ ہو۔ + +```tsx + const signature = await wallet.signMessage({ + account: fromAccount, + message, + }) +``` + +والیٹ سے [پیغام پر دستخط کرنے](https://viem.sh/docs/accounts/local/signMessage) کے لیے کہیں۔ + +```tsx + const hash = hashMessage(message) +``` + +پیغام کا ہیش حاصل کریں۔ صارف کو ڈیبگنگ (Noir کوڈ کی) کے لیے فراہم کرنا مددگار ہے۔ + +```tsx + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +[پبلک کی حاصل کریں](https://viem.sh/docs/utilities/recoverPublicKey)۔ یہ [Noir `ecrecover`](https://github.com/colinnielsen/ecrecover-noir) فنکشن کے لیے ضروری ہے۔ + +```tsx + setSignature(signature) + setHash(hash) + setPubKey(pubKey) +``` + +اسٹیٹ متغیرات سیٹ کریں۔ ایسا کرنے سے جزو دوبارہ تیار ہوتا ہے (جب `sign` فنکشن ختم ہوتا ہے) اور صارف کو اپ ڈیٹ شدہ اقدار دکھاتا ہے۔ + +```tsx + let proverToml = ` +``` + +`Prover.toml` کے لیے متن۔ + +```tsx +message="${message}" + +pubKeyX=${hexToArray(pubKey.slice(4,4+2*32))} +pubKeyY=${hexToArray(pubKey.slice(4+2*32))} +``` + +Viem ہمیں پبلک کی کو 65 بائٹ کی ہیکساڈیسیمل سٹرنگ کے طور پر فراہم کرتا ہے۔ پہلا بائٹ `0x04` ہے، جو ایک ورژن مارکر ہے۔ اس کے بعد پبلک کی کے `x` کے لیے 32 بائٹس اور پھر پبلک کی کے `y` کے لیے 32 بائٹس آتے ہیں۔ + +تاہم، Noir کو یہ معلومات دو بائٹ ارے کے طور پر حاصل کرنے کی توقع ہے، ایک `x` کے لیے اور ایک `y` کے لیے۔ اسے یہاں کلائنٹ پر پارس کرنا زیرو-نالج پروف کے حصے کے طور پر پارس کرنے سے زیادہ آسان ہے۔ + +نوٹ کریں کہ یہ عام طور پر زیرو-نالج میں ایک اچھی پریکٹس ہے۔ زیرو-نالج پروف کے اندر کا کوڈ مہنگا ہوتا ہے، اس لیے کوئی بھی پروسیسنگ جو زیرو-نالج پروف سے باہر کی جا سکتی ہے _چاہیے_ کہ وہ زیرو-نالج پروف سے باہر کی جائے۔ + +```tsx +signature=${hexToArray(signature.slice(2,-2))} +``` + +دستخط بھی 65 بائٹ کی ہیکساڈیسیمل سٹرنگ کے طور پر فراہم کیا جاتا ہے۔ تاہم، آخری بائٹ صرف پبلک کی کو بازیافت کرنے کے لیے ضروری ہے۔ چونکہ پبلک کی پہلے ہی Noir کوڈ کو فراہم کر دی جائے گی، ہمیں دستخط کی تصدیق کے لیے اس کی ضرورت نہیں ہے، اور Noir کوڈ کو اس کی ضرورت نہیں ہے۔ + +```tsx +${accounts.map(accountInProverToml).reduce((a,b) => a+b, "")} +` +``` + +اکاؤنٹس فراہم کریں۔ + +```tsx + setProverToml(proverToml) + } + + return ( + <> +

Transfer

+``` + +یہ جزو کا HTML (زیادہ درست طور پر، [JSX](https://react.dev/learn/writing-markup-with-jsx)) فارمیٹ ہے۔ + +#### `server/noir/src/main.nr` {#server-noir-src-main-nr} + +[یہ فائل](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/src/main.nr) اصل زیرو-نالج کوڈ ہے۔ + +``` +use std::hash::pedersen_hash; +``` + +[پیڈرسن ہیش](https://rya-sge.github.io/access-denied/2024/05/07/pedersen-hash-function/) [Noir اسٹینڈرڈ لائبریری](https://noir-lang.org/docs/noir/standard_library/cryptographic_primitives/hashes#pedersen_hash) کے ساتھ فراہم کیا گیا ہے۔ زیرو-نالج پروف عام طور پر اس ہیش فنکشن کا استعمال کرتے ہیں۔ اسٹینڈرڈ ہیش فنکشنز کے مقابلے میں [ارتھمیٹک سرکٹس](https://rareskills.io/post/arithmetic-circuit) کے اندر اس کا حساب لگانا بہت آسان ہے۔ + +``` +use keccak256::keccak256; +use dep::ecrecover; +``` + +یہ دو فنکشنز بیرونی لائبریریاں ہیں، جو [`Nargo.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Nargo.toml) میں بیان کی گئی ہیں۔ یہ بالکل وہی ہیں جن کے لیے ان کا نام رکھا گیا ہے، ایک فنکشن جو [keccak256 ہیش](https://emn178.github.io/online-tools/keccak_256.html) کا حساب لگاتا ہے اور ایک فنکشن جو Ethereum دستخطوں کی تصدیق کرتا ہے اور دستخط کنندہ کا Ethereum پتہ بازیافت کرتا ہے۔ + +``` +global ACCOUNT_NUMBER : u32 = 5; +``` + +Noir [Rust](https://www.rust-lang.org/) سے متاثر ہے۔ متغیرات، بطور ڈیفالٹ، مستقل ہوتے ہیں۔ اس طرح ہم عالمی کنفیگریشن مستقلات کی تعریف کرتے ہیں۔ خاص طور پر، `ACCOUNT_NUMBER` ان اکاؤنٹس کی تعداد ہے جنہیں ہم اسٹور کرتے ہیں۔ + +`u` نامی ڈیٹا کی اقسام اس تعداد کے بٹس ہیں، جو غیر دستخط شدہ ہیں۔ صرف معاون اقسام `u8`، `u16`، `u32`، `u64`، اور `u128` ہیں۔ + +``` +global FLAT_ACCOUNT_FIELDS : u32 = 2; +``` + +یہ متغیر اکاؤنٹس کے پیڈرسن ہیش کے لیے استعمال ہوتا ہے، جیسا کہ ذیل میں بیان کیا گیا ہے۔ + +``` +global MESSAGE_LENGTH : u32 = 100; +``` + +جیسا کہ اوپر بیان کیا گیا ہے، پیغام کی لمبائی مقرر ہے۔ یہاں اس کی وضاحت کی گئی ہے۔ + +``` +global ASCII_MESSAGE_LENGTH : [u8; 3] = [0x31, 0x30, 0x30]; +global HASH_BUFFER_SIZE : u32 = 26+3+MESSAGE_LENGTH; +``` + +[EIP-191 دستخط](https://eips.ethereum.org/EIPS/eip-191) کے لیے 26-بائٹ کے سابقے والا ایک بفر درکار ہوتا ہے، اس کے بعد ASCII میں پیغام کی لمبائی، اور آخر میں خود پیغام۔ + +``` +struct Account { + balance: u128, + address: Field, + nonce: u32, +} +``` + +وہ معلومات جو ہم ایک اکاؤنٹ کے بارے میں اسٹور کرتے ہیں۔ [`Field`](https://noir-lang.org/docs/noir/concepts/data_types/fields) ایک نمبر ہے، عام طور پر 253 بٹس تک، جسے براہ راست [ارتھمیٹک سرکٹ](https://rareskills.io/post/arithmetic-circuit) میں استعمال کیا جا سکتا ہے جو زیرو-نالج پروف کو نافذ کرتا ہے۔ یہاں ہم 160 بٹ Ethereum ایڈریس کو اسٹور کرنے کے لیے `Field` کا استعمال کرتے ہیں۔ + +``` +struct TransferTxn { + from: Field, + to: Field, + amount: u128, + nonce: u32 +} +``` + +وہ معلومات جو ہم ٹرانسفر ٹرانزیکشن کے لیے اسٹور کرتے ہیں۔ + +``` +fn flatten_account(account: Account) -> [Field; FLAT_ACCOUNT_FIELDS] { +``` + +ایک فنکشن کی تعریف۔ پیرامیٹر `Account` کی معلومات ہے۔ نتیجہ `Field` متغیرات کی ایک صف ہے، جس کی لمبائی `FLAT_ACCOUNT_FIELDS` ہے + +``` + let flat = [ + account.address, + ((account.balance << 32) + account.nonce.into()).into(), + ]; +``` + +صف میں پہلی قدر اکاؤنٹ کا پتہ ہے۔ دوسرے میں بیلنس اور نونس دونوں شامل ہیں۔ `.into()` کالز ایک نمبر کو اس ڈیٹا کی قسم میں تبدیل کرتی ہیں جس کی اسے ضرورت ہوتی ہے۔ `account.nonce` ایک `u32` قدر ہے، لیکن اسے `account.balance « 32` میں شامل کرنے کے لیے، جو ایک `u128` قدر ہے، اسے `u128` ہونا چاہیے۔ یہ پہلا `.into()` ہے۔ دوسرا `u128` نتیجے کو ایک `Field` میں تبدیل کرتا ہے تاکہ یہ صف میں فٹ ہو سکے۔ + +``` + flat +} +``` + +Noir میں، فنکشنز صرف آخر میں ایک قدر واپس کر سکتے ہیں (کوئی ابتدائی واپسی نہیں ہے)۔ واپسی کی قدر کی وضاحت کرنے کے لیے، آپ اسے فنکشن کے اختتامی بریکٹ سے ٹھیک پہلے جانچتے ہیں۔ + +``` +fn flatten_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] { +``` + +یہ فنکشن اکاؤنٹس کی صف کو ایک `Field` صف میں بدل دیتا ہے، جسے پیٹرسن ہیش کے ان پٹ کے طور پر استعمال کیا جا سکتا ہے۔ + +``` + let mut flat: [Field; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER] = [0; FLAT_ACCOUNT_FIELDS*ACCOUNT_NUMBER]; +``` + +یہ ایک قابل تغیر متغیر کی وضاحت کرنے کا طریقہ ہے، یعنی _نہ کہ_ ایک مستقل۔ Noir میں متغیرات کی ہمیشہ ایک قدر ہونی چاہیے، اس لیے ہم اس متغیر کو تمام صفر پر شروع کرتے ہیں۔ + +``` + for i in 0..ACCOUNT_NUMBER { +``` + +یہ ایک `for` لوپ ہے۔ نوٹ کریں کہ حدود مستقل ہیں۔ Noir لوپس کی حدود کمپائل ٹائم پر معلوم ہونی چاہئیں۔ وجہ یہ ہے کہ ارتھمیٹک سرکٹس فلو کنٹرول کو سپورٹ نہیں کرتے ہیں۔ `for` لوپ پر کارروائی کرتے وقت، کمپائلر صرف اس کے اندر کا کوڈ متعدد بار رکھتا ہے، ہر تکرار کے لیے ایک بار۔ + +``` + let fields = flatten_account(accounts[i]); + for j in 0..FLAT_ACCOUNT_FIELDS { + flat[i*FLAT_ACCOUNT_FIELDS + j] = fields[j]; + } + } + + flat +} + +fn hash_accounts(accounts: [Account; ACCOUNT_NUMBER]) -> Field { + pedersen_hash(flatten_accounts(accounts)) +} +``` + +آخر میں، ہم اس فنکشن پر پہنچ گئے جو اکاؤنٹس کی صف کو ہیش کرتا ہے۔ + +``` +fn find_account(accounts: [Account; ACCOUNT_NUMBER], address: Field) -> u32 { + let mut account : u32 = ACCOUNT_NUMBER; + + for i in 0..ACCOUNT_NUMBER { + if accounts[i].address == address { + account = i; + } + } +``` + +یہ فنکشن ایک مخصوص پتے والا اکاؤنٹ ڈھونڈتا ہے۔ یہ فنکشن معیاری کوڈ میں بہت غیر موثر ہوگا کیونکہ یہ تمام اکاؤنٹس پر تکرار کرتا ہے، یہاں تک کہ جب اسے پتہ مل جاتا ہے۔ + +تاہم، زیرو-نالج پروف میں، کوئی فلو کنٹرول نہیں ہے۔ اگر ہمیں کبھی بھی کسی شرط کو جانچنے کی ضرورت ہوتی ہے، تو ہمیں اسے ہر بار جانچنا پڑتا ہے۔ + +اسی طرح کی چیز `if` بیانات کے ساتھ ہوتی ہے۔ اوپر کے لوپ میں `if` بیان کو ان ریاضیاتی بیانات میں ترجمہ کیا گیا ہے۔ + +_conditionresult = accounts[i].address == address_ // ایک اگر وہ برابر ہیں، ورنہ صفر + +_accountnew = conditionresult\*i + (1-conditionresult)\*accountold_ + +```rust + assert (account < ACCOUNT_NUMBER, f"{address} does not have an account"); + + account +} +``` + +[`assert`](https://noir-lang.org/docs/dev/noir/concepts/assert) فنکشن زیرو-نالج پروف کو کریش کر دیتا ہے اگر دعویٰ غلط ہو۔ اس صورت میں، اگر ہم متعلقہ پتے والا کوئی اکاؤنٹ نہیں ڈھونڈ سکتے ہیں۔ پتے کی اطلاع دینے کے لیے، ہم ایک [فارمیٹ سٹرنگ](https://noir-lang.org/docs/noir/concepts/data_types/strings#format-strings) استعمال کرتے ہیں۔ + +```rust +fn apply_transfer_txn(accounts: [Account; ACCOUNT_NUMBER], txn: TransferTxn) -> [Account; ACCOUNT_NUMBER] { +``` + +یہ فنکشن ایک ٹرانسفر ٹرانزیکشن لاگو کرتا ہے اور نئی اکاؤنٹس کی صف واپس کرتا ہے۔ + +```rust + let from = find_account(accounts, txn.from); + let to = find_account(accounts, txn.to); + + let (txnFrom, txnAmount, txnNonce, accountNonce) = + (txn.from, txn.amount, txn.nonce, accounts[from].nonce); +``` + +ہم Noir میں فارمیٹ سٹرنگ کے اندر ڈھانچے کے عناصر تک رسائی حاصل نہیں کر سکتے، اس لیے ہم ایک قابل استعمال کاپی بناتے ہیں۔ + +```rust + assert (accounts[from].balance >= txn.amount, + f"{txnFrom} does not have {txnAmount} finney"); + + assert (accounts[from].nonce == txn.nonce, + f"Transaction has nonce {txnNonce}, but the account is expected to use {accountNonce}"); +``` + +یہ دو شرائط ہیں جو کسی ٹرانزیکشن کو غلط قرار دے سکتی ہیں۔ + +```rust + let mut newAccounts = accounts; + + newAccounts[from].balance -= txn.amount; + newAccounts[from].nonce += 1; + newAccounts[to].balance += txn.amount; + + newAccounts +} +``` + +نئی اکاؤنٹس کی صف بنائیں اور پھر اسے واپس کریں۔ + +```rust +fn readAddress(messageBytes: [u8; MESSAGE_LENGTH]) -> Field +``` + +یہ فنکشن پیغام سے پتہ پڑھتا ہے۔ + +```rust +{ + let mut result : Field = 0; + + for i in 7..47 { +``` + +پتہ ہمیشہ 20 بائٹس (عرف 40 ہیکساڈیسیمل ہندسوں) لمبا ہوتا ہے، اور کریکٹر #7 سے شروع ہوتا ہے۔ 40 ہیکساڈیسیمل ہندسے) لمبا، اور کریکٹر #7 سے شروع ہوتا ہے۔ + +```rust + result *= 0x10; + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + result += (messageBytes[i]-48).into(); + } + if messageBytes[i] >= 65 & messageBytes[i] <= 70 { // A-F + result += (messageBytes[i]-65+10).into() + } + if messageBytes[i] >= 97 & messageBytes[i] <= 102 { // a-f + result += (messageBytes[i]-97+10).into() + } + } + + result +} + +fn readAmountAndNonce(messageBytes: [u8; MESSAGE_LENGTH]) -> (u128, u32) +``` + +پیغام سے رقم اور نونس پڑھیں۔ + +```rust +{ + let mut amount : u128 = 0; + let mut nonce: u32 = 0; + let mut stillReadingAmount: bool = true; + let mut lookingForNonce: bool = false; + let mut stillReadingNonce: bool = false; +``` + +پیغام میں، پتے کے بعد پہلا نمبر فننی (عرف ہزارواں ETH) کی رقم ہے جسے ٹرانسفر کرنا ہے۔ ETH کا ہزارواں حصہ) ٹرانسفر کرنا ہے۔ دوسرا نمبر نونس ہے۔ ان کے درمیان کوئی بھی متن نظر انداز کر دیا جاتا ہے۔ + +```rust + for i in 48..MESSAGE_LENGTH { + if messageBytes[i] >= 48 & messageBytes[i] <= 57 { // 0-9 + let digit = (messageBytes[i]-48); + + if stillReadingAmount { + amount = amount*10 + digit.into(); + } + + if lookingForNonce { // We just found it + stillReadingNonce = true; + lookingForNonce = false; + } + + if stillReadingNonce { + nonce = nonce*10 + digit.into(); + } + } else { + if stillReadingAmount { + stillReadingAmount = false; + lookingForNonce = true; + } + if stillReadingNonce { + stillReadingNonce = false; + } + } + } + + (amount, nonce) +} +``` + +[ٹیوپل](https://noir-lang.org/docs/noir/concepts/data_types/tuples) واپس کرنا Noir میں ایک فنکشن سے متعدد قدریں واپس کرنے کا طریقہ ہے۔ + +```rust +fn readTransferTxn(message: str) -> TransferTxn +{ + let mut txn: TransferTxn = TransferTxn { from: 0, to: 0, amount:0, nonce:0 }; + let messageBytes = message.as_bytes(); + + txn.to = readAddress(messageBytes); + let (amount, nonce) = readAmountAndNonce(messageBytes); + txn.amount = amount; + txn.nonce = nonce; + + txn +} +``` + +یہ فنکشن پیغام کو بائٹس میں تبدیل کرتا ہے، پھر رقم کو ایک `TransferTxn` میں تبدیل کرتا ہے۔ + +```rust +// Viem کے hashMessage کے برابر +// https://viem.sh/docs/utilities/hashMessage#hashmessage +fn hashMessage(message: str) -> [u8;32] { +``` + +ہم اکاؤنٹس کے لیے پیڈرسن ہیش کا استعمال کرنے کے قابل تھے کیونکہ وہ صرف زیرو-نالج پروف کے اندر ہیش کیے جاتے ہیں۔ تاہم، اس کوڈ میں ہمیں پیغام کے دستخط کی جانچ کرنے کی ضرورت ہے، جو براؤزر کے ذریعے تیار کیا جاتا ہے۔ اس کے لیے، ہمیں [EIP 191](https://eips.ethereum.org/EIPS/eip-191) میں Ethereum دستخطی فارمیٹ کی پیروی کرنے کی ضرورت ہے۔ اس کا مطلب ہے کہ ہمیں ایک معیاری سابقے کے ساتھ ایک مشترکہ بفر بنانے کی ضرورت ہے، ASCII میں پیغام کی لمبائی، اور خود پیغام، اور اسے ہیش کرنے کے لیے Ethereum کے معیاری keccak256 کا استعمال کرنا ہوگا۔ + +```rust + // ASCII prefix + let prefix_bytes = [ + 0x19, // \x19 + 0x45, // 'E' + 0x74, // 't' + 0x68, // 'h' + 0x65, // 'e' + 0x72, // 'r' + 0x65, // 'e' + 0x75, // 'u' + 0x6D, // 'm' + 0x20, // ' ' + 0x53, // 'S' + 0x69, // 'i' + 0x67, // 'g' + 0x6E, // 'n' + 0x65, // 'e' + 0x64, // 'd' + 0x20, // ' ' + 0x4D, // 'M' + 0x65, // 'e' + 0x73, // 's' + 0x73, // 's' + 0x61, // 'a' + 0x67, // 'g' + 0x65, // 'e' + 0x3A, // ':' + 0x0A // '\n' + ]; +``` + +ان صورتوں سے بچنے کے لیے جہاں کوئی ایپلیکیشن صارف سے کسی ایسے پیغام پر دستخط کرنے کو کہتی ہے جسے ٹرانزیکشن کے طور پر یا کسی اور مقصد کے لیے استعمال کیا جا سکتا ہے، EIP 191 یہ بتاتا ہے کہ تمام دستخط شدہ پیغامات کریکٹر 0x19 (ایک درست ASCII کریکٹر نہیں) سے شروع ہوتے ہیں جس کے بعد `Ethereum Signed Message:` اور ایک نئی لائن آتی ہے۔ + +```rust + let mut buffer: [u8; HASH_BUFFER_SIZE] = [0u8; HASH_BUFFER_SIZE]; + for i in 0..26 { + buffer[i] = prefix_bytes[i]; + } + + let messageBytes : [u8; MESSAGE_LENGTH] = message.as_bytes(); + + if MESSAGE_LENGTH <= 9 { + for i in 0..1 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+1] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 10 & MESSAGE_LENGTH <= 99 { + for i in 0..2 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+2] = messageBytes[i]; + } + } + + if MESSAGE_LENGTH >= 100 { + for i in 0..3 { + buffer[i+26] = ASCII_MESSAGE_LENGTH[i]; + } + + for i in 0..MESSAGE_LENGTH { + buffer[i+26+3] = messageBytes[i]; + } + } + + assert(MESSAGE_LENGTH < 1000, "Messages whose length is over three digits are not supported"); +``` + +999 تک کی پیغام کی لمبائی کو سنبھالیں اور اگر یہ اس سے زیادہ ہو تو ناکام ہو جائیں۔ میں نے یہ کوڈ شامل کیا، حالانکہ پیغام کی لمبائی ایک مستقل ہے، کیونکہ اس سے اسے تبدیل کرنا آسان ہو جاتا ہے۔ پروڈکشن سسٹم پر، آپ شاید صرف یہ فرض کریں گے کہ `MESSAGE_LENGTH` بہتر کارکردگی کی خاطر تبدیل نہیں ہوتا ہے۔ + +```rust + keccak256::keccak256(buffer, HASH_BUFFER_SIZE) +} +``` + +Ethereum کے معیاری `keccak256` فنکشن کا استعمال کریں۔ + +```rust +fn signatureToAddressAndHash( + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64] + ) -> (Field, Field, Field) // address, first 16 bytes of hash, last 16 bytes of hash +{ +``` + +یہ فنکشن دستخط کی تصدیق کرتا ہے، جس کے لیے پیغام کا ہیش درکار ہوتا ہے۔ پھر یہ ہمیں وہ پتہ فراہم کرتا ہے جس نے اس پر دستخط کیا اور پیغام کا ہیش۔ پیغام کا ہیش دو `Field` اقدار میں فراہم کیا جاتا ہے کیونکہ پروگرام کے باقی حصوں میں بائٹ ارے کے مقابلے میں ان کا استعمال آسان ہے۔ + +ہمیں دو `Field` اقدار کا استعمال کرنے کی ضرورت ہے کیونکہ فیلڈ کے حسابات ایک بڑی تعداد کے [ماڈیولو](https://en.wikipedia.org/wiki/Modulo) کیے جاتے ہیں، لیکن وہ تعداد عام طور پر 256 بٹس سے کم ہوتی ہے (ورنہ EVM میں ان حسابات کو انجام دینا مشکل ہوگا)۔ + +```rust + let hash = hashMessage(message); + + let mut (hash1, hash2) = (0,0); + + for i in 0..16 { + hash1 = hash1*256 + hash[31-i].into(); + hash2 = hash2*256 + hash[15-i].into(); + } +``` + +`hash1` اور `hash2` کو قابل تغیر متغیرات کے طور پر بیان کریں، اور ہیش کو بائٹ بائٹ کر کے ان میں لکھیں۔ + +```rust + ( + ecrecover::ecrecover(pubKeyX, pubKeyY, signature, hash), +``` + +یہ [سولیڈٹی کے `ecrecover`](https://docs.soliditylang.org/en/v0.8.30/cheatsheet.html#mathematical-and-cryptographic-functions) سے ملتا جلتا ہے، دو اہم فرقوں کے ساتھ: + +- اگر دستخط درست نہیں ہے، تو کال ایک `assert` ناکام ہو جاتی ہے اور پروگرام ختم ہو جاتا ہے۔ +- جبکہ پبلک کی کو دستخط اور ہیش سے بازیافت کیا جا سکتا ہے، یہ ایک ایسی پروسیسنگ ہے جو بیرونی طور پر کی جا سکتی ہے اور، اس لیے، زیرو-نالج پروف کے اندر کرنے کے قابل نہیں ہے۔ اگر کوئی یہاں ہمیں دھوکہ دینے کی کوشش کرتا ہے، تو دستخط کی تصدیق ناکام ہو جائے گی۔ + +```rust + hash1, + hash2 + ) +} + +fn main( + accounts: [Account; ACCOUNT_NUMBER], + message: str, + pubKeyX: [u8; 32], + pubKeyY: [u8; 32], + signature: [u8; 64], + ) -> pub ( + Field, // Hash of old accounts array + Field, // Hash of new accounts array + Field, // First 16 bytes of message hash + Field, // Last 16 bytes of message hash + ) +``` + +آخر میں، ہم `main` فنکشن تک پہنچتے ہیں۔ ہمیں یہ ثابت کرنے کی ضرورت ہے کہ ہمارے پاس ایک ٹرانزیکشن ہے جو اکاؤنٹس کے ہیش کو پرانی قدر سے نئی میں درست طریقے سے تبدیل کرتا ہے۔ ہمیں یہ بھی ثابت کرنے کی ضرورت ہے کہ اس کا یہ مخصوص ٹرانزیکشن ہیش ہے تاکہ جس شخص نے اسے بھیجا ہے اسے معلوم ہو کہ اس کے ٹرانزیکشن پر کارروائی ہو چکی ہے۔ + +```rust +{ + let mut txn = readTransferTxn(message); +``` + +ہمیں `txn` کو قابل تغیر ہونے کی ضرورت ہے کیونکہ ہم پیغام سے سے پتہ نہیں پڑھتے ہیں، ہم اسے دستخط سے پڑھتے ہیں۔ + +```rust + let (fromAddress, txnHash1, txnHash2) = signatureToAddressAndHash( + message, + pubKeyX, + pubKeyY, + signature); + + txn.from = fromAddress; + + let newAccounts = apply_transfer_txn(accounts, txn); + + ( + hash_accounts(accounts), + hash_accounts(newAccounts), + txnHash1, + txnHash2 + ) +} +``` + +### مرحلہ 2 - ایک سرور شامل کرنا {#stage-2} + +دوسرے مرحلے میں، ہم ایک سرور شامل کرتے ہیں جو براؤزر سے ٹرانسفر ٹرانزیکشنز وصول کرتا ہے اور ان کو نافذ کرتا ہے۔ + +اسے عمل میں دیکھنے کے لیے: + +1. اگر Vite چل رہا ہے تو اسے روک دیں۔ + +2. وہ برانچ ڈاؤن لوڈ کریں جس میں سرور شامل ہے اور یقینی بنائیں کہ آپ کے پاس تمام ضروری ماڈیولز ہیں۔ + + ```sh + git checkout 02-add-server + cd client + npm install + cd ../server + npm install + ``` + + Noir کوڈ کو کمپائل کرنے کی ضرورت نہیں ہے، یہ وہی کوڈ ہے جو آپ نے مرحلہ 1 کے لیے استعمال کیا تھا۔ + +3. سرور شروع کریں۔ + + ```sh + npm run start + ``` + +4. ایک الگ کمانڈ لائن ونڈو میں، براؤزر کوڈ کی خدمت کے لیے Vite چلائیں۔ + + ```sh + cd client + npm run dev + ``` + +5. کلائنٹ کوڈ پر براؤز کریں [http://localhost:5173](http://localhost:5173) پر + +6. کسی ٹرانزیکشن کو جاری کرنے سے پہلے، آپ کو نونس کے ساتھ ساتھ وہ رقم بھی جاننے کی ضرورت ہے جو آپ بھیج سکتے ہیں۔ یہ معلومات حاصل کرنے کے لیے، **اکاؤنٹ ڈیٹا اپ ڈیٹ کریں** پر کلک کریں اور پیغام پر دستخط کریں۔ + + ہمارے پاس یہاں ایک مخمصہ ہے۔ ایک طرف، ہم کسی ایسے پیغام پر دستخط نہیں کرنا چاہتے جسے دوبارہ استعمال کیا جا سکے ([ری پلے حملہ](https://en.wikipedia.org/wiki/Replay_attack))، یہی وجہ ہے کہ ہم سب سے پہلے ایک نونس چاہتے ہیں۔ تاہم، ہمارے پاس ابھی تک کوئی نونس نہیں ہے۔ حل یہ ہے کہ ایک ایسا نونس منتخب کیا جائے جسے صرف ایک بار استعمال کیا جا سکے اور جو ہمارے پاس دونوں طرف پہلے سے موجود ہو، جیسے کہ موجودہ وقت۔ + + اس حل کے ساتھ مسئلہ یہ ہے کہ وقت بالکل ہم آہنگ نہیں ہو سکتا ہے۔ اس کے بجائے، ہم ایک ایسی قدر پر دستخط کرتے ہیں جو ہر منٹ بدلتی ہے۔ اس کا مطلب ہے کہ ری پلے حملوں کے لیے ہماری کمزوری کی کھڑکی زیادہ سے زیادہ ایک منٹ ہے۔ یہ دیکھتے ہوئے کہ پروڈکشن میں دستخط شدہ درخواست TLS کے ذریعے محفوظ کی جائے گی، اور یہ کہ سرنگ کا دوسرا رخ — سرور — پہلے ہی بیلنس اور نونس کا انکشاف کر سکتا ہے (اسے کام کرنے کے لیے انہیں جاننا ہوگا)، یہ ایک قابل قبول خطرہ ہے۔ + +7. ایک بار جب براؤزر بیلنس اور نونس واپس حاصل کر لیتا ہے، تو یہ ٹرانسفر فارم دکھاتا ہے۔ منزل کا پتہ اور رقم منتخب کریں اور **ٹرانسفر کریں** پر کلک کریں۔ اس درخواست پر دستخط کریں۔ + +8. ٹرانسفر دیکھنے کے لیے، یا تو **اکاؤنٹ ڈیٹا اپ ڈیٹ کریں** یا اس ونڈو میں دیکھیں جہاں آپ سرور چلاتے ہیں۔ سرور ہر بار جب یہ تبدیل ہوتا ہے تو اسٹیٹ کو لاگ کرتا ہے۔ + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + Listening on port 3000 + Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 36000 finney (milliEth) 0 processed + New state: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 64000 (1) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 100000 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 136000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0) + Txn send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 7200 finney (milliEth) 1 processed + New state: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 56800 (2) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 107200 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 136000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0) + Txn send 0x90F79bf6EB2c4f870365E785982E1f101E93b906 3000 finney (milliEth) 2 processed + New state: + 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 has 53800 (3) + 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 has 107200 (0) + 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC has 100000 (0) + 0x90F79bf6EB2c4f870365E785982E1f101E93b906 has 139000 (0) + 0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65 has 100000 (0) + ``` + +#### `server/index.mjs` {#server-index-mjs-1} + +[یہ فائل](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/index.mjs) سرور کے عمل پر مشتمل ہے، اور [`main.nr`](https://github.com/qbzzt/250911-zk-bank/blob/02-add-server/server/noir/src/main.nr) پر Noir کوڈ کے ساتھ تعامل کرتی ہے۔ یہاں دلچسپ حصوں کی وضاحت ہے۔ + +```js +import { Noir } from '@noir-lang/noir_js' +``` + +[noir.js](https://www.npmjs.com/package/@noir-lang/noir_js) لائبریری JavaScript کوڈ اور Noir کوڈ کے درمیان انٹرفیس کرتی ہے۔ + +```js +const circuit = JSON.parse(await fs.readFile("./noir/target/zkBank.json")) +const noir = new Noir(circuit) +``` + +ارتھمیٹک سرکٹ لوڈ کریں — وہ کمپائل شدہ Noir پروگرام جو ہم نے پچھلے مرحلے میں بنایا تھا — اور اسے چلانے کے لیے تیار کریں۔ + +```js +// We only provide account information in return to a signed request +const accountInformation = async signature => { + const fromAddress = await recoverAddress({ + hash: hashMessage("Get account data " + Math.floor((new Date().getTime())/60000)), + signature + }) +``` + +اکاؤنٹ کی معلومات فراہم کرنے کے لیے، ہمیں صرف دستخط کی ضرورت ہے۔ وجہ یہ ہے کہ ہم پہلے ہی جانتے ہیں کہ پیغام کیا ہوگا، اور اس لیے پیغام کا ہیش۔ + +```js +const processMessage = async (message, signature) => { +``` + +ایک پیغام پر کارروائی کریں اور اس ٹرانزیکشن کو انجام دیں جسے یہ انکوڈ کرتا ہے۔ + +```js + // Get the public key + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +اب جب کہ ہم سرور پر JavaScript چلاتے ہیں، ہم کلائنٹ کے بجائے وہاں سے پبلک کی بازیافت کر سکتے ہیں۔ + +```js + let noirResult + try { + noirResult = await noir.execute({ + message, + signature: signature.slice(2,-2).match(/.{2}/g).map(x => `0x${x}`), + pubKeyX, + pubKeyY, + accounts: Accounts + }) +``` + +`noir.execute` Noir پروگرام چلاتا ہے۔ پیرامیٹرز ان کے برابر ہیں جو [`Prover.toml`](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) میں فراہم کیے گئے ہیں۔ نوٹ کریں کہ لمبی قدریں ہیکساڈیسیمل سٹرنگز کی ایک صف کے طور پر فراہم کی جاتی ہیں (`["0x60", "0xA7"]`)، نہ کہ ایک ہی ہیکساڈیسیمل قدر (`0x60A7`) کے طور پر، جس طرح Viem کرتا ہے۔ + +```js + } catch (err) { + console.log(`Noir error: ${err}`) + throw Error("Invalid transaction, not processed") + } +``` + +اگر کوئی خرابی ہو تو اسے پکڑیں اور پھر کلائنٹ کو ایک آسان ورژن ریلے کریں۔ + +```js + Accounts[fromAccountNumber].nonce++ + Accounts[fromAccountNumber].balance -= amount + Accounts[toAccountNumber].balance += amount +``` + +ٹرانزیکشن لاگو کریں۔ ہم نے اسے پہلے ہی Noir کوڈ میں کر دیا ہے، لیکن اسے یہاں دوبارہ کرنا اس سے نتیجہ نکالنے سے زیادہ آسان ہے۔ + +```js +let Accounts = [ + { + address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + balance: 5000, + nonce: 0, + }, +``` + +ابتدائی `Accounts` کی ساخت۔ + +### مرحلہ 3 - Ethereum اسمارٹ کنٹریکٹس {#stage-3} + +1. سرور اور کلائنٹ کے عمل کو روک دیں۔ + +2. اسمارٹ کنٹریکٹس کے ساتھ برانچ ڈاؤن لوڈ کریں اور یقینی بنائیں کہ آپ کے پاس تمام ضروری ماڈیولز ہیں۔ + + ```sh + git checkout 03-smart-contracts + cd client + npm install + cd ../server + npm install + ``` + +3. ایک الگ کمانڈ لائن ونڈو میں `anvil` چلائیں۔ + +4. تصدیقی کلید اور سولیڈٹی تصدیق کنندہ تیار کریں، پھر تصدیق کنندہ کوڈ کو سولیڈٹی پروجیکٹ میں کاپی کریں۔ + + ```sh + cd noir + bb write_vk -b ./target/zkBank.json -o ./target --oracle_hash keccak + bb write_solidity_verifier -k ./target/vk -o ./target/Verifier.sol + cp target/Verifier.sol ../../smart-contracts/src + ``` + +5. اسمارٹ کنٹریکٹس پر جائیں اور `anvil` بلاک چین استعمال کرنے کے لیے ماحولیاتی متغیرات سیٹ کریں۔ + + ```sh + cd ../../smart-contracts + export ETH_RPC_URL=http://localhost:8545 + ETH_PRIVATE_KEY=ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + ``` + +6. `Verifier.sol` کو تعینات کریں اور پتے کو ایک ماحولیاتی متغیر میں ذخیرہ کریں۔ + + ```sh + VERIFIER_ADDRESS=`forge create src/Verifier.sol:HonkVerifier --private-key $ETH_PRIVATE_KEY --optimize --broadcast | awk '/Deployed to:/ {print $3}'` + echo $VERIFIER_ADDRESS + ``` + +7. `ZkBank` کنٹریکٹ کو تعینات کریں۔ + + ```sh + ZKBANK_ADDRESS=`forge create ZkBank --private-key $ETH_PRIVATE_KEY --broadcast --constructor-args $VERIFIER_ADDRESS 0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b | awk '/Deployed to:/ {print $3}'` + echo $ZKBANK_ADDRESS + ``` + + `0x199..67b` قدر `Accounts` کی ابتدائی اسٹیٹ کا پیڈرسن ہیش ہے۔ اگر آپ `server/index.mjs` میں اس ابتدائی اسٹیٹ میں ترمیم کرتے ہیں، تو آپ زیرو-نالج پروف کے ذریعے رپورٹ کردہ ابتدائی ہیش کو دیکھنے کے لیے ایک ٹرانزیکشن چلا سکتے ہیں۔ + +8. سرور چلائیں۔ + + ```sh + cd ../server + npm run start + ``` + +9. کلائنٹ کو ایک مختلف کمانڈ لائن ونڈو میں چلائیں۔ + + ```sh + cd client + npm run dev + ``` + +10. کچھ ٹرانزیکشنز چلائیں۔ + +11. یہ تصدیق کرنے کے لیے کہ اسٹیٹ آن چین تبدیل ہو گئی ہے، سرور کے عمل کو دوبارہ شروع کریں۔ دیکھیں کہ `ZkBank` اب ٹرانزیکشنز قبول نہیں کرتا ہے، کیونکہ ٹرانزیکشنز میں اصل ہیش ویلیو آن چین ذخیرہ شدہ ہیش ویلیو سے مختلف ہے۔ + + یہ متوقع غلطی کی قسم ہے۔ + + ``` + ori@CryptoDocGuy:~/x/250911-zk-bank/server$ npm run start + + > server@1.0.0 start + > node --experimental-json-modules index.mjs + + Listening on port 3000 + Verification error: ContractFunctionExecutionError: The contract function "processTransaction" reverted with the following reason: + Wrong old state hash + + Contract Call: + address: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 + function: processTransaction(bytes _proof, bytes32[] _publicInputs) + args: (0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf00000000000000000000000000000000000000000000000b75c020998797da7800000000000000000000000000000000000000000000000 + ``` + +#### `server/index.mjs` {#server-index-mjs-2} + +اس فائل میں تبدیلیاں زیادہ تر اصل پروف بنانے اور اسے آن چین جمع کرنے سے متعلق ہیں۔ + +```js +import { exec } from 'child_process' +import util from 'util' + +const execPromise = util.promisify(exec) +``` + +ہمیں آن چین بھیجنے کے لیے اصل پروف بنانے کے لیے [Barretenberg پیکیج](https://github.com/AztecProtocol/aztec-packages/tree/next/barretenberg) کا استعمال کرنے کی ضرورت ہے۔ ہم اس پیکیج کو یا تو کمانڈ لائن انٹرفیس (`bb`) چلا کر یا [JavaScript لائبریری، `bb.js`](https://www.npmjs.com/package/@aztec/bb.js) کا استعمال کر کے استعمال کر سکتے ہیں۔ JavaScript لائبریری مقامی طور پر کوڈ چلانے سے بہت سست ہے، اس لیے ہم یہاں کمانڈ لائن استعمال کرنے کے لیے [`exec`](https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback) کا استعمال کرتے ہیں۔ + +نوٹ کریں کہ اگر آپ `bb.js` استعمال کرنے کا فیصلہ کرتے ہیں، تو آپ کو ایک ایسا ورژن استعمال کرنے کی ضرورت ہے جو آپ کے استعمال کردہ Noir کے ورژن کے ساتھ مطابقت رکھتا ہو۔ لکھنے کے وقت، موجودہ Noir ورژن (1.0.0-beta.11) `bb.js` ورژن 0.87 استعمال کرتا ہے۔ + +```js +const zkBankAddress = process.env.ZKBANK_ADDRESS || "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" +``` + +یہاں کا پتہ وہ ہے جو آپ کو ملتا ہے جب آپ ایک صاف `anvil` سے شروع کرتے ہیں اور اوپر دی گئی ہدایات پر عمل کرتے ہیں۔ + +```js +const walletClient = createWalletClient({ + chain: anvil, + transport: http(), + account: privateKeyToAccount("0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6") +}) +``` + +یہ نجی کلید `anvil` میں ڈیفالٹ پہلے سے فنڈ شدہ اکاؤنٹس میں سے ایک ہے۔ + +```js +const generateProof = async (witness, fileID) => { +``` + +`bb` قابل عمل کا استعمال کرتے ہوئے ایک پروف تیار کریں۔ + +```js + const fname = `witness-${fileID}.gz` + await fs.writeFile(fname, witness) +``` + +گواہ کو ایک فائل میں لکھیں۔ + +```js + await execPromise(`bb prove -b ./noir/target/zkBank.json -w ${fname} -o ${fileID} --oracle_hash keccak --output_format fields`) +``` + +اصل میں پروف بنائیں۔ یہ مرحلہ عوامی متغیرات کے ساتھ ایک فائل بھی بناتا ہے، لیکن ہمیں اس کی ضرورت نہیں ہے۔ ہمیں وہ متغیرات پہلے ہی `noir.execute` سے مل گئے ہیں۔ + +```js + const proof = "0x" + JSON.parse(await fs.readFile(`./${fileID}/proof_fields.json`)).reduce((a,b) => a+b, "").replace(/0x/g, "") +``` + +پروف `Field` اقدار کی ایک JSON صف ہے، ہر ایک کو ایک ہیکساڈیسیمل قدر کے طور پر پیش کیا جاتا ہے۔ تاہم، ہمیں اسے ٹرانزیکشن میں ایک ہی `bytes` قدر کے طور پر بھیجنے کی ضرورت ہے، جسے Viem ایک بڑی ہیکساڈیسیمل سٹرنگ سے ظاہر کرتا ہے۔ یہاں ہم تمام اقدار کو جوڑ کر، تمام `0x` کو ہٹا کر، اور پھر آخر میں ایک شامل کر کے فارمیٹ کو تبدیل کرتے ہیں۔ + +```js + await execPromise(`rm -r ${fname} ${fileID}`) + + return proof +} +``` + +صفائی کریں اور پروف واپس کریں۔ + +```js +const processMessage = async (message, signature) => { + . + . + . + + const publicFields = noirResult.returnValue.map(x=>'0x' + x.slice(2).padStart(64, "0")) +``` + +عوامی فیلڈز کو 32-بائٹ اقدار کی ایک صف ہونے کی ضرورت ہے۔ تاہم، چونکہ ہمیں ٹرانزیکشن ہیش کو دو `Field` اقدار کے درمیان تقسیم کرنے کی ضرورت تھی، یہ 16 بائٹ کی قدر کے طور پر ظاہر ہوتا ہے۔ یہاں ہم صفر شامل کرتے ہیں تاکہ Viem سمجھ جائے کہ یہ دراصل 32 بائٹس ہے۔ + +```js + const proof = await generateProof(noirResult.witness, `${fromAddress}-${nonce}`) +``` + +ہر پتہ ہر نونس کو صرف ایک بار استعمال کرتا ہے تاکہ ہم گواہ فائل اور آؤٹ پٹ ڈائرکٹری کے لیے ایک منفرد شناخت کنندہ کے طور پر `fromAddress` اور `nonce` کے امتزاج کا استعمال کر سکیں۔ + +```js + try { + await zkBank.write.processTransaction([ + proof, publicFields]) + } catch (err) { + console.log(`Verification error: ${err}`) + throw Error("Can't verify the transaction onchain") + } + . + . + . +} +``` + +ٹرانزیکشن کو چین پر بھیجیں۔ + +#### `smart-contracts/src/ZkBank.sol` {#smart-contracts-src-zkbank-sol} + +یہ آن چین کوڈ ہے جو ٹرانزیکشن وصول کرتا ہے۔ + +```solidity +// SPDX-License-Identifier: MIT + +pragma solidity >=0.8.21; + +import {HonkVerifier} from "./Verifier.sol"; + +contract ZkBank { + HonkVerifier immutable myVerifier; + bytes32 currentStateHash; + + constructor(address _verifierAddress, bytes32 _initialStateHash) { + currentStateHash = _initialStateHash; + myVerifier = HonkVerifier(_verifierAddress); + } +``` + +آن چین کوڈ کو دو متغیرات کا ٹریک رکھنے کی ضرورت ہے: تصدیق کنندہ (ایک الگ کنٹریکٹ جو `nargo` کے ذریعے بنایا گیا ہے) اور موجودہ اسٹیٹ ہیش۔ + +```solidity + event TransactionProcessed( + bytes32 indexed transactionHash, + bytes32 oldStateHash, + bytes32 newStateHash + ); +``` + +جب بھی اسٹیٹ تبدیل ہوتی ہے، ہم ایک `TransactionProcessed` ایونٹ جاری کرتے ہیں۔ + +```solidity + function processTransaction( + bytes calldata _proof, + bytes32[] calldata _publicFields + ) public { +``` + +یہ فنکشن ٹرانزیکشنز پر کارروائی کرتا ہے۔ یہ پروف (`bytes` کے طور پر) اور عوامی ان پٹس (`bytes32` ارے کے طور پر) حاصل کرتا ہے، اس فارمیٹ میں جس کی تصدیق کنندہ کو ضرورت ہوتی ہے (آن چین پروسیسنگ اور اس لیے گیس کے اخراجات کو کم کرنے کے لیے)۔ + +```solidity + require(_publicInputs[0] == currentStateHash, + "Wrong old state hash"); +``` + +زیرو-نالج پروف یہ ہونا چاہیے کہ ٹرانزیکشن ہمارے موجودہ ہیش سے ایک نئے میں تبدیل ہوتا ہے۔ + +```solidity + myVerifier.verify(_proof, _publicFields); +``` + +زیرو-نالج پروف کی تصدیق کے لیے تصدیق کنندہ کنٹریکٹ کو کال کریں۔ یہ مرحلہ ٹرانزیکشن کو واپس کر دیتا ہے اگر زیرو-نالج پروف غلط ہو۔ + +```solidity + currentStateHash = _publicFields[1]; + + emit TransactionProcessed( + _publicFields[2]<<128 | _publicFields[3], + _publicFields[0], + _publicFields[1] + ); + } +} +``` + +اگر سب کچھ ٹھیک ہو جاتا ہے، تو اسٹیٹ ہیش کو نئی قدر میں اپ ڈیٹ کریں اور ایک `TransactionProcessed` ایونٹ جاری کریں۔ + +## مرکزی جزو کے ذریعے بدسلوکی {#abuses} + +انفارمیشن سیکیورٹی تین خصوصیات پر مشتمل ہے: + +- _رازداری_، صارفین وہ معلومات نہیں پڑھ سکتے جو وہ پڑھنے کے مجاز نہیں ہیں۔ +- _انٹیگریٹی_، معلومات کو مجاز صارفین کے علاوہ مجاز طریقے سے تبدیل نہیں کیا جا سکتا۔ +- _دستیابی_، مجاز صارفین سسٹم کا استعمال کر سکتے ہیں۔ + +اس سسٹم پر، انٹیگریٹی زیرو-نالج پروف کے ذریعے فراہم کی جاتی ہے۔ دستیابی کی ضمانت دینا بہت مشکل ہے، اور رازداری ناممکن ہے، کیونکہ بینک کو ہر اکاؤنٹ کا بیلنس اور تمام ٹرانزیکشنز جاننے کی ضرورت ہے۔ کسی ایسی ہستی کو روکنے کا کوئی طریقہ نہیں ہے جس کے پاس معلومات ہوں وہ اس معلومات کو بانٹنے سے۔ + +[اسٹیلتھ ایڈریسز](https://vitalik.eth.limo/general/2023/01/20/stealth.html) کا استعمال کرتے ہوئے ایک حقیقی خفیہ بینک بنانا ممکن ہو سکتا ہے، لیکن یہ اس مضمون کے دائرہ کار سے باہر ہے۔ + +### غلط معلومات {#false-info} + +ایک طریقہ جس سے سرور انٹیگریٹی کی خلاف ورزی کر سکتا ہے وہ یہ ہے کہ جب [ڈیٹا کی درخواست کی جاتی ہے](https://github.com/qbzzt/250911-zk-bank/blob/03-smart-contracts/server/index.mjs#L278-L291) تو غلط معلومات فراہم کی جائیں۔ + +اسے حل کرنے کے لیے، ہم ایک دوسرا Noir پروگرام لکھ سکتے ہیں جو اکاؤنٹس کو ایک نجی ان پٹ کے طور پر اور اس پتے کو جس کے لیے معلومات کی درخواست کی گئی ہے ایک عوامی ان پٹ کے طور پر وصول کرتا ہے۔ آؤٹ پٹ اس پتے کا بیلنس اور نونس، اور اکاؤنٹس کا ہیش ہے۔ + +یقیناً، اس پروف کی تصدیق آن چین نہیں کی جا سکتی، کیونکہ ہم آن چین پر نونس اور بیلنس پوسٹ نہیں کرنا چاہتے۔ تاہم، اس کی تصدیق براؤزر میں چلنے والے کلائنٹ کوڈ کے ذریعے کی جا سکتی ہے۔ + +### جبری ٹرانزیکشنز {#forced-txns} + +L2s پر دستیابی کو یقینی بنانے اور سنسرشپ کو روکنے کا معمول کا طریقہ [جبری ٹرانزیکشنز](https://docs.optimism.io/stack/transactions/forced-transaction) ہے۔ لیکن جبری ٹرانزیکشنز زیرو-نالج پروف کے ساتھ نہیں ملتے ہیں۔ سرور وہ واحد ہستی ہے جو ٹرانزیکشنز کی تصدیق کر سکتی ہے۔ + +ہم جبری ٹرانزیکشنز کو قبول کرنے کے لیے `smart-contracts/src/ZkBank.sol` میں ترمیم کر سکتے ہیں اور سرور کو اس وقت تک اسٹیٹ کو تبدیل کرنے سے روک سکتے ہیں جب تک کہ ان پر کارروائی نہ ہو جائے۔ تاہم، یہ ہمیں ایک سادہ denial-of-service حملے کے لیے کھول دیتا ہے۔ کیا ہوگا اگر کوئی جبری ٹرانزیکشن غلط ہو اور اس لیے اس پر کارروائی کرنا ناممکن ہو؟ + +حل یہ ہے کہ ایک زیرو-نالج پروف ہو کہ ایک جبری ٹرانزیکشن غلط ہے۔ یہ سرور کو تین اختیارات دیتا ہے: + +- جبری ٹرانزیکشن پر کارروائی کریں، یہ ثابت کرنے کے لیے ایک زیرو-نالج پروف فراہم کریں کہ اس پر کارروائی ہو چکی ہے اور نئی اسٹیٹ ہیش۔ +- جبری ٹرانزیکشن کو مسترد کریں، اور کنٹریکٹ کو ایک زیرو-نالج پروف فراہم کریں کہ ٹرانزیکشن غلط ہے (نامعلوم پتہ، خراب نونس، یا ناکافی بیلنس)۔ +- جبری ٹرانزیکشن کو نظر انداز کریں۔ سرور کو اصل میں ٹرانزیکشن پر کارروائی کرنے پر مجبور کرنے کا کوئی طریقہ نہیں ہے، لیکن اس کا مطلب ہے کہ پورا نظام دستیاب نہیں ہے۔ + +#### دستیابی بانڈز {#avail-bonds} + +حقیقی زندگی کے نفاذ میں، سرور کو چلانے کے لیے شاید کسی قسم کا منافع کا محرک ہوگا۔ ہم سرور سے ایک دستیابی بانڈ پوسٹ کروا کر اس ترغیب کو مضبوط کر سکتے ہیں جسے کوئی بھی جلا سکتا ہے اگر ایک جبری ٹرانزیکشن پر ایک مخصوص مدت کے اندر کارروائی نہ کی جائے۔ + +### خراب Noir کوڈ {#bad-noir-code} + +عام طور پر، لوگوں کو ایک اسمارٹ کنٹریکٹ پر بھروسہ دلانے کے لیے ہم سورس کوڈ کو [بلاک ایکسپلورر](https://eth.blockscout.com/address/0x7D16d2c4e96BCFC8f815E15b771aC847EcbDB48b?tab=contract) پر اپ لوڈ کرتے ہیں۔ تاہم، زیرو-نالج پروف کے معاملے میں، یہ ناکافی ہے۔ + +`Verifier.sol` میں تصدیقی کلید ہوتی ہے، جو Noir پروگرام کا ایک فنکشن ہے۔ تاہم، وہ کلید ہمیں یہ نہیں بتاتی کہ Noir پروگرام کیا تھا۔ اصل میں ایک قابل اعتماد حل کے لیے، آپ کو Noir پروگرام (اور وہ ورژن جس نے اسے بنایا ہے) اپ لوڈ کرنے کی ضرورت ہے۔ ورنہ، زیرو-نالج پروف ایک مختلف پروگرام کی عکاسی کر سکتے ہیں، جس میں ایک بیک ڈور ہو۔ + +جب تک بلاک ایکسپلورر ہمیں Noir پروگرامز کو اپ لوڈ کرنے اور تصدیق کرنے کی اجازت دینا شروع نہیں کرتے، آپ کو یہ خود کرنا چاہیے (ترجیحاً [IPFS](/developers/tutorials/ipfs-decentralized-ui/) پر)۔ پھر نفیس صارفین سورس کوڈ ڈاؤن لوڈ کرنے، اسے خود کمپائل کرنے، `Verifier.sol` بنانے، اور یہ تصدیق کرنے کے قابل ہوں گے کہ یہ آن چین والے سے یکساں ہے۔ + +## نتیجہ {#conclusion} + +پلازما قسم کی ایپلی کیشنز کو معلومات کے ذخیرہ کے طور پر ایک مرکزی جزو کی ضرورت ہوتی ہے۔ یہ ممکنہ کمزوریوں کو کھولتا ہے لیکن، بدلے میں، ہمیں ان طریقوں سے رازداری کو برقرار رکھنے کی اجازت دیتا ہے جو خود بلاک چین پر دستیاب نہیں ہیں۔ زیرو-نالج پروف کے ساتھ ہم انٹیگریٹی کو یقینی بنا سکتے ہیں اور ممکنہ طور پر اسے مرکزی جزو چلانے والے کے لیے دستیابی کو برقرار رکھنے کے لیے اقتصادی طور پر فائدہ مند بنا سکتے ہیں۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ + +## اعترافات {#acknowledgements} + +- جوش کرائٹس نے اس مضمون کا ایک مسودہ پڑھا اور ایک کانٹے دار Noir مسئلے میں میری مدد کی۔ + +کوئی بھی باقی غلطیاں میری ذمہ داری ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/calling-a-smart-contract-from-javascript/index.md b/public/content/translations/ur/developers/tutorials/calling-a-smart-contract-from-javascript/index.md new file mode 100644 index 00000000000..201d7e8993b --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/calling-a-smart-contract-from-javascript/index.md @@ -0,0 +1,131 @@ +--- +title: "JavaScript سے اسمارٹ کنٹریکٹ کال کرنا" +description: "Dai ٹوکن کی مثال کا استعمال کرتے ہوئے JavaScript سے اسمارٹ کنٹریکٹ فنکشن کو کال کرنے کا طریقہ" +author: jdourlens +tags: [ "لین دین", "فرنٹ اینڈ", "JavaScript", "web3.js" ] +skill: beginner +lang: ur-in +published: 2020-04-19 +source: EthereumDev +sourceUrl: https://ethereumdev.io/calling-a-smart-contract-from-javascript/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +اس ٹیوٹوریل میں ہم دیکھیں گے کہ JavaScript سے [اسمارٹ کنٹریکٹ](/developers/docs/smart-contracts/) فنکشن کو کیسے کال کیا جائے۔ پہلے اسمارٹ کنٹریکٹ کی اسٹیٹ (state) کو پڑھنا ہے (مثال کے طور پر، ERC20 ہولڈر کا بیلنس)، پھر ہم ٹوکن کی منتقلی کر کے بلاک چین کی اسٹیٹ (state) میں ترمیم کریں گے۔ آپ کو [بلاک چین کے ساتھ تعامل کرنے کے لیے JS ماحول ترتیب دینے](/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/) سے پہلے ہی واقف ہونا چاہیے۔ + +اس مثال کے لیے ہم DAI ٹوکن کے ساتھ کھیلیں گے، جانچ کے مقصد کے لیے ہم ganache-cli کا استعمال کرتے ہوئے بلاک چین کو فورک (fork) کریں گے اور ایک ایسے ایڈریس کو غیر مقفل (unlock) کریں گے جس میں پہلے سے ہی بہت زیادہ DAI موجود ہے: + +```bash +ganache-cli -f https://mainnet.infura.io/v3/[YOUR INFURA KEY] -d -i 66 1 --unlock 0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81 +``` + +اسمارٹ کنٹریکٹ کے ساتھ تعامل کرنے کے لیے ہمیں اس کے ایڈریس اور ABI کی ضرورت ہوگی: + +```js +const ERC20TransferABI = [ + { + constant: false, + inputs: [ + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, +] + +const DAI_ADDRESS = "0x6b175474e89094c44da98b954eedeac495271d0f" +``` + +اس پروجیکٹ کے لیے ہم نے مکمل ERC20 ABI کو صرف `balanceOf` اور `transfer` فنکشنز رکھنے کے لیے مختصر کر دیا ہے لیکن آپ [مکمل ERC20 ABI یہاں](https://ethereumdev.io/abi-for-erc20-contract-on-ethereum/) تلاش کر سکتے ہیں۔ + +پھر ہمیں اپنے اسمارٹ کنٹریکٹ کو انسٹنٹی ایٹ (instantiate) کرنے کی ضرورت ہے: + +```js +const web3 = new Web3("http://localhost:8545") + +const daiToken = new web3.eth.Contract(ERC20TransferABI, DAI_ADDRESS) +``` + +ہم دو ایڈریس بھی سیٹ اپ کریں گے: + +- وہ جو منتقلی وصول کرے گا اور +- وہ جسے ہم نے پہلے ہی غیر مقفل کر دیا ہے جو اسے بھیجے گا: + +```js +const senderAddress = "0x4d10ae710Bd8D1C31bd7465c8CBC3add6F279E81" +const receiverAddress = "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +``` + +اگلے حصے میں ہم `balanceOf` فنکشن کو کال کریں گے تاکہ دونوں ایڈریسز کے پاس موجود ٹوکنز کی موجودہ رقم حاصل کی جا سکے۔ + +## کال: اسمارٹ کنٹریکٹ سے ویلیو پڑھنا {#call-reading-value-from-a-smart-contract} + +پہلی مثال ایک “کانسٹینٹ” (constant) میتھڈ کو کال کرے گی اور بغیر کوئی ٹرانزیکشن بھیجے EVM میں اس کے اسمارٹ کنٹریکٹ میتھڈ کو ایگزیکیوٹ کرے گی۔ اس کے لیے ہم ایک ایڈریس کا ERC20 بیلنس پڑھیں گے۔ [ERC20 ٹوکنز کے بارے میں ہمارا مضمون پڑھیں](/developers/tutorials/understand-the-erc-20-token-smart-contract/)۔ + +آپ ایک انسٹنٹی ایٹ (instantiated) کیے گئے اسمارٹ کنٹریکٹ میتھڈز تک رسائی حاصل کر سکتے ہیں جن کے لیے آپ نے ABI فراہم کیا ہے، اس طرح: `yourContract.methods.methodname`۔ `call` فنکشن کا استعمال کر کے آپ فنکشن کو ایگزیکیوٹ کرنے کا نتیجہ وصول کریں گے۔ + +```js +daiToken.methods.balanceOf(senderAddress).call(function (err, res) { + if (err) { + console.log("ایک خرابی واقع ہوئی ہے", err) + return + } + console.log("بیلنس یہ ہے: ", res) +}) +``` + +یاد رکھیں کہ DAI ERC20 میں 18 ڈیسیمل (decimals) ہوتے ہیں جس کا مطلب ہے کہ آپ کو صحیح رقم حاصل کرنے کے لیے 18 صفر ہٹانے کی ضرورت ہے۔ uint256 کو سٹرنگز کے طور پر واپس کیا جاتا ہے کیونکہ JavaScript بڑی عددی ویلیوز کو ہینڈل نہیں کرتا ہے۔ اگر آپ کو یقین نہیں ہے کہ [JS میں بڑے نمبروں سے کیسے نمٹا جائے تو bignumber.js کے بارے میں ہمارا ٹیوٹوریل دیکھیں](https://ethereumdev.io/how-to-deal-with-big-numbers-in-javascript/)۔ + +## بھیجیں: اسمارٹ کنٹریکٹ فنکشن میں ٹرانزیکشن بھیجنا {#send-sending-a-transaction-to-a-smart-contract-function} + +دوسری مثال کے لیے ہم DAI اسمارٹ کنٹریکٹ کے ٹرانسفر فنکشن کو کال کریں گے تاکہ اپنے دوسرے ایڈریس پر 10 DAI بھیج سکیں۔ ٹرانسفر فنکشن دو پیرامیٹرز قبول کرتا ہے: وصول کنندہ کا ایڈریس اور منتقل کیے جانے والے ٹوکن کی رقم: + +```js +daiToken.methods + .transfer(receiverAddress, "100000000000000000000") + .send({ from: senderAddress }, function (err, res) { + if (err) { + console.log("ایک خرابی واقع ہوئی ہے", err) + return + } + console.log("ٹرانزیکشن کا ہیش: " + res) + }) +``` + +کال فنکشن اس ٹرانزیکشن کا ہیش واپس کرتا ہے جسے بلاک چین میں مائن کیا جائے گا۔ Ethereum پر، ٹرانزیکشن ہیشز قابلِ قیاس ہوتے ہیں - اسی طرح ہم ٹرانزیکشن کو ایگزیکیوٹ کرنے سے پہلے اس کا ہیش حاصل کر سکتے ہیں ([یہاں جانیں کہ ہیشز کا حساب کیسے لگایا جاتا ہے](https://ethereum.stackexchange.com/questions/45648/how-to-calculate-the-assigned-txhash-of-a-transaction))۔ + +چونکہ فنکشن صرف ٹرانزیکشن کو بلاک چین میں جمع کرتا ہے، اس لیے ہم نتیجہ اس وقت تک نہیں دیکھ سکتے جب تک کہ ہمیں یہ معلوم نہ ہو جائے کہ اسے کب مائن کیا گیا ہے اور بلاک چین میں شامل کیا گیا ہے۔ اگلے ٹیوٹوریل میں ہم سیکھیں گے کہ [بلاک چین پر کسی ٹرانزیکشن کے ہیش کو جان کر اس کے ایگزیکیوٹ ہونے کا انتظار کیسے کیا جائے](https://ethereumdev.io/waiting-for-a-transaction-to-be-mined-on-ethereum-with-js/)۔ diff --git a/public/content/translations/ur/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/ur/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md new file mode 100644 index 00000000000..875e969a19d --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md @@ -0,0 +1,584 @@ +--- +title: "آپ کے کانٹریکٹ کے لیے ایک یوزر انٹرفیس بنانا" +description: "TypeScript، React، Vite، اور Wagmi جیسے جدید اجزاء کا استعمال کرتے ہوئے، ہم ایک جدید، لیکن کم سے کم، یوزر انٹرفیس پر جائیں گے اور یہ سیکھیں گے کہ یوزر انٹرفیس سے والیٹ کو کیسے جوڑا جائے، معلومات کو پڑھنے کے لیے اسمارٹ کانٹریکٹ کو کال کریں، اسمارٹ کانٹریکٹ پر ٹرانزیکشن بھیجیں، اور تبدیلیوں کی شناخت کے لیے اسمارٹ کانٹریکٹ سے ایونٹس کی نگرانی کریں۔" +author: Ori Pomerantz +tags: [ "typescript", "react", "vite", "wagmi", "فرنٹ اینڈ" ] +skill: beginner +published: 2023-11-01 +lang: ur-in +sidebarDepth: 3 +--- + +آپ کو Ethereum ایکو سسٹم میں ایک ایسی خصوصیت ملی جس کی ہمیں ضرورت ہے۔ آپ نے اسے نافذ کرنے کے لیے اسمارٹ کانٹریکٹس لکھے، اور شاید کچھ متعلقہ کوڈ بھی جو آف چین چلتا ہے۔ یہ بہت اچھا ہے! بدقسمتی سے، یوزر انٹرفیس کے بغیر آپ کے پاس کوئی یوزر نہیں ہوگا، اور آخری بار جب آپ نے کوئی ویب سائٹ لکھی تھی تو لوگ ڈائل اپ موڈیم استعمال کرتے تھے اور JavaScript نیا تھا۔ + +یہ مضمون آپ کے لیے ہے۔ میں مانتا ہوں کہ آپ پروگرامنگ جانتے ہیں، اور شاید تھوڑا سا JavaScript اور HTML، لیکن آپ کی یوزر انٹرفیس کی مہارتیں زنگ آلود اور پرانی ہیں۔ ہم مل کر ایک سادہ جدید ایپلی کیشن کا جائزہ لیں گے تاکہ آپ دیکھ سکیں کہ آج کل یہ کیسے کیا جاتا ہے۔ + +## یہ اہم کیوں ہے {#why-important} + +نظریاتی طور پر، آپ لوگوں کو اپنے کانٹریکٹس کے ساتھ تعامل کرنے کے لیے [Etherscan](https://holesky.etherscan.io/address/0x432d810484add7454ddb3b5311f0ac2e95cecea8#writeContract) یا [Blockscout](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=write_contract) کا استعمال کروا سکتے ہیں۔ یہ تجربہ کار Ethereans کے لیے بہت اچھا ہوگا۔ لیکن ہم [ایک ارب اور لوگوں](https://blog.ethereum.org/2021/05/07/ethereum-for-the-next-billion) کی خدمت کرنے کی کوشش کر رہے ہیں۔ یہ ایک بہترین یوزر تجربے کے بغیر نہیں ہوگا، اور ایک دوستانہ یوزر انٹرفیس اس کا ایک بڑا حصہ ہے۔ + +## Greeter ایپلی کیشن {#greeter-app} + +ایک جدید UI کے کام کرنے کے پیچھے بہت زیادہ تھیوری ہے، اور [بہت سی اچھی سائٹس](https://react.dev/learn/thinking-in-react) [ہیں جو اس کی وضاحت کرتی ہیں](https://wagmi.sh/core/getting-started)۔ ان سائٹس کے ذریعے کیے گئے عمدہ کام کو دہرانے کے بجائے، میں یہ مانوں گا کہ آپ کر کے سیکھنا پسند کرتے ہیں اور ایک ایسی ایپلی کیشن سے شروعات کرتے ہیں جس کے ساتھ آپ کھیل سکتے ہیں۔ چیزوں کو انجام دینے کے لیے آپ کو اب بھی تھیوری کی ضرورت ہے، اور ہم اس پر آئیں گے - ہم صرف سورس فائل بہ سورس فائل جائیں گے، اور جیسے جیسے ہم ان تک پہنچیں گے چیزوں پر تبادلہ خیال کریں گے۔ + +### انسٹالیشن {#installation} + +1. اگر ضروری ہو تو، اپنے والیٹ میں [Holesky بلاک چین](https://chainlist.org/?search=holesky&testnets=true) شامل کریں اور [ٹیسٹ ETH حاصل کریں](https://www.holeskyfaucet.io/)۔ + +2. github ریپوزٹری کو کلون کریں۔ + + ```sh + git clone https://github.com/qbzzt/20230801-modern-ui.git + ``` + +3. ضروری پیکجز انسٹال کریں۔ + + ```sh + cd 20230801-modern-ui + pnpm install + ``` + +4. ایپلی کیشن شروع کریں۔ + + ```sh + pnpm dev + ``` + +5. ایپلی کیشن کے ذریعے دکھائے گئے URL پر براؤز کریں۔ زیادہ تر معاملات میں، یہ [http://localhost:5173/](http://localhost:5173/) ہے۔ + +6. آپ کانٹریکٹ کا سورس کوڈ، Hardhat کے Greeter کا تھوڑا سا تبدیل شدہ ورژن، [ایک بلاک چین ایکسپلورر پر](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contract) دیکھ سکتے ہیں۔ + +### فائل واک تھرو {#file-walk-through} + +#### `index.html` {#index-html} + +یہ فائل اس لائن کے علاوہ معیاری HTML بوائلرپلیٹ ہے، جو اسکرپٹ فائل کو امپورٹ کرتی ہے۔ + +```html + +``` + +#### `src/main.tsx` {#main-tsx} + +فائل ایکسٹینشن ہمیں بتاتی ہے کہ یہ فائل ایک [React کمپونینٹ](https://www.w3schools.com/react/react_components.asp) ہے جو [TypeScript](https://www.typescriptlang.org/) میں لکھی گئی ہے، یہ JavaScript کی ایک ایکسٹینشن ہے جو [ٹائپ چیکنگ](https://en.wikipedia.org/wiki/Type_system#Type_checking) کو سپورٹ کرتی ہے۔ TypeScript کو JavaScript میں کمپائل کیا جاتا ہے، لہذا ہم اسے کلائنٹ سائیڈ ایگزیکیوشن کے لیے استعمال کر سکتے ہیں۔ + +```tsx +import '@rainbow-me/rainbowkit/styles.css' +import { RainbowKitProvider } from '@rainbow-me/rainbowkit' +import * as React from 'react' +import * as ReactDOM from 'react-dom/client' +import { WagmiConfig } from 'wagmi' +import { chains, config } from './wagmi' +``` + +ہمیں درکار لائبریری کوڈ امپورٹ کریں۔ + +```tsx +import { App } from './App' +``` + +اس React کمپونینٹ کو امپورٹ کریں جو ایپلی کیشن کو نافذ کرتا ہے (نیچے دیکھیں)۔ + +```tsx +ReactDOM.createRoot(document.getElementById('root')!).render( +``` + +روٹ React کمپونینٹ بنائیں۔ `render` کا پیرامیٹر [JSX](https://www.w3schools.com/react/react_jsx.asp) ہے، ایک ایکسٹینشن زبان جو HTML اور JavaScript/TypeScript دونوں کا استعمال کرتی ہے۔ یہاں کا ایکسکلیمیشن پوائنٹ TypeScript کمپونینٹ کو بتاتا ہے: "آپ نہیں جانتے کہ `document.getElementById('root')` `ReactDOM.createRoot` کے لیے ایک درست پیرامیٹر ہوگا، لیکن فکر نہ کریں - میں ڈیولپر ہوں اور میں آپ کو بتا رہا ہوں کہ یہ ہوگا۔"۔ + +```tsx + +``` + +ایپلی کیشن [ایک `React.StrictMode` کمپونینٹ](https://react.dev/reference/react/StrictMode) کے اندر جا رہی ہے۔ یہ کمپونینٹ React لائبریری کو اضافی ڈیبگنگ چیکس داخل کرنے کے لیے کہتا ہے، جو ڈیولپمنٹ کے دوران مفید ہے۔ + +```tsx + +``` + +ایپلی کیشن [ایک `WagmiConfig` کمپونینٹ](https://wagmi.sh/react/api/WagmiProvider) کے اندر بھی ہے۔ [wagmi (we are going to make it) لائبریری](https://wagmi.sh/) React UI کی تعریفوں کو Ethereum ڈی سینٹرلائزڈ ایپلی کیشن لکھنے کے لیے [viem لائبریری](https://viem.sh/) سے جوڑتی ہے۔ + +```tsx + +``` + +اور آخر میں، [ایک `RainbowKitProvider` کمپونینٹ](https://www.rainbowkit.com/)۔ یہ کمپونینٹ لاگ آن کرنے اور والیٹ اور ایپلی کیشن کے درمیان مواصلات کو ہینڈل کرتا ہے۔ + +```tsx + +``` + +اب ہمارے پاس ایپلی کیشن کے لیے کمپونینٹ ہو سکتا ہے، جو اصل میں UI کو نافذ کرتا ہے۔ کمپونینٹ کے آخر میں `/>` React کو بتاتا ہے کہ اس کمپونینٹ کے اندر کوئی تعریف نہیں ہے، جیسا کہ XML معیار کے مطابق ہے۔ + +```tsx + + + , +) +``` + +یقیناً، ہمیں دوسرے کمپونینٹس کو بند کرنا ہوگا۔ + +#### `src/App.tsx` {#app-tsx} + +```tsx +import { ConnectButton } from '@rainbow-me/rainbowkit' +import { useAccount } from 'wagmi' +import { Greeter } from './components/Greeter' + +export function App() { +``` + +یہ React کمپونینٹ بنانے کا معیاری طریقہ ہے - ایک ایسا فنکشن بیان کریں جسے ہر بار رینڈر کرنے کی ضرورت پڑنے پر کال کیا جاتا ہے۔ اس فنکشن میں عام طور پر سب سے اوپر کچھ TypeScript یا JavaScript کوڈ ہوتا ہے، جس کے بعد ایک `return` اسٹیٹمنٹ ہوتا ہے جو JSX کوڈ کو واپس کرتا ہے۔ + +```tsx + const { isConnected } = useAccount() +``` + +یہاں ہم یہ چیک کرنے کے لیے [`useAccount`](https://wagmi.sh/react/api/hooks/useAccount) کا استعمال کرتے ہیں کہ آیا ہم والیٹ کے ذریعے بلاک چین سے جڑے ہیں یا نہیں۔ + +کنونشن کے مطابق، React میں `use...` کہلانے والے فنکشنز [ہکس](https://www.w3schools.com/react/react_hooks.asp) ہوتے ہیں جو کسی قسم کا ڈیٹا واپس کرتے ہیں۔ جب آپ اس طرح کے ہکس استعمال کرتے ہیں، تو نہ صرف آپ کا کمپونینٹ ڈیٹا حاصل کرتا ہے، بلکہ جب وہ ڈیٹا تبدیل ہوتا ہے تو کمپونینٹ کو اپ ڈیٹ شدہ معلومات کے ساتھ دوبارہ رینڈر کیا جاتا ہے۔ + +```tsx + return ( + <> +``` + +React کمپونینٹ کے JSX کو _لازماً_ ایک کمپونینٹ واپس کرنا چاہیے۔ جب ہمارے پاس متعدد کمپونینٹس ہوں اور ہمارے پاس کوئی ایسی چیز نہ ہو جو "فطری طور پر" لپیٹتی ہو تو ہم ایک خالی کمپونینٹ (`<> ...` استعمال کرتے ہیں `) تاکہ انہیں ایک ہی کمپونینٹ بنایا جا سکے۔ + +```tsx +

Greeter

+ +``` + +ہمیں RainbowKit سے [`ConnectButton` کمپونینٹ](https://www.rainbowkit.com/docs/connect-button) ملتا ہے۔ جب ہم جڑے نہیں ہوتے ہیں، تو یہ ہمیں ایک `Connect Wallet` بٹن دیتا ہے جو ایک موڈل کھولتا ہے جو والیٹس کی وضاحت کرتا ہے اور آپ کو یہ انتخاب کرنے دیتا ہے کہ آپ کون سا استعمال کرتے ہیں۔ جب ہم جڑے ہوتے ہیں، تو یہ ہمارے استعمال کردہ بلاک چین، ہمارے اکاؤنٹ کا ایڈریس، اور ہمارے ETH بیلنس کو دکھاتا ہے۔ ہم ان ڈسپلیز کو نیٹ ورک تبدیل کرنے یا منقطع کرنے کے لیے استعمال کر سکتے ہیں۔ + +```tsx + {isConnected && ( +``` + +جب ہمیں JSX میں اصل JavaScript (یا TypeScript جو JavaScript میں کمپائل کیا جائے گا) داخل کرنے کی ضرورت ہوتی ہے، تو ہم بریکٹس (`{}`) کا استعمال کرتے ہیں۔ + +سنٹیکس `a && b` [`a ?` کا مختصر ہے b : a`](https://www.w3schools.com/react/react_es6_ternary.asp)۔ یعنی، اگر `a`درست ہے تو یہ`b`کا اندازہ کرتا ہے اور بصورت دیگر یہ`a`کا اندازہ کرتا ہے (جو`false`، `0`، وغیرہ ہو سکتا ہے)۔ یہ React کو بتانے کا ایک آسان طریقہ ہے کہ ایک کمپونینٹ کو صرف تب ہی دکھایا جانا چاہیے جب کوئی خاص شرط پوری ہو۔ + +اس معاملے میں، ہم صرف یوزر کو `Greeter` دکھانا چاہتے ہیں اگر یوزر بلاک چین سے جڑا ہو۔ + +```tsx + + )} + + ) +} +``` + +#### `src/components/Greeter.tsx` {#greeter-tsx} + +اس فائل میں UI کی زیادہ تر فنکشنلٹی موجود ہے۔ اس میں ایسی تعریفیں شامل ہیں جو عام طور پر متعدد فائلوں میں ہوتی ہیں، لیکن چونکہ یہ ایک ٹیوٹوریل ہے، پروگرام کو پہلی بار سمجھنے میں آسانی کے لیے بہتر بنایا گیا ہے، نہ کہ کارکردگی یا دیکھ بھال کی آسانی کے لیے۔ + +```tsx +import { useState, ChangeEventHandler } from 'react' +import { useNetwork, + useReadContract, + usePrepareContractWrite, + useContractWrite, + useContractEvent + } from 'wagmi' +``` + +ہم ان لائبریری فنکشنز کا استعمال کرتے ہیں۔ دوبارہ، ان کی وضاحت نیچے کی گئی ہے جہاں وہ استعمال ہوتے ہیں۔ + +```tsx +import { AddressType } from 'abitype' +``` + +[`abitype` لائبریری](https://abitype.dev/) ہمیں مختلف Ethereum ڈیٹا کی اقسام کے لیے TypeScript کی تعریفیں فراہم کرتی ہے، جیسے [`AddressType`](https://abitype.dev/config#addresstype)۔ + +```tsx +let greeterABI = [ + . + . + . +] as const // greeterABI +``` + +`Greeter` کانٹریکٹ کے لیے ABI۔ +اگر آپ ایک ہی وقت میں کانٹریکٹس اور UI تیار کر رہے ہیں تو آپ عام طور پر انہیں ایک ہی ریپوزٹری میں ڈالیں گے اور Solidity کمپائلر کے ذریعہ تیار کردہ ABI کو اپنی ایپلی کیشن میں ایک فائل کے طور پر استعمال کریں گے۔ تاہم، یہاں اس کی ضرورت نہیں ہے کیونکہ کانٹریکٹ پہلے ہی تیار ہو چکا ہے اور تبدیل نہیں ہونے والا ہے۔ + +```tsx +type AddressPerBlockchainType = { + [key: number]: AddressType +} +``` + +TypeScript مضبوطی سے ٹائپ کیا گیا ہے۔ ہم اس تعریف کا استعمال اس ایڈریس کو متعین کرنے کے لیے کرتے ہیں جس میں `Greeter` کانٹریکٹ مختلف چینز پر ڈیپلائے کیا گیا ہے۔ کی (key) ایک نمبر (chainId) ہے، اور ویلیو ایک `AddressType` (ایک ایڈریس) ہے۔ + +```tsx +const contractAddrs: AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' +} +``` + +دو سپورٹڈ نیٹ ورکس پر کانٹریکٹ کا ایڈریس: [Holesky](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contact_code) اور [Sepolia](https://eth-sepolia.blockscout.com/address/0x7143d5c190F048C8d19fe325b748b081903E3BF0?tab=contact_code)۔ + +نوٹ: دراصل ایک تیسری تعریف ہے، Redstone Holesky کے لیے، اس کی وضاحت نیچے کی جائے گی۔ + +```tsx +type ShowObjectAttrsType = { + name: string, + object: any +} +``` + +اس قسم کا استعمال `ShowObject` کمپونینٹ (جس کی وضاحت بعد میں کی گئی ہے) کے پیرامیٹر کے طور پر کیا جاتا ہے۔ اس میں آبجیکٹ کا نام اور اس کی ویلیو شامل ہے، جو ڈیبگنگ کے مقاصد کے لیے دکھائے جاتے ہیں۔ + +```tsx +type ShowGreetingAttrsType = { + greeting: string | undefined +} +``` + +کسی بھی وقت، ہم یا تو جان سکتے ہیں کہ گریٹنگ کیا ہے (کیونکہ ہم نے اسے بلاک چین سے پڑھا ہے) یا نہیں جانتے (کیونکہ ہمیں ابھی تک یہ موصول نہیں ہوئی ہے)۔ لہذا ایک ایسی قسم کا ہونا مفید ہے جو یا تو ایک اسٹرنگ ہو یا کچھ بھی نہ ہو۔ + +##### `Greeter` کمپونینٹ {#greeter-component} + +```tsx +const Greeter = () => { +``` + +آخر کار، ہم کمپونینٹ کی وضاحت کرتے ہیں۔ + +```tsx + const { chain } = useNetwork() +``` + +اس چین کے بارے میں معلومات جسے ہم استعمال کر رہے ہیں، [wagmi](https://wagmi.sh/react/hooks/useNetwork) کی بدولت۔ +چونکہ یہ ایک ہک (`use...`) ہے، ہر بار جب یہ معلومات تبدیل ہوتی ہیں تو کمپونینٹ دوبارہ تیار ہوتا ہے۔ + +```tsx + const greeterAddr = chain && contractAddrs[chain.id] +``` + +Greeter کانٹریکٹ کا ایڈریس، جو چین کے لحاظ سے مختلف ہوتا ہے (اور جو `undefined` ہوتا ہے اگر ہمارے پاس چین کی معلومات نہ ہوں یا ہم کسی ایسی چین پر ہوں جس میں وہ کانٹریکٹ نہ ہو)۔ + +```tsx + const readResults = useReadContract({ + address: greeterAddr, + abi: greeterABI, + functionName: "greet" , // No arguments + watch: true + }) +``` + +[`useReadContract` ہک](https://wagmi.sh/react/api/hooks/useReadContract) ایک کانٹریکٹ سے معلومات پڑھتا ہے۔ آپ دیکھ سکتے ہیں کہ یہ UI میں `readResults` کو پھیلا کر کون سی معلومات واپس کرتا ہے۔ اس معاملے میں ہم چاہتے ہیں کہ یہ دیکھتا رہے تاکہ جب گریٹنگ تبدیل ہو تو ہمیں مطلع کیا جائے۔ + +**نوٹ:** ہم [`setGreeting` ایونٹس](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=logs) کو سن سکتے ہیں یہ جاننے کے لیے کہ گریٹنگ کب تبدیل ہوتی ہے اور اس طرح اپ ڈیٹ کریں۔ تاہم، جب کہ یہ زیادہ موثر ہو سکتا ہے، یہ تمام معاملات میں لاگو نہیں ہوگا۔ جب یوزر ایک مختلف چین پر سوئچ کرتا ہے تو گریٹنگ بھی تبدیل ہو جاتی ہے، لیکن اس تبدیلی کے ساتھ کوئی ایونٹ نہیں ہوتا ہے۔ ہمارے پاس کوڈ کا ایک حصہ ایونٹس کو سن رہا ہوسکتا ہے اور دوسرا چین کی تبدیلیوں کی شناخت کے لیے، لیکن یہ صرف [`watch` پیرامیٹر](https://wagmi.sh/react/api/hooks/useReadContract#watch-optional) سیٹ کرنے سے زیادہ پیچیدہ ہوگا۔ + +```tsx + const [ newGreeting, setNewGreeting ] = useState("") +``` + +React کا [`useState` ہک](https://www.w3schools.com/react/react_usestate.asp) ہمیں ایک اسٹیٹ متغیر کی وضاحت کرنے دیتا ہے، جس کی ویلیو کمپونینٹ کی ایک رینڈرنگ سے دوسری رینڈرنگ تک برقرار رہتی ہے۔ ابتدائی ویلیو پیرامیٹر ہے، اس معاملے میں خالی اسٹرنگ ہے۔ + +`useState` ہک دو ویلیوز کے ساتھ ایک لسٹ واپس کرتا ہے: + +1. اسٹیٹ متغیر کی موجودہ ویلیو۔ +2. جب ضرورت ہو تو اسٹیٹ متغیر میں ترمیم کرنے کے لیے ایک فنکشن۔ چونکہ یہ ایک ہک ہے، ہر بار جب اسے کال کیا جاتا ہے تو کمپونینٹ دوبارہ رینڈر ہوتا ہے۔ + +اس معاملے میں، ہم نئی گریٹنگ کے لیے ایک اسٹیٹ متغیر استعمال کر رہے ہیں جسے یوزر سیٹ کرنا چاہتا ہے۔ + +```tsx + const greetingChange : ChangeEventHandler = (evt) => + setNewGreeting(evt.target.value) +``` + +یہ ایونٹ ہینڈلر اس وقت کے لیے ہے جب نئی گریٹنگ ان پٹ فیلڈ تبدیل ہوتی ہے۔ ٹائپ، [`ChangeEventHandler`](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/)، یہ بتاتا ہے کہ یہ ایک HTML ان پٹ عنصر کی ویلیو کی تبدیلی کے لیے ہینڈلر ہے۔ `` حصہ استعمال کیا جاتا ہے کیونکہ یہ ایک [جینرک ٹائپ](https://www.w3schools.com/typescript/typescript_basic_generics.php) ہے۔ + +```tsx + const preparedTx = usePrepareContractWrite({ + address: greeterAddr, + abi: greeterABI, + functionName: 'setGreeting', + args: [ newGreeting ] + }) + const workingTx = useContractWrite(preparedTx.config) +``` + +یہ کلائنٹ کے نقطہ نظر سے بلاک چین ٹرانزیکشن جمع کرنے کا عمل ہے: + +1. [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas) کا استعمال کرتے ہوئے بلاک چین میں ایک نوڈ کو ٹرانزیکشن بھیجیں۔ +2. نوڈ سے جواب کا انتظار کریں۔ +3. جب جواب موصول ہو جائے، تو یوزر سے والیٹ کے ذریعے ٹرانزیکشن پر دستخط کرنے کے لیے کہیں۔ یہ مرحلہ نوڈ کا جواب موصول ہونے کے بعد _ہونا_ چاہیے کیونکہ یوزر کو دستخط کرنے سے پہلے ٹرانزیکشن کی گیس کی لاگت دکھائی جاتی ہے۔ +4. یوزر کے منظور کرنے کا انتظار کریں۔ +5. ٹرانزیکشن کو دوبارہ بھیجیں، اس بار [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) کا استعمال کرتے ہوئے۔ + +مرحلہ 2 میں ممکنہ طور پر قابل توجہ وقت لگے گا، جس کے دوران یوزرس سوچیں گے کہ کیا ان کا کمانڈ واقعی یوزر انٹرفیس کو موصول ہوا ہے اور ان سے ابھی تک ٹرانزیکشن پر دستخط کرنے کے لیے کیوں نہیں کہا جا رہا ہے۔ یہ خراب یوزر تجربہ (UX) بناتا ہے۔ + +اس کا حل [prepare hooks](https://wagmi.sh/react/prepare-hooks) کا استعمال کرنا ہے۔ ہر بار جب کوئی پیرامیٹر تبدیل ہوتا ہے، تو فوری طور پر نوڈ کو `eth_estimateGas` کی درخواست بھیجیں۔ پھر، جب یوزر واقعی ٹرانزیکشن بھیجنا چاہتا ہے (اس معاملے میں **گریٹنگ اپ ڈیٹ کریں** دبا کر)، تو گیس کی لاگت معلوم ہوتی ہے اور یوزر فوری طور پر والیٹ کا صفحہ دیکھ سکتا ہے۔ + +```tsx + return ( +``` + +اب ہم آخر کار واپس کرنے کے لیے اصل HTML بنا سکتے ہیں۔ + +```tsx + <> +

Greeter

+ { + !readResults.isError && !readResults.isLoading && + + } +
+``` + +ایک `ShowGreeting` کمپونینٹ بنائیں (جس کی وضاحت نیچے کی گئی ہے)، لیکن صرف اس صورت میں جب گریٹنگ بلاک چین سے کامیابی کے ساتھ پڑھی گئی ہو۔ + +```tsx + +``` + +یہ ان پٹ ٹیکسٹ فیلڈ ہے جہاں یوزر ایک نئی گریٹنگ سیٹ کر سکتا ہے۔ ہر بار جب یوزر کوئی کی (key) دباتا ہے، ہم `greetingChange` کو کال کرتے ہیں جو `setNewGreeting` کو کال کرتا ہے۔ چونکہ `setNewGreeting` `useState` ہک سے آتا ہے، یہ `Greeter` کمپونینٹ کو دوبارہ رینڈر کرنے کا سبب بنتا ہے۔ اس کا مطلب یہ ہے کہ: + +- ہمیں نئی گریٹنگ کی ویلیو رکھنے کے لیے `value` کی وضاحت کرنے کی ضرورت ہے، کیونکہ بصورت دیگر یہ ڈیفالٹ، یعنی خالی اسٹرنگ میں واپس آ جائے گی۔ +- `usePrepareContractWrite` ہر بار جب `newGreeting` تبدیل ہوتا ہے تو کال کیا جاتا ہے، جس کا مطلب ہے کہ اس کے پاس ہمیشہ تیار ٹرانزیکشن میں تازہ ترین `newGreeting` ہوگا۔ + +```tsx + +``` + +اگر `workingTx.write` نہیں ہے تو ہم ابھی بھی گریٹنگ اپ ڈیٹ بھیجنے کے لیے ضروری معلومات کا انتظار کر رہے ہیں، لہذا بٹن غیر فعال ہے۔ اگر `workingTx.write` ویلیو ہے تو یہ ٹرانزیکشن بھیجنے کے لیے کال کرنے والا فنکشن ہے۔ + +```tsx +
+ + + + + ) +``` + +آخر میں، یہ دیکھنے میں آپ کی مدد کرنے کے لیے کہ ہم کیا کر رہے ہیں، ان تین آبجیکٹس کو دکھائیں جن کا ہم استعمال کرتے ہیں: + +- `readResults` +- `preparedTx` +- `workingTx` + +##### `ShowGreeting` کمپونینٹ {#showgreeting-component} + +یہ کمپونینٹ دکھاتا ہے + +```tsx +const ShowGreeting = (attrs : ShowGreetingAttrsType) => { +``` + +ایک کمپونینٹ فنکشن کمپونینٹ کی تمام صفات کے ساتھ ایک پیرامیٹر حاصل کرتا ہے۔ + +```tsx + return {attrs.greeting} +} +``` + +##### `ShowObject` کمپونینٹ {#showobject-component} + +معلومات کے مقاصد کے لیے، ہم اہم آبجیکٹس (`readResults` گریٹنگ پڑھنے کے لیے اور `preparedTx` اور `workingTx` ہمارے بنائے ہوئے ٹرانزیکشنز کے لیے) کو دکھانے کے لیے `ShowObject` کمپونینٹ کا استعمال کرتے ہیں۔ + +```tsx +const ShowObject = (attrs: ShowObjectAttrsType ) => { + const keys = Object.keys(attrs.object) + const funs = keys.filter(k => typeof attrs.object[k] == "function") + return <> +
+``` + +ہم UI کو تمام معلومات سے بے ترتیبی نہیں کرنا چاہتے، لہذا انہیں دیکھنے یا بند کرنے کو ممکن بنانے کے لیے، ہم [`details`](https://www.w3schools.com/tags/tag_details.asp) ٹیگ کا استعمال کرتے ہیں۔ + +```tsx + {attrs.name} +
+        {JSON.stringify(attrs.object, null, 2)}
+```
+
+زیادہ تر فیلڈز [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) کا استعمال کرتے ہوئے دکھائے جاتے ہیں۔
+
+```tsx
+      
+ { funs.length > 0 && + <> + فنکشنز: +
    +``` + +مستثنیٰ فنکشنز ہیں، جو [JSON معیار](https://www.json.org/json-en.html) کا حصہ نہیں ہیں، لہذا انہیں الگ سے دکھانا پڑتا ہے۔ + +```tsx + {funs.map((f, i) => +``` + +JSX کے اندر، `{` کرلی بریکٹ `}` کے اندر کوڈ کو JavaScript کے طور پر سمجھا جاتا ہے۔ پھر، `(` ریگولر بریکٹ `)` کے اندر کوڈ کو دوبارہ JSX کے طور پر سمجھا جاتا ہے۔ + +```tsx + (
  • {f}
  • ) + )} +``` + +React کو [DOM ٹری](https://www.w3schools.com/js/js_htmldom.asp) میں ٹیگز کے لیے الگ شناختی نشانات کی ضرورت ہوتی ہے۔ اس کا مطلب ہے کہ ایک ہی ٹیگ کے بچوں (اس معاملے میں، [غیر ترتیب شدہ فہرست](https://www.w3schools.com/tags/tag_ul.asp)) کو مختلف `key` صفات کی ضرورت ہوتی ہے۔ + +```tsx +
+ + } +
+ +} +``` + +مختلف HTML ٹیگز کو ختم کریں۔ + +##### حتمی `export` {#the-final-export} + +```tsx +export { Greeter } +``` + +`Greeter` کمپونینٹ وہ ہے جسے ہمیں ایپلی کیشن کے لیے ایکسپورٹ کرنے کی ضرورت ہے۔ + +#### `src/wagmi.ts` {#wagmi-ts} + +آخر میں، WAGMI سے متعلق مختلف تعریفیں `src/wagmi.ts` میں ہیں۔ میں یہاں ہر چیز کی وضاحت نہیں کروں گا، کیونکہ اس کا زیادہ تر حصہ بوائلرپلیٹ ہے جسے آپ کو تبدیل کرنے کی ضرورت کا امکان نہیں ہے۔ + +یہاں کا کوڈ [github پر موجود](https://github.com/qbzzt/20230801-modern-ui/blob/main/src/wagmi.ts) کوڈ جیسا بالکل نہیں ہے کیونکہ مضمون میں بعد میں ہم ایک اور چین ([Redstone Holesky](https://redstone.xyz/docs/network-info)) شامل کرتے ہیں۔ + +```ts +import { getDefaultWallets } from '@rainbow-me/rainbowkit' +import { configureChains, createConfig } from 'wagmi' +import { holesky, sepolia } from 'wagmi/chains' +``` + +ان بلاک چینز کو امپورٹ کریں جن کو ایپلی کیشن سپورٹ کرتی ہے۔ آپ سپورٹڈ چینز کی فہرست [viem github میں](https://github.com/wagmi-dev/viem/tree/main/src/chains/definitions) دیکھ سکتے ہیں۔ + +```ts +import { publicProvider } from 'wagmi/providers/public' + +const walletConnectProjectId = 'c96e690bb92b6311e8e9b2a6a22df575' +``` + +[WalletConnect](https://walletconnect.com/) استعمال کرنے کے لیے آپ کو اپنی ایپلی کیشن کے لیے ایک پروجیکٹ آئی ڈی کی ضرورت ہے۔ آپ اسے [cloud.walletconnect.com پر](https://cloud.walletconnect.com/sign-in) حاصل کر سکتے ہیں۔ + +```ts +const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia ], + [ + publicProvider(), + ], +) + +const { connectors } = getDefaultWallets({ + appName: 'My wagmi + RainbowKit App', + chains, + projectId: walletConnectProjectId, +}) + +export const config = createConfig({ + autoConnect: true, + connectors, + publicClient, + webSocketPublicClient, +}) + +export { chains } +``` + +### ایک اور بلاک چین شامل کرنا {#add-blockchain} + +آج کل بہت سے [L2 اسکیلنگ سلوشن](/layer-2/) ہیں، اور آپ کچھ ایسے کو سپورٹ کرنا چاہ سکتے ہیں جنہیں viem ابھی تک سپورٹ نہیں کرتا ہے۔ ایسا کرنے کے لیے، آپ `src/wagmi.ts` میں ترمیم کریں۔ یہ ہدایات وضاحت کرتی ہیں کہ [Redstone Holesky](https://redstone.xyz/docs/network-info) کو کیسے شامل کیا جائے۔ + +1. viem سے `defineChain` ٹائپ امپورٹ کریں۔ + + ```ts + import { defineChain } from 'viem' + ``` + +2. نیٹ ورک کی تعریف شامل کریں۔ + + ```ts + const redstoneHolesky = defineChain({ + id: 17_001, + name: 'Redstone Holesky', + network: 'redstone-holesky', + nativeCurrency: { + decimals: 18, + name: 'Ether', + symbol: 'ETH', + }, + rpcUrls: { + default: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + public: { + http: ['https://rpc.holesky.redstone.xyz'], + webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], + }, + }, + blockExplorers: { + default: { name: 'Explorer', url: 'https://explorer.holesky.redstone.xyz' }, + }, + }) + ``` + +3. نئی چین کو `configureChains` کال میں شامل کریں۔ + + ```ts + const { chains, publicClient, webSocketPublicClient } = configureChains( + [ holesky, sepolia, redstoneHolesky ], + [ publicProvider(), ], + ) + ``` + +4. یقینی بنائیں کہ ایپلی کیشن نئے نیٹ ورک پر آپ کے کانٹریکٹس کے لیے ایڈریس جانتی ہے۔ اس معاملے میں، ہم `src/components/Greeter.tsx` میں ترمیم کرتے ہیں: + + ```ts + const contractAddrs : AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Redstone Holesky + 17001: '0x4919517f82a1B89a32392E1BF72ec827ba9986D3', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' + } + ``` + +## نتیجہ {#conclusion} + +یقیناً، آپ واقعی `Greeter` کے لیے یوزر انٹرفیس فراہم کرنے کی پرواہ نہیں کرتے ہیں۔ آپ اپنے کانٹریکٹس کے لیے ایک یوزر انٹرفیس بنانا چاہتے ہیں۔ اپنی ایپلی کیشن بنانے کے لیے، ان مراحل کو چلائیں: + +1. ایک wagmi ایپلی کیشن بنانے کے لیے متعین کریں۔ + + ```sh copy + pnpm create wagmi + ``` + +2. ایپلی کیشن کا نام دیں۔ + +3. **React** فریم ورک منتخب کریں۔ + +4. **Vite** ویرینٹ منتخب کریں۔ + +5. آپ [Rainbow kit شامل کر سکتے ہیں](https://www.rainbowkit.com/docs/installation#manual-setup)۔ + +اب جائیں اور اپنے کانٹریکٹس کو وسیع دنیا کے لیے قابل استعمال بنائیں۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ + diff --git a/public/content/translations/ur/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/ur/developers/tutorials/deploying-your-first-smart-contract/index.md new file mode 100644 index 00000000000..7a58026b9ba --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/deploying-your-first-smart-contract/index.md @@ -0,0 +1,95 @@ +--- +title: "اپنا پہلا سمارٹ کنٹریکٹ ڈیپلائے کرنا" +description: "ایتھیریم ٹیسٹ نیٹ ورک پر اپنا پہلا سمارٹ کنٹریکٹ ڈیپلائے کرنے کا تعارف" +author: "jdourlens" +tags: [ "اسمارٹ معاہدات", "remix", "solidity", "تعینات کرنا" ] +skill: beginner +lang: ur-in +published: 2020-04-03 +source: EthereumDev +sourceUrl: https://ethereumdev.io/deploying-your-first-smart-contract/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +میرا اندازہ ہے کہ آپ بھی ہماری طرح ایتھیریم بلاک چین پر اپنے پہلے [سمارٹ کنٹریکٹ](/developers/docs/smart-contracts/) کو [ڈیپلائے](/developers/docs/smart-contracts/deploying/) کرنے اور اس کے ساتھ تعامل کرنے کے لیے پرجوش ہیں۔ + +پریشان نہ ہوں، چونکہ یہ ہمارا پہلا سمارٹ کنٹریکٹ ہے، ہم اسے [مقامی ٹیسٹ نیٹ ورک](/developers/docs/networks/) پر ڈیپلائے کریں گے تاکہ اسے ڈیپلائے کرنے اور اس کے ساتھ جتنا چاہیں کھیلنے میں آپ کا کوئی خرچ نہ آئے۔ + +## ہمارا کنٹریکٹ لکھنا {#writing-our-contract} + +پہلا قدم [Remix پر جانا](https://remix.ethereum.org/) اور ایک نئی فائل بنانا ہے۔ Remix انٹرفیس کے اوپری بائیں حصے میں ایک نئی فائل شامل کریں اور اپنی پسند کا فائل نام درج کریں۔ + +![Remix انٹرفیس میں ایک نئی فائل شامل کرنا](./remix.png) + +نئی فائل میں، ہم مندرجہ ذیل کوڈ پیسٹ کریں گے۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >=0.5.17; + +contract Counter { + + // گنتی کی تعداد رکھنے کے لیے غیر دستخط شدہ int قسم کا عوامی متغیر + uint256 public count = 0; + + // فنکشن جو ہمارے کاؤنٹر میں اضافہ کرتا ہے + function increment() public { + count += 1; + } + + // گنتی کی قدر حاصل کرنے کے لیے غیر ضروری گیٹر + function getCount() public view returns (uint256) { + return count; + } + +} +``` + +اگر آپ پروگرامنگ کے عادی ہیں تو آپ آسانی سے اندازہ لگا سکتے ہیں کہ یہ پروگرام کیا کرتا ہے۔ یہاں لائن بہ لائن وضاحت دی گئی ہے: + +- لائن 4: ہم `Counter` نام کے ساتھ ایک کنٹریکٹ کی وضاحت کرتے ہیں۔ +- لائن 7: ہمارا کنٹریکٹ `count` نامی ایک غیر دستخط شدہ انٹیجر کو اسٹور کرتا ہے جو 0 سے شروع ہوتا ہے۔ +- لائن 10: پہلا فنکشن کنٹریکٹ کی حالت میں ترمیم کرے گا اور ہمارے متغیر `count` میں `increment()` کرے گا۔ +- لائن 15: دوسرا فنکشن صرف ایک گیٹر ہے تاکہ سمارٹ کنٹریکٹ کے باہر `count` متغیر کی قدر کو پڑھا جا سکے۔ نوٹ کریں کہ، چونکہ ہم نے اپنے `count` متغیر کو عوامی کے طور پر بیان کیا ہے، یہ ضروری نہیں ہے لیکن اسے ایک مثال کے طور پر دکھایا گیا ہے۔ + +یہ سب ہمارے پہلے سادہ سمارٹ کنٹریکٹ کے لیے ہے۔ جیسا کہ آپ جانتے ہوں گے، یہ جاوا یا C++ جیسی OOP (آبجیکٹ اورینٹڈ پروگرامنگ) زبانوں کی کلاس کی طرح لگتا ہے۔ اب ہمارے کنٹریکٹ کے ساتھ کھیلنے کا وقت ہے۔ + +## ہمارا کنٹریکٹ ڈیپلائے کرنا {#deploying-our-contract} + +چونکہ ہم نے اپنا پہلا سمارٹ کنٹریکٹ لکھا ہے، اب ہم اسے بلاک چین پر ڈیپلائے کریں گے تاکہ اس کے ساتھ کھیل سکیں۔ + +[بلاک چین پر سمارٹ کنٹریکٹ کو ڈیپلائے کرنا](/developers/docs/smart-contracts/deploying/) دراصل صرف ایک ٹرانزیکشن بھیجنا ہے جس میں کمپائل شدہ سمارٹ کنٹریکٹ کا کوڈ ہوتا ہے بغیر کسی وصول کنندہ کی وضاحت کیے۔ + +ہم سب سے پہلے بائیں جانب کمپائل آئیکن پر کلک کرکے [کنٹریکٹ کو کمپائل کریں گے](/developers/docs/smart-contracts/compiling/): + +![Remix ٹول بار میں کمپائل آئیکن](./remix-compile-button.png) + +پھر کمپائل بٹن پر کلک کریں: + +![Remix سولیڈیٹی کمپائلر میں کمپائل بٹن](./remix-compile.png) + +آپ "آٹو کمپائل" آپشن کو منتخب کرنے کا انتخاب کر سکتے ہیں تاکہ جب آپ ٹیکسٹ ایڈیٹر پر مواد محفوظ کریں تو کنٹریکٹ ہمیشہ کمپائل ہو جائے۔ + +پھر "ڈیپلائے اور رن ٹرانزیکشنز" اسکرین پر جائیں: + +![Remix ٹول بار میں ڈیپلائے آئیکن](./remix-deploy.png) + +ایک بار جب آپ "ڈیپلائے اور رن ٹرانزیکشنز" اسکرین پر ہوں، تو دو بار چیک کریں کہ آپ کے کنٹریکٹ کا نام ظاہر ہوتا ہے اور ڈیپلائے پر کلک کریں۔ جیسا کہ آپ صفحہ کے اوپری حصے میں دیکھ سکتے ہیں، موجودہ ماحول "JavaScript VM" ہے جس کا مطلب ہے کہ ہم اپنے سمارٹ کنٹریکٹ کو مقامی ٹیسٹ بلاک چین پر ڈیپلائے اور اس کے ساتھ تعامل کریں گے تاکہ تیزی سے اور بغیر کسی فیس کے ٹیسٹ کر سکیں۔ + +![Remix سولیڈیٹی کمپائلر میں ڈیپلائے بٹن](./remix-deploy-button.png) + +ایک بار جب آپ "ڈیپلائے" بٹن پر کلک کر لیں گے، تو آپ کو اپنا کنٹریکٹ نیچے ظاہر ہوتا نظر آئے گا۔ اسے پھیلانے کے لیے بائیں طرف کے تیر پر کلک کریں تاکہ ہم اپنے کنٹریکٹ کا مواد دیکھ سکیں۔ یہ ہمارا متغیر `counter`، ہمارا `increment()` فنکشن اور گیٹر `getCounter()` ہے۔ + +اگر آپ `count` یا `getCount` بٹن پر کلک کرتے ہیں، تو یہ دراصل کنٹریکٹ کے `count` متغیر کا مواد حاصل کرے گا اور اسے ظاہر کرے گا۔ چونکہ ہم نے ابھی تک `increment` فنکشن کو کال نہیں کیا ہے، اس لیے اسے 0 دکھانا چاہیے۔ + +![Remix سولیڈیٹی کمپائلر میں فنکشن بٹن](./remix-function-button.png) + +آئیے اب بٹن پر کلک کرکے `increment` فنکشن کو کال کریں۔ آپ کو ونڈو کے نیچے کی جانے والی ٹرانزیکشنز کے لاگز نظر آئیں گے۔ آپ دیکھیں گے کہ جب آپ `increment` بٹن کے بجائے ڈیٹا حاصل کرنے کے لیے بٹن دبا رہے ہوتے ہیں تو لاگز مختلف ہوتے ہیں۔ اس کی وجہ یہ ہے کہ بلاک چین پر ڈیٹا پڑھنے کے لیے کسی ٹرانزیکشن (لکھنے) یا فیس کی ضرورت نہیں ہوتی ہے۔ کیونکہ صرف بلاک چین کی حالت میں ترمیم کرنے کے لیے ٹرانزیکشن کرنے کی ضرورت ہوتی ہے: + +![ٹرانزیکشنز کا ایک لاگ](./transaction-log.png) + +انکریمنٹ بٹن دبانے کے بعد جو ہمارے `increment()` فنکشن کو کال کرنے کے لیے ایک ٹرانزیکشن پیدا کرے گا، اگر ہم کاؤنٹ یا گیٹ کاؤنٹ بٹنوں پر واپس کلک کرتے ہیں تو ہم اپنے سمارٹ کنٹریکٹ کی نئی اپ ڈیٹ شدہ حالت کو پڑھیں گے جس میں کاؤنٹ متغیر 0 سے بڑا ہوگا۔ + +![سمارٹ کنٹریکٹ کی نئی اپ ڈیٹ شدہ حالت](./updated-state.png) + +اگلے ٹیوٹوریل میں، ہم [آپ اپنے سمارٹ کنٹریکٹس میں ایونٹس کیسے شامل کر سکتے ہیں](/developers/tutorials/logging-events-smart-contracts/) کا احاطہ کریں گے۔ لاگنگ ایونٹس آپ کے سمارٹ کنٹریکٹ کو ڈیبگ کرنے اور یہ سمجھنے کا ایک آسان طریقہ ہے کہ فنکشن کو کال کرتے وقت کیا ہو رہا ہے۔ diff --git a/public/content/translations/ur/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md b/public/content/translations/ur/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md new file mode 100644 index 00000000000..6666440ae4b --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md @@ -0,0 +1,372 @@ +--- +title: "مقامی، ملٹی کلائنٹ ٹیسٹ نیٹ پر ایک dApp کو کیسے تیار اور ٹیسٹ کیا جائے" +description: "یہ گائیڈ پہلے آپ کو اس بارے میں بتائے گا کہ کسی dApp کو ڈیپلائے اور ٹیسٹ کرنے کے لیے ٹیسٹ نیٹ کا استعمال کرنے سے پہلے ملٹی کلائنٹ مقامی Ethereum ٹیسٹ نیٹ کو کیسے انسٹینٹیٹ اور کنفیگر کیا جائے۔" +author: "Tedi Mitiku" +tags: + [ + "کلائنٹس", + "نوڈز", + "اسمارٹ معاہدات", + "مرکبیت", + "کنسینسس لیئر", + "ایگزیکیوشن لیئر", + "testing" + ] +skill: intermediate +lang: ur-in +published: 2023-04-11 +--- + +## تعارف {#introduction} + +یہ گائیڈ آپ کو ایک قابل ترتیب مقامی Ethereum ٹیسٹ نیٹ کو انسٹینٹیٹ کرنے، اس پر ایک اسمارٹ کنٹریکٹ ڈیپلائے کرنے، اور آپ کے dApp کے خلاف ٹیسٹ چلانے کے لیے ٹیسٹ نیٹ کا استعمال کرنے کے عمل کے بارے میں بتاتا ہے۔ یہ گائیڈ ان dApp ڈیولپرز کے لیے ڈیزائن کیا گیا ہے جو لائیو ٹیسٹ نیٹ یا مین نیٹ پر ڈیپلائے کرنے سے پہلے اپنے dApps کو مقامی طور پر مختلف نیٹ ورک کنفیگریشنز کے خلاف تیار اور ٹیسٹ کرنا چاہتے ہیں۔ + +اس گائیڈ میں، آپ: + +- [Kurtosis](https://www.kurtosis.com/) کا استعمال کرتے ہوئے [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package) کے ساتھ ایک مقامی Ethereum ٹیسٹ نیٹ کو انسٹینٹیٹ کریں، +- اپنے Hardhat dApp ڈیولپمنٹ ماحول کو مقامی ٹیسٹ نیٹ سے جوڑیں تاکہ dApp کو کمپائل، ڈیپلائے اور ٹیسٹ کیا جا سکے، اور +- مقامی ٹیسٹ نیٹ کو کنفیگر کریں، بشمول نوڈس کی تعداد اور مخصوص EL/CL کلائنٹ جوڑی جیسے پیرامیٹرز، تاکہ مختلف نیٹ ورک کنفیگریشنز کے خلاف ڈیولپمنٹ اور ٹیسٹنگ ورک فلوز کو فعال کیا جا سکے۔ + +### Kurtosis کیا ہے؟ {#what-is-kurtosis} + +[Kurtosis](https://www.kurtosis.com/) ایک کمپوزیبل بلڈ سسٹم ہے جو ملٹی کنٹینر ٹیسٹ ماحول کو کنفیگر کرنے کے لیے ڈیزائن کیا گیا ہے۔ یہ خاص طور پر ڈیولپرز کو قابل تولید ماحول بنانے کے قابل بناتا ہے جس کے لیے ڈائنامک سیٹ اپ لاجک کی ضرورت ہوتی ہے، جیسے کہ بلاک چین ٹیسٹ نیٹس۔ + +اس گائیڈ میں، Kurtosis eth-network-package [`geth`](https://geth.ethereum.org/) ایگزیکیوشن لیئر (EL) کلائنٹ، نیز [`teku`](https://consensys.io/teku)، [`lighthouse`](https://lighthouse.sigmaprime.io/)، اور [`lodestar`](https://lodestar.chainsafe.io/) کنسینسس لیئر (CL) کلائنٹس کے لیے سپورٹ کے ساتھ ایک مقامی Ethereum ٹیسٹ نیٹ اسپن اپ کرتا ہے۔ یہ پیکیج Hardhat Network، Ganache، اور Anvil جیسے فریم ورکس میں نیٹ ورکس کے لیے ایک قابل ترتیب اور کمپوزیبل متبادل کے طور پر کام کرتا ہے۔ Kurtosis ڈیولپرز کو ان کے استعمال کردہ ٹیسٹ نیٹس پر زیادہ کنٹرول اور لچک فراہم کرتا ہے، جو ایک بڑی وجہ ہے کہ [Ethereum فاؤنڈیشن نے The Merge کو ٹیسٹ کرنے کے لیے Kurtosis کا استعمال کیا](https://www.kurtosis.com/blog/testing-the-ethereum-merge) اور نیٹ ورک اپ گریڈ کی جانچ کے لیے اس کا استعمال جاری رکھے ہوئے ہے۔ + +## Kurtosis سیٹ اپ کرنا {#setting-up-kurtosis} + +آگے بڑھنے سے پہلے، یقینی بنائیں کہ آپ کے پاس ہے: + +- اپنی مقامی مشین پر [ڈاکر انجن انسٹال اور شروع کیا](https://docs.kurtosis.com/install/#i-install--start-docker) +- [Kurtosis CLI انسٹال کیا](https://docs.kurtosis.com/install#ii-install-the-cli) (یا اگر آپ کے پاس پہلے سے ہی CLI انسٹال ہے تو اسے تازہ ترین ریلیز میں اپ گریڈ کیا) +- [Node.js](https://nodejs.org/en)، [yarn](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable)، اور [npx](https://www.npmjs.com/package/npx) انسٹال کیا (آپ کے dApp ماحول کے لیے) + +## ایک مقامی Ethereum ٹیسٹ نیٹ کو انسٹینٹیٹ کرنا {#instantiate-testnet} + +مقامی Ethereum ٹیسٹ نیٹ کو اسپن اپ کرنے کے لیے، چلائیں: + +```python +kurtosis --enclave local-eth-testnet run github.com/kurtosis-tech/eth-network-package +``` + +نوٹ: یہ کمانڈ `--enclave` فلیگ کا استعمال کرتے ہوئے آپ کے نیٹ ورک کا نام: \"local-eth-testnet\" رکھتا ہے۔ + +Kurtosis ان اقدامات کو پرنٹ کرے گا جو وہ ہدایات کی تشریح، توثیق، اور پھر عمل درآمد کے لیے پس پردہ اٹھا رہا ہے۔ آخر میں، آپ کو ایک آؤٹ پٹ نظر آنا چاہیے جو درج ذیل سے ملتا جلتا ہو: + +```python +INFO[2023-04-04T18:09:44-04:00] ====================================================== +INFO[2023-04-04T18:09:44-04:00] || Created enclave: local-eth-testnet || +INFO[2023-04-04T18:09:44-04:00] ====================================================== +Name: local-eth-testnet +UUID: 39372d756ae8 +Status: RUNNING +Creation Time: Tue, 04 Apr 2023 18:09:03 EDT + +========================================= Files Artifacts ========================================= +UUID Name +d4085a064230 cl-genesis-data +1c62cb792e4c el-genesis-data +bd60489b73a7 genesis-generation-config-cl +b2e593fe5228 genesis-generation-config-el +d552a54acf78 geth-prefunded-keys +5f7e661eb838 prysm-password +054e7338bb59 validator-keystore-0 + +========================================== User Services ========================================== +UUID Name Ports Status +e20f129ee0c5 cl-client-0-beacon http: 4000/tcp -> RUNNING + metrics: 5054/tcp -> + tcp-discovery: 9000/tcp -> 127.0.0.1:54263 + udp-discovery: 9000/udp -> 127.0.0.1:60470 +a8b6c926cdb4 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:54267 RUNNING + metrics: 5064/tcp -> +d7b802f623e8 el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:54253 RUNNING + rpc: 8545/tcp -> 127.0.0.1:54251 + tcp-discovery: 30303/tcp -> 127.0.0.1:54254 + udp-discovery: 30303/udp -> 127.0.0.1:53834 + ws: 8546/tcp -> 127.0.0.1:54252 +514a829c0a84 prelaunch-data-generator-1680646157905431468 STOPPED +62bd62d0aa7a prelaunch-data-generator-1680646157915424301 STOPPED +05e9619e0e90 prelaunch-data-generator-1680646157922872635 STOPPED + +``` + +مبارک ہو! آپ نے Docker پر ایک مقامی Ethereum ٹیسٹ نیٹ کو انسٹینٹیٹ کرنے کے لیے Kurtosis کا استعمال کیا، جس میں ایک CL (`lighthouse`) اور EL کلائنٹ (`geth`) ہے۔ + +### جائزہ {#review-instantiate-testnet} + +اس سیکشن میں، آپ نے ایک کمانڈ چلائی جس نے Kurtosis کو ہدایت دی کہ وہ Kurtosis [Enclave](https://docs.kurtosis.com/advanced-concepts/enclaves/) کے اندر ایک مقامی Ethereum ٹیسٹ نیٹ کو اسپن اپ کرنے کے لیے GitHub پر دور سے میزبان [`eth-network-package`](https://github.com/kurtosis-tech/eth-network-package) کا استعمال کرے۔ اپنے انکلیو کے اندر، آپ کو \"فائل آرٹفیکٹس\" اور \"یوزر سروسز\" دونوں ملیں گے۔ + +آپ کے انکلیو میں موجود [فائل آرٹفیکٹس](https://docs.kurtosis.com/advanced-concepts/files-artifacts/) میں EL اور CL کلائنٹس کو بوٹسٹریپ کرنے کے لیے تیار اور استعمال ہونے والا تمام ڈیٹا شامل ہے۔ یہ ڈیٹا `prelaunch-data-generator` سروس کا استعمال کرتے ہوئے بنایا گیا تھا جو اس [ڈاکر امیج](https://github.com/ethpandaops/ethereum-genesis-generator) سے بنائی گئی ہے۔ + +یوزر سروسز آپ کے انکلیو میں کام کرنے والی تمام کنٹینرائزڈ سروسز کو ظاہر کرتی ہیں۔ آپ دیکھیں گے کہ ایک واحد نوڈ بنایا گیا ہے، جس میں ایک EL کلائنٹ اور ایک CL کلائنٹ دونوں شامل ہیں۔ + +## اپنے dApp ڈیولپمنٹ ماحول کو مقامی Ethereum ٹیسٹ نیٹ سے جوڑیں {#connect-your-dapp} + +### dApp ڈیولپمنٹ ماحول سیٹ اپ کریں {#set-up-dapp-env} + +اب جب کہ آپ کے پاس ایک چلتا ہوا مقامی ٹیسٹ نیٹ ہے، آپ اپنے dApp ڈیولپمنٹ ماحول کو اپنے مقامی ٹیسٹ نیٹ کو استعمال کرنے کے لیے جوڑ سکتے ہیں۔ اس گائیڈ میں آپ کے مقامی ٹیسٹ نیٹ پر بلیک جیک dApp کو ڈیپلائے کرنے کے لیے Hardhat فریم ورک کا استعمال کیا جائے گا۔ + +اپنے dApp ڈیولپمنٹ ماحول کو سیٹ اپ کرنے کے لیے، اس ریپوزٹری کو کلون کریں جس میں ہمارا نمونہ dApp ہے اور اس کی انحصاریوں کو انسٹال کریں، چلائیں: + +```python +git clone https://github.com/kurtosis-tech/awesome-kurtosis.git && cd awesome-kurtosis/smart-contract-example && yarn +``` + +یہاں استعمال ہونے والا [smart-contract-example](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example) فولڈر [Hardhat](https://hardhat.org/) فریم ورک استعمال کرنے والے dApp ڈیولپر کے لیے عام سیٹ اپ پر مشتمل ہے: + +- [`contracts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/contracts) میں بلیک جیک dApp کے لیے کچھ سادہ اسمارٹ کنٹریکٹس شامل ہیں۔ +- [`scripts/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/scripts) میں آپ کے مقامی Ethereum نیٹ ورک پر ٹوکن کنٹریکٹ ڈیپلائے کرنے کے لیے ایک اسکرپٹ شامل ہے۔ +- [`test/`](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/smart-contract-example/test) میں آپ کے ٹوکن کنٹریکٹ کے لیے ایک سادہ .js ٹیسٹ شامل ہے تاکہ اس بات کی تصدیق کی جا سکے کہ ہمارے بلیک جیک dApp میں ہر کھلاڑی کے لیے 1000 منٹ کیے گئے ہیں۔ +- [`hardhat.config.ts`](https://github.com/kurtosis-tech/awesome-kurtosis/blob/main/smart-contract-example/hardhat.config.ts) آپ کے Hardhat سیٹ اپ کو کنفیگر کرتا ہے + +### مقامی ٹیسٹ نیٹ استعمال کرنے کے لیے Hardhat کو کنفیگر کریں {#configure-hardhat} + +اپنے dApp ڈیولپمنٹ ماحول کے سیٹ اپ کے ساتھ، اب آپ Kurtosis کا استعمال کرتے ہوئے تیار کردہ مقامی Ethereum ٹیسٹ نیٹ کو استعمال کرنے کے لیے Hardhat کو جوڑیں گے۔ اسے پورا کرنے کے لیے، اپنی `hardhat.config.ts` کنفیگ فائل میں `localnet` سٹرکٹ میں `<$YOUR_PORT>` کو کسی بھی `el-client-` سروس سے rpc uri آؤٹ پٹ کے پورٹ سے بدل دیں۔ اس نمونہ کیس میں، پورٹ `64248` ہوگا۔ آپ کا پورٹ مختلف ہوگا۔ + +`hardhat.config.ts` میں مثال: + +```js +localnet: { +url: 'http://127.0.0.1:<$YOUR_PORT>',// TODO: $YOUR_PORT کو ETH نیٹ ورک KURTOSIS پیکیج کے ذریعہ تیار کردہ نوڈ URI کے پورٹ سے تبدیل کریں + +// یہ eth-network-package کے ذریعہ بنائے گئے پہلے سے فنڈ شدہ ٹیسٹ اکاؤنٹس سے وابستہ پرائیویٹ کیز ہیں +// +accounts: [ + "ef5177cd0b6b21c87db5a0bf35d4084a8a57a9d6a064f86d51ac85f2b873a4e2", + "48fcc39ae27a0e8bf0274021ae6ebd8fe4a0e12623d61464c498900b28feb567", + "7988b3a148716ff800414935b305436493e1f25237a2a03e5eebc343735e2f31", + "b3c409b6b0b3aa5e65ab2dc1930534608239a478106acf6f3d9178e9f9b00b35", + "df9bb6de5d3dc59595bcaa676397d837ff49441d211878c024eabda2cd067c9f", + "7da08f856b5956d40a72968f93396f6acff17193f013e8053f6fbb6c08c194d6", + ], +}, +``` + +ایک بار جب آپ اپنی فائل محفوظ کر لیتے ہیں، تو آپ کا Hardhat dApp ڈیولپمنٹ ماحول اب آپ کے مقامی Ethereum ٹیسٹ نیٹ سے جڑ جاتا ہے! آپ یہ چلا کر تصدیق کر سکتے ہیں کہ آپ کا ٹیسٹ نیٹ کام کر رہا ہے: + +```python +npx hardhat balances --network localnet +``` + +آؤٹ پٹ کچھ اس طرح نظر آنا چاہئے: + +```python +0x878705ba3f8Bc32FCf7F4CAa1A35E72AF65CF766 has balance 10000000000000000000000000 +0x4E9A3d9D1cd2A2b2371b8b3F489aE72259886f1A has balance 10000000000000000000000000 +0xdF8466f277964Bb7a0FFD819403302C34DCD530A has balance 10000000000000000000000000 +0x5c613e39Fc0Ad91AfDA24587e6f52192d75FBA50 has balance 10000000000000000000000000 +0x375ae6107f8cC4cF34842B71C6F746a362Ad8EAc has balance 10000000000000000000000000 +0x1F6298457C5d76270325B724Da5d1953923a6B88 has balance 10000000000000000000000000 +``` + +اس سے تصدیق ہوتی ہے کہ Hardhat آپ کے مقامی ٹیسٹ نیٹ کا استعمال کر رہا ہے اور `eth-network-package` کے ذریعہ بنائے گئے پہلے سے فنڈ شدہ اکاؤنٹس کا پتہ لگاتا ہے۔ + +### مقامی طور پر اپنے dApp کو ڈیپلائے اور ٹیسٹ کریں {#deploy-and-test-dapp} + +dApp ڈیولپمنٹ ماحول کے مقامی Ethereum ٹیسٹ نیٹ سے مکمل طور پر منسلک ہونے کے ساتھ، اب آپ مقامی ٹیسٹ نیٹ کا استعمال کرتے ہوئے اپنے dApp کے خلاف ڈیولپمنٹ اور ٹیسٹنگ ورک فلو چلا سکتے ہیں۔ + +`ChipToken.sol` اسمارٹ کنٹریکٹ کو مقامی پروٹو ٹائپنگ اور ڈیولپمنٹ کے لیے کمپائل اور ڈیپلائے کرنے کے لیے، چلائیں: + +```python +npx hardhat compile +npx hardhat run scripts/deploy.ts --network localnet +``` + +آؤٹ پٹ کچھ اس طرح نظر آنا چاہئے: + +```python +ChipToken ڈیپلائے کیا گیا: 0xAb2A01BC351770D09611Ac80f1DE076D56E0487d +``` + +اب اپنے مقامی dApp کے خلاف `simple.js` ٹیسٹ چلانے کی کوشش کریں تاکہ اس بات کی تصدیق کی جا سکے کہ ہمارے بلیک جیک dApp میں ہر کھلاڑی کے لیے 1000 منٹ کیے گئے ہیں: + +آؤٹ پٹ کچھ اس طرح نظر آنا چاہئے: + +```python +npx hardhat test --network localnet +``` + +آؤٹ پٹ کچھ اس طرح نظر آنا چاہئے: + +```python +ChipToken + mint + ✔ should mint 1000 chips for PLAYER ONE + + 1 passing (654ms) +``` + +### جائزہ {#review-dapp-workflows} + +اس مقام پر، آپ نے اب ایک dApp ڈیولپمنٹ ماحول سیٹ اپ کیا ہے، اسے Kurtosis کے ذریعہ بنائے گئے مقامی Ethereum نیٹ ورک سے جوڑا ہے، اور اپنے dApp کے خلاف ایک سادہ ٹیسٹ کمپائل، ڈیپلائے، اور چلایا ہے۔ + +اب آئیے دریافت کریں کہ آپ مختلف نیٹ ورک کنفیگریشنز کے تحت ہمارے dApps کی جانچ کے لیے بنیادی نیٹ ورک کو کیسے کنفیگر کر سکتے ہیں۔ + +## مقامی Ethereum ٹیسٹ نیٹ کو کنفیگر کرنا {#configure-testnet} + +### کلائنٹ کنفیگریشنز اور نوڈس کی تعداد کو تبدیل کرنا {#configure-client-config-and-num-nodes} + +آپ کا مقامی Ethereum ٹیسٹ نیٹ مختلف EL اور CL کلائنٹ جوڑوں کے ساتھ ساتھ نوڈس کی مختلف تعداد کو استعمال کرنے کے لیے کنفیگر کیا جا سکتا ہے، اس منظر نامے اور مخصوص نیٹ ورک کنفیگریشن پر منحصر ہے جسے آپ تیار یا ٹیسٹ کرنا چاہتے ہیں۔ اس کا مطلب ہے کہ، ایک بار سیٹ اپ ہونے کے بعد، آپ ایک حسب ضرورت مقامی ٹیسٹ نیٹ کو اسپن اپ کر سکتے ہیں اور اسے وہی ورک فلو (ڈیپلائمنٹ، ٹیسٹ، وغیرہ) چلانے کے لیے استعمال کر سکتے ہیں۔ مختلف نیٹ ورک کنفیگریشنز کے تحت یہ یقینی بنانے کے لیے کہ سب کچھ توقع کے مطابق کام کرتا ہے۔ دیگر پیرامیٹرز کے بارے میں مزید جاننے کے لیے جن میں آپ ترمیم کر سکتے ہیں، اس لنک پر جائیں۔ + +اسے آزمائیں! آپ JSON فائل کے ذریعے `eth-network-package` کو مختلف کنفیگریشن آپشنز پاس کر سکتے ہیں۔ یہ نیٹ ورک پیرامیٹرز JSON فائل وہ مخصوص کنفیگریشنز فراہم کرتی ہے جو Kurtosis مقامی Ethereum نیٹ ورک کو سیٹ اپ کرنے کے لیے استعمال کرے گا۔ + +ڈیفالٹ کنفیگریشن فائل لیں اور اسے مختلف EL/CL جوڑوں کے ساتھ دو نوڈس کو اسپن اپ کرنے کے لیے ترمیم کریں: + +- نوڈ 1 `geth`/`lighthouse` کے ساتھ +- نوڈ 2 `geth`/`lodestar` کے ساتھ +- نوڈ 3 `geth`/`teku` کے ساتھ + +یہ کنفیگریشن آپ کے dApp کی جانچ کے لیے Ethereum نوڈ کے نفاذ کا ایک متضاد نیٹ ورک بناتی ہے۔ آپ کی کنفیگریشن فائل اب اس طرح نظر آنی چاہئے: + +```yaml +{ + "participants": + [ + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lighthouse", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "lodestar", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + { + "el_client_type": "geth", + "el_client_image": "", + "el_client_log_level": "", + "cl_client_type": "teku", + "cl_client_image": "", + "cl_client_log_level": "", + "beacon_extra_params": [], + "el_extra_params": [], + "validator_extra_params": [], + "builder_network_params": null, + }, + ], + "network_params": + { + "preregistered_validator_keys_mnemonic": "giant issue aisle success illegal bike spike question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy very lucky have athlete", + "num_validator_keys_per_node": 64, + "network_id": "3151908", + "deposit_contract_address": "0x4242424242424242424242424242424242424242", + "seconds_per_slot": 12, + "genesis_delay": 120, + "capella_fork_epoch": 5, + }, +} +``` + +ہر `participants` سٹرکٹ نیٹ ورک میں ایک نوڈ سے مطابقت رکھتا ہے، لہذا 3 `participants` سٹرکٹس Kurtosis کو آپ کے نیٹ ورک میں 3 نوڈس کو اسپن اپ کرنے کے لیے کہیں گے۔ ہر `participants` سٹرکٹ آپ کو اس مخصوص نوڈ کے لیے استعمال ہونے والے EL اور CL جوڑے کی وضاحت کرنے کی اجازت دے گا۔ + +`network_params` سٹرکٹ نیٹ ورک کی ترتیبات کو کنفیگر کرتا ہے جو ہر نوڈ کے لیے جینیسس فائلیں بنانے کے ساتھ ساتھ دیگر ترتیبات جیسے نیٹ ورک کے فی سلاٹ سیکنڈز کے لیے استعمال ہوتی ہیں۔ + +اپنی ترمیم شدہ پیرامیٹرز فائل کو کسی بھی ڈائرکٹری میں محفوظ کریں جس میں آپ چاہیں (نیچے دی گئی مثال میں، اسے ڈیسک ٹاپ پر محفوظ کیا گیا ہے) اور پھر اسے چلا کر اپنا Kurtosis پیکیج چلائیں: + +```python +kurtosis clean -a && kurtosis run --enclave local-eth-testnet github.com/kurtosis-tech/eth-network-package "$(cat ~/eth-network-params.json)" +``` + +نوٹ: `kurtosis clean -a` کمانڈ یہاں Kurtosis کو ہدایت دینے کے لیے استعمال کی جاتی ہے کہ وہ پرانے ٹیسٹ نیٹ اور اس کے مواد کو نیا شروع کرنے سے پہلے تباہ کر دے۔ + +ایک بار پھر، Kurtosis تھوڑی دیر کے لیے کام کرے گا اور انفرادی اقدامات کو پرنٹ کرے گا جو ہو رہے ہیں۔ آخر کار، آؤٹ پٹ کچھ اس طرح نظر آنا چاہئے: + +```python +Starlark code successfully run. No output was returned. +INFO[2023-04-07T11:43:16-04:00] ========================================================== +INFO[2023-04-07T11:43:16-04:00] || Created enclave: local-eth-testnet || +INFO[2023-04-07T11:43:16-04:00] ========================================================== +Name: local-eth-testnet +UUID: bef8c192008e +Status: RUNNING +Creation Time: Fri, 07 Apr 2023 11:41:58 EDT + +========================================= Files Artifacts ========================================= +UUID Name +cc495a8e364a cl-genesis-data +7033fcdb5471 el-genesis-data +a3aef43fc738 genesis-generation-config-cl +8e968005fc9d genesis-generation-config-el +3182cca9d3cd geth-prefunded-keys +8421166e234f prysm-password +d9e6e8d44d99 validator-keystore-0 +23f5ba517394 validator-keystore-1 +4d28dea40b5c validator-keystore-2 + +========================================== User Services ========================================== +UUID Name Ports Status +485e6fde55ae cl-client-0-beacon http: 4000/tcp -> http://127.0.0.1:65010 RUNNING + metrics: 5054/tcp -> http://127.0.0.1:65011 + tcp-discovery: 9000/tcp -> 127.0.0.1:65012 + udp-discovery: 9000/udp -> 127.0.0.1:54455 +73739bd158b2 cl-client-0-validator http: 5042/tcp -> 127.0.0.1:65016 RUNNING + metrics: 5064/tcp -> http://127.0.0.1:65017 +1b0a233cd011 cl-client-1-beacon http: 4000/tcp -> 127.0.0.1:65021 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65023 + tcp-discovery: 9000/tcp -> 127.0.0.1:65024 + udp-discovery: 9000/udp -> 127.0.0.1:56031 + validator-metrics: 5064/tcp -> 127.0.0.1:65022 +949b8220cd53 cl-client-1-validator http: 4000/tcp -> 127.0.0.1:65028 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65030 + tcp-discovery: 9000/tcp -> 127.0.0.1:65031 + udp-discovery: 9000/udp -> 127.0.0.1:60784 + validator-metrics: 5064/tcp -> 127.0.0.1:65029 +c34417bea5fa cl-client-2 http: 4000/tcp -> 127.0.0.1:65037 RUNNING + metrics: 8008/tcp -> 127.0.0.1:65035 + tcp-discovery: 9000/tcp -> 127.0.0.1:65036 + udp-discovery: 9000/udp -> 127.0.0.1:63581 +e19738e6329d el-client-0 engine-rpc: 8551/tcp -> 127.0.0.1:64986 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64988 + tcp-discovery: 30303/tcp -> 127.0.0.1:64987 + udp-discovery: 30303/udp -> 127.0.0.1:55706 + ws: 8546/tcp -> 127.0.0.1:64989 +e904687449d9 el-client-1 engine-rpc: 8551/tcp -> 127.0.0.1:64993 RUNNING + rpc: 8545/tcp -> 127.0.0.1:64995 + tcp-discovery: 30303/tcp -> 127.0.0.1:64994 + udp-discovery: 30303/udp -> 127.0.0.1:58096 + ws: 8546/tcp -> 127.0.0.1:64996 +ad6f401126fa el-client-2 engine-rpc: 8551/tcp -> 127.0.0.1:65003 RUNNING + rpc: 8545/tcp -> 127.0.0.1:65001 + tcp-discovery: 30303/tcp -> 127.0.0.1:65000 + udp-discovery: 30303/udp -> 127.0.0.1:57269 + ws: 8546/tcp -> 127.0.0.1:65002 +12d04a9dbb69 prelaunch-data-generator-1680882122181135513 STOPPED +5b45f9c0504b prelaunch-data-generator-1680882122192182847 STOPPED +3d4aaa75e218 prelaunch-data-generator-1680882122201668972 STOPPED +``` + +مبارک ہو! آپ نے کامیابی سے اپنے مقامی ٹیسٹ نیٹ کو 1 کے بجائے 3 نوڈس رکھنے کے لیے کنفیگر کر لیا ہے۔ اپنے dApp (ڈیپلائے اور ٹیسٹ) کے خلاف وہی ورک فلو چلانے کے لیے جو آپ نے پہلے کیے تھے، وہی آپریشنز انجام دیں جو ہم نے پہلے `<$YOUR_PORT>` کو اپنی `hardhat.config.ts` کنفیگ فائل میں `localnet` سٹرکٹ میں اپنے نئے، 3-نوڈ مقامی ٹیسٹ نیٹ میں کسی بھی `el-client-` سروس سے rpc uri آؤٹ پٹ کے پورٹ سے تبدیل کر کے کیے تھے۔ + +## نتیجہ {#conclusion} + +اور بس! اس مختصر گائیڈ کا خلاصہ کرنے کے لیے، آپ نے: + +- Kurtosis کا استعمال کرتے ہوئے Docker پر ایک مقامی Ethereum ٹیسٹ نیٹ بنایا +- اپنے مقامی dApp ڈیولپمنٹ ماحول کو مقامی Ethereum نیٹ ورک سے جوڑا +- مقامی Ethereum نیٹ ورک پر ایک dApp ڈیپلائے کیا اور اس کے خلاف ایک سادہ ٹیسٹ چلایا +- بنیادی Ethereum نیٹ ورک کو 3 نوڈس رکھنے کے لیے کنفیگر کیا + +ہم آپ سے یہ سننا پسند کریں گے کہ آپ کے لیے کیا اچھا رہا، کیا بہتر کیا جا سکتا ہے، یا آپ کے کسی بھی سوال کا جواب دینا۔ [GitHub](https://github.com/kurtosis-tech/kurtosis/issues/new/choose) کے ذریعے رابطہ کرنے یا [ہمیں ای میل](mailto:feedback@kurtosistech.com) کرنے میں ہچکچاہٹ محسوس نہ کریں! + +### دیگر مثالیں اور گائیڈز {#other-examples-guides} + +ہم آپ کو ہمارے [کوئیک اسٹارٹ](https://docs.kurtosis.com/quickstart) (جہاں آپ سب سے اوپر ایک Postgres ڈیٹا بیس اور API بنائیں گے) اور ہماری [awesome-kurtosis ریپوزٹری](https://github.com/kurtosis-tech/awesome-kurtosis) میں ہماری دیگر مثالیں دیکھنے کی ترغیب دیتے ہیں جہاں آپ کو کچھ بہترین مثالیں ملیں گی، بشمول ان کے لیے پیکیجز: + +- [اسی مقامی Ethereum ٹیسٹ نیٹ کو اسپن اپ کرنا](https://github.com/kurtosis-tech/eth2-package)، لیکن اضافی خدمات کے ساتھ جیسے ٹرانزیکشن اسپامر (ٹرانزیکشنز کی تقلید کے لیے)، ایک فورک مانیٹر، اور ایک منسلک Grafana اور Prometheus مثال۔ +- اسی مقامی Ethereum نیٹ ورک کے خلاف [سب-نیٹ ورکنگ ٹیسٹ](https://github.com/kurtosis-tech/awesome-kurtosis/tree/main/ethereum-network-partition-test) انجام دینا۔ diff --git a/public/content/translations/ur/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/ur/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md new file mode 100644 index 00000000000..ab602aef324 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -0,0 +1,144 @@ +--- +title: "کنٹریکٹ سائز کی حد سے نمٹنے کے لیے کنٹریکٹس کو چھوٹا کرنا" +description: "آپ اپنے اسمارٹ کنٹریکٹس کو بہت بڑا ہونے سے روکنے کے لیے کیا کر سکتے ہیں؟" +author: Markus Waas +lang: ur-in +tags: [ "solidity", "اسمارٹ معاہدات", "اسٹوریج" ] +skill: intermediate +published: 2020-06-26 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/max-contract-size +--- + +## ایک حد کیوں ہے؟ {#why-is-there-a-limit} + +[22 نومبر، 2016](https://blog.ethereum.org/2016/11/18/hard-fork-no-4-spurious-dragon/) کو Spurious Dragon ہارڈ-فورک نے [EIP-170](https://eips.ethereum.org/EIPS/eip-170) متعارف کرایا جس نے 24.576 kb کی اسمارٹ کنٹریکٹ سائز کی حد شامل کی۔ ایک Solidity ڈویلپر کے طور پر آپ کے لیے اس کا مطلب یہ ہے کہ جب آپ اپنے کنٹریکٹ میں زیادہ سے زیادہ فعالیت شامل کرتے ہیں، تو کسی وقت آپ حد تک پہنچ جائیں گے اور ڈیپلائے کرتے وقت آپ کو یہ خرابی نظر آئے گی: + +`انتباہ: کنٹریکٹ کوڈ کا سائز 24576 بائٹس سے زیادہ ہے (ایک حد جو Spurious Dragon میں متعارف کرائی گئی تھی)۔ یہ کنٹریکٹ شاید Mainnet پر ڈیپلائے نہ کیا جا سکے۔ آپٹیمائزر کو فعال کرنے پر غور کریں (کم "رنز" ویلیو کے ساتھ!)، ریورٹ اسٹرنگز کو بند کریں، یا لائبریریوں کا استعمال کریں۔` + +یہ حد ڈینائل-آف-سروس (DOS) حملوں کو روکنے کے لیے متعارف کرائی گئی تھی۔ گیس کے لحاظ سے کسی کنٹریکٹ پر کوئی بھی کال نسبتاً سستی ہوتی ہے۔ تاہم، ایتھیریم نوڈز کے لیے کنٹریکٹ کال کا اثر بلائے گئے کنٹریکٹ کوڈ کے سائز کے لحاظ سے غیر متناسب طور پر بڑھ جاتا ہے (ڈسک سے کوڈ پڑھنا، کوڈ کی پری-پروسیسنگ، مرکل پروف میں ڈیٹا شامل کرنا)۔ جب بھی آپ کے پاس ایسی صورتحال ہوتی ہے جہاں حملہ آور کو دوسروں کے لیے بہت زیادہ کام کرنے کے لیے کم وسائل کی ضرورت ہوتی ہے، تو آپ کو DOS حملوں کا امکان ہوتا ہے۔ + +اصل میں یہ کم مسئلہ تھا کیونکہ ایک قدرتی کنٹریکٹ سائز کی حد بلاک گیس کی حد ہے۔ ظاہر ہے، ایک کنٹریکٹ کو ایک ٹرانزیکشن کے اندر ڈیپلائے کیا جانا چاہیے جس میں کنٹریکٹ کا تمام بائٹ کوڈ موجود ہو۔ اگر آپ صرف اس ایک ٹرانزیکشن کو ایک بلاک میں شامل کرتے ہیں، تو آپ وہ تمام گیس استعمال کر سکتے ہیں، لیکن یہ لامحدود نہیں ہے۔ [London Upgrade](/ethereum-forks/#london) کے بعد سے، بلاک گیس کی حد نیٹ ورک کی طلب کے لحاظ سے 15M اور 30M یونٹس کے درمیان مختلف ہو سکتی ہے۔ + +ذیل میں ہم ان کے ممکنہ اثرات کے مطابق ترتیب دیے گئے کچھ طریقوں پر غور کریں گے۔ اسے وزن کم کرنے کی اصطلاح میں سوچیں۔ کسی کے لیے اپنے ہدف کے وزن (ہمارے معاملے میں 24kb) تک پہنچنے کے لیے بہترین حکمت عملی یہ ہے کہ پہلے بڑے اثر والے طریقوں پر توجہ دی جائے۔ زیادہ تر معاملات میں صرف اپنی خوراک کو ٹھیک کرنے سے آپ وہاں پہنچ جائیں گے، لیکن بعض اوقات آپ کو تھوڑا اور کرنے کی ضرورت ہوتی ہے۔ پھر آپ کچھ ورزش (درمیانے اثر) یا سپلیمنٹس (چھوٹا اثر) بھی شامل کر سکتے ہیں۔ + +## بڑا اثر {#big-impact} + +### اپنے کنٹریکٹس کو الگ کریں {#separate-your-contracts} + +یہ ہمیشہ آپ کا پہلا طریقہ ہونا چاہیے۔ آپ کنٹریکٹ کو متعدد چھوٹے کنٹریکٹس میں کیسے الگ کر سکتے ہیں؟ یہ عام طور پر آپ کو اپنے کنٹریکٹس کے لیے ایک اچھا آرکیٹیکچر تیار کرنے پر مجبور کرتا ہے۔ کوڈ کی پڑھنے کی اہلیت کے نقطہ نظر سے چھوٹے کنٹریکٹس کو ہمیشہ ترجیح دی جاتی ہے۔ کنٹریکٹس کو تقسیم کرنے کے لیے، اپنے آپ سے پوچھیں: + +- کون سے فنکشنز ایک ساتھ ہیں؟ فنکشنز کا ہر سیٹ اپنے کنٹریکٹ میں بہترین ہو سکتا ہے۔ +- کن فنکشنز کو کنٹریکٹ اسٹیٹ پڑھنے کی ضرورت نہیں ہے یا صرف اسٹیٹ کے ایک مخصوص سب سیٹ کی ضرورت ہے؟ +- کیا آپ اسٹوریج اور فعالیت کو تقسیم کر سکتے ہیں؟ + +### لائبریریاں {#libraries} + +فعالیت کے کوڈ کو اسٹوریج سے دور منتقل کرنے کا ایک آسان طریقہ [لائبریری](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#libraries) کا استعمال ہے۔ لائبریری کے فنکشنز کو اندرونی قرار نہ دیں کیونکہ یہ کمپائلیشن کے دوران براہ راست [کنٹریکٹ میں شامل](https://ethereum.stackexchange.com/questions/12975/are-internal-functions-in-libraries-not-covered-by-linking) ہو جائیں گے۔ لیکن اگر آپ پبلک فنکشنز استعمال کرتے ہیں، تو وہ درحقیقت ایک الگ لائبریری کنٹریکٹ میں ہوں گے۔ لائبریریوں کے استعمال کو مزید آسان بنانے کے لیے [using for](https://solidity.readthedocs.io/en/v0.6.10/contracts.html#using-for) پر غور کریں۔ + +### پراکسیز {#proxies} + +ایک مزید جدید حکمت عملی پراکسی سسٹم ہوگی۔ لائبریریاں پس پردہ `DELEGATECALL` کا استعمال کرتی ہیں جو کال کرنے والے کنٹریکٹ کی اسٹیٹ کے ساتھ دوسرے کنٹریکٹ کے فنکشن کو محض انجام دیتی ہیں۔ پراکسی سسٹمز کے بارے میں مزید جاننے کے لیے [یہ بلاگ پوسٹ](https://hackernoon.com/how-to-make-smart-contracts-upgradable-2612e771d5a2) دیکھیں۔ وہ آپ کو مزید فعالیت فراہم کرتے ہیں، مثال کے طور پر، وہ اپ گریڈ کی اہلیت کو فعال کرتے ہیں، لیکن وہ بہت زیادہ پیچیدگی بھی شامل کرتے ہیں۔ میں انہیں صرف کنٹریکٹ کے سائز کو کم کرنے کے لیے شامل نہیں کروں گا جب تک کہ کسی بھی وجہ سے یہ آپ کا واحد آپشن نہ ہو۔ + +## درمیانہ اثر {#medium-impact} + +### فنکشنز کو ہٹائیں {#remove-functions} + +یہ تو ظاہر ہونا چاہیے۔ فنکشنز کنٹریکٹ کا سائز کافی حد تک بڑھا دیتے ہیں۔ + +- **بیرونی**: اکثر ہم سہولت کی وجوہات کی بنا پر بہت سے ویو فنکشنز شامل کرتے ہیں۔ یہ بالکل ٹھیک ہے جب تک کہ آپ سائز کی حد تک نہ پہنچ جائیں۔ پھر آپ کو واقعی ان تمام فنکشنز کو ہٹانے کے بارے میں سوچنا چاہیے سوائے ان کے جو بالکل ضروری ہیں۔ +- **اندرونی**: آپ اندرونی/پرائیویٹ فنکشنز کو بھی ہٹا سکتے ہیں اور کوڈ کو سیدھا ان لائن کر سکتے ہیں جب تک کہ فنکشن کو صرف ایک بار کال کیا جائے۔ + +### اضافی متغیرات سے بچیں {#avoid-additional-variables} + +```solidity +function get(uint id) returns (address,address) { + MyStruct memory myStruct = myStructs[id]; + return (myStruct.addr1, myStruct.addr2); +} +``` + +```solidity +function get(uint id) returns (address,address) { + return (myStructs[id].addr1, myStructs[id].addr2); +} +``` + +اس طرح کی ایک سادہ سی تبدیلی **0.28kb** کا فرق پیدا کرتی ہے۔ امکان ہے کہ آپ اپنے کنٹریکٹس میں بہت سی ملتی جلتی صورتحال تلاش کر سکتے ہیں اور وہ واقعی ایک بڑی مقدار میں اضافہ کر سکتی ہیں۔ + +### خرابی کے پیغام کو مختصر کریں {#shorten-error-message} + +طویل ریورٹ پیغامات اور خاص طور پر بہت سے مختلف ریورٹ پیغامات کنٹریکٹ کو پھلا سکتے ہیں۔ اس کے بجائے مختصر ایرر کوڈز کا استعمال کریں اور انہیں اپنے کنٹریکٹ میں ڈی کوڈ کریں۔ ایک لمبا پیغام بہت چھوٹا ہو سکتا ہے: + +```solidity +require(msg.sender == owner, "اس فنکشن کو صرف اس کنٹریکٹ کا مالک کال کر سکتا ہے"); +``` + +```solidity +require(msg.sender == owner, "OW1"); +``` + +### خرابی کے پیغامات کے بجائے کسٹم ایررز کا استعمال کریں + +کسٹم ایررز [Solidity 0.8.4](https://blog.soliditylang.org/2021/04/21/custom-errors/) میں متعارف کرائے گئے ہیں۔ وہ آپ کے کنٹریکٹس کا سائز کم کرنے کا ایک بہترین طریقہ ہیں، کیونکہ وہ ABI-انکوڈڈ سلیکٹرز کے طور پر ہوتے ہیں (جیسے فنکشنز ہوتے ہیں)۔ + +```solidity +error Unauthorized(); + +if (msg.sender != owner) { + revert Unauthorized(); +} +``` + +### آپٹیمائزر میں کم رن ویلیو پر غور کریں {#consider-a-low-run-value-in-the-optimizer} + +آپ آپٹیمائزر کی سیٹنگز کو بھی تبدیل کر سکتے ہیں۔ 200 کی ڈیفالٹ ویلیو کا مطلب ہے کہ یہ بائٹ کوڈ کو اس طرح آپٹیمائز کرنے کی کوشش کر رہا ہے جیسے کسی فنکشن کو 200 بار کال کیا گیا ہو۔ اگر آپ اسے 1 میں تبدیل کرتے ہیں، تو آپ بنیادی طور پر آپٹیمائزر کو ہر فنکشن کو صرف ایک بار چلانے کے معاملے کے لیے آپٹیمائز کرنے کے لیے کہتے ہیں۔ صرف ایک بار چلنے کے لیے ایک آپٹمائزڈ فنکشن کا مطلب ہے کہ یہ خود ڈیپلائمنٹ کے لیے آپٹمائزڈ ہے۔ آگاہ رہیں کہ **اس سے فنکشنز کو چلانے کے لیے [گیس کے اخراجات](/developers/docs/gas/) بڑھ جاتے ہیں**، اس لیے ہو سکتا ہے کہ آپ ایسا نہ کرنا چاہیں۔ + +## چھوٹا اثر {#small-impact} + +### فنکشنز میں اسٹرکٹس کو پاس کرنے سے گریز کریں {#avoid-passing-structs-to-functions} + +اگر آپ [ABIEncoderV2](https://solidity.readthedocs.io/en/v0.6.10/layout-of-source-files.html#abiencoderv2) استعمال کر رہے ہیں، تو یہ کسی فنکشن میں اسٹرکٹس کو پاس نہ کرنے میں مدد کر سکتا ہے۔ پیرامیٹر کو بطور اسٹرکٹ پاس کرنے کے بجائے، مطلوبہ پیرامیٹرز کو براہ راست پاس کریں۔ اس مثال میں ہم نے مزید **0.1kb** بچائے۔ + +```solidity +function get(uint id) returns (address,address) { + return _get(myStruct); +} + +function _get(MyStruct memory myStruct) private view returns(address,address) { + return (myStruct.addr1, myStruct.addr2); +} +``` + +```solidity +function get(uint id) returns(address,address) { + return _get(myStructs[id].addr1, myStructs[id].addr2); +} + +function _get(address addr1, address addr2) private view returns(address,address) { + return (addr1, addr2); +} +``` + +### فنکشنز اور متغیرات کے لیے درست مرئیت کا اعلان کریں {#declare-correct-visibility-for-functions-and-variables} + +- فنکشنز یا متغیرات جو صرف باہر سے کال کیے جاتے ہیں؟ انہیں `public` کی بجائے `external` کے طور پر اعلان کریں۔ +- فنکشنز یا متغیرات جو صرف کنٹریکٹ کے اندر سے کال کیے جاتے ہیں؟ انہیں `public` کی بجائے `private` یا `internal` کے طور پر اعلان کریں۔ + +### موڈیفائرز کو ہٹائیں {#remove-modifiers} + +موڈیفائرز، خاص طور پر جب بہت زیادہ استعمال کیے جائیں، کنٹریکٹ کے سائز پر اہم اثر ڈال سکتے ہیں۔ انہیں ہٹانے اور اس کے بجائے فنکشنز استعمال کرنے پر غور کریں۔ + +```solidity +modifier checkStuff() {} + +function doSomething() checkStuff {} +``` + +```solidity +function checkStuff() private {} + +function doSomething() { checkStuff(); } +``` + +یہ ٹپس آپ کو کنٹریکٹ کا سائز نمایاں طور پر کم کرنے میں مدد کریں گی۔ ایک بار پھر، میں اس بات پر کافی زور نہیں دے سکتا، سب سے بڑے اثر کے لیے اگر ممکن ہو تو ہمیشہ کنٹریکٹس کو تقسیم کرنے پر توجہ دیں۔ diff --git a/public/content/translations/ur/developers/tutorials/eip-1271-smart-contract-signatures/index.md b/public/content/translations/ur/developers/tutorials/eip-1271-smart-contract-signatures/index.md new file mode 100644 index 00000000000..c4308fd5b46 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/eip-1271-smart-contract-signatures/index.md @@ -0,0 +1,123 @@ +--- +title: "EIP-1271: اسمارٹ کنٹریکٹ دستخط پر دستخط کرنا اور ان کی توثیق کرنا" +description: "EIP-1271 کے ساتھ اسمارٹ کنٹریکٹ دستخط کی تخلیق اور توثیق کا ایک جائزہ۔ ہم اسمارٹ کنٹریکٹ ڈیولپرز کے لیے ایک ٹھوس مثال فراہم کرنے کے لیے Safe (پہلے Gnosis Safe) میں استعمال ہونے والے EIP-1271 نفاذ کا بھی جائزہ لیتے ہیں۔" +author: Nathan H. Leung +lang: ur-in +tags: [ "eip-1271", "اسمارٹ معاہدات", "توثیق", "دستخط" ] +skill: intermediate +published: 2023-01-12 +--- + +[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) معیار اسمارٹ کنٹریکٹس کو دستخطوں کی توثیق کرنے کی اجازت دیتا ہے۔ + +اس ٹیوٹوریل میں، ہم ڈیجیٹل دستخطوں، EIP-1271 کے پس منظر، اور [Safe](https://safe.global/) (پہلے Gnosis Safe) کے ذریعے استعمال ہونے والے EIP-1271 کے مخصوص نفاذ کا ایک جائزہ دیتے ہیں۔ مجموعی طور پر، یہ آپ کے اپنے کنٹریکٹس میں EIP-1271 کو نافذ کرنے کے لیے ایک نقطہ آغاز کے طور پر کام کر سکتا ہے۔ + +## دستخط کیا ہے؟ + +اس تناظر میں، ایک دستخط (زیادہ واضح طور پر، ایک "ڈیجیٹل دستخط") ایک پیغام ہے جس کے ساتھ کسی قسم کا ثبوت ہوتا ہے کہ پیغام کسی مخصوص شخص/بھیجنے والے/ایڈریس سے آیا ہے۔ + +مثال کے طور پر، ایک ڈیجیٹل دستخط اس طرح نظر آ سکتا ہے: + +1. پیغام: "میں اپنے Ethereum والیٹ کے ساتھ اس ویب سائٹ پر لاگ ان کرنا چاہتا ہوں۔" +2. دستخط کنندہ: میرا ایڈریس `0x000…` ہے +3. ثبوت: یہاں کچھ ثبوت ہے کہ میں نے، `0x000…`، درحقیقت یہ پورا پیغام بنایا ہے (یہ عام طور پر کوئی کرپٹوگرافک چیز ہوتی ہے)۔ + +یہ نوٹ کرنا ضروری ہے کہ ڈیجیٹل دستخط میں "پیغام" اور "دستخط" دونوں شامل ہیں۔ + +کیوں؟ مثال کے طور پر، اگر آپ نے مجھے دستخط کرنے کے لیے ایک کنٹریکٹ دیا، اور پھر میں نے دستخط کا صفحہ کاٹ کر باقی کنٹریکٹ کے بغیر صرف اپنے دستخط آپ کو واپس کر دیے، تو کنٹریکٹ درست نہیں ہوگا۔ + +اسی طرح، ایک ڈیجیٹل دستخط کا متعلقہ پیغام کے بغیر کوئی مطلب نہیں ہے! + +## EIP-1271 کیوں موجود ہے؟ + +Ethereum پر مبنی بلاک چینز پر استعمال کے لیے ڈیجیٹل دستخط بنانے کے لیے، آپ کو عام طور پر ایک خفیہ پرائیویٹ کلید کی ضرورت ہوتی ہے جسے کوئی اور نہیں جانتا۔ یہی چیز آپ کے دستخط کو آپ کا بناتی ہے (خفیہ کلید کے علم کے بغیر کوئی اور وہی دستخط نہیں بنا سکتا)۔ + +آپ کے Ethereum اکاؤنٹ (یعنی، آپ کا بیرونی ملکیت والا اکاؤنٹ/EOA) کے ساتھ ایک پرائیویٹ کلید منسلک ہے، اور یہ وہ پرائیویٹ کلید ہے جو عام طور پر اس وقت استعمال ہوتی ہے جب کوئی ویب سائٹ یا ڈیپ آپ سے دستخط مانگتی ہے (مثال کے طور پر، "Ethereum کے ساتھ لاگ ان کریں" کے لیے)۔ + +ایک ایپ آپ کے بنائے ہوئے [دستخط کی توثیق](https://www.alchemy.com/docs/how-to-verify-a-message-signature-on-ethereum) ethers.js جیسی تھرڈ پارٹی لائبریری کا استعمال کرتے ہوئے [آپ کی پرائیویٹ کلید کو جانے بغیر](https://en.wikipedia.org/wiki/Public-key_cryptography) کر سکتی ہے اور اس بات پر یقین رکھ سکتی ہے کہ دستخط _آپ_ نے ہی بنایا تھا۔ + +> درحقیقت، چونکہ EOA ڈیجیٹل دستخط پبلک-کی کرپٹوگرافی کا استعمال کرتے ہیں، انہیں **آف چین** بنایا اور توثیق کیا جا سکتا ہے! گیس لیس DAO ووٹنگ اسی طرح کام کرتی ہے - آن چین ووٹ جمع کروانے کے بجائے، کرپٹوگرافک لائبریریوں کا استعمال کرتے ہوئے ڈیجیٹل دستخط آف چین بنائے اور ان کی توثیق کی جا سکتی ہے۔ + +جبکہ EOA اکاؤنٹس میں ایک پرائیویٹ کلید ہوتی ہے، اسمارٹ کنٹریکٹ اکاؤنٹس میں کسی بھی قسم کی پرائیویٹ یا خفیہ کلید نہیں ہوتی ہے (لہذا "Ethereum کے ساتھ لاگ ان کریں"، وغیرہ مقامی طور پر اسمارٹ کنٹریکٹ اکاؤنٹس کے ساتھ کام نہیں کر سکتے)۔ + +EIP-1271 جس مسئلے کو حل کرنا چاہتا ہے وہ یہ ہے: ہم کیسے بتا سکتے ہیں کہ اسمارٹ کنٹریکٹ کا دستخط درست ہے اگر اسمارٹ کنٹریکٹ میں کوئی "راز" نہیں ہے جسے وہ دستخط میں شامل کر سکے؟ + +## EIP-1271 کیسے کام کرتا ہے؟ + +اسمارٹ کنٹریکٹس میں پرائیویٹ کلیدیں نہیں ہوتیں جن کا استعمال پیغامات پر دستخط کرنے کے لیے کیا جا سکے۔ تو ہم کیسے بتا سکتے ہیں کہ دستخط اصلی ہے؟ + +ٹھیک ہے، ایک خیال یہ ہے کہ ہم صرف اسمارٹ کنٹریکٹ سے _پوچھ_ سکتے ہیں کہ کیا دستخط اصلی ہے! + +EIP-1271 جو کرتا ہے وہ یہ ہے کہ یہ اس خیال کو معیاری بناتا ہے کہ کسی اسمارٹ کنٹریکٹ سے "پوچھا جائے" کہ آیا دیا گیا دستخط درست ہے۔ + +EIP-1271 کو نافذ کرنے والے کنٹریکٹ میں `isValidSignature` نامی ایک فنکشن ہونا چاہیے جو ایک پیغام اور ایک دستخط لیتا ہے۔ کنٹریکٹ پھر کچھ توثیقی منطق چلا سکتا ہے (اسپیک یہاں کسی خاص چیز کو نافذ نہیں کرتا) اور پھر ایک قدر واپس کرتا ہے جو یہ بتاتا ہے کہ دستخط درست ہے یا نہیں۔ + +اگر `isValidSignature` ایک درست نتیجہ واپس کرتا ہے، تو یہ تقریباً کنٹریکٹ کے یہ کہنے کے مترادف ہے کہ "ہاں، میں اس دستخط + پیغام کو منظور کرتا ہوں!" + +### انٹرفیس + +یہاں EIP-1271 اسپیک میں عین مطابق انٹرفیس ہے (ہم ذیل میں `_hash` پیرامیٹر کے بارے میں بات کریں گے، لیکن ابھی کے لیے، اسے وہ پیغام سمجھیں جس کی توثیق کی جا رہی ہے): + +```jsx +pragma solidity ^0.5.0; + +contract ERC1271 { + + // bytes4(keccak256("isValidSignature(bytes32,bytes)") + bytes4 constant internal MAGICVALUE = 0x1626ba7e; + + /** + * @dev یہ واپس کرنا چاہئے کہ آیا فراہم کردہ دستخط فراہم کردہ ہیش کے لئے درست ہے + * @param _hash دستخط کیے جانے والے ڈیٹا کا ہیش + * @param _signature _hash سے وابستہ دستخط بائٹ ارے + * + * فنکشن کے پاس ہونے پر بائٹس4 میجک ویلیو 0x1626ba7e واپس کرنا لازمی ہے۔ + * اسٹیٹ میں ترمیم نہیں کرنی چاہئے (solc < 0.5 کے لیے STATICCALL کا استعمال کرتے ہوئے، solc > 0.5 کے لیے ویو موڈیفائر) + * بیرونی کالز کی اجازت ہونی چاہئے + */ + function isValidSignature( + bytes32 _hash, + bytes memory _signature) + public + view + returns (bytes4 magicValue); +} +``` + +## مثال EIP-1271 نفاذ: Safe + +کنٹریکٹس `isValidSignature` کو کئی طریقوں سے نافذ کر سکتے ہیں — اسپیک صرف عین مطابق نفاذ کے بارے میں زیادہ کچھ نہیں کہتا ہے۔ + +ایک قابل ذکر کنٹریکٹ جو EIP-1271 کو نافذ کرتا ہے وہ Safe ہے (پہلے Gnosis Safe)۔ + +Safe کے کوڈ میں، `isValidSignature` کو [نافذ کیا گیا ہے](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol) تاکہ دستخطوں کو [دو طریقوں سے](https://ethereum.stackexchange.com/questions/122635/signing-messages-as-a-gnosis-safe-eip1271-support) بنایا اور توثیق کیا جا سکے: + +1. آن چین پیغامات + 1. تخلیق: ایک سیف مالک پیغام پر "دستخط" کرنے کے لیے ایک نیا سیف ٹرانزیکشن بناتا ہے، پیغام کو ٹرانزیکشن میں ڈیٹا کے طور پر منتقل کرتا ہے۔ ایک بار جب کافی مالکان ملٹی سگ تھریشولڈ تک پہنچنے کے لیے ٹرانزیکشن پر دستخط کر دیتے ہیں، تو ٹرانزیکشن کو براڈکاسٹ کیا جاتا ہے اور چلایا جاتا ہے۔ ٹرانزیکشن میں، ایک سیف فنکشن ہے جسے (`signMessage(bytes calldata _data)`) کہا جاتا ہے جو پیغام کو "منظور شدہ" پیغامات کی فہرست میں شامل کرتا ہے۔ + 2. توثیق: Safe کنٹریکٹ پر `isValidSignature` کو کال کریں، اور توثیق کرنے کے لیے پیغام کو پیغام پیرامیٹر کے طور پر اور [دستخط پیرامیٹر کے لیے ایک خالی قدر](https://github.com/safe-global/safe-contracts/blob/main/contracts/handler/CompatibilityFallbackHandler.sol#L32) (یعنی `0x`) منتقل کریں۔ Safe دیکھے گا کہ دستخط پیرامیٹر خالی ہے اور دستخط کی کرپٹوگرافک طور پر توثیق کرنے کے بجائے، یہ جان لے گا کہ آگے بڑھ کر یہ چیک کرنا ہے کہ آیا پیغام "منظور شدہ" پیغامات کی فہرست میں ہے یا نہیں۔ +2. آف چین پیغامات: + 1. تخلیق: ایک سیف مالک آف چین ایک پیغام بناتا ہے، پھر دوسرے سیف مالکان سے انفرادی طور پر پیغام پر دستخط کرواتا ہے جب تک کہ ملٹی سگ منظوری کی حد کو عبور کرنے کے لیے کافی دستخط نہ ہو جائیں۔ + 2. توثیق: `isValidSignature` کو کال کریں۔ پیغام پیرامیٹر میں، توثیق کیے جانے والے پیغام کو منتقل کریں۔ دستخط پیرامیٹر میں، ہر سیف مالک کے انفرادی دستخطوں کو ایک ساتھ جوڑ کر، آگے پیچھے منتقل کریں۔ Safe یہ چیک کرے گا کہ حد کو پورا کرنے کے لیے کافی دستخط ہیں **اور** یہ کہ ہر دستخط درست ہے۔ اگر ایسا ہے تو، یہ ایک قدر واپس کرے گا جو دستخط کی کامیاب توثیق کی نشاندہی کرتا ہے۔ + +## `_hash` پیرامیٹر بالکل کیا ہے؟ پورا پیغام کیوں نہیں منتقل کرتے؟ + +آپ نے شاید دیکھا ہوگا کہ [EIP-1271 انٹرفیس](https://eips.ethereum.org/EIPS/eip-1271) میں `isValidSignature` فنکشن خود پیغام نہیں لیتا، بلکہ اس کے بجائے ایک `_hash` پیرامیٹر لیتا ہے۔ اس کا مطلب یہ ہے کہ `isValidSignature` میں پورا صوابدیدی لمبائی کا پیغام منتقل کرنے کے بجائے، ہم اس کے بجائے پیغام کا 32-بائٹ ہیش (عام طور پر keccak256) منتقل کرتے ہیں۔ + +کال ڈیٹا کا ہر بائٹ — یعنی، اسمارٹ کنٹریکٹ فنکشن میں منتقل کیا گیا فنکشن پیرامیٹر ڈیٹا — کی [لاگت 16 گیس (4 گیس اگر صفر بائٹ ہے)](https://eips.ethereum.org/EIPS/eip-2028) ہوتی ہے، لہذا اگر پیغام لمبا ہو تو یہ بہت زیادہ گیس بچا سکتا ہے۔ + +### پچھلی EIP-1271 تفصیلات + +عام استعمال میں EIP-1271 کی ایسی تفصیلات ہیں جن میں `isValidSignature` فنکشن ہے جس کا پہلا پیرامیٹر `bytes` قسم کا (صوابدیدی لمبائی، بجائے مقررہ لمبائی `bytes32` کے) اور پیرامیٹر کا نام `message` ہے۔ یہ EIP-1271 معیار کا ایک [پرانا ورژن](https://github.com/safe-global/safe-contracts/issues/391#issuecomment-1075427206) ہے۔ + +## میرے اپنے کنٹریکٹس میں EIP-1271 کو کیسے نافذ کیا جانا چاہئے؟ + +اسپیک یہاں بہت کھلا ہے۔ Safe نفاذ میں کچھ اچھے خیالات ہیں: + +- آپ کنٹریکٹ کے "مالک" کے EOA دستخطوں کو درست سمجھ سکتے ہیں۔ +- آپ منظور شدہ پیغامات کی ایک فہرست محفوظ کر سکتے ہیں اور صرف انہیں ہی درست سمجھ سکتے ہیں۔ + +آخر میں، یہ کنٹریکٹ ڈیولپر کے طور پر آپ پر منحصر ہے! + +## نتیجہ + +[EIP-1271](https://eips.ethereum.org/EIPS/eip-1271) ایک ہمہ جہت معیار ہے جو اسمارٹ کنٹریکٹس کو دستخطوں کی توثیق کرنے کی اجازت دیتا ہے۔ یہ اسمارٹ کنٹریکٹس کے لیے EOAs کی طرح زیادہ کام کرنے کا دروازہ کھولتا ہے — مثال کے طور پر "Ethereum کے ساتھ لاگ ان کریں" کو اسمارٹ کنٹریکٹس کے ساتھ کام کرنے کا ایک طریقہ فراہم کرتا ہے — اور اسے کئی طریقوں سے نافذ کیا جا سکتا ہے (Safe کا ایک غیر معمولی، دلچسپ نفاذ قابل غور ہے)۔ diff --git a/public/content/translations/ur/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/ur/developers/tutorials/erc-721-vyper-annotated-code/index.md new file mode 100644 index 00000000000..ffbfe173ec7 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/erc-721-vyper-annotated-code/index.md @@ -0,0 +1,643 @@ +--- +title: "Vyper ERC-721 کنٹریکٹ واک تھرو" +description: "Ryuya Nakamura کا ERC-721 کنٹریکٹ اور یہ کیسے کام کرتا ہے" +author: Ori Pomerantz +lang: ur-in +tags: [ "vyper", "erc-721", "python" ] +skill: beginner +published: 2021-04-01 +--- + +## تعارف {#introduction} + +[ERC-721](/developers/docs/standards/tokens/erc-721/) معیار نان فنجیبل ٹوکن (NFT) کی ملکیت رکھنے کے لیے استعمال کیا جاتا ہے۔ +[ERC-20](/developers/docs/standards/tokens/erc-20/) ٹوکن ایک کموڈیٹی کی طرح برتاؤ کرتے ہیں، کیونکہ انفرادی ٹوکن کے درمیان کوئی فرق نہیں ہے۔ +اس کے برعکس، ERC-721 ٹوکن ایسے اثاثوں کے لیے ڈیزائن کیے گئے ہیں جو ملتے جلتے تو ہیں لیکن ایک جیسے نہیں، جیسے کہ مختلف [بلی کے کارٹونز](https://www.cryptokitties.co/) یا رئیل اسٹیٹ کے مختلف ٹکڑوں کے ٹائٹلز۔ + +اس مضمون میں ہم [Ryuya Nakamura کے ERC-721 کنٹریکٹ](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) کا تجزیہ کریں گے۔ +یہ کنٹریکٹ [Vyper](https://vyper.readthedocs.io/en/latest/index.html) میں لکھا گیا ہے، جو ایک پائتھن جیسی کنٹریکٹ زبان ہے جسے Solidity کے مقابلے میں غیر محفوظ کوڈ لکھنا زیادہ مشکل بنانے کے لیے ڈیزائن کیا گیا ہے۔ + +## کنٹریکٹ {#contract} + +```python +# @dev ERC-721 نان فنجیبل ٹوکن معیار کا نفاذ۔ +# @author Ryuya Nakamura (@nrryuya) +# یہاں سے ترمیم شدہ: https://github.com/vyperlang/vyper/blob/de74722bf2d8718cca46902be165f9fe0e3641dd/examples/tokens/ERC721.vy +``` + +Vyper میں، جیسا کہ Python میں ہے، کمنٹس ایک ہیش (`#`) سے شروع ہوتے ہیں اور لائن کے آخر تک جاری رہتے ہیں۔ وہ کمنٹس جن میں `@` شامل ہوتا ہے [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) کے ذریعے انسان کے پڑھنے کے قابل دستاویزات تیار کرنے کے لیے استعمال ہوتے ہیں۔ + +```python +from vyper.interfaces import ERC721 + +implements: ERC721 +``` + +ERC-721 انٹرفیس Vyper زبان میں پہلے سے موجود ہے۔ +[آپ کوڈ کی تعریف یہاں دیکھ سکتے ہیں](https://github.com/vyperlang/vyper/blob/master/vyper/builtin_interfaces/ERC721.py)۔ +انٹرفیس کی تعریف Vyper کے بجائے Python میں لکھی گئی ہے، کیونکہ انٹرفیس نہ صرف بلاک چین کے اندر استعمال ہوتے ہیں، بلکہ کسی بیرونی کلائنٹ سے بلاک چین کو ٹرانزیکشن بھیجتے وقت بھی استعمال ہوتے ہیں، جو Python میں لکھا ہو سکتا ہے۔ + +پہلی لائن انٹرفیس کو امپورٹ کرتی ہے، اور دوسری لائن یہ بتاتی ہے کہ ہم اسے یہاں نافذ کر رہے ہیں۔ + +### ERC721Receiver انٹرفیس {#receiver-interface} + +```python +# safeTransferFrom() کے ذریعے کال کیے جانے والے کنٹریکٹ کے لیے انٹرفیس +interface ERC721Receiver: + def onERC721Received( +``` + +ERC-721 دو قسم کی منتقلی کو سپورٹ کرتا ہے: + +- `transferFrom`، جو بھیجنے والے کو کسی بھی منزل کے پتے کی وضاحت کرنے دیتا ہے اور منتقلی کی ذمہ داری بھیجنے والے پر ڈالتا ہے۔ اس کا مطلب ہے کہ آپ کسی غلط پتے پر منتقل کر سکتے ہیں، ایسی صورت میں NFT ہمیشہ کے لیے ضائع ہو جاتا ہے۔ +- `safeTransferFrom`، جو یہ چیک کرتا ہے کہ منزل کا پتہ کنٹریکٹ ہے یا نہیں۔ اگر ایسا ہے تو، ERC-721 کنٹریکٹ وصول کرنے والے کنٹریکٹ سے پوچھتا ہے کہ کیا وہ NFT وصول کرنا چاہتا ہے۔ + +`safeTransferFrom` کی درخواستوں کا جواب دینے کے لیے ایک وصول کرنے والے کنٹریکٹ کو `ERC721Receiver` نافذ کرنا ہوتا ہے۔ + +```python + _operator: address, + _from: address, +``` + +`_from` پتہ ٹوکن کا موجودہ مالک ہے۔ `_operator` پتہ وہ ہے جس نے منتقلی کی درخواست کی ہے (یہ دونوں ایک جیسے نہیں ہو سکتے، الاؤنسز کی وجہ سے)۔ + +```python + _tokenId: uint256, +``` + +ERC-721 ٹوکن IDs 256 بٹس کی ہوتی ہیں۔ عام طور پر وہ ٹوکن کی نمائندگی کرنے والی کسی بھی چیز کی تفصیل کو ہیش کرکے بنائے جاتے ہیں۔ + +```python + _data: Bytes[1024] +``` + +درخواست میں 1024 بائٹس تک کا صارف کا ڈیٹا ہو سکتا ہے۔ + +```python + ) -> bytes32: view +``` + +ایسے معاملات کو روکنے کے لیے جن میں کوئی کنٹریکٹ غلطی سے منتقلی قبول کر لیتا ہے، واپسی کی قیمت بولین نہیں ہوتی، بلکہ ایک مخصوص قیمت کے ساتھ 256 بٹس ہوتی ہے۔ + +یہ فنکشن ایک `view` ہے، جس کا مطلب ہے کہ یہ بلاک چین کی حالت کو پڑھ سکتا ہے، لیکن اسے تبدیل نہیں کر سکتا۔ + +### ایونٹس {#events} + +[Events](https://media.consensys.net/technical-introduction-to-events-and-logs-in-ethereum-a074d65dd61e) بلاک چین کے باہر صارفین اور سرورز کو واقعات سے آگاہ کرنے کے لیے جاری کیے جاتے ہیں۔ نوٹ کریں کہ ایونٹس کا مواد بلاک چین پر موجود کنٹریکٹس کے لیے دستیاب نہیں ہوتا ہے۔ + +```python +# @dev کسی بھی میکانزم کے ذریعے کسی بھی NFT کی ملکیت تبدیل ہونے پر جاری ہوتا ہے۔ یہ ایونٹ اس وقت جاری ہوتا ہے جب NFTs بنائے جاتے ہیں +# (`from` == 0) اور تباہ کیے جاتے ہیں (`to` == 0)۔ استثناء: کنٹریکٹ کی تخلیق کے دوران، کسی بھی +# تعداد میں NFTs ٹرانسفر جاری کیے بغیر بنائے اور تفویض کیے جا سکتے ہیں۔ کسی بھی +# منتقلی کے وقت، اس NFT کے لیے منظور شدہ پتہ (اگر کوئی ہو) کو none پر ری سیٹ کر دیا جاتا ہے۔ +# @param _from NFT کا بھیجنے والا (اگر پتہ صفر ہے تو یہ ٹوکن کی تخلیق کی نشاندہی کرتا ہے)۔ +# @param _to NFT کا وصول کنندہ (اگر پتہ صفر ہے تو یہ ٹوکن کی تباہی کی نشاندہی کرتا ہے)۔ +# @param _tokenId وہ NFT جو منتقل کیا گیا۔ +event Transfer: + sender: indexed(address) + receiver: indexed(address) + tokenId: indexed(uint256) +``` + +یہ ERC-20 ٹرانسفر ایونٹ کی طرح ہے، سوائے اس کے کہ ہم رقم کے بجائے `tokenId` کی اطلاع دیتے ہیں۔ +صفر پتے کا کوئی مالک نہیں ہے، لہذا روایت کے مطابق ہم اسے ٹوکنز کی تخلیق اور تباہی کی اطلاع دینے کے لیے استعمال کرتے ہیں۔ + +```python +# @dev یہ اس وقت جاری ہوتا ہے جب کسی NFT کے لیے منظور شدہ پتہ تبدیل کیا جاتا ہے یا اس کی دوبارہ تصدیق کی جاتی ہے۔ صفر +# پتہ اس بات کی نشاندہی کرتا ہے کہ کوئی منظور شدہ پتہ نہیں ہے۔ جب ٹرانسفر ایونٹ جاری ہوتا ہے، تو یہ بھی +# اشارہ کرتا ہے کہ اس NFT کے لیے منظور شدہ پتہ (اگر کوئی ہو) کو none پر ری سیٹ کر دیا گیا ہے۔ +# @param _owner NFT کا مالک۔ +# @param _approved وہ پتہ جسے ہم منظور کر رہے ہیں۔ +# @param _tokenId وہ NFT جسے ہم منظور کر رہے ہیں۔ +event Approval: + owner: indexed(address) + approved: indexed(address) + tokenId: indexed(uint256) +``` + +ایک ERC-721 کی منظوری ایک ERC-20 الاؤنس کی طرح ہے۔ ایک مخصوص پتے کو ایک مخصوص ٹوکن منتقل کرنے کی اجازت ہے۔ یہ کنٹریکٹس کو اس وقت جواب دینے کے لیے ایک میکانزم فراہم کرتا ہے جب وہ کوئی ٹوکن قبول کرتے ہیں۔ کنٹریکٹس ایونٹس کو نہیں سن سکتے، لہذا اگر آپ صرف ٹوکن ان کو منتقل کر دیتے ہیں تو وہ اس کے بارے میں "جانتے" نہیں ہیں۔ اس طرح مالک پہلے ایک منظوری جمع کرتا ہے اور پھر کنٹریکٹ کو ایک درخواست بھیجتا ہے: "میں نے آپ کو ٹوکن X منتقل کرنے کی منظوری دی ہے، براہ کرم کریں..."۔ + +یہ ERC-721 معیار کو ERC-20 معیار کی طرح بنانے کے لیے ایک ڈیزائن کا انتخاب ہے۔ چونکہ ERC-721 ٹوکنز فنجیبل نہیں ہیں، ایک کنٹریکٹ ٹوکن کی ملکیت کو دیکھ کر یہ بھی شناخت کر سکتا ہے کہ اسے ایک مخصوص ٹوکن ملا ہے۔ + +```python +# @dev یہ اس وقت جاری ہوتا ہے جب کسی مالک کے لیے آپریٹر کو فعال یا غیر فعال کیا جاتا ہے۔ آپریٹر مالک کے +# تمام NFTs کا انتظام کر سکتا ہے۔ +# @param _owner NFT کا مالک۔ +# @param _operator وہ پتہ جس پر ہم آپریٹر کے حقوق سیٹ کر رہے ہیں۔ +# @param _approved آپریٹر کے حقوق کی حیثیت (اگر آپریٹر کے حقوق دیے گئے ہیں تو true اور اگر +# منسوخ کیے گئے ہیں تو false)۔ +event ApprovalForAll: + owner: indexed(address) + operator: indexed(address) + approved: bool +``` + +کبھی کبھی ایک _آپریٹر_ کا ہونا مفید ہوتا ہے جو کسی مخصوص قسم کے اکاؤنٹ کے تمام ٹوکنز کا انتظام کر سکے (وہ جو ایک مخصوص کنٹریکٹ کے ذریعے منظم ہوتے ہیں)، جو کہ پاور آف اٹارنی کی طرح ہے۔ مثال کے طور پر، میں ایسی طاقت ایک ایسے کنٹریکٹ کو دینا چاہ سکتا ہوں جو یہ چیک کرے کہ کیا میں نے چھ ماہ سے اس سے رابطہ نہیں کیا ہے، اور اگر ایسا ہے تو میرے اثاثے میرے وارثوں میں تقسیم کر دے (اگر ان میں سے کوئی اس کا مطالبہ کرتا ہے، تو کنٹریکٹس ٹرانزیکشن کے ذریعے کال کیے بغیر کچھ نہیں کر سکتے)۔ ERC-20 میں ہم وراثت کے کنٹریکٹ کو ایک بڑا الاؤنس دے سکتے ہیں، لیکن یہ ERC-721 کے لیے کام نہیں کرتا کیونکہ ٹوکنز فنجیبل نہیں ہیں۔ یہ اس کے مساوی ہے۔ + +`approved` کی قیمت ہمیں بتاتی ہے کہ آیا ایونٹ منظوری کے لیے ہے، یا منظوری کی واپسی کے لیے۔ + +### اسٹیٹ متغیرات {#state-vars} + +ان متغیرات میں ٹوکنز کی موجودہ حالت ہوتی ہے: کون سے دستیاب ہیں اور ان کا مالک کون ہے۔ ان میں سے زیادہ تر `HashMap` آبجیکٹس ہیں، [یک سمتی میپنگز جو دو اقسام کے درمیان موجود ہیں](https://vyper.readthedocs.io/en/latest/types.html#mappings)۔ + +```python +# @dev NFT ID سے اس پتے تک میپنگ جو اس کا مالک ہے۔ +idToOwner: HashMap[uint256, address] + +# @dev NFT ID سے منظور شدہ پتے تک میپنگ۔ +idToApprovals: HashMap[uint256, address] +``` + +Ethereum میں صارف اور کنٹریکٹ کی شناخت 160 بٹ کے پتوں سے ظاہر ہوتی ہے۔ یہ دو متغیرات ٹوکن آئی ڈیز سے ان کے مالکان اور ان لوگوں تک میپ کرتے ہیں جنہیں انہیں منتقل کرنے کی منظوری دی گئی ہے (ہر ایک کے لیے زیادہ سے زیادہ ایک)۔ Ethereum میں، غیر شروع شدہ ڈیٹا ہمیشہ صفر ہوتا ہے، لہذا اگر کوئی مالک یا منظور شدہ ٹرانسفرر نہیں ہے تو اس ٹوکن کی قیمت صفر ہے۔ + +```python +# @dev مالک کے پتے سے اس کے ٹوکنز کی گنتی تک میپنگ۔ +ownerToNFTokenCount: HashMap[address, uint256] +``` + +یہ متغیر ہر مالک کے ٹوکنز کی گنتی رکھتا ہے۔ مالکان سے ٹوکنز تک کوئی میپنگ نہیں ہے، لہذا کسی مخصوص مالک کے ٹوکنز کی شناخت کا واحد طریقہ بلاک چین کی ایونٹ ہسٹری میں پیچھے دیکھنا اور مناسب `ٹرانسفر` ایونٹس کو دیکھنا ہے۔ ہم اس متغیر کا استعمال یہ جاننے کے لیے کر سکتے ہیں کہ جب ہمارے پاس تمام NFTs ہوں اور ہمیں وقت میں مزید پیچھے دیکھنے کی ضرورت نہ ہو۔ + +نوٹ کریں کہ یہ الگورتھم صرف یوزر انٹرفیس اور بیرونی سرورز کے لیے کام کرتا ہے۔ بلاک چین پر چلنے والا کوڈ ماضی کے ایونٹس کو نہیں پڑھ سکتا۔ + +```python +# @dev مالک کے پتے سے آپریٹر کے پتوں کی میپنگ تک میپنگ۔ +ownerToOperators: HashMap[address, HashMap[address, bool]] +``` + +ایک اکاؤنٹ میں ایک سے زیادہ آپریٹر ہو سکتے ہیں۔ ایک سادہ `HashMap` ان پر نظر رکھنے کے لیے ناکافی ہے، کیونکہ ہر کلید ایک واحد قدر کی طرف لے جاتی ہے۔ اس کے بجائے، آپ قدر کے طور پر `HashMap[address, bool]` استعمال کر سکتے ہیں۔ پہلے سے طے شدہ طور پر ہر پتے کی قدر `False` ہے، جس کا مطلب ہے کہ یہ آپریٹر نہیں ہے۔ آپ ضرورت کے مطابق قدروں کو `True` پر سیٹ کر سکتے ہیں۔ + +```python +# @dev منٹر کا پتہ، جو ٹوکن منٹ کر سکتا ہے +minter: address +``` + +نئے ٹوکن کسی نہ کسی طرح بنائے جانے چاہئیں۔ اس کنٹریکٹ میں ایک واحد ادارہ ہے جسے ایسا کرنے کی اجازت ہے، یعنی `minter`۔ یہ مثال کے طور پر ایک گیم کے لیے کافی ہونے کا امکان ہے۔ دیگر مقاصد کے لیے، زیادہ پیچیدہ کاروباری منطق بنانے کی ضرورت پڑ سکتی ہے۔ + +```python +# @dev انٹرفیس آئی ڈی سے bool تک میپنگ اس بارے میں کہ آیا یہ سپورٹڈ ہے یا نہیں +supportedInterfaces: HashMap[bytes32, bool] + +# @dev ERC165 کا ERC165 انٹرفیس آئی ڈی +ERC165_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000001ffc9a7 + +# @dev ERC721 کا ERC165 انٹرفیس آئی ڈی +ERC721_INTERFACE_ID: constant(bytes32) = 0x0000000000000000000000000000000000000000000000000000000080ac58cd +``` + +[ERC-165](https://eips.ethereum.org/EIPS/eip-165) ایک کنٹریکٹ کے لیے ایک میکانزم کی وضاحت کرتا ہے تاکہ یہ ظاہر کیا جا سکے کہ ایپلیکیشنز اس کے ساتھ کیسے بات چیت کر سکتی ہیں، اور یہ کن ERCs کے مطابق ہے۔ اس صورت میں، کنٹریکٹ ERC-165 اور ERC-721 کے مطابق ہے۔ + +### فنکشنز {#functions} + +یہ وہ فنکشنز ہیں جو دراصل ERC-721 کو نافذ کرتے ہیں۔ + +#### کنسٹرکٹر {#constructor} + +```python +@external +def __init__(): +``` + +Vyper میں، جیسا کہ Python میں ہے، کنسٹرکٹر فنکشن کو `__init__` کہا جاتا ہے۔ + +```python + """ + @dev کنٹریکٹ کنسٹرکٹر۔ + """ +``` + +Python میں، اور Vyper میں، آپ ایک ملٹی لائن اسٹرنگ کی وضاحت کرکے بھی ایک کمنٹ بنا سکتے ہیں (جو `"""` سے شروع اور ختم ہوتا ہے)، اور اسے کسی بھی طرح سے استعمال نہیں کرتے ہیں۔ ان کمنٹس میں [NatSpec](https://vyper.readthedocs.io/en/latest/natspec.html) بھی شامل ہو سکتا ہے۔ + +```python + self.supportedInterfaces[ERC165_INTERFACE_ID] = True + self.supportedInterfaces[ERC721_INTERFACE_ID] = True + self.minter = msg.sender +``` + +اسٹیٹ متغیرات تک رسائی کے لیے آپ `self.` استعمال کرتے ہیں۔` (دوبارہ، جیسا کہ پائتھن میں ہے)۔ + +#### فنکشنز دیکھیں {#views} + +یہ وہ فنکشنز ہیں جو بلاک چین کی حالت میں ترمیم نہیں کرتے ہیں، اور اس لیے اگر انہیں بیرونی طور پر کال کیا جائے تو مفت میں عمل میں لایا جا سکتا ہے۔ اگر ویو فنکشنز کو کسی کنٹریکٹ کے ذریعے کال کیا جاتا ہے تو انہیں اب بھی ہر نوڈ پر عمل میں لانا پڑتا ہے اور اس لیے گیس کی لاگت آتی ہے۔ + +```python +@view +@external +``` + +فنکشن کی تعریف سے پہلے یہ کلیدی الفاظ جو ایٹ سائن (`@`) سے شروع ہوتے ہیں، _ڈیکوریشنز_ کہلاتے ہیں۔ وہ ان حالات کی وضاحت کرتے ہیں جن میں ایک فنکشن کو کال کیا جا سکتا ہے۔ + +- `@view` اس بات کی وضاحت کرتا ہے کہ یہ فنکشن ایک ویو ہے۔ +- `@external` اس بات کی وضاحت کرتا ہے کہ اس مخصوص فنکشن کو ٹرانزیکشنز اور دیگر کنٹریکٹس کے ذریعے کال کیا جا سکتا ہے۔ + +```python +def supportsInterface(_interfaceID: bytes32) -> bool: +``` + +Python کے برعکس، Vyper ایک [اسٹیٹک ٹائپڈ زبان](https://wikipedia.org/wiki/Type_system#Static_type_checking) ہے۔ +آپ [ڈیٹا ٹائپ](https://vyper.readthedocs.io/en/latest/types.html) کی شناخت کیے بغیر کسی متغیر، یا فنکشن پیرامیٹر کا اعلان نہیں کر سکتے۔ اس صورت میں ان پٹ پیرامیٹر `bytes32` ہے، ایک 256 بٹ کی قدر ([ایتھیریم ورچوئل مشین](/developers/docs/evm/) کا مقامی لفظ سائز 256 بٹس ہے)۔ آؤٹ پٹ ایک بولین قدر ہے۔ روایت کے مطابق، فنکشن پیرامیٹرز کے نام انڈر اسکور (`_`) سے شروع ہوتے ہیں۔ + +```python + """ + @dev انٹرفیس کی شناخت ERC-165 میں بیان کی گئی ہے۔ + @param _interfaceID انٹرفیس کا آئی ڈی + """ + return self.supportedInterfaces[_interfaceID] +``` + +`self.supportedInterfaces` HashMap سے قدر واپس کریں، جو کنسٹرکٹر (`__init__`) میں سیٹ کی گئی ہے۔ + +```python +### فنکشنز دیکھیں ### + +``` + +یہ وہ ویو فنکشنز ہیں جو ٹوکنز کے بارے میں معلومات صارفین اور دیگر کنٹریکٹس کو دستیاب کراتے ہیں۔ + +```python +@view +@external +def balanceOf(_owner: address) -> uint256: + """ + @dev `_owner` کے زیر ملکیت NFTs کی تعداد واپس کرتا ہے۔ + اگر `_owner` صفر کا پتہ ہے تو تھرو کرتا ہے۔ صفر پتے کو تفویض کردہ NFTs کو غلط سمجھا جاتا ہے۔ + @param _owner وہ پتہ جس کے لیے بیلنس کی دریافت کرنی ہے۔ + """ + assert _owner != ZERO_ADDRESS +``` + +یہ لائن [asserts](https://vyper.readthedocs.io/en/latest/statements.html#assert) کرتی ہے کہ `_owner` صفر نہیں ہے۔ اگر ایسا ہے تو، ایک خرابی ہے اور آپریشن کو واپس کر دیا جاتا ہے۔ + +```python + return self.ownerToNFTokenCount[_owner] + +@view +@external +def ownerOf(_tokenId: uint256) -> address: + """ + @dev NFT کے مالک کا پتہ واپس کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + @param _tokenId ایک NFT کے لیے شناخت کنندہ۔ + """ + owner: address = self.idToOwner[_tokenId] + # اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے + assert owner != ZERO_ADDRESS + return owner +``` + +ایتھیریم ورچوئل مشین (evm) میں کوئی بھی اسٹوریج جس میں کوئی قدر ذخیرہ نہیں کی گئی ہے وہ صفر ہوتا ہے۔ +اگر `_tokenId` پر کوئی ٹوکن نہیں ہے تو `self.idToOwner[_tokenId]` کی قدر صفر ہے۔ اس صورت میں فنکشن واپس ہوجاتا ہے۔ + +```python +@view +@external +def getApproved(_tokenId: uint256) -> address: + """ + @dev ایک واحد NFT کے لیے منظور شدہ پتہ حاصل کریں۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + @param _tokenId اس NFT کا آئی ڈی جس کی منظوری کی دریافت کرنی ہے۔ + """ + # اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے + assert self.idToOwner[_tokenId] != ZERO_ADDRESS + return self.idToApprovals[_tokenId] +``` + +نوٹ کریں کہ `getApproved` صفر واپس _کر سکتا_ ہے۔ اگر ٹوکن درست ہے تو یہ `self.idToApprovals[_tokenId]` واپس کرتا ہے۔ +اگر کوئی منظور کنندہ نہیں ہے تو وہ قدر صفر ہے۔ + +```python +@view +@external +def isApprovedForAll(_owner: address, _operator: address) -> bool: + """ + @dev چیک کرتا ہے کہ آیا `_operator` `_owner` کے لیے ایک منظور شدہ آپریٹر ہے۔ + @param _owner وہ پتہ جو NFTs کا مالک ہے۔ + @param _operator وہ پتہ جو مالک کی جانب سے کام کرتا ہے۔ + """ + return (self.ownerToOperators[_owner])[_operator] +``` + +یہ فنکشن چیک کرتا ہے کہ آیا `_operator` کو اس کنٹریکٹ میں `_owner` کے تمام ٹوکنز کا انتظام کرنے کی اجازت ہے۔ +چونکہ متعدد آپریٹرز ہو سکتے ہیں، یہ ایک دو سطحی HashMap ہے۔ + +#### ٹرانسفر ہیلپر فنکشنز {#transfer-helpers} + +یہ فنکشنز ان آپریشنز کو نافذ کرتے ہیں جو ٹوکنز کی منتقلی یا انتظام کا حصہ ہیں۔ + +```python + +### ٹرانسفر فنکشن ہیلپرز ### + +@view +@internal +``` + +یہ ڈیکوریشن، `@internal`، کا مطلب ہے کہ فنکشن صرف اسی کنٹریکٹ کے اندر دیگر فنکشنز سے قابل رسائی ہے۔ روایت کے مطابق، ان فنکشنز کے نام بھی انڈر اسکور (`_`) سے شروع ہوتے ہیں۔ + +```python +def _isApprovedOrOwner(_spender: address, _tokenId: uint256) -> bool: + """ + @dev واپس کرتا ہے کہ آیا دیا گیا خرچ کنندہ ایک دیا گیا ٹوکن آئی ڈی منتقل کر سکتا ہے + @param spender خرچ کنندہ کا پتہ جس کی دریافت کرنی ہے + @param tokenId منتقل کیے جانے والے ٹوکن کا uint256 آئی ڈی + @return bool کہ آیا msg.sender دیے گئے ٹوکن آئی ڈی کے لیے منظور شدہ ہے، + مالک کا آپریٹر ہے، یا ٹوکن کا مالک ہے + """ + owner: address = self.idToOwner[_tokenId] + spenderIsOwner: bool = owner == _spender + spenderIsApproved: bool = _spender == self.idToApprovals[_tokenId] + spenderIsApprovedForAll: bool = (self.ownerToOperators[owner])[_spender] + return (spenderIsOwner or spenderIsApproved) or spenderIsApprovedForAll +``` + +کسی پتے کو ٹوکن منتقل کرنے کی اجازت دینے کے تین طریقے ہیں: + +1. پتہ ٹوکن کا مالک ہے +2. اس پتے کو وہ ٹوکن خرچ کرنے کی منظوری دی گئی ہے +3. پتہ ٹوکن کے مالک کے لیے آپریٹر ہے + +اوپر والا فنکشن ایک ویو ہو سکتا ہے کیونکہ یہ حالت کو تبدیل نہیں کرتا ہے۔ آپریٹنگ اخراجات کو کم کرنے کے لیے، کوئی بھی فنکشن جو ایک ویو ہو _سکتا_ ہے وہ ایک ویو _ہونا_ چاہیے۔ + +```python +@internal +def _addTokenTo(_to: address, _tokenId: uint256): + """ + @dev ایک دیے گئے پتے پر ایک NFT شامل کریں + اگر `_tokenId` کسی کی ملکیت میں ہے تو تھرو کرتا ہے۔ + """ + # اگر `_tokenId` کسی کی ملکیت میں ہے تو تھرو کرتا ہے + assert self.idToOwner[_tokenId] == ZERO_ADDRESS + # مالک کو تبدیل کریں + self.idToOwner[_tokenId] = _to + # گنتی ٹریکنگ کو تبدیل کریں + self.ownerToNFTokenCount[_to] += 1 + + +@internal +def _removeTokenFrom(_from: address, _tokenId: uint256): + """ + @dev ایک دیے گئے پتے سے ایک NFT ہٹائیں + اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے۔ + """ + # اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے + assert self.idToOwner[_tokenId] == _from + # مالک کو تبدیل کریں + self.idToOwner[_tokenId] = ZERO_ADDRESS + # گنتی ٹریکنگ کو تبدیل کریں + self.ownerToNFTokenCount[_from] -= 1 +``` + +جب منتقلی میں کوئی مسئلہ ہوتا ہے تو ہم کال کو واپس کر دیتے ہیں۔ + +```python +@internal +def _clearApproval(_owner: address, _tokenId: uint256): + """ + @dev دیے گئے پتے کی منظوری صاف کریں + اگر `_owner` موجودہ مالک نہیں ہے تو تھرو کرتا ہے۔ + """ + # اگر `_owner` موجودہ مالک نہیں ہے تو تھرو کرتا ہے + assert self.idToOwner[_tokenId] == _owner + if self.idToApprovals[_tokenId] != ZERO_ADDRESS: + # منظوریوں کو ری سیٹ کریں + self.idToApprovals[_tokenId] = ZERO_ADDRESS +``` + +صرف ضرورت پڑنے پر ہی قدر کو تبدیل کریں۔ اسٹیٹ متغیرات اسٹوریج میں رہتے ہیں۔ اسٹوریج میں لکھنا EVM (ایتھیریم ورچوئل مشین) کے سب سے مہنگے آپریشنز میں سے ایک ہے ([گیس](/developers/docs/gas/) کے لحاظ سے)۔ لہذا، اسے کم سے کم کرنا ایک اچھا خیال ہے، یہاں تک کہ موجودہ قدر کو لکھنے کی بھی زیادہ لاگت آتی ہے۔ + +```python +@internal +def _transferFrom(_from: address, _to: address, _tokenId: uint256, _sender: address): + """ + @dev ایک NFT کی منتقلی پر عمل کریں۔ + جب تک `msg.sender` موجودہ مالک، ایک مجاز آپریٹر، یا اس NFT کے لیے منظور شدہ + پتہ نہ ہو، تھرو کرتا ہے۔ (نوٹ: `msg.sender` کو نجی فنکشن میں اجازت نہیں ہے لہذا `_sender` پاس کریں۔) + اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے۔ + اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + """ +``` + +ہمارے پاس یہ اندرونی فنکشن ہے کیونکہ ٹوکن منتقل کرنے کے دو طریقے ہیں (باقاعدہ اور محفوظ)، لیکن ہم چاہتے ہیں کہ کوڈ میں صرف ایک ہی جگہ ہو جہاں ہم اسے کرتے ہیں تاکہ آڈیٹنگ آسان ہو۔ + +```python + # ضروریات چیک کریں + assert self._isApprovedOrOwner(_sender, _tokenId) + # اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے + assert _to != ZERO_ADDRESS + # منظوری صاف کریں۔ اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے + self._clearApproval(_from, _tokenId) + # NFT ہٹائیں۔ اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے + self._removeTokenFrom(_from, _tokenId) + # NFT شامل کریں + self._addTokenTo(_to, _tokenId) + # منتقلی کو لاگ کریں + log Transfer(_from, _to, _tokenId) +``` + +Vyper میں ایک ایونٹ جاری کرنے کے لیے آپ ایک `log` اسٹیٹمنٹ استعمال کرتے ہیں ([مزید تفصیلات کے لیے یہاں دیکھیں](https://vyper.readthedocs.io/en/latest/event-logging.html#event-logging))۔ + +#### منتقلی کے فنکشنز {#transfer-funs} + +```python + +### منتقلی کے فنکشنز ### + +@external +def transferFrom(_from: address, _to: address, _tokenId: uint256): + """ + @dev جب تک `msg.sender` موجودہ مالک، ایک مجاز آپریٹر، یا اس NFT کے لیے منظور شدہ + پتہ نہ ہو، تھرو کرتا ہے۔ + اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے۔ + اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + @notice کالر اس بات کی تصدیق کرنے کا ذمہ دار ہے کہ `_to` NFTs وصول کرنے کے قابل ہے ورنہ + وہ مستقل طور پر ضائع ہو سکتے ہیں۔ + @param _from NFT کا موجودہ مالک۔ + @param _to نیا مالک۔ + @param _tokenId منتقل کرنے کے لیے NFT۔ + """ + self._transferFrom(_from, _to, _tokenId, msg.sender) +``` + +یہ فنکشن آپ کو کسی بھی پتے پر منتقل کرنے دیتا ہے۔ جب تک کہ پتہ صارف کا نہ ہو، یا کوئی ایسا کنٹریکٹ جو ٹوکن منتقل کرنا جانتا ہو، کوئی بھی ٹوکن جو آپ منتقل کرتے ہیں وہ اس پتے میں پھنس جائے گا اور بیکار ہو جائے گا۔ + +```python +@external +def safeTransferFrom( + _from: address, + _to: address, + _tokenId: uint256, + _data: Bytes[1024]=b"" + ): + """ + @dev ایک NFT کی ملکیت ایک پتے سے دوسرے پتے پر منتقل کرتا ہے۔ + جب تک `msg.sender` موجودہ مالک، ایک مجاز آپریٹر، یا اس + NFT کے لیے منظور شدہ پتہ نہ ہو، تھرو کرتا ہے۔ + اگر `_from` موجودہ مالک نہیں ہے تو تھرو کرتا ہے۔ + اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + اگر `_to` ایک سمارٹ کنٹریکٹ ہے، تو یہ `_to` پر `onERC721Received` کو کال کرتا ہے اور اگر + واپسی کی قدر `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` نہ ہو تو تھرو کرتا ہے۔ + نوٹ: bytes4 کو پیڈنگ کے ساتھ bytes32 سے ظاہر کیا جاتا ہے + @param _from NFT کا موجودہ مالک۔ + @param _to نیا مالک۔ + @param _tokenId منتقل کرنے کے لیے NFT۔ + @param _data اضافی ڈیٹا بغیر کسی مخصوص فارمیٹ کے، `_to` کو کال میں بھیجا گیا۔ + """ + self._transferFrom(_from, _to, _tokenId, msg.sender) +``` + +پہلے منتقلی کرنا ٹھیک ہے کیونکہ اگر کوئی مسئلہ ہوتا ہے تو ہم ویسے بھی واپس کر دیں گے، لہذا کال میں کیا گیا سب کچھ منسوخ ہو جائے گا۔ + +```python + if _to.is_contract: # چیک کریں کہ آیا `_to` ایک کنٹریکٹ ایڈریس ہے +``` + +پہلے یہ دیکھنے کے لیے چیک کریں کہ آیا پتہ ایک کنٹریکٹ ہے (اگر اس میں کوڈ ہے)۔ اگر نہیں، تو فرض کریں کہ یہ صارف کا پتہ ہے اور صارف ٹوکن کا استعمال یا اسے منتقل کر سکے گا۔ لیکن اسے آپ کو تحفظ کے جھوٹے احساس میں مبتلا نہ ہونے دیں۔ آپ `safeTransferFrom` کے ساتھ بھی ٹوکن کھو سکتے ہیں، اگر آپ انہیں ایک ایسے پتے پر منتقل کرتے ہیں جس کی نجی کلید کسی کو معلوم نہیں ہے۔ + +```python + returnValue: bytes32 = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data) +``` + +ٹارگٹ کنٹریکٹ کو کال کریں تاکہ یہ دیکھا جا سکے کہ کیا وہ ERC-721 ٹوکن وصول کر سکتا ہے۔ + +```python + # اگر منتقلی کی منزل ایک کنٹریکٹ ہے جو 'onERC721Received' کو نافذ نہیں کرتا ہے تو تھرو کرتا ہے + assert returnValue == method_id("onERC721Received(address,address,uint256,bytes)", output_type=bytes32) +``` + +اگر منزل ایک کنٹریکٹ ہے، لیکن ایک ایسا جو ERC-721 ٹوکن قبول نہیں کرتا (یا جس نے اس مخصوص منتقلی کو قبول نہ کرنے کا فیصلہ کیا ہے)، تو واپس کریں۔ + +```python +@external +def approve(_approved: address, _tokenId: uint256): + """ + @dev ایک NFT کے لیے منظور شدہ پتہ سیٹ کریں یا اس کی دوبارہ تصدیق کریں۔ صفر پتہ اس بات کی نشاندہی کرتا ہے کہ کوئی منظور شدہ پتہ نہیں ہے۔ + جب تک `msg.sender` موجودہ NFT کا مالک، یا موجودہ مالک کا ایک مجاز آپریٹر نہ ہو، تھرو کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ (نوٹ: یہ EIP میں نہیں لکھا گیا ہے) + اگر `_approved` موجودہ مالک ہے تو تھرو کرتا ہے۔ (نوٹ: یہ EIP میں نہیں لکھا گیا ہے) + @param _approved دیے گئے NFT آئی ڈی کے لیے منظور کیا جانے والا پتہ۔ + @param _tokenId منظور کیے جانے والے ٹوکن کا آئی ڈی۔ + """ + owner: address = self.idToOwner[_tokenId] + # اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے + assert owner != ZERO_ADDRESS + # اگر `_approved` موجودہ مالک ہے تو تھرو کرتا ہے + assert _approved != owner +``` + +روایت کے مطابق اگر آپ کوئی منظور کنندہ نہیں رکھنا چاہتے تو آپ صفر پتے کو مقرر کرتے ہیں، خود کو نہیں۔ + +```python + # ضروریات چیک کریں + senderIsOwner: bool = self.idToOwner[_tokenId] == msg.sender + senderIsApprovedForAll: bool = (self.ownerToOperators[owner])[msg.sender] + assert (senderIsOwner or senderIsApprovedForAll) +``` + +منظوری سیٹ کرنے کے لیے آپ یا تو مالک ہو سکتے ہیں، یا مالک کی طرف سے مجاز آپریٹر۔ + +```python + # منظوری سیٹ کریں + self.idToApprovals[_tokenId] = _approved + log Approval(owner, _approved, _tokenId) + + +@external +def setApprovalForAll(_operator: address, _approved: bool): + """ + @dev کسی تیسرے فریق ("آپریٹر") کے لیے `msg.sender` کے تمام اثاثوں کا انتظام کرنے کے لیے منظوری کو فعال یا غیر فعال کرتا ہے۔ + یہ ApprovalForAll ایونٹ بھی جاری کرتا ہے۔ + اگر `_operator` `msg.sender` ہے تو تھرو کرتا ہے۔ (نوٹ: یہ EIP میں نہیں لکھا گیا ہے) + @notice یہ اس وقت بھی کام کرتا ہے جب بھیجنے والے کے پاس اس وقت کوئی ٹوکن نہ ہو۔ + @param _operator مجاز آپریٹرز کے سیٹ میں شامل کرنے کے لیے پتہ۔ + @param _approved اگر آپریٹرز منظور شدہ ہیں تو True، منظوری منسوخ کرنے کے لیے false۔ + """ + # اگر `_operator` `msg.sender` ہے تو تھرو کرتا ہے + assert _operator != msg.sender + self.ownerToOperators[msg.sender][_operator] = _approved + log ApprovalForAll(msg.sender, _operator, _approved) +``` + +#### نئے ٹوکن منٹ کریں اور موجودہ کو تباہ کریں {#mint-burn} + +وہ اکاؤنٹ جس نے کنٹریکٹ بنایا ہے وہ `minter` ہے، وہ سپر یوزر جسے نئے NFTs منٹ کرنے کا اختیار ہے۔ تاہم، اسے بھی موجودہ ٹوکنز کو جلانے کی اجازت نہیں ہے۔ صرف مالک، یا مالک کی طرف سے مجاز ادارہ، ایسا کر سکتا ہے۔ + +```python +### منٹ اور برن فنکشنز ### + +@external +def mint(_to: address, _tokenId: uint256) -> bool: +``` + +یہ فنکشن ہمیشہ `True` واپس کرتا ہے، کیونکہ اگر آپریشن ناکام ہوتا ہے تو اسے واپس کر دیا جاتا ہے۔ + +```python + """ + @dev ٹوکن منٹ کرنے کا فنکشن + اگر `msg.sender` منٹر نہیں ہے تو تھرو کرتا ہے۔ + اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے۔ + اگر `_tokenId` کسی کی ملکیت میں ہے تو تھرو کرتا ہے۔ + @param _to وہ پتہ جو منٹ کیے گئے ٹوکن وصول کرے گا۔ + @param _tokenId منٹ کیے جانے والے ٹوکن کا آئی ڈی۔ + @return ایک بولین جو اس بات کی نشاندہی کرتا ہے کہ آیا آپریشن کامیاب تھا۔ + """ + # اگر `msg.sender` منٹر نہیں ہے تو تھرو کرتا ہے + assert msg.sender == self.minter +``` + +صرف منٹر (وہ اکاؤنٹ جس نے ERC-721 کنٹریکٹ بنایا ہے) نئے ٹوکن منٹ کر سکتا ہے۔ یہ مستقبل میں ایک مسئلہ ہو سکتا ہے اگر ہم منٹر کی شناخت تبدیل کرنا چاہیں۔ ایک پروڈکشن کنٹریکٹ میں آپ شاید ایک ایسا فنکشن چاہیں گے جو منٹر کو منٹر کی مراعات کسی اور کو منتقل کرنے کی اجازت دے۔ + +```python + # اگر `_to` صفر کا پتہ ہے تو تھرو کرتا ہے + assert _to != ZERO_ADDRESS + # NFT شامل کریں۔ اگر `_tokenId` کسی کی ملکیت میں ہے تو تھرو کرتا ہے + self._addTokenTo(_to, _tokenId) + log Transfer(ZERO_ADDRESS, _to, _tokenId) + return True +``` + +روایت کے مطابق، نئے ٹوکنز کی منٹنگ صفر پتے سے منتقلی کے طور پر شمار ہوتی ہے۔ + +```python + +@external +def burn(_tokenId: uint256): + """ + @dev ایک مخصوص ERC721 ٹوکن کو جلاتا ہے۔ + جب تک `msg.sender` موجودہ مالک، ایک مجاز آپریٹر، یا اس NFT کے لیے منظور شدہ + پتہ نہ ہو، تھرو کرتا ہے۔ + اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے۔ + @param _tokenId جلائے جانے والے ERC721 ٹوکن کا uint256 آئی ڈی۔ + """ + # ضروریات چیک کریں + assert self._isApprovedOrOwner(msg.sender, _tokenId) + owner: address = self.idToOwner[_tokenId] + # اگر `_tokenId` ایک درست NFT نہیں ہے تو تھرو کرتا ہے + assert owner != ZERO_ADDRESS + self._clearApproval(owner, _tokenId) + self._removeTokenFrom(owner, _tokenId) + log Transfer(owner, ZERO_ADDRESS, _tokenId) +``` + +جو کوئی بھی ٹوکن منتقل کرنے کی اجازت رکھتا ہے اسے اسے جلانے کی اجازت ہے۔ جبکہ ایک جلانے کا عمل صفر پتے پر منتقلی کے برابر لگتا ہے، صفر پتہ دراصل ٹوکن وصول نہیں کرتا ہے۔ یہ ہمیں ٹوکن کے لیے استعمال ہونے والے تمام اسٹوریج کو آزاد کرنے کی اجازت دیتا ہے، جو ٹرانزیکشن کی گیس لاگت کو کم کر سکتا ہے۔ + +## اس کنٹریکٹ کا استعمال {#using-contract} + +Solidity کے برعکس، Vyper میں وراثت نہیں ہے۔ یہ کوڈ کو واضح اور اس لیے محفوظ بنانے کے لیے ایک دانستہ ڈیزائن کا انتخاب ہے۔ لہذا اپنا خود کا Vyper ERC-721 کنٹریکٹ بنانے کے لیے آپ [اس کنٹریکٹ](https://github.com/vyperlang/vyper/blob/master/examples/tokens/ERC721.vy) کو لیتے ہیں اور اپنی مطلوبہ کاروباری منطق کو نافذ کرنے کے لیے اس میں ترمیم کرتے ہیں۔ + +## نتیجہ {#conclusion} + +جائزے کے لیے، اس کنٹریکٹ میں کچھ اہم ترین خیالات یہ ہیں: + +- محفوظ منتقلی کے ساتھ ERC-721 ٹوکن وصول کرنے کے لیے، کنٹریکٹس کو `ERC721Receiver` انٹرفیس کو نافذ کرنا ہوتا ہے۔ +- یہاں تک کہ اگر آپ محفوظ منتقلی کا استعمال کرتے ہیں، تب بھی ٹوکن پھنس سکتے ہیں اگر آپ انہیں ایک ایسے پتے پر بھیجتے ہیں جس کی نجی کلید معلوم نہیں ہے۔ +- جب کسی آپریشن میں کوئی مسئلہ ہو تو صرف ناکامی کی قدر واپس کرنے کے بجائے کال کو `واپس` کرنا ایک اچھا خیال ہے۔ +- ERC-721 ٹوکن تب موجود ہوتے ہیں جب ان کا کوئی مالک ہوتا ہے۔ +- ایک NFT منتقل کرنے کے لیے مجاز ہونے کے تین طریقے ہیں۔ آپ مالک ہو سکتے ہیں، ایک مخصوص ٹوکن کے لیے منظور شدہ ہو سکتے ہیں، یا مالک کے تمام ٹوکنز کے لیے آپریٹر ہو سکتے ہیں۔ +- ماضی کے واقعات صرف بلاک چین کے باہر نظر آتے ہیں۔ بلاک چین کے اندر چلنے والا کوڈ انہیں نہیں دیکھ سکتا۔ + +اب جائیں اور محفوظ Vyper کنٹریکٹس نافذ کریں۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ + diff --git a/public/content/translations/ur/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/ur/developers/tutorials/erc20-annotated-code/index.md new file mode 100644 index 00000000000..642c8568278 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/erc20-annotated-code/index.md @@ -0,0 +1,834 @@ +--- +title: "ERC-20 کنٹریکٹ واک تھرو" +description: "OpenZeppelin ERC-20 کنٹریکٹ میں کیا ہے اور یہ وہاں کیوں ہے؟" +author: Ori Pomerantz +lang: ur-in +tags: [ "solidity", "erc-20" ] +skill: beginner +published: 2021-03-09 +--- + +## تعارف {#introduction} + +ایتھیریم کے سب سے عام استعمالات میں سے ایک یہ ہے کہ ایک گروپ ایک قابل تجارت ٹوکن بنائے، ایک طرح سے ان کی اپنی کرنسی۔ یہ ٹوکنز عام طور پر ایک معیار کی پیروی کرتے ہیں، +[ERC-20](/developers/docs/standards/tokens/erc-20/)۔ یہ معیار ایسے ٹولز لکھنا ممکن بناتا ہے، جیسے لیکویڈیٹی پولز اور والیٹس، جو تمام ERC-20 +ٹوکنز کے ساتھ کام کرتے ہیں۔ اس مضمون میں ہم +[OpenZeppelin Solidity ERC20 امپلیمینٹیشن](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) کے ساتھ ساتھ +[انٹرفیس ڈیفینیشن](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) کا تجزیہ کریں گے۔ + +یہ اینوٹیٹیڈ سورس کوڈ ہے۔ اگر آپ ERC-20 کو امپلیمنٹ کرنا چاہتے ہیں، +[یہ ٹیوٹوریل پڑھیں](https://docs.openzeppelin.com/contracts/2.x/erc20-supply)۔ + +## انٹرفیس {#the-interface} + +ERC-20 جیسے معیار کا مقصد بہت سے ٹوکنز امپلیمینٹیشنز کی اجازت دینا ہے جو والیٹس اور ڈی سینٹرلائزڈ ایکسچینجز جیسی ایپلیکیشنز میں انٹرآپریبل ہیں۔ اسے حاصل کرنے کے لیے، ہم ایک +[انٹرفیس](https://www.geeksforgeeks.org/solidity/solidity-basics-of-interface/) بناتے ہیں۔ کوئی بھی کوڈ جسے ٹوکن کنٹریکٹ استعمال کرنے کی ضرورت ہے وہ انٹرفیس میں وہی ڈیفینیشنز استعمال کر سکتا ہے اور اسے استعمال کرنے والے تمام ٹوکن کنٹریکٹس کے ساتھ ہم آہنگ ہو سکتا ہے، چاہے وہ MetaMask جیسا والیٹ ہو، etherscan.io جیسا dapp ہو، یا لیکویڈیٹی پول جیسا کوئی مختلف کنٹریکٹ ہو۔ + +![ERC-20 انٹرفیس کی مثال](erc20_interface.png) + +اگر آپ ایک تجربہ کار پروگرامر ہیں، تو آپ کو شاید [Java](https://www.w3schools.com/java/java_interface.asp) یا یہاں تک کہ [C ہیڈر فائلز](https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html) میں بھی اسی طرح کی کنسٹرکٹس دیکھنا یاد ہوگا۔ + +یہ OpenZeppelin سے [ERC-20 انٹرفیس](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) کی ایک ڈیفینیشن ہے۔ یہ [انسانی پڑھنے کے قابل معیار](https://eips.ethereum.org/EIPS/eip-20) کا Solidity کوڈ میں ترجمہ ہے۔ یقیناً، انٹرفیس خود یہ وضاحت نہیں کرتا ہے کہ _کیسے_ کچھ کرنا ہے۔ اس کی وضاحت نیچے کنٹریکٹ سورس کوڈ میں کی گئی ہے۔ + +  + +```solidity +// SPDX-License-Identifier: MIT +``` + +Solidity فائلوں میں لائسنس شناخت کنندہ شامل ہونا چاہیے۔ [آپ یہاں لائسنسوں کی فہرست دیکھ سکتے ہیں](https://spdx.org/licenses/)۔ اگر آپ کو کسی مختلف لائسنس کی ضرورت ہے تو تبصروں میں اس کی وضاحت کریں۔ + +  + +```solidity +pragma solidity >=0.6.0 <0.8.0; +``` + +Solidity زبان اب بھی تیزی سے ترقی کر رہی ہے، اور نئے ورژنز پرانے کوڈ کے ساتھ ہم آہنگ نہیں ہو سکتے ہیں +([یہاں دیکھیں](https://docs.soliditylang.org/en/v0.7.0/070-breaking-changes.html))۔ لہذا، یہ ایک اچھا خیال ہے کہ نہ صرف زبان کا کم از کم ورژن، بلکہ ایک زیادہ سے زیادہ ورژن بھی بیان کیا جائے، جس کے ساتھ آپ نے کوڈ کی جانچ کی ہے۔ + +  + +```solidity +/** + * @dev EIP میں بیان کردہ ERC20 معیار کا انٹرفیس۔ + */ +``` + +تبصرے میں `@dev` [NatSpec فارمیٹ](https://docs.soliditylang.org/en/develop/natspec-format.html) کا حصہ ہے، جو سورس کوڈ سے +ڈاکیومینٹیشن تیار کرنے کے لیے استعمال ہوتا ہے۔ + +  + +```solidity +interface IERC20 { +``` + +روایت کے مطابق، انٹرفیس کے نام `I` سے شروع ہوتے ہیں۔ + +  + +```solidity + /** + * @dev وجود میں موجود ٹوکنز کی مقدار واپس کرتا ہے۔ + */ + function totalSupply() external view returns (uint256); +``` + +یہ فنکشن `external` ہے، جس کا مطلب ہے [اسے صرف کنٹریکٹ کے باہر سے کال کیا جا سکتا ہے](https://docs.soliditylang.org/en/v0.7.0/cheatsheet.html#index-2)۔ +یہ کنٹریکٹ میں ٹوکنز کی کل سپلائی واپس کرتا ہے۔ یہ قدر Ethereum میں سب سے عام قسم، غیر دستخط شدہ 256 بٹس کا استعمال کرتے ہوئے واپس کی جاتی ہے (256 بٹس EVM کا +نیٹیو ورڈ سائز ہے)۔ یہ فنکشن ایک `view` بھی ہے، جس کا مطلب ہے کہ یہ اسٹیٹ کو تبدیل نہیں کرتا ہے، لہذا اسے بلاک چین کے ہر نوڈ پر چلانے کے بجائے ایک ہی نوڈ پر عمل میں لایا جا سکتا ہے۔ اس قسم کا فنکشن ٹرانزیکشن پیدا نہیں کرتا اور اس پر [گیس](/developers/docs/gas/) کی لاگت نہیں آتی۔ + +**نوٹ:** نظریاتی طور پر یہ ظاہر ہو سکتا ہے کہ کنٹریکٹ کا تخلیق کار اصل قدر سے کم کل سپلائی واپس کر کے دھوکہ دے سکتا ہے، جس سے ہر ٹوکن +اس کی اصل قیمت سے زیادہ قیمتی نظر آتا ہے۔ تاہم، یہ خوف بلاک چین کی حقیقی نوعیت کو نظر انداز کرتا ہے۔ بلاک چین پر ہونے والی ہر چیز کی تصدیق ہر نوڈ سے کی جا سکتی ہے۔ اسے حاصل کرنے کے لیے، ہر کنٹریکٹ کا مشین لینگویج کوڈ اور اسٹوریج ہر نوڈ پر دستیاب ہے۔ جبکہ آپ کو اپنے کنٹریکٹ کے لیے Solidity +کوڈ شائع کرنے کی ضرورت نہیں ہے، کوئی بھی آپ کو سنجیدگی سے نہیں لے گا جب تک کہ آپ سورس کوڈ اور Solidity کا وہ ورژن شائع نہ کریں جس کے ساتھ اسے کمپائل کیا گیا تھا، تاکہ اس کی آپ کے فراہم کردہ مشین لینگویج کوڈ سے تصدیق کی جا سکے۔ +مثال کے طور پر، [یہ کنٹریکٹ](https://eth.blockscout.com/address/0xa530F85085C6FE2f866E7FdB716849714a89f4CD?tab=contract) دیکھیں۔ + +  + +```solidity + /** + * @dev `account` کی ملکیت والے ٹوکنز کی مقدار واپس کرتا ہے۔ + */ + function balanceOf(address account) external view returns (uint256); +``` + +جیسا کہ نام سے ظاہر ہے، `balanceOf` ایک اکاؤنٹ کا بیلنس واپس کرتا ہے۔ Ethereum اکاؤنٹس کو Solidity میں `address` قسم کا استعمال کرتے ہوئے شناخت کیا جاتا ہے، جس میں 160 بٹس ہوتے ہیں۔ +یہ `external` اور `view` بھی ہے۔ + +  + +```solidity + /** + * @dev کالر کے اکاؤنٹ سے `recipient` کو `amount` ٹوکنز منتقل کرتا ہے۔ + * + * ایک بولین قدر واپس کرتا ہے جو یہ بتاتا ہے کہ آیا آپریشن کامیاب ہوا۔ + * + * ایک {Transfer} ایونٹ ایمٹ کرتا ہے۔ + */ + function transfer(address recipient, uint256 amount) external returns (bool); +``` + +`transfer` فنکشن کالر سے ٹوکنز کو ایک مختلف ایڈریس پر منتقل کرتا ہے۔ اس میں اسٹیٹ کی تبدیلی شامل ہے، لہذا یہ `view` نہیں ہے۔ +جب کوئی صارف اس فنکشن کو کال کرتا ہے تو یہ ایک ٹرانزیکشن بناتا ہے اور گیس کی لاگت آتی ہے۔ یہ ایک ایونٹ، `Transfer` بھی ایمٹ کرتا ہے، تاکہ بلاک چین پر ہر کسی کو ایونٹ کے بارے میں مطلع کیا جا سکے۔ + +فنکشن میں دو مختلف قسم کے کالرز کے لیے دو قسم کے آؤٹ پٹ ہیں: + +- صارفین جو فنکشن کو براہ راست صارف انٹرفیس سے کال کرتے ہیں۔ عام طور پر صارف ایک ٹرانزیکشن جمع کرتا ہے اور جواب کا انتظار نہیں کرتا، جس میں غیر معینہ مدت لگ سکتی ہے۔ صارف یہ دیکھ سکتا ہے کہ کیا ہوا ہے + ٹرانزیکشن کی رسید (جس کی شناخت ٹرانزیکشن ہیش سے ہوتی ہے) یا `Transfer` ایونٹ کو دیکھ کر۔ +- دوسرے کنٹریکٹس، جو فنکشن کو مجموعی ٹرانزیکشن کے حصے کے طور پر کال کرتے ہیں۔ ان کنٹریکٹس کو نتیجہ فوری طور پر مل جاتا ہے، + کیونکہ وہ اسی ٹرانزیکشن میں چلتے ہیں، لہذا وہ فنکشن کی واپسی کی قدر استعمال کر سکتے ہیں۔ + +اسی قسم کا آؤٹ پٹ دوسرے فنکشنز کے ذریعے بنایا جاتا ہے جو کنٹریکٹ کی اسٹیٹ کو تبدیل کرتے ہیں۔ + +  + +الاؤنسز ایک اکاؤنٹ کو کچھ ٹوکنز خرچ کرنے کی اجازت دیتے ہیں جو ایک مختلف مالک سے تعلق رکھتے ہیں۔ +یہ مفید ہے، مثال کے طور پر، ان کنٹریکٹس کے لیے جو بیچنے والے کے طور پر کام کرتے ہیں۔ کنٹریکٹس +ایونٹس کی نگرانی نہیں کر سکتے، لہذا اگر کوئی خریدار براہ راست بیچنے والے کنٹریکٹ کو ٹوکنز منتقل کرتا +ہے تو اس کنٹریکٹ کو معلوم نہیں ہوگا کہ اسے ادائیگی کی گئی ہے۔ اس کے بجائے، خریدار بیچنے والے کنٹریکٹ کو ایک مخصوص رقم خرچ کرنے کی اجازت دیتا ہے، اور بیچنے والا اس رقم کو منتقل کرتا ہے۔ +یہ ایک فنکشن کے ذریعے کیا جاتا ہے جسے بیچنے والا کنٹریکٹ کال کرتا ہے، تاکہ بیچنے والا کنٹریکٹ +جان سکے کہ آیا یہ کامیاب تھا۔ + +```solidity + /** + * @dev باقی ٹوکنز کی تعداد واپس کرتا ہے جو `spender` کو {transferFrom} کے ذریعے `owner` کی جانب سے خرچ کرنے کی اجازت ہوگی۔ یہ + * بطور ڈیفالٹ صفر ہے۔ + * + * یہ قدر اس وقت تبدیل ہوتی ہے جب {approve} یا {transferFrom} کو کال کیا جاتا ہے۔ + */ + function allowance(address owner, address spender) external view returns (uint256); +``` + +`allowance` فنکشن کسی کو بھی یہ دیکھنے کے لیے استفسار کرنے دیتا ہے کہ ایک +ایڈریس (`owner`) دوسرے ایڈریس (`spender`) کو خرچ کرنے کی کیا الاؤنس دیتا ہے۔ + +  + +```solidity + /** + * @dev کالر کے ٹوکنز پر `spender` کے الاؤنس کے طور پر `amount` سیٹ کرتا ہے۔ + * + * ایک بولین قدر واپس کرتا ہے جو یہ بتاتا ہے کہ آیا آپریشن کامیاب ہوا۔ + * + * اہم: خبردار رہیں کہ اس طریقے سے الاؤنس تبدیل کرنے سے یہ خطرہ لاحق ہوتا ہے + * کہ کوئی بدقسمت ٹرانزیکشن آرڈرنگ کے ذریعے پرانے اور نئے دونوں الاؤنس استعمال کر سکتا ہے۔ اس ریس + * کی حالت کو کم کرنے کا ایک ممکنہ حل یہ ہے کہ پہلے خرچ کرنے والے کے الاؤنس کو 0 تک کم کریں اور اس کے بعد + * مطلوبہ قدر سیٹ کریں: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * ایک {Approval} ایونٹ ایمٹ کرتا ہے۔ + */ + function approve(address spender, uint256 amount) external returns (bool); +``` + +`approve` فنکشن ایک الاؤنس بناتا ہے۔ اس کے بارے میں پیغام کو ضرور پڑھیں کہ اسے کیسے غلط استعمال کیا جا سکتا ہے۔ Ethereum میں آپ اپنی ٹرانزیکشنز کی ترتیب کو کنٹرول کرتے ہیں، +لیکن آپ اس ترتیب کو کنٹرول نہیں کر سکتے جس میں دوسرے لوگوں کی ٹرانزیکشنز پر عمل درآمد کیا جائے گا، +جب تک کہ آپ اپنی ٹرانزیکشن اس وقت تک جمع نہ کریں جب تک کہ آپ دوسری طرف کی ٹرانزیکشن کو نہ دیکھ لیں۔ + +  + +```solidity + /** + * @dev الاؤنس میکانزم کا استعمال کرتے ہوئے `sender` سے `recipient` کو `amount` ٹوکنز منتقل کرتا ہے۔ + * `amount` پھر کالر کے الاؤنس سے کاٹا جاتا ہے۔ + * + * ایک بولین قدر واپس کرتا ہے جو یہ بتاتا ہے کہ آیا آپریشن کامیاب ہوا۔ + * + * ایک {Transfer} ایونٹ ایمٹ کرتا ہے۔ + */ + function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); +``` + +آخر میں، `transferFrom` خرچ کرنے والے کے ذریعے الاؤنس کو حقیقت میں خرچ کرنے کے لیے استعمال کیا جاتا ہے۔ + +  + +```solidity + + /** + * @dev اس وقت ایمٹ ہوتا ہے جب `value` ٹوکنز ایک اکاؤنٹ (`from`) سے دوسرے (`to`) میں منتقل ہوتے ہیں۔ + * + * نوٹ کریں کہ `value` صفر ہو سکتا ہے۔ + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev اس وقت ایمٹ ہوتا ہے جب {approve} پر کال کے ذریعے ایک `owner` کے لیے `spender` کا الاؤنس سیٹ کیا جاتا ہے۔ `value` نیا الاؤنس ہے۔ + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} +``` + +یہ ایونٹس اس وقت ایمٹ ہوتے ہیں جب ERC-20 کنٹریکٹ کی اسٹیٹ تبدیل ہوتی ہے۔ + +## اصل کنٹریکٹ {#the-actual-contract} + +یہ اصل کنٹریکٹ ہے جو ERC-20 معیار کو لاگو کرتا ہے، +[یہاں سے لیا گیا ہے](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)۔ +اس کا مقصد جیسا ہے ویسا استعمال کرنا نہیں ہے، لیکن آپ اس سے +[انہیریٹ](https://www.tutorialspoint.com/solidity/solidity_inheritance.htm) کر کے اسے کسی قابل استعمال چیز تک بڑھا سکتے ہیں۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.8.0; +``` + +  + +### امپورٹ اسٹیٹمنٹس {#import-statements} + +اوپر دی گئی انٹرفیس ڈیفینیشنز کے علاوہ، کنٹریکٹ ڈیفینیشن دو دیگر فائلوں کو امپورٹ کرتی ہے: + +```solidity + +import "../../GSN/Context.sol"; +import "./IERC20.sol"; +import "../../math/SafeMath.sol"; +``` + +- `GSN/Context.sol` [OpenGSN](https://www.opengsn.org/) کو استعمال کرنے کے لیے درکار ڈیفینیشنز ہیں، ایک ایسا نظام جو ایتھر کے بغیر صارفین کو + بلاک چین استعمال کرنے کی اجازت دیتا ہے۔ نوٹ کریں کہ یہ ایک پرانا ورژن ہے، اگر آپ OpenGSN کے ساتھ انٹیگریٹ کرنا چاہتے ہیں تو + [یہ ٹیوٹوریل استعمال کریں](https://docs.opengsn.org/javascript-client/tutorial.html)۔ +- [SafeMath لائبریری](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/)، جو Solidity ورژنز **<0.8.0** کے لیے + اریتھمیٹک اوور فلو/انڈر فلو کو روکتی ہے۔ Solidity ≥0.8.0 میں، اریتھمیٹک آپریشنز خود بخود + اوور فلو/انڈر فلو پر ریورٹ ہو جاتے ہیں، جس سے SafeMath غیر ضروری ہو جاتا ہے۔ یہ کنٹریکٹ پرانے کمپائلر ورژنز کے ساتھ بیک ورڈ کمپیٹیبلٹی کے لیے SafeMath کا استعمال کرتا ہے۔ + +  + +یہ تبصرہ کنٹریکٹ کے مقصد کی وضاحت کرتا ہے۔ + +```solidity +/** + * @dev {IERC20} انٹرفیس کا امپلیمینٹیشن۔ + * + * یہ امپلیمینٹیشن اس طریقے سے اگنوسٹک ہے جس سے ٹوکنز بنائے جاتے ہیں۔ اس کا مطلب ہے + * کہ {_mint} کا استعمال کرتے ہوئے ایک ڈیریوڈ کنٹریکٹ میں ایک سپلائی میکانزم شامل کرنا ہوگا۔ + * ایک عام میکانزم کے لیے {ERC20PresetMinterPauser} دیکھیں۔ + * + * ٹپ: تفصیلی تحریر کے لیے ہماری گائیڈ دیکھیں + * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[سپلائی میکانزم کو کیسے + * لاگو کیا جائے]۔ + * + * ہم نے عام OpenZeppelin رہنما خطوط پر عمل کیا ہے: فنکشنز ناکامی پر `false` واپس کرنے کے بجائے + * ریورٹ کرتے ہیں۔ یہ طرز عمل بہرحال روایتی ہے + * اور ERC20 ایپلیکیشنز کی توقعات سے متصادم نہیں ہے۔ + * + * مزید برآں، {transferFrom} پر کالز پر ایک {Approval} ایونٹ ایمٹ ہوتا ہے۔ + * یہ ایپلیکیشنز کو صرف مذکورہ ایونٹس کو سن کر تمام اکاؤنٹس کے لیے الاؤنس کو دوبارہ بنانے کی اجازت دیتا ہے۔ EIP کی دیگر امپلیمینٹیشنز + * ان ایونٹس کو ایمٹ نہیں کر سکتی ہیں، کیونکہ اس کی تفصیلات میں ضرورت نہیں ہے۔ + * + * آخر میں، غیر معیاری {decreaseAllowance} اور {increaseAllowance} + * فنکشنز الاؤنس سیٹ کرنے کے ارد گرد معروف مسائل کو کم کرنے کے لیے شامل کیے گئے ہیں۔ + * {IERC20-approve} دیکھیں۔ + */ + +``` + +### کنٹریکٹ ڈیفینیشن {#contract-definition} + +```solidity +contract ERC20 is Context, IERC20 { +``` + +یہ لائن انہیریٹنس کی وضاحت کرتی ہے، اس معاملے میں اوپر سے `IERC20` اور OpenGSN کے لیے `Context` سے۔ + +  + +```solidity + + using SafeMath for uint256; + +``` + +یہ لائن `SafeMath` لائبریری کو `uint256` قسم سے منسلک کرتی ہے۔ آپ یہ لائبریری +[یہاں](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) تلاش کر سکتے ہیں۔ + +### ویری ایبل ڈیفینیشنز {#variable-definitions} + +یہ ڈیفینیشنز کنٹریکٹ کے اسٹیٹ ویری ایبلز کی وضاحت کرتی ہیں۔ یہ ویری ایبلز `private` قرار دیے گئے ہیں، لیکن +اس کا صرف یہ مطلب ہے کہ بلاک چین پر موجود دوسرے کنٹریکٹس انہیں پڑھ نہیں سکتے۔ _بلاک چین پر کوئی راز نہیں ہیں_، ہر نوڈ پر موجود سافٹ ویئر میں ہر بلاک پر ہر کنٹریکٹ کی اسٹیٹ ہوتی ہے۔ روایت کے مطابق، اسٹیٹ ویری ایبلز کا نام `_` رکھا جاتا ہے۔ + +پہلے دو ویری ایبلز [میپنگز](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) ہیں، +یعنی وہ تقریباً [ایسوسی ایٹیو ایرے](https://wikipedia.org/wiki/Associative_array) کی طرح برتاؤ کرتے ہیں، +سوائے اس کے کہ کیز عددی قدریں ہیں۔ اسٹوریج صرف ان اندراجات کے لیے مختص کیا جاتا ہے جن کی قدریں ڈیفالٹ (صفر) سے مختلف ہوتی ہیں۔ + +```solidity + mapping (address => uint256) private _balances; +``` + +پہلی میپنگ، `_balances`، ایڈریسز اور اس ٹوکن کے ان کے متعلقہ بیلنسز ہیں۔ بیلنس تک رسائی کے لیے، یہ نحو استعمال کریں: `_balances[
]`۔ + +  + +```solidity + mapping (address => mapping (address => uint256)) private _allowances; +``` + +یہ ویری ایبل، `_allowances`، پہلے بیان کردہ الاؤنسز کو اسٹور کرتا ہے۔ پہلا انڈیکس ٹوکنز کا مالک ہے، اور دوسرا الاؤنس کے ساتھ کنٹریکٹ ہے۔ ایڈریس A کی رقم تک رسائی حاصل کرنے کے لیے جو وہ ایڈریس B کے اکاؤنٹ سے خرچ کر سکتا ہے، `_allowances[B][A]` استعمال کریں۔ + +  + +```solidity + uint256 private _totalSupply; +``` + +جیسا کہ نام سے پتہ چلتا ہے، یہ ویری ایبل ٹوکنز کی کل سپلائی کا ٹریک رکھتا ہے۔ + +  + +```solidity + string private _name; + string private _symbol; + uint8 private _decimals; +``` + +یہ تینوں ویری ایبلز پڑھنے کی اہلیت کو بہتر بنانے کے لیے استعمال کیے جاتے ہیں۔ پہلے دو خود وضاحتی ہیں، لیکن `_decimals` نہیں ہے۔ + +ایک طرف، Ethereum میں فلوٹنگ پوائنٹ یا فریکشنل ویری ایبلز نہیں ہیں۔ دوسری طرف، انسان ٹوکنز کو تقسیم کرنے کے قابل ہونا پسند کرتے ہیں۔ لوگوں کے کرنسی کے لیے سونے پر بسنے کی ایک وجہ یہ تھی کہ جب کوئی گائے کی قیمت کے برابر بطخ خریدنا چاہتا تھا تو چینج کرنا مشکل تھا۔ + +اس کا حل انٹیجرز کا ٹریک رکھنا ہے، لیکن اصلی ٹوکن کے بجائے ایک فریکشنل ٹوکن کو گننا ہے جو تقریباً بے قیمت ہے۔ ایتھر کے معاملے میں، فریکشنل ٹوکن کو wei کہا جاتا ہے، اور 10^18 wei ایک +ETH کے برابر ہے۔ لکھتے وقت، 10,000,000,000,000 wei تقریباً ایک امریکی یا یورو سینٹ کے برابر ہے۔ + +ایپلیکیشنز کو یہ جاننے کی ضرورت ہے کہ ٹوکن بیلنس کیسے دکھایا جائے۔ اگر کسی صارف کے پاس 3,141,000,000,000,000,000 wei ہیں، تو کیا یہ +3.14 ETH ہے؟ 31.41 ETH؟ 3,141 ETH؟ ایتھر کے معاملے میں یہ 10^18 wei سے ETH تک بیان کیا گیا ہے، لیکن اپنے +ٹوکن کے لیے آپ ایک مختلف قدر منتخب کر سکتے ہیں۔ اگر ٹوکن کو تقسیم کرنے کا کوئی مطلب نہیں ہے، تو آپ صفر کی `_decimals` قدر استعمال کر سکتے ہیں۔ اگر آپ ETH جیسا ہی معیار استعمال کرنا چاہتے ہیں تو **18** کی قدر استعمال کریں۔ + +### کنسٹرکٹر {#the-constructor} + +```solidity + /** + * @dev {name} اور {symbol} کے لیے قدریں سیٹ کرتا ہے، {decimals} کو 18 کی + * ڈیفالٹ قدر کے ساتھ انیشلائز کرتا ہے۔ + * + * {decimals} کے لیے ایک مختلف قدر منتخب کرنے کے لیے، {_setupDecimals} استعمال کریں۔ + * + * یہ تینوں قدریں ناقابل تغیر ہیں: انہیں صرف تعمیر کے دوران ایک بار سیٹ کیا جا سکتا ہے۔ + */ + constructor (string memory name_, string memory symbol_) public { + // Solidity ≥0.7.0 میں، 'public' مضمر ہے اور اسے چھوڑا جا سکتا ہے۔ + + _name = name_; + _symbol = symbol_; + _decimals = 18; + } +``` + +کنسٹرکٹر کو اس وقت کال کیا جاتا ہے جب کنٹریکٹ پہلی بار بنایا جاتا ہے۔ روایت کے مطابق، فنکشن پیرامیٹرز کا نام `_` رکھا جاتا ہے۔ + +### یوزر انٹرفیس فنکشنز {#user-interface-functions} + +```solidity + /** + * @dev ٹوکن کا نام واپس کرتا ہے۔ + */ + function name() public view returns (string memory) { + return _name; + } + + /** + * @dev ٹوکن کی علامت واپس کرتا ہے، عام طور پر نام کا ایک چھوٹا ورژن۔ + */ + function symbol() public view returns (string memory) { + return _symbol; + } + + /** + * @dev اس کی صارف کی نمائندگی حاصل کرنے کے لیے استعمال ہونے والے ڈیسیملز کی تعداد واپس کرتا ہے۔ + * مثال کے طور پر، اگر `decimals` `2` کے برابر ہے، تو `505` ٹوکنز کا بیلنس + * صارف کو `5,05` (`505 / 10 ** 2`) کے طور پر دکھایا جانا چاہیے۔ + * + * ٹوکنز عام طور پر 18 کی قدر کا انتخاب کرتے ہیں، جو ایتھر اور wei کے درمیان تعلق کی نقل کرتا ہے۔ + * یہ وہ قدر ہے جسے {ERC20} استعمال کرتا ہے، جب تک کہ {_setupDecimals} کو کال نہ کیا جائے۔ + * + * نوٹ: یہ معلومات صرف _ڈسپلے_ کے مقاصد کے لیے استعمال ہوتی ہیں: یہ کسی بھی طرح + * کنٹریکٹ کے کسی بھی اریتھمیٹک کو متاثر نہیں کرتی ہے، بشمول + * {IERC20-balanceOf} اور {IERC20-transfer}۔ + */ + function decimals() public view returns (uint8) { + return _decimals; + } +``` + +یہ فنکشنز، `name`، `symbol`، اور `decimals` یوزر انٹرفیسز کو آپ کے کنٹریکٹ کے بارے میں جاننے میں مدد کرتے ہیں تاکہ وہ اسے صحیح طریقے سے ڈسپلے کر سکیں۔ + +ریٹرن کی قسم `string memory` ہے، یعنی ایک سٹرنگ ریٹرن کریں جو میموری میں اسٹور ہے۔ ویری ایبلز، جیسے سٹرنگز، کو تین جگہوں پر اسٹور کیا جا سکتا ہے: + +| | لائف ٹائم | کنٹریکٹ تک رسائی | گیس کی لاگت | +| -------- | ------------- | ---------------- | ---------------------------------------------------------------------- | +| میموری | فنکشن کال | پڑھنا/لکھنا | دس یا سو (اونچی جگہوں کے لیے زیادہ) | +| کال ڈیٹا | فنکشن کال | صرف پڑھنا | ریٹرن ٹائپ کے طور پر استعمال نہیں کیا جا سکتا، صرف فنکشن پیرامیٹر ٹائپ | +| اسٹوریج | تبدیل ہونے تک | پڑھنا/لکھنا | زیادہ (پڑھنے کے لیے 800، لکھنے کے لیے 20k) | + +اس معاملے میں، `memory` بہترین انتخاب ہے۔ + +### ٹوکن کی معلومات پڑھیں {#read-token-information} + +یہ وہ فنکشنز ہیں جو ٹوکن کے بارے میں معلومات فراہم کرتے ہیں، یا تو کل سپلائی یا کسی +اکاؤنٹ کا بیلنس۔ + +```solidity + /** + * @dev {IERC20-totalSupply} دیکھیں۔ + */ + function totalSupply() public view override returns (uint256) { + return _totalSupply; + } +``` + +`totalSupply` فنکشن ٹوکنز کی کل سپلائی واپس کرتا ہے۔ + +  + +```solidity + /** + * @dev {IERC20-balanceOf} دیکھیں۔ + */ + function balanceOf(address account) public view override returns (uint256) { + return _balances[account]; + } +``` + +ایک اکاؤنٹ کا بیلنس پڑھیں۔ نوٹ کریں کہ کسی کو بھی کسی دوسرے کے اکاؤنٹ کا بیلنس حاصل کرنے کی اجازت ہے۔ اس معلومات کو چھپانے کی کوشش کرنے کا کوئی فائدہ نہیں، کیونکہ یہ ہر نوڈ پر ویسے بھی دستیاب ہے۔ _بلاک چین پر کوئی راز نہیں ہے۔_ + +### ٹوکنز منتقل کریں {#transfer-tokens} + +```solidity + /** + * @dev {IERC20-transfer} دیکھیں۔ + * + * تقاضے: + * + * - `recipient` صفر ایڈریس نہیں ہو سکتا۔ + * - کالر کے پاس کم از کم `amount` کا بیلنس ہونا چاہیے۔ + */ + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { +``` + +`transfer` فنکشن کو بھیجنے والے کے اکاؤنٹ سے ٹوکنز کو کسی دوسرے اکاؤنٹ میں منتقل کرنے کے لیے کال کیا جاتا ہے۔ نوٹ کریں کہ اگرچہ یہ ایک بولین قدر واپس کرتا ہے، وہ قدر ہمیشہ **true** ہوتی ہے۔ اگر منتقلی ناکام ہو جاتی ہے تو کنٹریکٹ کال کو ریورٹ کر دیتا ہے۔ + +  + +```solidity + _transfer(_msgSender(), recipient, amount); + return true; + } +``` + +`_transfer` فنکشن اصل کام کرتا ہے۔ یہ ایک پرائیویٹ فنکشن ہے جسے صرف دوسرے کنٹریکٹ فنکشنز کے ذریعے کال کیا جا سکتا ہے۔ روایت کے مطابق پرائیویٹ فنکشنز کا نام `_` رکھا جاتا ہے، بالکل اسٹیٹ ویری ایبلز کی طرح۔ + +عام طور پر Solidity میں ہم میسج بھیجنے والے کے لیے `msg.sender` استعمال کرتے ہیں۔ تاہم، یہ [OpenGSN](http://opengsn.org/) کو توڑتا ہے۔ اگر ہم اپنے ٹوکن کے ساتھ ایتھر لیس ٹرانزیکشنز کی اجازت دینا چاہتے ہیں، تو ہمیں `_msgSender()` استعمال کرنے کی ضرورت ہے۔ یہ عام ٹرانزیکشنز کے لیے `msg.sender` واپس کرتا ہے، لیکن ایتھر لیس ٹرانزیکشنز کے لیے اصل دستخط کنندہ واپس کرتا ہے نہ کہ وہ کنٹریکٹ جس نے میسج ریلے کیا۔ + +### الاؤنس فنکشنز {#allowance-functions} + +یہ وہ فنکشنز ہیں جو الاؤنس کی فعالیت کو لاگو کرتے ہیں: `allowance`، `approve`، `transferFrom`، اور `_approve`۔ مزید برآں، OpenZeppelin کا امپلیمینٹیشن بنیادی معیار سے آگے بڑھ کر کچھ خصوصیات شامل کرتا ہے جو سیکیورٹی کو بہتر بناتی ہیں: `increaseAllowance`، اور `decreaseAllowance`۔ + +#### الاؤنس فنکشن {#allowance} + +```solidity + /** + * @dev {IERC20-allowance} دیکھیں۔ + */ + function allowance(address owner, address spender) public view virtual override returns (uint256) { + return _allowances[owner][spender]; + } +``` + +`allowance` فنکشن ہر کسی کو کسی بھی الاؤنس کو چیک کرنے کی اجازت دیتا ہے۔ + +#### approve فنکشن {#approve} + +```solidity + /** + * @dev {IERC20-approve} دیکھیں۔ + * + * تقاضے: + * + * - `spender` صفر ایڈریس نہیں ہو سکتا۔ + */ + function approve(address spender, uint256 amount) public virtual override returns (bool) { +``` + +یہ فنکشن الاؤنس بنانے کے لیے کال کیا جاتا ہے۔ یہ اوپر دیے گئے `transfer` فنکشن سے ملتا جلتا ہے: + +- فنکشن صرف ایک اندرونی فنکشن (اس معاملے میں، `_approve`) کو کال کرتا ہے جو اصل کام کرتا ہے۔ +- فنکشن یا تو `true` (اگر کامیاب ہو) واپس کرتا ہے یا ریورٹ (اگر نہیں)۔ + +  + +```solidity + _approve(_msgSender(), spender, amount); + return true; + } +``` + +ہم اندرونی فنکشنز کا استعمال ان جگہوں کی تعداد کو کم سے کم کرنے کے لیے کرتے ہیں جہاں اسٹیٹ کی تبدیلیاں ہوتی ہیں۔ _کوئی بھی_ فنکشن جو اسٹیٹ کو تبدیل کرتا ہے وہ ایک ممکنہ سیکیورٹی رسک ہے جس کا سیکیورٹی کے لیے آڈٹ کرنے کی ضرورت ہے۔ اس طرح ہمارے پاس غلط ہونے کے امکانات کم ہیں۔ + +#### transferFrom فنکشن {#transferFrom} + +یہ وہ فنکشن ہے جسے ایک خرچ کرنے والا الاؤنس خرچ کرنے کے لیے کال کرتا ہے۔ اس کے لیے دو آپریشنز کی ضرورت ہے: خرچ کی جانے والی رقم کو منتقل کریں اور الاؤنس کو اس رقم سے کم کریں۔ + +```solidity + /** + * @dev {IERC20-transferFrom} دیکھیں۔ + * + * اپ ڈیٹ شدہ الاؤنس کی نشاندہی کرنے والا ایک {Approval} ایونٹ ایمٹ کرتا ہے۔ یہ + * EIP کے ذریعہ ضروری نہیں ہے۔ {ERC20} کے آغاز میں نوٹ دیکھیں۔ + * + * تقاضے: + * + * - `sender` اور `recipient` صفر ایڈریس نہیں ہو سکتے۔ + * - `sender` کے پاس کم از کم `amount` کا بیلنس ہونا چاہیے۔ + * - کالر کے پاس کم از کم `amount` کے `sender` کے ٹوکنز کے لیے الاؤنس ہونا چاہیے۔ + */ + function transferFrom(address sender, address recipient, uint256 amount) public virtual + override returns (bool) { + _transfer(sender, recipient, amount); +``` + +  + +`a.sub(b, "message")` فنکشن کال دو کام کرتی ہے۔ سب سے پہلے، یہ `a-b` کا حساب لگاتا ہے، جو کہ نیا الاؤنس ہے۔ +دوسرا، یہ چیک کرتا ہے کہ یہ نتیجہ منفی نہیں ہے۔ اگر یہ منفی ہے تو کال فراہم کردہ میسج کے ساتھ ریورٹ ہو جاتی ہے۔ نوٹ کریں کہ جب کوئی کال ریورٹ ہوتی ہے تو اس کال کے دوران پہلے کی گئی کوئی بھی پروسیسنگ نظر انداز کر دی جاتی ہے لہذا ہمیں `_transfer` کو انڈو کرنے کی ضرورت نہیں ہے۔ + +```solidity + _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, + "ERC20: منتقلی کی رقم الاؤنس سے زیادہ ہے")); + return true; + } +``` + +#### OpenZeppelin سیفٹی ایڈیشنز {#openzeppelin-safety-additions} + +ایک غیر صفر الاؤنس کو دوسری غیر صفر قدر پر سیٹ کرنا خطرناک ہے، +کیونکہ آپ صرف اپنی ٹرانزیکشنز کی ترتیب کو کنٹرول کرتے ہیں، کسی اور کی نہیں۔ تصور کریں کہ آپ کے پاس دو صارفین ہیں، ایلس جو سادہ لوح ہے اور بل جو بے ایمان ہے۔ ایلس بل سے کچھ سروس چاہتی ہے، جس کے بارے میں وہ سوچتی ہے کہ اس کی قیمت پانچ ٹوکن ہے - لہذا وہ بل کو پانچ ٹوکن کا الاؤنس دیتی ہے۔ + +پھر کچھ بدلتا ہے اور بل کی قیمت دس ٹوکن تک بڑھ جاتی ہے۔ ایلس، جو اب بھی سروس چاہتی ہے، ایک ٹرانزیکشن بھیجتی ہے جو بل کے الاؤنس کو دس پر سیٹ کرتی ہے۔ جس لمحے بل اس نئی ٹرانزیکشن کو ٹرانزیکشن پول میں دیکھتا ہے وہ ایک ٹرانزیکشن بھیجتا ہے جو ایلس کے پانچ ٹوکن خرچ کرتا ہے اور اس کی گیس کی قیمت بہت زیادہ ہے تاکہ اسے تیزی سے مائن کیا جا سکے۔ اس طرح بل پہلے پانچ ٹوکن خرچ کر سکتا ہے اور پھر، جب ایلس کا نیا الاؤنس مائن ہو جاتا ہے، تو پندرہ ٹوکن کی کل قیمت کے لیے دس مزید خرچ کر سکتا ہے، جو ایلس کی اجازت سے زیادہ ہے۔ اس تکنیک کو [فرنٹ رننگ](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/#front-running) کہا جاتا ہے + +| ایلس ٹرانزیکشن | ایلس نانس | بل ٹرانزیکشن | بل نانس | بل کا الاؤنس | ایلس سے بل کی کل آمدنی | +| ------------------------------------ | --------- | ------------------------------------------------ | ------- | ------------ | ---------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | +| approve(Bill, 10) | 11 | | | 10 | 5 | +| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 15 | + +اس مسئلے سے بچنے کے لیے، یہ دو فنکشنز (`increaseAllowance` اور `decreaseAllowance`) آپ کو ایک مخصوص رقم سے الاؤنس میں ترمیم کرنے کی اجازت دیتے ہیں۔ لہذا اگر بل نے پہلے ہی پانچ ٹوکن خرچ کر لیے ہیں، تو وہ صرف پانچ مزید خرچ کر سکے گا۔ ٹائمنگ پر منحصر ہے، اس کے کام کرنے کے دو طریقے ہیں، دونوں کا اختتام بل کو صرف دس ٹوکن ملنے پر ہوتا ہے: + +A: + +| ایلس ٹرانزیکشن | ایلس نانس | بل ٹرانزیکشن | بل نانس | بل کا الاؤنس | ایلس سے بل کی کل آمدنی | +| --------------------------------------------- | --------: | ----------------------------------------------- | ------: | -----------: | ---------------------- | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| | | transferFrom(Alice, Bill, 5) | 10,123 | 0 | 5 | +| increaseAllowance(Bill, 5) | 11 | | | 0+5 = 5 | 5 | +| | | transferFrom(Alice, Bill, 5) | 10,124 | 0 | 10 | + +B: + +| ایلس ٹرانزیکشن | ایلس نانس | بل ٹرانزیکشن | بل نانس | بل کا الاؤنس | ایلس سے بل کی کل آمدنی | +| --------------------------------------------- | --------: | ------------------------------------------------ | ------: | -----------: | ---------------------: | +| approve(Bill, 5) | 10 | | | 5 | 0 | +| increaseAllowance(Bill, 5) | 11 | | | 5+5 = 10 | 0 | +| | | transferFrom(Alice, Bill, 10) | 10,124 | 0 | 10 | + +```solidity + /** + * @dev کالر کے ذریعہ `spender` کو دیے گئے الاؤنس کو ایٹامک طور پر بڑھاتا ہے۔ + * + * یہ {approve} کا ایک متبادل ہے جسے {IERC20-approve} میں بیان کردہ مسائل کے + * ازالے کے طور پر استعمال کیا جا سکتا ہے۔ + * + * اپ ڈیٹ شدہ الاؤنس کی نشاندہی کرنے والا ایک {Approval} ایونٹ ایمٹ کرتا ہے۔ + * + * تقاضے: + * + * - `spender` صفر ایڈریس نہیں ہو سکتا۔ + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); + return true; + } +``` + +`a.add(b)` فنکشن ایک محفوظ اضافہ ہے۔ اس غیر امکانی صورت میں کہ `a`+`b`>=`2^256` یہ اس طرح سے ریپ نہیں ہوتا جس طرح عام اضافہ ہوتا ہے۔ + +```solidity + + /** + * @dev کالر کے ذریعہ `spender` کو دیے گئے الاؤنس کو ایٹامک طور پر کم کرتا ہے۔ + * + * یہ {approve} کا ایک متبادل ہے جسے {IERC20-approve} میں بیان کردہ مسائل کے + * ازالے کے طور پر استعمال کیا جا سکتا ہے۔ + * + * اپ ڈیٹ شدہ الاؤنس کی نشاندہی کرنے والا ایک {Approval} ایونٹ ایمٹ کرتا ہے۔ + * + * تقاضے: + * + * - `spender` صفر ایڈریس نہیں ہو سکتا۔ + * - `spender` کے پاس کالر کے لیے کم از کم `subtractedValue` کا الاؤنس ہونا چاہیے۔ + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, + "ERC20: الاؤنس صفر سے کم ہو گیا")); + return true; + } +``` + +### ٹوکن کی معلومات میں ترمیم کرنے والے فنکشنز {#functions-that-modify-token-information} + +یہ وہ چار فنکشنز ہیں جو اصل کام کرتے ہیں: `_transfer`، `_mint`، `_burn`، اور `_approve`۔ + +#### _transfer فنکشن {#_transfer} + +```solidity + /** + * @dev `sender` سے `recipient` کو `amount` ٹوکنز منتقل کرتا ہے۔ + * + * یہ اندرونی فنکشن {transfer} کے برابر ہے، اور اسے + * مثلاً، خودکار ٹوکن فیس، سلیشنگ میکانزم وغیرہ کو لاگو کرنے کے لیے استعمال کیا جا سکتا ہے۔ + * + * ایک {Transfer} ایونٹ ایمٹ کرتا ہے۔ + * + * تقاضے: + * + * - `sender` صفر ایڈریس نہیں ہو سکتا۔ + * - `recipient` صفر ایڈریس نہیں ہو سکتا۔ + * - `sender` کے پاس کم از کم `amount` کا بیلنس ہونا چاہیے۔ + */ + function _transfer(address sender, address recipient, uint256 amount) internal virtual { +``` + +یہ فنکشن، `_transfer`، ایک اکاؤنٹ سے دوسرے اکاؤنٹ میں ٹوکنز منتقل کرتا ہے۔ اسے `transfer` (بھیجنے والے کے اپنے اکاؤنٹ سے منتقلی کے لیے) اور `transferFrom` (کسی اور کے اکاؤنٹ سے منتقلی کے لیے الاؤنسز کا استعمال کرتے ہوئے) دونوں کے ذریعے کال کیا جاتا ہے۔ + +  + +```solidity + require(sender != address(0), "ERC20: صفر ایڈریس سے منتقلی"); + require(recipient != address(0), "ERC20: صفر ایڈریس پر منتقلی"); +``` + +Ethereum میں کوئی بھی حقیقت میں صفر ایڈریس کا مالک نہیں ہے (یعنی، کوئی بھی ایسی پرائیویٹ کلید نہیں جانتا جس کی مماثل پبلک کلید کو صفر ایڈریس میں تبدیل کیا گیا ہو)۔ جب لوگ اس ایڈریس کا استعمال کرتے ہیں، تو یہ عام طور پر ایک سافٹ ویئر بگ ہوتا ہے - لہذا اگر صفر ایڈریس بھیجنے والے یا وصول کنندہ کے طور پر استعمال کیا جاتا ہے تو ہم ناکام ہو جاتے ہیں۔ + +  + +```solidity + _beforeTokenTransfer(sender, recipient, amount); + +``` + +اس کنٹریکٹ کو استعمال کرنے کے دو طریقے ہیں: + +1. اسے اپنے کوڈ کے لیے بطور ٹیمپلیٹ استعمال کریں +2. [اس سے انہیریٹ کریں](https://www.bitdegree.org/learn/solidity-inheritance)، اور صرف ان فنکشنز کو اوور رائڈ کریں جن میں آپ کو ترمیم کرنے کی ضرورت ہے۔ + +دوسرا طریقہ بہت بہتر ہے کیونکہ OpenZeppelin ERC-20 کوڈ کا پہلے ہی آڈٹ کیا جا چکا ہے اور اسے محفوظ دکھایا گیا ہے۔ جب آپ انہیریٹنس استعمال کرتے ہیں تو یہ واضح ہوتا ہے کہ آپ کن فنکشنز میں ترمیم کرتے ہیں، اور اپنے کنٹریکٹ پر بھروسہ کرنے کے لیے لوگوں کو صرف ان مخصوص فنکشنز کا آڈٹ کرنے کی ضرورت ہوتی ہے۔ + +ہر بار جب ٹوکنز ہاتھ بدلتے ہیں تو ایک فنکشن انجام دینا اکثر مفید ہوتا ہے۔ تاہم، `_transfer` ایک بہت اہم فنکشن ہے اور اسے غیر محفوظ طریقے سے لکھنا ممکن ہے (نیچے دیکھیں)، لہذا اسے اوور رائڈ نہ کرنا بہتر ہے۔ اس کا حل `_beforeTokenTransfer` ہے، ایک [ہک فنکشن](https://wikipedia.org/wiki/Hooking)۔ آپ اس فنکشن کو اوور رائڈ کر سکتے ہیں، اور اسے ہر منتقلی پر کال کیا جائے گا۔ + +  + +```solidity + _balances[sender] = _balances[sender].sub(amount, "ERC20: منتقلی کی رقم بیلنس سے زیادہ ہے"); + _balances[recipient] = _balances[recipient].add(amount); +``` + +یہ وہ لائنیں ہیں جو اصل میں منتقلی کرتی ہیں۔ نوٹ کریں کہ ان کے درمیان **کچھ بھی نہیں** ہے، اور یہ کہ ہم منتقل شدہ رقم کو وصول کنندہ میں شامل کرنے سے پہلے بھیجنے والے سے گھٹاتے ہیں۔ یہ اہم ہے کیونکہ اگر درمیان میں کسی دوسرے کنٹریکٹ کو کال کیا جاتا تو اسے اس کنٹریکٹ کو دھوکہ دینے کے لیے استعمال کیا جا سکتا تھا۔ اس طرح منتقلی ایٹامک ہوتی ہے، اس کے بیچ میں کچھ نہیں ہو سکتا۔ + +  + +```solidity + emit Transfer(sender, recipient, amount); + } +``` + +آخر میں، ایک `Transfer` ایونٹ ایمٹ کریں۔ ایونٹس اسمارٹ کنٹریکٹس کے لیے قابل رسائی نہیں ہیں، لیکن بلاک چین کے باہر چلنے والا کوڈ ایونٹس کو سن سکتا ہے اور ان پر رد عمل ظاہر کر سکتا ہے۔ مثال کے طور پر، ایک والیٹ اس بات کا ٹریک رکھ سکتا ہے کہ مالک کو کب مزید ٹوکنز ملتے ہیں۔ + +#### _mint اور _burn فنکشنز {#_mint-and-_burn} + +یہ دو فنکشنز (`_mint` اور `_burn`) ٹوکنز کی کل سپلائی میں ترمیم کرتے ہیں۔ +یہ اندرونی ہیں اور اس کنٹریکٹ میں انہیں کال کرنے والا کوئی فنکشن نہیں ہے، لہذا یہ صرف اس صورت میں مفید ہیں جب آپ کنٹریکٹ سے انہیریٹ کریں اور یہ فیصلہ کرنے کے لیے اپنی منطق شامل کریں کہ کن حالات میں نئے ٹوکنز منٹ کیے جائیں یا موجودہ کو برن کیا جائے۔ + +**نوٹ:** ہر ERC-20 ٹوکن کی اپنی کاروباری منطق ہوتی ہے جو ٹوکن مینجمنٹ کا حکم دیتی ہے۔ +مثال کے طور پر، ایک فکسڈ سپلائی کنٹریکٹ کنسٹرکٹر میں صرف `_mint` کو کال کر سکتا ہے اور کبھی بھی `_burn` کو کال نہیں کرتا۔ ایک کنٹریکٹ جو ٹوکن بیچتا ہے وہ ادائیگی ہونے پر `_mint` کو کال کرے گا، اور قیاس ہے کہ کسی وقت `_burn` کو کال کرے گا تاکہ بے قابو افراط زر سے بچا جا سکے۔ + +```solidity + /** @dev `amount` ٹوکنز بناتا ہے اور انہیں `account` کو تفویض کرتا ہے، کل سپلائی + * میں اضافہ کرتا ہے۔ + * + * ایک {Transfer} ایونٹ ایمٹ کرتا ہے جس میں `from` کو صفر ایڈریس پر سیٹ کیا جاتا ہے۔ + * + * تقاضے: + * + * - `to` صفر ایڈریس نہیں ہو سکتا۔ + */ + function _mint(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: صفر ایڈریس پر منٹ کریں"); + _beforeTokenTransfer(address(0), account, amount); + _totalSupply = _totalSupply.add(amount); + _balances[account] = _balances[account].add(amount); + emit Transfer(address(0), account, amount); + } +``` + +جب ٹوکنز کی کل تعداد تبدیل ہو تو `_totalSupply` کو اپ ڈیٹ کرنا یقینی بنائیں۔ + +  + +```solidity + /** + * @dev `account` سے `amount` ٹوکنز کو تباہ کرتا ہے، کل سپلائی کو + * کم کرتا ہے۔ + * + * ایک {Transfer} ایونٹ ایمٹ کرتا ہے جس میں `to` کو صفر ایڈریس پر سیٹ کیا جاتا ہے۔ + * + * تقاضے: + * + * - `account` صفر ایڈریس نہیں ہو سکتا۔ + * - `account` کے پاس کم از کم `amount` ٹوکنز ہونے چاہئیں۔ + */ + function _burn(address account, uint256 amount) internal virtual { + require(account != address(0), "ERC20: صفر ایڈریس سے برن کریں"); + + _beforeTokenTransfer(account, address(0), amount); + + _balances[account] = _balances[account].sub(amount, "ERC20: برن کی رقم بیلنس سے زیادہ ہے"); + _totalSupply = _totalSupply.sub(amount); + emit Transfer(account, address(0), amount); + } +``` + +`_burn` فنکشن تقریباً `_mint` کی طرح ہے، سوائے اس کے کہ یہ دوسری سمت میں جاتا ہے۔ + +#### _approve فنکشن {#_approve} + +یہ وہ فنکشن ہے جو اصل میں الاؤنسز کی وضاحت کرتا ہے۔ نوٹ کریں کہ یہ مالک کو ایک ایسا الاؤنس بیان کرنے کی اجازت دیتا ہے جو مالک کے موجودہ بیلنس سے زیادہ ہے۔ یہ ٹھیک ہے کیونکہ بیلنس منتقلی کے وقت چیک کیا جاتا ہے، جب یہ الاؤنس بنائے جانے کے وقت کے بیلنس سے مختلف ہو سکتا ہے۔ + +```solidity + /** + * @dev `owner` کے ٹوکنز پر `spender` کے الاؤنس کے طور پر `amount` سیٹ کرتا ہے۔ + * + * یہ اندرونی فنکشن `approve` کے برابر ہے، اور اسے + * مثلاً، کچھ سب سسٹمز کے لیے خودکار الاؤنس سیٹ کرنے وغیرہ کے لیے استعمال کیا جا سکتا ہے۔ + * + * ایک {Approval} ایونٹ ایمٹ کرتا ہے۔ + * + * تقاضے: + * + * - `owner` صفر ایڈریس نہیں ہو سکتا۔ + * - `spender` صفر ایڈریس نہیں ہو سکتا۔ + */ + function _approve(address owner, address spender, uint256 amount) internal virtual { + require(owner != address(0), "ERC20: صفر ایڈریس سے منظور کریں"); + require(spender != address(0), "ERC20: صفر ایڈریس پر منظور کریں"); + + _allowances[owner][spender] = amount; +``` + +  + +ایک `Approval` ایونٹ ایمٹ کریں۔ ایپلیکیشن کیسے لکھی جاتی ہے اس پر منحصر ہے، خرچ کرنے والے کنٹریکٹ کو منظوری کے بارے میں یا تو مالک کے ذریعے بتایا جا سکتا ہے یا ایک سرور کے ذریعے جو ان ایونٹس کو سنتا ہے۔ + +```solidity + emit Approval(owner, spender, amount); + } + +``` + +### ڈیسیملز ویری ایبل میں ترمیم کریں {#modify-the-decimals-variable} + +```solidity + + + /** + * @dev {decimals} کو 18 کی ڈیفالٹ قدر کے علاوہ کسی اور قدر پر سیٹ کرتا ہے۔ + * + * انتباہ: اس فنکشن کو صرف کنسٹرکٹر سے کال کیا جانا چاہیے۔ زیادہ تر + * ایپلیکیشنز جو ٹوکن کنٹریکٹس کے ساتھ تعامل کرتی ہیں وہ توقع نہیں کریں گی کہ + * {decimals} کبھی تبدیل ہو، اور اگر ایسا ہوتا ہے تو وہ غلط طریقے سے کام کر سکتی ہیں۔ + */ + function _setupDecimals(uint8 decimals_) internal { + _decimals = decimals_; + } +``` + +یہ فنکشن `_decimals` ویری ایبل میں ترمیم کرتا ہے جو یوزر انٹرفیس کو یہ بتانے کے لیے استعمال ہوتا ہے کہ رقم کی تشریح کیسے کی جائے۔ +آپ کو اسے کنسٹرکٹر سے کال کرنا چاہیے۔ اسے کسی بھی بعد کے مقام پر کال کرنا بے ایمانی ہوگی، اور ایپلیکیشنز اسے سنبھالنے کے لیے ڈیزائن نہیں کی گئی ہیں۔ + +### ہکس {#hooks} + +```solidity + + /** + * @dev ہک جو ٹوکنز کی کسی بھی منتقلی سے پہلے کال کیا جاتا ہے۔ اس میں + * منٹنگ اور برننگ شامل ہیں۔ + * + * کالنگ کی شرائط: + * + * - جب `from` اور `to` دونوں غیر صفر ہوں، تو `from` کے `amount` ٹوکنز + * `to` کو منتقل کیے جائیں گے۔ + * - جب `from` صفر ہو، تو `to` کے لیے `amount` ٹوکنز منٹ کیے جائیں گے۔ + * - جب `to` صفر ہو، تو `from` کے `amount` ٹوکنز برن کیے جائیں گے۔ + * - `from` اور `to` کبھی بھی دونوں صفر نہیں ہوتے۔ + * + * ہکس کے بارے میں مزید جاننے کے لیے، xref:ROOT:extending-contracts.adoc#using-hooks[ہکس کا استعمال] پر جائیں۔ + */ + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } +} +``` + +یہ منتقلی کے دوران کال کیا جانے والا ہک فنکشن ہے۔ یہ یہاں خالی ہے، لیکن اگر آپ کو اس سے کچھ کروانے کی ضرورت ہے تو آپ اسے صرف اوور رائڈ کرتے ہیں۔ + +## نتیجہ {#conclusion} + +جائزے کے لیے، اس کنٹریکٹ میں کچھ اہم ترین خیالات یہ ہیں (میری رائے میں، آپ کی رائے مختلف ہو سکتی ہے): + +- _بلاک چین پر کوئی راز نہیں ہوتے_۔ کوئی بھی معلومات جس تک ایک اسمارٹ کنٹریکٹ رسائی حاصل کر سکتا ہے وہ پوری دنیا کے لیے دستیاب ہے۔ +- آپ اپنی ٹرانزیکشنز کی ترتیب کو کنٹرول کر سکتے ہیں، لیکن یہ نہیں کہ دوسرے لوگوں کی ٹرانزیکشن کب ہوتی ہے۔ یہی وجہ ہے کہ الاؤنس تبدیل کرنا خطرناک ہو سکتا ہے، کیونکہ یہ خرچ کرنے والے کو دونوں الاؤنسز کی رقم خرچ کرنے دیتا ہے۔ +- `uint256` قسم کی قدریں ریپ ہوتی ہیں۔ دوسرے لفظوں میں، _0-1=2^256-1_۔ اگر یہ مطلوبہ طرز عمل نہیں ہے، تو آپ کو اس کی جانچ کرنی ہوگی (یا SafeMath لائبریری کا استعمال کرنا ہوگا جو آپ کے لیے یہ کرتی ہے)۔ نوٹ کریں کہ یہ [Solidity 0.8.0](https://docs.soliditylang.org/en/breaking/080-breaking-changes.html) میں تبدیل ہو گیا ہے۔ +- ایک مخصوص قسم کی تمام اسٹیٹ تبدیلیاں ایک مخصوص جگہ پر کریں، کیونکہ اس سے آڈٹ کرنا آسان ہو جاتا ہے۔ + یہی وجہ ہے کہ ہمارے پاس، مثال کے طور پر، `_approve` ہے، جسے `approve`، `transferFrom`، `increaseAllowance`، اور `decreaseAllowance` کے ذریعے کال کیا جاتا ہے +- اسٹیٹ کی تبدیلیاں ایٹامک ہونی چاہئیں، ان کے درمیان کوئی اور عمل نہیں ہونا چاہیے (جیسا کہ آپ `_transfer` میں دیکھ سکتے ہیں)۔ اس کی وجہ یہ ہے کہ اسٹیٹ کی تبدیلی کے دوران آپ کے پاس ایک غیر مستقل اسٹیٹ ہوتی ہے۔ مثال کے طور پر، جب آپ بھیجنے والے کے بیلنس سے کٹوتی کرتے ہیں اور جب آپ وصول کنندہ کے بیلنس میں اضافہ کرتے ہیں، اس کے درمیان وجود میں کم ٹوکن ہوتے ہیں جتنا ہونا چاہیے۔ اگر ان کے درمیان آپریشنز ہوں، خاص طور پر کسی دوسرے کنٹریکٹ کو کالز ہوں، تو اس کا ممکنہ طور پر غلط استعمال کیا جا سکتا ہے۔ + +اب جب کہ آپ نے دیکھ لیا ہے کہ OpenZeppelin ERC-20 کنٹریکٹ کیسے لکھا جاتا ہے، اور خاص طور پر اسے کیسے زیادہ محفوظ بنایا جاتا ہے، جائیں اور اپنے محفوظ کنٹریکٹس اور ایپلیکیشنز لکھیں۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/erc20-with-safety-rails/index.md b/public/content/translations/ur/developers/tutorials/erc20-with-safety-rails/index.md new file mode 100644 index 00000000000..cb258f22f74 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/erc20-with-safety-rails/index.md @@ -0,0 +1,217 @@ +--- +title: "حفاظتی ریلز کے ساتھ ERC-20" +description: "لوگوں کو معمولی غلطیوں سے بچنے میں مدد کرنے کا طریقہ" +author: Ori Pomerantz +lang: ur-in +tags: [ "erc-20" ] +skill: beginner +published: 2022-08-15 +--- + +## تعارف {#introduction} + +ایتھیریم کی سب سے بڑی خوبیوں میں سے ایک یہ ہے کہ کوئی مرکزی اتھارٹی نہیں ہے جو آپ کے ٹرانزیکشنز میں ترمیم کر سکے یا انہیں کالعدم کر سکے۔ ایتھیریم کے ساتھ ایک بڑا مسئلہ یہ ہے کہ کوئی ایسی مرکزی اتھارٹی نہیں ہے جس کے پاس صارف کی غلطیوں یا غیر قانونی ٹرانزیکشنز کو کالعدم کرنے کا اختیار ہو۔ اس مضمون میں آپ ان کچھ عام غلطیوں کے بارے میں جانیں گے جو صارفین [ERC-20](/developers/docs/standards/tokens/erc-20/) ٹوکنز کے ساتھ کرتے ہیں، اور ساتھ ہی یہ بھی جانیں گے کہ ایسے ERC-20 کنٹریکٹس کیسے بنائے جائیں جو صارفین کو ان غلطیوں سے بچنے میں مدد کریں، یا جو کسی مرکزی اتھارٹی کو کچھ اختیارات دیں (مثال کے طور پر اکاؤنٹس کو منجمد کرنے کا اختیار)۔ + +نوٹ کریں کہ جب کہ ہم [OpenZeppelin ERC-20 ٹوکن کنٹریکٹ](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20) کا استعمال کریں گے، یہ مضمون اس کی بہت زیادہ تفصیل سے وضاحت نہیں کرتا ہے۔ آپ یہ معلومات [یہاں](/developers/tutorials/erc20-annotated-code) حاصل کر سکتے ہیں۔ + +اگر آپ مکمل سورس کوڈ دیکھنا چاہتے ہیں: + +1. [Remix IDE](https://remix.ethereum.org/) کھولیں۔ +2. گٹ ہب کلون آئیکن (![گٹ ہب کلون آئیکن](icon-clone.png)) پر کلک کریں۔ +3. گٹ ہب ریپوزٹری `https://github.com/qbzzt/20220815-erc20-safety-rails` کو کلون کریں۔ +4. **contracts > erc20-safety-rails.sol** کھولیں۔ + +## ایک ERC-20 کنٹریکٹ بنانا {#creating-an-erc-20-contract} + +حفاظتی ریل کی فعالیت شامل کرنے سے پہلے ہمیں ایک ERC-20 کنٹریکٹ کی ضرورت ہے۔ اس مضمون میں ہم [اوپن زیپلن کنٹریکٹس وزرڈ](https://docs.openzeppelin.com/contracts/5.x/wizard) کا استعمال کریں گے۔ اسے دوسرے براؤزر میں کھولیں اور ان ہدایات پر عمل کریں: + +1. **ERC20** منتخب کریں۔ + +2. یہ سیٹنگز درج کریں: + + | پیرامیٹر | قدر | + | --------------- | ---------------- | + | نام | SafetyRailsToken | + | علامت | SAFE | + | Premint | 1000 | + | خصوصیات | کوئی نہیں | + | رسائی کنٹرول | Ownable | + | اپ گریڈ ایبلیٹی | کوئی نہیں | + +3. اوپر اسکرول کریں اور (Remix کے لیے) **ری مکس میں کھولیں** پر کلک کریں یا ایک مختلف ماحول استعمال کرنے کے لیے **ڈاؤن لوڈ** کریں۔ میں یہ فرض کروں گا کہ آپ ری مکس استعمال کر رہے ہیں، اگر آپ کچھ اور استعمال کرتے ہیں تو بس مناسب تبدیلیاں کریں۔ + +4. اب ہمارے پاس ایک مکمل طور پر فعال ERC-20 کنٹریکٹ ہے۔ امپورٹڈ کوڈ دیکھنے کے لیے آپ `.deps` > `npm` کو بڑھا سکتے ہیں۔ + +5. کنٹریکٹ کو کمپائل کریں، ڈیپلائے کریں، اور اس کے ساتھ کھیلیں یہ دیکھنے کے لیے کہ یہ ایک ERC-20 کنٹریکٹ کے طور پر کام کرتا ہے۔ اگر آپ کو ریمکس استعمال کرنے کا طریقہ سیکھنے کی ضرورت ہے، [تو اس ٹیوٹوریل کا استعمال کریں](https://remix.ethereum.org/?#activate=udapp,solidity,LearnEth)۔ + +## عام غلطیاں {#common-mistakes} + +### غلطیاں {#the-mistakes} + +صارفین کبھی کبھی غلط ایڈریس پر ٹوکن بھیج دیتے ہیں۔ جبکہ ہم ان کے ذہنوں کو پڑھ کر یہ نہیں جان سکتے کہ وہ کیا کرنا چاہتے تھے، غلطی کی دو قسمیں ہیں جو بہت زیادہ ہوتی ہیں اور جن کا پتہ لگانا آسان ہے: + +1. کنٹریکٹ کے اپنے ایڈریس پر ٹوکن بھیجنا۔ مثال کے طور پر، [Optimism کا OP ٹوکن](https://optimism.mirror.xyz/qvd0WfuLKnePm1Gxb9dpGchPf5uDz5NSMEFdgirDS4c) دو ماہ سے بھی کم عرصے میں [120,000 سے زیادہ](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000042) OP ٹوکن جمع کرنے میں کامیاب رہا۔ یہ دولت کی ایک اہم مقدار کی نمائندگی کرتا ہے جسے غالباً لوگوں نے کھو دیا ہے۔ + +2. ٹوکن کو ایک خالی ایڈریس پر بھیجنا، ایک ایسا ایڈریس جو [بیرونی ملکیت والے اکاؤنٹ](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) یا [اسمارٹ کنٹریکٹ](/developers/docs/smart-contracts) سے مطابقت نہیں رکھتا۔ اگرچہ میرے پاس اس بات کے اعداد و شمار نہیں ہیں کہ ایسا کتنی بار ہوتا ہے، [ایک واقعے میں 20,000,000 ٹوکنز کا نقصان ہو سکتا تھا](https://gov.optimism.io/t/message-to-optimism-community-from-wintermute/2595)۔ + +### ٹرانسفرز کو روکنا {#preventing-transfers} + +OpenZeppelin ERC-20 کنٹریکٹ میں [ایک ہُک، `_beforeTokenTransfer`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol#L364-L368) شامل ہے، جسے ٹوکن کی منتقلی سے پہلے کال کیا جاتا ہے۔ ڈیفالٹ کے طور پر یہ ہُک کچھ نہیں کرتا، لیکن ہم اس پر اپنی فعالیت کو لٹکا سکتے ہیں، جیسے چیکس جو کوئی مسئلہ ہونے پر واپس ہو جاتے ہیں۔ + +ہُک استعمال کرنے کے لیے، کنسٹرکٹر کے بعد یہ فنکشن شامل کریں: + +```solidity + function _beforeTokenTransfer(address from, address to, uint256 amount) + internal virtual + override(ERC20) + { + super._beforeTokenTransfer(from, to, amount); + } +``` + +اس فنکشن کے کچھ حصے نئے ہو سکتے ہیں اگر آپ Solidity سے بہت زیادہ واقف نہیں ہیں: + +```solidity + internal virtual +``` + +ورچوئل `virtual` کلیدی لفظ کا مطلب ہے کہ جس طرح ہم نے `ERC20` سے فعالیت وراثت میں حاصل کی اور اس فنکشن کو اوور رائیڈ کیا، اسی طرح دوسرے کنٹریکٹس ہم سے وراثت میں لے سکتے ہیں اور اس فنکشن کو اوور رائیڈ کر سکتے ہیں۔ + +```solidity + override(ERC20) +``` + +ہمیں واضح طور پر یہ بتانا ہوگا کہ ہم `_beforeTokenTransfer` کی ERC20 ٹوکن تعریف کو [اوور رائیڈ](https://docs.soliditylang.org/en/v0.8.15/contracts.html#function-overriding) کر رہے ہیں۔ عام طور پر، سیکورٹی کے نقطہ نظر سے، واضح تعریفیں مضمر تعریفوں سے بہت بہتر ہیں - آپ یہ نہیں بھول سکتے کہ آپ نے کچھ کیا ہے اگر وہ آپ کے سامنے ہے۔ یہی وجہ ہے کہ ہمیں یہ بتانے کی ضرورت ہے کہ ہم کس سپر کلاس کے `_beforeTokenTransfer` کو اوور رائیڈ کر رہے ہیں۔ + +```solidity + super._beforeTokenTransfer(from, to, amount); +``` + +یہ لائن اس کنٹریکٹ یا کنٹریکٹس کے `_beforeTokenTransfer` فنکشن کو کال کرتی ہے جس سے ہم نے وراثت میں حاصل کیا ہے جس میں یہ ہے۔ اس معاملے میں، وہ صرف `ERC20` ہے، `Ownable` میں یہ ہُک نہیں ہے۔ اگرچہ فی الحال `ERC20._beforeTokenTransfer` کچھ نہیں کرتا، ہم اسے اس صورت میں کال کرتے ہیں کہ مستقبل میں فعالیت شامل کی جائے (اور پھر ہم کنٹریکٹ کو دوبارہ ڈیپلائے کرنے کا فیصلہ کرتے ہیں، کیونکہ کنٹریکٹس ڈیپلائیمنٹ کے بعد تبدیل نہیں ہوتے)۔ + +### ضروریات کی کوڈنگ {#coding-the-requirements} + +ہم فنکشن میں یہ ضروریات شامل کرنا چاہتے ہیں: + +- ایڈریس `to` `address(this)` کے برابر نہیں ہو سکتا، جو کہ خود ERC-20 کنٹریکٹ کا ایڈریس ہے۔ +- ایڈریس `to` خالی نہیں ہو سکتا، اسے یا تو ہونا چاہیے: + - ایک بیرونی ملکیت والا اکاؤنٹ (EOA)۔ ہم براہ راست یہ نہیں جانچ سکتے کہ کوئی ایڈریس EOA ہے یا نہیں، لیکن ہم کسی ایڈریس کا ETH بیلنس چیک کر سکتے ہیں۔ EOAs کا تقریباً ہمیشہ ایک بیلنس ہوتا ہے، چاہے وہ اب استعمال نہ ہو رہے ہوں - انہیں آخری wei تک صاف کرنا مشکل ہے۔ + - ایک اسمارٹ کنٹریکٹ۔ یہ جانچنا کہ آیا کوئی ایڈریس ایک اسمارٹ کنٹریکٹ ہے، تھوڑا مشکل ہے۔ ایک آپ کوڈ ہے جو بیرونی کوڈ کی لمبائی کو چیک کرتا ہے، جسے [`EXTCODESIZE`](https://www.evm.codes/#3b) کہتے ہیں، لیکن یہ Solidity میں براہ راست دستیاب نہیں ہے۔ اس کے لیے ہمیں [Yul](https://docs.soliditylang.org/en/v0.8.15/yul.html) کا استعمال کرنا ہوگا، جو کہ EVM اسمبلی ہے۔ کچھ اور قدریں ہیں جنہیں ہم Solidity سے استعمال کر سکتے ہیں ([`
.code` اور `
.codehash`](https://docs.soliditylang.org/en/v0.8.15/units-and-global-variables.html#members-of-address-types))، لیکن ان کی لاگت زیادہ ہے۔ + +آئیے نئے کوڈ کو لائن بہ لائن دیکھتے ہیں: + +```solidity + require(to != address(this), "کنٹریکٹ ایڈریس پر ٹوکن نہیں بھیج سکتے"); +``` + +یہ پہلی ضرورت ہے، جانچیں کہ `to` اور `this(address)` ایک ہی چیز نہیں ہیں۔ + +```solidity + bool isToContract; + assembly { + isToContract := gt(extcodesize(to), 0) + } +``` + +اس طرح ہم جانچتے ہیں کہ کوئی ایڈریس کنٹریکٹ ہے یا نہیں۔ ہم Yul سے براہ راست آؤٹ پٹ حاصل نہیں کر سکتے، اس لیے اس کے بجائے ہم نتیجہ رکھنے کے لیے ایک متغیر کی وضاحت کرتے ہیں (اس معاملے میں `isToContract`)۔ Yul اس طرح کام کرتا ہے کہ ہر آپ کوڈ کو ایک فنکشن سمجھا جاتا ہے۔ تو پہلے ہم کنٹریکٹ کا سائز حاصل کرنے کے لیے [`EXTCODESIZE`](https://www.evm.codes/#3b) کو کال کرتے ہیں، اور پھر [`GT`](https://www.evm.codes/#11) کا استعمال کرتے ہوئے یہ جانچتے ہیں کہ یہ صفر نہیں ہے (ہم غیر دستخط شدہ انٹیجرز کے ساتھ کام کر رہے ہیں، اس لیے یقیناً یہ منفی نہیں ہو سکتا)۔ پھر ہم نتیجہ `isToContract` میں لکھتے ہیں۔ + +```solidity + require(to.balance != 0 || isToContract, "خالی ایڈریس پر ٹوکن نہیں بھیج سکتے"); +``` + +اور آخر میں، ہمارے پاس خالی ایڈریسز کے لیے اصل جانچ ہے۔ + +## انتظامی رسائی {#admin-access} + +کبھی کبھی ایک ایڈمنسٹریٹر کا ہونا مفید ہوتا ہے جو غلطیوں کو کالعدم کر سکے۔ غلط استعمال کے امکانات کو کم کرنے کے لیے، یہ ایڈمنسٹریٹر ایک [ملٹی سگ](https://blog.logrocket.com/security-choices-multi-signature-wallets/) ہو سکتا ہے تاکہ متعدد لوگوں کو کسی کارروائی پر متفق ہونا پڑے۔ اس مضمون میں ہمارے پاس دو انتظامی خصوصیات ہوں گی: + +1. اکاؤنٹس کو منجمد اور غیر منجمد کرنا۔ یہ مفید ہو سکتا ہے، مثال کے طور پر، جب کسی اکاؤنٹ سے سمجھوتہ کیا گیا ہو۔ +2. اثاثوں کی صفائی۔ + + کبھی کبھی دھوکہ باز قانونی حیثیت حاصل کرنے کے لیے حقیقی ٹوکن کے کنٹریکٹ پر جعلی ٹوکن بھیجتے ہیں۔ مثال کے طور پر، [یہاں دیکھیں](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe?tab=holders)۔ جائز ERC-20 کنٹریکٹ [0x4200....0042](https://optimism.blockscout.com/token/0x4200000000000000000000000000000000000042) ہے۔ اسکیم جو اس کا دکھاوا کرتی ہے وہ [0x234....bbe](https://optimism.blockscout.com/token/0x2348B1a1228DDCd2dB668c3d30207c3E1852fBbe) ہے۔ + + یہ بھی ممکن ہے کہ لوگ غلطی سے ہمارے کنٹریکٹ میں جائز ERC-20 ٹوکن بھیج دیں، جو انہیں باہر نکالنے کا ایک طریقہ رکھنے کی ایک اور وجہ ہے۔ + +OpenZeppelin انتظامی رسائی کو فعال کرنے کے لیے دو میکانزم فراہم کرتا ہے: + +- [`Ownable`](https://docs.openzeppelin.com/contracts/5.x/access-control#ownership-and-ownable) کنٹریکٹس کا ایک ہی مالک ہوتا ہے۔ وہ فنکشنز جن میں `onlyOwner` [موڈیفائر](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) ہوتا ہے، انہیں صرف وہی مالک کال کر سکتا ہے۔ مالکان ملکیت کسی اور کو منتقل کر سکتے ہیں یا اسے مکمل طور پر ترک کر سکتے ہیں۔ دیگر تمام اکاؤنٹس کے حقوق عام طور پر یکساں ہوتے ہیں۔ +- [`AccessControl`](https://docs.openzeppelin.com/contracts/5.x/access-control#role-based-access-control) کنٹریکٹس میں [کردار پر مبنی رسائی کنٹرول (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control) ہوتا ہے۔ + +سادگی کی خاطر، اس مضمون میں ہم `Ownable` کا استعمال کرتے ہیں۔ + +### کنٹریکٹس کو منجمد اور غیر منجمد کرنا {#freezing-and-thawing-contracts} + +کنٹریکٹس کو منجمد اور غیر منجمد کرنے کے لیے کئی تبدیلیوں کی ضرورت ہوتی ہے: + +- ایڈریسز سے [بولینز](https://en.wikipedia.org/wiki/Boolean_data_type) تک ایک [میپنگ](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) یہ ٹریک رکھنے کے لیے کہ کون سے ایڈریسز منجمد ہیں۔ تمام قدریں ابتدائی طور پر صفر ہوتی ہیں، جس کی بولین قدروں کے لیے غلط تشریح کی جاتی ہے۔ یہ وہی ہے جو ہم چاہتے ہیں کیونکہ ڈیفالٹ کے طور پر اکاؤنٹس منجمد نہیں ہوتے ہیں۔ + + ```solidity + mapping(address => bool) public frozenAccounts; + ``` + +- [ایونٹس](https://www.tutorialspoint.com/solidity/solidity_events.htm) کسی بھی دلچسپی رکھنے والے کو مطلع کرنے کے لیے جب کوئی اکاؤنٹ منجمد یا غیر منجمد کیا جاتا ہے۔ تکنیکی طور پر ان کارروائیوں کے لیے ایونٹس کی ضرورت نہیں ہے، لیکن یہ آف چین کوڈ کو ان ایونٹس کو سننے اور یہ جاننے میں مدد کرتا ہے کہ کیا ہو رہا ہے۔ جب کوئی ایسی چیز ہوتی ہے جو کسی اور سے متعلق ہو سکتی ہے تو اسمارٹ کنٹریکٹ کے لیے انہیں خارج کرنا اچھے آداب سمجھے جاتے ہیں۔ + + ایونٹس انڈیکسڈ ہیں اس لیے ان تمام اوقات کو تلاش کرنا ممکن ہو گا جب کوئی اکاؤنٹ منجمد یا غیر منجمد کیا گیا ہو۔ + + ```solidity + // جب اکاؤنٹس منجمد یا غیر منجمد کیے جاتے ہیں + event AccountFrozen(address indexed _addr); + event AccountThawed(address indexed _addr); + ``` + +- اکاؤنٹس کو منجمد اور غیر منجمد کرنے کے لیے فنکشنز۔ یہ دونوں فنکشنز تقریباً ایک جیسے ہیں، اس لیے ہم صرف فریز فنکشن پر غور کریں گے۔ + + ```solidity + function freezeAccount(address addr) + public + onlyOwner + ``` + + [`public`](https://www.tutorialspoint.com/solidity/solidity_contracts.htm) سے نشان زد فنکشنز کو دوسرے اسمارٹ کنٹریکٹس سے یا براہ راست ٹرانزیکشن کے ذریعے کال کیا جا سکتا ہے۔ + + ```solidity + { + require(!frozenAccounts[addr], "اکاؤنٹ پہلے ہی منجمد ہے"); + frozenAccounts[addr] = true; + emit AccountFrozen(addr); + } // freezeAccount + ``` + + اگر اکاؤنٹ پہلے سے ہی منجمد ہے، تو واپس جائیں۔ ورنہ، اسے منجمد کریں اور ایک ایونٹ `emit` کریں۔ + +- منجمد اکاؤنٹ سے رقم کی منتقلی کو روکنے کے لیے `_beforeTokenTransfer` کو تبدیل کریں۔ نوٹ کریں کہ منجمد اکاؤنٹ میں اب بھی رقم منتقل کی جا سکتی ہے۔ + + ```solidity + require(!frozenAccounts[from], "اکاؤنٹ منجمد ہے"); + ``` + +### اثاثوں کی صفائی {#asset-cleanup} + +اس کنٹریکٹ کے ذریعے رکھے گئے ERC-20 ٹوکنز کو جاری کرنے کے لیے ہمیں اس ٹوکن کنٹریکٹ پر ایک فنکشن کال کرنے کی ضرورت ہے جس سے وہ تعلق رکھتے ہیں، یا تو [`transfer`](https://eips.ethereum.org/EIPS/eip-20#transfer) یا [`approve`](https://eips.ethereum.org/EIPS/eip-20#approve)۔ اس معاملے میں الاؤنسز پر گیس ضائع کرنے کا کوئی فائدہ نہیں، ہم براہ راست بھی منتقل کر سکتے ہیں۔ + +```solidity + function cleanupERC20( + address erc20, + address dest + ) + public + onlyOwner + { + IERC20 token = IERC20(erc20); +``` + +جب ہم ایڈریس وصول کرتے ہیں تو یہ ایک کنٹریکٹ کے لیے آبجیکٹ بنانے کا نحو ہے۔ ہم ایسا کر سکتے ہیں کیونکہ ہمارے پاس سورس کوڈ کے حصے کے طور پر ERC20 ٹوکنز کی تعریف ہے (لائن 4 دیکھیں)، اور اس فائل میں [IERC20 کی تعریف](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) شامل ہے، جو ایک OpenZeppelin ERC-20 کنٹریکٹ کے لیے انٹرفیس ہے۔ + +```solidity + uint balance = token.balanceOf(address(this)); + token.transfer(dest, balance); + } +``` + +یہ ایک کلین اپ فنکشن ہے، اس لیے قیاس ہے کہ ہم کوئی ٹوکن نہیں چھوڑنا چاہتے۔ صارف سے دستی طور پر بیلنس حاصل کرنے کے بجائے، ہم اس عمل کو خودکار بھی بنا سکتے ہیں۔ + +## نتیجہ {#conclusion} + +یہ ایک کامل حل نہیں ہے - "صارف نے غلطی کی" کے مسئلے کا کوئی کامل حل نہیں ہے۔ تاہم، اس قسم کی جانچ کا استعمال کم از کم کچھ غلطیوں کو روک سکتا ہے۔ اکاؤنٹس کو منجمد کرنے کی صلاحیت، اگرچہ خطرناک ہے، لیکن ہیکر کو چوری شدہ فنڈز سے انکار کرکے کچھ ہیکس کے نقصان کو محدود کرنے کے لیے استعمال کی جا سکتی ہے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/ethereum-for-web2-auth/index.md b/public/content/translations/ur/developers/tutorials/ethereum-for-web2-auth/index.md new file mode 100644 index 00000000000..18b8dc33934 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/ethereum-for-web2-auth/index.md @@ -0,0 +1,886 @@ +--- +title: "ویب 2 کی توثیق کے لیے ایتھیریم کا استعمال" +description: "اس ٹیوٹوریل کو پڑھنے کے بعد، ایک ڈیولپر ایتھیریم لاگ ان (ویب 3) کو SAML لاگ ان کے ساتھ مربوط کر سکے گا، جو ویب 2 میں سنگل سائن آن اور دیگر متعلقہ خدمات فراہم کرنے کے لیے استعمال ہونے والا ایک معیار ہے۔ یہ ویب 2 وسائل تک رسائی کی توثیق ایتھیریم دستخطوں کے ذریعے کرنے کی اجازت دیتا ہے، جس میں صارف کی خصوصیات تصدیق ناموں سے آتی ہیں۔" +author: Ori Pomerantz +tags: [ "ویب 2", "توثیق (Authentication)", "eas" ] +skill: beginner +lang: ur-in +published: 2025-04-30 +--- + +## تعارف + +[SAML](https://www.onelogin.com/learn/saml) ویب 2 پر استعمال ہونے والا ایک معیار ہے جو [شناختی فراہم کنندہ (IdP)](https://en.wikipedia.org/wiki/Identity_provider#SAML_identity_provider) کو [سروس فراہم کنندگان (SP)](https://en.wikipedia.org/wiki/Service_provider_\(SAML\)) کے لیے صارف کی معلومات فراہم کرنے کی اجازت دیتا ہے۔ + +اس ٹیوٹوریل میں آپ سیکھیں گے کہ ایتھیریم دستخطوں کو SAML کے ساتھ کیسے مربوط کیا جائے تاکہ صارفین اپنے ایتھیریم والیٹس کا استعمال ان ویب 2 خدمات کے لیے خود کی توثیق کر سکیں جو ابھی تک مقامی طور پر ایتھیریم کو سپورٹ نہیں کرتی ہیں۔ + +نوٹ کریں کہ یہ ٹیوٹوریل دو الگ الگ سامعین کے لیے لکھا گیا ہے: + +- ایتھیریم کے لوگ جو ایتھیریم کو سمجھتے ہیں اور انہیں SAML سیکھنے کی ضرورت ہے۔ +- ویب 2 کے لوگ جو SAML اور ویب 2 کی توثیق کو سمجھتے ہیں اور انہیں ایتھیریم سیکھنے کی ضرورت ہے۔ + +نتیجتاً، اس میں بہت سارا تعارفی مواد ہوگا جو آپ پہلے سے جانتے ہیں۔ بلا جھجھک اسے چھوڑ دیں۔ + +### ایتھیریم کے لوگوں کے لیے SAML + +SAML ایک مرکزی پروٹوکول ہے۔ ایک سروس فراہم کنندہ (SP) صرف ایک شناختی فراہم کنندہ (IdP) سے دعوے (جیسے "یہ میرا صارف جان ہے، اس کے پاس A، B اور C کرنے کی اجازت ہونی چاہیے") قبول کرتا ہے اگر اس کے ساتھ پہلے سے موجود اعتماد کا رشتہ ہو، یا اس [سرٹیفکیٹ اتھارٹی](https://www.ssl.com/article/what-is-a-certificate-authority-ca/) کے ساتھ جس نے اس IdP کے سرٹیفکیٹ پر دستخط کیے ہیں۔ + +مثال کے طور پر، SP ایک ٹریول ایجنسی ہو سکتی ہے جو کمپنیوں کو سفری خدمات فراہم کرتی ہے، اور IdP کمپنی کی اندرونی ویب سائٹ ہو سکتی ہے۔ جب ملازمین کو کاروباری سفر بک کرنے کی ضرورت ہوتی ہے، تو ٹریول ایجنسی انہیں اصل میں سفر بک کرنے کی اجازت دینے سے پہلے کمپنی کے ذریعے توثیق کے لیے بھیجتی ہے۔ + +![مرحلہ وار SAML عمل](./fig-01-saml.png) + +یہ وہ طریقہ ہے جس سے تینوں ادارے، براؤزر، SP، اور IdP، رسائی کے لیے گفت و شنید کرتے ہیں۔ SP کو براؤزر استعمال کرنے والے صارف کے بارے میں پہلے سے کچھ جاننے کی ضرورت نہیں، صرف IdP پر بھروسہ کرنے کی ضرورت ہے۔ + +### SAML کے لوگوں کے لیے ایتھیریم + +ایتھیریم ایک غیر مرکزی نظام ہے۔ + +![ایتھیریم لاگ آن](./fig-02-eth-logon.png) + +صارفین کے پاس ایک نجی کلید ہوتی ہے (عام طور پر براؤزر ایکسٹینشن میں رکھی جاتی ہے)۔ نجی کلید سے آپ ایک عوامی کلید، اور اس سے 20 بائٹ کا پتہ اخذ کر سکتے ہیں۔ جب صارفین کو کسی سسٹم میں لاگ ان کرنے کی ضرورت ہوتی ہے، تو ان سے نانس (ایک بار استعمال ہونے والی قدر) کے ساتھ ایک پیغام پر دستخط کرنے کی درخواست کی جاتی ہے۔ سرور اس بات کی تصدیق کر سکتا ہے کہ دستخط اسی پتے سے بنایا گیا تھا۔ + +![تصدیق ناموں سے اضافی ڈیٹا حاصل کرنا](./fig-03-eas-data.png) + +دستخط صرف ایتھیریم پتے کی تصدیق کرتا ہے۔ دیگر صارف صفات حاصل کرنے کے لیے، آپ عام طور پر [تصدیق نامے](https://attest.org/) استعمال کرتے ہیں۔ ایک تصدیق نامے میں عام طور پر یہ فیلڈز ہوتے ہیں: + +- **تصدیق کنندہ**، وہ پتہ جس نے تصدیق کی +- **وصول کنندہ**، وہ پتہ جس پر تصدیق کا اطلاق ہوتا ہے +- **ڈیٹا**، وہ ڈیٹا جس کی تصدیق کی جا رہی ہے، جیسے نام، اجازتیں وغیرہ۔ +- **اسکیما**، ڈیٹا کی تشریح کے لیے استعمال ہونے والے اسکیما کی آئی ڈی۔ + +ایتھیریم کی غیر مرکزی نوعیت کی وجہ سے، کوئی بھی صارف تصدیق نامے بنا سکتا ہے۔ تصدیق کنندہ کی شناخت اس بات کی نشاندہی کرنے کے لیے اہم ہے کہ ہم کن تصدیق ناموں کو قابل اعتماد سمجھتے ہیں۔ + +## سیٹ اپ + +پہلا قدم ایک SAML SP اور ایک SAML IdP کا ہونا ہے جو آپس میں مواصلت کر رہے ہوں۔ + +1. سافٹ ویئر ڈاؤن لوڈ کریں۔ اس مضمون کے لیے نمونہ سافٹ ویئر [گٹ ہب پر](https://github.com/qbzzt/250420-saml-ethereum) ہے۔ مختلف مراحل مختلف برانچوں میں محفوظ ہیں، اس مرحلے کے لیے آپ کو `saml-only` چاہیے۔ + + ```sh + git clone https://github.com/qbzzt/250420-saml-ethereum -b saml-only + cd 250420-saml-ethereum + pnpm install + ``` + +2. خود دستخط شدہ سرٹیفکیٹس کے ساتھ کلیدیں بنائیں۔ اس کا مطلب ہے کہ کلید خود اپنی سرٹیفکیٹ اتھارٹی ہے، اور اسے دستی طور پر سروس فراہم کنندہ میں درآمد کرنے کی ضرورت ہے۔ مزید معلومات کے لیے [OpenSSL دستاویزات](https://docs.openssl.org/master/man1/openssl-req/) دیکھیں۔ + + ```sh + mkdir keys + cd keys + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-sp.crt -keyout saml-sp.pem -subj /CN=sp/ + openssl req -new -x509 -days 365 -nodes -sha256 -out saml-idp.crt -keyout saml-idp.pem -subj /CN=idp/ + cd .. + ``` + +3. سرورز (SP اور IdP دونوں) شروع کریں + + ```sh + pnpm start + ``` + +4. URL [http://localhost:3000/](http://localhost:3000/) پر SP پر براؤز کریں اور IdP (پورٹ 3001) پر ری ڈائریکٹ ہونے کے لیے بٹن پر کلک کریں۔ + +5. IdP کو اپنا ای میل پتہ فراہم کریں اور **سروس فراہم کنندہ میں لاگ ان کریں** پر کلک کریں۔ دیکھیں کہ آپ کو سروس فراہم کنندہ (پورٹ 3000) پر واپس ری ڈائریکٹ کر دیا گیا ہے اور یہ آپ کو آپ کے ای میل پتے سے جانتا ہے۔ + +### تفصیلی وضاحت + +یہ ہے جو ہوتا ہے، مرحلہ وار: + +![ایتھیریم کے بغیر عام SAML لاگ آن](./fig-04-saml-no-eth.png) + +#### src/config.mts + +اس فائل میں شناختی فراہم کنندہ اور سروس فراہم کنندہ دونوں کے لیے کنفیگریشن موجود ہے۔ عام طور پر یہ دونوں مختلف ادارے ہوں گے، لیکن یہاں ہم سادگی کے لیے کوڈ شیئر کر سکتے ہیں۔ + +```typescript +const fs = await import("fs") + +const protocol="http" +``` + +ابھی کے لیے ہم صرف ٹیسٹ کر رہے ہیں، لہذا HTTP استعمال کرنا ٹھیک ہے۔ + +```typescript +export const spCert = fs.readFileSync("keys/saml-sp.crt").toString() +export const idpCert = fs.readFileSync("keys/saml-idp.crt").toString() +``` + +عوامی کلیدیں پڑھیں، جو عام طور پر دونوں اجزاء کے لیے دستیاب ہوتی ہیں (اور یا تو براہ راست قابل اعتماد ہوتی ہیں، یا کسی قابل اعتماد سرٹیفکیٹ اتھارٹی کے ذریعے دستخط شدہ ہوتی ہیں)۔ + +```typescript +export const spPort = 3000 +export const spHostname = "localhost" +export const spDir = "sp" + +export const idpPort = 3001 +export const idpHostname = "localhost" +export const idpDir = "idp" + +export const spUrl = `${protocol}://${spHostname}:${spPort}/${spDir}` +export const idpUrl = `${protocol}://${idpHostname}:${idpPort}/${idpDir}` +``` + +دونوں اجزاء کے لیے URLs۔ + +```typescript +export const spPublicData = { +``` + +سروس فراہم کنندہ کے لیے عوامی ڈیٹا۔ + +```typescript + entityID: `${spUrl}/metadata`, +``` + +روایت کے مطابق، SAML میں `entityID` وہ URL ہے جہاں ادارے کا میٹا ڈیٹا دستیاب ہوتا ہے۔ یہ میٹا ڈیٹا یہاں عوامی ڈیٹا سے مطابقت رکھتا ہے، سوائے اس کے کہ یہ XML فارم میں ہے۔ + +```typescript + wantAssertionsSigned: true, + authnRequestsSigned: false, + signingCert: spCert, + allowCreate: true, + assertionConsumerService: [{ + Binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + Location: `${spUrl}/assertion`, + }] + } +``` + +ہمارے مقاصد کے لیے سب سے اہم تعریف `assertionConsumerServer` ہے۔ اس کا مطلب ہے کہ سروس فراہم کنندہ کو کسی چیز کا دعویٰ کرنے کے لیے (مثال کے طور پر، "یہ معلومات بھیجنے والا صارف somebody@example.com ہے") ہمیں URL `http://localhost:3000/sp/assertion` پر [HTTP POST](https://www.w3schools.com/tags/ref_httpmethods.asp) استعمال کرنے کی ضرورت ہے۔ + +```typescript +export const idpPublicData = { + entityID: `${idpUrl}/metadata`, + signingCert: idpCert, + wantAuthnRequestsSigned: false, + singleSignOnService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/login` + }], + singleLogoutService: [{ + Binding: "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", + Location: `${idpUrl}/logout` + }], + } +``` + +شناختی فراہم کنندہ کے لیے عوامی ڈیٹا اسی طرح کا ہے۔ یہ بتاتا ہے کہ کسی صارف کو لاگ ان کرنے کے لیے آپ `http://localhost:3001/idp/login` پر POST کرتے ہیں اور کسی صارف کو لاگ آؤٹ کرنے کے لیے آپ `http://localhost:3001/idp/logout` پر POST کرتے ہیں۔ + +#### src/sp.mts + +یہ وہ کوڈ ہے جو سروس فراہم کنندہ کو نافذ کرتا ہے۔ + +```typescript +import * as config from "./config.mts" +const fs = await import("fs") +const saml = await import("samlify") +``` + +ہم SAML کو نافذ کرنے کے لیے [`samlify`](https://www.npmjs.com/package/samlify) لائبریری کا استعمال کرتے ہیں۔ + +```typescript +import * as validator from "@authenio/samlify-node-xmllint" +saml.setSchemaValidator(validator) +``` + +`samlify` لائبریری ایک پیکیج سے یہ توثیق کرنے کی توقع کرتی ہے کہ XML درست ہے، متوقع عوامی کلید کے ساتھ دستخط شدہ ہے، وغیرہ۔ ہم اس مقصد کے لیے [`@authenio/samlify-node-xmllint`](https://www.npmjs.com/package/@authenio/samlify-node-xmllint) کا استعمال کرتے ہیں۔ + +```typescript +const express = (await import("express")).default +const spRouter = express.Router() +const app = express() +``` + +ایک [`express`](https://expressjs.com/) [`Router`](https://expressjs.com/en/5x/api.html#router) ایک "چھوٹی ویب سائٹ" ہے جسے کسی ویب سائٹ کے اندر نصب کیا جا سکتا ہے۔ اس معاملے میں، ہم اسے تمام سروس فراہم کنندہ کی تعریفوں کو ایک ساتھ گروپ کرنے کے لیے استعمال کرتے ہیں۔ + +```typescript +const spPrivateKey = fs.readFileSync("keys/saml-sp.pem").toString() + +const sp = saml.ServiceProvider({ + privateKey: spPrivateKey, + ...config.spPublicData +}) +``` + +سروس فراہم کنندہ کی اپنی نمائندگی تمام عوامی ڈیٹا، اور وہ نجی کلید ہے جسے وہ معلومات پر دستخط کرنے کے لیے استعمال کرتا ہے۔ + +```typescript +const idp = saml.IdentityProvider(config.idpPublicData); +``` + +عوامی ڈیٹا میں وہ سب کچھ ہوتا ہے جو سروس فراہم کنندہ کو شناختی فراہم کنندہ کے بارے میں جاننے کی ضرورت ہوتی ہے۔ + +```typescript +spRouter.get(`/metadata`, + (req, res) => res.header("Content-Type", "text/xml").send(sp.getMetadata()) +) +``` + +دیگر SAML اجزاء کے ساتھ باہمی تعاون کو فعال کرنے کے لیے، سروس اور شناختی فراہم کنندگان کو اپنا عوامی ڈیٹا (جسے میٹا ڈیٹا کہا جاتا ہے) `/metadata` میں XML فارمیٹ میں دستیاب ہونا چاہیے۔ + +```typescript +spRouter.post(`/assertion`, +``` + +یہ وہ صفحہ ہے جس تک براؤزر اپنی شناخت کے لیے رسائی حاصل کرتا ہے۔ دعویٰ میں صارف کا شناخت کنندہ (یہاں ہم ای میل پتہ استعمال کرتے ہیں) شامل ہوتا ہے، اور اس میں اضافی صفات بھی شامل ہو سکتی ہیں۔ یہ اوپر کے ترتیب وار خاکے میں مرحلہ 7 کے لیے ہینڈلر ہے۔ + +```typescript + async (req, res) => { + // console.log(`SAML response:\n${Buffer.from(req.body.SAMLResponse, 'base64').toString('utf-8')}`) +``` + +آپ دعوے میں فراہم کردہ XML ڈیٹا دیکھنے کے لیے کمنٹ آؤٹ کمانڈ کا استعمال کر سکتے ہیں۔ یہ [بیس 64 انکوڈڈ](https://en.wikipedia.org/wiki/Base64) ہے۔ + +```typescript + try { + const loginResponse = await sp.parseLoginResponse(idp, 'post', req); +``` + +شناختی سرور سے لاگ ان کی درخواست کو پارس کریں۔ + +```typescript + res.send(` + + +

ہیلو ${loginResponse.extract.nameID}

+ + + `) + res.send(); +``` + +ایک HTML جواب بھیجیں، صرف صارف کو یہ دکھانے کے لیے کہ ہمیں لاگ ان مل گیا ہے۔ + +```typescript + } catch (err) { + console.error('SAML جواب پر کارروائی کرنے میں خرابی:', err); + res.status(400).send('SAML توثیق ناکام'); + } + } +) +``` + +ناکامی کی صورت میں صارف کو مطلع کریں۔ + +```typescript +spRouter.get('/login', +``` + +جب براؤزر اس صفحے کو حاصل کرنے کی کوشش کرتا ہے تو ایک لاگ ان درخواست بنائیں۔ یہ اوپر کے ترتیب وار خاکے میں مرحلہ 1 کے لیے ہینڈلر ہے۔ + +```typescript + async (req, res) => { + const loginRequest = await sp.createLoginRequest(idp, "post") +``` + +لاگ ان کی درخواست پوسٹ کرنے کے لیے معلومات حاصل کریں۔ + +```typescript + res.send(` + + + +``` + +یہ صفحہ خود بخود فارم (نیچے دیکھیں) جمع کراتا ہے۔ اس طرح صارف کو ری ڈائریکٹ ہونے کے لیے کچھ کرنے کی ضرورت نہیں ہے۔ یہ اوپر کے ترتیب وار خاکے میں مرحلہ 2 ہے۔ + +```typescript +
+``` + +`loginRequest.entityEndpoint` (شناختی فراہم کنندہ کے اینڈ پوائنٹ کا URL) پر پوسٹ کریں۔ + +```typescript + +``` + +ان پٹ کا نام `loginRequest.type` (`SAMLRequest`) ہے۔ اس فیلڈ کا مواد `loginRequest.context` ہے، جو دوبارہ XML ہے جو بیس 64 انکوڈڈ ہے۔ + +```typescript +
+ + + `) + } +) + +app.use(express.urlencoded({extended: true})) +``` + +[یہ مڈل ویئر](https://expressjs.com/en/5x/api.html#express.urlencoded) [HTTP درخواست](https://www.tutorialspoint.com/http/http_requests.htm) کی باڈی کو پڑھتا ہے۔ پہلے سے طے شدہ طور پر express اسے نظر انداز کرتا ہے، کیونکہ زیادہ تر درخواستوں کو اس کی ضرورت نہیں ہوتی۔ ہمیں اس کی ضرورت ہے کیونکہ POST باڈی کا استعمال کرتا ہے۔ + +```typescript +app.use(`/${config.spDir}`, spRouter) +``` + +راؤٹر کو سروس فراہم کنندہ ڈائرکٹری (`/sp`) میں نصب کریں۔ + +```typescript +app.get("/", (req, res) => { + res.send(` + + + + + + `) +}) +``` + +اگر کوئی براؤزر روٹ ڈائرکٹری حاصل کرنے کی کوشش کرتا ہے، تو اسے لاگ ان صفحہ کا ایک لنک فراہم کریں۔ + +```typescript +app.listen(config.spPort, () => { + console.log(`سروس فراہم کنندہ http://${config.spHostname}:${config.spPort} پر چل رہا ہے`) +}) +``` + +اس express ایپلیکیشن کے ساتھ `spPort` کو سنیں۔ + +#### src/idp.mts + +یہ شناختی فراہم کنندہ ہے۔ یہ سروس فراہم کنندہ سے بہت ملتا جلتا ہے، نیچے دی گئی وضاحتیں ان حصوں کے لیے ہیں جو مختلف ہیں۔ + +```typescript +const xmlParser = new (await import("fast-xml-parser")).XMLParser( + { + ignoreAttributes: false, // صفات کو محفوظ رکھیں + attributeNamePrefix: "@_", // صفات کے لیے سابقہ + } +) +``` + +ہمیں سروس فراہم کنندہ سے موصول ہونے والی XML درخواست کو پڑھنے اور سمجھنے کی ضرورت ہے۔ + +```typescript +const getLoginPage = requestId => ` +``` + +یہ فنکشن خودکار طور پر جمع کردہ فارم کے ساتھ صفحہ بناتا ہے جو اوپر کے ترتیب وار خاکے کے مرحلہ 4 میں واپس آتا ہے۔ + +```typescript + + + لاگ ان صفحہ + + +

لاگ ان صفحہ

+
+ + ای میل پتہ: +
+ +``` + +دو فیلڈز ہیں جو ہم سروس فراہم کنندہ کو بھیجتے ہیں: + +1. وہ `requestId` جس کا ہم جواب دے رہے ہیں۔ +2. صارف کا شناخت کنندہ (ہم ابھی کے لیے صارف کا فراہم کردہ ای میل پتہ استعمال کرتے ہیں)۔ + +```typescript +
+ + + +const idpRouter = express.Router() + +idpRouter.post("/loginSubmitted", async (req, res) => { + const loginResponse = await idp.createLoginResponse( +``` + +یہ اوپر کے ترتیب وار خاکے کے مرحلہ 5 کے لیے ہینڈلر ہے۔ [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125) لاگ ان جواب بناتا ہے۔ + +```typescript + sp, + { + authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', + audience: sp.entityID, +``` + +سامعین سروس فراہم کنندہ ہے۔ + +```typescript + extract: { + request: { + id: req.body.requestId + } + }, +``` + +درخواست سے نکالی گئی معلومات۔ درخواست میں جس ایک پیرامیٹر کا ہم خیال رکھتے ہیں وہ requestId ہے، جو سروس فراہم کنندہ کو درخواستوں اور ان کے جوابات کو ملانے دیتا ہے۔ + +```typescript + signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // دستخط کو یقینی بنائیں +``` + +جواب پر دستخط کرنے کے لیے ڈیٹا رکھنے کے لیے ہمیں `signingKey` کی ضرورت ہے۔ سروس فراہم کنندہ غیر دستخط شدہ درخواستوں پر بھروسہ نہیں کرتا ہے۔ + +```typescript + }, + "post", + { + email: req.body.email +``` + +یہ صارف کی معلومات کے ساتھ وہ فیلڈ ہے جسے ہم سروس فراہم کنندہ کو واپس بھیجتے ہیں۔ + +```typescript + } + ); + + res.send(` + + + + +
+ +
+ + + `) +}) +``` + +دوبارہ، ایک خودکار طور پر جمع کردہ فارم استعمال کریں۔ یہ اوپر کے ترتیب وار خاکے کا مرحلہ 6 ہے۔ + +```typescript + +// لاگ ان درخواستوں کے لیے IdP اینڈ پوائنٹ +idpRouter.post(`/login`, +``` + +یہ وہ اینڈ پوائنٹ ہے جو سروس فراہم کنندہ سے لاگ ان کی درخواست وصول کرتا ہے۔ یہ اوپر کے ترتیب وار خاکے کے مرحلہ 3 کا ہینڈلر ہے۔ + +```typescript + async (req, res) => { + try { + // ورک اراؤنڈ کیونکہ میں parseLoginRequest کو کام کرنے پر مجبور نہیں کر سکا۔ + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"])) +``` + +ہمیں توثیق کی درخواست کی آئی ڈی کو پڑھنے کے لیے [`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144) کا استعمال کرنے کے قابل ہونا چاہیے۔ تاہم، میں اسے کام کرنے پر مجبور نہیں کر سکا اور اس پر زیادہ وقت صرف کرنا مناسب نہیں تھا، لہذا میں نے صرف ایک [عام مقصد کے XML پارسر](https://www.npmjs.com/package/fast-xml-parser) کا استعمال کیا۔ ہمیں جس معلومات کی ضرورت ہے وہ `` ٹیگ کے اندر `ID` کی صفت ہے، جو XML کی اعلیٰ سطح پر ہے۔ + +## ایتھیریم دستخطوں کا استعمال + +اب جب کہ ہم صارف کی شناخت سروس فراہم کنندہ کو بھیج سکتے ہیں، اگلا قدم صارف کی شناخت کو قابل اعتماد طریقے سے حاصل کرنا ہے۔ Viem ہمیں صرف والیٹ سے صارف کا پتہ پوچھنے کی اجازت دیتا ہے، لیکن اس کا مطلب ہے براؤزر سے معلومات مانگنا۔ ہم براؤزر کو کنٹرول نہیں کرتے ہیں، لہذا ہم اس سے ملنے والے جواب پر خود بخود بھروسہ نہیں کر سکتے۔ + +اس کے بجائے، IdP براؤزر کو دستخط کرنے کے لیے ایک سٹرنگ بھیجے گا۔ اگر براؤزر میں موجود والیٹ اس سٹرنگ پر دستخط کرتا ہے، تو اس کا مطلب ہے کہ یہ واقعی وہی پتہ ہے (یعنی، یہ اس پتے سے مطابقت رکھنے والی نجی کلید کو جانتا ہے)۔ + +اسے عملی طور پر دیکھنے کے لیے، موجودہ IdP اور SP کو روکیں اور یہ کمانڈز چلائیں: + +```sh +git checkout eth-signatures +pnpm install +pnpm start +``` + +پھر [SP پر](http://localhost:3000) براؤز کریں اور ہدایات پر عمل کریں۔ + +نوٹ کریں کہ اس مقام پر ہم نہیں جانتے کہ ایتھیریم پتے سے ای میل پتہ کیسے حاصل کیا جائے، لہذا اس کے بجائے ہم SP کو `@bad.email.address` کی اطلاع دیتے ہیں۔ + +### تفصیلی وضاحت + +تبدیلیاں پچھلے خاکے میں مرحلہ 4-5 میں ہیں۔ + +![ایتھیریم دستخط کے ساتھ SAML](./fig-05-saml-w-signature.png) + +ہم نے جو واحد فائل تبدیل کی ہے وہ `idp.mts` ہے۔ یہاں تبدیل شدہ حصے ہیں۔ + +```typescript +import { v4 as uuidv4 } from 'uuid' +import { verifyMessage } from 'viem' +``` + +ہمیں ان دو اضافی لائبریریوں کی ضرورت ہے۔ ہم [نانس](https://en.wikipedia.org/wiki/Cryptographic_nonce) کی قدر بنانے کے لیے [`uuid`](https://www.npmjs.com/package/uuid) کا استعمال کرتے ہیں۔ قدر خود کوئی معنی نہیں رکھتی، صرف یہ حقیقت کہ یہ صرف ایک بار استعمال ہوتی ہے۔ + +[`viem`](https://viem.sh/) لائبریری ہمیں ایتھیریم کی تعریفیں استعمال کرنے دیتی ہے۔ یہاں ہمیں اس کی تصدیق کرنے کی ضرورت ہے کہ دستخط واقعی درست ہے۔ + +```typescript +const loginPrompt = "سروس فراہم کنندہ تک رسائی حاصل کرنے کے لیے، اس نانس پر دستخط کریں: " +``` + +والیٹ صارف سے پیغام پر دستخط کرنے کی اجازت مانگتا ہے۔ ایک پیغام جو صرف ایک نانس ہو صارفین کو الجھا سکتا ہے، لہذا ہم اس پرامپٹ کو شامل کرتے ہیں۔ + +```typescript +// requestIDs یہاں رکھیں +let nonces = {} +``` + +ہمیں درخواست کی معلومات کی ضرورت ہے تاکہ ہم اس کا جواب دے سکیں۔ ہم اسے درخواست کے ساتھ بھیج سکتے ہیں (مرحلہ 4)، اور اسے واپس وصول کر سکتے ہیں (مرحلہ 5)۔ تاہم، ہم براؤزر سے ملنے والی معلومات پر بھروسہ نہیں کر سکتے، جو ایک ممکنہ طور پر مخالف صارف کے کنٹرول میں ہے۔ لہذا اسے یہاں محفوظ کرنا بہتر ہے، نانس کو کلید کے طور پر استعمال کرتے ہوئے۔ + +نوٹ کریں کہ ہم سادگی کی خاطر اسے یہاں ایک متغیر کے طور پر کر رہے ہیں۔ تاہم، اس کے کئی نقصانات ہیں: + +- ہم سروس سے انکار کے حملے کا شکار ہیں۔ ایک بدنیتی پر مبنی صارف متعدد بار لاگ آن کرنے کی کوشش کر سکتا ہے، جس سے ہماری میموری بھر جائے گی۔ +- اگر IdP کے عمل کو دوبارہ شروع کرنے کی ضرورت پڑی تو، ہم موجودہ قدروں کو کھو دیں گے۔ +- ہم متعدد پروسیسز میں لوڈ بیلنس نہیں کر سکتے، کیونکہ ہر ایک کا اپنا متغیر ہوگا۔ + +پروڈکشن سسٹم پر ہم ڈیٹا بیس کا استعمال کریں گے اور کسی قسم کا میعاد ختم ہونے کا طریقہ کار نافذ کریں گے۔ + +```typescript +const getSignaturePage = requestId => { + const nonce = uuidv4() + nonces[nonce] = requestId +``` + +ایک نانس بنائیں، اور مستقبل میں استعمال کے لیے `requestId` کو محفوظ کریں۔ + +```typescript + return ` + + + + + +

براہ کرم دستخط کریں

+ +
+ + + +` +} +``` + +باقی صرف معیاری HTML ہے۔ + +```typescript +idpRouter.get("/signature/:nonce/:account/:signature", async (req, res) => { +``` + +یہ ترتیب وار خاکے میں مرحلہ 5 کے لیے ہینڈلر ہے۔ + +```typescript + const requestId = nonces[req.params.nonce] + if (requestId === undefined) { + res.send("خراب نانس") + return ; + } + + nonces[req.params.nonce] = undefined +``` + +درخواست کی آئی ڈی حاصل کریں، اور `nonces` سے نانس کو حذف کریں تاکہ یہ یقینی بنایا جا سکے کہ اسے دوبارہ استعمال نہیں کیا جا سکتا۔ + +```typescript + try { +``` + +چونکہ دستخط کے غلط ہونے کے بہت سے طریقے ہیں، ہم اسے ایک `try ...` میں لپیٹتے ہیں۔ کسی بھی پھینکی گئی غلطیوں کو پکڑنے کے لیے `catch` بلاک۔ + +```typescript + const validSignature = await verifyMessage({ + address: req.params.account, + message: `${loginPrompt}${req.params.nonce}`, + signature: req.params.signature + }) +``` + +ترتیب وار خاکے میں مرحلہ 5.5 کو نافذ کرنے کے لیے [`verifyMessage`](https://viem.sh/docs/actions/public/verifyMessage#verifymessage) کا استعمال کریں۔ + +```typescript + if (!validSignature) + throw("خراب دستخط") + } catch (err) { + res.send("خرابی:" + err) + return ; + } +``` + +ہینڈلر کا بقیہ حصہ اس کے برابر ہے جو ہم نے پہلے `/loginSubmitted` ہینڈلر میں کیا ہے، سوائے ایک چھوٹی سی تبدیلی کے۔ + +```typescript + const loginResponse = await idp.createLoginResponse( + . + . + . + { + email: req.params.account + "@bad.email.address" + } + ); +``` + +ہمارے پاس اصل ای میل پتہ نہیں ہے (ہم اسے اگلے حصے میں حاصل کریں گے)، لہذا ابھی کے لیے ہم ایتھیریم پتہ واپس کرتے ہیں اور اسے واضح طور پر ای میل پتے کے طور پر نشان زد نہیں کرتے ہیں۔ + +```typescript +// لاگ ان درخواستوں کے لیے IdP اینڈ پوائنٹ +idpRouter.post(`/login`, + async (req, res) => { + try { + // ورک اراؤنڈ کیونکہ میں parseLoginRequest کو کام کرنے پر مجبور نہیں کر سکا۔ + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getSignaturePage(samlRequest["samlp:AuthnRequest"]["@_ID"])) + } catch (err) { + console.error('SAML جواب پر کارروائی کرنے میں خرابی:', err); + res.status(400).send('SAML توثیق ناکام'); + } + } +) +``` + +مرحلہ 3 کے ہینڈلر میں `getLoginPage` کی بجائے اب `getSignaturePage` کا استعمال کریں۔ + +## ای میل پتہ حاصل کرنا + +اگلا قدم ای میل پتہ حاصل کرنا ہے، جو سروس فراہم کنندہ کی طرف سے درخواست کردہ شناخت کنندہ ہے۔ ایسا کرنے کے لیے، ہم [ایتھیریم تصدیقی سروس (EAS)](https://attest.org/) کا استعمال کرتے ہیں۔ + +تصدیق نامے حاصل کرنے کا سب سے آسان طریقہ [GraphQL API](https://docs.attest.org/docs/developer-tools/api) کا استعمال کرنا ہے۔ ہم اس استفسار کا استعمال کرتے ہیں: + +``` +query GetAttestationsByRecipient { + attestations( + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } + take: 1 + ) { + data + id + attester + } +} +``` + +اس [`schemaId`](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) میں صرف ایک ای میل پتہ شامل ہے۔ یہ استفسار اس اسکیما کے تصدیق ناموں کی درخواست کرتا ہے۔ تصدیق نامے کا موضوع `recipient` کہلاتا ہے۔ یہ ہمیشہ ایک ایتھیریم پتہ ہوتا ہے۔ + +انتباہ: جس طرح سے ہم یہاں تصدیق نامے حاصل کر رہے ہیں اس میں دو حفاظتی مسائل ہیں۔ + +- ہم API اینڈ پوائنٹ، `https://optimism.easscan.org/graphql` پر جا رہے ہیں، جو ایک مرکزی جزو ہے۔ ہم `id` صفت حاصل کر سکتے ہیں اور پھر آن چین پر ایک تلاش کر کے تصدیق کر سکتے ہیں کہ تصدیق نامہ حقیقی ہے، لیکن API اینڈ پوائنٹ اب بھی ہمیں ان کے بارے میں نہ بتا کر تصدیق ناموں کو سنسر کر سکتا ہے۔ + + یہ مسئلہ حل کرنا ناممکن نہیں ہے، ہم اپنا GraphQL اینڈ پوائنٹ چلا سکتے ہیں اور چین لاگز سے تصدیق نامے حاصل کر سکتے ہیں، لیکن یہ ہمارے مقاصد کے لیے ضرورت سے زیادہ ہے۔ + +- ہم تصدیق کنندہ کی شناخت کو نہیں دیکھتے ہیں۔ کوئی بھی ہمیں غلط معلومات فراہم کر سکتا ہے۔ ایک حقیقی دنیا کے نفاذ میں ہمارے پاس قابل اعتماد تصدیق کنندگان کا ایک سیٹ ہوگا اور ہم صرف ان کے تصدیق ناموں کو دیکھیں گے۔ + +اسے عملی طور پر دیکھنے کے لیے، موجودہ IdP اور SP کو روکیں اور یہ کمانڈز چلائیں: + +```sh +git checkout email-address +pnpm install +pnpm start +``` + +پھر اپنا ای میل پتہ فراہم کریں۔ ایسا کرنے کے آپ کے پاس دو طریقے ہیں: + +- ایک نجی کلید کا استعمال کرتے ہوئے ایک والیٹ درآمد کریں، اور ٹیسٹنگ نجی کلید `0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80` کا استعمال کریں۔ + +- اپنے ای میل پتے کے لیے ایک تصدیق نامہ شامل کریں: + + 1. تصدیق ایکسپلورر میں [اسکیما پر](https://optimism.easscan.org/schema/view/0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977) براؤز کریں۔ + + 2. **اسکیما کے ساتھ تصدیق کریں** پر کلک کریں۔ + + 3. وصول کنندہ کے طور پر اپنا ایتھیریم پتہ، ای میل پتے کے طور پر اپنا ای میل پتہ درج کریں، اور **آن چین** منتخب کریں۔ پھر **تصدیق نامہ بنائیں** پر کلک کریں۔ + + 4. اپنے والیٹ میں ٹرانزیکشن کی منظوری دیں۔ گیس کی ادائیگی کے لیے آپ کو [آپٹیمزم بلاک چین](https://app.optimism.io/bridge/deposit) پر کچھ ETH کی ضرورت ہوگی۔ + +کسی بھی طرح، اس کے بعد [http://localhost:3000](http://localhost:3000) پر براؤز کریں اور ہدایات پر عمل کریں۔ اگر آپ نے ٹیسٹنگ نجی کلید درآمد کی ہے، تو آپ کو موصول ہونے والا ای میل `test_addr_0@example.com` ہے۔ اگر آپ نے اپنا پتہ استعمال کیا ہے، تو یہ وہی ہونا چاہیے جس کی آپ نے تصدیق کی ہے۔ + +### تفصیلی وضاحت + +![ایتھیریم پتے سے ای میل تک پہنچنا](./fig-06-saml-sig-n-email.png) + +نئے اقدامات GraphQL مواصلت، اقدامات 5.6 اور 5.7 ہیں۔ + +دوبارہ، یہاں `idp.mts` کے تبدیل شدہ حصے ہیں۔ + +```typescript +import { GraphQLClient } from 'graphql-request' +import { SchemaEncoder } from '@ethereum-attestation-service/eas-sdk' +``` + +ہمیں جن لائبریریوں کی ضرورت ہے انہیں درآمد کریں۔ + +```typescript +const graphqlEndpointUrl = "https://optimism.easscan.org/graphql" +``` + +ہر بلاک چین کے لیے [ایک الگ اینڈ پوائنٹ](https://docs.attest.org/docs/developer-tools/api) ہے۔ + +```typescript +const graphqlClient = new GraphQLClient(graphqlEndpointUrl, { fetch }) +``` + +ایک نیا `GraphQLClient` کلائنٹ بنائیں جسے ہم اینڈ پوائنٹ سے استفسار کرنے کے لیے استعمال کر سکتے ہیں۔ + +```typescript +const graphqlSchema = 'string emailAddress' +const graphqlEncoder = new SchemaEncoder(graphqlSchema) +``` + +GraphQL ہمیں صرف بائٹس کے ساتھ ایک مبہم ڈیٹا آبجیکٹ دیتا ہے۔ اسے سمجھنے کے لیے ہمیں اسکیما کی ضرورت ہے۔ + +```typescript +const ethereumAddressToEmail = async ethAddr => { +``` + +ایتھیریم پتے سے ای میل پتے تک پہنچنے کا ایک فنکشن۔ + +```typescript + const query = ` + query GetAttestationsByRecipient { +``` + +یہ ایک GraphQL استفسار ہے۔ + +```typescript + attestations( +``` + +ہم تصدیق نامے تلاش کر رہے ہیں۔ + +```typescript + where: { + recipient: { equals: "${getAddress(ethAddr)}" } + schemaId: { equals: "0xfa2eff59a916e3cc3246f9aec5e0ca00874ae9d09e4678e5016006f07622f977" } + } +``` + +ہم جو تصدیق نامے چاہتے ہیں وہ ہمارے اسکیما میں ہیں، جہاں وصول کنندہ `getAddress(ethAddr)` ہے۔ [`getAddress`](https://viem.sh/docs/utilities/getAddress#getaddress) فنکشن اس بات کو یقینی بناتا ہے کہ ہمارے پتے کا [چیک سم](https://github.com/ethereum/ercs/blob/master/ERCS/erc-55.md) درست ہے۔ یہ ضروری ہے کیونکہ GraphQL کیس-اہم ہے۔ "0xBAD060A7"، "0xBad060A7"، اور "0xbad060a7" مختلف قدریں ہیں۔ + +```typescript + take: 1 +``` + +ہمیں کتنے ہی تصدیق نامے ملیں، ہم صرف پہلا چاہتے ہیں۔ + +```typescript + ) { + data + id + attester + } + }` +``` + +ہم جو فیلڈز وصول کرنا چاہتے ہیں۔ + +- `attester`: وہ پتہ جس نے تصدیق نامہ جمع کرایا۔ عام طور پر اس کا استعمال یہ فیصلہ کرنے کے لیے کیا جاتا ہے کہ آیا تصدیق نامے پر بھروسہ کرنا ہے یا نہیں۔ +- `id`: تصدیق نامہ آئی ڈی۔ آپ اس قدر کا استعمال [آن چین پر تصدیق نامہ پڑھنے](https://optimism.blockscout.com/address/0x4200000000000000000000000000000000000021?tab=read_proxy&source_address=0x4E0275Ea5a89e7a3c1B58411379D1a0eDdc5b088#0xa3112a64) کے لیے کر سکتے ہیں تاکہ یہ تصدیق کی جا سکے کہ GraphQL استفسار سے ملنے والی معلومات درست ہے۔ +- `data`: اسکیما ڈیٹا (اس معاملے میں، ای میل پتہ)۔ + +```typescript + const queryResult = await graphqlClient.request(query) + + if (queryResult.attestations.length == 0) + return "no_address@available.is" +``` + +اگر کوئی تصدیق نامہ نہیں ہے، تو ایک ایسی قدر واپس کریں جو واضح طور پر غلط ہو، لیکن جو سروس فراہم کنندہ کو درست معلوم ہو۔ + +```typescript + const attestationDataFields = graphqlEncoder.decodeData(queryResult.attestations[0].data) + return attestationDataFields[0].value.value +} +``` + +اگر کوئی قدر ہے، تو ڈیٹا کو ڈی کوڈ کرنے کے لیے `decodeData` کا استعمال کریں۔ ہمیں اس کے فراہم کردہ میٹا ڈیٹا کی ضرورت نہیں، صرف قدر خود۔ + +```typescript + const loginResponse = await idp.createLoginResponse( + sp, + { + . + . + . + }, + "post", + { + email: await ethereumAddressToEmail(req.params.account) + } + ); +``` + +ای میل پتہ حاصل کرنے کے لیے نئے فنکشن کا استعمال کریں۔ + +## غیر مرکزیت کے بارے میں کیا خیال ہے؟ + +اس ترتیب میں صارفین وہ شخص ہونے کا بہانہ نہیں کر سکتے جو وہ نہیں ہیں، جب تک کہ ہم ایتھیریم سے ای میل پتے کی میپنگ کے لیے قابل اعتماد تصدیق کنندگان پر انحصار کرتے ہیں۔ تاہم، ہمارا شناختی فراہم کنندہ اب بھی ایک مرکزی جزو ہے۔ جس کے پاس بھی شناختی فراہم کنندہ کی نجی کلید ہے وہ سروس فراہم کنندہ کو غلط معلومات بھیج سکتا ہے۔ + +[ملٹی پارٹی کمپیوٹیشن (MPC)](https://en.wikipedia.org/wiki/Secure_multi-party_computation) کا استعمال کرتے ہوئے ایک حل ہو سکتا ہے۔ مجھے امید ہے کہ مستقبل کے ٹیوٹوریل میں اس کے بارے میں لکھوں گا۔ + +## نتیجہ + +لاگ آن معیار، جیسے ایتھیریم دستخط، کو اپنانے میں مرغی اور انڈے کا مسئلہ درپیش ہے۔ سروس فراہم کنندگان وسیع تر ممکنہ مارکیٹ کو اپیل کرنا چاہتے ہیں۔ صارفین اپنے لاگ آن معیار کی حمایت کے بارے میں فکر کیے بغیر خدمات تک رسائی حاصل کرنا چاہتے ہیں۔ +اڈاپٹر بنانا، جیسے کہ ایتھیریم IdP، ہمیں اس رکاوٹ کو دور کرنے میں مدد کر سکتا ہے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/ur/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md new file mode 100644 index 00000000000..a15aafd580f --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md @@ -0,0 +1,156 @@ +--- +title: "ایتھیریم ڈیولپمنٹ کے ساتھ شروعات کرنا" +description: "یہ ایتھیریم ڈیولپمنٹ کے ساتھ شروعات کرنے کے لیے ایک ابتدائی گائیڈ ہے۔ ہم آپ کو ایک API اینڈ پوائنٹ شروع کرنے، کمانڈ لائن کی درخواست کرنے سے لے کر آپ کی پہلی ویب 3 اسکرپٹ لکھنے تک لے جائیں گے! بلاک چین ڈیولپمنٹ کے کسی تجربے کی ضرورت نہیں ہے!" +author: "Elan Halpern" +tags: + [ + "javascript", + "ethers.js", + "نوڈز", + "querying", + "alchemy" + ] +skill: beginner +lang: ur-in +published: 2020-10-30 +source: Medium +sourceUrl: https://medium.com/alchemy-api/getting-started-with-ethereum-development-using-alchemy-c3d6a45c567f +--- + +![ایتھیریم اور Alchemy لوگو](./ethereum-alchemy.png) + +یہ ایتھیریم ڈیولپمنٹ کے ساتھ شروعات کرنے کے لیے ایک ابتدائی گائیڈ ہے۔ اس ٹیوٹوریل کے لیے ہم [Alchemy](https://alchemyapi.io/) کا استعمال کریں گے، جو کہ معروف بلاک چین ڈیولپر پلیٹ فارم ہے جو Maker، 0x، MyEtherWallet، Dharma، اور Kyber سمیت 70% سرفہرست بلاک چین ایپس کے لاکھوں صارفین کو تقویت فراہم کرتا ہے۔ Alchemy ہمیں ایتھیریم چین پر ایک API اینڈ پوائنٹ تک رسائی فراہم کرے گا تاکہ ہم ٹرانزیکشنز کو پڑھ اور لکھ سکیں۔ + +ہم آپ کو Alchemy کے ساتھ سائن اپ کرنے سے لے کر آپ کی پہلی ویب 3 اسکرپٹ لکھنے تک لے جائیں گے! بلاک چین ڈیولپمنٹ کے کسی تجربے کی ضرورت نہیں ہے! + +## 1۔ ایک مفت Alchemy اکاؤنٹ کے لیے سائن اپ کریں {#sign-up-for-a-free-alchemy-account} + +Alchemy کے ساتھ ایک اکاؤنٹ بنانا آسان ہے، [یہاں مفت میں سائن اپ کریں](https://auth.alchemy.com/)۔ + +## 2۔ ایک Alchemy ایپ بنائیں {#create-an-alchemy-app} + +ایتھیریم چین کے ساتھ کمیونیکیٹ کرنے اور Alchemy کی پروڈکٹس کا استعمال کرنے کے لیے، آپ کو اپنی درخواستوں کی توثیق کرنے کے لیے ایک API کی کی ضرورت ہے۔ + +آپ [ڈیش بورڈ سے API کیز بنا سکتے ہیں](https://dashboard.alchemy.com/)۔ ایک نئی کی بنانے کے لیے، نیچے دکھائے گئے "ایپ بنائیں" (Create App) پر نیویگیٹ کریں: + +_ہمیں اپنا ڈیش بورڈ دکھانے کی اجازت دینے کے لیے [_ShapeShift_](https://shapeshift.com/) کا خصوصی شکریہ!_ + +![Alchemy ڈیش بورڈ](./alchemy-dashboard.png) + +اپنی نئی کی حاصل کرنے کے لیے "ایپ بنائیں" (Create App) کے تحت تفصیلات پُر کریں۔ آپ یہاں اپنی پہلے بنائی ہوئی ایپس اور اپنی ٹیم کی بنائی ہوئی ایپس کو بھی دیکھ سکتے ہیں۔ کسی بھی ایپ کے لیے "کی دیکھیں" (View Key) پر کلک کرکے موجودہ کیز حاصل کریں۔ + +![Alchemy کے ساتھ ایپ بنانے کا اسکرین شاٹ](./create-app.png) + +آپ "ایپس" (Apps) پر ہوور کرکے اور کسی ایک کو منتخب کرکے بھی موجودہ API کیز حاصل کر سکتے ہیں۔ آپ یہاں "کی دیکھیں" (View Key) کے ساتھ ساتھ مخصوص ڈومینز کو وائٹ لسٹ کرنے، کئی ڈیولپر ٹولز دیکھنے اور اینالیٹکس دیکھنے کے لیے "ایپ میں ترمیم کریں" (Edit App) بھی کر سکتے ہیں۔ + +![ایک صارف کو API کیز حاصل کرنے کا طریقہ دکھانے والا Gif](./pull-api-keys.gif) + +## 3۔ کمانڈ لائن سے ایک درخواست کریں {#make-a-request-from-the-command-line} + +JSON-RPC اور curl کا استعمال کرتے ہوئے Alchemy کے ذریعے ایتھیریم بلاک چین کے ساتھ انٹریکٹ کریں۔ + +مینوئل درخواستوں کے لیے، ہم `POST` درخواستوں کے ذریعے `JSON-RPC` کے ساتھ انٹریکٹ کرنے کی تجویز دیتے ہیں۔ بس `Content-Type: application/json` ہیڈر پاس کریں اور اپنی کوئری کو `POST` باڈی کے طور پر درج ذیل فیلڈز کے ساتھ پاس کریں: + +- `jsonrpc`: JSON-RPC ورژن — فی الحال، صرف `2.0` سپورٹڈ ہے۔ +- `method`: ETH API کا طریقہ۔ [API کا حوالہ دیکھیں۔](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc) +- `params`: طریقہ کار کو پاس کیے جانے والے پیرامیٹرز کی ایک فہرست۔ +- `id`: آپ کی درخواست کا ID۔ جواب کے ذریعے واپس کیا جائے گا تاکہ آپ ٹریک رکھ سکیں کہ کونسا جواب کس درخواست سے تعلق رکھتا ہے۔ + +یہاں ایک مثال ہے جسے آپ موجودہ گیس کی قیمت حاصل کرنے کے لیے کمانڈ لائن سے چلا سکتے ہیں: + +```bash +curl https://eth-mainnet.alchemyapi.io/v2/demo \ +-X POST \ +-H "Content-Type: application/json" \ +-d '{"jsonrpc":"2.0","method":"eth_gasPrice","params":[],"id":73}' +``` + +_**نوٹ:** [https://eth-mainnet.alchemyapi.io/v2/demo](https://eth-mainnet.alchemyapi.io/jsonrpc/demo) کو اپنی API کی `https://eth-mainnet.alchemyapi.io/v2/**your-api-key` سے بدلیں۔_ + +**نتائج:** + +```json +{ "id": 73,"jsonrpc": "2.0","result": "0x09184e72a000" // 10000000000000 } +``` + +## 4. اپنا ویب 3 کلائنٹ سیٹ اپ کریں {#set-up-your-web3-client} + +**اگر آپ کے پاس پہلے سے کلائنٹ ہے،** تو اپنے موجودہ نوڈ پرووائیڈر URL کو اپنی API کی کے ساتھ Alchemy URL میں تبدیل کریں: `“https://eth-mainnet.alchemyapi.io/v2/your-api-key"` + +**_نوٹ:_** نیچے دی گئی اسکرپٹس کو **نوڈ کانٹیکسٹ** میں چلانے یا **فائل میں محفوظ کرنے** کی ضرورت ہے، کمانڈ لائن سے نہیں۔ اگر آپ کے پاس پہلے سے نوڈ یا npm انسٹال نہیں ہے، تو میکس کے لیے یہ فوری [سیٹ اپ گائیڈ](https://app.gitbook.com/@alchemyapi/s/alchemy/guides/alchemy-for-macs) دیکھیں۔ + +بہت ساری [ویب 3 لائبریریاں](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) ہیں جنہیں آپ Alchemy کے ساتھ انٹیگریٹ کر سکتے ہیں، تاہم، ہم [Alchemy Web3](https://docs.alchemy.com/reference/api-overview) استعمال کرنے کی تجویز دیتے ہیں، جو web3.js کا ایک ڈراپ ان متبادل ہے، جسے Alchemy کے ساتھ بغیر کسی رکاوٹ کے کام کرنے کے لیے بنایا اور کنفیگر کیا گیا ہے۔ یہ متعدد فوائد فراہم کرتا ہے جیسے خودکار دوبارہ کوششیں اور مضبوط WebSocket سپورٹ۔ + +AlchemyWeb3.js کو انسٹال کرنے کے لیے، **اپنی پروجیکٹ ڈائرکٹری پر نیویگیٹ کریں** اور چلائیں: + +**Yarn کے ساتھ:** + +``` +yarn add @alch/alchemy-web3 +``` + +**NPM کے ساتھ:** + +``` +npm install @alch/alchemy-web3 +``` + +Alchemy کے نوڈ انفراسٹرکچر کے ساتھ انٹریکٹ کرنے کے لیے، NodeJS میں چلائیں یا اسے جاوا اسکرپٹ فائل میں شامل کریں: + +```js +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3( + "https://eth-mainnet.alchemyapi.io/v2/your-api-key" +) +``` + +## 5. اپنی پہلی ویب 3 اسکرپٹ لکھیں! {#write-your-first-web3-script} + +اب تھوڑی ویب 3 پروگرامنگ میں عملی طور پر کام کرنے کے لیے، ہم ایک سادہ اسکرپٹ لکھیں گے جو ایتھیریم مین نیٹ سے تازہ ترین بلاک نمبر پرنٹ کرتی ہے۔ + +**1.** **اگر آپ نے پہلے سے ایسا نہیں کیا ہے، تو اپنے ٹرمینل میں ایک نئی پروجیکٹ ڈائرکٹری بنائیں اور اس میں cd کریں:** + +``` +mkdir web3-example +cd web3-example +``` + +**2.** **اگر آپ نے پہلے سے نہیں کیا ہے تو Alchemy web3 (یا کوئی بھی web3) ڈیپینڈینسی کو اپنے پروجیکٹ میں انسٹال کریں:** + +``` +npm install @alch/alchemy-web3 +``` + +**3.** **`index.js` نامی ایک فائل بنائیں اور اس میں درج ذیل مواد شامل کریں:** + +> آپ کو بالآخر `demo` کو اپنی Alchemy HTTP API کی سے بدلنا چاہیے۔ + +```js +async function main() { + const { createAlchemyWeb3 } = require("@alch/alchemy-web3") + const web3 = createAlchemyWeb3("https://eth-mainnet.alchemyapi.io/v2/demo") + const blockNumber = await web3.eth.getBlockNumber() + console.log("تازہ ترین بلاک نمبر ہے " + blockNumber) +} +main() +``` + +async چیزوں سے ناواقف ہیں؟ یہ [میڈیم پوسٹ](https://medium.com/better-programming/understanding-async-await-in-javascript-1d81bb079b2c) دیکھیں۔ + +\*\*4۔ **اسے اپنے ٹرمینل میں نوڈ کا استعمال کرتے ہوئے چلائیں** + +``` +node index.js +``` + +\*\*5۔ **اب آپ کو اپنے کنسول میں تازہ ترین بلاک نمبر کا آؤٹ پٹ نظر آنا چاہیے!** + +``` +تازہ ترین بلاک نمبر 11043912 ہے +``` + +**واہ!** مبارک ہو! **آپ نے ابھی ابھی Alchemy کا استعمال کرتے ہوئے اپنی پہلی ویب 3 اسکرپٹ لکھی ہے 🎉** + +یقین نہیں ہے کہ آگے کیا کرنا ہے؟ ہمارے [ہیلو ورلڈ اسمارٹ کنٹریکٹ گائیڈ](https://www.alchemy.com/docs/hello-world-smart-contract) میں اپنا پہلا اسمارٹ کنٹریکٹ ڈیپلائے کرنے کی کوشش کریں اور کچھ سولیڈیٹی پروگرامنگ میں عملی کام کریں، یا [ڈیش بورڈ ڈیمو ایپ](https://docs.alchemyapi.io/tutorials/demo-app) کے ساتھ اپنے ڈیش بورڈ کے علم کی جانچ کریں! + +_[Alchemy کے ساتھ مفت میں سائن اپ کریں](https://auth.alchemy.com/)، ہماری [دستاویزات](https://www.alchemy.com/docs/) دیکھیں، اور تازہ ترین خبروں کے لیے، ہمیں [Twitter](https://twitter.com/AlchemyPlatform) پر فالو کریں_۔ diff --git a/public/content/translations/ur/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/ur/developers/tutorials/guide-to-smart-contract-security-tools/index.md new file mode 100644 index 00000000000..26d546f1b72 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/guide-to-smart-contract-security-tools/index.md @@ -0,0 +1,102 @@ +--- +title: "اسمارٹ کنٹریکٹ سیکیورٹی ٹولز کے لئے ایک گائیڈ" +description: "تین مختلف ٹیسٹنگ اور پروگرام کے تجزیہ کی تکنیکوں کا ایک جائزہ" +author: "Trailofbits" +lang: ur-in +tags: [ "solidity", "اسمارٹ معاہدات", "سیکورٹی" ] +skill: intermediate +published: 2020-09-07 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis +--- + +ہم تین مخصوص ٹیسٹنگ اور پروگرام کے تجزیہ کی تکنیکوں کا استعمال کرنے جا رہے ہیں: + +- **[Slither](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) کے ساتھ اسٹیٹک تجزیہ۔** پروگرام کے تمام راستوں کا تخمینہ لگایا جاتا ہے اور ایک ہی وقت میں تجزیہ کیا جاتا ہے، مختلف پروگرام پریزنٹیشنز (مثال کے طور پر، کنٹرول-فلو-گراف) کے ذریعے۔ +- **[Echidna](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) کے ساتھ فزنگ۔** کوڈ کو ٹرانزیکشنز کی سیوڈو-رینڈم جنریشن کے ساتھ عمل میں لایا جاتا ہے۔ فزر دی گئی پراپرٹی کی خلاف ورزی کرنے کے لیے ٹرانزیکشنز کا ایک سلسلہ تلاش کرنے کی کوشش کرے گا۔ +- **[Manticore](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) کے ساتھ سمبولک ایکزیکیوشن۔** ایک رسمی تصدیقی تکنیک، جو ہر ایکزیکیوشن پاتھ کو ایک ریاضیاتی فارمولے میں ترجمہ کرتی ہے، جس کے اوپر رکاوٹوں کی جانچ کی جا سکتی ہے۔ + +ہر تکنیک کے فوائد اور نقصانات ہیں، اور یہ [مخصوص معاملات](#determining-security-properties) میں مفید ہوگی: + +| تکنیک | ٹول | استعمال | رفتار | چھوٹے ہوئے بگز | غلط الارم | +| ----------------- | --------- | ----------------------------- | ----- | -------------- | --------- | +| اسٹیٹک تجزیہ | Slither | CLI اور اسکرپٹس | سیکنڈ | معتدل | کم | +| فزنگ | Echidna | Solidity پراپرٹیز | منٹ | کم | کوئی نہیں | +| سمبولک ایکزیکیوشن | Manticore | Solidity پراپرٹیز اور اسکرپٹس | گھنٹے | کوئی نہیں\* | کوئی نہیں | + +\* اگر تمام راستوں کو ٹائم آؤٹ کے بغیر دریافت کیا جاتا ہے + +**Slither** سیکنڈوں میں کنٹریکٹس کا تجزیہ کرتا ہے، تاہم، اسٹیٹک تجزیہ غلط الارم کا باعث بن سکتا ہے اور پیچیدہ جانچ (مثال کے طور پر، حسابی جانچ) کے لیے کم موزوں ہوگا۔ بلٹ ان ڈیٹیکٹرز تک پش بٹن رسائی کے لیے API کے ذریعے Slither چلائیں یا صارف کی طرف سے متعین کردہ جانچ کے لیے API کے ذریعے۔ + +**Echidna** کو کئی منٹ تک چلنے کی ضرورت ہے اور یہ صرف سچے مثبت نتائج پیدا کرے گا۔ Echidna صارف کی فراہم کردہ سیکیورٹی پراپرٹیز کی جانچ کرتا ہے، جو Solidity میں لکھی گئی ہیں۔ یہ بگز کو چھوڑ سکتا ہے کیونکہ یہ رینڈم ایکسپلوریشن پر مبنی ہے۔ + +**Manticore** "سب سے بھاری وزن" کا تجزیہ کرتا ہے۔ Echidna کی طرح، Manticore صارف کی فراہم کردہ پراپرٹیز کی تصدیق کرتا ہے۔ اسے چلنے کے لیے زیادہ وقت درکار ہوگا، لیکن یہ کسی پراپرٹی کی درستگی کو ثابت کر سکتا ہے اور غلط الارم کی اطلاع نہیں دے گا۔ + +## تجویز کردہ ورک فلو {#suggested-workflow} + +Slither کے بلٹ ان ڈیٹیکٹرز کے ساتھ شروع کریں تاکہ یہ یقینی بنایا جا سکے کہ کوئی سادہ بگز ابھی موجود نہیں ہیں یا بعد میں متعارف نہیں ہوں گے۔ وراثت، متغیر انحصار، اور ساختی مسائل سے متعلق پراپرٹیز کی جانچ کے لیے Slither کا استعمال کریں۔ جیسے جیسے کوڈبیس بڑھتا ہے، اسٹیٹ مشین کی مزید پیچیدہ پراپرٹیز کی جانچ کے لیے Echidna کا استعمال کریں۔ Solidity سے غیر دستیاب تحفظات کے لیے کسٹم چیکس تیار کرنے کے لیے Slither پر دوبارہ جائیں، جیسے کسی فنکشن کو اوور رائڈ ہونے سے بچانا۔ آخر میں، اہم سیکیورٹی پراپرٹیز کی ٹارگٹڈ تصدیق کے لیے Manticore کا استعمال کریں، جیسے، حسابی آپریشنز۔ + +- عام مسائل کو پکڑنے کے لیے Slither کے CLI کا استعمال کریں +- اپنے کنٹریکٹ کی اعلیٰ سطحی سیکیورٹی پراپرٹیز کی جانچ کے لیے Echidna کا استعمال کریں +- کسٹم اسٹیٹک چیکس لکھنے کے لیے Slither کا استعمال کریں +- جب آپ اہم سیکیورٹی پراپرٹیز کی گہری یقین دہانی چاہتے ہیں تو Manticore کا استعمال کریں + +**یونٹ ٹیسٹ پر ایک نوٹ**۔ اعلیٰ معیار کا سافٹ ویئر بنانے کے لیے یونٹ ٹیسٹ ضروری ہیں۔ تاہم، یہ تکنیکیں سیکیورٹی کی خامیوں کو تلاش کرنے کے لیے سب سے زیادہ موزوں نہیں ہیں۔ وہ عام طور پر کوڈ کے مثبت رویوں کی جانچ کے لیے استعمال ہوتے ہیں (یعنی، کوڈ عام سیاق و سباق میں توقع کے مطابق کام کرتا ہے)، جبکہ سیکیورٹی کی خامیاں ان ایج کیسز میں رہتی ہیں جن پر ڈیولپرز نے غور نہیں کیا تھا۔ درجنوں اسمارٹ کنٹریکٹ سیکیورٹی جائزوں کے ہمارے مطالعے میں، [یونٹ ٹیسٹ کوریج کا سیکیورٹی کی خامیوں کی تعداد یا شدت پر کوئی اثر نہیں تھا](https://blog.trailofbits.com/2019/08/08/246-findings-from-our-smart-contract-audits-an-executive-summary/) جو ہمیں اپنے کلائنٹ کے کوڈ میں ملیں۔ + +## سیکیورٹی پراپرٹیز کا تعین کرنا {#determining-security-properties} + +اپنے کوڈ کو مؤثر طریقے سے ٹیسٹ اور تصدیق کرنے کے لیے، آپ کو ان علاقوں کی نشاندہی کرنی ہوگی جن پر توجہ کی ضرورت ہے۔ چونکہ سیکیورٹی پر خرچ ہونے والے آپ کے وسائل محدود ہیں، اس لیے اپنی کوشش کو بہتر بنانے کے لیے اپنے کوڈبیس کے کمزور یا اعلیٰ قیمت والے حصوں کی گنجائش کا تعین کرنا ضروری ہے۔ تھریٹ ماڈلنگ مدد کر سکتی ہے۔ جائزہ لینے پر غور کریں: + +- [ریپڈ رسک اسیسمنٹس](https://infosec.mozilla.org/guidelines/risk/rapid_risk_assessment.html) (ہمارا ترجیحی طریقہ جب وقت کم ہو) +- [ڈیٹا سینٹرک سسٹم تھریٹ ماڈلنگ کے لیے گائیڈ](https://csrc.nist.gov/pubs/sp/800/154/ipd) (عرف NIST 800-154) +- [Shostack تھریٹ ماڈلنگ](https://www.amazon.com/Threat-Modeling-Designing-Adam-Shostack/dp/1118809998) +- [STRIDE](https://wikipedia.org/wiki/STRIDE_\(security\)) / [DREAD](https://wikipedia.org/wiki/DREAD_\(risk_assessment_model\)) +- [PASTA](https://wikipedia.org/wiki/Threat_model#P.A.S.T.A.) +- [Assertions کا استعمال](https://blog.regehr.org/archives/1091) + +### اجزاء {#components} + +یہ جاننا کہ آپ کیا جانچنا چاہتے ہیں، آپ کو صحیح ٹول منتخب کرنے میں بھی مدد ملے گی۔ + +وہ وسیع علاقے جو اسمارٹ کنٹریکٹس کے لیے اکثر متعلقہ ہوتے ہیں ان میں شامل ہیں: + +- **اسٹیٹ مشین۔** زیادہ تر کنٹریکٹس کو اسٹیٹ مشین کے طور پر پیش کیا جا سکتا ہے۔ یہ جانچنے پر غور کریں کہ (1) کوئی غلط اسٹیٹ تک نہیں پہنچا جا سکتا، (2) اگر کوئی اسٹیٹ درست ہے تو اس تک پہنچا جا سکتا ہے، اور (3) کوئی اسٹیٹ کنٹریکٹ کو ٹریپ نہیں کرتی ہے۔ + + - Echidna اور Manticore اسٹیٹ مشین کی تفصیلات کی جانچ کے لیے ترجیحی ٹولز ہیں۔ + +- **رسائی کنٹرولز۔** اگر آپ کے سسٹم میں مراعات یافتہ صارفین ہیں (مثال کے طور پر، ایک مالک، کنٹرولرز، ...) آپ کو یہ یقینی بنانا ہوگا کہ (1) ہر صارف صرف مجاز کارروائیاں انجام دے سکتا ہے اور (2) کوئی صارف زیادہ مراعات یافتہ صارف کی کارروائیوں کو بلاک نہیں کر سکتا۔ + + - Slither، Echidna اور Manticore درست رسائی کنٹرولز کی جانچ کر سکتے ہیں۔ مثال کے طور پر، Slither یہ جانچ سکتا ہے کہ صرف وائٹ لسٹ کیے گئے فنکشنز میں onlyOwner موڈیفائر کی کمی ہے۔ Echidna اور Manticore زیادہ پیچیدہ رسائی کنٹرول کے لیے مفید ہیں، جیسے کہ اجازت صرف اس صورت میں دی جاتی ہے جب کنٹریکٹ کسی دی گئی اسٹیٹ تک پہنچ جائے۔ + +- **حسابی آپریشنز۔** حسابی آپریشنز کی درستگی کی جانچ کرنا بہت اہم ہے۔ ہر جگہ `SafeMath` کا استعمال اوور فلو/انڈر فلو کو روکنے کے لیے ایک اچھا قدم ہے، تاہم، آپ کو اب بھی دیگر حسابی خامیوں پر غور کرنا چاہیے، بشمول راؤنڈنگ کے مسائل اور وہ خامیاں جو کنٹریکٹ کو ٹریپ کرتی ہیں۔ + + - Manticore یہاں بہترین انتخاب ہے۔ Echidna کا استعمال کیا جا سکتا ہے اگر حساب کتاب SMT سالور کے دائرہ کار سے باہر ہو۔ + +- **وراثت کی درستگی۔** Solidity کنٹریکٹس کثیر وراثت پر بہت زیادہ انحصار کرتے ہیں۔ غلطیاں جیسے کہ `super` کال سے محروم شیڈونگ فنکشن اور غلط تشریح شدہ c3 لینیئرائزیشن آرڈر آسانی سے متعارف ہو سکتے ہیں۔ + + - Slither ان مسائل کا پتہ لگانے کو یقینی بنانے کا ٹول ہے۔ + +- **بیرونی تعاملات۔** کنٹریکٹس ایک دوسرے کے ساتھ تعامل کرتے ہیں، اور کچھ بیرونی کنٹریکٹس پر بھروسہ نہیں کرنا چاہیے۔ مثال کے طور پر، اگر آپ کا کنٹریکٹ بیرونی اوریکلز پر انحصار کرتا ہے، تو کیا یہ محفوظ رہے گا اگر آدھے دستیاب اوریکلز سے سمجھوتہ ہو جائے؟ + + - Manticore اور Echidna آپ کے کنٹریکٹس کے ساتھ بیرونی تعاملات کی جانچ کے لیے بہترین انتخاب ہیں۔ Manticore میں بیرونی کنٹریکٹس کو اسٹب کرنے کے لیے ایک بلٹ ان میکانزم ہے۔ + +- **معیاری مطابقت۔** Ethereum معیارات (مثال کے طور پر، ERC20) کے ڈیزائن میں خامیوں کی ایک تاریخ ہے۔ اس معیار کی حدود سے آگاہ رہیں جس پر آپ تعمیر کر رہے ہیں۔ + - Slither، Echidna، اور Manticore آپ کو کسی دیے گئے معیار سے انحراف کا پتہ لگانے میں مدد کریں گے۔ + +### ٹول سلیکشن چیٹ شیٹ {#tool-selection-cheatsheet} + +| جز | ٹولز | مثالیں | +| --------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| اسٹیٹ مشین | Echidna, Manticore | | +| رسائی کنٹرول | Slither, Echidna, Manticore | [Slither exercise 2](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise2.md)، [Echidna exercise 2](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-2.md) | +| حسابی آپریشنز | Manticore, Echidna | [Echidna exercise 1](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/exercises/Exercise-1.md)، [Manticore exercises 1 - 3](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore/exercises) | +| وراثت کی درستگی | Slither | [Slither exercise 1](https://github.com/crytic/slither/blob/7f54c8b948c34fb35e1d61adaa1bd568ca733253/docs/src/tutorials/exercise1.md) | +| بیرونی تعاملات | Manticore, Echidna | | +| معیاری مطابقت | Slither, Echidna, Manticore | [`slither-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) | + +آپ کے اہداف کے لحاظ سے دیگر علاقوں کی جانچ کرنے کی ضرورت ہوگی، لیکن توجہ کے یہ موٹے دانے والے علاقے کسی بھی اسمارٹ کنٹریکٹ سسٹم کے لیے ایک اچھی شروعات ہیں۔ + +ہمارے عوامی آڈٹس میں تصدیق شدہ یا آزمائی گئی پراپرٹیز کی مثالیں شامل ہیں۔ حقیقی دنیا کی سیکیورٹی پراپرٹیز کا جائزہ لینے کے لیے درج ذیل رپورٹس کے `Automated Testing and Verification` سیکشنز کو پڑھنے پر غور کریں: + +- [0x](https://github.com/trailofbits/publications/blob/master/reviews/0x-protocol.pdf) +- [Balancer](https://github.com/trailofbits/publications/blob/master/reviews/BalancerCore.pdf) diff --git a/public/content/translations/ur/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/ur/developers/tutorials/hello-world-smart-contract-fullstack/index.md new file mode 100644 index 00000000000..e971035a361 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/hello-world-smart-contract-fullstack/index.md @@ -0,0 +1,1540 @@ +--- +title: "ہیلو ورلڈ اسمارٹ کنٹریکٹ برائے مبتدی - فل اسٹیک" +description: "Ethereum پر ایک سادہ اسمارٹ کنٹریکٹ لکھنے اور اسے ڈیپلائے کرنے کے بارے میں تعارفی ٹیوٹوریل۔" +author: "nstrike2" +tags: + [ + "solidity", + "hardhat", + "alchemy", + "اسمارٹ معاہدات", + "تعینات کرنا", + "بلاک ایکسپلورر", + "فرنٹ اینڈ", + "لین دین" + ] +skill: beginner +lang: ur-in +published: 2021-10-25 +--- + +اگر آپ بلاک چین ڈیولپمنٹ میں نئے ہیں اور یہ نہیں جانتے کہ کہاں سے شروع کرنا ہے یا اسمارٹ کنٹریکٹس کو کیسے ڈیپلائے اور ان کے ساتھ تعامل کرنا ہے تو یہ گائیڈ آپ کے لیے ہے۔ ہم [MetaMask](https://metamask.io)، [Solidity](https://docs.soliditylang.org/en/v0.8.0/)، [Hardhat](https://hardhat.org)، اور [Alchemy](https://alchemy.com/eth) کا استعمال کرتے ہوئے Goerli ٹیسٹ نیٹ ورک پر ایک سادہ، اسمارٹ کنٹریکٹ بنانے اور اسے ڈیپلائے کرنے کے عمل سے گزریں گے۔ + +اس ٹیوٹوریل کو مکمل کرنے کے لیے آپ کو ایک Alchemy اکاؤنٹ کی ضرورت ہوگی۔ [ایک مفت اکاؤنٹ کے لیے سائن اپ کریں](https://www.alchemy.com/). + +اگر آپ کو کسی بھی وقت کوئی سوال ہو تو، بلا جھجھک [Alchemy Discord](https://discord.gg/gWuC7zB) میں رابطہ کریں! + +## حصہ 1 - Hardhat کا استعمال کرتے ہوئے اپنا اسمارٹ کنٹریکٹ بنائیں اور ڈیپلائے کریں {#part-1} + +### Ethereum نیٹ ورک سے جڑیں {#connect-to-the-ethereum-network} + +Ethereum چین سے درخواستیں کرنے کے بہت سے طریقے ہیں۔ سادگی کے لیے، ہم Alchemy پر ایک مفت اکاؤنٹ استعمال کریں گے، جو ایک بلاک چین ڈیولپر پلیٹ فارم اور API ہے جو ہمیں خود ایک نوڈ چلائے بغیر Ethereum چین کے ساتھ بات چیت کرنے کی اجازت دیتا ہے۔ Alchemy میں نگرانی اور تجزیات کے لیے ڈیولپر ٹولز بھی ہیں؛ ہم اس ٹیوٹوریل میں ان سے فائدہ اٹھائیں گے تاکہ یہ سمجھ سکیں کہ ہمارے اسمارٹ کنٹریکٹ کی ڈیپلائیمنٹ میں پس پردہ کیا ہو رہا ہے۔ + +### اپنی ایپ اور API کلید بنائیں {#create-your-app-and-api-key} + +ایک بار جب آپ Alchemy اکاؤنٹ بنا لیتے ہیں، تو آپ ایک ایپ بنا کر ایک API کلید تیار کر سکتے ہیں۔ یہ آپ کو Goerli ٹیسٹ نیٹ پر درخواستیں بھیجنے کی اجازت دے گا۔ اگر آپ ٹیسٹ نیٹ سے واقف نہیں ہیں تو آپ [نیٹ ورک منتخب کرنے کے لیے Alchemy کی گائیڈ پڑھ سکتے ہیں](https://www.alchemy.com/docs/choosing-a-web3-network)۔ + +Alchemy ڈیش بورڈ پر، نیویگیشن بار میں **ایپس** ڈراپ ڈاؤن تلاش کریں اور **ایپ بنائیں** پر کلک کریں۔ + +![Hello world create app](./hello-world-create-app.png) + +اپنی ایپ کو '_ہیلو ورلڈ_' نام دیں اور ایک مختصر تفصیل لکھیں۔ اپنے ماحول کے طور پر **اسٹیجنگ** اور اپنے نیٹ ورک کے طور پر **Goerli** منتخب کریں۔ + +![create app view hello world](./create-app-view-hello-world.png) + +_نوٹ: یقینی بنائیں کہ **Goerli** منتخب کریں، ورنہ یہ ٹیوٹوریل کام نہیں کرے گا۔_ + +**ایپ بنائیں** پر کلک کریں۔ آپ کی ایپ نیچے دی گئی جدول میں ظاہر ہوگی۔ + +### ایک Ethereum اکاؤنٹ بنائیں {#create-an-ethereum-account} + +ٹرانزیکشنز بھیجنے اور وصول کرنے کے لیے آپ کو ایک Ethereum اکاؤنٹ کی ضرورت ہے۔ ہم MetaMask استعمال کریں گے، جو براؤزر میں ایک ورچوئل والیٹ ہے جو صارفین کو اپنے Ethereum اکاؤنٹ کے پتے کا انتظام کرنے کی اجازت دیتا ہے۔ + +آپ [یہاں](https://metamask.io/download) مفت میں MetaMask اکاؤنٹ ڈاؤن لوڈ اور بنا سکتے ہیں۔ جب آپ ایک اکاؤنٹ بنا رہے ہوں، یا اگر آپ کے پاس پہلے سے ہی ایک اکاؤنٹ ہے، تو یقینی بنائیں کہ اوپری دائیں کونے میں "Goerli ٹیسٹ نیٹ ورک" پر سوئچ کریں (تاکہ ہم اصلی پیسے سے نمٹ نہ رہے ہوں)۔ + +### مرحلہ 4: ایک فاسیٹ سے ایتھر شامل کریں {#step-4-add-ether-from-a-faucet} + +اپنے اسمارٹ کنٹریکٹ کو ٹیسٹ نیٹ ورک پر ڈیپلائے کرنے کے لیے، آپ کو کچھ جعلی ETH کی ضرورت ہوگی۔ Goerli نیٹ ورک پر ETH حاصل کرنے کے لیے، Goerli فوسیٹ پر جائیں اور اپنا Goerli اکاؤنٹ ایڈریس درج کریں۔ نوٹ کریں کہ Goerli فوسیٹس حال ہی میں تھوڑے غیر معتبر ہو سکتے ہیں - آزمانے کے لیے اختیارات کی فہرست کے لیے [ٹیسٹ نیٹ ورکس کا صفحہ](/developers/docs/networks/#goerli) دیکھیں۔ + +_نوٹ: نیٹ ورک کی بھیڑ کی وجہ سے، اس میں کچھ وقت لگ سکتا ہے۔_ +`` + +### مرحلہ 5: اپنا بیلنس چیک کریں {#step-5-check-your-balance} + +یہ دوبارہ چیک کرنے کے لیے کہ آیا ETH آپ کے والیٹ میں ہے، آئیے [Alchemy کے کمپوزر ٹول](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) کا استعمال کرتے ہوئے ایک [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) درخواست کریں۔ یہ ہمارے والیٹ میں ETH کی رقم واپس کرے گا۔ مزید جاننے کے لیے [کمپوزر ٹول کا استعمال کیسے کریں اس پر Alchemy کا مختصر ٹیوٹوریل](https://youtu.be/r6sjRxBZJuU) دیکھیں۔ + +اپنا MetaMask اکاؤنٹ کا پتہ درج کریں اور **درخواست بھیجیں** پر کلک کریں۔ آپ کو ایک جواب نظر آئے گا جو نیچے دیے گئے کوڈ کے ٹکڑے جیسا لگتا ہے۔ + +```json +{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } +``` + +> _نوٹ: یہ نتیجہ wei میں ہے، ETH میں نہیں۔ Wei کو ایتھر کی سب سے چھوٹی اکائی کے طور پر استعمال کیا جاتا ہے۔_ + +اف! ہمارا جعلی پیسہ سب وہیں ہے۔ + +### مرحلہ 6: ہمارے پروجیکٹ کو شروع کریں {#step-6-initialize-our-project} + +سب سے پہلے، ہمیں اپنے پروجیکٹ کے لیے ایک فولڈر بنانا ہوگا۔ اپنی کمانڈ لائن پر جائیں اور درج ذیل کو ان پٹ کریں۔ + +``` +mkdir hello-world +cd hello-world +``` + +اب جب کہ ہم اپنے پروجیکٹ فولڈر کے اندر ہیں، ہم پروجیکٹ کو شروع کرنے کے لیے `npm init` استعمال کریں گے۔ + +> اگر آپ کے پاس ابھی تک npm انسٹال نہیں ہے، تو [Node.js اور npm انسٹال کرنے کے لیے ان ہدایات](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) پر عمل کریں۔ + +اس ٹیوٹوریل کے مقصد کے لیے، اس سے کوئی فرق نہیں پڑتا کہ آپ ابتدائی سوالات کا جواب کیسے دیتے ہیں۔ حوالہ کے لیے ہم نے اسے اس طرح کیا: + +``` +پیکیج کا نام: (hello-world) +ورژن: (1.0.0) +تفصیل: ہیلو ورلڈ اسمارٹ کنٹریکٹ +انٹری پوائنٹ: (index.js) +ٹیسٹ کمانڈ: +گٹ ریپوزٹری: +کلیدی الفاظ: +مصنف: +لائسنس: (ISC) + +/Users/.../.../.../hello-world/package.json پر لکھنے کے بارے میں: + +{ + "name": "hello-world", + "version": "1.0.0", + "description": "ہیلو ورلڈ اسمارٹ کنٹریکٹ", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} +``` + +package.json کو منظور کریں اور ہم تیار ہیں! + +### مرحلہ 7: Hardhat ڈاؤن لوڈ کریں {#step-7-download-hardhat} + +Hardhat آپ کے Ethereum سافٹ ویئر کو کمپائل، ڈیپلوئے، ٹیسٹ اور ڈیبگ کرنے کے لیے ایک ڈیولپمنٹ ماحول ہے۔ یہ ڈیولپرز کو لائیو چین پر ڈیپلوئے کرنے سے پہلے مقامی طور پر اسمارٹ کنٹریکٹس اور dapps بنانے میں مدد کرتا ہے۔ + +ہمارے `hello-world` پروجیکٹ کے اندر چلائیں: + +``` +npm install --save-dev hardhat +``` + +[انسٹالیشن کی ہدایات](https://hardhat.org/getting-started/#overview) پر مزید تفصیلات کے لیے یہ صفحہ دیکھیں۔ + +### مرحلہ 8: Hardhat پروجیکٹ بنائیں {#step-8-create-hardhat-project} + +ہمارے `hello-world` پروجیکٹ فولڈر کے اندر، چلائیں: + +``` +npx hardhat +``` + +پھر آپ کو ایک خوش آمدیدی پیغام اور یہ منتخب کرنے کا آپشن نظر آئے گا کہ آپ کیا کرنا چاہتے ہیں۔ “create an empty hardhat.config.js” منتخب کریں: + +``` +888 888 888 888 888 +888 888 888 888 888 +888 888 888 888 888 +8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 +888 888 "88b 888P" d88" 888 888 "88b "88b 888 +888 888 .d888888 888 888 888 888 888 .d888888 888 +888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. +888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 + +👷 Hardhat v2.0.11 میں خوش آمدید 👷‍ + +آپ کیا کرنا چاہتے ہیں؟ … +ایک نمونہ پروجیکٹ بنائیں +❯ ایک خالی hardhat.config.js بنائیں +بند کریں +``` + +یہ پروجیکٹ میں ایک `hardhat.config.js` فائل بنائے گا۔ ہم اسے بعد میں ٹیوٹوریل میں اپنے پروجیکٹ کے سیٹ اپ کی وضاحت کے لیے استعمال کریں گے۔ + +### مرحلہ 9: پروجیکٹ فولڈر شامل کریں {#step-9-add-project-folders} + +پروجیکٹ کو منظم رکھنے کے لیے، آئیے دو نئے فولڈر بنائیں۔ کمانڈ لائن میں، اپنے `hello-world` پروجیکٹ کی روٹ ڈائرکٹری میں جائیں اور ٹائپ کریں: + +``` +mkdir contracts +mkdir scripts +``` + +- `contracts/` وہ جگہ ہے جہاں ہم اپنی ہیلو ورلڈ اسمارٹ کنٹریکٹ کوڈ فائل رکھیں گے۔ +- `scripts/` وہ جگہ ہے جہاں ہم اپنے کنٹریکٹ کو ڈیپلائے کرنے اور اس کے ساتھ انٹریکٹ کرنے کے لیے اسکرپٹس رکھیں گے۔ + +### مرحلہ 10: ہمارا کنٹریکٹ لکھیں {#step-10-write-our-contract} + +آپ خود سے پوچھ رہے ہوں گے کہ ہم کوڈ کب لکھنے جا رہے ہیں؟ یہی وقت ہے! + +اپنے پسندیدہ ایڈیٹر میں ہیلو-ورلڈ پروجیکٹ کھولیں۔ اسمارٹ کنٹریکٹس زیادہ تر Solidity میں لکھے جاتے ہیں، جسے ہم اپنا اسمارٹ کنٹریکٹ لکھنے کے لیے استعمال کریں گے۔‌ + +1. `contracts` فولڈر پر جائیں اور `HelloWorld.sol` نامی ایک نئی فائل بنائیں۔ +2. ذیل میں ایک نمونہ ہیلو ورلڈ اسمارٹ کنٹریکٹ ہے جسے ہم اس ٹیوٹوریل کے لیے استعمال کریں گے۔ نیچے دیے گئے مواد کو `HelloWorld.sol` فائل میں کاپی کریں۔ + +_نوٹ: یہ سمجھنے کے لیے کہ یہ کنٹریکٹ کیا کرتا ہے، تبصرے ضرور پڑھیں۔_ + +``` +// Solidity کے ورژن کی وضاحت کرتا ہے، سیمنٹک ورژننگ کا استعمال کرتے ہوئے۔ +// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity >=0.7.3; + +// `HelloWorld` نامی ایک کنٹریکٹ کی وضاحت کرتا ہے۔ +// ایک کنٹریکٹ فنکشنز اور ڈیٹا (اس کی حالت) کا ایک مجموعہ ہے۔ ایک بار ڈیپلائے ہونے کے بعد، ایک کنٹریکٹ Ethereum بلاک چین پر ایک مخصوص ایڈریس پر رہتا ہے۔ مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + //اپ ڈیٹ فنکشن کال ہونے پر جاری کیا جاتا ہے + //اسمارٹ کنٹریکٹ ایونٹس آپ کے کنٹریکٹ کے لیے یہ بتانے کا ایک طریقہ ہیں کہ بلاک چین پر آپ کے ایپ فرنٹ اینڈ پر کچھ ہوا ہے، جو کچھ ایونٹس کے لیے 'سن' سکتا ہے اور جب وہ ہوتے ہیں تو کارروائی کر سکتا ہے۔ + event UpdatedMessages(string oldStr, string newStr); + + // `string` قسم کے `message` نامی ایک اسٹیٹ متغیر کا اعلان کرتا ہے۔ + // اسٹیٹ متغیرات وہ متغیرات ہیں جن کی قدریں کنٹریکٹ اسٹوریج میں مستقل طور پر محفوظ ہوتی ہیں۔ کلیدی لفظ `public` متغیرات کو کنٹریکٹ کے باہر سے قابل رسائی بناتا ہے اور ایک فنکشن بناتا ہے جسے دوسرے کنٹریکٹس یا کلائنٹس قدر تک رسائی کے لیے کال کر سکتے ہیں۔ + string public message; + + // بہت سی کلاس پر مبنی آبجیکٹ اورینٹڈ زبانوں کی طرح، ایک کنسٹرکٹر ایک خاص فنکشن ہے جو صرف کنٹریکٹ کی تخلیق پر عمل میں لایا جاتا ہے۔ + // کنسٹرکٹرز کا استعمال کنٹریکٹ کے ڈیٹا کو شروع کرنے کے لیے کیا جاتا ہے۔ مزید جانیں:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // ایک اسٹرنگ آرگیومنٹ `initMessage` کو قبول کرتا ہے اور قدر کو کنٹریکٹ کے `message` اسٹوریج متغیر میں سیٹ کرتا ہے۔ + message = initMessage; + } + + // ایک عوامی فنکشن جو ایک اسٹرنگ آرگیومنٹ کو قبول کرتا ہے اور `message` اسٹوریج متغیر کو اپ ڈیٹ کرتا ہے۔ + function update(string memory newMessage) public { + string memory oldMsg = message; + message = newMessage; + emit UpdatedMessages(oldMsg, newMessage); + } +} +``` + +یہ ایک بنیادی اسمارٹ کنٹریکٹ ہے جو تخلیق کے وقت ایک پیغام محفوظ کرتا ہے۔ اسے `update` فنکشن کو کال کرکے اپ ڈیٹ کیا جاسکتا ہے۔ + +### مرحلہ 11: MetaMask اور Alchemy کو اپنے پروجیکٹ سے جوڑیں {#step-11-connect-metamask-alchemy-to-your-project} + +ہم نے ایک MetaMask والیٹ، Alchemy اکاؤنٹ بنایا ہے، اور اپنا اسمارٹ کنٹریکٹ لکھا ہے، اب ان تینوں کو جوڑنے کا وقت آگیا ہے۔ + +آپ کے والیٹ سے بھیجی گئی ہر ٹرانزیکشن کے لیے آپ کی منفرد پرائیویٹ کلید کا استعمال کرتے ہوئے ایک دستخط کی ضرورت ہوتی ہے۔ ہمارے پروگرام کو یہ اجازت دینے کے لیے، ہم اپنی پرائیویٹ کلید کو ایک انوائرمنٹ فائل میں محفوظ طریقے سے محفوظ کر سکتے ہیں۔ ہم یہاں Alchemy کے لیے ایک API کلید بھی محفوظ کریں گے۔ + +> ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، web3 کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے پر [یہ ٹیوٹوریل](https://www.alchemy.com/docs/hello-world-smart-contract#step-11-connect-metamask--alchemy-to-your-project) دیکھیں۔ + +سب سے پہلے، اپنی پروجیکٹ ڈائرکٹری میں dotenv پیکیج انسٹال کریں: + +``` +npm install dotenv --save +``` + +پھر، پروجیکٹ کی روٹ ڈائرکٹری میں ایک `.env` فائل بنائیں۔ اس میں اپنی MetaMask پرائیویٹ کلید اور HTTP Alchemy API URL شامل کریں۔ + +آپ کی انوائرمنٹ فائل کا نام `.env` ہونا چاہئے ورنہ اسے انوائرمنٹ فائل کے طور پر تسلیم نہیں کیا جائے گا۔ + +اس کا نام `process.env` یا `.env-custom` یا کچھ اور نہ رکھیں۔ + +- اپنی پرائیویٹ کلید برآمد کرنے کے لیے [ان ہدایات](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) پر عمل کریں +- HTTP Alchemy API URL حاصل کرنے کے لیے نیچے دیکھیں + +![](./get-alchemy-api-key.gif) + +آپ کا `.env` اس طرح نظر آنا چاہیے: + +``` +API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +PRIVATE_KEY = "your-metamask-private-key" +``` + +انہیں حقیقت میں ہمارے کوڈ سے جوڑنے کے لیے، ہم ان متغیرات کا حوالہ اپنی `hardhat.config.js` فائل میں مرحلہ 13 پر دیں گے۔ + +### مرحلہ 12: Ethers.js انسٹال کریں {#step-12-install-ethersjs} + +Ethers.js ایک لائبریری ہے جو زیادہ صارف دوست طریقوں کے ساتھ [معیاری JSON-RPC طریقوں](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc) کو لپیٹ کر Ethereum کے ساتھ تعامل اور درخواستیں کرنا آسان بناتی ہے۔ + +Hardhat ہمیں اضافی ٹولنگ اور توسیع شدہ فعالیت کے لیے [پلگ انز](https://hardhat.org/plugins/) کو مربوط کرنے کی اجازت دیتا ہے۔ ہم کنٹریکٹ ڈیپلائیمنٹ کے لیے [Ethers پلگ ان](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) سے فائدہ اٹھائیں گے۔ + +اپنی پروجیکٹ ڈائرکٹری میں ٹائپ کریں: + +```bash +npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" +``` + +### مرحلہ 13: hardhat.config.js کو اپ ڈیٹ کریں {#step-13-update-hardhat-configjs} + +ہم نے اب تک کئی انحصارات اور پلگ ان شامل کیے ہیں، اب ہمیں `hardhat.config.js` کو اپ ڈیٹ کرنے کی ضرورت ہے تاکہ ہمارے پروجیکٹ کو ان سب کے بارے میں معلوم ہو۔ + +اپنی `hardhat.config.js` کو اس طرح اپ ڈیٹ کریں: + +```javascript +/** + * @type import('hardhat/config').HardhatUserConfig + */ + +require("dotenv").config() +require("@nomiclabs/hardhat-ethers") + +const { API_URL, PRIVATE_KEY } = process.env + +module.exports = { + solidity: "0.7.3", + defaultNetwork: "goerli", + networks: { + hardhat: {}, + goerli: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`], + }, + }, +} +``` + +### مرحلہ 14: ہمارا کنٹریکٹ کمپائل کریں {#step-14-compile-our-contract} + +یہ یقینی بنانے کے لیے کہ اب تک سب کچھ کام کر رہا ہے، آئیے اپنے کنٹریکٹ کو کمپائل کریں۔ `compile` ٹاسک بلٹ ان ہارڈ ہیٹ ٹاسک میں سے ایک ہے۔ + +کمانڈ لائن سے چلائیں: + +```bash +npx hardhat compile +``` + +آپ کو `SPDX license identifier not provided in source file` کے بارے میں ایک انتباہ مل سکتا ہے، لیکن اس کے بارے میں فکر کرنے کی کوئی ضرورت نہیں ہے — امید ہے کہ باقی سب کچھ ٹھیک نظر آئے گا! اگر نہیں، تو آپ ہمیشہ [Alchemy discord](https://discord.gg/u72VCg3) میں پیغام بھیج سکتے ہیں۔ + +### مرحلہ 15: ہمارا ڈیپلائے اسکرپٹ لکھیں {#step-15-write-our-deploy-script} + +اب جب کہ ہمارا کنٹریکٹ لکھا جا چکا ہے اور ہماری کنفیگریشن فائل تیار ہے، اب وقت آگیا ہے کہ ہم اپنی کنٹریکٹ ڈیپلوئے اسکرپٹ لکھیں۔ + +`scripts/` فولڈر پر جائیں اور `deploy.js` نامی ایک نئی فائل بنائیں، اس میں درج ذیل مواد شامل کریں: + +```javascript +async function main() { + const HelloWorld = await ethers.getContractFactory("HelloWorld") + + // ڈیپلائیمنٹ شروع کریں، ایک وعدہ واپس کریں جو ایک کنٹریکٹ آبجیکٹ پر حل ہوتا ہے + const hello_world = await HelloWorld.deploy("Hello World!") + console.log("کنٹریکٹ اس ایڈریس پر ڈیپلائے کیا گیا:", hello_world.address) +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error) + process.exit(1) + }) +``` + +Hardhat اپنے [کنٹریکٹس ٹیوٹوریل](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) میں بہت اچھی طرح سے وضاحت کرتا ہے کہ کوڈ کی یہ ہر لائن کیا کرتی ہے، ہم نے یہاں ان کی وضاحتیں اپنائی ہیں۔ + +```javascript +const HelloWorld = await ethers.getContractFactory("HelloWorld") +``` + +ethers.js میں ایک `ContractFactory` ایک تجرید ہے جو نئے اسمارٹ کنٹریکٹس کو ڈیپلائے کرنے کے لیے استعمال ہوتی ہے، لہذا یہاں `HelloWorld` ہمارے ہیلو ورلڈ کنٹریکٹ کی مثالوں کے لیے ایک [فیکٹری](https://en.wikipedia.org/wiki/Factory_\(object-oriented_programming\)) ہے۔ `hardhat-ethers` پلگ ان کا استعمال کرتے وقت `ContractFactory` اور `Contract`، مثالیں پہلے دستخط کنندہ (مالک) سے بطور ڈیفالٹ جڑی ہوتی ہیں۔ + +```javascript +const hello_world = await HelloWorld.deploy() +``` + +`ContractFactory` پر `deploy()` کو کال کرنے سے ڈیپلائیمنٹ شروع ہو جائے گی، اور ایک `Promise` واپس آئے گا جو ایک `Contract` آبجیکٹ پر حل ہوتا ہے۔ یہ وہ آبجیکٹ ہے جس میں ہمارے ہر اسمارٹ کنٹریکٹ فنکشن کے لیے ایک طریقہ ہے۔ + +### مرحلہ 16: ہمارا کنٹریکٹ ڈیپلائے کریں {#step-16-deploy-our-contract} + +ہم آخر کار اپنے اسمارٹ کنٹریکٹ کو ڈیپلوئے کرنے کے لیے تیار ہیں! کمانڈ لائن پر جائیں اور چلائیں: + +```bash +npx hardhat run scripts/deploy.js --network goerli +``` + +پھر آپ کو کچھ اس طرح نظر آنا چاہیے: + +```bash +کنٹریکٹ اس ایڈریس پر ڈیپلائے کیا گیا: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +``` + +**براہ کرم یہ ایڈریس محفوظ کریں**۔ ہم اسے بعد میں ٹیوٹوریل میں استعمال کریں گے۔ + +اگر ہم [Goerli etherscan](https://goerli.etherscan.io) پر جائیں اور اپنے کنٹریکٹ ایڈریس کو تلاش کریں تو ہمیں یہ دیکھنا چاہیے کہ یہ کامیابی سے ڈیپلائے ہو گیا ہے۔ ٹرانزیکشن کچھ اس طرح نظر آئے گی: + +![](./etherscan-contract.png) + +`From` ایڈریس آپ کے MetaMask اکاؤنٹ ایڈریس سے مماثل ہونا چاہئے اور `To` ایڈریس **کنٹریکٹ کی تخلیق** کہے گا۔ اگر ہم ٹرانزیکشن پر کلک کرتے ہیں تو ہمیں `To` فیلڈ میں اپنا کنٹریکٹ ایڈریس نظر آئے گا۔ + +![](./etherscan-transaction.png) + +مبارک ہو! آپ نے ابھی ایک Ethereum ٹیسٹ نیٹ پر ایک اسمارٹ کنٹریکٹ ڈیپلائے کیا ہے۔ + +پس پردہ کیا ہو رہا ہے یہ سمجھنے کے لیے، آئیے اپنے [Alchemy ڈیش بورڈ](https://dashboard.alchemy.com/explorer) میں ایکسپلورر ٹیب پر جائیں۔ اگر آپ کے پاس متعدد Alchemy ایپس ہیں تو یقینی بنائیں کہ ایپ کے لحاظ سے فلٹر کریں اور **ہیلو ورلڈ** منتخب کریں۔ + +![](./hello-world-explorer.png) + +یہاں آپ کو کچھ JSON-RPC طریقے نظر آئیں گے جو Hardhat/Ethers نے ہمارے لیے پس پردہ بنائے تھے جب ہم نے `.deploy()` فنکشن کو کال کیا تھا۔ یہاں دو اہم طریقے ہیں [`eth_sendRawTransaction`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction)، جو ہمارے کنٹریکٹ کو Goerli چین پر لکھنے کی درخواست ہے، اور [`eth_getTransactionByHash`](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_gettransactionbyhash)، جو ہیش دیے جانے پر ہماری ٹرانزیکشن کے بارے میں معلومات پڑھنے کی درخواست ہے۔ ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، [Web3 کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے پر ہمارا ٹیوٹوریل](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) دیکھیں۔ + +## حصہ 2: اپنے اسمارٹ کنٹریکٹ کے ساتھ تعامل کریں {#part-2-interact-with-your-smart-contract} + +اب جب کہ ہم نے Goerli نیٹ ورک پر ایک اسمارٹ کنٹریکٹ کامیابی سے ڈیپلائے کر لیا ہے، آئیے سیکھتے ہیں کہ اس کے ساتھ کیسے تعامل کیا جائے۔ + +### ایک interact.js فائل بنائیں {#create-a-interactjs-file} + +یہ وہ فائل ہے جہاں ہم اپنا تعامل کا اسکرپٹ لکھیں گے۔ ہم Ethers.js لائبریری استعمال کریں گے جو آپ نے پہلے حصہ 1 میں انسٹال کی تھی۔ + +`scripts/` فولڈر کے اندر، `interact.js` نامی ایک نئی فائل بنائیں اور درج ذیل کوڈ شامل کریں: + +```javascript +// interact.js + +const API_KEY = process.env.API_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY +const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS +``` + +### اپنی .env فائل کو اپ ڈیٹ کریں {#update-your-env-file} + +ہم نئے انوائرمنٹ متغیرات استعمال کریں گے، لہذا ہمیں انہیں `.env` فائل میں بیان کرنے کی ضرورت ہے جو [ہم نے پہلے بنائی تھی](#step-11-connect-metamask-&-alchemy-to-your-project)۔ + +ہمیں اپنے Alchemy `API_KEY` اور `CONTRACT_ADDRESS` کے لیے ایک تعریف شامل کرنے کی ضرورت ہوگی جہاں آپ کا اسمارٹ کنٹریکٹ ڈیپلائے کیا گیا تھا۔ + +آپ کی `.env` فائل کچھ اس طرح نظر آنی چاہیے: + +```bash +# .env + +API_URL = "https://eth-goerli.alchemyapi.io/v2/" +API_KEY = "" +PRIVATE_KEY = "" +CONTRACT_ADDRESS = "0x" +``` + +### اپنا کنٹریکٹ ABI حاصل کریں {#grab-your-contract-ABI} + +ہمارا کنٹریکٹ [ABI (ایپلیکیشن بائنری انٹرفیس)](/glossary/#abi) ہمارے اسمارٹ کنٹریکٹ کے ساتھ تعامل کرنے کا انٹرفیس ہے۔ Hardhat خود بخود ایک ABI تیار کرتا ہے اور اسے `HelloWorld.json` میں محفوظ کرتا ہے۔ ABI کا استعمال کرنے کے لیے، ہمیں اپنی `interact.js` فائل میں کوڈ کی درج ذیل لائنیں شامل کرکے مواد کو پارس کرنا ہوگا: + +```javascript +// interact.js +const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json") +``` + +اگر آپ ABI دیکھنا چاہتے ہیں تو آپ اسے اپنے کنسول پر پرنٹ کر سکتے ہیں: + +```javascript +console.log(JSON.stringify(contract.abi)) +``` + +اپنا ABI کنسول پر پرنٹ دیکھنے کے لیے، اپنے ٹرمینل پر جائیں اور چلائیں: + +```bash +npx hardhat run scripts/interact.js +``` + +### اپنے کنٹریکٹ کی ایک مثال بنائیں {#create-an-instance-of-your-contract} + +ہمارے کنٹریکٹ کے ساتھ تعامل کرنے کے لیے، ہمیں اپنے کوڈ میں کنٹریکٹ کی ایک مثال بنانے کی ضرورت ہے۔ Ethers.js کے ساتھ ایسا کرنے کے لیے، ہمیں تین تصورات کے ساتھ کام کرنے کی ضرورت ہوگی: + +1. پرووائیڈر - ایک نوڈ پرووائیڈر جو آپ کو بلاک چین تک پڑھنے اور لکھنے کی رسائی دیتا ہے +2. دستخط کنندہ - ایک Ethereum اکاؤنٹ کی نمائندگی کرتا ہے جو ٹرانزیکشنز پر دستخط کر سکتا ہے +3. کنٹریکٹ - ایک Ethers.js آبجیکٹ جو آن چین ڈیپلائے کیے گئے ایک مخصوص کنٹریکٹ کی نمائندگی کرتا ہے + +ہم کنٹریکٹ کی اپنی مثال بنانے کے لیے پچھلے مرحلے سے کنٹریکٹ ABI کا استعمال کریں گے: + +```javascript +// interact.js + +// پرووائیڈر +const alchemyProvider = new ethers.providers.AlchemyProvider( + (network = "goerli"), + API_KEY +) + +// دستخط کنندہ +const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) + +// کنٹریکٹ +const helloWorldContract = new ethers.Contract( + CONTRACT_ADDRESS, + contract.abi, + signer +) +``` + +[ethers.js دستاویزات](https://docs.ethers.io/v5/) میں پرووائیڈرز، دستخط کنندگان، اور کنٹریکٹس کے بارے میں مزید جانیں۔ + +### ابتدائی پیغام پڑھیں {#read-the-init-message} + +یاد ہے جب ہم نے اپنا کنٹریکٹ `initMessage = "Hello world!"` کے ساتھ ڈیپلائے کیا تھا؟ اب ہم اپنے اسمارٹ کنٹریکٹ میں محفوظ اس پیغام کو پڑھنے اور اسے کنسول پر پرنٹ کرنے جا رہے ہیں۔ + +JavaScript میں، نیٹ ورکس کے ساتھ تعامل کرتے وقت غیر مطابقت پذیر فنکشنز استعمال ہوتے ہیں۔ غیر مطابقت پذیر فنکشنز کے بارے میں مزید جاننے کے لیے، [یہ میڈیم مضمون پڑھیں](https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff)۔ + +ہمارے اسمارٹ کنٹریکٹ میں `message` فنکشن کو کال کرنے اور ابتدائی پیغام پڑھنے کے لیے نیچے دیے گئے کوڈ کا استعمال کریں: + +```javascript +// interact.js + +// ... + +async function main() { + const message = await helloWorldContract.message() + console.log("پیغام یہ ہے: " + message) +} +main() +``` + +`npx hardhat run scripts/interact.js` کا استعمال کرتے ہوئے ٹرمینل میں فائل چلانے کے بعد ہمیں یہ جواب نظر آنا چاہیے: + +``` +پیغام یہ ہے: ہیلو ورلڈ! +``` + +مبارک ہو! آپ نے ابھی Ethereum بلاک چین سے اسمارٹ کنٹریکٹ کا ڈیٹا کامیابی سے پڑھ لیا ہے، شاباش! + +### پیغام کو اپ ڈیٹ کریں {#update-the-message} + +صرف پیغام پڑھنے کے بجائے، ہم `update` فنکشن کا استعمال کرتے ہوئے اپنے اسمارٹ کنٹریکٹ میں محفوظ پیغام کو بھی اپ ڈیٹ کر سکتے ہیں! بہت اچھا ہے، ہے نا؟ + +پیغام کو اپ ڈیٹ کرنے کے لیے، ہم اپنے انسٹینٹی ایٹڈ کنٹریکٹ آبجیکٹ پر براہ راست `update` فنکشن کو کال کر سکتے ہیں: + +```javascript +// interact.js + +// ... + +async function main() { + const message = await helloWorldContract.message() + console.log("پیغام یہ ہے: " + message) + + console.log("پیغام کو اپ ڈیٹ کیا جا رہا ہے...") + const tx = await helloWorldContract.update("یہ نیا پیغام ہے۔") + await tx.wait() +} +main() +``` + +نوٹ کریں کہ لائن 11 پر، ہم واپس کیے گئے ٹرانزیکشن آبجیکٹ پر `.wait()` کو کال کرتے ہیں۔ یہ یقینی بناتا ہے کہ ہمارا اسکرپٹ فنکشن سے باہر نکلنے سے پہلے بلاک چین پر ٹرانزیکشن کے مائن ہونے کا انتظار کرے۔ اگر `.wait()` کال شامل نہیں ہے، تو اسکرپٹ کنٹریکٹ میں اپ ڈیٹ شدہ `message` قدر نہیں دیکھ سکتا۔ + +### نیا پیغام پڑھیں {#read-the-new-message} + +آپ کو اپ ڈیٹ شدہ `message` قدر پڑھنے کے لیے [پچھلے مرحلے](#read-the-init-message) کو دہرانے کے قابل ہونا چاہیے۔ ایک لمحہ نکالیں اور دیکھیں کہ کیا آپ اس نئی قدر کو پرنٹ کرنے کے لیے ضروری تبدیلیاں کر سکتے ہیں! + +اگر آپ کو کوئی اشارہ چاہیے، تو یہاں یہ ہے کہ آپ کی `interact.js` فائل اس وقت کیسی نظر آنی چاہیے: + +```javascript +// interact.js + +const API_KEY = process.env.API_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY +const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS + +const contract = require("../artifacts/contracts/HelloWorld.sol/HelloWorld.json") + +// پرووائیڈر - Alchemy +const alchemyProvider = new ethers.providers.AlchemyProvider( + (network = "goerli"), + API_KEY +) + +// دستخط کنندہ - آپ +const signer = new ethers.Wallet(PRIVATE_KEY, alchemyProvider) + +// کنٹریکٹ کی مثال +const helloWorldContract = new ethers.Contract( + CONTRACT_ADDRESS, + contract.abi, + signer +) + +async function main() { + const message = await helloWorldContract.message() + console.log("پیغام یہ ہے: " + message) + + console.log("پیغام کو اپ ڈیٹ کیا جا رہا ہے...") + const tx = await helloWorldContract.update("یہ نیا پیغام ہے") + await tx.wait() + + const newMessage = await helloWorldContract.message() + console.log("نیا پیغام یہ ہے: " + newMessage) +} + +main() +``` + +اب صرف اسکرپٹ چلائیں اور آپ کو پرانا پیغام، اپ ڈیٹ کی حیثیت، اور نیا پیغام اپنے ٹرمینل پر پرنٹ ہوتا نظر آنا چاہیے! + +`npx hardhat run scripts/interact.js --network goerli` + +``` +پیغام یہ ہے: ہیلو ورلڈ! +پیغام کو اپ ڈیٹ کیا جا رہا ہے... +نیا پیغام یہ ہے: یہ نیا پیغام ہے۔ +``` + +اس اسکرپٹ کو چلاتے وقت، آپ کو معلوم ہو سکتا ہے کہ نیا پیغام لوڈ ہونے سے پہلے `Updating the message...` مرحلے میں کچھ وقت لگتا ہے۔ یہ مائننگ کے عمل کی وجہ سے ہے؛ اگر آپ ٹرانزیکشنز کو مائن ہونے کے دوران ٹریک کرنے میں دلچسپی رکھتے ہیں، تو ٹرانزیکشن کی حیثیت دیکھنے کے لیے [Alchemy میم پول](https://dashboard.alchemyapi.io/mempool) پر جائیں۔ اگر ٹرانزیکشن ڈراپ ہو جاتی ہے، تو [Goerli Etherscan](https://goerli.etherscan.io) کو چیک کرنا اور اپنی ٹرانزیکشن ہیش کو تلاش کرنا بھی مددگار ہے۔ + +## حصہ 3: اپنے اسمارٹ کنٹریکٹ کو Etherscan پر شائع کریں {#part-3-publish-your-smart-contract-to-etherscan} + +آپ نے اپنے اسمارٹ کنٹریکٹ کو زندہ کرنے کی تمام محنت کی؛ اب اسے دنیا کے ساتھ شیئر کرنے کا وقت ہے! + +Etherscan پر اپنے اسمارٹ کنٹریکٹ کی تصدیق کرکے، کوئی بھی آپ کا سورس کوڈ دیکھ سکتا ہے اور آپ کے اسمارٹ کنٹریکٹ کے ساتھ تعامل کر سکتا ہے۔ آئیے شروع کرتے ہیں! + +### مرحلہ 1: اپنے Etherscan اکاؤنٹ پر ایک API کلید تیار کریں {#step-1-generate-an-api-key-on-your-etherscan-account} + +Etherscan API کلید اس بات کی تصدیق کے لیے ضروری ہے کہ آپ اس اسمارٹ کنٹریکٹ کے مالک ہیں جسے آپ شائع کرنے کی کوشش کر رہے ہیں۔ + +اگر آپ کے پاس پہلے سے Etherscan اکاؤنٹ نہیں ہے، تو [ایک اکاؤنٹ کے لیے سائن اپ کریں](https://etherscan.io/register)۔ + +لاگ ان ہونے کے بعد، نیویگیشن بار میں اپنا صارف نام تلاش کریں، اس پر ہوور کریں اور **میری پروفائل** بٹن منتخب کریں۔ + +آپ کے پروفائل صفحہ پر، آپ کو ایک سائیڈ نیویگیشن بار نظر آنا چاہیے۔ سائیڈ نیویگیشن بار سے، **API کیز** منتخب کریں۔ اگلا، ایک نئی API کلید بنانے کے لیے "شامل کریں" بٹن دبائیں، اپنی ایپ کا نام **hello-world** رکھیں اور **نئی API کلید بنائیں** بٹن دبائیں۔ + +آپ کی نئی API کلید API کلید کی میز میں ظاہر ہونی چاہیے۔ API کلید کو اپنے کلپ بورڈ پر کاپی کریں۔ + +اگلا، ہمیں Etherscan API کلید کو اپنی `.env` فائل میں شامل کرنے کی ضرورت ہے۔ + +اسے شامل کرنے کے بعد، آپ کی `.env` فائل اس طرح نظر آنی چاہیے: + +```javascript +API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key" +PUBLIC_KEY = "your-public-account-address" +PRIVATE_KEY = "your-private-account-address" +CONTRACT_ADDRESS = "your-contract-address" +ETHERSCAN_API_KEY = "your-etherscan-key" +``` + +### Hardhat کے ذریعے ڈیپلائے کیے گئے اسمارٹ کنٹریکٹس {#hardhat-deployed-smart-contracts} + +#### hardhat-etherscan انسٹال کریں {#install-hardhat-etherscan} + +Hardhat کا استعمال کرتے ہوئے اپنے کنٹریکٹ کو Etherscan پر شائع کرنا سیدھا سادہ ہے۔ شروع کرنے کے لیے آپ کو پہلے `hardhat-etherscan` پلگ ان انسٹال کرنے کی ضرورت ہوگی۔ `hardhat-etherscan` خود بخود اسمارٹ کنٹریکٹ کے سورس کوڈ اور ABI کی Etherscan پر تصدیق کرے گا۔ اسے شامل کرنے کے لیے، `hello-world` ڈائرکٹری میں چلائیں: + +```text +npm install --save-dev @nomiclabs/hardhat-etherscan +``` + +انسٹال ہونے کے بعد، اپنی `hardhat.config.js` کے اوپری حصے میں درج ذیل بیان شامل کریں، اور Etherscan کنفیگریشن کے اختیارات شامل کریں: + +```javascript +// hardhat.config.js + +require("dotenv").config() +require("@nomiclabs/hardhat-ethers") +require("@nomiclabs/hardhat-etherscan") + +const { API_URL, PRIVATE_KEY, ETHERSCAN_API_KEY } = process.env + +module.exports = { + solidity: "0.7.3", + defaultNetwork: "goerli", + networks: { + hardhat: {}, + goerli: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`], + }, + }, + etherscan: { + // Etherscan کے لیے آپ کی API کلید + // https://etherscan.io/ پر ایک حاصل کریں + apiKey: ETHERSCAN_API_KEY, + }, +} +``` + +#### Etherscan پر اپنے اسمارٹ کنٹریکٹ کی تصدیق کریں {#verify-your-smart-contract-on-etherscan} + +یقینی بنائیں کہ تمام فائلیں محفوظ ہیں اور تمام `.env` متغیرات صحیح طریقے سے کنفیگر کیے گئے ہیں۔ + +`verify` ٹاسک چلائیں، کنٹریکٹ ایڈریس، اور جس نیٹ ورک پر یہ ڈیپلائے کیا گیا ہے اسے پاس کریں: + +```text +npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS 'Hello World!' +``` + +یقینی بنائیں کہ `DEPLOYED_CONTRACT_ADDRESS` Goerli ٹیسٹ نیٹ ورک پر آپ کے ڈیپلائے کیے گئے اسمارٹ کنٹریکٹ کا ایڈریس ہے۔ اس کے علاوہ، آخری آرگیومنٹ (`'Hello World!'`) وہی اسٹرنگ قدر ہونی چاہیے جو [حصہ 1 میں ڈیپلائے مرحلے کے دوران](#write-our-deploy-script) استعمال کی گئی تھی۔ + +اگر سب کچھ ٹھیک رہا، تو آپ کو اپنے ٹرمینل میں درج ذیل پیغام نظر آئے گا: + +```text +کنٹریکٹ کے لیے سورس کوڈ کامیابی سے جمع کر دیا گیا +contracts/HelloWorld.sol:HelloWorld at 0xdeployed-contract-address +Etherscan پر تصدیق کے لیے۔ تصدیق کے نتیجے کا انتظار ہے... + + +Etherscan پر HelloWorld کنٹریکٹ کامیابی سے تصدیق شدہ ہے۔ +https://goerli.etherscan.io/address/#contracts +``` + +مبارک ہو! آپ کا اسمارٹ کنٹریکٹ کوڈ Etherscan پر ہے! + +### Etherscan پر اپنا اسمارٹ کنٹریکٹ دیکھیں! {#check-out-your-smart-contract-on-etherscan} + +جب آپ اپنے ٹرمینل میں فراہم کردہ لنک پر جاتے ہیں، تو آپ کو Etherscan پر اپنا اسمارٹ کنٹریکٹ کوڈ اور ABI شائع ہوتا نظر آنا چاہیے! + +**واہو - آپ نے کر دکھایا چیمپئن! اب کوئی بھی آپ کے اسمارٹ کنٹریکٹ کو کال یا اس پر لکھ سکتا ہے! ہم یہ دیکھنے کے لیے انتظار نہیں کر سکتے کہ آپ اگلا کیا بناتے ہیں!** + +## حصہ 4 - اپنے اسمارٹ کنٹریکٹ کو فرنٹ اینڈ کے ساتھ مربوط کرنا {#part-4-integrating-your-smart-contract-with-the-frontend} + +اس ٹیوٹوریل کے آخر تک، آپ جان جائیں گے کہ کیسے: + +- MetaMask والیٹ کو اپنے dapp سے جوڑیں +- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API کا استعمال کرتے ہوئے اپنے اسمارٹ کنٹریکٹ سے ڈیٹا پڑھیں +- MetaMask کا استعمال کرتے ہوئے Ethereum ٹرانزیکشنز پر دستخط کریں + +اس dapp کے لیے، ہم اپنے فرنٹ اینڈ فریم ورک کے طور پر [React](https://react.dev/) کا استعمال کریں گے؛ تاہم، یہ نوٹ کرنا ضروری ہے کہ ہم اس کی بنیادی باتوں کو توڑنے میں زیادہ وقت نہیں گزاریں گے، کیونکہ ہم زیادہ تر اپنے پروجیکٹ میں Web3 کی فعالیت لانے پر توجہ دیں گے۔ + +پیشگی شرط کے طور پر، آپ کو React کی مبتدی سطح کی سمجھ ہونی چاہیے۔ اگر نہیں، تو ہم سرکاری [React کا تعارف ٹیوٹوریل](https://react.dev/learn) مکمل کرنے کی سفارش کرتے ہیں۔ + +### اسٹارٹر فائلیں کلون کریں {#clone-the-starter-files} + +سب سے پہلے، اس پروجیکٹ کے لیے اسٹارٹر فائلیں حاصل کرنے کے لیے [hello-world-part-four GitHub repository](https://github.com/alchemyplatform/hello-world-part-four-tutorial) پر جائیں اور اس ریپوزٹری کو اپنی مقامی مشین پر کلون کریں۔ + +کلون کی گئی ریپوزٹری کو مقامی طور پر کھولیں۔ نوٹ کریں کہ اس میں دو فولڈرز ہیں: `starter-files` اور `completed`۔ + +- `starter-files`- **ہم اس ڈائرکٹری میں کام کریں گے**، ہم UI کو آپ کے Ethereum والیٹ اور اسمارٹ کنٹریکٹ سے جوڑیں گے جسے ہم نے [حصہ 3](#part-3) میں Etherscan پر شائع کیا تھا۔ +- `completed` میں مکمل ٹیوٹوریل شامل ہے اور اسے صرف ایک حوالہ کے طور پر استعمال کیا جانا چاہئے اگر آپ پھنس جائیں۔ + +اگلا، اپنی `starter-files` کی کاپی کو اپنے پسندیدہ کوڈ ایڈیٹر میں کھولیں، اور پھر `src` فولڈر میں جائیں۔ + +ہمارا لکھا ہوا سارا کوڈ `src` فولڈر کے تحت رہے گا۔ ہم اپنے پروجیکٹ کو Web3 کی فعالیت دینے کے لیے `HelloWorld.js` جزو اور `util/interact.js` JavaScript فائلوں میں ترمیم کریں گے۔ + +### اسٹارٹر فائلیں چیک کریں {#check-out-the-starter-files} + +کوڈنگ شروع کرنے سے پہلے، آئیے دریافت کریں کہ اسٹارٹر فائلوں میں ہمیں کیا فراہم کیا گیا ہے۔ + +#### اپنا react پروجیکٹ چلائیں {#get-your-react-project-running} + +آئیے اپنے براؤزر میں React پروجیکٹ چلا کر شروع کریں۔ React کی خوبصورتی یہ ہے کہ ایک بار جب ہمارا پروجیکٹ ہمارے براؤزر میں چل رہا ہو، تو ہمارے ذریعے محفوظ کی گئی کوئی بھی تبدیلی ہمارے براؤزر میں لائیو اپ ڈیٹ ہو جائے گی۔ + +پروجیکٹ کو چلانے کے لیے، `starter-files` فولڈر کی روٹ ڈائرکٹری پر جائیں، اور پروجیکٹ کی انحصار کو انسٹال کرنے کے لیے اپنے ٹرمینل میں `npm install` چلائیں: + +```bash +cd starter-files +npm install +``` + +ان کے انسٹال ہونے کے بعد، اپنے ٹرمینل میں `npm start` چلائیں: + +```bash +npm start +``` + +ایسا کرنے سے آپ کے براؤزر میں [http://localhost:3000/](http://localhost:3000/) کھل جانا چاہیے، جہاں آپ کو ہمارے پروجیکٹ کا فرنٹ اینڈ نظر آئے گا۔ اس میں ایک فیلڈ (آپ کے اسمارٹ کنٹریکٹ میں محفوظ پیغام کو اپ ڈیٹ کرنے کی جگہ)، ایک "والیٹ جوڑیں" بٹن، اور ایک "اپ ڈیٹ" بٹن ہونا چاہیے۔ + +اگر آپ کسی بھی بٹن پر کلک کرنے کی کوشش کرتے ہیں، تو آپ دیکھیں گے کہ وہ کام نہیں کرتے ہیں - اس کی وجہ یہ ہے کہ ہمیں ابھی بھی ان کی فعالیت کو پروگرام کرنے کی ضرورت ہے۔ + +#### `HelloWorld.js` جزو {#the-helloworld-js-component} + +آئیے اپنے ایڈیٹر میں `src` فولڈر میں واپس جائیں اور `HelloWorld.js` فائل کھولیں۔ یہ بہت ضروری ہے کہ ہم اس فائل میں ہر چیز کو سمجھیں، کیونکہ یہ بنیادی React کمپونینٹ ہے جس پر ہم کام کریں گے۔ + +اس فائل کے اوپری حصے میں، آپ دیکھیں گے کہ ہمارے پاس کئی درآمدی بیانات ہیں جو ہمارے پروجیکٹ کو چلانے کے لیے ضروری ہیں، بشمول React لائبریری، useEffect اور useState ہکس، `./util/interact.js` سے کچھ آئٹمز (ہم ان کی مزید تفصیلات جلد بیان کریں گے!)، اور Alchemy لوگو۔ + +```javascript +// HelloWorld.js + +import React from "react" +import { useEffect, useState } from "react" +import { + helloWorldContract, + connectWallet, + updateMessage, + loadCurrentMessage, + getCurrentWalletConnected, +} from "./util/interact.js" + +import alchemylogo from "./alchemylogo.svg" +``` + +اگلا، ہمارے پاس ہمارے ریاستی متغیرات ہیں جنہیں ہم مخصوص واقعات کے بعد اپ ڈیٹ کریں گے۔ + +```javascript +// HelloWorld.js + +//ریاستی متغیرات +const [walletAddress, setWallet] = useState("") +const [status, setStatus] = useState("") +const [message, setMessage] = useState("نیٹ ورک سے کوئی کنکشن نہیں ہے۔") +const [newMessage, setNewMessage] = useState("") +``` + +یہاں ہر متغیر کی نمائندگی کرتا ہے: + +- `walletAddress` - ایک اسٹرنگ جو صارف کے والیٹ کا پتہ محفوظ کرتا ہے +- `status`- ایک اسٹرنگ جو ایک مددگار پیغام محفوظ کرتا ہے جو صارف کو dapp کے ساتھ تعامل کرنے کے طریقے کے بارے میں رہنمائی کرتا ہے +- `message` - ایک اسٹرنگ جو اسمارٹ کنٹریکٹ میں موجودہ پیغام کو محفوظ کرتا ہے +- `newMessage` - ایک اسٹرنگ جو نیا پیغام محفوظ کرتا ہے جو اسمارٹ کنٹریکٹ میں لکھا جائے گا + +ریاستی متغیرات کے بعد، آپ کو پانچ غیر نافذ شدہ افعال نظر آئیں گے: `useEffect` ,`addSmartContractListener`, `addWalletListener` , `connectWalletPressed`, اور `onUpdatePressed`۔ ہم ذیل میں وضاحت کریں گے کہ وہ کیا کرتے ہیں: + +```javascript +// HelloWorld.js + +//صرف ایک بار کال کیا گیا +useEffect(async () => { + //TODO: نافذ کریں +}, []) + +function addSmartContractListener() { + //TODO: نافذ کریں +} + +function addWalletListener() { + //TODO: نافذ کریں +} + +const connectWalletPressed = async () => { + //TODO: نافذ کریں +} + +const onUpdatePressed = async () => { + //TODO: نافذ کریں +} +``` + +- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html)- یہ ایک React ہک ہے جسے آپ کے جزو کے رینڈر ہونے کے بعد کال کیا جاتا ہے۔ کیونکہ اس میں ایک خالی سرنی `[]` پراپ پاس کی گئی ہے (لائن 4 دیکھیں)، اسے صرف جزو کے _پہلے_ رینڈر پر کال کیا جائے گا۔ یہاں ہم اپنے اسمارٹ کنٹریکٹ میں محفوظ موجودہ پیغام کو لوڈ کریں گے، اپنے اسمارٹ کنٹریکٹ اور والیٹ سننے والوں کو کال کریں گے، اور اپنے UI کو اپ ڈیٹ کریں گے تاکہ یہ ظاہر ہو کہ آیا والیٹ پہلے سے جڑا ہوا ہے۔ +- `addSmartContractListener`- یہ فنکشن ایک سننے والا سیٹ اپ کرتا ہے جو ہمارے HelloWorld کنٹریکٹ کے `UpdatedMessages` ایونٹ کو دیکھے گا اور جب ہمارے اسمارٹ کنٹریکٹ میں پیغام تبدیل ہو جائے گا تو ہمارے UI کو اپ ڈیٹ کرے گا۔ +- `addWalletListener`- یہ فنکشن ایک سننے والا سیٹ اپ کرتا ہے جو صارف کے MetaMask والیٹ کی حالت میں تبدیلیوں کا پتہ لگاتا ہے، جیسے کہ جب صارف اپنا والیٹ منقطع کرتا ہے یا پتے تبدیل کرتا ہے۔ +- `connectWalletPressed`- اس فنکشن کو صارف کے MetaMask والیٹ کو ہمارے dapp سے جوڑنے کے لیے کال کیا جائے گا۔ +- `onUpdatePressed` - اس فنکشن کو اس وقت کال کیا جائے گا جب صارف اسمارٹ کنٹریکٹ میں محفوظ پیغام کو اپ ڈیٹ کرنا چاہے گا۔ + +اس فائل کے آخر کے قریب، ہمارے پاس ہمارے کمپونینٹ کا UI ہے۔ + +```javascript +// HelloWorld.js + +//ہمارے جزو کا UI +return ( +
+ + + +

موجودہ پیغام:

+

{message}

+ +

نیا پیغام:

+ +
+ setNewMessage(e.target.value)} + value={newMessage} + /> +

{status}

+ + +
+ +
+) +``` + +اگر آپ اس کوڈ کو احتیاط سے اسکین کرتے ہیں، تو آپ دیکھیں گے کہ ہم اپنے UI میں اپنے مختلف ریاستی متغیرات کہاں استعمال کرتے ہیں: + +- لائن 6-12 پر، اگر صارف کا والیٹ جڑا ہوا ہے (یعنی، `walletAddress.length > 0`)، تو ہم ID "walletButton" والے بٹن میں صارف کے `walletAddress` کا ایک چھوٹا ورژن دکھاتے ہیں؛ ورنہ یہ صرف "والیٹ جوڑیں" کہتا ہے۔ +- لائن 17 پر، ہم اسمارٹ کنٹریکٹ میں محفوظ موجودہ پیغام دکھاتے ہیں، جو `message` اسٹرنگ میں پکڑا گیا ہے۔ +- لائن 23-26 پر، ہم اپنے `newMessage` ریاستی متغیر کو اپ ڈیٹ کرنے کے لیے ایک [کنٹرولڈ جزو](https://legacy.reactjs.org/docs/forms.html#controlled-components) استعمال کرتے ہیں جب ٹیکسٹ فیلڈ میں ان پٹ تبدیل ہوتا ہے۔ + +ہمارے ریاستی متغیرات کے علاوہ، آپ یہ بھی دیکھیں گے کہ `connectWalletPressed` اور `onUpdatePressed` افعال کو اس وقت کال کیا جاتا ہے جب IDs `publishButton` اور `walletButton` والے بٹنوں پر بالترتیب کلک کیا جاتا ہے۔ + +آخر میں، آئیے اس بات پر توجہ دیں کہ یہ `HelloWorld.js` جزو کہاں شامل کیا گیا ہے۔ + +اگر آپ `App.js` فائل پر جاتے ہیں، جو React میں مرکزی جزو ہے جو دیگر تمام اجزاء کے لیے کنٹینر کے طور پر کام کرتا ہے، تو آپ دیکھیں گے کہ ہمارا `HelloWorld.js` جزو لائن 7 پر داخل کیا گیا ہے۔ + +آخری لیکن کم از کم، آئیے ایک اور فائل چیک کریں جو آپ کے لیے فراہم کی گئی ہے، `interact.js` فائل۔ + +#### `interact.js` فائل {#the-interact-js-file} + +چونکہ ہم [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) پیراڈائم کی پیروی کرنا چاہتے ہیں، ہم ایک الگ فائل چاہیں گے جس میں ہمارے dapp کی منطق، ڈیٹا، اور قوانین کا انتظام کرنے کے لیے ہمارے تمام افعال شامل ہوں، اور پھر ان افعال کو ہمارے فرنٹ اینڈ (ہمارا `HelloWorld.js` جزو) میں برآمد کرنے کے قابل ہوں۔ + +👆🏽یہ ہماری `interact.js` فائل کا عین مقصد ہے! + +اپنی `src` ڈائرکٹری میں `util` فولڈر پر جائیں، اور آپ دیکھیں گے کہ ہم نے `interact.js` نامی ایک فائل شامل کی ہے جس میں ہمارے تمام اسمارٹ کنٹریکٹ تعامل اور والیٹ افعال اور متغیرات شامل ہوں گے۔ + +```javascript +// interact.js + +//export const helloWorldContract; + +export const loadCurrentMessage = async () => {} + +export const connectWallet = async () => {} + +const getCurrentWalletConnected = async () => {} + +export const updateMessage = async (message) => {} +``` + +آپ دیکھیں گے کہ فائل کے اوپری حصے میں، ہم نے `helloWorldContract` آبجیکٹ پر تبصرہ کیا ہے۔ بعد میں اس ٹیوٹوریل میں، ہم اس آبجیکٹ کو غیر تبصرہ کریں گے اور اس متغیر میں اپنے اسمارٹ کنٹریکٹ کو انسٹینٹی ایٹ کریں گے، جسے ہم پھر اپنے `HelloWorld.js` جزو میں برآمد کریں گے۔ + +ہمارے `helloWorldContract` آبجیکٹ کے بعد چار غیر نافذ شدہ افعال درج ذیل کام کرتے ہیں: + +- `loadCurrentMessage` - یہ فنکشن اسمارٹ کنٹریکٹ میں محفوظ موجودہ پیغام کو لوڈ کرنے کی منطق کو سنبھالتا ہے۔ یہ [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3) کا استعمال کرتے ہوئے ہیلو ورلڈ اسمارٹ کنٹریکٹ پر ایک _ریڈ_ کال کرے گا۔ +- `connectWallet` - یہ فنکشن صارف کے MetaMask کو ہمارے dapp سے جوڑے گا۔ +- `getCurrentWalletConnected` - یہ فنکشن چیک کرے گا کہ آیا کوئی Ethereum اکاؤنٹ پہلے سے ہی صفحہ لوڈ پر ہمارے dapp سے جڑا ہوا ہے اور ہمارے UI کو اسی کے مطابق اپ ڈیٹ کرے گا۔ +- `updateMessage` - یہ فنکشن اسمارٹ کنٹریکٹ میں محفوظ پیغام کو اپ ڈیٹ کرے گا۔ یہ ہیلو ورلڈ اسمارٹ کنٹریکٹ پر ایک _رائٹ_ کال کرے گا، لہذا صارف کے MetaMask والیٹ کو پیغام کو اپ ڈیٹ کرنے کے لیے ایک Ethereum ٹرانزیکشن پر دستخط کرنا ہوگا۔ + +اب جب کہ ہم سمجھ گئے ہیں کہ ہم کس کے ساتھ کام کر رہے ہیں، آئیے یہ معلوم کریں کہ اپنے اسمارٹ کنٹریکٹ سے کیسے پڑھا جائے! + +### مرحلہ 3: اپنے اسمارٹ کنٹریکٹ سے پڑھیں {#step-3-read-from-your-smart-contract} + +اپنے اسمارٹ کنٹریکٹ سے پڑھنے کے لیے، آپ کو کامیابی سے سیٹ اپ کرنے کی ضرورت ہوگی: + +- Ethereum چین سے ایک API کنکشن +- آپ کے اسمارٹ کنٹریکٹ کی ایک لوڈ شدہ مثال +- آپ کے اسمارٹ کنٹریکٹ فنکشن کو کال کرنے کے لیے ایک فنکشن +- ایک سننے والا جو اپ ڈیٹس کے لیے دیکھتا ہے جب آپ اسمارٹ کنٹریکٹ سے پڑھ رہے ڈیٹا میں تبدیلی آتی ہے + +یہ بہت سارے مراحل لگ سکتے ہیں، لیکن فکر نہ کریں! ہم آپ کو ہر ایک کو قدم بہ قدم کرنے کا طریقہ بتائیں گے! :\) + +#### Ethereum چین سے ایک API کنکشن قائم کریں {#establish-an-api-connection-to-the-ethereum-chain} + +تو یاد ہے کہ اس ٹیوٹوریل کے حصہ 2 میں، ہم نے اپنے اسمارٹ کنٹریکٹ سے پڑھنے کے لیے اپنی [Alchemy Web3 کلید کا استعمال کیا تھا](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)؟ آپ کو اپنے dapp میں چین سے پڑھنے کے لیے بھی ایک Alchemy Web3 کلید کی ضرورت ہوگی۔ + +اگر آپ کے پاس یہ پہلے سے نہیں ہے، تو پہلے [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) انسٹال کریں، اپنی `starter-files` کی روٹ ڈائرکٹری پر جائیں اور اپنے ٹرمینل میں درج ذیل کو چلائیں: + +```text +npm install @alch/alchemy-web3 +``` + +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) [Web3.js](https://docs.web3js.org/) کے ارد گرد ایک ریپر ہے، جو بہتر API طریقے اور دیگر اہم فوائد فراہم کرتا ہے تاکہ آپ کی زندگی کو ایک web3 ڈیولپر کے طور پر آسان بنایا جا سکے۔ یہ کم سے کم کنفیگریشن کی ضرورت کے لیے ڈیزائن کیا گیا ہے تاکہ آپ اسے اپنی ایپ میں فوراً استعمال کرنا شروع کر سکیں! + +پھر، اپنے پروجیکٹ ڈائرکٹری میں [dotenv](https://www.npmjs.com/package/dotenv) پیکیج انسٹال کریں، تاکہ ہمارے پاس اپنی API کلید کو حاصل کرنے کے بعد اسے محفوظ کرنے کے لیے ایک محفوظ جگہ ہو۔ + +```text +npm install dotenv --save +``` + +ہمارے dapp کے لیے، **ہم اپنی HTTP API کلید کے بجائے اپنی Websockets API کلید کا استعمال کریں گے**، کیونکہ یہ ہمیں ایک سننے والا سیٹ اپ کرنے کی اجازت دے گا جو اس وقت پتہ لگاتا ہے جب اسمارٹ کنٹریکٹ میں محفوظ پیغام تبدیل ہوتا ہے۔ + +ایک بار جب آپ کے پاس اپنی API کلید ہو، تو اپنی روٹ ڈائرکٹری میں ایک `.env` فائل بنائیں اور اس میں اپنا Alchemy Websockets url شامل کریں۔ اس کے بعد، آپ کی `.env` فائل اس طرح نظر آنی چاہیے: + +```javascript +REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ +``` + +اب، ہم اپنے dapp میں اپنا Alchemy Web3 اینڈ پوائنٹ سیٹ اپ کرنے کے لیے تیار ہیں! آئیے اپنی `interact.js` پر واپس جائیں، جو ہمارے `util` فولڈر کے اندر نیسٹڈ ہے اور فائل کے اوپری حصے میں درج ذیل کوڈ شامل کریں: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +//export const helloWorldContract; +``` + +اوپر، ہم نے پہلے اپنی `.env` فائل سے Alchemy کلید درآمد کی اور پھر اپنا Alchemy Web3 اینڈ پوائنٹ قائم کرنے کے لیے اپنی `alchemyKey` کو `createAlchemyWeb3` میں پاس کیا۔ + +اس اینڈ پوائنٹ کے تیار ہونے کے ساتھ، اب وقت آگیا ہے کہ ہم اپنا اسمارٹ کنٹریکٹ لوڈ کریں! + +#### اپنا ہیلو ورلڈ اسمارٹ کنٹریکٹ لوڈ کرنا {#loading-your-hello-world-smart-contract} + +اپنے ہیلو ورلڈ اسمارٹ کنٹریکٹ کو لوڈ کرنے کے لیے، آپ کو اس کا کنٹریکٹ ایڈریس اور ABI کی ضرورت ہوگی، جو دونوں Etherscan پر مل سکتے ہیں اگر آپ نے [اس ٹیوٹوریل کا حصہ 3](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) مکمل کیا ہو۔ + +#### Etherscan سے اپنا کنٹریکٹ ABI کیسے حاصل کریں {#how-to-get-your-contract-abi-from-etherscan} + +اگر آپ نے اس ٹیوٹوریل کا حصہ 3 چھوڑ دیا ہے، تو آپ HelloWorld کنٹریکٹ کا استعمال کر سکتے ہیں جس کا ایڈریس [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) ہے۔ اس کا ABI [یہاں](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) پایا جا سکتا ہے۔ + +ایک کنٹریکٹ ABI اس بات کی وضاحت کے لیے ضروری ہے کہ کنٹریکٹ کس فنکشن کو کال کرے گا اور یہ بھی یقینی بناتا ہے کہ فنکشن آپ کی توقع کے مطابق فارمیٹ میں ڈیٹا واپس کرے گا۔ ایک بار جب ہم اپنا کنٹریکٹ ABI کاپی کر لیں، تو آئیے اسے اپنی `src` ڈائرکٹری میں `contract-abi.json` نامی JSON فائل کے طور پر محفوظ کریں۔ + +آپ کی contract-abi.json فائل آپ کی src فولڈر میں محفوظ ہونی چاہیے۔ + +ہمارے کنٹریکٹ ایڈریس، ABI، اور Alchemy Web3 اینڈ پوائنٹ سے لیس، ہم اپنے اسمارٹ کنٹریکٹ کی ایک مثال لوڈ کرنے کے لیے [کنٹریکٹ میتھڈ](https://docs.web3js.org/api/web3-eth-contract/class/Contract) کا استعمال کر سکتے ہیں۔ `interact.js` فائل میں اپنا کنٹریکٹ ABI درآمد کریں اور اپنا کنٹریکٹ ایڈریس شامل کریں۔ + +```javascript +// interact.js + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" +``` + +اب ہم آخر کار اپنے `helloWorldContract` متغیر کو غیر تبصرہ کر سکتے ہیں، اور اپنے AlchemyWeb3 اینڈ پوائنٹ کا استعمال کرتے ہوئے اسمارٹ کنٹریکٹ کو لوڈ کر سکتے ہیں: + +```javascript +// interact.js +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +خلاصہ کرنے کے لیے، آپ کی `interact.js` کی پہلی 12 لائنیں اب اس طرح نظر آنی چاہئیں: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" + +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +اب جب کہ ہمارا کنٹریکٹ لوڈ ہو گیا ہے، ہم اپنا `loadCurrentMessage` فنکشن نافذ کر سکتے ہیں! + +#### اپنی `interact.js` فائل میں `loadCurrentMessage` کو نافذ کرنا {#implementing-loadCurrentMessage-in-your-interact-js-file} + +یہ فنکشن بہت سادہ ہے۔ ہم اپنے کنٹریکٹ سے پڑھنے کے لیے ایک سادہ غیر مطابقت پذیر web3 کال کریں گے۔ ہمارا فنکشن اسمارٹ کنٹریکٹ میں محفوظ پیغام کو واپس کرے گا: + +اپنی `interact.js` فائل میں `loadCurrentMessage` کو درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// interact.js + +export const loadCurrentMessage = async () => { + const message = await helloWorldContract.methods.message().call() + return message +} +``` + +چونکہ ہم اس اسمارٹ کنٹریکٹ کو اپنے UI میں دکھانا چاہتے ہیں، آئیے اپنے `HelloWorld.js` جزو میں `useEffect` فنکشن کو درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// HelloWorld.js + +//صرف ایک بار کال کیا گیا +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) +}, []) +``` + +نوٹ کریں، ہم صرف یہ چاہتے ہیں کہ ہمارا `loadCurrentMessage` جزو کے پہلے رینڈر کے دوران ایک بار کال کیا جائے۔ ہم جلد ہی `addSmartContractListener` نافذ کریں گے تاکہ اسمارٹ کنٹریکٹ میں پیغام تبدیل ہونے کے بعد UI خود بخود اپ ڈیٹ ہو جائے۔ + +اس سے پہلے کہ ہم اپنے سننے والے میں غوطہ لگائیں، آئیے دیکھتے ہیں کہ ہمارے پاس اب تک کیا ہے۔ اپنی `HelloWorld.js` اور `interact.js` فائلیں محفوظ کریں، اور پھر [http://localhost:3000/](http://localhost:3000/) پر جائیں۔ + +آپ دیکھیں گے کہ موجودہ پیغام اب "نیٹ ورک سے کوئی کنکشن نہیں ہے" نہیں کہتا۔ اس کے بجائے یہ اسمارٹ کنٹریکٹ میں محفوظ پیغام کی عکاسی کرتا ہے۔ زبردست! + +#### آپ کا UI اب اسمارٹ کنٹریکٹ میں محفوظ پیغام کی عکاسی کرنا چاہئے {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} + +اب اس سننے والے کی بات کرتے ہیں... + +#### `addSmartContractListener` نافذ کریں {#implement-addsmartcontractlistener} + +اگر آپ اس ٹیوٹوریل سیریز کے [حصہ 1](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract) میں لکھی گئی `HelloWorld.sol` فائل کو یاد کریں، تو آپ کو یاد ہوگا کہ `UpdatedMessages` نامی ایک اسمارٹ کنٹریکٹ ایونٹ ہے جو ہمارے اسمارٹ کنٹریکٹ کے `update` فنکشن کو کال کرنے کے بعد خارج ہوتا ہے (لائن 9 اور 27 دیکھیں): + +```javascript +// HelloWorld.sol + +// Solidity کے ورژن کی وضاحت کرتا ہے، سیمنٹک ورژننگ کا استعمال کرتے ہوئے۔ +// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.7.3; + +// `HelloWorld` نامی ایک کنٹریکٹ کی وضاحت کرتا ہے۔ +// ایک کنٹریکٹ فنکشنز اور ڈیٹا (اس کی حالت) کا ایک مجموعہ ہے۔ ایک بار ڈیپلائے ہونے کے بعد، ایک کنٹریکٹ Ethereum بلاک چین پر ایک مخصوص ایڈریس پر رہتا ہے۔ مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + //اپ ڈیٹ فنکشن کال ہونے پر جاری کیا جاتا ہے + //اسمارٹ کنٹریکٹ ایونٹس آپ کے کنٹریکٹ کے لیے یہ بتانے کا ایک طریقہ ہیں کہ بلاک چین پر آپ کے ایپ فرنٹ اینڈ پر کچھ ہوا ہے، جو کچھ ایونٹس کے لیے 'سن' سکتا ہے اور جب وہ ہوتے ہیں تو کارروائی کر سکتا ہے۔ + event UpdatedMessages(string oldStr, string newStr); + + // `string` قسم کے `message` نامی ایک اسٹیٹ متغیر کا اعلان کرتا ہے۔ + // اسٹیٹ متغیرات وہ متغیرات ہیں جن کی قدریں کنٹریکٹ اسٹوریج میں مستقل طور پر محفوظ ہوتی ہیں۔ کلیدی لفظ `public` متغیرات کو کنٹریکٹ کے باہر سے قابل رسائی بناتا ہے اور ایک فنکشن بناتا ہے جسے دوسرے کنٹریکٹس یا کلائنٹس قدر تک رسائی کے لیے کال کر سکتے ہیں۔ + string public message; + + // بہت سی کلاس پر مبنی آبجیکٹ اورینٹڈ زبانوں کی طرح، ایک کنسٹرکٹر ایک خاص فنکشن ہے جو صرف کنٹریکٹ کی تخلیق پر عمل میں لایا جاتا ہے۔ + // کنسٹرکٹرز کا استعمال کنٹریکٹ کے ڈیٹا کو شروع کرنے کے لیے کیا جاتا ہے۔ مزید جانیں:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // ایک اسٹرنگ آرگیومنٹ `initMessage` کو قبول کرتا ہے اور قدر کو کنٹریکٹ کے `message` اسٹوریج متغیر میں سیٹ کرتا ہے۔ + message = initMessage; + } + + // ایک عوامی فنکشن جو ایک اسٹرنگ آرگیومنٹ کو قبول کرتا ہے اور `message` اسٹوریج متغیر کو اپ ڈیٹ کرتا ہے۔ + function update(string memory newMessage) public { + string memory oldMsg = message; + message = newMessage; + emit UpdatedMessages(oldMsg, newMessage); + } +} +``` + +اسمارٹ کنٹریکٹ ایونٹس آپ کے کنٹریکٹ کے لیے یہ بتانے کا ایک طریقہ ہیں کہ بلاک چین پر کچھ ہوا ہے (یعنی، ایک _ایونٹ_ تھا) آپ کی فرنٹ اینڈ ایپلیکیشن کو، جو مخصوص ایونٹس کے لیے 'سن' سکتی ہے اور جب وہ ہوتے ہیں تو کارروائی کر سکتی ہے۔ + +`addSmartContractListener` فنکشن خاص طور پر ہمارے ہیلو ورلڈ اسمارٹ کنٹریکٹ کے `UpdatedMessages` ایونٹ کو سنے گا، اور ہمارے UI کو نیا پیغام دکھانے کے لیے اپ ڈیٹ کرے گا۔ + +`addSmartContractListener` کو درج ذیل میں تبدیل کریں: + +```javascript +// HelloWorld.js + +function addSmartContractListener() { + helloWorldContract.events.UpdatedMessages({}, (error, data) => { + if (error) { + setStatus("😥 " + error.message) + } else { + setMessage(data.returnValues[1]) + setNewMessage("") + setStatus("🎉 آپ کا پیغام اپ ڈیٹ ہو گیا ہے!") + } + }) +} +``` + +آئیے دیکھتے ہیں کہ جب سننے والا کسی ایونٹ کا پتہ لگاتا ہے تو کیا ہوتا ہے: + +- اگر ایونٹ کے خارج ہونے پر کوئی خرابی ہوتی ہے، تو یہ ہمارے `status` ریاستی متغیر کے ذریعے UI میں ظاہر ہوگی۔ +- ورنہ، ہم واپس کیے گئے `data` آبجیکٹ کا استعمال کریں گے۔ `data.returnValues` ایک صفر پر انڈیکس شدہ سرنی ہے جہاں سرنی میں پہلا عنصر پچھلا پیغام اور دوسرا عنصر اپ ڈیٹ شدہ پیغام کو محفوظ کرتا ہے۔ مجموعی طور پر، ایک کامیاب ایونٹ پر ہم اپنی `message` اسٹرنگ کو اپ ڈیٹ شدہ پیغام پر سیٹ کریں گے، `newMessage` اسٹرنگ کو صاف کریں گے، اور اپنی `status` ریاستی متغیر کو اپ ڈیٹ کریں گے تاکہ یہ ظاہر ہو کہ ہمارے اسمارٹ کنٹریکٹ پر ایک نیا پیغام شائع ہوا ہے۔ + +آخر میں، آئیے اپنے `useEffect` فنکشن میں اپنے سننے والے کو کال کریں تاکہ یہ `HelloWorld.js` جزو کے پہلے رینڈر پر شروع ہو۔ مجموعی طور پر، آپ کا `useEffect` فنکشن اس طرح نظر آنا چاہیے: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() +}, []) +``` + +اب جب کہ ہم اپنے اسمارٹ کنٹریکٹ سے پڑھنے کے قابل ہیں، یہ بہت اچھا ہوگا کہ یہ معلوم کیا جائے کہ اس پر کیسے لکھا جائے! تاہم، اپنے dapp پر لکھنے کے لیے، ہمارے پاس پہلے ایک Ethereum والیٹ اس سے جڑا ہونا چاہیے۔ + +لہذا، اگلا ہم اپنا Ethereum والیٹ (MetaMask) سیٹ اپ کرنے اور پھر اسے اپنے dapp سے جوڑنے کا کام کریں گے! + +### مرحلہ 4: اپنا Ethereum والیٹ سیٹ اپ کریں {#step-4-set-up-your-ethereum-wallet} + +Ethereum چین پر کچھ بھی لکھنے کے لیے، صارفین کو اپنی ورچوئل والیٹ کی پرائیویٹ کیز کا استعمال کرتے ہوئے ٹرانزیکشنز پر دستخط کرنا ہوگا۔ اس ٹیوٹوریل کے لیے، ہم [MetaMask](https://metamask.io/) کا استعمال کریں گے، جو براؤزر میں ایک ورچوئل والیٹ ہے جو آپ کے Ethereum اکاؤنٹ کے پتے کا انتظام کرنے کے لیے استعمال ہوتا ہے، کیونکہ یہ اس ٹرانزیکشن پر دستخط کو آخری صارف کے لیے بہت آسان بنا دیتا ہے۔ + +اگر آپ یہ سمجھنا چاہتے ہیں کہ Ethereum پر ٹرانزیکشنز کیسے کام کرتی ہیں، تو Ethereum فاؤنڈیشن کا [یہ صفحہ](/developers/docs/transactions/) دیکھیں۔ + +#### MetaMask ڈاؤن لوڈ کریں {#download-metamask} + +آپ [یہاں](https://metamask.io/download) مفت میں MetaMask اکاؤنٹ ڈاؤن لوڈ اور بنا سکتے ہیں۔ جب آپ ایک اکاؤنٹ بنا رہے ہوں، یا اگر آپ کے پاس پہلے سے ہی ایک اکاؤنٹ ہے، تو یقینی بنائیں کہ اوپری دائیں کونے میں "Goerli ٹیسٹ نیٹ ورک" پر سوئچ کریں (تاکہ ہم اصلی پیسے سے نمٹ نہ رہے ہوں)۔ + +#### ایک فوسیٹ سے ایتھر شامل کریں {#add-ether-from-a-faucet} + +Ethereum بلاک چین پر ایک ٹرانزیکشن پر دستخط کرنے کے لیے، ہمیں کچھ جعلی Eth کی ضرورت ہوگی۔ Eth حاصل کرنے کے لیے آپ [FaucETH](https://fauceth.komputing.org) پر جا سکتے ہیں اور اپنا Goerli اکاؤنٹ ایڈریس درج کر سکتے ہیں، "فنڈز کی درخواست کریں" پر کلک کریں، پھر ڈراپ ڈاؤن میں "Ethereum Testnet Goerli" منتخب کریں اور آخر میں "فنڈز کی درخواست کریں" بٹن کو دوبارہ کلک کریں۔ اس کے فوراً بعد آپ کو اپنے MetaMask اکاؤنٹ میں Eth نظر آنا چاہیے! + +#### اپنا بیلنس چیک کریں {#check-your-balance} + +ہمارا بیلنس موجود ہے یا نہیں اس کی دوبارہ جانچ کرنے کے لیے، آئیے [Alchemy کے کمپوزر ٹول](https://composer.alchemyapi.io/?composer_state=%7B%22network%22%3A0%2C%22methodName%22%3A%22eth_getBalance%22%2C%22paramValues%22%3A%5B%22%22%2C%22latest%22%5D%7D) کا استعمال کرتے ہوئے ایک [eth_getBalance](https://docs.alchemyapi.io/alchemy/documentation/alchemy-api-reference/json-rpc#eth_getbalance) کی درخواست کریں۔ یہ ہمارے والیٹ میں Eth کی رقم واپس کرے گا۔ اپنے MetaMask اکاؤنٹ کا ایڈریس درج کرنے اور "Send Request" پر کلک کرنے کے بعد، آپ کو اس طرح کا جواب نظر آنا چاہیے: + +```text +{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"} +``` + +**نوٹ:** یہ نتیجہ wei میں ہے eth میں نہیں۔ Wei کو ایتھر کی سب سے چھوٹی اکائی کے طور پر استعمال کیا جاتا ہے۔ wei سے eth میں تبدیلی یہ ہے: 1 eth = 10¹⁸ wei۔ تو اگر ہم 0xde0b6b3a7640000 کو اعشاریہ میں تبدیل کرتے ہیں تو ہمیں 1\*10¹⁸ ملتا ہے جو 1 eth کے برابر ہے۔ + +اف! ہمارا جعلی پیسہ سب وہیں ہے! 🤑 + +### مرحلہ 5: MetaMask کو اپنے UI سے جوڑیں {#step-5-connect-metamask-to-your-UI} + +اب جب کہ ہمارا MetaMask والیٹ سیٹ اپ ہو گیا ہے، آئیے اپنے dApp کو اس سے جوڑتے ہیں! + +#### `connectWallet` فنکشن {#the-connectWallet-function} + +ہماری `interact.js` فائل میں، آئیے `connectWallet` فنکشن کو نافذ کریں، جسے ہم پھر اپنے `HelloWorld.js` جزو میں کال کر سکتے ہیں۔ + +آئیے `connectWallet` کو درج ذیل میں تبدیل کریں: + +```javascript +// interact.js + +export const connectWallet = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_requestAccounts", + }) + const obj = { + status: "👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔", + address: addressArray[0], + } + return obj + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

+ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +

+
+ ), + } + } +} +``` + +تو کوڈ کا یہ بڑا بلاک بالکل کیا کرتا ہے؟ + +پہلے، یہ چیک کرتا ہے کہ آیا آپ کے براؤزر میں `window.ethereum` فعال ہے۔ + +`window.ethereum` MetaMask اور دیگر والیٹ فراہم کنندگان کے ذریعے انجیکٹ کردہ ایک عالمی API ہے جو ویب سائٹس کو صارفین کے Ethereum اکاؤنٹس کی درخواست کرنے کی اجازت دیتا ہے۔ اگر منظور ہو جائے، تو یہ ان بلاک چینز سے ڈیٹا پڑھ سکتا ہے جن سے صارف جڑا ہوا ہے، اور صارف کو پیغامات اور ٹرانزیکشنز پر دستخط کرنے کا مشورہ دے سکتا ہے۔ مزید معلومات کے لیے [MetaMask دستاویزات](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) دیکھیں! + +اگر `window.ethereum` موجود _نہیں_ ہے، تو اس کا مطلب ہے کہ MetaMask انسٹال نہیں ہے۔ اس کے نتیجے میں ایک JSON آبجیکٹ واپس کیا جاتا ہے، جہاں واپس کیا گیا `address` ایک خالی اسٹرنگ ہوتا ہے، اور `status` JSX آبجیکٹ یہ بتاتا ہے کہ صارف کو MetaMask انسٹال کرنا ہوگا۔ + +اب اگر `window.ethereum` موجود _ہے_، تو یہ وہ جگہ ہے جہاں چیزیں دلچسپ ہو جاتی ہیں۔ + +ایک try/catch لوپ کا استعمال کرتے ہوئے، ہم [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) کو کال کرکے MetaMask سے جڑنے کی کوشش کریں گے۔ اس فنکشن کو کال کرنے سے براؤزر میں MetaMask کھل جائے گا، جس کے تحت صارف سے اپنے والیٹ کو آپ کے dApp سے جوڑنے کا کہا جائے گا۔ + +- اگر صارف جڑنے کا انتخاب کرتا ہے، تو `method: "eth_requestAccounts"` ایک سرنی واپس کرے گا جس میں صارف کے تمام اکاؤنٹ پتے شامل ہوں گے جو dapp سے جڑے ہوئے ہیں۔ مجموعی طور پر، ہمارا `connectWallet` فنکشن ایک JSON آبجیکٹ واپس کرے گا جس میں اس اری کا _پہلا_ `address` (لائن 9 دیکھیں) اور ایک `status` پیغام ہوگا جو صارف کو اسمارٹ کنٹریکٹ کے لیے ایک پیغام لکھنے کا کہے گا۔ +- اگر صارف کنکشن کو مسترد کر دیتا ہے، تو JSON آبجیکٹ میں واپس کیے گئے `address` کے لیے ایک خالی اسٹرنگ اور ایک `status` پیغام ہوگا جو یہ ظاہر کرے گا کہ صارف نے کنکشن کو مسترد کر دیا ہے۔ + +اب جب کہ ہم نے یہ `connectWallet` فنکشن لکھ لیا ہے، اگلا مرحلہ اسے اپنے `HelloWorld.js` جزو میں کال کرنا ہے۔ + +#### `connectWallet` فنکشن کو اپنے `HelloWorld.js` UI جزو میں شامل کریں {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +`HelloWorld.js` میں `connectWalletPressed` فنکشن پر جائیں، اور اسے درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +نوٹ کریں کہ ہماری زیادہ تر فعالیت `interact.js` فائل سے ہمارے `HelloWorld.js` جزو سے کس طرح تجرید کی گئی ہے؟ یہ اس لیے ہے تاکہ ہم M-V-C پیراڈائم کی تعمیل کریں! + +`connectWalletPressed` میں، ہم صرف اپنے امپورٹ کردہ `connectWallet` فنکشن پر ایک await کال کرتے ہیں، اور اس کے جواب کا استعمال کرتے ہوئے، ہم اپنے `status` اور `walletAddress` متغیرات کو ان کے اسٹیٹ ہکس کے ذریعے اپ ڈیٹ کرتے ہیں۔ + +اب، آئیے دونوں فائلیں (`HelloWorld.js` اور `interact.js`) محفوظ کریں اور اب تک اپنے UI کی جانچ کریں۔ + +[http://localhost:3000/](http://localhost:3000/) صفحے پر اپنا براؤزر کھولیں، اور صفحے کے اوپری دائیں کونے میں "والیٹ جوڑیں" بٹن دبائیں۔ + +اگر آپ نے MetaMask انسٹال کیا ہوا ہے، تو آپ سے اپنے والیٹ کو اپنے dApp سے جوڑنے کا کہا جائے گا۔ جڑنے کی دعوت قبول کریں۔ + +آپ کو دیکھنا چاہئے کہ والیٹ بٹن اب یہ ظاہر کرتا ہے کہ آپ کا پتہ جڑا ہوا ہے! بہت خوب 🔥 + +اگلا، صفحہ کو ریفریش کرنے کی کوشش کریں... یہ عجیب ہے۔ ہمارا والیٹ بٹن ہمیں MetaMask سے جڑنے کا کہہ رہا ہے، حالانکہ یہ پہلے سے ہی جڑا ہوا ہے... + +تاہم، کوئی خوف نہیں! ہم اسے آسانی سے حل کر سکتے ہیں (سمجھے؟) `getCurrentWalletConnected` کو نافذ کرکے، جو یہ چیک کرے گا کہ آیا کوئی پتہ پہلے سے ہی ہمارے dapp سے جڑا ہوا ہے اور ہمارے UI کو اسی کے مطابق اپ ڈیٹ کرے گا! + +#### `getCurrentWalletConnected` فنکشن {#the-getcurrentwalletconnected-function} + +`interact.js` فائل میں اپنے `getCurrentWalletConnected` فنکشن کو درج ذیل میں اپ ڈیٹ کریں: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔", + } + } else { + return { + address: "", + status: "🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

+ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +

+
+ ), + } + } +} +``` + +یہ کوڈ _بہت_ ملتا جلتا ہے `connectWallet` فنکشن سے جو ہم نے پچھلے مرحلے میں لکھا تھا۔ + +بنیادی فرق یہ ہے کہ `eth_requestAccounts` میتھڈ کو کال کرنے کے بجائے، جو صارف کے لیے اپنے والیٹ کو جوڑنے کے لیے MetaMask کھولتا ہے، یہاں ہم `eth_accounts` میتھڈ کو کال کرتے ہیں، جو صرف ایک اری واپس کرتا ہے جس میں فی الحال ہمارے dApp سے جڑے ہوئے MetaMask پتے ہوتے ہیں۔ + +اس فنکشن کو عمل میں دیکھنے کے لیے، آئیے اسے اپنے `HelloWorld.js` جزو کے `useEffect` فنکشن میں کال کریں: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +نوٹ کریں، ہم اپنے `walletAddress` اور `status` اسٹیٹ متغیرات کو اپ ڈیٹ کرنے کے لیے `getCurrentWalletConnected` پر اپنی کال کے جواب کا استعمال کرتے ہیں۔ + +اب جب کہ آپ نے یہ کوڈ شامل کر دیا ہے، آئیے اپنے براؤزر ونڈو کو ریفریش کرنے کی کوشش کریں۔ + +بہت اچھے! بٹن کو کہنا چاہیے کہ آپ جڑے ہوئے ہیں، اور آپ کے جڑے ہوئے والیٹ کے پتے کا ایک پیش نظارہ دکھانا چاہیے - یہاں تک کہ آپ کے ریفریش کرنے کے بعد بھی! + +#### `addWalletListener` نافذ کریں {#implement-addwalletlistener} + +ہمارے dApp والیٹ سیٹ اپ کا آخری مرحلہ والیٹ لسنر کو نافذ کرنا ہے تاکہ جب ہمارے والیٹ کی حالت تبدیل ہو تو ہمارا UI اپ ڈیٹ ہو، جیسے جب صارف منقطع ہوتا ہے یا اکاؤنٹس تبدیل کرتا ہے۔ + +اپنی `HelloWorld.js` فائل میں، اپنے `addWalletListener` فنکشن کو درج ذیل میں تبدیل کریں: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔") + } else { + setWallet("") + setStatus("🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔") + } + }) + } else { + setStatus( +

+ {" "} + 🦊 + آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + +

+ ) + } +} +``` + +مجھے شرط ہے کہ آپ کو اس مقام پر کیا ہو رہا ہے یہ سمجھنے کے لیے ہماری مدد کی بھی ضرورت نہیں ہے، لیکن مکمل ہونے کی خاطر، آئیے اسے جلدی سے توڑتے ہیں: + +- سب سے پہلے، ہمارا فنکشن چیک کرتا ہے کہ آیا `window.ethereum` فعال ہے (یعنی، MetaMask انسٹال ہے)۔ + - اگر ایسا نہیں ہے، تو ہم صرف اپنے `status` اسٹیٹ متغیر کو ایک JSX اسٹرنگ پر سیٹ کرتے ہیں جو صارف کو MetaMask انسٹال کرنے کا کہتا ہے۔ + - اگر یہ فعال ہے، تو ہم لائن 3 پر لسنر `window.ethereum.on("accountsChanged")` سیٹ اپ کرتے ہیں جو MetaMask والیٹ میں اسٹیٹ تبدیلیوں کو سنتا ہے، جس میں یہ شامل ہے کہ جب صارف dApp سے ایک اضافی اکاؤنٹ جوڑتا ہے، اکاؤنٹس تبدیل کرتا ہے، یا ایک اکاؤنٹ منقطع کرتا ہے۔ اگر کم از کم ایک اکاؤنٹ جڑا ہوا ہے، تو `walletAddress` اسٹیٹ متغیر کو لسنر کے ذریعے واپس کیے گئے `accounts` اری میں پہلے اکاؤنٹ کے طور پر اپ ڈیٹ کیا جاتا ہے۔ ورنہ، `walletAddress` کو ایک خالی اسٹرنگ کے طور پر سیٹ کیا جاتا ہے۔ + +آخری لیکن کم از کم، ہمیں اسے اپنے `useEffect` فنکشن میں کال کرنا ہوگا: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +اور بس! ہم نے کامیابی سے اپنی تمام والیٹ کی فعالیت کی پروگرامنگ مکمل کر لی ہے! اب اپنے آخری کام کی طرف: اپنے اسمارٹ کنٹریکٹ میں محفوظ پیغام کو اپ ڈیٹ کرنا! + +### مرحلہ 6: `updateMessage` فنکشن نافذ کریں {#step-6-implement-the-updateMessage-function} + +ٹھیک ہے فیم، ہم آخری مرحلے پر پہنچ گئے ہیں! اپنی `interact.js` فائل کے `updateMessage` میں، ہم درج ذیل کام کرنے جا رہے ہیں: + +1. یقینی بنائیں کہ وہ پیغام جسے ہم اپنے اسمارٹ رابطہ میں شائع کرنا چاہتے ہیں، درست ہے +2. MetaMask کا استعمال کرتے ہوئے اپنے ٹرانزیکشن پر دستخط کریں +3. اس فنکشن کو ہمارے `HelloWorld.js` فرنٹ اینڈ جزو سے کال کریں + +اس میں زیادہ وقت نہیں لگے گا؛ آئیے اس dapp کو مکمل کریں! + +#### ان پٹ کی خرابی کو ہینڈل کرنا {#input-error-handling} + +فطری طور پر، فنکشن کے آغاز میں کسی قسم کا ان پٹ ایرر ہینڈلنگ ہونا معنی خیز ہے۔ + +ہم چاہیں گے کہ ہمارا فنکشن جلد واپس آ جائے اگر کوئی MetaMask ایکسٹینشن انسٹال نہیں ہے، کوئی والیٹ جڑا ہوا نہیں ہے (یعنی، پاس کیا گیا `address` ایک خالی اسٹرنگ ہے)، یا `message` ایک خالی اسٹرنگ ہے۔ آئیے `updateMessage` میں درج ذیل ایرر ہینڈلنگ شامل کریں: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 بلاک چین پر پیغام کو اپ ڈیٹ کرنے کے لیے اپنا MetaMask والیٹ جوڑیں۔", + } + } + + if (message.trim() === "") { + return { + status: "❌ آپ کا پیغام خالی اسٹرنگ نہیں ہو سکتا۔", + } + } +} +``` + +اب جب کہ اس میں مناسب ان پٹ ایرر ہینڈلنگ ہے، اب وقت آگیا ہے کہ MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں! + +#### ہمارے ٹرانزیکشن پر دستخط کرنا {#signing-our-transaction} + +اگر آپ پہلے سے ہی روایتی web3 Ethereum ٹرانزیکشنز کے ساتھ آرام دہ ہیں، تو جو کوڈ ہم اگلا لکھیں گے وہ بہت مانوس ہوگا۔ اپنے ان پٹ ایرر ہینڈلنگ کوڈ کے نیچے، `updateMessage` میں درج ذیل شامل کریں: + +```javascript +// interact.js + +//ٹرانزیکشن پیرامیٹرز سیٹ اپ کریں +const transactionParameters = { + to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ + from: address, // صارف کے فعال پتے سے مماثل ہونا چاہئے۔ + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//ٹرانزیکشن پر دستخط کریں +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Etherscan پر اپنے ٹرانزیکشن کی حیثیت دیکھیں! + +
+ ℹ️ ایک بار جب ٹرانزیکشن نیٹ ورک کے ذریعے تصدیق ہو جائے گی، پیغام خود بخود اپ ڈیٹ ہو جائے گا۔ +
+ ), + } +} catch (error) { + return { + status: "😥 " + error.message, + } +} +``` + +آئیے دیکھتے ہیں کہ کیا ہو رہا ہے۔ پہلے، ہم اپنے ٹرانزیکشنز پیرامیٹرز سیٹ اپ کرتے ہیں، جہاں: + +- `to` وصول کنندہ کا پتہ (ہمارا اسمارٹ کنٹریکٹ) بتاتا ہے +- `from` ٹرانزیکشن کے دستخط کنندہ کی وضاحت کرتا ہے، `address` متغیر جسے ہم نے اپنے فنکشن میں پاس کیا تھا +- `data` ہمارے ہیلو ورلڈ اسمارٹ کنٹریکٹ کے `update` میتھڈ کی کال پر مشتمل ہے، جو ہمارے `message` اسٹرنگ متغیر کو ان پٹ کے طور پر حاصل کرتا ہے + +پھر، ہم ایک `window.ethereum.request` کال کا انتظار کرتے ہیں، جہاں ہم MetaMask سے ٹرانزیکشن پر دستخط کرنے کے لیے کہتے ہیں۔ نوٹ کریں، لائن 11 اور 12 پر، ہم اپنے eth میتھڈ، `eth_sendTransaction` کی وضاحت کر رہے ہیں اور اپنے `transactionParameters` کو پاس کر رہے ہیں۔ + +اس مقام پر، MetaMask براؤزر میں کھل جائے گا، اور صارف سے ٹرانزیکشن پر دستخط کرنے یا مسترد کرنے کا کہے گا۔ + +- اگر ٹرانزیکشن کامیاب ہو جاتی ہے، تو فنکشن ایک JSON آبجیکٹ واپس کرے گا جہاں `status` JSX اسٹرنگ صارف کو اپنے ٹرانزیکشن کے بارے میں مزید معلومات کے لیے Etherscan چیک کرنے کا اشارہ دیتی ہے۔ +- اگر ٹرانزیکشن ناکام ہو جاتی ہے، تو فنکشن ایک JSON آبجیکٹ واپس کرے گا جہاں `status` اسٹرنگ خرابی کا پیغام پہنچاتی ہے۔ + +مجموعی طور پر، ہمارا `updateMessage` فنکشن اس طرح نظر آنا چاہیے: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + //ان پٹ ایرر ہینڈلنگ + if (!window.ethereum || address === null) { + return { + status: + "💡 بلاک چین پر پیغام کو اپ ڈیٹ کرنے کے لیے اپنا MetaMask والیٹ جوڑیں۔", + } + } + + if (message.trim() === "") { + return { + status: "❌ آپ کا پیغام خالی اسٹرنگ نہیں ہو سکتا۔", + } + } + + //ٹرانزیکشن پیرامیٹرز سیٹ اپ کریں + const transactionParameters = { + to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ + from: address, // صارف کے فعال پتے سے مماثل ہونا چاہئے۔ + data: helloWorldContract.methods.update(message).encodeABI(), + } + + //ٹرانزیکشن پر دستخط کریں + try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Etherscan پر اپنے ٹرانزیکشن کی حیثیت دیکھیں! + +
+ ℹ️ ایک بار جب ٹرانزیکشن نیٹ ورک کے ذریعے تصدیق ہو جائے گی، پیغام خود بخود اپ ڈیٹ ہو جائے گا۔ +
+ ), + } + } catch (error) { + return { + status: "😥 " + error.message, + } + } +} +``` + +آخری لیکن کم از کم، ہمیں اپنے `updateMessage` فنکشن کو اپنے `HelloWorld.js` جزو سے جوڑنے کی ضرورت ہے۔ + +#### `updateMessage` کو `HelloWorld.js` فرنٹ اینڈ سے جوڑیں {#connect-updatemessage-to-the-helloworld-js-frontend} + +ہمارے `onUpdatePressed` فنکشن کو درآمد شدہ `updateMessage` فنکشن پر ایک await کال کرنی چاہیے اور `status` ریاستی متغیر میں ترمیم کرنی چاہیے تاکہ یہ ظاہر ہو کہ آیا ہمارا ٹرانزیکشن کامیاب ہوا یا ناکام: + +```javascript +// HelloWorld.js + +const onUpdatePressed = async () => { + const { status } = await updateMessage(walletAddress, newMessage) + setStatus(status) +} +``` + +یہ بہت صاف اور سادہ ہے۔ اور اندازہ لگائیں کیا... آپ کا DAPP مکمل ہے!!! + +آگے بڑھیں اور **اپ ڈیٹ** بٹن کو آزمائیں! + +### اپنا کسٹم dapp بنائیں {#make-your-own-custom-dapp} + +واہ، آپ ٹیوٹوریل کے آخر تک پہنچ گئے! خلاصہ کرنے کے لیے، آپ نے سیکھا کہ کیسے: + +- MetaMask والیٹ کو اپنے dapp پروجیکٹ سے جوڑیں +- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API کا استعمال کرتے ہوئے اپنے اسمارٹ کنٹریکٹ سے ڈیٹا پڑھیں +- MetaMask کا استعمال کرتے ہوئے Ethereum ٹرانزیکشنز پر دستخط کریں + +اب آپ اس ٹیوٹوریل کی مہارتوں کو اپنے کسٹم dapp پروجیکٹ کی تعمیر کے لیے استعمال کرنے کے لیے پوری طرح سے لیس ہیں! ہمیشہ کی طرح، اگر آپ کے کوئی سوالات ہیں، تو [Alchemy Discord](https://discord.gg/gWuC7zB) میں مدد کے لیے ہم سے رابطہ کرنے میں ہچکچاہٹ نہ کریں۔ 🧙‍♂️ + +ایک بار جب آپ یہ ٹیوٹوریل مکمل کر لیں، تو ہمیں بتائیں کہ آپ کا تجربہ کیسا رہا یا اگر آپ کے پاس کوئی رائے ہے تو ہمیں ٹویٹر پر [@alchemyplatform](https://twitter.com/AlchemyPlatform) پر ٹیگ کرکے بتائیں! diff --git a/public/content/translations/ur/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/ur/developers/tutorials/hello-world-smart-contract/index.md new file mode 100644 index 00000000000..9fbaff1d609 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/hello-world-smart-contract/index.md @@ -0,0 +1,366 @@ +--- +title: "ابتدائی افراد کے لیے ہیلو ورلڈ اسمارٹ کنٹریکٹ" +description: "Ethereum پر ایک سادہ اسمارٹ کنٹریکٹ لکھنے اور اسے ڈیپلائے کرنے کے بارے میں تعارفی ٹیوٹوریل۔" +author: "elanh" +tags: + [ + "solidity", + "hardhat", + "alchemy", + "اسمارٹ معاہدات", + "تعینات کرنا" + ] +skill: beginner +lang: ur-in +published: 2021-03-31 +--- + +اگر آپ بلاک چین ڈیولپمنٹ میں نئے ہیں اور نہیں جانتے کہ کہاں سے شروع کریں، یا اگر آپ صرف یہ سمجھنا چاہتے ہیں کہ اسمارٹ کنٹریکٹس کو کیسے ڈیپلائے اور ان کے ساتھ کیسے انٹریکٹ کیا جائے، تو یہ گائیڈ آپ کے لیے ہے۔ ہم ایک ورچوئل والیٹ [MetaMask](https://metamask.io/)، [Solidity](https://docs.soliditylang.org/en/v0.8.0/)، [Hardhat](https://hardhat.org/)، اور [Alchemy](https://www.alchemy.com/eth) کا استعمال کرتے ہوئے Sepolia ٹیسٹ نیٹ ورک پر ایک سادہ اسمارٹ کنٹریکٹ بنانے اور اسے ڈیپلائے کرنے کے عمل سے گزریں گے (اگر آپ ابھی تک یہ نہیں سمجھ پائے ہیں کہ ان میں سے کسی کا کیا مطلب ہے تو فکر نہ کریں، ہم اس کی وضاحت کریں گے)۔ + +اس ٹیوٹوریل کے [حصہ 2](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) میں ہم یہ دیکھیں گے کہ ایک بار یہاں ڈیپلائے ہونے کے بعد ہم اپنے اسمارٹ کنٹریکٹ کے ساتھ کیسے انٹریکٹ کر سکتے ہیں، اور [حصہ 3](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) میں ہم اسے Etherscan پر کیسے پبلش کرنا ہے اس پر بات کریں گے۔ + +اگر کسی بھی وقت آپ کے سوالات ہوں تو [Alchemy Discord](https://discord.gg/gWuC7zB) میں بلا جھجھک رابطہ کریں! + +## مرحلہ 1: Ethereum نیٹ ورک سے جڑیں {#step-1} + +Ethereum چین سے درخواستیں کرنے کے بہت سے طریقے ہیں۔ سادگی کے لیے، ہم Alchemy پر ایک مفت اکاؤنٹ استعمال کریں گے، جو ایک بلاک چین ڈیولپر پلیٹ فارم اور API ہے جو ہمیں اپنے نوڈس چلائے بغیر Ethereum چین کے ساتھ بات چیت کرنے کی اجازت دیتا ہے۔ اس پلیٹ فارم میں نگرانی اور تجزیات کے لیے ڈیولپر ٹولز بھی ہیں جن سے ہم اس ٹیوٹوریل میں فائدہ اٹھائیں گے تاکہ یہ سمجھ سکیں کہ ہمارے اسمارٹ کنٹریکٹ کی ڈیپلائمنٹ میں پس پردہ کیا ہو رہا ہے۔ اگر آپ کے پاس پہلے سے Alchemy اکاؤنٹ نہیں ہے، تو [آپ یہاں مفت میں سائن اپ کر سکتے ہیں](https://dashboard.alchemy.com/signup)۔ + +## مرحلہ 2: اپنی ایپ (اور API کلید) بنائیں {#step-2} + +ایک بار جب آپ Alchemy اکاؤنٹ بنا لیں، تو آپ ایک ایپ بنا کر API کلید تیار کر سکتے ہیں۔ یہ ہمیں Sepolia ٹیسٹ نیٹ ورک سے درخواستیں کرنے کی اجازت دے گا۔ اگر آپ ٹیسٹ نیٹس سے واقف نہیں ہیں، تو [یہ صفحہ](/developers/docs/networks/) دیکھیں۔ + +1. نیو بار میں "Select an app" منتخب کرکے اور "Create new app" پر کلک کرکے اپنے Alchemy ڈیش بورڈ میں "Create new app" صفحہ پر جائیں۔ + +![Hello world create app](./hello-world-create-app.png) + +2. اپنی ایپ کو ”Hello World“ کا نام دیں، ایک مختصر تفصیل پیش کریں، اور ایک یوز کیس منتخب کریں، مثلاً، "Infra & Tooling"۔ اگلا، "Ethereum" تلاش کریں اور نیٹ ورک منتخب کریں۔ + +![create app view hello world](./create-app-view-hello-world.png) + +3. آگے بڑھنے کے لیے "Next" پر کلک کریں، پھر ”Create app“ اور بس! آپ کا کام ہو گیا۔ آپ کی ایپ نیو بار ڈراپ ڈاؤن مینو میں ظاہر ہونی چاہیے، جس میں کاپی کرنے کے لیے ایک API کلید دستیاب ہوگی۔ + +## مرحلہ 3: ایک Ethereum اکاؤنٹ (ایڈریس) بنائیں {#step-3} + +ٹرانزیکشنز بھیجنے اور وصول کرنے کے لیے ہمیں ایک Ethereum اکاؤنٹ کی ضرورت ہے۔ اس ٹیوٹوریل کے لیے، ہم MetaMask استعمال کریں گے، جو براؤزر میں ایک ورچوئل والیٹ ہے جو آپ کے Ethereum اکاؤنٹ ایڈریس کو منظم کرنے کے لیے استعمال ہوتا ہے۔ [لین دین](/developers/docs/transactions/) پر مزید۔ + +آپ [یہاں](https://metamask.io/download) سے MetaMask ڈاؤن لوڈ کر سکتے ہیں اور مفت میں ایک Ethereum اکاؤنٹ بنا سکتے ہیں۔ جب آپ ایک اکاؤنٹ بنا رہے ہوں، یا اگر آپ کے پاس پہلے سے ہی ایک اکاؤنٹ ہے، تو یقینی بنائیں کہ آپ نیٹ ورک ڈراپ ڈاؤن مینو کا استعمال کرکے "Sepolia" ٹیسٹ نیٹ ورک پر سوئچ کر لیں (تاکہ ہم حقیقی رقم سے نمٹ نہ رہے ہوں)۔ + +اگر آپ کو فہرست میں Sepolia نظر نہیں آتا، تو مینو میں جائیں، پھر ایڈوانسڈ میں جائیں اور "Show test networks" کو آن کرنے کے لیے نیچے اسکرول کریں۔ نیٹ ورک سلیکشن مینو میں، ٹیسٹ نیٹس کی فہرست تلاش کرنے کے لیے "Custom" ٹیب کا انتخاب کریں اور "Sepolia" کو منتخب کریں۔ + +![metamask sepolia example](./metamask-sepolia-example.png) + +## مرحلہ 4: ایک فوسیٹ سے ایتھر شامل کریں {#step-4} + +اپنے اسمارٹ کنٹریکٹ کو ٹیسٹ نیٹ ورک پر ڈیپلائے کرنے کے لیے، ہمیں کچھ جعلی Eth کی ضرورت ہوگی۔ Sepolia ETH حاصل کرنے کے لیے آپ مختلف فوسیٹس کی فہرست دیکھنے کے لیے [Sepolia نیٹ ورک کی تفصیلات](/developers/docs/networks/#sepolia) پر جا سکتے ہیں۔ اگر کوئی کام نہ کرے تو دوسرا آزمائیں کیونکہ وہ کبھی کبھی خالی ہو سکتے ہیں۔ نیٹ ورک ٹریفک کی وجہ سے آپ کو اپنا جعلی ETH حاصل کرنے میں کچھ وقت لگ سکتا ہے۔ آپ کو جلد ہی اپنے Metamask اکاؤنٹ میں ETH نظر آنا چاہیے! + +## مرحلہ 5: اپنا بیلنس چیک کریں {#step-5} + +یہ یقینی بنانے کے لیے کہ ہمارا بیلنس وہاں ہے، آئیے [Alchemy کے کمپوزر ٹول](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest) کا استعمال کرتے ہوئے ایک [eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance) درخواست کریں۔ یہ ہمارے والیٹ میں ETH کی رقم واپس کرے گا۔ اپنے MetaMask اکاؤنٹ کا ایڈریس درج کرنے اور "Send Request" پر کلک کرنے کے بعد، آپ کو اس طرح کا جواب نظر آنا چاہیے: + +```json +{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } +``` + +> **نوٹ:** یہ نتیجہ ETH میں نہیں بلکہ wei میں ہے۔ Wei کو ایتھر کی سب سے چھوٹی اکائی کے طور پر استعمال کیا جاتا ہے۔ wei سے ETH میں تبدیلی یہ ہے: 1 eth = 1018 wei۔ لہذا اگر ہم 0x2B5E3AF16B1880000 کو ڈیسیمل میں تبدیل کریں تو ہمیں 5\*10¹⁸ ملتا ہے جو 5 ETH کے برابر ہے۔ +> +> اف! ہمارے جعلی پیسے سب وہاں ہیں ۔ + +## مرحلہ 6: ہمارے پروجیکٹ کو شروع کریں {#step-6} + +سب سے پہلے، ہمیں اپنے پروجیکٹ کے لیے ایک فولڈر بنانا ہوگا۔ اپنی کمانڈ لائن پر جائیں اور ٹائپ کریں: + +``` +mkdir hello-world +cd hello-world +``` + +اب جب کہ ہم اپنے پروجیکٹ فولڈر کے اندر ہیں، ہم پروجیکٹ کو شروع کرنے کے لیے `npm init` استعمال کریں گے۔ اگر آپ کے پاس پہلے سے npm انسٹال نہیں ہے، تو [ان ہدایات](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) پر عمل کریں (ہمیں Node.js کی بھی ضرورت ہوگی لہذا اسے بھی ڈاؤن لوڈ کریں!)۔ + +``` +npm init +``` + +اس سے کوئی فرق نہیں پڑتا کہ آپ انسٹالیشن کے سوالات کا جواب کیسے دیتے ہیں، یہاں حوالہ کے لیے ہم نے اسے کیسے کیا: + +``` +پیکیج کا نام: (hello-world) +ورژن: (1.0.0) +تفصیل: hello world smart contract +اینٹری پوائنٹ: (index.js) +ٹیسٹ کمانڈ: +گٹ ریپوزٹری: +کلیدی الفاظ: +مصنف: +لائسنس: (ISC) +/Users/.../.../.../hello-world/package.json میں لکھنے کے بارے میں: + +{ + "name": "hello-world", + "version": "1.0.0", + "description": "hello world smart contract", + "main": "index.js", + "scripts": { + "test": "echo \\"Error: no test specified\\" && exit 1" + }, + "author": "", + "license": "ISC" +} +``` + +package.json کو منظور کریں اور ہم تیار ہیں! + +## مرحلہ 7: [Hardhat](https://hardhat.org/getting-started/#overview) ڈاؤن لوڈ کریں {#step-7} + +Hardhat آپ کے Ethereum سافٹ ویئر کو کمپائل، ڈیپلوئے، ٹیسٹ اور ڈیبگ کرنے کے لیے ایک ڈیولپمنٹ ماحول ہے۔ یہ ڈیولپرز کو لائیو چین پر ڈیپلوئے کرنے سے پہلے مقامی طور پر اسمارٹ کنٹریکٹس اور dapps بنانے میں مدد کرتا ہے۔ + +ہمارے `hello-world` پروجیکٹ کے اندر چلائیں: + +``` +npm install --save-dev hardhat +``` + +[انسٹالیشن کی ہدایات](https://hardhat.org/getting-started/#overview) پر مزید تفصیلات کے لیے یہ صفحہ دیکھیں۔ + +## مرحلہ 8: Hardhat پروجیکٹ بنائیں {#step-8} + +ہمارے پروجیکٹ فولڈر کے اندر چلائیں: + +``` +npx hardhat +``` + +پھر آپ کو ایک خوش آمدیدی پیغام اور یہ منتخب کرنے کا آپشن نظر آئے گا کہ آپ کیا کرنا چاہتے ہیں۔ “create an empty hardhat.config.js” منتخب کریں: + +``` +888 888 888 888 888 +888 888 888 888 888 +888 888 888 888 888 +8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 +888 888 "88b 888P" d88" 888 888 "88b "88b 888 +888 888 .d888888 888 888 888 888 888 .d888888 888 +888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. +888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 + +👷 Hardhat v2.0.11 میں خوش آمدید 👷‍? + +آپ کیا کرنا چاہتے ہیں؟ … +ایک نمونہ پروجیکٹ بنائیں +❯ ایک خالی hardhat.config.js بنائیں +باہر نکلیں +``` + +یہ ہمارے لیے ایک `hardhat.config.js` فائل بنائے گا جہاں ہم اپنے پروجیکٹ کے لیے تمام سیٹ اپ کی وضاحت کریں گے (مرحلہ 13 پر)۔ + +## مرحلہ 9: پروجیکٹ فولڈرز شامل کریں {#step-9} + +اپنے پروجیکٹ کو منظم رکھنے کے لیے ہم دو نئے فولڈر بنائیں گے۔ اپنی کمانڈ لائن میں اپنے پروجیکٹ کی روٹ ڈائرکٹری پر جائیں اور ٹائپ کریں: + +``` +mkdir contracts +mkdir scripts +``` + +- `contracts/` وہ جگہ ہے جہاں ہم اپنی ہیلو ورلڈ اسمارٹ کنٹریکٹ کوڈ فائل رکھیں گے۔ +- `scripts/` وہ جگہ ہے جہاں ہم اپنے کنٹریکٹ کو ڈیپلائے کرنے اور اس کے ساتھ انٹریکٹ کرنے کے لیے اسکرپٹس رکھیں گے۔ + +## مرحلہ 10: ہمارا کنٹریکٹ لکھیں {#step-10} + +آپ خود سے پوچھ رہے ہوں گے کہ آخر ہم کوڈ کب لکھیں گے؟ خیر، ہم یہاں ہیں، مرحلہ 10 پر۔ + +اپنے پسندیدہ ایڈیٹر میں ہیلو-ورلڈ پروجیکٹ کھولیں (ہمیں [VSCode](https://code.visualstudio.com/) پسند ہے)۔ اسمارٹ کنٹریکٹس Solidity نامی زبان میں لکھے جاتے ہیں جسے ہم اپنا HelloWorld.sol اسمارٹ کنٹریکٹ لکھنے کے لیے استعمال کریں گے۔ + +1. ”contracts“ فولڈر پر جائیں اور HelloWorld.sol نامی ایک نئی فائل بنائیں۔ +2. نیچے Ethereum فاؤنڈیشن کا ایک نمونہ ہیلو ورلڈ اسمارٹ کنٹریکٹ ہے جسے ہم اس ٹیوٹوریل کے لیے استعمال کریں گے۔ نیچے دیے گئے مواد کو اپنی HelloWorld.sol فائل میں کاپی اور پیسٹ کریں، اور یہ سمجھنے کے لیے تبصرے ضرور پڑھیں کہ یہ کنٹریکٹ کیا کرتا ہے: + +```solidity +// سیمنٹک ورژنگ کا استعمال کرتے ہوئے، Solidity کا ورژن بتاتا ہے۔ +// مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.7.0; + +// `HelloWorld` نامی ایک کنٹریکٹ کی وضاحت کرتا ہے۔ +// ایک کنٹریکٹ فنکشنز اور ڈیٹا (اس کی اسٹیٹ) کا مجموعہ ہوتا ہے۔ ایک بار ڈیپلائے ہونے کے بعد، ایک کنٹریکٹ Ethereum بلاک چین پر ایک مخصوص ایڈریس پر رہتا ہے۔ مزید جانیں: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + // `string` قسم کے ایک اسٹیٹ ویری ایبل `message` کا اعلان کرتا ہے۔ + // اسٹیٹ ویری ایبلز ایسے ویری ایبلز ہیں جن کی ویلیوز مستقل طور پر کنٹریکٹ اسٹوریج میں محفوظ ہوجاتی ہیں۔ کلیدی لفظ `public` ویری ایبلز کو کنٹریکٹ کے باہر سے قابل رسائی بناتا ہے اور ایک ایسا فنکشن بناتا ہے جسے دوسرے کنٹریکٹس یا کلائنٹس ویلیو تک رسائی کے لیے کال کرسکتے ہیں۔ + string public message; + + // کئی کلاس پر مبنی آبجیکٹ اورینٹڈ زبانوں کی طرح، ایک کنسٹرکٹر ایک خاص فنکشن ہے جو صرف کنٹریکٹ بنانے پر ہی عمل میں لایا جاتا ہے۔ + // کنسٹرکٹرز کا استعمال کنٹریکٹ کے ڈیٹا کو شروع کرنے کے لیے کیا جاتا ہے۔ مزید جانیں:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // ایک سٹرنگ آرگیومنٹ `initMessage` کو قبول کرتا ہے اور ویلیو کو کنٹریکٹ کے `message` اسٹوریج ویری ایبل میں سیٹ کرتا ہے۔ + message = initMessage; + } + + // ایک پبلک فنکشن جو ایک سٹرنگ آرگیومنٹ کو قبول کرتا ہے اور `message` اسٹوریج ویری ایبل کو اپ ڈیٹ کرتا ہے۔ + function update(string memory newMessage) public { + message = newMessage; + } +} +``` + +یہ ایک انتہائی سادہ اسمارٹ کنٹریکٹ ہے جو بناتے وقت ایک پیغام اسٹور کرتا ہے اور `update` فنکشن کو کال کرکے اپ ڈیٹ کیا جاسکتا ہے۔ + +## مرحلہ 11: MetaMask اور Alchemy کو اپنے پروجیکٹ سے جوڑیں {#step-11} + +ہم نے ایک MetaMask والیٹ، Alchemy اکاؤنٹ بنایا ہے، اور اپنا اسمارٹ کنٹریکٹ لکھا ہے، اب ان تینوں کو جوڑنے کا وقت آگیا ہے۔ + +آپ کے ورچوئل والیٹ سے بھیجی گئی ہر ٹرانزیکشن کے لیے آپ کی منفرد پرائیویٹ کلید کا استعمال کرتے ہوئے ایک دستخط کی ضرورت ہوتی ہے۔ ہمارے پروگرام کو یہ اجازت فراہم کرنے کے لیے، ہم اپنی پرائیویٹ کلید (اور Alchemy API کلید) کو ایک ماحولیاتی فائل میں محفوظ طریقے سے اسٹور کر سکتے ہیں۔ + +> ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، web3 کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے پر [یہ ٹیوٹوریل](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) دیکھیں۔ + +سب سے پہلے، اپنی پروجیکٹ ڈائرکٹری میں dotenv پیکیج انسٹال کریں: + +``` +npm install dotenv --save +``` + +پھر، ہمارے پروجیکٹ کی روٹ ڈائرکٹری میں ایک `.env` فائل بنائیں، اور اس میں اپنی MetaMask پرائیویٹ کلید اور HTTP Alchemy API URL شامل کریں۔ + +- اپنی پرائیویٹ کلید کو ایکسپورٹ کرنے کے لیے [ان ہدایات](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/) پر عمل کریں۔ +- HTTP Alchemy API URL حاصل کرنے کے لیے نیچے دیکھیں + +![get alchemy api key](./get-alchemy-api-key.png) + +Alchemy API URL کاپی کریں + +آپ کا `.env` اس طرح نظر آنا چاہیے: + +``` +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" +PRIVATE_KEY = "your-metamask-private-key" +``` + +انہیں حقیقت میں ہمارے کوڈ سے جوڑنے کے لیے، ہم ان متغیرات کا حوالہ اپنی `hardhat.config.js` فائل میں مرحلہ 13 پر دیں گے۔ + + + + +.env کو کمٹ نہ کریں! براہ کرم یقینی بنائیں کہ آپ اپنی .env فائل کسی کے ساتھ شیئر یا ظاہر نہ کریں، کیونکہ ایسا کرنے سے آپ اپنے رازوں پر سمجھوتہ کر رہے ہیں۔ اگر آپ ورژن کنٹرول استعمال کر رہے ہیں، تو اپنی .env کو gitignore فائل میں شامل کریں۔ + + + + +## مرحلہ 12: Ethers.js انسٹال کریں {#step-12-install-ethersjs} + +Ethers.js ایک لائبریری ہے جو [معیاری JSON-RPC طریقوں](/developers/docs/apis/json-rpc/) کو زیادہ صارف دوست طریقوں کے ساتھ لپیٹ کر Ethereum کے ساتھ تعامل اور درخواستیں کرنا آسان بناتی ہے۔ + +Hardhat اضافی ٹولنگ اور توسیع شدہ فعالیت کے لیے [پلگ انز](https://hardhat.org/plugins/) کو ضم کرنا انتہائی آسان بناتا ہے۔ ہم کنٹریکٹ ڈیپلائمنٹ کے لیے [Ethers پلگ ان](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) سے فائدہ اٹھائیں گے ([Ethers.js](https://github.com/ethers-io/ethers.js/) میں کچھ انتہائی صاف کنٹریکٹ ڈیپلائمنٹ کے طریقے ہیں)۔ + +اپنی پروجیکٹ ڈائرکٹری میں ٹائپ کریں: + +``` +npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" +``` + +ہمیں اگلے مرحلے میں اپنی `hardhat.config.js` میں بھی ethers کی ضرورت ہوگی۔ + +## مرحلہ 13: hardhat.config.js کو اپ ڈیٹ کریں {#step-13-update-hardhatconfigjs} + +ہم نے اب تک کئی انحصارات اور پلگ ان شامل کیے ہیں، اب ہمیں `hardhat.config.js` کو اپ ڈیٹ کرنے کی ضرورت ہے تاکہ ہمارے پروجیکٹ کو ان سب کے بارے میں معلوم ہو۔ + +اپنی `hardhat.config.js` کو اس طرح اپ ڈیٹ کریں: + +``` +require('dotenv').config(); + +require("@nomiclabs/hardhat-ethers"); +const { API_URL, PRIVATE_KEY } = process.env; + +/** +* @type import('hardhat/config').HardhatUserConfig +*/ +module.exports = { + solidity: "0.7.3", + defaultNetwork: "sepolia", + networks: { + hardhat: {}, + sepolia: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`] + } + }, +} +``` + +## مرحلہ 14: ہمارے کنٹریکٹ کو کمپائل کریں {#step-14-compile-our-contracts} + +یہ یقینی بنانے کے لیے کہ اب تک سب کچھ کام کر رہا ہے، آئیے اپنے کنٹریکٹ کو کمپائل کریں۔ `compile` ٹاسک بلٹ ان ہارڈ ہیٹ ٹاسک میں سے ایک ہے۔ + +کمانڈ لائن سے چلائیں: + +``` +npx hardhat compile +``` + +آپ کو `SPDX license identifier not provided in source file` کے بارے میں ایک وارننگ مل سکتی ہے، لیکن اس کے بارے میں فکر کرنے کی ضرورت نہیں ہے — امید ہے کہ باقی سب کچھ اچھا لگے گا! اگر نہیں، تو آپ ہمیشہ [Alchemy discord](https://discord.gg/u72VCg3) میں پیغام بھیج سکتے ہیں۔ + +## مرحلہ 15: ہماری ڈیپلائے اسکرپٹ لکھیں {#step-15-write-our-deploy-scripts} + +اب جب کہ ہمارا کنٹریکٹ لکھا جا چکا ہے اور ہماری کنفیگریشن فائل تیار ہے، اب وقت آگیا ہے کہ ہم اپنی کنٹریکٹ ڈیپلوئے اسکرپٹ لکھیں۔ + +`scripts/` فولڈر پر جائیں اور `deploy.js` نامی ایک نئی فائل بنائیں، اس میں درج ذیل مواد شامل کریں: + +``` +async function main() { + const HelloWorld = await ethers.getContractFactory("HelloWorld"); + + // ڈیپلائمنٹ شروع کریں، ایک پرومس واپس کرتا ہے جو ایک کنٹریکٹ آبجیکٹ میں ریزولو ہوتا ہے + const hello_world = await HelloWorld.deploy("Hello World!"); + console.log("Contract deployed to address:", hello_world.address);} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); +``` + +Hardhat اپنے [کنٹریکٹس ٹیوٹوریل](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) میں بہت اچھی طرح سے وضاحت کرتا ہے کہ کوڈ کی یہ ہر لائن کیا کرتی ہے، ہم نے یہاں ان کی وضاحتیں اپنائی ہیں۔ + +``` +const HelloWorld = await ethers.getContractFactory("HelloWorld"); +``` + +ethers.js میں ایک `ContractFactory` ایک ابسٹریکشن ہے جو نئے اسمارٹ کنٹریکٹس کو ڈیپلائے کرنے کے لیے استعمال ہوتی ہے، لہذا یہاں `HelloWorld` ہمارے ہیلو ورلڈ کنٹریکٹ کی مثالوں کے لیے ایک فیکٹری ہے۔ `hardhat-ethers` پلگ ان کا استعمال کرتے وقت `ContractFactory` اور `Contract` کی مثالیں پہلے دستخط کنندہ سے بطور ڈیفالٹ جڑی ہوتی ہیں۔ + +``` +const hello_world = await HelloWorld.deploy(); +``` + +ایک `ContractFactory` پر `deploy()` کو کال کرنے سے ڈیپلائمنٹ شروع ہو جائے گی، اور ایک `Promise` واپس آئے گا جو ایک `Contract` میں ریزولو ہوتا ہے۔ یہ وہ آبجیکٹ ہے جس میں ہمارے ہر اسمارٹ کنٹریکٹ فنکشن کے لیے ایک طریقہ ہے۔ + +## مرحلہ 16: ہمارا کنٹریکٹ ڈیپلائے کریں {#step-16-deploy-our-contract} + +ہم آخر کار اپنے اسمارٹ کنٹریکٹ کو ڈیپلوئے کرنے کے لیے تیار ہیں! کمانڈ لائن پر جائیں اور چلائیں: + +``` +npx hardhat run scripts/deploy.js --network sepolia +``` + +پھر آپ کو کچھ اس طرح نظر آنا چاہیے: + +``` +کنٹریکٹ اس ایڈریس پر ڈیپلائے کیا گیا: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +``` + +اگر ہم [Sepolia etherscan](https://sepolia.etherscan.io/) پر جائیں اور اپنے کنٹریکٹ ایڈریس کو تلاش کریں تو ہمیں یہ دیکھنے کے قابل ہونا چاہیے کہ یہ کامیابی سے ڈیپلائے ہو گیا ہے۔ ٹرانزیکشن کچھ اس طرح نظر آئے گی: + +![etherscan contract](./etherscan-contract.png) + +`From` ایڈریس آپ کے MetaMask اکاؤنٹ کے ایڈریس سے مماثل ہونا چاہیے اور To ایڈریس پر ”Contract Creation“ لکھا ہوگا لیکن اگر ہم ٹرانزیکشن میں کلک کریں گے تو ہمیں `To` فیلڈ میں اپنا کنٹریکٹ ایڈریس نظر آئے گا: + +![etherscan transaction](./etherscan-transaction.png) + +مبارک ہو! آپ نے ابھی Ethereum چین پر ایک اسمارٹ کنٹریکٹ ڈیپلائے کیا ہے 🎉 + +یہ سمجھنے کے لیے کہ پس پردہ کیا ہو رہا ہے، آئیے اپنے [Alchemy ڈیش بورڈ](https://dashboard.alchemyapi.io/explorer) میں ایکسپلورر ٹیب پر جائیں۔ اگر آپ کے پاس متعدد Alchemy ایپس ہیں تو ایپ کے لحاظ سے فلٹر کرنا اور ”Hello World“ کو منتخب کرنا یقینی بنائیں۔ +![hello world explorer](./hello-world-explorer.png) + +یہاں آپ کو مٹھی بھر JSON-RPC کالز نظر آئیں گی جو Hardhat/Ethers نے ہمارے لیے پس پردہ کی تھیں جب ہم نے `.deploy()` فنکشن کو کال کیا تھا۔ یہاں دو اہم کالز ہیں [`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction)، جو دراصل ہمارے کنٹریکٹ کو Sepolia چین پر لکھنے کی درخواست ہے، اور [`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash) جو ہیش دیے جانے پر ہمارے ٹرانزیکشن کے بارے میں معلومات پڑھنے کی درخواست ہے (ٹرانزیکشنز کے وقت ایک عام پیٹرن)۔ ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، [Web3 اور Alchemy کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) پر یہ ٹیوٹوریل دیکھیں۔ + +اس ٹیوٹوریل کے حصہ 1 کے لیے بس اتنا ہی، حصہ 2 میں ہم اصل میں [اپنے اسمارٹ کنٹریکٹ کے ساتھ انٹریکٹ کریں گے](https://www.alchemy.com/docs/interacting-with-a-smart-contract) اپنے ابتدائی پیغام کو اپ ڈیٹ کرکے، اور حصہ 3 میں ہم [اپنے اسمارٹ کنٹریکٹ کو Etherscan پر پبلش کریں گے](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) تاکہ ہر کوئی جان سکے کہ اس کے ساتھ کیسے انٹریکٹ کرنا ہے۔ + +**Alchemy کے بارے میں مزید جاننا چاہتے ہیں؟ ہماری [ویب سائٹ](https://www.alchemy.com/eth) دیکھیں۔ کبھی بھی کوئی اپ ڈیٹ مس نہیں کرنا چاہتے؟ ہمارے نیوز لیٹر کو [یہاں](https://www.alchemy.com/newsletter) سبسکرائب کریں! ہمارے [Discord](https://discord.gg/u72VCg3) میں بھی شامل ہونا یقینی بنائیں۔**۔ diff --git a/public/content/translations/ur/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/ur/developers/tutorials/how-to-implement-an-erc721-market/index.md new file mode 100644 index 00000000000..630e11769de --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -0,0 +1,145 @@ +--- +title: "ERC-721 مارکیٹ کو کیسے نافذ کریں" +description: "ایک غیر مرکزی کلاسیفائیڈ بورڈ پر ٹوکنائزڈ آئٹمز کو فروخت کے لیے کیسے پیش کریں" +author: "Alberto Cuesta Cañada" +tags: [ "اسمارٹ معاہدات", "erc-721", "solidity", "tokens" ] +skill: intermediate +lang: ur-in +published: 2020-03-19 +source: Hackernoon +sourceUrl: https://hackernoon.com/how-to-implement-an-erc721-market-1e1a32j9 +--- + +اس مضمون میں، میں آپ کو دکھانے جا رہا ہوں کہ Ethereum بلاک چین کے لیے Craigslist کو کیسے کوڈ کیا جائے۔ + +Gumtree، Ebay اور Craigslist سے پہلے، کلاسیفائیڈ بورڈز زیادہ تر کارک یا کاغذ کے بنے ہوتے تھے۔ اسکول کی راہداریوں، اخبارات، اسٹریٹ لائٹس، اور اسٹور فرنٹ پر کلاسیفائیڈ بورڈز لگے ہوتے تھے۔ + +انٹرنیٹ کے آنے سے یہ سب کچھ بدل گیا۔ ایک مخصوص کلاسیفائیڈ بورڈ کو دیکھنے والے لوگوں کی تعداد کئی گنا بڑھ گئی۔ اس کے ساتھ، وہ بازار جن کی وہ نمائندگی کرتے تھے، بہت زیادہ موثر ہو گئے اور عالمی سطح تک پھیل گئے۔ Ebay ایک بہت بڑا کاروبار ہے جس کی ابتدا ان فزیکل کلاسیفائیڈ بورڈز سے ہوتی ہے۔ + +بلاک چین کے ساتھ یہ بازار ایک بار پھر بدلنے کے لیے تیار ہیں، میں آپ کو دکھاتا ہوں کہ کیسے۔ + +## منیٹائزیشن {#monetization} + +ایک عوامی بلاک چین کلاسیفائیڈ بورڈ کے کاروباری ماڈل کو Ebay اور کمپنی کے ماڈل سے مختلف ہونا پڑے گا۔ + +سب سے پہلے، [غیر مرکزیت کا زاویہ](/developers/docs/web2-vs-web3/) ہے۔ موجودہ پلیٹ فارمز کو اپنے سرورز کو برقرار رکھنے کی ضرورت ہوتی ہے۔ ایک غیر مرکزی پلیٹ فارم کو اس کے صارفین کے ذریعے برقرار رکھا جاتا ہے، اس لیے بنیادی پلیٹ فارم کو چلانے کی لاگت پلیٹ فارم کے مالک کے لیے صفر ہو جاتی ہے۔ + +پھر فرنٹ اینڈ ہے، یعنی وہ ویب سائٹ یا انٹرفیس جو پلیٹ فارم تک رسائی فراہم کرتا ہے۔ یہاں بہت سے اختیارات ہیں۔ پلیٹ فارم کے مالکان رسائی کو محدود کر سکتے ہیں اور ہر کسی کو اپنا انٹرفیس استعمال کرنے پر مجبور کر سکتے ہیں، جس کے لیے وہ ایک فیس وصول کرتے ہیں۔ پلیٹ فارم کے مالکان رسائی کو کھلا رکھنے کا فیصلہ بھی کر سکتے ہیں (طاقت عوام کے ہاتھ میں!) اور کسی کو بھی پلیٹ فارم کے لیے انٹرفیس بنانے کی اجازت دے سکتے ہیں۔ یا مالکان ان انتہاؤں کے درمیان کوئی بھی طریقہ اختیار کرنے کا فیصلہ کر سکتے ہیں۔ + +_مجھ سے زیادہ وژن رکھنے والے کاروباری رہنما یہ جانتے ہوں گے کہ اسے کیسے منیٹائز کیا جائے۔_ _میں صرف یہ دیکھتا ہوں کہ یہ موجودہ صورتحال سے مختلف ہے اور شاید منافع بخش بھی ہے۔_ + +مزید برآں، آٹومیشن اور ادائیگیوں کا زاویہ بھی ہے۔ کچھ چیزوں کو بہت [مؤثر طریقے سے ٹوکنائزڈ](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) کیا جا سکتا ہے اور ایک کلاسیفائیڈ بورڈ پر ان کی تجارت کی جا سکتی ہے۔ ٹوکنائزڈ اثاثوں کو بلاک چین میں آسانی سے منتقل کیا جا سکتا ہے۔ انتہائی پیچیدہ ادائیگی کے طریقوں کو بلاک چین میں آسانی سے نافذ کیا جا سکتا ہے۔ + +مجھے یہاں کاروبار کا ایک موقع نظر آ رہا ہے۔ بغیر کسی چلانے کی لاگت والا ایک کلاسیفائیڈ بورڈ آسانی سے نافذ کیا جا سکتا ہے، جس میں ہر لین دین میں پیچیدہ ادائیگی کے راستے شامل ہوں۔ مجھے یقین ہے کہ کوئی نہ کوئی اس بارے میں ایک خیال لے کر آئے گا کہ اسے کس لیے استعمال کیا جائے۔ + +میں تو بس اسے بنا کر خوش ہوں۔ آئیے کوڈ پر ایک نظر ڈالتے ہیں۔ + +## عمل درآمد {#implementation} + +کچھ عرصہ پہلے ہم نے کاروباری کیس کی مثالوں کے نفاذ اور دیگر اچھی چیزوں کے ساتھ ایک [اوپن سورس ریپوزٹری](https://github.com/HQ20/contracts?ref=hackernoon.com) شروع کی تھی، براہ کرم اس پر ایک نظر ڈالیں۔ + +اس [Ethereum کلاسیفائیڈز بورڈ](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) کا کوڈ وہیں ہے، براہ کرم اسے استعمال کریں اور اس کا بھرپور فائدہ اٹھائیں۔ بس اس بات سے آگاہ رہیں کہ کوڈ کا آڈٹ نہیں کیا گیا ہے اور اس میں پیسہ لگانے سے پہلے آپ کو اپنی خود کی جانچ پڑتال کرنے کی ضرورت ہے۔ + +بورڈ کی بنیادی باتیں پیچیدہ نہیں ہیں۔ بورڈ میں موجود تمام اشتہارات صرف چند فیلڈز کے ساتھ ایک اسٹرکٹ ہوں گے: + +```solidity +struct Trade { + address poster; + uint256 item; + uint256 price; + bytes32 status; // کھلا، عملدرآمد، منسوخ +} +``` + +تو کوئی ہے جو اشتہار پوسٹ کر رہا ہے۔ فروخت کے لیے ایک آئٹم۔ آئٹم کی قیمت۔ ٹریڈ کی حیثیت جو کہ کھلی، عملدرآمد شدہ یا منسوخ ہو سکتی ہے۔ + +یہ تمام ٹریڈز ایک میپنگ میں رکھے جائیں گے۔ کیونکہ Solidity میں ہر چیز ایک میپنگ ہی لگتی ہے۔ اس لیے بھی کہ یہ آسان ہے۔ + +```solidity +mapping(uint256 => Trade) public trades; +``` + +میپنگ کا استعمال کرنے کا صرف یہ مطلب ہے کہ ہمیں ہر اشتہار کو پوسٹ کرنے سے پہلے اس کے لیے ایک آئی ڈی بنانی ہوگی، اور اس پر کام کرنے سے پہلے ہمیں اشتہار کی آئی ڈی جاننے کی ضرورت ہوگی۔ اس سے نمٹنے کے متعدد طریقے ہیں، چاہے وہ اسمارٹ کنٹریکٹ میں ہوں یا فرنٹ اینڈ میں۔ اگر آپ کو کچھ اشارے چاہئیں تو براہ کرم پوچھیں۔ + +اگلا سوال یہ پیدا ہوتا ہے کہ وہ کون سی اشیاء ہیں جن کا ہم لین دین کرتے ہیں، اور وہ کون سی کرنسی ہے جو لین دین کی ادائیگی کے لیے استعمال ہوتی ہے۔ + +آئٹمز کے لیے، ہم صرف یہ مطالبہ کرنے جا رہے ہیں کہ وہ [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com) انٹرفیس کو نافذ کریں، جو واقعی بلاک چین میں حقیقی دنیا کی اشیاء کی نمائندگی کرنے کا ایک طریقہ ہے، حالانکہ یہ [ڈیجیٹل اثاثوں کے ساتھ بہترین کام کرتا ہے](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com)۔ ہم کنسٹرکٹر میں اپنے ERC721 کنٹریکٹ کی وضاحت کرنے جا رہے ہیں، جس کا مطلب ہے کہ ہمارے کلاسیفائیڈ بورڈ میں موجود کسی بھی اثاثے کو پہلے سے ٹوکنائزڈ ہونا ضروری ہے۔ + +ادائیگیوں کے لیے، ہم کچھ ایسا ہی کرنے جا رہے ہیں۔ زیادہ تر بلاک چین پروجیکٹس اپنی خود کی [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com) کرپٹو کرنسی کی وضاحت کرتے ہیں۔ کچھ دوسرے DAI جیسی مرکزی دھارے کی کرنسی کا استعمال کرنا پسند کرتے ہیں۔ اس کلاسیفائیڈ بورڈ میں، آپ کو صرف تعمیر کے وقت یہ فیصلہ کرنا ہوگا کہ آپ کی کرنسی کیا ہوگی۔ آسان ہے۔ + +```solidity +constructor ( + address _currencyTokenAddress, address _itemTokenAddress +) public { + currencyToken = IERC20(_currencyTokenAddress); + itemToken = IERC721(_itemTokenAddress); + tradeCounter = 0; +} +``` + +ہم وہاں پہنچ رہے ہیں۔ ہمارے پاس اشتہارات، تجارت کے لیے آئٹمز اور ادائیگیوں کے لیے ایک کرنسی ہے۔ اشتہار بنانے کا مطلب ہے کسی آئٹم کو ایسکرو میں رکھنا تاکہ یہ دکھایا جا سکے کہ آپ کے پاس وہ آئٹم ہے اور آپ نے اسے دو بار پوسٹ نہیں کیا ہے، ممکنہ طور پر کسی مختلف بورڈ پر۔ + +نیچے دیا گیا کوڈ بالکل یہی کرتا ہے۔ آئٹم کو ایسکرو میں رکھتا ہے، اشتہار بناتا ہے، کچھ ہاؤس کیپنگ کرتا ہے۔ + +```solidity +function openTrade(uint256 _item, uint256 _price) + public +{ + itemToken.transferFrom(msg.sender, address(this), _item); + trades[tradeCounter] = Trade({ + poster: msg.sender, + item: _item, + price: _price, + status: "Open" + }); + tradeCounter += 1; + emit TradeStatusChange(tradeCounter - 1, "Open"); +} +``` + +ٹریڈ کو قبول کرنے کا مطلب ہے ایک اشتہار (ٹریڈ) کا انتخاب کرنا، قیمت ادا کرنا، اور آئٹم وصول کرنا۔ نیچے دیا گیا کوڈ ایک ٹریڈ کو بازیافت کرتا ہے۔ یہ چیک کرتا ہے کہ آیا یہ دستیاب ہے۔ آئٹم کی قیمت ادا کرتا ہے۔ آئٹم کو بازیافت کرتا ہے۔ اشتہار کو اپ ڈیٹ کرتا ہے۔ + +```solidity +function executeTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require(trade.status == "Open", "ٹریڈ کھلی نہیں ہے۔"); + currencyToken.transferFrom(msg.sender, trade.poster, trade.price); + itemToken.transferFrom(address(this), msg.sender, trade.item); + trades[_trade].status = "Executed"; + emit TradeStatusChange(_trade, "Executed"); +} +``` + +آخر میں، ہمارے پاس بیچنے والوں کے لیے ایک آپشن ہے کہ وہ کسی خریدار کے قبول کرنے سے پہلے ٹریڈ سے پیچھے ہٹ سکتے ہیں۔ کچھ ماڈلز میں، اشتہارات ختم ہونے سے پہلے ایک مدت کے لیے لائیو رہتے ہیں۔ یہ آپ کی پسند ہے، جو آپ کے بازار کے ڈیزائن پر منحصر ہے۔ + +یہ کوڈ ٹریڈ کو انجام دینے کے لیے استعمال ہونے والے کوڈ سے بہت ملتا جلتا ہے، صرف اتنا فرق ہے کہ اس میں کرنسی کا تبادلہ نہیں ہوتا اور آئٹم اشتہار پوسٹ کرنے والے کے پاس واپس چلا جاتا ہے۔ + +```solidity +function cancelTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require( + msg.sender == trade.poster, + "ٹریڈ کو صرف پوسٹر ہی منسوخ کر سکتا ہے۔" + ); + require(trade.status == "Open", "ٹریڈ کھلی نہیں ہے۔"); + itemToken.transferFrom(address(this), trade.poster, trade.item); + trades[_trade].status = "Cancelled"; + emit TradeStatusChange(_trade, "Cancelled"); +} +``` + +بس یہی ہے۔ آپ نفاذ کے اختتام تک پہنچ گئے ہیں۔ یہ کافی حیران کن ہے کہ کچھ کاروباری تصورات کوڈ میں ظاہر ہونے پر کتنے جامع ہوتے ہیں، اور یہ ان میں سے ایک معاملہ ہے۔ مکمل کنٹریکٹ کو [ہمارے ریپو میں](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol) چیک کریں۔ + +## نتیجہ {#conclusion} + +کلاسیفائیڈ بورڈز ایک عام مارکیٹ کنفیگریشن ہیں جو انٹرنیٹ کے ساتھ بڑے پیمانے پر پھیلے، اور چند اجارہ دار فاتحین کے ساتھ ایک بہت مقبول کاروباری ماڈل بن گئے۔ + +کلاسیفائیڈ بورڈز ایک بلاک چین ماحول میں نقل کرنے کے لیے ایک آسان ٹول بھی ہیں، جن میں بہت مخصوص خصوصیات ہیں جو موجودہ بڑے اداروں کے لیے ایک چیلنج کو ممکن بنائیں گی۔ + +اس مضمون میں، میں نے ایک کلاسیفائیڈ بورڈ کاروبار کی کاروباری حقیقت اور تکنیکی نفاذ کے درمیان ایک پل بنانے کی کوشش کی ہے۔ اگر آپ کے پاس صحیح مہارتیں ہیں تو یہ علم آپ کو نفاذ کے لیے ایک وژن اور روڈ میپ بنانے میں مدد کرے گا۔ + +ہمیشہ کی طرح، اگر آپ کچھ دلچسپ بنانے جا رہے ہیں اور کچھ مشورہ چاہتے ہیں، تو براہ کرم [مجھ سے رابطہ کریں](https://albertocuesta.es/)! مجھے مدد کرنے میں ہمیشہ خوشی ہوتی ہے۔ diff --git a/public/content/translations/ur/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/ur/developers/tutorials/how-to-mint-an-nft/index.md new file mode 100644 index 00000000000..acab008787e --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-mint-an-nft/index.md @@ -0,0 +1,329 @@ +--- +title: "NFT کیسے منٹ کریں (NFT ٹیوٹوریل سیریز کا حصہ 2/3)" +description: "اس ٹیوٹوریل میں بتایا گیا ہے کہ ہمارے اسمارٹ کنٹریکٹ اور Web3 کا استعمال کرتے ہوئے Ethereum بلاک چین پر NFT کیسے منٹ کیا جائے۔" +author: "Sumi Mudgil" +tags: [ "ERC-721", "alchemy", "solidity", "اسمارٹ معاہدات" ] +skill: beginner +lang: ur-in +published: 2021-04-22 +--- + +[Beeple](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): $69 ملین +[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): $11 ملین +[Grimes](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): $6 ملین + +ان سبھی نے Alchemy کے طاقتور API کا استعمال کرتے ہوئے اپنے NFTs منٹ کیے۔ اس ٹیوٹوریل میں، ہم آپ کو سکھائیں گے کہ یہی کام \<10 منٹ سے کم میں کیسے کیا جائے۔ + +”NFT منٹ کرنا“ بلاک چین پر آپ کے ERC-721 ٹوکن کا ایک منفرد انسٹینس شائع کرنے کا عمل ہے۔ [اس NFT ٹیوٹوریل سیریز کے حصہ 1](/developers/tutorials/how-to-write-and-deploy-an-nft/) سے ہمارے اسمارٹ کنٹریکٹ کا استعمال کرتے ہوئے، آئیے اپنی Web3 کی مہارتوں کا مظاہرہ کریں اور ایک NFT منٹ کریں۔ اس ٹیوٹوریل کے آخر میں، آپ اتنے NFTs منٹ کر سکیں گے جتنے آپ کا دل (اور والیٹ) چاہے! + +آئیں شروع کرتے ہیں! + +## مرحلہ 1: Web3 انسٹال کریں {#install-web3} + +اگر آپ نے اپنا NFT اسمارٹ کنٹریکٹ بنانے کے پہلے ٹیوٹوریل پر عمل کیا ہے، تو آپ کو پہلے سے ہی Ethers.js استعمال کرنے کا تجربہ ہے۔ Web3 بھی Ethers کی طرح ہی ہے، کیونکہ یہ ایک لائبریری ہے جو Ethereum بلاک چین کو درخواستیں بھیجنا آسان بنانے کے لیے استعمال ہوتی ہے۔ اس ٹیوٹوریل میں ہم [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3) کا استعمال کریں گے، جو ایک بہتر Web3 لائبریری ہے جو خودکار ری ٹرائی اور مضبوط WebSocket سپورٹ پیش کرتی ہے۔ + +اپنی پروجیکٹ ہوم ڈائریکٹری میں چلائیں: + +``` +npm install @alch/alchemy-web3 +``` + +## مرحلہ 2: ایک `mint-nft.js` فائل بنائیں {#create-mintnftjs} + +اپنی اسکرپٹس ڈائریکٹری کے اندر، ایک `mint-nft.js` فائل بنائیں اور کوڈ کی درج ذیل لائنیں شامل کریں: + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) +``` + +## مرحلہ 3: اپنے کنٹریکٹ کا ABI حاصل کریں {#contract-abi} + +ہمارا کنٹریکٹ ABI (ایپلی کیشن بائنری انٹرفیس) ہمارے اسمارٹ کنٹریکٹ کے ساتھ تعامل کرنے کا انٹرفیس ہے۔ آپ کنٹریکٹ ABIs کے بارے میں مزید [یہاں](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is) جان سکتے ہیں۔ Hardhat ہمارے لیے خود بخود ایک ABI بناتا ہے اور اسے `MyNFT.json` فائل میں محفوظ کرتا ہے۔ اسے استعمال کرنے کے لیے ہمیں اپنی `mint-nft.js` فائل میں کوڈ کی درج ذیل لائنیں شامل کرکے مواد کو پارس کرنا ہوگا۔ + +```js +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +``` + +اگر آپ ABI دیکھنا چاہتے ہیں تو آپ اسے اپنے کنسول پر پرنٹ کر سکتے ہیں: + +```js +console.log(JSON.stringify(contract.abi)) +``` + +`mint-nft.js` چلانے اور اپنے ABI کو کنسول پر پرنٹ ہوتے دیکھنے کے لیے اپنے ٹرمینل پر جائیں اور چلائیں: + +```js +node scripts/mint-nft.js +``` + +## مرحلہ 4: IPFS کا استعمال کرتے ہوئے اپنے NFT کے لیے میٹا ڈیٹا کنفیگر کریں {#config-meta} + +اگر آپ کو حصہ 1 میں ہمارے ٹیوٹوریل سے یاد ہو، تو ہمارا `mintNFT` اسمارٹ کنٹریکٹ فنکشن ایک tokenURI پیرامیٹر لیتا ہے جسے NFT کے میٹا ڈیٹا کی وضاحت کرنے والے JSON دستاویز میں حل ہونا چاہیے— جو واقعی NFT کو زندہ کرتا ہے، جس سے اس میں قابلِ ترتیب خصوصیات جیسے نام، تفصیل، تصویر اور دیگر صفات شامل ہو سکتے ہیں۔ + +> _انٹرپلینیٹری فائل سسٹم (IPFS) تقسیم شدہ فائل سسٹم میں ڈیٹا کو اسٹور اور شیئر کرنے کے لیے ایک غیر مرکزی پروٹوکول اور پیئر ٹو پیئر نیٹ ورک ہے۔_ + +ہم اپنے NFT اثاثے اور میٹا ڈیٹا کو ذخیرہ کرنے کے لیے Pinata، ایک آسان IPFS API اور ٹول کٹ، کا استعمال کریں گے تاکہ یہ یقینی بنایا جا سکے کہ ہمارا NFT واقعی غیر مرکزی ہے۔ اگر آپ کا Pinata اکاؤنٹ نہیں ہے، تو [یہاں](https://app.pinata.cloud) ایک مفت اکاؤنٹ کے لیے سائن اپ کریں اور اپنی ای میل کی توثیق کرنے کے اقدامات مکمل کریں۔ + +ایک بار جب آپ اکاؤنٹ بنا لیں: + +- ”فائلز“ پیج پر جائیں اور صفحہ کے اوپر بائیں جانب نیلے "اپ لوڈ" بٹن پر کلک کریں۔ + +- Pinata پر ایک تصویر اپ لوڈ کریں — یہ آپ کے NFT کے لیے تصویری اثاثہ ہوگا۔ آپ اثاثے کو جو چاہیں نام دے سکتے ہیں + +- اپ لوڈ کرنے کے بعد، آپ کو "فائلز" پیج پر ٹیبل میں فائل کی معلومات نظر آئیں گی۔ آپ کو ایک CID کالم بھی نظر آئے گا۔ آپ اس کے ساتھ والے کاپی بٹن پر کلک کرکے CID کو کاپی کر سکتے ہیں۔ آپ اپنا اپ لوڈ یہاں دیکھ سکتے ہیں: `https://gateway.pinata.cloud/ipfs/`۔ مثال کے طور پر، آپ IPFS پر ہمارے ذریعہ استعمال کردہ تصویر کو [یہاں](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5) تلاش کر سکتے ہیں۔ + +زیادہ بصری سیکھنے والوں کے لیے، اوپر دیے گئے اقدامات کا خلاصہ یہاں دیا گیا ہے: + +![Pinata پر اپنی تصویر کیسے اپ لوڈ کریں](./instructionsPinata.gif) + +اب، ہم Pinata پر ایک اور دستاویز اپ لوڈ کرنا چاہیں گے۔ لیکن ایسا کرنے سے پہلے، ہمیں اسے بنانا ہوگا! + +اپنی روٹ ڈائریکٹری میں، `nft-metadata.json` نامی ایک نئی فائل بنائیں اور درج ذیل json کوڈ شامل کریں: + +```json +{ + "attributes": [ + { + "trait_type": "نسل", + "value": "مالٹیپو" + }, + { + "trait_type": "آنکھوں کا رنگ", + "value": "موکا" + } + ], + "description": "دنیا کا سب سے پیارا اور حساس پپی۔", + "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb", + "name": "ریمسیز" +} +``` + +آپ json میں ڈیٹا تبدیل کرنے کے لیے آزاد ہیں۔ آپ صفات کے سیکشن سے ہٹا سکتے ہیں یا اس میں اضافہ کر سکتے ہیں۔ سب سے اہم بات، یقینی بنائیں کہ تصویر کا فیلڈ آپ کی IPFS تصویر کے مقام کی طرف اشارہ کرتا ہے — ورنہ، آپ کے NFT میں ایک (بہت پیارے!) کی تصویر شامل ہوگی کتے کی۔ + +ایک بار جب آپ JSON فائل کی ترمیم مکمل کر لیں، تو اسے محفوظ کریں اور Pinata پر اپ لوڈ کریں، اسی طرح کے اقدامات پر عمل کرتے ہوئے جو ہم نے تصویر اپ لوڈ کرنے کے لیے کیے تھے۔ + +![Pinata پر اپنی nft-metadata.json کیسے اپ لوڈ کریں](./uploadPinata.gif) + +## مرحلہ 5: اپنے کنٹریکٹ کا ایک انسٹینس بنائیں {#instance-contract} + +اب، اپنے کنٹریکٹ کے ساتھ تعامل کرنے کے لیے، ہمیں اپنے کوڈ میں اس کا ایک انسٹینس بنانا ہوگا۔ ایسا کرنے کے لیے ہمیں اپنے کنٹریکٹ ایڈریس کی ضرورت ہوگی جسے ہم ڈیپلائمنٹ یا [Blockscout](https://eth-sepolia.blockscout.com/) سے اس ایڈریس کو تلاش کرکے حاصل کر سکتے ہیں جسے آپ نے کنٹریکٹ ڈیپلائے کرنے کے لیے استعمال کیا تھا۔ + +![Etherscan پر اپنا کنٹریکٹ ایڈریس دیکھیں](./view-contract-etherscan.png) + +مندرجہ بالا مثال میں، ہمارا کنٹریکٹ ایڈریس 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778 ہے۔ + +اگلا ہم ABI اور ایڈریس کا استعمال کرکے اپنا کنٹریکٹ بنانے کے لیے Web3 [کنٹریکٹ میتھڈ](https://docs.web3js.org/api/web3-eth-contract/class/Contract) کا استعمال کریں گے۔ اپنی `mint-nft.js` فائل میں، درج ذیل شامل کریں: + +```js +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" + +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) +``` + +## مرحلہ 6: `.env` فائل کو اپ ڈیٹ کریں {#update-env} + +اب، Ethereum چین پر ٹرانزیکشنز بنانے اور بھیجنے کے لیے، ہم اکاؤنٹ نانس حاصل کرنے کے لیے آپ کے عوامی Ethereum اکاؤنٹ ایڈریس کا استعمال کریں گے (نیچے وضاحت کی جائے گی)۔ + +اپنی پبلک کی کو اپنی `.env` فائل میں شامل کریں — اگر آپ نے ٹیوٹوریل کا حصہ 1 مکمل کر لیا ہے، تو ہماری `.env` فائل اب کچھ اس طرح نظر آنی چاہیے: + +```js +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" +PRIVATE_KEY = "your-private-account-address" +PUBLIC_KEY = "your-public-account-address" +``` + +## مرحلہ 7: اپنی ٹرانزیکشن بنائیں {#create-txn} + +سب سے پہلے، آئیے `mintNFT(tokenData)` نامی ایک فنکشن کی وضاحت کریں اور درج ذیل کام کرکے اپنی ٹرانزیکشن بنائیں: + +1. `.env` فائل سے اپنی _PRIVATE_KEY_ اور _PUBLIC_KEY_ حاصل کریں۔ + +2. اگلا، ہمیں اکاؤنٹ نانس کا پتہ لگانے کی ضرورت ہوگی۔ نانس کی تفصیلات آپ کے ایڈریس سے بھیجی گئی ٹرانزیکشنز کی تعداد پر نظر رکھنے کے لیے استعمال ہوتی ہیں — جس کی ہمیں سیکیورٹی مقاصد اور [ری پلے حملوں](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce) کو روکنے کے لیے ضرورت ہے۔ اپنے ایڈریس سے بھیجی گئی ٹرانزیکشنز کی تعداد حاصل کرنے کے لیے، ہم [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount) کا استعمال کرتے ہیں۔ + +3. آخر میں ہم درج ذیل معلومات کے ساتھ اپنی ٹرانزیکشن ترتیب دیں گے: + +- `'from': PUBLIC_KEY` — ہماری ٹرانزیکشن کا ماخذ ہمارا پبلک ایڈریس ہے + +- `'to': contractAddress` — وہ کنٹریکٹ جس کے ساتھ ہم تعامل کرنا اور ٹرانزیکشن بھیجنا چاہتے ہیں + +- `'nonce': nonce` — ہمارے ایڈریس سے بھیجی گئی ٹرانزیکشنز کی تعداد کے ساتھ اکاؤنٹ نانس + +- `'gas': estimatedGas` — ٹرانزیکشن مکمل کرنے کے لیے درکار تخمینہ شدہ گیس + +- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — وہ حساب جو ہم اس ٹرانزیکشن میں انجام دینا چاہتے ہیں — جو اس معاملے میں ایک NFT منٹ کرنا ہے + +آپ کی `mint-nft.js` فائل اب اس طرح نظر آنی چاہیے: + +```js + require('dotenv').config(); + const API_URL = process.env.API_URL; + const PUBLIC_KEY = process.env.PUBLIC_KEY; + const PRIVATE_KEY = process.env.PRIVATE_KEY; + + const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); + const web3 = createAlchemyWeb3(API_URL); + + const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json"); + const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"; + const nftContract = new web3.eth.Contract(contract.abi, contractAddress); + + async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); // تازہ ترین نانس حاصل کریں + + // ٹرانزیکشن + const tx = { + 'from': PUBLIC_KEY, + 'to': contractAddress, + 'nonce': nonce, + 'gas': 500000, + 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI() + }; + }​ +``` + +## مرحلہ 8: ٹرانزیکشن پر دستخط کریں {#sign-txn} + +اب جب کہ ہم نے اپنی ٹرانزیکشن بنا لی ہے، ہمیں اسے بھیجنے کے لیے اس پر دستخط کرنے کی ضرورت ہے۔ یہ وہ جگہ ہے جہاں ہم اپنی پرائیویٹ کی کا استعمال کریں گے۔ + +`web3.eth.sendSignedTransaction` ہمیں ٹرانزیکشن ہیش دے گا، جسے ہم یہ یقینی بنانے کے لیے استعمال کر سکتے ہیں کہ ہماری ٹرانزیکشن مائن ہو گئی ہے اور نیٹ ورک کے ذریعے ڈراپ نہیں ہوئی ہے۔ آپ دیکھیں گے کہ ٹرانزیکشن پر دستخط کرنے والے سیکشن میں، ہم نے کچھ ایرر چیکنگ شامل کی ہے تاکہ ہمیں معلوم ہو کہ ہماری ٹرانزیکشن کامیابی سے گزر گئی ہے یا نہیں۔ + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const PUBLIC_KEY = process.env.PUBLIC_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY + +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) + +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) + +async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") // تازہ ترین نانس حاصل کریں + + // ٹرانزیکشن + const tx = { + from: PUBLIC_KEY, + to: contractAddress, + nonce: nonce, + gas: 500000, + data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(), + } + + const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY) + signPromise + .then((signedTx) => { + web3.eth.sendSignedTransaction( + signedTx.rawTransaction, + function (err, hash) { + if (!err) { + console.log( + "آپ کی ٹرانزیکشن کا ہیش ہے: ", + hash, + "\nاپنی ٹرانزیکشن کی حیثیت دیکھنے کے لیے Alchemy's Mempool کو چیک کریں!" + ) + } else { + console.log( + "آپ کی ٹرانزیکشن جمع کرتے وقت کچھ غلط ہو گیا:", + err + ) + } + } + ) + }) + .catch((err) => { + console.log(" وعدہ ناکام رہا:", err) + }) +} +``` + +## مرحلہ 9: `mintNFT` کو کال کریں اور node `mint-nft.js` چلائیں {#call-mintnft-fn} + +کیا آپ کو وہ `metadata.json` یاد ہے جسے آپ نے Pinata پر اپ لوڈ کیا تھا؟ Pinata سے اس کا ہیش کوڈ حاصل کریں اور `mintNFT` فنکشن میں پیرامیٹر کے طور پر درج ذیل کو پاس کریں `https://gateway.pinata.cloud/ipfs/` + +ہیش کوڈ حاصل کرنے کا طریقہ یہاں ہے: + +![Pinata پر اپنے nft میٹا ڈیٹا کا ہیش کوڈ کیسے حاصل کریں](./metadataPinata.gif)_Pinata پر اپنے nft میٹا ڈیٹا کا ہیش کوڈ کیسے حاصل کریں_ + +> اس بات کو یقینی بنانے کے لیے دو بار چیک کریں کہ آپ نے جو ہیش کوڈ کاپی کیا ہے وہ آپ کی **metadata.json** سے لنک کرتا ہے، اس کے لیے `https://gateway.pinata.cloud/ipfs/` کو ایک الگ ونڈو میں لوڈ کریں۔ صفحہ نیچے دیے گئے اسکرین شاٹ کی طرح نظر آنا چاہیے: + +![آپ کے صفحے پر json میٹا ڈیٹا ظاہر ہونا چاہیے](./metadataJSON.png)_آپ کے صفحے پر json میٹا ڈیٹا ظاہر ہونا چاہیے_ + +مجموعی طور پر، آپ کا کوڈ کچھ اس طرح نظر آنا چاہیے: + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const PUBLIC_KEY = process.env.PUBLIC_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY + +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) + +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) + +async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") // تازہ ترین نانس حاصل کریں + + // ٹرانزیکشن + const tx = { + from: PUBLIC_KEY, + to: contractAddress, + nonce: nonce, + gas: 500000, + data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(), + } + + const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY) + signPromise + .then((signedTx) => { + web3.eth.sendSignedTransaction( + signedTx.rawTransaction, + function (err, hash) { + if (!err) { + console.log( + "آپ کی ٹرانزیکشن کا ہیش ہے: ", + hash, + "\nاپنی ٹرانزیکشن کی حیثیت دیکھنے کے لیے Alchemy's Mempool کو چیک کریں!" + ) + } else { + console.log( + "آپ کی ٹرانزیکشن جمع کرتے وقت کچھ غلط ہو گیا:", + err + ) + } + } + ) + }) + .catch((err) => { + console.log("وعدہ ناکام رہا:", err) + }) +} + +mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP") +``` + +اب، اپنا NFT ڈیپلائے کرنے کے لیے `node scripts/mint-nft.js` چلائیں۔ چند سیکنڈ کے بعد، آپ کو اپنے ٹرمینل میں اس طرح کا جواب نظر آنا چاہیے: + + ``` + آپ کی ٹرانزیکشن کا ہیش ہے: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 + + اپنی ٹرانزیکشن کا اسٹیٹس دیکھنے کے لیے Alchemy کا Mempool چیک کریں! + ``` + +اگلا، اپنی ٹرانزیکشن کا اسٹیٹس دیکھنے کے لیے اپنے [Alchemy mempool](https://dashboard.alchemyapi.io/mempool) پر جائیں (چاہے وہ پینڈنگ ہو، مائن ہو گیا ہو، یا نیٹ ورک کے ذریعے ڈراپ ہو گیا ہو)۔ اگر آپ کی ٹرانزیکشن ڈراپ ہو گئی ہے، تو [Blockscout](https://eth-sepolia.blockscout.com/) کو چیک کرنا اور اپنی ٹرانزیکشن ہیش کو تلاش کرنا بھی مددگار ہے۔ + +![Etherscan پر اپنے NFT ٹرانزیکشن ہیش کو دیکھیں](./view-nft-etherscan.png)_Etherscan پر اپنے NFT ٹرانزیکشن ہیش کو دیکھیں_ + +اور بس ہو گیا! اب آپ نے Ethereum بلاک چین پر ایک NFT ڈیپلائے اور منٹ کر لیا ہے + +`mint-nft.js` کا استعمال کرتے ہوئے آپ اتنے NFTs منٹ کر سکتے ہیں جتنے آپ کا دل (اور والیٹ) چاہے! بس یہ یقینی بنائیں کہ آپ NFT کے میٹا ڈیٹا کی وضاحت کرنے والا ایک نیا tokenURI پاس کریں (ورنہ، آپ مختلف IDs کے ساتھ بہت سارے یکساں بنا لیں گے)۔ + +یقیناً، آپ اپنے NFT کو اپنے والیٹ میں دکھانا چاہیں گے — تو [حصہ 3: اپنے والیٹ میں اپنا NFT کیسے دیکھیں](/developers/tutorials/how-to-view-nft-in-metamask/) ضرور دیکھیں! diff --git a/public/content/translations/ur/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/ur/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md new file mode 100644 index 00000000000..302ae22ea42 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -0,0 +1,102 @@ +--- +title: "ٹیسٹنگ کے لیے Solidity اسمارٹ کنٹریکٹس کو کیسے موک کریں" +description: "ٹیسٹنگ کے دوران آپ کو اپنے کنٹریکٹس کا مذاق کیوں اڑانا چاہئے" +author: Markus Waas +lang: ur-in +tags: [ "solidity", "اسمارٹ معاہدات", "testing", "mocking" ] +skill: intermediate +published: 2020-05-02 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/mocking-contracts +--- + +[موک آبجیکٹس](https://wikipedia.org/wiki/Mock_object) آبجیکٹ اورینٹڈ پروگرامنگ میں ایک عام ڈیزائن پیٹرن ہیں۔ پرانے فرانسیسی لفظ 'mocquer' سے ماخوذ ہے جس کا مطلب ہے 'مذاق اڑانا'، یہ 'کسی حقیقی چیز کی نقل کرنے' میں تبدیل ہو گیا جو دراصل وہی ہے جو ہم پروگرامنگ میں کرتے ہیں۔ براہ کرم اپنے اسمارٹ کنٹریکٹس کا مذاق صرف تب ہی اڑائیں جب آپ چاہیں، لیکن جب بھی ممکن ہو انہیں موک کریں۔ یہ آپ کی زندگی کو آسان بناتا ہے۔ + +## موکس کے ساتھ کنٹریکٹس کی یونٹ ٹیسٹنگ {#unit-testing-contracts-with-mocks} + +ایک کنٹریکٹ کو موک کرنے کا بنیادی طور پر مطلب اس کنٹریکٹ کا دوسرا ورژن بنانا ہے جو اصل والے سے بہت ملتا جلتا برتاؤ کرتا ہے، لیکن اس طریقے سے جسے ڈیولپر آسانی سے کنٹرول کر سکتا ہے۔ آپ اکثر پیچیدہ کنٹریکٹس کے ساتھ کام کرتے ہیں جہاں آپ صرف [کنٹریکٹ کے چھوٹے حصوں کی یونٹ ٹیسٹنگ](/developers/docs/smart-contracts/testing/) کرنا چاہتے ہیں۔ مسئلہ یہ ہے کہ اگر اس چھوٹے حصے کی ٹیسٹنگ کے لیے ایک بہت ہی مخصوص کنٹریکٹ اسٹیٹ کی ضرورت ہو جس تک پہنچنا مشکل ہو تو کیا ہوگا؟ + +آپ ہر بار پیچیدہ ٹیسٹ سیٹ اپ لاجک لکھ سکتے ہیں جو کنٹریکٹ کو مطلوبہ اسٹیٹ میں لاتا ہے یا آپ ایک موک لکھتے ہیں۔ انہیریٹنس کے ساتھ ایک کنٹریکٹ کو موک کرنا آسان ہے۔ بس ایک دوسرا موک کنٹریکٹ بنائیں جو اصل والے سے انہیریٹ کرتا ہو۔ اب آپ اپنے موک کے فنکشنز کو اوور رائڈ کر سکتے ہیں۔ آئیے اسے ایک مثال سے دیکھتے ہیں۔ + +## مثال: پرائیویٹ ERC20 {#example-private-erc20} + +ہم ایک مثال ERC-20 کنٹریکٹ استعمال کرتے ہیں جس کا ایک ابتدائی پرائیویٹ ٹائم ہوتا ہے۔ مالک پرائیویٹ یوزرس کا نظم کر سکتا ہے اور شروع میں صرف انہیں ہی ٹوکنز حاصل کرنے کی اجازت ہوگی۔ ایک خاص وقت گزر جانے کے بعد، ہر کسی کو ٹوکنز استعمال کرنے کی اجازت ہوگی۔ اگر آپ کو تجسس ہے، تو ہم نئے OpenZeppelin کنٹریکٹس v3 سے [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) ہک استعمال کر رہے ہیں۔ + +```solidity +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract PrivateERC20 is ERC20, Ownable { + mapping (address => bool) public isPrivateUser; + uint256 private publicAfterTime; + + constructor(uint256 privateERC20timeInSec) ERC20("PrivateERC20", "PRIV") public { + publicAfterTime = now + privateERC20timeInSec; + } + + function addUser(address user) external onlyOwner { + isPrivateUser[user] = true; + } + + function isPublic() public view returns (bool) { + return now >= publicAfterTime; + } + + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { + super._beforeTokenTransfer(from, to, amount); + + require(_validRecipient(to), "PrivateERC20: invalid recipient"); + } + + function _validRecipient(address to) private view returns (bool) { + if (isPublic()) { + return true; + } + + return isPrivateUser[to]; + } +} +``` + +اور اب آئیے اسے موک کرتے ہیں۔ + +```solidity +pragma solidity ^0.6.0; +import "../PrivateERC20.sol"; + +contract PrivateERC20Mock is PrivateERC20 { + bool isPublicConfig; + + constructor() public PrivateERC20(0) {} + + function setIsPublic(bool isPublic) external { + isPublicConfig = isPublic; + } + + function isPublic() public view returns (bool) { + return isPublicConfig; + } +} +``` + +آپ کو مندرجہ ذیل میں سے ایک ایرر میسیج ملے گا: + +- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.` +- `PrivateERC20.sol: TypeError: Trying to override non-virtual function.` `Did you forget to add "virtual"?.` + +چونکہ ہم نیا 0.6 Solidity ورژن استعمال کر رہے ہیں، ہمیں ان فنکشنز کے لیے `virtual` کی ورڈ شامل کرنا ہوگا جنہیں اوور رائڈ کیا جا سکتا ہے اور اوور رائڈ کرنے والے فنکشن کے لیے `override` شامل کرنا ہوگا۔ تو آئیے انہیں دونوں `isPublic` فنکشنز میں شامل کرتے ہیں۔ + +اب اپنے یونٹ ٹیسٹس میں، آپ اس کے بجائے `PrivateERC20Mock` استعمال کر سکتے ہیں۔ جب آپ پرائیویٹ استعمال کے وقت کے دوران برتاؤ کی ٹیسٹنگ کرنا چاہتے ہیں، تو `setIsPublic(false)` استعمال کریں اور اسی طرح پبلک استعمال کے وقت کی ٹیسٹنگ کے لیے `setIsPublic(true)` استعمال کریں۔ یقیناً ہماری مثال میں، ہم وقت کو اسی کے مطابق تبدیل کرنے کے لیے [ٹائم ہیلپرز](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) بھی استعمال کر سکتے ہیں۔ لیکن موکنگ کا آئیڈیا اب واضح ہو جانا چاہیے اور آپ ایسے منظرناموں کا تصور کر سکتے ہیں جہاں یہ صرف وقت کو آگے بڑھانے جتنا آسان نہیں ہوتا۔ + +## بہت سے کنٹریکٹس کو موک کرنا {#mocking-many-contracts} + +اگر آپ کو ہر ایک موک کے لیے ایک اور کنٹریکٹ بنانا پڑے تو یہ گڑبڑ ہو سکتا ہے۔ اگر یہ آپ کو پریشان کرتا ہے، تو آپ [MockContract](https://github.com/gnosis/mock-contract) لائبریری کو دیکھ سکتے ہیں۔ یہ آپ کو کنٹریکٹس کے برتاؤ کو فوری طور پر اوور رائڈ کرنے اور تبدیل کرنے کی اجازت دیتا ہے۔ تاہم، یہ صرف دوسرے کنٹریکٹ پر کالز کو موک کرنے کے لیے کام کرتا ہے، لہذا یہ ہماری مثال کے لیے کام نہیں کرے گا۔ + +## موکنگ اور بھی زیادہ طاقتور ہو سکتی ہے {#mocking-can-be-even-more-powerful} + +موکنگ کی طاقتیں یہیں ختم نہیں ہوتیں۔ + +- فنکشنز شامل کرنا: نہ صرف کسی مخصوص فنکشن کو اوور رائڈ کرنا مفید ہے، بلکہ اضافی فنکشنز شامل کرنا بھی مفید ہے۔ ٹوکنز کے لیے ایک اچھی مثال ایک اضافی `mint` فنکشن رکھنا ہے تاکہ کسی بھی یوزر کو مفت میں نئے ٹوکنز حاصل کرنے کی اجازت مل سکے۔ +- ٹیسٹ نیٹس میں استعمال: جب آپ اپنے ڈیپ (dapp) کے ساتھ اپنے کنٹریکٹس کو ٹیسٹ نیٹس پر ڈیپلائے اور ٹیسٹ کرتے ہیں، تو ایک موکڈ ورژن استعمال کرنے پر غور کریں۔ فنکشنز کو اوور رائڈ کرنے سے گریز کریں جب تک کہ آپ کو واقعی ایسا کرنے کی ضرورت نہ ہو۔ آخرکار آپ اصلی لاجک کی ٹیسٹنگ کرنا چاہتے ہیں۔ لیکن مثال کے طور پر ایک ری سیٹ فنکشن شامل کرنا مفید ہو سکتا ہے جو صرف کنٹریکٹ اسٹیٹ کو شروع میں ری سیٹ کر دیتا ہے، کسی نئے ڈیپلائمنٹ کی ضرورت نہیں ہوتی۔ ظاہر ہے کہ آپ ایک Mainnet کنٹریکٹ میں ایسا نہیں چاہیں گے۔ diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md new file mode 100644 index 00000000000..d38dc406313 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -0,0 +1,705 @@ +--- +title: "اسمارٹ کنٹریکٹس کو ٹیسٹ کرنے کے لیے Echidna کا استعمال کیسے کریں" +description: "اسمارٹ کنٹریکٹس کو خود بخود ٹیسٹ کرنے کے لیے Echidna کا استعمال کیسے کریں" +author: "Trailofbits" +lang: ur-in +tags: + [ + "solidity", + "اسمارٹ معاہدات", + "سیکورٹی", + "testing", + "fuzzing" + ] +skill: advanced +published: 2020-04-10 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna +--- + +## انسٹالیشن {#installation} + +Echidna کو docker کے ذریعے یا پہلے سے کمپائل شدہ بائنری کا استعمال کرکے انسٹال کیا جا سکتا ہے۔ + +### docker کے ذریعے Echidna {#echidna-through-docker} + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox +``` + +_آخری کمانڈ eth-security-toolbox کو ایک docker میں چلاتا ہے جس کی آپ کی موجودہ ڈائریکٹری تک رسائی ہے۔ آپ اپنے ہوسٹ سے فائلیں تبدیل کر سکتے ہیں، اور docker سے فائلوں پر ٹولز چلا سکتے ہیں_ + +docker کے اندر، چلائیں: + +```bash +solc-select 0.5.11 +cd /home/training +``` + +### بائنری {#binary} + +[https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0) + +## پراپرٹی پر مبنی فزنگ کا تعارف {#introduction-to-property-based-fuzzing} + +Echidna ایک پراپرٹی پر مبنی fuzzer ہے، جس کی تفصیل ہم نے اپنی پچھلی بلاگ پوسٹس میں بیان کی ہے ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). + +### Fuzzing {#fuzzing} + +[Fuzzing](https://wikipedia.org/wiki/Fuzzing) سیکورٹی کمیونٹی میں ایک معروف تکنیک ہے۔ یہ پروگرام میں کیڑے تلاش کرنے کے لیے کم و بیش بے ترتیب ان پٹس پیدا کرنے پر مشتمل ہے۔ روایتی سافٹ ویئر کے لیے Fuzzers (جیسے کہ [AFL](http://lcamtuf.coredump.cx/afl/) یا [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) کیڑے تلاش کرنے کے لیے موثر ٹولز کے طور پر جانے جاتے ہیں۔ + +ان پٹس کی خالصتاً بے ترتیب جنریشن سے ہٹ کر، اچھے ان پٹس پیدا کرنے کے لیے بہت سی تکنیکیں اور حکمت عملیاں ہیں، جن میں شامل ہیں: + +- ہر ایگزیکیوشن سے فیڈ بیک حاصل کریں اور اس کا استعمال کرتے ہوئے جنریشن کی رہنمائی کریں۔ مثال کے طور پر، اگر کوئی نیا تیار کردہ ان پٹ کسی نئے راستے کی دریافت کا باعث بنتا ہے، تو اس کے قریب نئے ان پٹ تیار کرنا سمجھ میں آ سکتا ہے۔ +- ساختی رکاوٹ کا احترام کرتے ہوئے ان پٹ تیار کرنا۔ مثال کے طور پر، اگر آپ کے ان پٹ میں چیک سم کے ساتھ ہیڈر ہے، تو یہ سمجھ میں آئے گا کہ fuzzer کو چیک سم کی توثیق کرنے والا ان پٹ تیار کرنے دیا جائے۔ +- نئے ان پٹس تیار کرنے کے لیے معروف ان پٹس کا استعمال: اگر آپ کے پاس درست ان پٹ کے بڑے ڈیٹا سیٹ تک رسائی ہے، تو آپ کا fuzzer شروع سے اپنی جنریشن شروع کرنے کے بجائے ان سے نئے ان پٹ تیار کر سکتا ہے۔ ان کو عام طور پر _seeds_ کہا جاتا ہے۔ + +### پراپرٹی پر مبنی فزنگ {#property-based-fuzzing} + +Echidna کا تعلق fuzzer کے ایک مخصوص خاندان سے ہے: پراپرٹی پر مبنی فزنگ [QuickCheck](https://wikipedia.org/wiki/QuickCheck) سے بہت زیادہ متاثر ہے۔ کلاسک fuzzer کے برعکس جو کریشز تلاش کرنے کی کوشش کرے گا، Echidna صارف کی طرف سے بیان کردہ انویرینٹس کو توڑنے کی کوشش کرے گا۔ + +اسمارٹ کنٹریکٹس میں، انویرینٹس Solidity فنکشنز ہیں، جو کسی بھی غلط یا غلط اسٹیٹ کی نمائندگی کر سکتے ہیں جس تک کنٹریکٹ پہنچ سکتا ہے، بشمول: + +- غلط رسائی کنٹرول: حملہ آور کنٹریکٹ کا مالک بن گیا۔ +- غلط اسٹیٹ مشین: کنٹریکٹ کے موقوف ہونے کے دوران ٹوکنز منتقل کیے جا سکتے ہیں۔ +- غلط حساب: صارف اپنے بیلنس کو انڈر فلو کر سکتا ہے اور لامحدود مفت ٹوکن حاصل کر سکتا ہے۔ + +### Echidna کے ساتھ پراپرٹی کی جانچ کرنا {#testing-a-property-with-echidna} + +ہم دیکھیں گے کہ Echidna کے ساتھ اسمارٹ کنٹریکٹ کی جانچ کیسے کی جائے۔ ہدف درج ذیل اسمارٹ کنٹریکٹ ہے [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): + +```solidity +contract Token{ + mapping(address => uint) public balances; + function airdrop() public{ + balances[msg.sender] = 1000; + } + function consume() public{ + require(balances[msg.sender]>0); + balances[msg.sender] -= 1; + } + function backdoor() public{ + balances[msg.sender] += 1; + } +} +``` + +ہم یہ فرض کریں گے کہ اس ٹوکن میں درج ذیل خصوصیات ہونی چاہئیں: + +- کوئی بھی زیادہ سے زیادہ 1000 ٹوکنز رکھ سکتا ہے۔ +- ٹوکن منتقل نہیں کیا جا سکتا (یہ ERC20 ٹوکن نہیں ہے) + +### ایک پراپرٹی لکھیں {#write-a-property} + +Echidna خصوصیات Solidity فنکشنز ہیں۔ ایک پراپرٹی میں ہونا چاہئے: + +- کوئی آرگیومنٹ نہ ہو +- کامیاب ہونے پر `true` لوٹائیں +- اس کا نام `echidna` سے شروع ہو + +Echidna کرے گا: + +- پراپرٹی کو جانچنے کے لیے خود بخود صوابدیدی لین دین پیدا کریں۔ +- کسی بھی ایسے لین دین کی اطلاع دیں جس کی وجہ سے کوئی پراپرٹی `false` لوٹائے یا غلطی پیدا کرے۔ +- پراپرٹی کو کال کرتے وقت ضمنی اثر کو مسترد کریں (یعنی، اگر پراپرٹی کسی اسٹیٹ متغیر کو تبدیل کرتی ہے، تو اسے ٹیسٹ کے بعد مسترد کر دیا جاتا ہے) + +درج ذیل پراپرٹی جانچتی ہے کہ کالر کے پاس 1000 سے زیادہ ٹوکن نہیں ہیں: + +```solidity +function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; +} +``` + +اپنے کنٹریکٹ کو اپنی خصوصیات سے الگ کرنے کے لیے وراثت کا استعمال کریں: + +```solidity +contract TestToken is Token{ + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) پراپرٹی کو نافذ کرتا ہے اور ٹوکن سے وراثت میں ملتا ہے۔ + +### ایک کنٹریکٹ شروع کریں {#initiate-a-contract} + +Echidna کو بغیر آرگیومنٹ کے ایک [constructor](/developers/docs/smart-contracts/anatomy/#constructor-functions) کی ضرورت ہے۔ اگر آپ کے کنٹریکٹ کو کسی مخصوص ابتداء کی ضرورت ہے، تو آپ کو اسے کنسٹرکٹر میں کرنا ہوگا۔ + +Echidna میں کچھ مخصوص ایڈریسز ہیں: + +- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` جو کنسٹرکٹر کو کال کرتا ہے۔ +- `0x10000`, `0x20000`، اور `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` جو بے ترتیب طور پر دیگر فنکشنز کو کال کرتے ہیں۔ + +ہمیں اپنی موجودہ مثال میں کسی خاص ابتداء کی ضرورت نہیں ہے، نتیجے کے طور پر ہمارا کنسٹرکٹر خالی ہے۔ + +### Echidna چلائیں {#run-echidna} + +Echidna کو اس کے ساتھ لانچ کیا گیا ہے: + +```bash +echidna-test contract.sol +``` + +اگر contract.sol میں متعدد کنٹریکٹس ہیں، تو آپ ہدف کی وضاحت کر سکتے ہیں: + +```bash +echidna-test contract.sol --contract MyContract +``` + +### خلاصہ: ایک پراپرٹی کی جانچ {#summary-testing-a-property} + +درج ذیل ہماری مثال پر echidna کے چلانے کا خلاصہ کرتا ہے: + +```solidity +contract TestToken is Token{ + constructor() public {} + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +```bash +echidna-test testtoken.sol --contract TestToken +... + +echidna_balance_under_1000: failed!💥 + Call sequence, shrinking (1205/5000): + airdrop() + backdoor() + +... +``` + +Echidna نے پایا کہ اگر `backdoor` کو کال کیا جائے تو پراپرٹی کی خلاف ورزی ہوتی ہے۔ + +## فزنگ مہم کے دوران کال کرنے کے لیے فنکشنز کو فلٹر کرنا {#filtering-functions-to-call-during-a-fuzzing-campaign} + +ہم دیکھیں گے کہ fuzzed کیے جانے والے فنکشنز کو کیسے فلٹر کیا جائے۔ +ہدف درج ذیل اسمارٹ کنٹریکٹ ہے: + +```solidity +contract C { + bool state1 = false; + bool state2 = false; + bool state3 = false; + bool state4 = false; + + function f(uint x) public { + require(x == 12); + state1 = true; + } + + function g(uint x) public { + require(state1); + require(x == 8); + state2 = true; + } + + function h(uint x) public { + require(state2); + require(x == 42); + state3 = true; + } + + function i() public { + require(state3); + state4 = true; + } + + function reset1() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function reset2() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function echidna_state4() public returns (bool) { + return (!state4); + } +} +``` + +یہ چھوٹی سی مثال Echidna کو اسٹیٹ متغیر کو تبدیل کرنے کے لیے لین دین کا ایک خاص سلسلہ تلاش کرنے پر مجبور کرتی ہے۔ +یہ ایک fuzzer کے لیے مشکل ہے (یہ [Manticore](https://github.com/trailofbits/manticore) جیسے علامتی ایگزیکیوشن ٹول استعمال کرنے کی سفارش کی جاتی ہے)۔ +ہم اس کی تصدیق کے لیے Echidna چلا سکتے ہیں: + +```bash +echidna-test multi.sol +... +echidna_state4: passed! 🎉 +Seed: -3684648582249875403 +``` + +### فلٹرنگ فنکشنز {#filtering-functions} + +Echidna کو اس کنٹریکٹ کو جانچنے کے لیے صحیح ترتیب تلاش کرنے میں دشواری ہوتی ہے کیونکہ دو ری سیٹ فنکشنز (`reset1` اور `reset2`) تمام اسٹیٹ متغیرات کو `false` پر سیٹ کر دیں گے۔ +تاہم، ہم ری سیٹ فنکشن کو بلیک لسٹ کرنے یا صرف `f`، `g`، `h` اور `i` فنکشنز کو وائٹ لسٹ کرنے کے لیے ایک خاص Echidna فیچر استعمال کر سکتے ہیں۔ + +فنکشنز کو بلیک لسٹ کرنے کے لیے، ہم یہ کنفیگریشن فائل استعمال کر سکتے ہیں: + +```yaml +filterBlacklist: true +filterFunctions: ["reset1", "reset2"] +``` + +فنکشنز کو فلٹر کرنے کا دوسرا طریقہ وائٹ لسٹڈ فنکشنز کی فہرست بنانا ہے۔ ایسا کرنے کے لیے، ہم یہ کنفیگریشن فائل استعمال کر سکتے ہیں: + +```yaml +filterBlacklist: false +filterFunctions: ["f", "g", "h", "i"] +``` + +- `filterBlacklist` پہلے سے طے شدہ طور پر `true` ہے۔ +- فلٹرنگ صرف نام سے کی جائے گی (پیرامیٹرز کے بغیر)۔ اگر آپ کے پاس `f()` اور `f(uint256)` ہے، تو فلٹر `"f"` دونوں فنکشنز سے مماثل ہوگا۔ + +### Echidna چلائیں {#run-echidna-1} + +کنفیگریشن فائل `blacklist.yaml` کے ساتھ Echidna کو چلانے کے لیے: + +```bash +echidna-test multi.sol --config blacklist.yaml +... +echidna_state4: failed!💥 + Call sequence: + f(12) + g(8) + h(42) + i() +``` + +Echidna تقریباً فوراً پراپرٹی کو غلط ثابت کرنے کے لیے لین دین کا سلسلہ تلاش کر لے گا۔ + +### خلاصہ: فلٹرنگ فنکشنز {#summary-filtering-functions} + +Echidna فزنگ مہم کے دوران کال کرنے کے لیے فنکشنز کو بلیک لسٹ یا وائٹ لسٹ کر سکتا ہے: + +```yaml +filterBlacklist: true +filterFunctions: ["f1", "f2", "f3"] +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +Echidna ایک فزنگ مہم شروع کرتا ہے جو یا تو `f1`، `f2` اور `f3` کو بلیک لسٹ کرتا ہے یا صرف انہیں کال کرتا ہے، `filterBlacklist` بولین کی قدر کے مطابق۔ + +## Echidna کے ساتھ Solidity کے assert کی جانچ کیسے کریں {#how-to-test-soliditys-assert-with-echidna} + +اس مختصر ٹیوٹوریل میں، ہم یہ دکھانے جا رہے ہیں کہ کنٹریکٹس میں اسسرشن چیکنگ کو ٹیسٹ کرنے کے لیے Echidna کا استعمال کیسے کریں۔ آئیے فرض کریں کہ ہمارے پاس اس طرح کا ایک کنٹریکٹ ہے: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + // tmp <= counter + return (counter - tmp); + } +} +``` + +### ایک اسسرشن لکھیں {#write-an-assertion} + +ہم یہ یقینی بنانا چاہتے ہیں کہ `tmp` اس کے فرق کو واپس کرنے کے بعد `counter` سے کم یا اس کے برابر ہے۔ ہم ایک Echidna پراپرٹی لکھ سکتے ہیں، لیکن ہمیں `tmp` ویلیو کو کہیں ذخیرہ کرنے کی ضرورت ہوگی۔ اس کے بجائے، ہم اس طرح کا ایک اسسرشن استعمال کر سکتے ہیں: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +### Echidna چلائیں {#run-echidna-2} + +اسسرشن فیل ہونے کی جانچ کو فعال کرنے کے لیے، ایک [Echidna کنفیگریشن فائل](https://github.com/crytic/echidna/wiki/Config) `config.yaml` بنائیں: + +```yaml +checkAsserts: true +``` + +جب ہم Echidna میں اس کنٹریکٹ کو چلاتے ہیں، تو ہمیں متوقع نتائج ملتے ہیں: + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +جیسا کہ آپ دیکھ سکتے ہیں، Echidna `inc` فنکشن میں کچھ اسسرشن فیل ہونے کی اطلاع دیتا ہے۔ فی فنکشن ایک سے زیادہ اسسرشن شامل کرنا ممکن ہے، لیکن Echidna یہ نہیں بتا سکتا کہ کون سا اسسرشن فیل ہوا۔ + +### اسسرشنز کا استعمال کب اور کیسے کریں {#when-and-how-use-assertions} + +اسسرشنز کو واضح خصوصیات کے متبادل کے طور پر استعمال کیا جا سکتا ہے، خاص طور پر اگر جانچ کی جانے والی شرائط براہ راست کچھ آپریشن `f` کے صحیح استعمال سے متعلق ہوں۔ کچھ کوڈ کے بعد اسسرشنز شامل کرنے سے اس بات کو یقینی بنایا جائے گا کہ چیک اس کے ایگزیکیوٹ ہونے کے فوراً بعد ہوگا: + +```solidity +function f(..) public { + // کچھ پیچیدہ کوڈ + ... + assert (condition); + ... +} + +``` + +اس کے برعکس، ایک واضح echidna پراپرٹی کا استعمال بے ترتیب طور پر ایگزیکیوشن لین دین کرے گا اور اس بات کو نافذ کرنے کا کوئی آسان طریقہ نہیں ہے کہ اسے کب چیک کیا جائے گا۔ یہ حل اب بھی ممکن ہے: + +```solidity +function echidna_assert_after_f() public returns (bool) { + f(..); + return(condition); +} +``` + +تاہم، کچھ مسائل ہیں: + +- یہ ناکام ہو جاتا ہے اگر `f` کو `internal` یا `external` کے طور پر قرار دیا گیا ہو۔ +- یہ واضح نہیں ہے کہ `f` کو کال کرنے کے لیے کون سے دلائل استعمال کیے جائیں۔ +- اگر `f` واپس آجاتا ہے، تو پراپرٹی ناکام ہو جائے گی۔ + +عام طور پر، ہم اسسرشنز کا استعمال کرنے کے طریقے پر [جان ریگیر کی سفارش](https://blog.regehr.org/archives/1091) پر عمل کرنے کی سفارش کرتے ہیں: + +- اسسرشن کی جانچ کے دوران کسی بھی ضمنی اثر پر مجبور نہ کریں۔ مثال کے طور پر: `assert(ChangeStateAndReturn() == 1)` +- واضح بیانات پر زور نہ دیں۔ مثال کے طور پر `assert(var >= 0)` جہاں `var` کو `uint` کے طور پر قرار دیا گیا ہے۔ + +آخر میں، براہ کرم `assert` کے بجائے `require` کا **استعمال نہ کریں**، کیونکہ Echidna اس کا پتہ نہیں لگا سکے گا (لیکن کنٹریکٹ بہرحال واپس آ جائے گا)۔ + +### خلاصہ: اسسرشن کی جانچ {#summary-assertion-checking} + +درج ذیل ہماری مثال پر echidna کے چلانے کا خلاصہ کرتا ہے: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +Echidna نے پایا کہ `inc` میں اسسرشن ناکام ہو سکتا ہے اگر اس فنکشن کو بڑے دلائل کے ساتھ متعدد بار کال کیا جائے۔ + +## Echidna کارپس کو جمع کرنا اور اس میں ترمیم کرنا {#collecting-and-modifying-an-echidna-corpus} + +ہم دیکھیں گے کہ Echidna کے ساتھ لین دین کے کارپس کو کیسے جمع کیا جائے اور استعمال کیا جائے۔ ہدف درج ذیل اسمارٹ کنٹریکٹ [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol) ہے: + +```solidity +contract C { + bool value_found = false; + function magic(uint magic_1, uint magic_2, uint magic_3, uint magic_4) public { + require(magic_1 == 42); + require(magic_2 == 129); + require(magic_3 == magic_4+333); + value_found = true; + return; + } + + function echidna_magic_values() public returns (bool) { + return !value_found; + } + +} +``` + +یہ چھوٹی سی مثال Echidna کو اسٹیٹ متغیر کو تبدیل کرنے کے لیے کچھ مخصوص اقدار تلاش کرنے پر مجبور کرتی ہے۔ یہ ایک fuzzer کے لیے مشکل ہے +(یہ [Manticore](https://github.com/trailofbits/manticore) جیسے علامتی ایگزیکیوشن ٹول استعمال کرنے کی سفارش کی جاتی ہے)۔ +ہم اس کی تصدیق کے لیے Echidna چلا سکتے ہیں: + +```bash +echidna-test magic.sol +... + +echidna_magic_values: passed! 🎉 + +Seed: 2221503356319272685 +``` + +تاہم، ہم اب بھی اس فزنگ مہم کو چلاتے وقت کارپس جمع کرنے کے لیے Echidna کا استعمال کر سکتے ہیں۔ + +### کارپس جمع کرنا {#collecting-a-corpus} + +کارپس جمع کرنے کو فعال کرنے کے لیے، ایک کارپس ڈائریکٹری بنائیں: + +```bash +mkdir corpus-magic +``` + +اور ایک [Echidna کنفیگریشن فائل](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: + +```yaml +coverage: true +corpusDir: "corpus-magic" +``` + +اب ہم اپنا ٹول چلا سکتے ہیں اور جمع شدہ کارپس کی جانچ کر سکتے ہیں: + +```bash +echidna-test magic.sol --config config.yaml +``` + +Echidna اب بھی صحیح جادوئی اقدار نہیں ڈھونڈ سکتا، لیکن ہم اس کے جمع کردہ کارپس پر ایک نظر ڈال سکتے ہیں۔ +مثال کے طور پر، ان میں سے ایک فائل یہ تھی: + +```json +[ + { + "_gas'": "0xffffffff", + "_delay": ["0x13647", "0xccf6"], + "_src": "00a329c0648769a73afac7f9381e08fb43dbea70", + "_dst": "00a329c0648769a73afac7f9381e08fb43dbea72", + "_value": "0x0", + "_call": { + "tag": "SolCall", + "contents": [ + "magic", + [ + { + "contents": [ + 256, + "93723985220345906694500679277863898678726808528711107336895287282192244575836" + ], + "tag": "AbiUInt" + }, + { + "contents": [256, "334"], + "tag": "AbiUInt" + }, + { + "contents": [ + 256, + "68093943901352437066264791224433559271778087297543421781073458233697135179558" + ], + "tag": "AbiUInt" + }, + { + "tag": "AbiUInt", + "contents": [256, "332"] + } + ] + ] + }, + "_gasprice'": "0xa904461f1" + } +] +``` + +واضح طور پر، یہ ان پٹ ہماری پراپرٹی میں ناکامی کو متحرک نہیں کرے گا۔ تاہم، اگلے مرحلے میں، ہم دیکھیں گے کہ اس کے لیے اسے کیسے تبدیل کیا جائے۔ + +### کارپس کو سیڈ کرنا {#seeding-a-corpus} + +`magic` فنکشن سے نمٹنے کے لیے Echidna کو کچھ مدد کی ضرورت ہے۔ ہم اس کے لیے موزوں پیرامیٹرز استعمال کرنے کے لیے ان پٹ کو کاپی اور ترمیم کرنے جا رہے ہیں: + +```bash +cp corpus/2712688662897926208.txt corpus/new.txt +``` + +ہم `new.txt` کو `magic(42,129,333,0)` کال کرنے کے لیے تبدیل کریں گے۔ اب، ہم Echidna کو دوبارہ چلا سکتے ہیں: + +```bash +echidna-test magic.sol --config config.yaml +... +echidna_magic_values: failed!💥 + Call sequence: + magic(42,129,333,0) + + +Unique instructions: 142 +Unique codehashes: 1 +Seed: -7293830866560616537 + +``` + +اس بار، اس نے پایا کہ پراپرٹی کی فوری طور پر خلاف ورزی ہوئی ہے۔ + +## زیادہ گیس کی کھپت والے لین دین کی تلاش {#finding-transactions-with-high-gas-consumption} + +ہم دیکھیں گے کہ Echidna کے ساتھ زیادہ گیس کی کھپت والے لین دین کو کیسے تلاش کیا جائے۔ ہدف درج ذیل اسمارٹ کنٹریکٹ ہے: + +```solidity +contract C { + uint state; + + function expensive(uint8 times) internal { + for(uint8 i=0; i < times; i++) + state = state + i; + } + + function f(uint x, uint y, uint8 times) public { + if (x == 42 && y == 123) + expensive(times); + else + state = 0; + } + + function echidna_test() public returns (bool) { + return true; + } + +} +``` + +یہاں `expensive` میں گیس کی بڑی کھپت ہو سکتی ہے۔ + +فی الحال، Echidna کو ہمیشہ جانچ کے لیے ایک پراپرٹی کی ضرورت ہوتی ہے: یہاں `echidna_test` ہمیشہ `true` لوٹاتا ہے۔ +ہم اس کی تصدیق کے لیے Echidna چلا سکتے ہیں: + +``` +echidna-test gas.sol +... +echidna_test: passed! 🎉 + +Seed: 2320549945714142710 +``` + +### گیس کی کھپت کی پیمائش {#measuring-gas-consumption} + +Echidna کے ساتھ گیس کی کھپت کو فعال کرنے کے لیے، ایک کنفیگریشن فائل `config.yaml` بنائیں: + +```yaml +estimateGas: true +``` + +اس مثال میں، ہم نتائج کو سمجھنے میں آسانی پیدا کرنے کے لیے لین دین کی ترتیب کے سائز کو بھی کم کریں گے: + +```yaml +seqLen: 2 +estimateGas: true +``` + +### Echidna چلائیں {#run-echidna-3} + +ایک بار جب ہم کنفیگریشن فائل بنا لیں، تو ہم Echidna کو اس طرح چلا سکتے ہیں: + +```bash +echidna-test gas.sol --config config.yaml +... +echidna_test: passed! 🎉 + +f used a maximum of 1333608 gas + Call sequence: + f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2 + +Unique instructions: 157 +Unique codehashes: 1 +Seed: -325611019680165325 + +``` + +- دکھائی گئی گیس [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-) کے ذریعے فراہم کردہ ایک تخمینہ ہے۔ + +### گیس کم کرنے والی کالز کو فلٹر کرنا {#filtering-out-gas-reducing-calls} + +اوپر **فزنگ مہم کے دوران کال کرنے کے لیے فنکشنز کو فلٹر کرنے** پر ٹیوٹوریل دکھاتا ہے کہ آپ کی جانچ سے کچھ فنکشنز کو کیسے ہٹایا جائے۔ +گیس کا درست تخمینہ حاصل کرنے کے لیے یہ اہم ہو سکتا ہے۔ +درج ذیل مثال پر غور کریں: + +```solidity +contract C { + address [] addrs; + function push(address a) public { + addrs.push(a); + } + function pop() public { + addrs.pop(); + } + function clear() public{ + addrs.length = 0; + } + function check() public{ + for(uint256 i = 0; i < addrs.length; i++) + for(uint256 j = i+1; j < addrs.length; j++) + if (addrs[i] == addrs[j]) + addrs[j] = address(0x0); + } + function echidna_test() public returns (bool) { + return true; + } +} +``` + +اگر Echidna تمام فنکشنز کو کال کر سکتا ہے، تو اسے زیادہ گیس لاگت والے لین دین آسانی سے نہیں ملیں گے: + +``` +echidna-test pushpop.sol --config config.yaml +... +pop used a maximum of 10746 gas +... +check used a maximum of 23730 gas +... +clear used a maximum of 35916 gas +... +push used a maximum of 40839 gas +``` + +اس کی وجہ یہ ہے کہ لاگت `addrs` کے سائز پر منحصر ہے اور بے ترتیب کالز صف کو تقریباً خالی چھوڑ دیتی ہیں۔ +`pop` اور `clear` کو بلیک لسٹ کرنے سے، تاہم، ہمیں بہت بہتر نتائج ملتے ہیں: + +```yaml +filterBlacklist: true +filterFunctions: ["pop", "clear"] +``` + +``` +echidna-test pushpop.sol --config config.yaml +... +push used a maximum of 40839 gas +... +check used a maximum of 1484472 gas +``` + +### خلاصہ: زیادہ گیس کی کھپت والے لین دین کی تلاش {#summary-finding-transactions-with-high-gas-consumption} + +Echidna `estimateGas` کنفیگریشن آپشن کا استعمال کرکے زیادہ گیس کی کھپت والے لین دین تلاش کر سکتا ہے: + +```yaml +estimateGas: true +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +Echidna ہر فنکشن کے لیے زیادہ سے زیادہ گیس کی کھپت کے ساتھ ایک ترتیب کی اطلاع دے گا، جب فزنگ مہم ختم ہو جائے گی۔