From af87aee5dcc20da2bcc5300a0094bc8c09e3cb40 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:09:20 +0000 Subject: [PATCH 1/2] i18n(ur): translation import part 08 of 13 (23 files) --- .../index.md | 526 +++++++ .../index.md | 233 +++ .../how-to-use-tellor-as-your-oracle/index.md | 81 + .../how-to-view-nft-in-metamask/index.md | 33 + .../how-to-write-and-deploy-an-nft/index.md | 380 +++++ .../index.md | 179 +++ .../tutorials/ipfs-decentralized-ui/index.md | 73 + .../index.md | 111 ++ .../index.md | 269 ++++ .../logging-events-smart-contracts/index.md | 62 + .../index.md | 247 +++ .../index.md | 151 ++ .../developers/tutorials/nft-minter/index.md | 874 +++++++++++ .../index.md | 1354 +++++++++++++++++ .../reverse-engineering-a-contract/index.md | 744 +++++++++ .../tutorials/run-node-raspberry-pi/index.md | 184 +++ .../tutorials/scam-token-tricks/index.md | 470 ++++++ .../tutorials/secret-state/index.md | 741 +++++++++ .../secure-development-workflow/index.md | 52 + .../tutorials/send-token-ethersjs/index.md | 210 +++ .../index.md | 208 +++ .../tutorials/server-components/index.md | 295 ++++ .../index.md | 92 ++ 23 files changed, 7569 insertions(+) create mode 100644 public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md create mode 100644 public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md create mode 100644 public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md create mode 100644 public/content/translations/ur/developers/tutorials/how-to-view-nft-in-metamask/index.md create mode 100644 public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md create mode 100644 public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md create mode 100644 public/content/translations/ur/developers/tutorials/ipfs-decentralized-ui/index.md create mode 100644 public/content/translations/ur/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md create mode 100644 public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md create mode 100644 public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md create mode 100644 public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md create mode 100644 public/content/translations/ur/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md create mode 100644 public/content/translations/ur/developers/tutorials/nft-minter/index.md create mode 100644 public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md create mode 100644 public/content/translations/ur/developers/tutorials/reverse-engineering-a-contract/index.md create mode 100644 public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md create mode 100644 public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md create mode 100644 public/content/translations/ur/developers/tutorials/secret-state/index.md create mode 100644 public/content/translations/ur/developers/tutorials/secure-development-workflow/index.md create mode 100644 public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md create mode 100644 public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md create mode 100644 public/content/translations/ur/developers/tutorials/server-components/index.md create mode 100644 public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md new file mode 100644 index 00000000000..47c472e1fa1 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md @@ -0,0 +1,526 @@ +--- +title: "اسمارٹ کنٹریکٹس میں بگز تلاش کرنے کے لیے Manticore کا استعمال کیسے کریں" +description: "اسمارٹ کنٹریکٹس میں خود بخود بگز تلاش کرنے کے لیے Manticore کا استعمال کیسے کریں" +author: Trailofbits +lang: ur-in +tags: + [ + "solidity", + "اسمارٹ معاہدات", + "سیکورٹی", + "testing", + "رسمی تصدیق" + ] +skill: advanced +published: 2020-01-13 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore +--- + +اس ٹیوٹوریل کا مقصد یہ دکھانا ہے کہ اسمارٹ کنٹریکٹس میں خود بخود بگز تلاش کرنے کے لیے Manticore کا استعمال کیسے کیا جائے۔ + +## انسٹالیشن {#installation} + +Manticore کے لیے >= python 3.6 درکار ہے۔ اسے pip کے ذریعے یا docker کا استعمال کرکے انسٹال کیا جاسکتا ہے۔ + +### docker کے ذریعے Manticore {#manticore-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/trufflecon/ +``` + +### pip کے ذریعے Manticore {#manticore-through-pip} + +```bash +pip3 install --user manticore +``` + +solc 0.5.11 تجویز کیا جاتا ہے۔ + +### ایک اسکرپٹ چلانا {#running-a-script} + +python 3 کے ساتھ ایک python اسکرپٹ چلانے کے لیے: + +```bash +python3 script.py +``` + +## ڈائنامک سمبولک ایگزیکیوشن کا تعارف {#introduction-to-dynamic-symbolic-execution} + +### مختصر طور پر ڈائنامک سمبولک ایگزیکیوشن {#dynamic-symbolic-execution-in-a-nutshell} + +ڈائنامک سمبولک ایگزیکیوشن (DSE) پروگرام کے تجزیے کی ایک تکنیک ہے جو اعلیٰ درجے کی سیمانٹک بیداری کے ساتھ اسٹیٹ اسپیس کو تلاش کرتی ہے۔ یہ تکنیک "پروگرام پاتھس" کی دریافت پر مبنی ہے، جسے `path predicates` کہلانے والے ریاضیاتی فارمولوں کے طور پر پیش کیا جاتا ہے۔ تصوراتی طور پر، یہ تکنیک دو مراحل میں پاتھ پریڈیکیٹس پر کام کرتی ہے: + +1. یہ پروگرام کے ان پٹ پر پابندیوں کا استعمال کرتے ہوئے تعمیر کیے جاتے ہیں۔ +2. یہ ایسے پروگرام ان پٹس پیدا کرنے کے لیے استعمال ہوتے ہیں جو متعلقہ پاتھس کو ایگزیکیوٹ کرنے کا سبب بنیں گے۔ + +یہ نقطہ نظر اس لحاظ سے کوئی غلط مثبت پیدا نہیں کرتا ہے کہ تمام شناخت شدہ پروگرام اسٹیٹس کو ٹھوس ایگزیکیوشن کے دوران ٹرگر کیا جا سکتا ہے۔ مثال کے طور پر، اگر تجزیہ میں کوئی انٹیجر اوور فلو ملتا ہے، تو اس کے دوبارہ پیدا کیے جانے کی ضمانت ہے۔ + +### پاتھ پریڈیکیٹ کی مثال {#path-predicate-example} + +DSE کیسے کام کرتا ہے اس کی بصیرت حاصل کرنے کے لیے، درج ذیل مثال پر غور کریں: + +```solidity +function f(uint a){ + + if (a == 65) { + // ایک بگ موجود ہے + } + +} +``` + +چونکہ `f()` میں دو پاتھس ہیں، اس لیے ایک DSE دو مختلف پاتھ پریڈیکیٹس بنائے گا: + +- پاتھ 1: `a == 65` +- پاتھ 2: `Not (a == 65)` + +ہر پاتھ پریڈیکیٹ ایک ریاضیاتی فارمولا ہے جسے [SMT solver](https://wikipedia.org/wiki/Satisfiability_modulo_theories) نامی ایک نام نہاد کو دیا جا سکتا ہے، جو مساوات کو حل کرنے کی کوشش کرے گا۔ `پاتھ 1` کے لیے، سولور کہے گا کہ پاتھ کو `a = 65` کے ساتھ تلاش کیا جا سکتا ہے۔ `پاتھ 2` کے لیے، سولور `a` کو 65 کے علاوہ کوئی بھی قدر دے سکتا ہے، مثال کے طور پر `a = 0`۔ + +### خصوصیات کی تصدیق کرنا {#verifying-properties} + +Manticore ہر پاتھ کے تمام ایگزیکیوشن پر مکمل کنٹرول کی اجازت دیتا ہے۔ نتیجے کے طور پر، یہ آپ کو تقریباً کسی بھی چیز پر من مانی پابندیاں شامل کرنے کی اجازت دیتا ہے۔ یہ کنٹرول کنٹریکٹ پر خصوصیات بنانے کی اجازت دیتا ہے۔ + +درج ذیل مثال پر غور کریں: + +```solidity +function unsafe_add(uint a, uint b) returns(uint c){ + c = a + b; // کوئی اوور فلو تحفظ نہیں + return c; +} +``` + +یہاں فنکشن میں تلاش کرنے کے لیے صرف ایک پاتھ ہے: + +- پاتھ 1: `c = a + b` + +Manticore کا استعمال کرتے ہوئے، آپ اوور فلو کی جانچ کر سکتے ہیں، اور پاتھ پریڈیکیٹ میں پابندیاں شامل کر سکتے ہیں: + +- `c = a + b AND (c < a OR c < b)` + +اگر `a` اور `b` کی ایسی ویلیویشن تلاش کرنا ممکن ہے جس کے لیے مذکورہ بالا پاتھ پریڈیکیٹ قابل عمل ہے، تو اس کا مطلب ہے کہ آپ کو ایک اوور فلو مل گیا ہے۔ مثال کے طور پر سولور ان پٹ `a = 10 , b = MAXUINT256` پیدا کر سکتا ہے۔ + +اگر آپ ایک فکسڈ ورژن پر غور کریں: + +```solidity +function safe_add(uint a, uint b) returns(uint c){ + c = a + b; + require(c>=a); + require(c>=b); + return c; +} +``` + +اوور فلو چیک کے ساتھ متعلقہ فارمولا ہوگا: + +- `c = a + b AND (c >= a) AND (c=>b) AND (c < a OR c < b)` + +اس فارمولے کو حل نہیں کیا جا سکتا؛ دوسرے لفظوں میں یہ ایک **ثبوت** ہے کہ `safe_add` میں، `c` ہمیشہ بڑھے گا۔ + +DSE اس طرح ایک طاقتور ٹول ہے، جو آپ کے کوڈ پر من مانی پابندیوں کی تصدیق کر سکتا ہے۔ + +## Manticore کے تحت چلانا {#running-under-manticore} + +ہم دیکھیں گے کہ Manticore API کے ساتھ ایک اسمارٹ کنٹریکٹ کو کیسے تلاش کیا جائے۔ ہدف درج ذیل اسمارٹ کنٹریکٹ [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) ہے: + +```solidity +pragma solidity >=0.4.24 <0.6.0; + +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### ایک اسٹینڈ الون ایکسپلوریشن چلائیں {#run-a-standalone-exploration} + +آپ درج ذیل کمانڈ کے ذریعے Manticore کو براہ راست اسمارٹ کنٹریکٹ پر چلا سکتے ہیں (`پروجیکٹ` ایک Solidity فائل، یا ایک پروجیکٹ ڈائریکٹری ہو سکتا ہے): + +```bash +$ manticore project +``` + +آپ کو اس طرح کے ٹیسٹ کیسز کا آؤٹ پٹ ملے گا (ترتیب بدل سکتی ہے): + +``` +... +... m.c.manticore:INFO: Generated testcase No. 0 - STOP +... m.c.manticore:INFO: Generated testcase No. 1 - REVERT +... m.c.manticore:INFO: Generated testcase No. 2 - RETURN +... m.c.manticore:INFO: Generated testcase No. 3 - REVERT +... m.c.manticore:INFO: Generated testcase No. 4 - STOP +... m.c.manticore:INFO: Generated testcase No. 5 - REVERT +... m.c.manticore:INFO: Generated testcase No. 6 - REVERT +... m.c.manticore:INFO: Results in /home/ethsec/workshops/Automated Smart Contracts Audit - TruffleCon 2018/manticore/examples/mcore_t6vi6ij3 +... +``` + +اضافی معلومات کے بغیر، Manticore نئے سمبولک +ٹرانزیکشنز کے ساتھ کنٹریکٹ کو اس وقت تک تلاش کرے گا جب تک کہ وہ کنٹریکٹ پر نئے پاتھس کو تلاش نہ کر لے۔ Manticore ایک ناکام ٹرانزیکشن کے بعد (مثال کے طور پر: ایک revert کے بعد) نئے ٹرانزیکشنز نہیں چلاتا ہے۔ + +Manticore معلومات کو ایک `mcore_*` ڈائریکٹری میں آؤٹ پٹ کرے گا۔ دیگر چیزوں کے علاوہ، آپ کو اس ڈائریکٹری میں ملے گا: + +- `global.summary`: کوریج اور کمپائلر وارننگز +- `test_XXXXX.summary`: کوریج، آخری ہدایت، فی ٹیسٹ کیس اکاؤنٹ بیلنس +- `test_XXXXX.tx`: فی ٹیسٹ کیس ٹرانزیکشنز کی تفصیلی فہرست + +یہاں Manticore کو 7 ٹیسٹ کیسز ملے ہیں، جو اس کے مطابق ہیں (فائل نام کی ترتیب بدل سکتی ہے): + +| | ٹرانزیکشن 0 | ٹرانزیکشن 1 | ٹرانزیکشن 2 | نتیجہ | +| :-------------------------------------------------------: | :--------------: | :------------------------: | -------------------------- | :----: | +| **test_00000000.tx** | کنٹریکٹ کی تخلیق | f(!=65) | f(!=65) | STOP | +| **test_00000001.tx** | کنٹریکٹ کی تخلیق | فال بیک فنکشن | | REVERT | +| **test_00000002.tx** | کنٹریکٹ کی تخلیق | | | RETURN | +| **test_00000003.tx** | کنٹریکٹ کی تخلیق | f(65) | | REVERT | +| **test_00000004.tx** | کنٹریکٹ کی تخلیق | f(!=65) | | STOP | +| **test_00000005.tx** | کنٹریکٹ کی تخلیق | f(!=65) | f(65) | REVERT | +| **test_00000006.tx** | کنٹریکٹ کی تخلیق | f(!=65) | فال بیک فنکشن | REVERT | + +_ایکسپلوریشن کا خلاصہ f(!=65) ظاہر کرتا ہے کہ f کو 65 سے مختلف کسی بھی قدر کے ساتھ کال کیا گیا ہے۔_ + +جیسا کہ آپ دیکھ سکتے ہیں، Manticore ہر کامیاب یا واپس کیے گئے ٹرانزیکشن کے لیے ایک منفرد ٹیسٹ کیس تیار کرتا ہے۔ + +اگر آپ تیز کوڈ ایکسپلوریشن چاہتے ہیں تو `--quick-mode` فلیگ کا استعمال کریں (یہ بگ ڈیٹیکٹرز، گیس کمپیوٹیشن، ... کو غیر فعال کر دیتا ہے) + +### API کے ذریعے ایک اسمارٹ کنٹریکٹ میں ہیرا پھیری کرنا {#manipulate-a-smart-contract-through-the-api} + +یہ سیکشن Manticore Python API کے ذریعے ایک اسمارٹ کنٹریکٹ میں ہیرا پھیری کرنے کے طریقے کی تفصیلات بیان کرتا ہے۔ آپ python ایکسٹینشن `*.py` کے ساتھ نئی فائل بنا سکتے ہیں اور اس فائل میں API کمانڈز (جن کی بنیادی باتیں ذیل میں بیان کی جائیں گی) کو شامل کرکے ضروری کوڈ لکھ سکتے ہیں اور پھر اسے `$ python3 *.py` کمانڈ کے ساتھ چلا سکتے ہیں۔ آپ ذیل میں دی گئی کمانڈز کو براہ راست python کنسول میں بھی ایگزیکیوٹ کر سکتے ہیں، کنسول چلانے کے لیے `$ python3` کمانڈ کا استعمال کریں۔ + +### اکاؤنٹس بنانا {#creating-accounts} + +سب سے پہلے آپ کو درج ذیل کمانڈز کے ساتھ ایک نئی بلاک چین شروع کرنی چاہیے: + +```python +from manticore.ethereum import ManticoreEVM + +m = ManticoreEVM() +``` + +ایک غیر کنٹریکٹ اکاؤنٹ [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) کا استعمال کرتے ہوئے بنایا جاتا ہے: + +```python +user_account = m.create_account(balance=1000) +``` + +ایک Solidity کنٹریکٹ [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract) کا استعمال کرتے ہوئے تعینات کیا جا سکتا ہے: + +```solidity +source_code = ''' +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +''' +# کنٹریکٹ شروع کریں +contract_account = m.solidity_create_contract(source_code, owner=user_account) +``` + +#### خلاصہ {#summary} + +- آپ [m.create_account](https://manticore.readthedocs.io/en/latest/evm.html?highlight=create_account#manticore.ethereum.ManticoreEVM.create_account) اور [m.solidity_create_contract](https://manticore.readthedocs.io/en/latest/evm.html?highlight=solidity_create#manticore.ethereum.ManticoreEVM.create_contract) کے ساتھ صارف اور کنٹریکٹ اکاؤنٹس بنا سکتے ہیں۔ + +### ٹرانزیکشنز کو ایگزیکیوٹ کرنا {#executing-transactions} + +Manticore دو قسم کے ٹرانزیکشن کو سپورٹ کرتا ہے: + +- را ٹرانزیکشن: تمام فنکشنز کو تلاش کیا جاتا ہے +- نامزد ٹرانزیکشن: صرف ایک فنکشن کو تلاش کیا جاتا ہے + +#### را ٹرانزیکشن {#raw-transaction} + +ایک را ٹرانزیکشن [m.transaction](https://manticore.readthedocs.io/en/latest/evm.html?highlight=transaction#manticore.ethereum.ManticoreEVM.transaction) کا استعمال کرتے ہوئے ایگزیکیوٹ کیا جاتا ہے: + +```python +m.transaction(caller=user_account, + address=contract_account, + data=data, + value=value) +``` + +ٹرانزیکشن کا کالر، ایڈریس، ڈیٹا، یا ویلیو یا تو ٹھوس یا سمبولک ہو سکتا ہے: + +- [m.make_symbolic_value](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_value#manticore.ethereum.ManticoreEVM.make_symbolic_value) ایک سمبولک ویلیو بناتا ہے۔ +- [m.make_symbolic_buffer(size)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=make_symbolic_buffer#manticore.ethereum.ManticoreEVM.make_symbolic_buffer) ایک سمبولک بائٹ ایرے بناتا ہے۔ + +مثال کے طور پر: + +```python +symbolic_value = m.make_symbolic_value() +symbolic_data = m.make_symbolic_buffer(320) +m.transaction(caller=user_account, + address=contract_address, + data=symbolic_data, + value=symbolic_value) +``` + +اگر ڈیٹا سمبولک ہے، تو Manticore ٹرانزیکشن ایگزیکیوشن کے دوران کنٹریکٹ کے تمام فنکشنز کو تلاش کرے گا۔ فنکشن کا انتخاب کیسے کام کرتا ہے، یہ سمجھنے کے لیے [Hands on the Ethernaut CTF](https://blog.trailofbits.com/2017/11/06/hands-on-the-ethernaut-ctf/) مضمون میں فال بیک فنکشن کی وضاحت دیکھنا مددگار ہوگا۔ + +#### نامزد ٹرانزیکشن {#named-transaction} + +فنکشنز کو ان کے نام کے ذریعے ایگزیکیوٹ کیا جا سکتا ہے۔ +`f(uint var)` کو ایک سمبولک ویلیو کے ساتھ، user_account سے، اور 0 ایتھر کے ساتھ ایگزیکیوٹ کرنے کے لیے، استعمال کریں: + +```python +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var, caller=user_account, value=0) +``` + +اگر ٹرانزیکشن کی `value` کی وضاحت نہیں کی گئی ہے، تو یہ بطور ڈیفالٹ 0 ہے۔ + +#### خلاصہ {#summary-1} + +- ایک ٹرانزیکشن کے آرگومنٹس ٹھوس یا سمبولک ہو سکتے ہیں +- ایک را ٹرانزیکشن تمام فنکشنز کو تلاش کرے گا +- فنکشن کو ان کے نام سے کال کیا جا سکتا ہے + +### ورک اسپیس {#workspace} + +`m.workspace` وہ ڈائریکٹری ہے جو تمام تیار کردہ فائلوں کے لیے آؤٹ پٹ ڈائریکٹری کے طور پر استعمال ہوتی ہے: + +```python +print("نتائج {} میں ہیں".format(m.workspace)) +``` + +### ایکسپلوریشن کو ختم کریں {#terminate-the-exploration} + +ایکسپلوریشن کو روکنے کے لیے [m.finalize()](https://manticore.readthedocs.io/en/latest/evm.html?highlight=finalize#manticore.ethereum.ManticoreEVM.finalize) کا استعمال کریں۔ ایک بار یہ طریقہ کال ہو جانے کے بعد مزید کوئی ٹرانزیکشن نہیں بھیجا جانا چاہیے اور Manticore ہر تلاش کیے گئے پاتھ کے لیے ٹیسٹ کیسز تیار کرتا ہے۔ + +### خلاصہ: Manticore کے تحت چلانا {#summary-running-under-manticore} + +پچھلے تمام مراحل کو ایک ساتھ رکھنے پر، ہم حاصل کرتے ہیں: + +```python +from manticore.ethereum import ManticoreEVM + +m = ManticoreEVM() + +with open('example.sol') as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +print("نتائج {} میں ہیں".format(m.workspace)) +m.finalize() # ایکسپلوریشن کو روکیں +``` + +اوپر دیا گیا تمام کوڈ آپ [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) میں تلاش کر سکتے ہیں + +## تھروئنگ پاتھس حاصل کرنا {#getting-throwing-paths} + +اب ہم `f()` میں استثناء پیدا کرنے والے پاتھس کے لیے مخصوص ان پٹس تیار کریں گے۔ ہدف اب بھی درج ذیل اسمارٹ کنٹریکٹ [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) ہے: + +```solidity +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### اسٹیٹ کی معلومات کا استعمال {#using-state-information} + +ہر ایگزیکیوٹ ہونے والے پاتھ کی بلاک چین کی اپنی اسٹیٹ ہوتی ہے۔ ایک اسٹیٹ یا تو تیار ہوتی ہے یا اسے ختم کر دیا جاتا ہے، جس کا مطلب ہے کہ یہ ایک THROW یا REVERT ہدایت تک پہنچ جاتی ہے: + +- [m.ready_states](https://manticore.readthedocs.io/en/latest/states.html#accessing): تیار اسٹیٹس کی فہرست (انہوں نے REVERT/INVALID ایگزیکیوٹ نہیں کیا) +- [m.killed_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): ختم شدہ اسٹیٹس کی فہرست +- [m.all_states](https://manticore.readthedocs.io/en/latest/states.html#accessings): تمام اسٹیٹس + +```python +for state in m.all_states: + # اسٹیٹ کے ساتھ کچھ کریں +``` + +آپ اسٹیٹ کی معلومات تک رسائی حاصل کر سکتے ہیں۔ مثال کے طور پر: + +- `state.platform.get_balance(account.address)`: اکاؤنٹ کا بیلنس +- `state.platform.transactions`: ٹرانزیکشنز کی فہرست +- `state.platform.transactions[-1].return_data`: آخری ٹرانزیکشن کے ذریعے واپس کیا گیا ڈیٹا + +آخری ٹرانزیکشن کے ذریعے واپس کیا گیا ڈیٹا ایک ایرے ہے، جسے ABI.deserialize کے ساتھ ایک ویلیو میں تبدیل کیا جا سکتا ہے، مثال کے طور پر: + +```python +data = state.platform.transactions[0].return_data +data = ABI.deserialize("uint", data) +``` + +### ٹیسٹ کیس کیسے تیار کریں {#how-to-generate-testcase} + +ٹیسٹ کیس تیار کرنے کے لیے [m.generate_testcase(state, name)](https://manticore.readthedocs.io/en/latest/evm.html?highlight=generate_testcase#manticore.ethereum.ManticoreEVM.generate_testcase) کا استعمال کریں: + +```python +m.generate_testcase(state, 'BugFound') +``` + +### خلاصہ {#summary-2} + +- آپ m.all_states کے ساتھ اسٹیٹ پر اعادہ کر سکتے ہیں +- `state.platform.get_balance(account.address)` اکاؤنٹ کا بیلنس واپس کرتا ہے +- `state.platform.transactions` ٹرانزیکشنز کی فہرست واپس کرتا ہے +- `transaction.return_data` واپس کیا گیا ڈیٹا ہے +- `m.generate_testcase(state, name)` اسٹیٹ کے لیے ان پٹس تیار کرتا ہے + +### خلاصہ: تھروئنگ پاتھ حاصل کرنا {#summary-getting-throwing-path} + +```python +from manticore.ethereum import ManticoreEVM + +m = ManticoreEVM() + +with open('example.sol') as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +## چیک کریں کہ کیا کوئی ایگزیکیوشن REVERT یا INVALID کے ساتھ ختم ہوتا ہے + +for state in m.terminated_states: + last_tx = state.platform.transactions[-1] + if last_tx.result in ['REVERT', 'INVALID']: + print('تھرو ملا {}'.format(m.workspace)) + m.generate_testcase(state, 'ThrowFound') +``` + +اوپر دیا گیا تمام کوڈ آپ [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) میں تلاش کر سکتے ہیں + +_نوٹ کریں کہ ہم ایک بہت آسان اسکرپٹ تیار کر سکتے تھے، کیونکہ terminated_state کے ذریعے واپس کی گئی تمام اسٹیٹس کے نتیجے میں REVERT یا INVALID ہوتا ہے: اس مثال کا مقصد صرف یہ دکھانا تھا کہ API میں ہیرا پھیری کیسے کی جائے۔_ + +## پابندیاں شامل کرنا {#adding-constraints} + +ہم دیکھیں گے کہ ایکسپلوریشن کو کیسے محدود کیا جائے۔ ہم یہ فرض کریں گے کہ `f()` کی +دستاویزات میں کہا گیا ہے کہ فنکشن کو کبھی بھی `a == 65` کے ساتھ کال نہیں کیا جاتا، لہذا `a == 65` والا کوئی بھی بگ حقیقی بگ نہیں ہے۔ ہدف اب بھی درج ذیل اسمارٹ کنٹریکٹ [`example.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example.sol) ہے: + +```solidity +pragma solidity >=0.4.24 <0.6.0; +contract Simple { + function f(uint a) payable public{ + if (a == 65) { + revert(); + } + } +} +``` + +### آپریٹرز {#operators} + +[Operators](https://github.com/trailofbits/manticore/blob/master/manticore/core/smtlib/operators.py) ماڈیول پابندیوں کی ہیرا پھیری میں سہولت فراہم کرتا ہے، دیگر چیزوں کے علاوہ یہ فراہم کرتا ہے: + +- Operators.AND, +- Operators.OR, +- Operators.UGT (غیر دستخط شدہ سے بڑا), +- Operators.UGE (غیر دستخط شدہ سے بڑا یا برابر)، +- Operators.ULT (غیر دستخط شدہ سے کم)، +- Operators.ULE (غیر دستخط شدہ سے کم یا برابر)۔ + +ماڈیول کو امپورٹ کرنے کے لیے درج ذیل کا استعمال کریں: + +```python +from manticore.core.smtlib import Operators +``` + +`Operators.CONCAT` ایک ایرے کو ایک ویلیو سے جوڑنے کے لیے استعمال کیا جاتا ہے۔ مثال کے طور پر، ایک ٹرانزیکشن کے return_data کو ایک ویلیو میں تبدیل کرنے کی ضرورت ہے تاکہ اسے دوسری ویلیو کے خلاف چیک کیا جا سکے: + +```python +last_return = Operators.CONCAT(256, *last_return) +``` + +### پابندیاں {#state-constraint} + +آپ پابندیوں کا استعمال عالمی سطح پر یا کسی مخصوص اسٹیٹ کے لیے کر سکتے ہیں۔ + +#### عالمی پابندی {#state-constraint} + +عالمی پابندی شامل کرنے کے لیے `m.constrain(constraint)` کا استعمال کریں۔ +مثال کے طور پر، آپ ایک سمبولک ایڈریس سے ایک کنٹریکٹ کو کال کر سکتے ہیں، اور اس ایڈریس کو مخصوص ویلیوز تک محدود کر سکتے ہیں: + +```python +symbolic_address = m.make_symbolic_value() +m.constraint(Operators.OR(symbolic == 0x41, symbolic_address == 0x42)) +m.transaction(caller=user_account, + address=contract_account, + data=m.make_symbolic_buffer(320), + value=0) +``` + +#### اسٹیٹ کی پابندی {#state-constraint} + +کسی مخصوص اسٹیٹ میں پابندی شامل کرنے کے لیے [state.constrain(constraint)](https://manticore.readthedocs.io/en/latest/states.html?highlight=StateBase#manticore.core.state.StateBase.constrain) کا استعمال کریں۔ +اس کا استعمال اسٹیٹ کو اس کی ایکسپلوریشن کے بعد محدود کرنے کے لیے کیا جا سکتا ہے تاکہ اس پر کچھ خصوصیت کی جانچ کی جا سکے۔ + +### پابندی کی جانچ کرنا {#checking-constraint} + +یہ جاننے کے لیے کہ کیا کوئی پابندی اب بھی قابل عمل ہے، `solver.check(state.constraints)` کا استعمال کریں۔ +مثال کے طور پر، درج ذیل `symbolic_value` کو 65 سے مختلف ہونے پر مجبور کرے گا اور یہ جانچے گا کہ کیا اسٹیٹ اب بھی قابل عمل ہے: + +```python +state.constrain(symbolic_var != 65) +if solver.check(state.constraints): + # اسٹیٹ قابل عمل ہے +``` + +### خلاصہ: پابندیاں شامل کرنا {#summary-adding-constraints} + +پچھلے کوڈ میں پابندی شامل کرنے پر، ہم حاصل کرتے ہیں: + +```python +from manticore.ethereum import ManticoreEVM +from manticore.core.smtlib.solver import Z3Solver + +solver = Z3Solver.instance() + +m = ManticoreEVM() + +with open("example.sol") as f: + source_code = f.read() + +user_account = m.create_account(balance=1000) +contract_account = m.solidity_create_contract(source_code, owner=user_account) + +symbolic_var = m.make_symbolic_value() +contract_account.f(symbolic_var) + +no_bug_found = True + +## چیک کریں کہ کیا کوئی ایگزیکیوشن REVERT یا INVALID کے ساتھ ختم ہوتا ہے + +for state in m.terminated_states: + last_tx = state.platform.transactions[-1] + if last_tx.result in ['REVERT', 'INVALID']: + # ہم اس پاتھ پر غور نہیں کرتے جہاں a == 65 ہے + condition = symbolic_var != 65 + if m.generate_testcase(state, name="BugFound", only_if=condition): + print(f'بگ ملا، نتائج {m.workspace} میں ہیں') + no_bug_found = False + +if no_bug_found: + print(f'کوئی بگ نہیں ملا') +``` + +اوپر دیا گیا تمام کوڈ آپ [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) میں تلاش کر سکتے ہیں diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md new file mode 100644 index 00000000000..f898caf8f19 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md @@ -0,0 +1,233 @@ +--- +title: "اسمارٹ کنٹریکٹ بگز کو تلاش کرنے کے لیے Slither کا استعمال کیسے کریں" +description: "اسمارٹ کنٹریکٹس میں بگز کو خود بخود تلاش کرنے کے لیے Slither کا استعمال کیسے کریں" +author: Trailofbits +lang: ur-in +tags: [ "solidity", "اسمارٹ معاہدات", "سیکورٹی", "testing" ] +skill: advanced +published: 2020-06-09 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/slither +--- + +## Slither کا استعمال کیسے کریں {#how-to-use-slither} + +اس ٹیوٹوریل کا مقصد یہ دکھانا ہے کہ اسمارٹ کنٹریکٹس میں بگز کو خود بخود تلاش کرنے کے لیے Slither کا استعمال کیسے کیا جائے۔ + +- [انسٹالیشن](#installation) +- [کمانڈ لائن کا استعمال](#command-line) +- [اسٹیٹک تجزیہ کا تعارف](#static-analysis): اسٹیٹک تجزیہ کا مختصر تعارف +- [API](#api-basics): پائتھن API کی تفصیل + +## انسٹالیشن {#installation} + +Slither کے لیے Python >= 3.6 درکار ہے۔ اسے pip کے ذریعے یا docker کا استعمال کرکے انسٹال کیا جاسکتا ہے۔ + +pip کے ذریعے Slither: + +```bash +pip3 install --user slither-analyzer +``` + +docker کے ذریعے Slither: + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox +``` + +_آخری کمانڈ eth-security-toolbox کو ایک docker میں چلاتا ہے جس کی آپ کی موجودہ ڈائریکٹری تک رسائی ہے۔ آپ اپنے ہوسٹ سے فائلیں تبدیل کر سکتے ہیں، اور docker سے فائلوں پر ٹولز چلا سکتے ہیں_ + +docker کے اندر، چلائیں: + +```bash +solc-select 0.5.11 +cd /home/trufflecon/ +``` + +### ایک اسکرپٹ چلانا {#running-a-script} + +python 3 کے ساتھ ایک python اسکرپٹ چلانے کے لیے: + +```bash +python3 script.py +``` + +### کمانڈ لائن {#command-line} + +**کمانڈ لائن بمقابلہ صارف کے ذریعے متعین کردہ اسکرپٹس۔** Slither پہلے سے متعین ڈیٹیکٹرز کے ایک سیٹ کے ساتھ آتا ہے جو بہت سے عام بگز کو تلاش کرتے ہیں۔ کمانڈ لائن سے Slither کو کال کرنے پر تمام ڈیٹیکٹرز چل جائیں گے، اسٹیٹک تجزیہ کے تفصیلی علم کی ضرورت نہیں: + +```bash +slither project_paths +``` + +ڈیٹیکٹرز کے علاوہ، Slither میں اس کے [پرنٹرز](https://github.com/crytic/slither#printers) اور [ٹولز](https://github.com/crytic/slither#tools) کے ذریعے کوڈ ریویو کی صلاحیتیں ہیں۔ + +پرائیویٹ ڈیٹیکٹرز اور GitHub انٹیگریشن تک رسائی حاصل کرنے کے لیے [crytic.io](https://github.com/crytic) کا استعمال کریں۔ + +## اسٹیٹک تجزیہ {#static-analysis} + +Slither اسٹیٹک تجزیہ فریم ورک کی صلاحیتوں اور ڈیزائن کو بلاگ پوسٹس ([1](https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/), [2](https://blog.trailofbits.com/2019/05/27/slither-the-leading-static-analyzer-for-smart-contracts/)) اور ایک [تعلیمی مقالے](https://github.com/trailofbits/publications/blob/master/papers/wetseb19.pdf) میں بیان کیا گیا ہے۔ + +اسٹیٹک تجزیہ مختلف اقسام میں موجود ہے۔ آپ کو شاید اس بات کا احساس ہوگا کہ [clang](https://clang-analyzer.llvm.org/) اور [gcc](https://lwn.net/Articles/806099/) جیسے کمپائلرز ان تحقیقی تکنیکوں پر انحصار کرتے ہیں، لیکن یہ ([Infer](https://fbinfer.com/), [CodeClimate](https://codeclimate.com/), [FindBugs](http://findbugs.sourceforge.net/) اور [Frama-C](https://frama-c.com/) اور [Polyspace](https://www.mathworks.com/products/polyspace.html) جیسے رسمی طریقوں پر مبنی ٹولز) کی بھی بنیاد ہے۔ + +ہم یہاں اسٹیٹک تجزیہ کی تکنیکوں اور محققین کا جامع طور پر جائزہ نہیں لیں گے۔ اس کے بجائے، ہم اس بات پر توجہ مرکوز کریں گے کہ Slither کے کام کرنے کے طریقے کو سمجھنے کے لیے کیا ضروری ہے تاکہ آپ بگز کو تلاش کرنے اور کوڈ کو سمجھنے کے لیے اس کا زیادہ مؤثر طریقے سے استعمال کر سکیں۔ + +- [کوڈ کی نمائندگی](#code-representation) +- [کوڈ کا تجزیہ](#analysis) +- [درمیانی نمائندگی](#intermediate-representation) + +### کوڈ کی نمائندگی {#code-representation} + +ڈائنامک تجزیہ کے برعکس، جو ایک ہی ایگزیکیوشن پاتھ کے بارے میں استدلال کرتا ہے، اسٹیٹک تجزیہ ایک ہی وقت میں تمام پاتھس کے بارے میں استدلال کرتا ہے۔ ایسا کرنے کے لیے، یہ ایک مختلف کوڈ کی نمائندگی پر انحصار کرتا ہے۔ دو سب سے عام ہیں ایبسٹریکٹ سنٹیکس ٹری (AST) اور کنٹرول فلو گراف (CFG)۔ + +### ایبسٹریکٹ سنٹیکس ٹریز (AST) {#abstract-syntax-trees-ast} + +AST کا استعمال ہر بار کیا جاتا ہے جب کمپائلر کوڈ کو پارس کرتا ہے۔ یہ شاید سب سے بنیادی ڈھانچہ ہے جس پر اسٹیٹک تجزیہ کیا جا سکتا ہے۔ + +مختصراً، ایک AST ایک سٹرکچرڈ ٹری ہے جہاں، عام طور پر، ہر لیف میں ایک ویری ایبل یا ایک کانسٹنٹ ہوتا ہے اور انٹرنل نوڈز آپرینڈز یا کنٹرول فلو آپریشنز ہوتے ہیں۔ درج ذیل کوڈ پر غور کریں: + +```solidity +function safeAdd(uint a, uint b) pure internal returns(uint){ + if(a + b <= a){ + revert(); + } + return a + b; +} +``` + +متعلقہ AST کو اس میں دکھایا گیا ہے: + +![AST](./ast.png) + +Slither, solc کے ذریعے ایکسپورٹ کردہ AST کا استعمال کرتا ہے۔ + +بنانے میں آسان ہونے کے باوجود، AST ایک نیسٹڈ سٹرکچر ہے۔ بعض اوقات، اس کا تجزیہ کرنا سب سے سیدھا نہیں ہوتا ہے۔ مثال کے طور پر، ایکسپریشن `a + b <= a` کے ذریعے استعمال ہونے والے آپریشنز کی شناخت کے لیے، آپ کو پہلے `<=` اور پھر `+` کا تجزیہ کرنا ہوگا۔ ایک عام طریقہ نام نہاد وزیٹر پیٹرن کا استعمال کرنا ہے، جو ٹری کے ذریعے ریکرسیولی نیویگیٹ کرتا ہے۔ Slither میں [`ExpressionVisitor`](https://github.com/crytic/slither/blob/master/slither/visitors/expression/expression.py) میں ایک عام وزیٹر موجود ہے۔ + +درج ذیل کوڈ `ExpressionVisitor` کا استعمال کرتا ہے یہ پتہ لگانے کے لیے کہ آیا ایکسپریشن میں کوئی ایڈیشن ہے: + +```python +from slither.visitors.expression.expression import ExpressionVisitor +from slither.core.expressions.binary_operation import BinaryOperationType + +class HasAddition(ExpressionVisitor): + + def result(self): + return self._result + + def _post_binary_operation(self, expression): + if expression.type == BinaryOperationType.ADDITION: + self._result = True + +visitor = HasAddition(expression) # ایکسپریشن وہ ایکسپریشن ہے جس کی جانچ کی جانی ہے +print(f'The expression {expression} has a addition: {visitor.result()}') +``` + +### کنٹرول فلو گراف (CFG) {#control-flow-graph-cfg} + +دوسری سب سے عام کوڈ کی نمائندگی کنٹرول فلو گراف (CFG) ہے۔ جیسا کہ اس کے نام سے ظاہر ہے، یہ ایک گراف پر مبنی نمائندگی ہے جو تمام ایگزیکیوشن پاتھس کو ظاہر کرتی ہے۔ ہر نوڈ میں ایک یا ایک سے زیادہ ہدایات ہوتی ہیں۔ گراف میں ایجز کنٹرول فلو آپریشنز (if/then/else, loop, وغیرہ) کی نمائندگی کرتے ہیں۔ ہماری پچھلی مثال کا CFG یہ ہے: + +![CFG](./cfg.png) + +CFG وہ نمائندگی ہے جس کے اوپر زیادہ تر تجزیے بنائے جاتے ہیں۔ + +بہت سی دوسری کوڈ کی نمائندگیاں موجود ہیں۔ ہر نمائندگی کے اپنے فائدے اور نقصانات ہیں اس تجزیہ کے مطابق جو آپ کرنا چاہتے ہیں۔ + +### تجزیہ {#analysis} + +سب سے آسان قسم کے تجزیے جو آپ Slither کے ساتھ کر سکتے ہیں وہ سنٹیکٹک تجزیے ہیں۔ + +### سنٹیکس کا تجزیہ {#syntax-analysis} + +Slither پیٹرن میچنگ جیسے طریقے کا استعمال کرتے ہوئے تضادات اور خامیوں کو تلاش کرنے کے لیے کوڈ کے مختلف اجزاء اور ان کی نمائندگی کے ذریعے نیویگیٹ کر سکتا ہے۔ + +مثال کے طور پر درج ذیل ڈیٹیکٹرز سنٹیکس سے متعلقہ مسائل کو تلاش کرتے ہیں: + +- [اسٹیٹ ویری ایبل شیڈونگ](https://github.com/crytic/slither/wiki/Detector-Documentation#state-variable-shadowing): تمام اسٹیٹ ویری ایبلز پر ایٹریٹ کرتا ہے اور چیک کرتا ہے کہ آیا کوئی موروثی کنٹریکٹ سے کسی ویری ایبل کو شیڈو کرتا ہے ([state.py#L51-L62](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/shadowing/state.py#L51-L62)) + +- [غلط ERC20 انٹرفیس](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface): غلط ERC20 فنکشن سگنیچرز کو تلاش کرتا ہے ([incorrect_erc20_interface.py#L34-L55](https://github.com/crytic/slither/blob/0441338e055ab7151b30ca69258561a5a793f8ba/slither/detectors/erc/incorrect_erc20_interface.py#L34-L55)) + +### سیمنٹک تجزیہ {#semantic-analysis} + +سنٹیکس تجزیہ کے برعکس، ایک سیمنٹک تجزیہ زیادہ گہرائی میں جائے گا اور کوڈ کے "معنی" کا تجزیہ کرے گا۔ اس فیملی میں کچھ وسیع اقسام کے تجزیے شامل ہیں۔ یہ زیادہ طاقتور اور مفید نتائج کی طرف لے جاتے ہیں، لیکن لکھنے میں بھی زیادہ پیچیدہ ہیں۔ + +سیمنٹک تجزیے سب سے جدید کمزوریوں کا پتہ لگانے کے لیے استعمال کیے جاتے ہیں۔ + +#### ڈیٹا کا انحصاری تجزیہ {#fixed-point-computation} + +ایک ویری ایبل `variable_a` کو `variable_b` پر ڈیٹا-ڈیپینڈینٹ کہا جاتا ہے اگر کوئی ایسا پاتھ ہے جس کے لیے `variable_a` کی قدر `variable_b` سے متاثر ہوتی ہے۔ + +درج ذیل کوڈ میں، `variable_a`، `variable_b` پر منحصر ہے: + +```solidity +// ... +variable_a = variable_b + 1; +``` + +Slither بلٹ ان [ڈیٹا ڈیپینڈینسی](https://github.com/crytic/slither/wiki/data-dependency) کی صلاحیتوں کے ساتھ آتا ہے، اس کی درمیانی نمائندگی کی بدولت (جس پر بعد کے سیکشن میں بحث کی گئی ہے)۔ + +ڈیٹا ڈیپینڈینسی کے استعمال کی ایک مثال [خطرناک سخت مساوات ڈیٹیکٹر](https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities) میں مل سکتی ہے۔ یہاں Slither ایک خطرناک قدر کے ساتھ سخت مساوات کے موازنہ کو تلاش کرے گا ([incorrect_strict_equality.py#L86-L87](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L86-L87))، اور صارف کو مطلع کرے گا کہ اسے کسی حملہ آور کو کنٹریکٹ میں پھنسانے سے روکنے کے لیے `==` کے بجائے `>=` یا `<=` کا استعمال کرنا چاہیے۔ دیگر چیزوں کے علاوہ، ڈیٹیکٹر `balanceOf(address)` ([incorrect_strict_equality.py#L63-L64](https://github.com/crytic/slither/blob/6d86220a53603476f9567c3358524ea4db07fb25/slither/detectors/statements/incorrect_strict_equality.py#L63-L64)) پر کال کی واپسی کی قدر کو خطرناک سمجھے گا، اور اس کے استعمال کو ٹریک کرنے کے لیے ڈیٹا ڈیپینڈینسی انجن کا استعمال کرے گا۔ + +#### فکسڈ پوائنٹ کمپیوٹیشن {#fixed-point-computation} + +اگر آپ کا تجزیہ CFG کے ذریعے نیویگیٹ کرتا ہے اور ایجز کی پیروی کرتا ہے، تو آپ کو پہلے سے دیکھے گئے نوڈس نظر آنے کا امکان ہے۔ مثال کے طور پر، اگر ایک لوپ کو نیچے دکھایا گیا ہے: + +```solidity +for(uint i; i < range; ++){ + variable_a += 1 +} +``` + +آپ کے تجزیہ کو یہ جاننے کی ضرورت ہوگی کہ کب رکنا ہے۔ یہاں دو اہم حکمت عملیاں ہیں: (1) ہر نوڈ پر ایک محدود تعداد میں ایٹریٹ کریں، (2) ایک نام نہاد _فکس پوائنٹ_ کا حساب لگائیں۔ ایک فکس پوائنٹ کا بنیادی طور پر مطلب ہے کہ اس نوڈ کا تجزیہ کوئی بامعنی معلومات فراہم نہیں کرتا ہے۔ + +فکس پوائنٹ کے استعمال کی ایک مثال ری اینٹرینسی ڈیٹیکٹرز میں مل سکتی ہے: Slither نوڈس کو ایکسپلور کرتا ہے، اور ایکسٹرنل کالز، اسٹوریج میں لکھنے اور پڑھنے کی تلاش کرتا ہے۔ ایک بار جب یہ فکس پوائنٹ ([reentrancy.py#L125-L131](https://github.com/crytic/slither/blob/master/slither/detectors/reentrancy/reentrancy.py#L125-L131)) تک پہنچ جاتا ہے، تو یہ ایکسپلوریشن کو روک دیتا ہے، اور نتائج کا تجزیہ کرتا ہے یہ دیکھنے کے لیے کہ آیا ری اینٹرینسی موجود ہے، مختلف ری اینٹرینسی پیٹرنز ([reentrancy_benign.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_benign.py), [reentrancy_read_before_write.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_read_before_write.py), [reentrancy_eth.py](https://github.com/crytic/slither/blob/b275bcc824b1b932310cf03b6bfb1a1fef0ebae1/slither/detectors/reentrancy/reentrancy_eth.py)) کے ذریعے۔ + +موثر فکسڈ پوائنٹ کمپیوٹیشن کا استعمال کرتے ہوئے تجزیے لکھنے کے لیے اس بات کی اچھی سمجھ کی ضرورت ہوتی ہے کہ تجزیہ اپنی معلومات کو کیسے پھیلاتا ہے۔ + +### درمیانی نمائندگی {#intermediate-representation} + +ایک درمیانی نمائندگی (IR) ایک ایسی زبان ہے جو اصل زبان کے مقابلے میں اسٹیٹک تجزیہ کے لیے زیادہ موزوں ہو۔ Slither, Solidity کو اپنے IR: [SlithIR](https://github.com/crytic/slither/wiki/SlithIR) میں ترجمہ کرتا ہے۔ + +اگر آپ صرف بنیادی چیکس لکھنا چاہتے ہیں تو SlithIR کو سمجھنا ضروری نہیں ہے۔ تاہم، اگر آپ جدید سیمنٹک تجزیے لکھنے کا ارادہ رکھتے ہیں تو یہ کام آئے گا۔ [SlithIR](https://github.com/crytic/slither/wiki/Printer-documentation#slithir) اور [SSA](https://github.com/crytic/slither/wiki/Printer-documentation#slithir-ssa) پرنٹرز آپ کو یہ سمجھنے میں مدد کریں گے کہ کوڈ کا ترجمہ کیسے ہوتا ہے۔ + +## API کی بنیادی باتیں {#api-basics} + +Slither میں ایک API ہے جو آپ کو کنٹریکٹ اور اس کے فنکشنز کی بنیادی خصوصیات کو ایکسپلور کرنے دیتا ہے۔ + +کوڈبیس کو لوڈ کرنے کے لیے: + +```python +from slither import Slither +slither = Slither('/path/to/project') + +``` + +### کنٹریکٹس اور فنکشنز کو ایکسپلور کرنا {#exploring-contracts-and-functions} + +ایک `Slither` آبجیکٹ میں ہوتا ہے: + +- `contracts (list(Contract)`: کنٹریکٹس کی فہرست +- `contracts_derived (list(Contract)`: ان کنٹریکٹس کی فہرست جو کسی دوسرے کنٹریکٹ سے موروثی نہیں ہیں (کنٹریکٹس کا سب سیٹ) +- `get_contract_from_name (str)`: اس کے نام سے ایک کنٹریکٹ واپس کریں + +ایک `Contract` آبجیکٹ میں ہوتا ہے: + +- `name (str)`: کنٹریکٹ کا نام +- `functions (list(Function))`: فنکشنز کی فہرست +- `modifiers (list(Modifier))`: فنکشنز کی فہرست +- `all_functions_called (list(Function/Modifier))`: کنٹریکٹ کے ذریعے پہنچنے کے قابل تمام اندرونی فنکشنز کی فہرست +- `inheritance (list(Contract))`: موروثی کنٹریکٹس کی فہرست +- `get_function_from_signature (str)`: اس کے سگنیچر سے ایک فنکشن واپس کریں +- `get_modifier_from_signature (str)`: اس کے سگنیچر سے ایک موڈیفائر واپس کریں +- `get_state_variable_from_name (str)`: اس کے نام سے ایک اسٹیٹ ویری ایبل واپس کریں + +ایک `Function` یا `Modifier` آبجیکٹ میں ہوتا ہے: + +- `name (str)`: فنکشن کا نام +- `contract (contract)`: وہ کنٹریکٹ جہاں فنکشن کا اعلان کیا گیا ہے +- `nodes (list(Node))`: فنکشن/موڈیفائر کے CFG کو بنانے والے نوڈس کی فہرست +- `entry_point (Node)`: CFG کا انٹری پوائنٹ +- `variables_read (list(Variable))`: پڑھے گئے ویری ایبلز کی فہرست +- `variables_written (list(Variable))`: لکھے گئے ویری ایبلز کی فہرست +- `state_variables_read (list(StateVariable))`: پڑھے گئے اسٹیٹ ویری ایبلز کی فہرست (ویری ایبلز`ریڈ کا سب سیٹ) +- `state_variables_written (list(StateVariable))`: لکھے گئے اسٹیٹ ویری ایبلز کی فہرست (ویری ایبلز`رٹن کا سب سیٹ) diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md new file mode 100644 index 00000000000..b74d5fc2bbe --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md @@ -0,0 +1,81 @@ +--- +title: "Tellor کو اپنے اوریکل کے طور پر کیسے سیٹ اپ کریں" +description: "Tellor اوریکل کو اپنے پروٹوکول میں ضم کرنے کے ساتھ شروع کرنے کے لئے ایک گائیڈ" +author: "Tellor" +lang: ur-in +tags: [ "solidity", "اسمارٹ معاہدات", "اوریکلز" ] +skill: beginner +published: 2021-06-29 +source: Tellor Docs +sourceUrl: https://docs.tellor.io/tellor/ +--- + +پاپ کوئز: آپ کا پروٹوکول تقریباً ختم ہو چکا ہے، لیکن اسے آف چین ڈیٹا تک رسائی حاصل کرنے کے لیے ایک اوریکل کی ضرورت ہے... آپ کیا کرتے ہیں؟ + +## (نرم) شرائط {#soft-prerequisites} + +اس پوسٹ کا مقصد اوریکل فیڈ تک رسائی کو ہر ممکن حد تک آسان اور سیدھا بنانا ہے۔ یہ کہنے کے بعد، ہم اوریکل پہلو پر توجہ مرکوز کرنے کے لئے آپ کی کوڈنگ کی مہارت کی سطح کے بارے میں مندرجہ ذیل فرض کر رہے ہیں۔ + +مفروضے: + +- آپ ٹرمینل نیویگیٹ کر سکتے ہیں +- آپ نے npm انسٹال کیا ہے +- آپ جانتے ہیں کہ انحصار کو منظم کرنے کے لئے npm کا استعمال کیسے کریں + +Tellor ایک لائیو اور اوپن سورس اوریکل ہے جو نفاذ کے لیے تیار ہے۔ یہ ابتدائی رہنما یہاں اس آسانی کو ظاہر کرنے کے لیے ہے جس کے ساتھ کوئی بھی Tellor کے ساتھ شروع کر سکتا ہے، جو آپ کے پروجیکٹ کو مکمل طور پر غیر مرکزی اور سنسر شپ سے مزاحم اوریکل فراہم کرتا ہے۔ + +## جائزہ {#overview} + +Tellor ایک اوریکل سسٹم ہے جہاں پارٹیاں آف چین ڈیٹا پوائنٹ (مثال کے طور پر، BTC/USD) کی قیمت کی درخواست کر سکتی ہیں اور رپورٹرز اس قیمت کو آن چین ڈیٹا بینک میں شامل کرنے کے لیے مقابلہ کرتے ہیں، جو تمام Ethereum اسمارٹ کنٹریکٹس کے ذریعے قابل رسائی ہے۔ اس ڈیٹا بینک کے ان پٹس کو اسٹیک شدہ رپورٹرز کے نیٹ ورک کے ذریعے محفوظ کیا جاتا ہے۔ Tellor کرپٹو-اقتصادی ترغیبی میکانزم کا استعمال کرتا ہے، رپورٹرز کے ذریعے ایماندارانہ ڈیٹا جمع کرانے پر انعام دیتا ہے اور Tellor کے ٹوکن، Tributes (TRB) کے اجراء اور ایک تنازعہ کے میکانزم کے ذریعے برے اداکاروں کو سزا دیتا ہے۔ + +اس ٹیوٹوریل میں ہم اس پر بات کریں گے: + +- ابتدائی ٹول کٹ ترتیب دینا جس کی آپ کو شروع کرنے اور چلانے کی ضرورت ہوگی۔ +- ایک سادہ مثال کے ذریعے چلیں۔ +- ان نیٹ ورکس کے ٹیسٹ نیٹ پتے درج کریں جن پر آپ فی الحال Tellor کی جانچ کر سکتے ہیں۔ + +## UsingTellor کا استعمال {#usingtellor} + +سب سے پہلی چیز جو آپ کرنا چاہیں گے وہ ہے Tellor کو اپنے اوریکل کے طور پر استعمال کرنے کے لیے ضروری بنیادی ٹولز کو انسٹال کرنا۔ Tellor یوزر کنٹریکٹس کو انسٹال کرنے کے لیے [اس پیکیج](https://github.com/tellor-io/usingtellor) کا استعمال کریں: + +`npm install usingtellor` + +ایک بار انسٹال ہونے کے بعد یہ آپ کے کنٹریکٹس کو 'UsingTellor' کنٹریکٹ سے فنکشنز وراثت میں حاصل کرنے کی اجازت دے گا۔ + +بہت خوب! اب جب کہ آپ کے پاس ٹولز تیار ہیں، آئیے ایک سادہ سی مشق سے گزرتے ہیں جہاں ہم بٹ کوائن کی قیمت حاصل کرتے ہیں: + +### BTC/USD مثال {#btcusd-example} + +UsingTellor کنٹریکٹ کو وراثت میں حاصل کریں، Tellor ایڈریس کو کنسٹرکٹر آرگیومنٹ کے طور پر پاس کرتے ہوئے: + +یہاں ایک مثال ہے: + +```solidity +import "usingtellor/contracts/UsingTellor.sol"; + +contract PriceContract is UsingTellor { + uint256 public btcPrice; + + //اس کنٹریکٹ کو اب UsingTellor کے تمام فنکشنز تک رسائی حاصل ہے + +constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} + +function setBtcPrice() public { + bytes memory _b = abi.encode("SpotPrice",abi.encode("btc","usd")); + bytes32 _queryId = keccak256(_b); + + uint256 _timestamp; + bytes _value; + + (_value, _timestamp) = getDataBefore(_queryId, block.timestamp - 15 minutes); + + btcPrice = abi.decode(_value,(uint256)); + } +} +``` + +کنٹریکٹ ایڈریسز کی مکمل فہرست کے لیے [یہاں](https://docs.tellor.io/tellor/the-basics/contracts-reference) رجوع کریں۔ + +استعمال میں آسانی کے لیے، UsingTellor ریپو آسان انضمام کے لیے [Tellor Playground](https://github.com/tellor-io/TellorPlayground) کنٹریکٹ کے ایک ورژن کے ساتھ آتا ہے۔ مددگار فنکشنز کی فہرست کے لیے [یہاں](https://github.com/tellor-io/sampleUsingTellor#tellor-playground) دیکھیں۔ + +Tellor اوریکل کے زیادہ مضبوط نفاذ کے لیے، دستیاب فنکشنز کی مکمل فہرست [یہاں](https://github.com/tellor-io/usingtellor/blob/master/README.md) دیکھیں۔ diff --git a/public/content/translations/ur/developers/tutorials/how-to-view-nft-in-metamask/index.md b/public/content/translations/ur/developers/tutorials/how-to-view-nft-in-metamask/index.md new file mode 100644 index 00000000000..09f8c7fe1d4 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-view-nft-in-metamask/index.md @@ -0,0 +1,33 @@ +--- +title: "اپنے والٹ میں اپنا NFT کیسے دیکھیں (NFT ٹیوٹوریل سیریز کا حصہ 3/3)" +description: "یہ ٹیوٹوریل بیان کرتا ہے کہ MetaMask پر موجودہ NFT کو کیسے دیکھیں!" +author: "Sumi Mudgil" +tags: [ "ERC-721", "Alchemy", "Solidity" ] +skill: beginner +lang: ur-in +published: 2021-04-22 +--- + +یہ ٹیوٹوریل NFT ٹیوٹوریل سیریز کا حصہ 3/3 ہے، جہاں ہم اپنا نیا منٹ کیا ہوا NFT دیکھتے ہیں۔ تاہم، آپ MetaMask کا استعمال کرتے ہوئے کسی بھی ERC-721 ٹوکن کے لیے عمومی ٹیوٹوریل استعمال کر سکتے ہیں، بشمول Mainnet یا کسی بھی testnet پر۔ اگر آپ Ethereum پر اپنا NFT منٹ کرنے کا طریقہ سیکھنا چاہتے ہیں، تو آپ کو [حصہ 1 NFT اسمارٹ کنٹریکٹ کو کیسے لکھیں اور ڈیپلوئے کریں](/developers/tutorials/how-to-write-and-deploy-an-nft) دیکھنا چاہئے! + +مبارک ہو! آپ ہماری NFT ٹیوٹوریل سیریز کے سب سے مختصر اور آسان ترین حصے تک پہنچ گئے ہیں — اپنے نئے منٹ کیے گئے NFT کو ورچوئل والٹ پر کیسے دیکھیں۔ ہم اس مثال کے لیے MetaMask کا استعمال کریں گے کیونکہ ہم نے پچھلے دو حصوں میں اسی کا استعمال کیا تھا۔ + +ایک شرط کے طور پر، آپ کے موبائل پر MetaMask پہلے سے انسٹال ہونا چاہیے، اور اس میں وہ اکاؤنٹ شامل ہونا چاہیے جس میں آپ نے اپنا NFT منٹ کیا ہے — آپ ایپ کو [iOS](https://apps.apple.com/us/app/metamask-blockchain-wallet/id1438144202) یا [Android](https://play.google.com/store/apps/details?id=io.metamask&hl=en_US&gl=US) پر مفت حاصل کر سکتے ہیں۔ + +## مرحلہ 1: اپنا نیٹ ورک Sepolia پر سیٹ کریں {#set-network-to-sepolia} + +ایپ کے اوپری حصے میں، "والٹ" بٹن دبائیں، جس کے بعد آپ کو ایک نیٹ ورک منتخب کرنے کے لیے کہا جائے گا۔ چونکہ ہمارا NFT Sepolia نیٹ ورک پر منٹ کیا گیا تھا، آپ اپنے نیٹ ورک کے طور پر Sepolia کو منتخب کرنا چاہیں گے۔ + +![MetaMask موبائل پر Sepolia کو اپنے نیٹ ورک کے طور پر کیسے سیٹ کریں](./goerliMetamask.gif) + +## مرحلہ 2: MetaMask میں اپنی جمع کرنے والی چیز شامل کریں {#add-nft-to-metamask} + +ایک بار جب آپ Sepolia نیٹ ورک پر ہوں، تو دائیں جانب "Collectibles" ٹیب کو منتخب کریں اور NFT اسمارٹ کنٹریکٹ کا ایڈریس اور اپنے NFT کا ERC-721 ٹوکن ID شامل کریں — جسے آپ ہمارے ٹیوٹوریل کے حصہ II میں ڈیپلوئے کیے گئے اپنے NFT کے ٹرانزیکشن ہیش کی بنیاد پر Etherscan پر تلاش کر سکتے ہیں۔ + +![اپنا ٹرانزیکشن ہیش اور ERC-721 ٹوکن ID کیسے تلاش کریں](./findNFTEtherscan.png) + +اپنا NFT دیکھنے کے لیے آپ کو چند بار ریفریش کرنے کی ضرورت پڑ سکتی ہے — لیکن یہ وہاں موجود ہوگا ! + +![اپنا NFT MetaMask پر کیسے اپ لوڈ کریں](./findNFTMetamask.gif) + +مبارک ہو! آپ نے کامیابی سے ایک NFT منٹ کر لیا ہے، اور اب آپ اسے دیکھ سکتے ہیں! ہم یہ دیکھنے کا انتظار نہیں کر سکتے کہ آپ NFT کی دنیا میں کیسے دھوم مچاتے ہیں! diff --git a/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md new file mode 100644 index 00000000000..cf2a844b3ce --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md @@ -0,0 +1,380 @@ +--- +title: "NFT کیسے لکھیں اور ڈیپلوئے کریں (NFT ٹیوٹوریل سیریز کا حصہ 1/3)" +description: "یہ ٹیوٹوریل NFTs پر ایک سیریز کا حصہ 1 ہے جو آپ کو مرحلہ وار بتائے گا کہ Ethereum اور انٹر پلینٹری فائل سسٹم (IPFS) کا استعمال کرتے ہوئے ایک نان-فنجیبل ٹوکن (ERC-721 ٹوکن) اسمارٹ کنٹریکٹ کیسے لکھیں اور ڈیپلوئے کریں۔" +author: "Sumi Mudgil" +tags: [ "ERC-721", "Alchemy", "Solidity", "اسمارٹ معاہدات" ] +skill: beginner +lang: ur-in +published: 2021-04-22 +--- + +NFTs کے بلاک چین کو عوام کی نظروں میں لانے کے ساتھ، اب آپ کے لیے Ethereum بلاک چین پر اپنا خود کا NFT کنٹریکٹ (ERC-721 ٹوکن) شائع کرکے اس ہائپ کو خود سمجھنے کا ایک بہترین موقع ہے! + +Alchemy کو NFT اسپیس کے سب سے بڑے ناموں کو طاقت فراہم کرنے پر بے حد فخر ہے، جس میں Makersplace (جس نے حال ہی میں کرسٹی'ز میں 69 ملین ڈالر میں ایک ریکارڈ ڈیجیٹل آرٹ ورک فروخت کیا)، Dapper Labs (NBA Top Shot اور Crypto Kitties کے تخلیق کار)، OpenSea (دنیا کا سب سے بڑا NFT مارکیٹ پلیس)، Zora، Super Rare، NFTfi، Foundation، Enjin، Origin Protocol، Immutable، اور مزید شامل ہیں۔ + +اس ٹیوٹوریل میں، ہم [MetaMask](https://metamask.io/)، [Solidity](https://docs.soliditylang.org/en/v0.8.0/)، [Hardhat](https://hardhat.org/)، [Pinata](https://pinata.cloud/) اور [Alchemy](https://alchemy.com/signup/eth) کا استعمال کرتے ہوئے Sepolia ٹیسٹ نیٹ ورک پر ایک ERC-721 اسمارٹ کنٹریکٹ بنانے اور ڈیپلوئے کرنے کے بارے میں بتائیں گے (اگر آپ ابھی تک نہیں سمجھتے کہ ان میں سے کسی کا کیا مطلب ہے تو پریشان نہ ہوں — ہم اس کی وضاحت کریں گے!)۔ + +اس ٹیوٹوریل کے حصہ 2 میں ہم دیکھیں گے کہ ہم اپنے اسمارٹ کنٹریکٹ کا استعمال کرکے ایک NFT کیسے مِنٹ کر سکتے ہیں، اور حصہ 3 میں ہم وضاحت کریں گے کہ MetaMask پر اپنے NFT کو کیسے دیکھیں۔ + +اور ہاں، اگر آپ کے پاس کسی بھی وقت کوئی سوالات ہوں، تو [Alchemy Discord](https://discord.gg/gWuC7zB) میں رابطہ کرنے یا [Alchemy کی NFT API دستاویزات](https://docs.alchemy.com/alchemy/enhanced-apis/nft-api) پر جانے میں ہچکچاہٹ محسوس نہ کریں! + +## مرحلہ 1: Ethereum نیٹ ورک سے جڑیں {#connect-to-ethereum} + +Ethereum بلاک چین سے درخواستیں کرنے کے بہت سے طریقے ہیں، لیکن چیزوں کو آسان بنانے کے لیے، ہم [Alchemy](https://alchemy.com/signup/eth) پر ایک مفت اکاؤنٹ استعمال کریں گے، جو ایک بلاک چین ڈیولپر پلیٹ فارم اور API ہے جو ہمیں اپنے نوڈس چلائے بغیر Ethereum چین کے ساتھ بات چیت کرنے کی اجازت دیتا ہے۔ + +اس ٹیوٹوریل میں، ہم اپنے اسمارٹ کنٹریکٹ کی ڈیپلوئمنٹ کے دوران پس پردہ کیا ہو رہا ہے یہ سمجھنے کے لیے مانیٹرنگ اور تجزیات کے لیے Alchemy کے ڈیولپر ٹولز کا بھی فائدہ اٹھائیں گے۔ اگر آپ کے پاس پہلے سے Alchemy اکاؤنٹ نہیں ہے، تو آپ [یہاں](https://alchemy.com/signup/eth) مفت میں سائن اپ کر سکتے ہیں۔ + +## مرحلہ 2: اپنی ایپ (اور API کلید) بنائیں {#make-api-key} + +ایک بار جب آپ Alchemy اکاؤنٹ بنا لیں، تو آپ ایک ایپ بنا کر API کلید تیار کر سکتے ہیں۔ یہ ہمیں Sepolia ٹیسٹ نیٹ ورک سے درخواستیں کرنے کی اجازت دے گا۔ اگر آپ ٹیسٹ نیٹ ورکس کے بارے میں مزید جاننے کے لیے متجسس ہیں تو [اس گائیڈ](https://docs.alchemyapi.io/guides/choosing-a-network) کو دیکھیں۔ + +1. نیو بار میں "Apps" پر ہوور کرکے اور "Create App" پر کلک کرکے اپنے Alchemy ڈیش بورڈ میں "Create App" صفحہ پر جائیں۔ + +![اپنی ایپ بنائیں](./create-your-app.png) + +2. اپنی ایپ کو نام دیں (ہم نے “My First NFT!” منتخب کیا)، ایک مختصر تفصیل دیں، چین کے لیے “Ethereum” منتخب کریں، اور اپنے نیٹ ورک کے لیے “Sepolia” کا انتخاب کریں۔ مرج کے بعد سے دوسرے ٹیسٹ نیٹس کو فرسودہ کر دیا گیا ہے۔ + +![اپنی ایپ کو کنفیگر اور شائع کریں](./alchemy-explorer-sepolia.png) + +3. “Create app” پر کلک کریں اور بس! آپ کی ایپ نیچے دی گئی ٹیبل میں ظاہر ہونی چاہیے۔ + +## مرحلہ 3: ایک Ethereum اکاؤنٹ (ایڈریس) بنائیں {#create-eth-address} + +ٹرانزیکشنز بھیجنے اور وصول کرنے کے لیے ہمیں ایک Ethereum اکاؤنٹ کی ضرورت ہے۔ اس ٹیوٹوریل کے لیے، ہم MetaMask استعمال کریں گے، جو براؤزر میں ایک ورچوئل والیٹ ہے جو آپ کے Ethereum اکاؤنٹ ایڈریس کو منظم کرنے کے لیے استعمال ہوتا ہے۔ اگر آپ یہ سمجھنا چاہتے ہیں کہ Ethereum پر ٹرانزیکشنز کیسے کام کرتی ہیں، تو Ethereum فاؤنڈیشن کا [یہ صفحہ](/developers/docs/transactions/) دیکھیں۔ + +آپ [یہاں](https://metamask.io/download) مفت میں MetaMask اکاؤنٹ ڈاؤن لوڈ اور بنا سکتے ہیں۔ جب آپ اکاؤنٹ بنا رہے ہوں، یا اگر آپ کے پاس پہلے سے ہی اکاؤنٹ ہے، تو یقینی بنائیں کہ اوپری دائیں کونے میں "Sepolia Test Network" پر سوئچ کریں (تاکہ ہم اصلی پیسے کے ساتھ کام نہ کر رہے ہوں)۔ + +![Sepolia کو اپنے نیٹ ورک کے طور پر سیٹ کریں](./metamask-goerli.png) + +## مرحلہ 4: ایک فاسیٹ سے ایتھر شامل کریں {#step-4-add-ether-from-a-faucet} + +اپنے اسمارٹ کنٹریکٹ کو ٹیسٹ نیٹ ورک پر ڈیپلوئے کرنے کے لیے، ہمیں کچھ جعلی ETH کی ضرورت ہوگی۔ ETH حاصل کرنے کے لیے آپ Alchemy کے زیر اہتمام [Sepolia Faucet](https://sepoliafaucet.com/) پر جا سکتے ہیں، لاگ ان کریں اور اپنا اکاؤنٹ ایڈریس درج کریں، "Send Me ETH" پر کلک کریں۔ اس کے فوراً بعد آپ کو اپنے MetaMask اکاؤنٹ میں ETH نظر آنا چاہیے! + +## مرحلہ 5: اپنا بیلنس چیک کریں {#check-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" پر کلک کرنے کے بعد، آپ کو اس طرح کا جواب نظر آنا چاہیے: + + ``` + `{"jsonrpc": "2.0", "id": 0, "result": "0xde0b6b3a7640000"}` + ``` + +> **نوٹ** یہ نتیجہ wei میں ہے، ETH میں نہیں۔ Wei کو ایتھر کی سب سے چھوٹی اکائی کے طور پر استعمال کیا جاتا ہے۔ wei سے ETH میں تبدیلی 1 eth = 1018 wei ہے۔ لہذا اگر ہم 0xde0b6b3a7640000 کو ڈیسیمل میں تبدیل کرتے ہیں تو ہمیں 1\*1018 wei ملتا ہے، جو 1 ETH کے برابر ہے۔ + +اف! ہمارا جعلی پیسہ سب وہیں ہے۔ + +## مرحلہ 6: ہمارے پروجیکٹ کو شروع کریں {#initialize-project} + +سب سے پہلے، ہمیں اپنے پروجیکٹ کے لیے ایک فولڈر بنانا ہوگا۔ اپنی کمانڈ لائن پر جائیں اور ٹائپ کریں: + + ``` + mkdir my-nft + cd my-nft + ``` + +اب جب کہ ہم اپنے پروجیکٹ فولڈر کے اندر ہیں، ہم پروجیکٹ کو شروع کرنے کے لیے npm init استعمال کریں گے۔ اگر آپ کے پاس پہلے سے npm انسٹال نہیں ہے، تو [ان ہدایات](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) پر عمل کریں (ہمیں [Node.js](https://nodejs.org/en/download/) کی بھی ضرورت ہوگی، لہذا اسے بھی ڈاؤن لوڈ کریں!)۔ + + ``` + npm init + ``` + +اس سے کوئی فرق نہیں پڑتا کہ آپ انسٹالیشن کے سوالات کا جواب کیسے دیتے ہیں؛ یہاں ہم نے اسے حوالہ کے لیے کیسے کیا ہے: + +```json + package name: (my-nft) + version: (1.0.0) + description: میرا پہلا NFT! + entry point: (index.js) + test command: + git repository: + keywords: + author: + license: (ISC) + About to write to /Users/thesuperb1/Desktop/my-nft/package.json: + + { + "name": "my-nft", + "version": "1.0.0", + "description": "میرا پہلا NFT!", + "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) انسٹال کریں {#install-hardhat} + +Hardhat آپ کے Ethereum سافٹ ویئر کو کمپائل، ڈیپلوئے، ٹیسٹ اور ڈیبگ کرنے کے لیے ایک ڈیولپمنٹ ماحول ہے۔ یہ ڈیولپرز کو لائیو چین پر ڈیپلوئے کرنے سے پہلے مقامی طور پر اسمارٹ کنٹریکٹس اور dapps بنانے میں مدد کرتا ہے۔ + +ہمارے my-nft پروجیکٹ کے اندر چلائیں: + + ``` + npm install --save-dev hardhat + ``` + +[انسٹالیشن کی ہدایات](https://hardhat.org/getting-started/#overview) پر مزید تفصیلات کے لیے یہ صفحہ دیکھیں۔ + +## مرحلہ 8: Hardhat پروجیکٹ بنائیں {#create-hardhat-project} + +ہمارے پروجیکٹ فولڈر کے اندر چلائیں: + + ``` + 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: پروجیکٹ فولڈرز شامل کریں {#add-project-folders} + +اپنے پروجیکٹ کو منظم رکھنے کے لیے، ہم دو نئے فولڈر بنائیں گے۔ اپنی کمانڈ لائن میں اپنے پروجیکٹ کی روٹ ڈائرکٹری پر جائیں اور ٹائپ کریں: + + ``` + mkdir contracts + mkdir scripts + ``` + +- `contracts/` وہ جگہ ہے جہاں ہم اپنا NFT اسمارٹ کنٹریکٹ کوڈ رکھیں گے۔ + +- `scripts/` وہ جگہ ہے جہاں ہم اپنے اسمارٹ کنٹریکٹ کو ڈیپلوئے کرنے اور اس کے ساتھ تعامل کرنے کے لیے اسکرپٹس رکھیں گے۔ + +## مرحلہ 10: ہمارا کنٹریکٹ لکھیں {#write-contract} + +اب جب کہ ہمارا ماحول سیٹ ہو گیا ہے، تو مزید دلچسپ چیزوں کی طرف بڑھتے ہیں: _ہمارا اسمارٹ کنٹریکٹ کوڈ لکھنا!_ + +اپنے پسندیدہ ایڈیٹر میں my-nft پروجیکٹ کھولیں (ہمیں [VSCode](https://code.visualstudio.com/) پسند ہے)۔ اسمارٹ کنٹریکٹس Solidity نامی زبان میں لکھے جاتے ہیں جسے ہم اپنا MyNFT.sol اسمارٹ کنٹریکٹ لکھنے کے لیے استعمال کریں گے۔ + +1. `contracts` فولڈر پر جائیں اور MyNFT.sol نامی ایک نئی فائل بنائیں۔ + +2. ذیل میں ہمارا NFT اسمارٹ کنٹریکٹ کوڈ ہے، جسے ہم نے [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721) لائبریری کے ERC-721 نفاذ پر مبنی کیا ہے۔ نیچے دیئے گئے مواد کو اپنی MyNFT.sol فائل میں کاپی اور پیسٹ کریں۔ + + ```solidity + //کنٹریکٹ [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) پر مبنی ہے + // SPDX-License-Identifier: MIT + pragma solidity ^0.8.0; + + import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + import "@openzeppelin/contracts/utils/Counters.sol"; + import "@openzeppelin/contracts/access/Ownable.sol"; + import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; + + contract MyNFT is ERC721URIStorage, Ownable { + using Counters for Counters.Counter; + Counters.Counter private _tokenIds; + + constructor() ERC721("MyNFT", "NFT") {} + + function mintNFT(address recipient, string memory tokenURI) + public onlyOwner + returns (uint256) + { + _tokenIds.increment(); + + uint256 newItemId = _tokenIds.current(); + _mint(recipient, newItemId); + _setTokenURI(newItemId, tokenURI); + + return newItemId; + } + } + ``` + +3. چونکہ ہم OpenZeppelin کنٹریکٹ لائبریری سے کلاسز وراثت میں لے رہے ہیں، اپنی کمانڈ لائن میں `npm install @openzeppelin/contracts^4.0.0` چلا کر لائبریری کو اپنے فولڈر میں انسٹال کریں۔ + +تو، یہ کوڈ اصل میں _کرتا_ کیا ہے؟ آئیے اسے لائن بہ لائن توڑتے ہیں۔ + +ہمارے اسمارٹ کنٹریکٹ کے اوپری حصے میں، ہم تین [OpenZeppelin](https://openzeppelin.com/) اسمارٹ کنٹریکٹ کلاسز درآمد کرتے ہیں: + +- @openzeppelin/contracts/token/ERC721/ERC721.sol میں ERC-721 معیار کا نفاذ شامل ہے، جسے ہمارا NFT اسمارٹ کنٹریکٹ وراثت میں لے گا۔ (ایک درست NFT ہونے کے لیے، آپ کے اسمارٹ کنٹریکٹ کو ERC-721 معیار کے تمام طریقوں کو نافذ کرنا ہوگا)۔ وراثت میں ملے ERC-721 فنکشنز کے بارے میں مزید جاننے کے لیے، انٹرفیس کی تعریف [یہاں](https://eips.ethereum.org/EIPS/eip-721) دیکھیں۔ + +- @openzeppelin/contracts/utils/Counters.sol کاؤنٹرز فراہم کرتا ہے جنہیں صرف ایک سے بڑھایا یا گھٹایا جا سکتا ہے۔ ہمارا اسمارٹ کنٹریکٹ مِنٹ کیے گئے NFTs کی کل تعداد پر نظر رکھنے اور ہمارے نئے NFT پر منفرد ID سیٹ کرنے کے لیے ایک کاؤنٹر استعمال کرتا ہے۔ (ایک اسمارٹ کنٹریکٹ کا استعمال کرتے ہوئے مِنٹ کیے گئے ہر NFT کو ایک منفرد ID تفویض کی جانی چاہیے—یہاں ہماری منفرد ID صرف موجودہ NFTs کی کل تعداد سے طے ہوتی ہے۔ مثال کے طور پر، پہلا NFT جسے ہم اپنے اسمارٹ کنٹریکٹ سے مِنٹ کرتے ہیں اس کی ID "1" ہے، ہمارے دوسرے NFT کی ID "2" ہے، وغیرہ)۔ + +- @openzeppelin/contracts/access/Ownable.sol ہمارے اسمارٹ کنٹریکٹ پر [رسائی کنٹرول](https://docs.openzeppelin.com/contracts/3.x/access-control) سیٹ کرتا ہے، تاکہ صرف اسمارٹ کنٹریکٹ کا مالک (آپ) ہی NFTs مِنٹ کر سکے۔ (نوٹ کریں، رسائی کنٹرول کو شامل کرنا مکمل طور پر ایک ترجیح ہے۔ اگر آپ چاہتے ہیں کہ کوئی بھی آپ کے اسمارٹ کنٹریکٹ کا استعمال کرتے ہوئے NFT مِنٹ کر سکے، تو لائن 10 پر Ownable لفظ اور لائن 17 پر onlyOwner کو ہٹا دیں)۔ + +ہمارے امپورٹ اسٹیٹمنٹس کے بعد، ہمارے پاس ہمارا کسٹم NFT اسمارٹ کنٹریکٹ ہے، جو حیرت انگیز طور پر مختصر ہے — اس میں صرف ایک کاؤنٹر، ایک کنسٹرکٹر، اور ایک ہی فنکشن ہے! یہ ہمارے وراثت میں ملے OpenZeppelin کنٹریکٹس کی بدولت ہے، جو ایک NFT بنانے کے لیے درکار زیادہ تر طریقوں کو نافذ کرتے ہیں، جیسے `ownerOf` جو NFT کے مالک کو واپس کرتا ہے، اور `transferFrom`، جو NFT کی ملکیت کو ایک اکاؤنٹ سے دوسرے اکاؤنٹ میں منتقل کرتا ہے۔ + +ہمارے ERC-721 کنسٹرکٹر میں، آپ دیکھیں گے کہ ہم 2 اسٹرنگز، “MyNFT” اور “NFT” پاس کرتے ہیں۔ پہلا متغیر اسمارٹ کنٹریکٹ کا نام ہے، اور دوسرا اس کی علامت ہے۔ آپ ان میں سے ہر ایک متغیر کو جو چاہیں نام دے سکتے ہیں! + +آخر میں، ہمارے پاس ہمارا فنکشن `mintNFT(address recipient, string memory tokenURI)` ہے جو ہمیں ایک NFT مِنٹ کرنے کی اجازت دیتا ہے! آپ دیکھیں گے کہ یہ فنکشن دو متغیرات لیتا ہے: + +- `address recipient` اس ایڈریس کی وضاحت کرتا ہے جو آپ کا تازہ مِنٹ کیا ہوا NFT وصول کرے گا + +- `string memory tokenURI` ایک اسٹرنگ ہے جسے ایک JSON دستاویز میں حل ہونا چاہئے جو NFT کے میٹا ڈیٹا کو بیان کرتا ہے۔ ایک NFT کا میٹا ڈیٹا ہی دراصل اسے زندگی بخشتا ہے، جس سے اس میں قابل ترتیب خصوصیات ہوتی ہیں، جیسے نام، تفصیل، تصویر، اور دیگر خصوصیات۔ اس ٹیوٹوریل کے حصہ 2 میں، ہم اس میٹا ڈیٹا کو کنفیگر کرنے کا طریقہ بیان کریں گے۔ + +`mintNFT` وراثت میں ملی ERC-721 لائبریری سے کچھ طریقے کال کرتا ہے، اور آخر میں ایک نمبر واپس کرتا ہے جو تازہ مِنٹ کیے گئے NFT کی ID کی نمائندگی کرتا ہے۔ + +## مرحلہ 11: MetaMask اور Alchemy کو اپنے پروجیکٹ سے جوڑیں {#connect-metamask-and-alchemy} + +اب جب کہ ہم نے ایک MetaMask والیٹ، Alchemy اکاؤنٹ بنا لیا ہے، اور اپنا اسمارٹ کنٹریکٹ لکھ لیا ہے، اب وقت آگیا ہے کہ تینوں کو جوڑا جائے۔ + +آپ کے ورچوئل والیٹ سے بھیجی گئی ہر ٹرانزیکشن کے لیے آپ کی منفرد پرائیویٹ کلید کا استعمال کرتے ہوئے ایک دستخط کی ضرورت ہوتی ہے۔ ہمارے پروگرام کو یہ اجازت فراہم کرنے کے لیے، ہم اپنی پرائیویٹ کلید (اور Alchemy API کلید) کو ایک ماحولیاتی فائل میں محفوظ طریقے سے اسٹور کر سکتے ہیں۔ + +ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، web3 کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے پر [یہ ٹیوٹوریل](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) دیکھیں۔ + +سب سے پہلے، اپنی پروجیکٹ ڈائرکٹری میں dotenv پیکیج انسٹال کریں: + + ``` + npm install dotenv --save + ``` + +پھر، ہمارے پروجیکٹ کی روٹ ڈائرکٹری میں ایک `.env` فائل بنائیں، اور اس میں اپنی MetaMask پرائیویٹ کلید اور HTTP Alchemy API URL شامل کریں۔ + +- اپنی پرائیویٹ کلید کو MetaMask سے ایکسپورٹ کرنے کے لیے [ان ہدایات](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) پر عمل کریں۔ + +- HTTP Alchemy API URL حاصل کرنے کے لیے نیچے دیکھیں اور اسے اپنے کلپ بورڈ پر کاپی کریں۔ + +![اپنا Alchemy API URL کاپی کریں](./copy-alchemy-api-url.gif) + +اب آپ کی `.env` فائل اس طرح نظر آنی چاہیے: + + ``` + API_URL="https://eth-sepolia.g.alchemy.com/v2/your-api-key" + PRIVATE_KEY="your-metamask-private-key" + ``` + +ان کو حقیقت میں ہمارے کوڈ سے جوڑنے کے لیے، ہم مرحلہ 13 میں اپنی hardhat.config.js فائل میں ان متغیرات کا حوالہ دیں گے۔ + + + +## مرحلہ 12: Ethers.js انسٹال کریں {#install-ethers} + +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 کو اپ ڈیٹ کریں {#update-hardhat-config} + +ہم نے اب تک کئی انحصار اور پلگ ان شامل کیے ہیں، اب ہمیں hardhat.config.js کو اپ ڈیٹ کرنے کی ضرورت ہے تاکہ ہمارے پروجیکٹ کو ان سب کے بارے میں معلوم ہو۔ + +اپنی hardhat.config.js کو اس طرح دکھنے کے لیے اپ ڈیٹ کریں: + +```js + /** + * @type import('hardhat/config').HardhatUserConfig + */ + require('dotenv').config(); + require("@nomiclabs/hardhat-ethers"); + const { API_URL, PRIVATE_KEY } = process.env; + module.exports = { + solidity: "0.8.1", + defaultNetwork: "sepolia", + networks: { + hardhat: {}, + sepolia: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`] + } + }, + } +``` + +## مرحلہ 14: ہمارا کنٹریکٹ کمپائل کریں {#compile-contract} + +یہ یقینی بنانے کے لیے کہ اب تک سب کچھ کام کر رہا ہے، آئیے اپنے کنٹریکٹ کو کمپائل کریں۔ کمپائل ٹاسک بلٹ ان ہارڈ ہیٹ ٹاسک میں سے ایک ہے۔ + +کمانڈ لائن سے چلائیں: + + ``` + npx hardhat compile + ``` + +آپ کو سورس فائل میں SPDX لائسنس شناخت کنندہ فراہم نہ کیے جانے کے بارے میں ایک انتباہ مل سکتا ہے، لیکن اس کے بارے میں فکر کرنے کی ضرورت نہیں ہے — امید ہے کہ باقی سب کچھ ٹھیک نظر آئے گا! اگر نہیں، تو آپ ہمیشہ [Alchemy discord](https://discord.gg/u72VCg3) میں پیغام بھیج سکتے ہیں۔ + +## مرحلہ 15: ہماری ڈیپلوئے اسکرپٹ لکھیں {#write-deploy} + +اب جب کہ ہمارا کنٹریکٹ لکھا جا چکا ہے اور ہماری کنفیگریشن فائل تیار ہے، اب وقت آگیا ہے کہ ہم اپنی کنٹریکٹ ڈیپلوئے اسکرپٹ لکھیں۔ + +`scripts/` فولڈر پر جائیں اور `deploy.js` نامی ایک نئی فائل بنائیں، اس میں درج ذیل مواد شامل کریں: + +```js +async function main() { + const MyNFT = await ethers.getContractFactory("MyNFT") + + // ڈیپلوئمنٹ شروع کریں، ایک وعدہ واپس کریں جو ایک کنٹریکٹ آبجیکٹ میں حل ہو + const myNFT = await MyNFT.deploy() + await myNFT.deployed() + console.log("کنٹریکٹ اس ایڈریس پر ڈیپلوئے کیا گیا:", myNFT.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 MyNFT = await ethers.getContractFactory("MyNFT"); + ``` + +ethers.js میں ایک ContractFactory نئے اسمارٹ کنٹریکٹس کو ڈیپلوئے کرنے کے لیے استعمال ہونے والا ایک خلاصہ ہے، لہذا MyNFT یہاں ہمارے NFT کنٹریکٹ کی مثالوں کے لیے ایک فیکٹری ہے۔ hardhat-ethers پلگ ان کا استعمال کرتے وقت ContractFactory اور Contract مثالیں پہلے دستخط کنندہ سے بطور ڈیفالٹ منسلک ہوتی ہیں۔ + + ``` + const myNFT = await MyNFT.deploy(); + ``` + +ContractFactory پر deploy() کو کال کرنے سے ڈیپلوئمنٹ شروع ہو جائے گی، اور ایک Promise واپس آئے گا جو ایک Contract میں حل ہو جائے گا۔ یہ وہ آبجیکٹ ہے جس میں ہمارے ہر اسمارٹ کنٹریکٹ فنکشن کے لیے ایک طریقہ ہے۔ + +## مرحلہ 16: ہمارا کنٹریکٹ ڈیپلوئے کریں {#deploy-contract} + +ہم آخر کار اپنے اسمارٹ کنٹریکٹ کو ڈیپلوئے کرنے کے لیے تیار ہیں! اپنی پروجیکٹ ڈائرکٹری کی جڑ پر واپس جائیں، اور کمانڈ لائن میں چلائیں: + + ``` + npx hardhat --network sepolia run scripts/deploy.js + ``` + +پھر آپ کو کچھ اس طرح نظر آنا چاہیے: + + ``` + کنٹریکٹ اس ایڈریس پر ڈیپلوئے کیا گیا: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 + ``` + +اگر ہم [Sepolia etherscan](https://sepolia.etherscan.io/) پر جائیں اور اپنے کنٹریکٹ ایڈریس کو تلاش کریں تو ہمیں یہ دیکھنے کے قابل ہونا چاہئے کہ یہ کامیابی سے ڈیپلوئے ہو گیا ہے۔ اگر آپ اسے فوراً نہیں دیکھ سکتے ہیں، تو براہ کرم تھوڑی دیر انتظار کریں کیونکہ اس میں کچھ وقت لگ سکتا ہے۔ ٹرانزیکشن کچھ اس طرح نظر آئے گی: + +![Etherscan پر اپنے ٹرانزیکشن کا ایڈریس دیکھیں](./etherscan-sepoila-contract-creation.png) + +From ایڈریس آپ کے MetaMask اکاؤنٹ کے ایڈریس سے ملنا چاہیے اور To ایڈریس پر “Contract Creation” لکھا ہوگا۔ اگر ہم ٹرانزیکشن میں کلک کرتے ہیں، تو ہمیں To فیلڈ میں اپنا کنٹریکٹ ایڈریس نظر آئے گا: + +![Etherscan پر اپنے کنٹریکٹ کا ایڈریس دیکھیں](./etherscan-sepolia-tx-details.png) + +یاہ! آپ نے ابھی اپنا NFT اسمارٹ کنٹریکٹ Ethereum (ٹیسٹ نیٹ) چین پر ڈیپلوئے کیا ہے! + +یہ سمجھنے کے لیے کہ پس پردہ کیا ہو رہا ہے، آئیے اپنے [Alchemy ڈیش بورڈ](https://dashboard.alchemyapi.io/explorer) میں ایکسپلورر ٹیب پر جائیں۔ اگر آپ کے پاس ایک سے زیادہ Alchemy ایپس ہیں تو ایپ کے ذریعے فلٹر کرنا اور “MyNFT” منتخب کرنا یقینی بنائیں۔ + +![Alchemy کے ایکسپلورر ڈیش بورڈ کے ساتھ “پس پردہ” کی گئی کالز دیکھیں](./alchemy-explorer-goerli.png) + +یہاں آپ کو مٹھی بھر JSON-RPC کالز نظر آئیں گی جو Hardhat/Ethers نے ہمارے لیے پس پردہ کی تھیں جب ہم نے .deploy() فنکشن کو کال کیا تھا۔ یہاں دو اہم کالز [eth_sendRawTransaction](/developers/docs/apis/json-rpc/#eth_sendrawtransaction) ہیں، جو دراصل ہمارے اسمارٹ کنٹریکٹ کو Sepolia چین پر لکھنے کی درخواست ہے، اور [eth_getTransactionByHash](/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) جو ہیش کی بنیاد پر ہماری ٹرانزیکشن کے بارے میں معلومات پڑھنے کی درخواست ہے (ٹرانزیکشنز بھیجتے وقت ایک عام نمونہ)۔ ٹرانزیکشنز بھیجنے کے بارے میں مزید جاننے کے لیے، [Web3 کا استعمال کرتے ہوئے ٹرانزیکشنز بھیجنے](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) پر یہ ٹیوٹوریل دیکھیں۔ + +اس ٹیوٹوریل کے حصہ 1 کے لیے بس اتنا ہی۔ [حصہ 2 میں، ہم اصل میں ایک NFT مِنٹ کرکے اپنے اسمارٹ کنٹریکٹ کے ساتھ تعامل کریں گے](/developers/tutorials/how-to-mint-an-nft/)، اور [حصہ 3 میں ہم آپ کو دکھائیں گے کہ اپنے Ethereum والیٹ میں اپنے NFT کو کیسے دیکھیں](/developers/tutorials/how-to-view-nft-in-metamask/)! diff --git a/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md new file mode 100644 index 00000000000..434ff69e3d0 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -0,0 +1,179 @@ +--- +title: "Solidity سے دوسرے معاہدوں کے ساتھ تعامل کریں" +description: "ایک موجودہ معاہدے سے ایک اسمارٹ معاہدہ کیسے تعینات کریں اور اس کے ساتھ تعامل کریں" +author: "jdourlens" +tags: + [ + "اسمارٹ معاہدات", + "solidity", + "remix", + "تعینات کرنا", + "مرکبیت" + ] +skill: advanced +lang: ur-in +published: 2020-04-05 +source: EthereumDev +sourceUrl: https://ethereumdev.io/interact-with-other-contracts-from-solidity/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +پچھلے ٹیوٹوریلز میں ہم نے بہت کچھ سیکھا [اپنا پہلا اسمارٹ معاہدہ کیسے تعینات کریں](/developers/tutorials/deploying-your-first-smart-contract/) اور اس میں کچھ خصوصیات شامل کرنا جیسے [موڈیفائرز کے ساتھ رسائی کو کنٹرول کرنا](https://ethereumdev.io/organize-your-code-and-control-access-to-your-smart-contract-with-modifiers/) یا [Solidity میں غلطی سے نمٹنا](https://ethereumdev.io/handle-errors-in-solidity-with-require-and-revert/)۔ اس ٹیوٹوریل میں ہم سیکھیں گے کہ ایک موجودہ معاہدے سے ایک اسمارٹ معاہدہ کیسے تعینات کیا جائے اور اس کے ساتھ تعامل کیا جائے۔ + +ہم ایک ایسا معاہدہ بنائیں گے جو کسی کو بھی اپنا `Counter` اسمارٹ معاہدہ رکھنے کے قابل بنائے گا اس کے لیے ایک فیکٹری بنا کر، اس کا نام `CounterFactory` ہوگا۔ سب سے پہلے یہاں ہمارے ابتدائی `Counter` اسمارٹ معاہدے کا کوڈ ہے: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + uint256 private _count; + address private _owner; + address private _factory; + + + modifier onlyOwner(address caller) { + require(caller == _owner, "آپ معاہدے کے مالک نہیں ہیں"); + _; + } + + modifier onlyFactory() { + require(msg.sender == _factory, "آپ کو فیکٹری استعمال کرنے کی ضرورت ہے"); + _; + } + + constructor(address owner) public { + _owner = owner; + _factory = msg.sender; + } + + function getCount() public view returns (uint256) { + return _count; + } + + function increment(address caller) public onlyFactory onlyOwner(caller) { + _count++; + } + +} +``` + +نوٹ کریں کہ ہم نے فیکٹری کے ایڈریس اور معاہدے کے مالک کے ایڈریس کا ٹریک رکھنے کے لیے معاہدے کے کوڈ میں تھوڑی ترمیم کی ہے۔ جب آپ کسی دوسرے معاہدے سے کسی معاہدے کا کوڈ کال کرتے ہیں، تو msg.sender ہمارے معاہدے کی فیکٹری کے ایڈریس کا حوالہ دے گا۔ یہ سمجھنے کے لیے **ایک بہت اہم نکتہ ہے** کیونکہ دوسرے معاہدوں کے ساتھ تعامل کرنے کے لیے ایک معاہدے کا استعمال ایک عام رواج ہے۔ اس لیے آپ کو پیچیدہ معاملات میں اس بات کا خیال رکھنا چاہیے کہ بھیجنے والا کون ہے۔ + +اس کے لیے ہم نے ایک `onlyFactory` موڈیفائر بھی شامل کیا ہے جو اس بات کو یقینی بناتا ہے کہ اسٹیٹ کو تبدیل کرنے والے فنکشن کو صرف فیکٹری کے ذریعے ہی کال کیا جا سکتا ہے جو اصل کالر کو ایک پیرامیٹر کے طور پر پاس کرے گا۔ + +ہمارے نئے `CounterFactory` کے اندر جو دیگر تمام کاؤنٹروں کا نظم کرے گا، ہم ایک میپنگ شامل کریں گے جو ایک مالک کو اس کے کاؤنٹر معاہدے کے ایڈریس کے ساتھ منسلک کرے گا: + +```solidity +mapping(address => Counter) _counters; +``` + +Ethereum میں، میپنگ جاوا اسکرپٹ میں آبجیکٹس کے مساوی ہیں، وہ قسم A کی کلید کو قسم B کی قدر سے میپ کرنے کے قابل بناتے ہیں۔ اس صورت میں ہم ایک مالک کے ایڈریس کو اس کے کاؤنٹر کے انسٹنس کے ساتھ میپ کرتے ہیں۔ + +کسی کے لیے ایک نیا کاؤنٹر شروع کرنا اس طرح نظر آئے گا: + +```solidity + function createCounter() public { + require (_counters[msg.sender] == Counter(0)); + _counters[msg.sender] = new Counter(msg.sender); + } +``` + +ہم پہلے چیک کرتے ہیں کہ آیا وہ شخص پہلے سے ہی ایک کاؤنٹر کا مالک ہے۔ اگر وہ کاؤنٹر کا مالک نہیں ہے تو ہم اس کا ایڈریس `Counter` کنسٹرکٹر کو پاس کر کے ایک نیا کاؤنٹر شروع کرتے ہیں اور نئے بنائے گئے انسٹنس کو میپنگ کو تفویض کرتے ہیں۔ + +ایک مخصوص کاؤنٹر کی گنتی حاصل کرنے کے لیے یہ اس طرح نظر آئے گا: + +```solidity +function getCount(address account) public view returns (uint256) { + require (_counters[account] != Counter(0)); + return (_counters[account].getCount()); +} + +function getMyCount() public view returns (uint256) { + return (getCount(msg.sender)); +} +``` + +پہلا فنکشن یہ چیک کرتا ہے کہ آیا دیے گئے ایڈریس کے لیے کاؤنٹر معاہدہ موجود ہے اور پھر انسٹنس سے `getCount` میتھڈ کو کال کرتا ہے۔ دوسرا فنکشن: `getMyCount` صرف msg.sender کو براہ راست `getCount` فنکشن میں پاس کرنے کا ایک مختصر طریقہ ہے۔ + +`increment` فنکشن کافی ملتا جلتا ہے لیکن اصل ٹرانزیکشن بھیجنے والے کو `Counter` معاہدے میں پاس کرتا ہے: + +```solidity +function increment() public { + require (_counters[msg.sender] != Counter(0)); + Counter(_counters[msg.sender]).increment(msg.sender); + } +``` + +نوٹ کریں کہ اگر بہت زیادہ بار کال کیا گیا، تو ہمارا کاؤنٹر ممکنہ طور پر اوور فلو کا شکار ہو سکتا ہے۔ اس ممکنہ صورتحال سے بچانے کے لیے آپ کو جتنا ممکن ہو [SafeMath لائبریری](https://ethereumdev.io/using-safe-math-library-to-prevent-from-overflows/) کا استعمال کرنا چاہیے۔ + +ہمارے معاہدے کو تعینات کرنے کے لیے، آپ کو `CounterFactory` اور `Counter` دونوں کا کوڈ فراہم کرنا ہوگا۔ مثال کے طور پر Remix میں تعینات کرتے وقت آپ کو CounterFactory کو منتخب کرنے کی ضرورت ہوگی۔ + +مکمل کوڈ یہاں ہے: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + uint256 private _count; + address private _owner; + address private _factory; + + + modifier onlyOwner(address caller) { + require(caller == _owner, "آپ معاہدے کے مالک نہیں ہیں"); + _; + } + + modifier onlyFactory() { + require(msg.sender == _factory, "آپ کو فیکٹری استعمال کرنے کی ضرورت ہے"); + _; + } + + constructor(address owner) public { + _owner = owner; + _factory = msg.sender; + } + + function getCount() public view returns (uint256) { + return _count; + } + + function increment(address caller) public onlyFactory onlyOwner(caller) { + _count++; + } + +} + +contract CounterFactory { + + mapping(address => Counter) _counters; + + function createCounter() public { + require (_counters[msg.sender] == Counter(0)); + _counters[msg.sender] = new Counter(msg.sender); + } + + function increment() public { + require (_counters[msg.sender] != Counter(0)); + Counter(_counters[msg.sender]).increment(msg.sender); + } + + function getCount(address account) public view returns (uint256) { + require (_counters[account] != Counter(0)); + return (_counters[account].getCount()); + } + + function getMyCount() public view returns (uint256) { + return (getCount(msg.sender)); + } + +} +``` + +کمپائل کرنے کے بعد، Remix ڈیپلائے سیکشن میں آپ تعینات کی جانے والی فیکٹری کو منتخب کریں گے: + +![Remix میں تعینات کی جانے والی فیکٹری کا انتخاب](./counterfactory-deploy.png) + +پھر آپ اپنی معاہدہ فیکٹری کے ساتھ کھیل سکتے ہیں اور بدلتی ہوئی قدر کو چیک کر سکتے ہیں۔ اگر آپ اسمارٹ معاہدے کو کسی مختلف ایڈریس سے کال کرنا چاہتے ہیں تو آپ کو Remix کے اکاؤنٹ سلیکٹ میں ایڈریس تبدیل کرنے کی ضرورت ہوگی۔ diff --git a/public/content/translations/ur/developers/tutorials/ipfs-decentralized-ui/index.md b/public/content/translations/ur/developers/tutorials/ipfs-decentralized-ui/index.md new file mode 100644 index 00000000000..1806e4ed156 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/ipfs-decentralized-ui/index.md @@ -0,0 +1,73 @@ +--- +title: "غیر مرکزی یوزر انٹرفیس کے لیے IPFS" +description: "یہ ٹیوٹوریل پڑھنے والے کو سکھاتا ہے کہ ایک ڈیپ (dapp) کے لیے یوزر انٹرفیس کو اسٹور کرنے کے لیے IPFS کا استعمال کیسے کریں۔ اگرچہ ایپلیکیشن کا ڈیٹا اور کاروباری منطق غیر مرکزی ہے، لیکن سنسر شپ سے مزاحم یوزر انٹرفیس کے بغیر، یوزر کسی بھی طرح اس تک رسائی کھو سکتے ہیں۔" +author: Ori Pomerantz +tags: [ "ipfs" ] +skill: beginner +lang: ur-in +published: 2024-06-29 +--- + +آپ نے ایک ناقابل یقین نیا ڈیپ (dapp) لکھا ہے۔ آپ نے اس کے لیے ایک [یوزر انٹرفیس](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) بھی لکھا ہے۔ لیکن اب آپ کو ڈر ہے کہ کوئی آپ کے یوزر انٹرفیس کو بند کرکے اسے سنسر کرنے کی کوشش کرے گا، جو کلاؤڈ میں صرف ایک سرور ہے۔ اس ٹیوٹوریل میں آپ سیکھتے ہیں کہ اپنے یوزر انٹرفیس کو **[انٹرپلینیٹری فائل سسٹم (IPFS)](https://ipfs.tech/developers/)** پر ڈال کر سنسر شپ سے کیسے بچا جائے تاکہ کوئی بھی دلچسپی رکھنے والا اسے مستقبل کی رسائی کے لیے سرور پر پن کر سکے۔ + +آپ تمام کام کرنے کے لیے [Fleek](https://resources.fleek.xyz/docs/) جیسی تھرڈ پارٹی سروس کا استعمال کر سکتے ہیں۔ یہ ٹیوٹوریل ان لوگوں کے لیے ہے جو یہ سمجھنے کے لیے کافی کچھ کرنا چاہتے ہیں کہ وہ کیا کر رہے ہیں، چاہے اس میں زیادہ کام ہی کیوں نہ ہو۔ + +## مقامی طور پر شروع کرنا {#getting-started-locally} + +متعدد [تھرڈ-پارٹی IPFS فراہم کنندگان](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service) ہیں، لیکن جانچ کے لیے مقامی طور پر IPFS چلا کر شروع کرنا بہتر ہے۔ + +1. [IPFS یوزر انٹرفیس](https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions) انسٹال کریں۔ + +2. اپنی ویب سائٹ کے ساتھ ایک ڈائرکٹری بنائیں۔ اگر آپ [Vite](https://vite.dev/) استعمال کر رہے ہیں، تو یہ کمانڈ استعمال کریں: + + ```sh + pnpm vite build + ``` + +3. IPFS ڈیسک ٹاپ میں، **Import > Folder** پر کلک کریں اور پچھلے مرحلے میں بنائی گئی ڈائرکٹری کو منتخب کریں۔ + +4. جس فولڈر کو آپ نے ابھی اپ لوڈ کیا ہے اسے منتخب کریں اور **Rename** پر کلک کریں۔ اسے ایک زیادہ بامعنی نام دیں۔ + +5. اسے دوبارہ منتخب کریں اور **Share link** پر کلک کریں۔ URL کو کلپ بورڈ پر کاپی کریں۔ لنک `https://ipfs.io/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ` جیسا ہوگا۔ + +6. **Status** پر کلک کریں۔ گیٹ وے ایڈریس دیکھنے کے لیے **Advanced** ٹیب کو پھیلائیں۔ مثال کے طور پر، میرے سسٹم پر ایڈریس `http://127.0.0.1:8080` ہے۔ + +7. اپنا ایڈریس تلاش کرنے کے لیے لنک مرحلے سے پاتھ کو گیٹ وے ایڈریس کے ساتھ جوڑیں۔ مثال کے طور پر، اوپر دی گئی مثال کے لیے، URL ہے `http://127.0.0.1:8080/ipfs/QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`۔ اپنی سائٹ دیکھنے کے لیے اس URL کو براؤزر میں کھولیں۔ + +## اپ لوڈ کرنا {#uploading} + +تو اب آپ مقامی طور پر فائلوں کو پیش کرنے کے لیے IPFS کا استعمال کر سکتے ہیں، جو بہت دلچسپ نہیں ہے۔ اگلا مرحلہ یہ ہے کہ جب آپ آف لائن ہوں تو انہیں دنیا کے لیے دستیاب کرائیں۔ + +کئی مشہور [پننگ سروسز](https://docs.ipfs.tech/concepts/persistence/#pinning-services) ہیں۔ ان میں سے کسی ایک کا انتخاب کریں۔ آپ جو بھی سروس استعمال کرتے ہیں، آپ کو ایک اکاؤنٹ بنانے اور اسے اپنے IPFS ڈیسک ٹاپ میں **مواد شناخت کنندہ (CID)** فراہم کرنے کی ضرورت ہے۔ + +ذاتی طور پر، مجھے استعمال کرنے کے لیے [4EVERLAND](https://docs.4everland.org/storage/4ever-pin/guides) سب سے آسان لگا۔ اس کے لیے ہدایات یہ ہیں: + +1. [ڈیش بورڈ](https://dashboard.4everland.org/overview) پر براؤز کریں اور اپنے والیٹ سے لاگ ان کریں۔ + +2. بائیں سائڈبار میں **Storage > 4EVER Pin** پر کلک کریں۔ + +3. **Upload > Selected CID** پر کلک کریں۔ اپنے مواد کو ایک نام دیں اور IPFS ڈیسک ٹاپ سے CID فراہم کریں۔ فی الحال ایک CID ایک اسٹرنگ ہے جو `Qm` سے شروع ہوتی ہے جس کے بعد 44 حروف اور ہندسے ہوتے ہیں جو ایک [بیس-58 انکوڈڈ](https://medium.com/bootdotdev/base64-vs-base58-encoding-c25553ff4524) ہیش کی نمائندگی کرتے ہیں، جیسے `QmaCuQ7yN6iyBjLmLGe8YiFuCwnePoKfVu6ue8vLBsLJQJ`، لیکن [اس کے تبدیل ہونے کا امکان ہے](https://docs.ipfs.tech/concepts/content-addressing/#version-1-v1)۔ + +4. ابتدائی اسٹیٹس **Queued** ہے۔ دوبارہ لوڈ کریں جب تک کہ یہ **Pinned** میں تبدیل نہ ہو جائے۔ + +5. لنک حاصل کرنے کے لیے اپنے CID پر کلک کریں۔ آپ میری ایپلیکیشن [یہاں](https://bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im/) دیکھ سکتے ہیں۔ + +6. آپ کو اپنے اکاؤنٹ کو ایک مہینے سے زیادہ کے لیے پن کرنے کے لیے اسے فعال کرنے کی ضرورت پڑسکتی ہے۔ اکاؤنٹ ایکٹیویشن کی لاگت تقریباً 1$ ہے۔ اگر آپ نے اسے بند کر دیا ہے، تو لاگ آؤٹ کریں اور دوبارہ فعال کرنے کے لیے پوچھے جانے کے لیے واپس لاگ ان کریں۔ + +## IPFS سے استعمال کرنا {#using-from-ipfs} + +اس وقت آپ کے پاس ایک مرکزی گیٹ وے کا لنک ہے جو آپ کے IPFS مواد کو پیش کرتا ہے۔ مختصر یہ کہ، آپ کا یوزر انٹرفیس تھوڑا محفوظ ہو سکتا ہے لیکن یہ اب بھی سنسر شپ سے مزاحم نہیں ہے۔ حقیقی سنسرشپ مزاحمت کے لیے، یوزرس کو IPFS کو [براہ راست براؤزر سے](https://docs.ipfs.tech/install/ipfs-companion/#prerequisites) استعمال کرنے کی ضرورت ہے۔ + +ایک بار جب آپ اسے انسٹال کر لیتے ہیں (اور ڈیسک ٹاپ IPFS کام کر رہا ہوتا ہے)، تو آپ کسی بھی سائٹ پر [/ipfs/``](https://any.site/ipfs/bafybeifqka2odrne5b6l5guthqvbxu4pujko2i6rx2zslvr3qxs6u5o7im) پر جا سکتے ہیں اور آپ کو وہ مواد، ایک غیر مرکزی طریقے سے پیش کیا ہوا، مل جائے گا۔ + +## نقصانات {#drawbacks} + +آپ IPFS فائلوں کو قابل اعتماد طریقے سے حذف نہیں کر سکتے، لہذا جب تک آپ اپنے یوزر انٹرفیس میں ترمیم کر رہے ہیں، شاید بہتر ہے کہ اسے یا تو مرکزی چھوڑ دیں، یا [انٹرپلینیٹری نیم سسٹم (IPNS)](https://docs.ipfs.tech/concepts/ipns/#mutability-in-ipfs) کا استعمال کریں، ایک ایسا نظام جو IPFS کے اوپر تغیر پذیری فراہم کرتا ہے۔ یقیناً، کوئی بھی چیز جو قابل تغیر ہے اسے سنسر کیا جا سکتا ہے، IPNS کے معاملے میں اس شخص پر دباؤ ڈال کر جس کے پاس پرائیویٹ کی ہے جس سے یہ مطابقت رکھتا ہے۔ + +مزید برآں، کچھ پیکیجز کو IPFS کے ساتھ مسئلہ ہے، لہذا اگر آپ کی ویب سائٹ بہت پیچیدہ ہے تو یہ ایک اچھا حل نہیں ہو سکتا ہے۔ اور یقیناً، کوئی بھی چیز جو سرور انضمام پر انحصار کرتی ہے اسے صرف IPFS پر کلائنٹ سائیڈ رکھ کر غیر مرکزی نہیں بنایا جا سکتا ہے۔ + +## نتیجہ {#conclusion} + +جس طرح Ethereum آپ کو اپنے ڈیپ (dapp) کے ڈیٹا بیس اور کاروباری منطق کے پہلوؤں کو غیر مرکزی بنانے دیتا ہے، اسی طرح IPFS آپ کو یوزر انٹرفیس کو غیر مرکزی بنانے دیتا ہے۔ یہ آپ کو اپنے ڈیپ (dapp) کے خلاف ایک اور حملے کے ویکٹر کو بند کرنے دیتا ہے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md b/public/content/translations/ur/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md new file mode 100644 index 00000000000..3ede6b5e5f8 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/index.md @@ -0,0 +1,111 @@ +--- +title: "create-eth-app کے ساتھ اپنے ڈیپ فرنٹ اینڈ ڈیولپمنٹ کو کک اسٹارٹ کریں" +description: "create-eth-app کا استعمال کیسے کریں اور اس کی خصوصیات کا ایک جائزہ" +author: "Markus Waas" +tags: + [ + "فرنٹ اینڈ", + "javascript", + "ethers.js", + "دی گراف", + "defi" + ] +skill: beginner +lang: ur-in +published: 2020-04-27 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/create-eth-app +--- + +پچھلی بار ہم نے [Solidity کی بڑی تصویر](https://soliditydeveloper.com/solidity-overview-2020) پر نظر ڈالی تھی اور [create-eth-app](https://github.com/PaulRBerg/create-eth-app) کا ذکر بھی کیا تھا۔ اب آپ جانیں گے کہ اسے کیسے استعمال کیا جائے، کون سی خصوصیات اس میں ضم ہیں اور اس کو مزید وسیع کرنے کے اضافی آئیڈیاز کیا ہیں۔ [Sablier](http://sablier.com/) کے بانی، Paul Razvan Berg کے ذریعہ شروع کی گئی، یہ ایپ آپ کے فرنٹ اینڈ ڈیولپمنٹ کو کِک اسٹارٹ کرے گی اور منتخب کرنے کے لیے کئی اختیاری انضمام کے ساتھ آتی ہے۔ + +## انسٹالیشن {#installation} + +انسٹالیشن کے لیے Yarn 0.25 یا اس سے اعلیٰ ورژن کی ضرورت ہے (`npm install yarn --global`)۔ یہ چلانے جتنا ہی آسان ہے: + +```bash +yarn create eth-app my-eth-app +cd my-eth-app +yarn react-app:start +``` + +یہ اندرونی طور پر [create-react-app](https://github.com/facebook/create-react-app) کا استعمال کر رہا ہے۔ اپنی ایپ دیکھنے کے لیے، `http://localhost:3000/` کھولیں۔ جب آپ پروڈکشن میں ڈیپلائے کرنے کے لیے تیار ہوں، تو yarn build کے ساتھ ایک مِنیفائیڈ بنڈل بنائیں۔ اسے ہوسٹ کرنے کا ایک آسان طریقہ [Netlify](https://www.netlify.com/) ہوگا۔ آپ ایک GitHub ریپو بنا سکتے ہیں، اسے Netlify میں شامل کر سکتے ہیں، بلڈ کمانڈ سیٹ اپ کر سکتے ہیں اور بس ہو گیا! آپ کی ایپ ہوسٹ ہو جائے گی اور ہر کسی کے لیے قابل استعمال ہوگی۔ اور یہ سب کچھ مفت ہے۔ + +## خصوصیات {#features} + +### React اور create-react-app {#react--create-react-app} + +سب سے پہلے ایپ کا دل: React اور _create-react-app_ کے ساتھ آنے والی تمام اضافی خصوصیات۔ اگر آپ Ethereum کو انٹیگریٹ نہیں کرنا چاہتے ہیں تو صرف اس کا استعمال کرنا ایک بہترین آپشن ہے۔ [React](https://react.dev/) خود انٹرایکٹو UI بنانا بہت آسان بنا دیتا ہے۔ ہو سکتا ہے یہ [Vue](https://vuejs.org/) کی طرح مبتدیوں کے لیے آسان نہ ہو، لیکن یہ اب بھی زیادہ تر استعمال ہوتا ہے، اس میں زیادہ خصوصیات ہیں اور سب سے اہم بات یہ ہے کہ منتخب کرنے کے لیے ہزاروں اضافی لائبریریاں موجود ہیں۔ _create-react-app_ اس کے ساتھ شروعات کرنا بھی بہت آسان بنا دیتا ہے اور اس میں شامل ہیں: + +- React, JSX, ES6, TypeScript, فلو سنٹیکس سپورٹ۔ +- ES6 سے آگے زبان کی اضافی چیزیں جیسے آبجیکٹ اسپریڈ آپریٹر۔ +- آٹوپریفکسڈ CSS، لہذا آپ کو -webkit- یا دیگر پریفکس کی ضرورت نہیں ہے۔ +- کوریج رپورٹنگ کے لیے بلٹ ان سپورٹ کے ساتھ ایک تیز انٹرایکٹو یونٹ ٹیسٹ رنر۔ +- ایک لائیو ڈیولپمنٹ سرور جو عام غلطیوں کے بارے میں خبردار کرتا ہے۔ +- ہیشز اور سورس میپس کے ساتھ، پروڈکشن کے لیے JS، CSS، اور تصاویر کو بنڈل کرنے کے لیے ایک بلڈ اسکرپٹ۔ + +خاص طور پر _create-eth-app_ نئے [hooks effects](https://legacy.reactjs.org/docs/hooks-effect.html) کا استعمال کر رہا ہے۔ طاقتور، پھر بھی بہت چھوٹے نام نہاد فنکشنل کمپونینٹس لکھنے کا ایک طریقہ۔ _create-eth-app_ میں ان کا استعمال کیسے ہوتا ہے اس کے لیے Apollo کے بارے میں نیچے والا سیکشن دیکھیں۔ + +### Yarn Workspaces {#yarn-workspaces} + +[Yarn Workspaces](https://classic.yarnpkg.com/en/docs/workspaces/) آپ کو ایک سے زیادہ پیکیجز رکھنے کی اجازت دیتے ہیں، لیکن ان سب کو روٹ فولڈر سے منظم کرنے اور `yarn install` کا استعمال کرتے ہوئے سب کے لیے ایک ساتھ ڈیپینڈینسیز انسٹال کرنے کے قابل بناتے ہیں۔ یہ خاص طور پر چھوٹے اضافی پیکیجز کے لیے معنی خیز ہے جیسے کہ اسمارٹ کنٹریکٹس ایڈریس/ABI مینجمنٹ (یہ معلومات کہ آپ نے کون سے اسمارٹ کنٹریکٹس کہاں ڈیپلائے کیے ہیں اور ان کے ساتھ کیسے کمیونیکیٹ کرنا ہے) یا گراف انٹیگریشن، دونوں `create-eth-app` کا حصہ ہیں۔ + +### ethers.js {#ethersjs} + +جبکہ [Web3](https://docs.web3js.org/) اب بھی زیادہ تر استعمال ہوتا ہے، [ethers.js](https://docs.ethers.io/) نے پچھلے سال ایک متبادل کے طور پر بہت زیادہ مقبولیت حاصل کی ہے اور یہی وہ ہے جسے _create-eth-app_ میں انٹیگریٹ کیا گیا ہے۔ آپ اس کے ساتھ کام کر سکتے ہیں، اسے Web3 میں تبدیل کر سکتے ہیں یا [ethers.js v5](https://docs.ethers.org/v5/) میں اپ گریڈ کرنے پر غور کر سکتے ہیں جو تقریباً بیٹا سے باہر ہے۔ + +### دی گراف {#the-graph} + +[GraphQL](https://graphql.org/) ایک [Restful API](https://restfulapi.net/) کے مقابلے میں ڈیٹا کو ہینڈل کرنے کا ایک متبادل طریقہ ہے۔ ان کے Restful Apis پر کئی فوائد ہیں، خاص طور پر وکندریقرت بلاک چین ڈیٹا کے لیے۔ اگر آپ اس کے پیچھے کی وجہ جاننے میں دلچسپی رکھتے ہیں، تو [GraphQL Will Power the Decentralized Web](https://medium.com/graphprotocol/graphql-will-power-the-decentralized-web-d7443a69c69a) پر ایک نظر ڈالیں۔ + +عام طور پر آپ براہ راست اپنے اسمارٹ کنٹریکٹ سے ڈیٹا حاصل کرتے ہیں۔ تازہ ترین ٹریڈ کا وقت پڑھنا چاہتے ہیں؟ بس `MyContract.methods.latestTradeTime().call()` کو کال کریں جو Ethereum نوڈ سے آپ کے ڈی ایپ میں ڈیٹا حاصل کرتا ہے۔ لیکن کیا ہوگا اگر آپ کو سینکڑوں مختلف ڈیٹا پوائنٹس کی ضرورت ہو؟ اس کے نتیجے میں نوڈ پر سینکڑوں ڈیٹا فیچ ہوں گے، جس میں ہر بار [RTT](https://wikipedia.org/wiki/Round-trip_delay_time) کی ضرورت ہوگی، جو آپ کے ڈی ایپ کو سست اور ناکارہ بنا دے گا۔ ایک حل آپ کے کنٹریکٹ کے اندر ایک فیچر کال فنکشن ہو سکتا ہے جو ایک ساتھ ایک سے زیادہ ڈیٹا واپس کرتا ہے۔ اگرچہ یہ ہمیشہ مثالی نہیں ہے۔ + +اور پھر آپ کو تاریخی ڈیٹا میں بھی دلچسپی ہو سکتی ہے۔ آپ نہ صرف آخری ٹریڈ کا وقت جاننا چاہتے ہیں، بلکہ ان تمام ٹریڈز کے اوقات بھی جاننا چاہتے ہیں جو آپ نے خود کیے ہیں۔ _create-eth-app_ سب گراف پیکیج کا استعمال کریں، [ڈاکومنٹیشن](https://thegraph.com/docs/en/subgraphs/developing/creating/starting-your-subgraph) پڑھیں اور اسے اپنے کنٹریکٹس کے مطابق ڈھالیں۔ اگر آپ مقبول اسمارٹ کنٹریکٹس کی تلاش میں ہیں، تو ہو سکتا ہے کہ پہلے سے ہی ایک سب گراف موجود ہو۔ [سب گراف ایکسپلورر](https://thegraph.com/explorer/) دیکھیں۔ + +ایک بار جب آپ کے پاس سب گراف ہو جاتا ہے، تو یہ آپ کو اپنے ڈی ایپ میں ایک سادہ کوئری لکھنے کی اجازت دیتا ہے جو آپ کے لیے درکار تمام اہم بلاک چین ڈیٹا کو بازیافت کرتا ہے، بشمول تاریخی ڈیٹا، اور اس کے لیے صرف ایک فیچ کی ضرورت ہوتی ہے۔ + +### Apollo {#apollo} + +[Apollo Boost](https://www.apollographql.com/docs/react/get-started/) انٹیگریشن کی بدولت آپ آسانی سے اپنے React ڈی ایپ میں گراف کو انٹیگریٹ کر سکتے ہیں۔ خاص طور پر [React hooks and Apollo](https://www.apollographql.com/blog/apollo-client-now-with-react-hooks) کا استعمال کرتے وقت، ڈیٹا حاصل کرنا اتنا ہی آسان ہے جتنا کہ اپنے کمپونینٹ میں ایک ہی GraphQl کوئری لکھنا: + +```js +const { loading, error, data } = useQuery(myGraphQlQuery) + +React.useEffect(() => { + if (!loading && !error && data) { + console.log({ data }) + } +}, [loading, error, data]) +``` + +## ٹیمپلیٹس {#templates} + +اس کے علاوہ آپ کئی مختلف ٹیمپلیٹس میں سے انتخاب کر سکتے ہیں۔ اب تک آپ Aave، Compound، UniSwap یا sablier انٹیگریشن استعمال کر سکتے ہیں۔ وہ سبھی پہلے سے بنے سب گراف انٹیگریشنز کے ساتھ اہم سروس اسمارٹ کنٹریکٹ ایڈریسز شامل کرتے ہیں۔ بس ٹیمپلیٹ کو کریشن کمانڈ میں شامل کریں جیسے `yarn create eth-app my-eth-app --with-template aave`۔ + +### Aave {#aave} + +[Aave](https://aave.com/) ایک وکندریقرت رقم قرض دینے والی مارکیٹ ہے۔ ڈیپازیٹرز غیر فعال آمدنی حاصل کرنے کے لیے مارکیٹ کو لیکویڈیٹی فراہم کرتے ہیں، جبکہ قرض لینے والے کولیٹرلز کا استعمال کرکے قرض لے سکتے ہیں۔ Aave کی ایک منفرد خصوصیت [فلیش لونز](https://aave.com/docs/developers/flash-loans) ہیں جو آپ کو بغیر کسی کولیٹرل کے رقم ادھار لینے کی اجازت دیتے ہیں، جب تک کہ آپ ایک ٹرانزیکشن کے اندر قرض واپس کر دیں۔ یہ مفید ہو سکتا ہے، مثال کے طور پر، آربٹریج ٹریڈنگ پر آپ کو اضافی نقد رقم دینے کے لیے۔ + +ٹریڈ کیے گئے ٹوکنز جو آپ کو سود کماتے ہیں انہیں _aTokens_ کہا جاتا ہے۔ + +جب آپ _create-eth-app_ کے ساتھ Aave کو انٹیگریٹ کرنے کا انتخاب کرتے ہیں، تو آپ کو ایک [سب گراف انٹیگریشن](https://docs.aave.com/developers/getting-started/using-graphql) ملے گا۔ Aave، The Graph کا استعمال کرتا ہے اور آپ کو پہلے ہی [Ropsten](https://thegraph.com/explorer/subgraph/aave/protocol-ropsten) اور [Mainnet](https://thegraph.com/explorer/subgraph/aave/protocol) پر [خام](https://thegraph.com/explorer/subgraph/aave/protocol-raw) یا [فارمیٹ شدہ](https://thegraph.com/explorer/subgraph/aave/protocol) شکل میں کئی استعمال کے لیے تیار سب گراف فراہم کرتا ہے۔ + +![Aave فلیش لون میم – "ہاں، اگر میں اپنا فلیش لون 1 ٹرانزیکشن سے زیادہ وقت تک رکھ سکتا، تو یہ بہت اچھا ہوتا"](./flashloan-meme.png) + +### Compound {#compound} + +[Compound](https://compound.finance/)، Aave کی طرح ہے۔ انٹیگریشن میں نیا [Compound v2 Subgraph](https://medium.com/graphprotocol/https-medium-com-graphprotocol-compound-v2-subgraph-highlight-a5f38f094195) پہلے سے ہی شامل ہے۔ یہاں سود کمانے والے ٹوکنز کو حیرت انگیز طور پر _cTokens_ کہا جاتا ہے۔ + +### Uniswap {#uniswap} + +[Uniswap](https://uniswap.exchange/) ایک وکندریقرت ایکسچینج (DEX) ہے۔ لیکویڈیٹی فراہم کرنے والے ٹریڈ کے دونوں اطراف کے لیے مطلوبہ ٹوکنز یا ایتھر فراہم کرکے فیس کما سکتے ہیں۔ یہ بڑے پیمانے پر استعمال ہوتا ہے اور اس لیے ٹوکنز کی ایک بہت وسیع رینج کے لیے اس کی لیکویڈیٹی سب سے زیادہ ہے۔ آپ اسے آسانی سے اپنے ڈی ایپ میں انٹیگریٹ کر سکتے ہیں، مثال کے طور پر، صارفین کو اپنے ETH کو DAI سے تبدیل کرنے کی اجازت دینے کے لیے۔ + +بدقسمتی سے، اس تحریر کے وقت انٹیگریشن صرف Uniswap v1 کے لیے ہے نہ کہ [ابھی جاری کردہ v2](https://uniswap.org/blog/uniswap-v2/) کے لیے۔ + +### Sablier {#sablier} + +[Sablier](https://sablier.com/) صارفین کو رقم کی ادائیگیوں کو اسٹریم کرنے کی اجازت دیتا ہے۔ ایک ہی تنخواہ کے دن کے بجائے، آپ کو ابتدائی سیٹ اپ کے بعد مزید کسی انتظامی کارروائی کے بغیر مسلسل اپنی رقم ملتی ہے۔ انٹیگریشن میں اس کا [اپنا سب گراف](https://thegraph.com/explorer/subgraph/sablierhq/sablier) شامل ہے۔ + +## آگے کیا ہے؟ {#whats-next} + +اگر آپ کے پاس _create-eth-app_ کے بارے میں سوالات ہیں، تو [Sablier کمیونٹی سرور](https://discord.gg/bsS8T47) پر جائیں، جہاں آپ _create-eth-app_ کے مصنفین سے رابطہ کر سکتے ہیں۔ کچھ پہلے اگلے اقدامات کے طور پر آپ [Material UI](https://mui.com/material-ui/) جیسے UI فریم ورک کو انٹیگریٹ کرنا چاہ سکتے ہیں، اس ڈیٹا کے لیے GraphQL کوئریز لکھیں جس کی آپ کو واقعی ضرورت ہے اور ڈیپلائمنٹ سیٹ اپ کریں۔ diff --git a/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md b/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md new file mode 100644 index 00000000000..81ee317b711 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md @@ -0,0 +1,269 @@ +--- +title: "SQL کے ساتھ Ethereum کے بنیادی موضوعات سیکھیں" +description: "یہ ٹیوٹوریل قارئین کو اسٹرکچرڈ کوئری لینگویج (SQL) کے ساتھ آن چین ڈیٹا کو کوئری کر کے ٹرانزیکشن، بلاکس اور گیس سمیت Ethereum کے بنیادی تصورات کو سمجھنے میں مدد کرتا ہے۔" +author: "Paul Apivat" +tags: [ "SQL", "کوئری کرنا", "ٹرانزیکشنز" ] +skill: beginner +lang: ur-in +published: 2021-05-11 +source: paulapivat.com +sourceUrl: https://paulapivat.com/post/query_ethereum/ +--- + +بہت سے Ethereum ٹیوٹوریل ڈیولپرز کو ہدف بناتے ہیں، لیکن ڈیٹا تجزیہ کاروں یا ان لوگوں کے لیے تعلیمی وسائل کی کمی ہے جو کلائنٹ یا نوڈ چلائے بغیر آن چین ڈیٹا دیکھنا چاہتے ہیں۔ + +یہ ٹیوٹوریل قارئین کو [Dune Analytics](https://dune.com/) کے فراہم کردہ انٹرفیس کے ذریعے اسٹرکچرڈ کوئری لینگویج (SQL) کے ساتھ آن چین ڈیٹا کو کوئری کرکے ٹرانزیکشن، بلاکس اور گیس سمیت Ethereum کے بنیادی تصورات کو سمجھنے میں مدد کرتا ہے۔ + +آن چین ڈیٹا ہمیں Ethereum، نیٹ ورک، اور کمپیوٹنگ پاور کے لیے ایک معیشت کو سمجھنے میں مدد کر سکتا ہے اور اسے آج Ethereum کو درپیش چیلنجوں (یعنی گیس کی بڑھتی ہوئی قیمتوں) اور اس سے بھی اہم بات یہ ہے کہ اسکیلنگ کے حل کے بارے میں بات چیت کو سمجھنے کی بنیاد کے طور پر کام کرنا چاہیے۔ + +### ٹرانزیکشنز {#transactions} + +Ethereum پر صارف کا سفر صارف کے زیر کنٹرول اکاؤنٹ یا ETH بیلنس والی کسی ہستی کو شروع کرنے سے شروع ہوتا ہے۔ اکاؤنٹ کی دو قسمیں ہیں - صارف کے زیر کنٹرول یا ایک اسمارٹ کنٹریکٹ (دیکھیں [ethereum.org](/developers/docs/accounts/))۔ + +کسی بھی اکاؤنٹ کو [Etherscan](https://etherscan.io/) یا [Blockscout](https://eth.blockscout.com/) جیسے بلاک ایکسپلورر پر دیکھا جا سکتا ہے۔ بلاک ایکسپلورر Ethereum کے ڈیٹا کا ایک پورٹل ہیں۔ وہ حقیقی وقت میں، بلاکس، ٹرانزیکشنز، مائنرز، اکاؤنٹس اور دیگر آن چین سرگرمیوں پر ڈیٹا دکھاتے ہیں (یہاں دیکھیں [here](/developers/docs/data-and-analytics/block-explorers/))۔ + +تاہم، ایک صارف بیرونی بلاک ایکسپلوررز کے ذریعہ فراہم کردہ معلومات کو ہم آہنگ کرنے کے لیے براہ راست ڈیٹا کو کوئری کرنا چاہے گا۔ [Dune Analytics](https://dune.com/) SQL کے کچھ علم رکھنے والے کسی بھی شخص کو یہ صلاحیت فراہم کرتا ہے۔ + +حوالہ کے لیے، Ethereum فاؤنڈیشن (EF) کے لیے اسمارٹ کنٹریکٹ اکاؤنٹ کو [Blockscout](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) پر دیکھا جا سکتا ہے۔ + +ایک بات قابل غور ہے کہ تمام اکاؤنٹس، بشمول EF کے، کا ایک عوامی پتہ ہوتا ہے جسے ٹرانزیکشن بھیجنے اور وصول کرنے کے لیے استعمال کیا جا سکتا ہے۔ + +Etherscan پر اکاؤنٹ کا بیلنس باقاعدہ ٹرانزیکشنز اور اندرونی ٹرانزیکشنز پر مشتمل ہوتا ہے۔ اندرونی ٹرانزیکشنز، نام کے باوجود، _اصل_ ٹرانزیکشنز نہیں ہیں جو چین کی حالت کو بدلتی ہیں۔ وہ ایک معاہدے کو انجام دینے کے ذریعے شروع کی گئی قدر کی منتقلی ہیں ([source](https://ethereum.stackexchange.com/questions/3417/how-to-get-contract-internal-transactions))۔ چونکہ اندرونی ٹرانزیکشنز پر کوئی دستخط نہیں ہوتے ہیں، اس لیے وہ بلاک چین میں شامل **نہیں** ہوتے ہیں اور انہیں Dune Analytics سے کوئری نہیں کیا جا سکتا۔ + +لہذا، یہ ٹیوٹوریل باقاعدہ ٹرانزیکشنز پر توجہ مرکوز کرے گا۔ اسے اس طرح کوئری کیا جا سکتا ہے: + +```sql +WITH temp_table AS ( +SELECT + hash, + block_number, + block_time, + "from", + "to", + value / 1e18 AS ether, + gas_used, + gas_price / 1e9 AS gas_price_gwei +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +) +SELECT + hash, + block_number, + block_time, + "from", + "to", + ether, + (gas_used * gas_price_gwei) / 1e9 AS txn_fee +FROM temp_table +``` + +اس سے وہی معلومات حاصل ہوں گی جو Etherscan کے ٹرانزیکشن پیج پر فراہم کی گئی ہیں۔ موازنہ کے لیے، یہاں دو ذرائع ہیں: + +#### Etherscan {#etherscan} + +![](./etherscan_view.png) + +[Blockscout پر EF کا کنٹریکٹ پیج۔](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) + +#### ڈیون اینالیٹکس {#dune-analytics} + +![](./dune_view.png) + +آپ ڈیش بورڈ [یہاں](https://dune.com/paulapivat/Learn-Ethereum) تلاش کر سکتے ہیں۔ کوئری دیکھنے کے لیے ٹیبل پر کلک کریں (اوپر بھی دیکھیں)۔ + +### ٹرانزیکشنز کو توڑنا {#breaking_down_transactions} + +جمع کرائی گئی ٹرانزیکشن میں کئی معلومات شامل ہوتی ہیں ([source](/developers/docs/transactions/)): + +- **وصول کنندہ**: وصول کرنے والا پتہ ("to" کے طور پر کوئری کیا گیا) +- **دستخط**: جبکہ بھیجنے والے کی نجی کلیدیں کسی ٹرانزیکشن پر دستخط کرتی ہیں، جو ہم SQL کے ساتھ کوئری کر سکتے ہیں وہ بھیجنے والے کا عوامی پتہ ہے ("from")۔ +- **قدر**: یہ منتقل شدہ ETH کی رقم ہے (`ether` کالم دیکھیں)۔ +- **ڈیٹا**: یہ صوابدیدی ڈیٹا ہے جسے ہیش کیا گیا ہے (`data` کالم دیکھیں) +- **gasLimit** – گیس یونٹس کی زیادہ سے زیادہ مقدار جو ٹرانزیکشن کے ذریعے استعمال کی جا سکتی ہے۔ گیس کی اکائیاں کمپیوٹیشنل مراحل کی نمائندگی کرتی ہیں +- **maxPriorityFeePerGas** - گیس کی زیادہ سے زیادہ مقدار جو مائنر کو ٹپ کے طور پر شامل کی جائے گی +- **maxFeePerGas** - ٹرانزیکشن کے لیے ادا کی جانے والی گیس کی زیادہ سے زیادہ مقدار (بشمول baseFeePerGas اور maxPriorityFeePerGas) + +ہم Ethereum فاؤنڈیشن کے عوامی پتے پر ٹرانزیکشنز کے لیے معلومات کے ان مخصوص ٹکڑوں کو کوئری کر سکتے ہیں: + +```sql +SELECT + "to", + "from", + value / 1e18 AS ether, + data, + gas_limit, + gas_price / 1e9 AS gas_price_gwei, + gas_used, + ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +``` + +### بلاکس {#blocks} + +ہر ٹرانزیکشن Ethereum ورچوئل مشین ([EVM](/developers/docs/evm/)) کی حالت کو بدل دے گی ([source](/developers/docs/transactions/))۔ ٹرانزیکشنز کو تصدیق اور بلاک میں شامل کرنے کے لیے نیٹ ورک پر نشر کیا جاتا ہے۔ ہر ٹرانزیکشن ایک بلاک نمبر سے منسلک ہے۔ ڈیٹا دیکھنے کے لیے، ہم ایک مخصوص بلاک نمبر کو کوئری کر سکتے ہیں: 12396854 (اس تحریر کے مطابق Ethereum فاؤنڈیشن ٹرانزیکشنز میں سب سے حالیہ بلاک، 11/5/21)۔ + +مزید برآں، جب ہم اگلے دو بلاکس کو کوئری کرتے ہیں، تو ہم دیکھ سکتے ہیں کہ ہر بلاک میں پچھلے بلاک کا ہیش (یعنی پیرنٹ ہیش) ہوتا ہے، جو یہ ظاہر کرتا ہے کہ بلاک چین کیسے بنتا ہے۔ + +ہر بلاک میں اس کے پیرنٹ بلاک کا حوالہ ہوتا ہے۔ یہ نیچے `hash` اور `parent_hash` کالموں کے درمیان دکھایا گیا ہے ([source](/developers/docs/blocks/)): + +![parent_hash](./parent_hash.png) + +Dune Analytics پر [query](https://dune.com/queries/44856/88292) یہ ہے: + +```sql +SELECT + time, + number, + hash, + parent_hash, + nonce +FROM ethereum."blocks" +WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856 +LIMIT 10 +``` + +ہم وقت، بلاک نمبر، مشکل، ہیش، پیرنٹ ہیش، اور نونس کو کوئری کرکے ایک بلاک کا جائزہ لے سکتے ہیں۔ + +صرف ایک چیز جس کا یہ کوئری احاطہ نہیں کرتی ہے وہ ہے _ٹرانزیکشن کی فہرست_ جس کے لیے نیچے ایک الگ کوئری اور _اسٹیٹ روٹ_ درکار ہے۔ ایک مکمل یا آرکائیول نوڈ تمام ٹرانزیکشنز اور اسٹیٹ ٹرانزیشن کو اسٹور کرے گا، جس سے کلائنٹس کو کسی بھی وقت چین کی حالت کو کوئری کرنے کی اجازت ملے گی۔ چونکہ اس کے لیے بڑی اسٹوریج کی جگہ درکار ہے، ہم چین ڈیٹا کو اسٹیٹ ڈیٹا سے الگ کر سکتے ہیں: + +- چین ڈیٹا (بلاکس، ٹرانزیکشنز کی فہرست) +- اسٹیٹ ڈیٹا (ہر ٹرانزیکشن کے اسٹیٹ ٹرانزیشن کا نتیجہ) + +اسٹیٹ روٹ بعد میں آتا ہے اور یہ _مضمر_ ڈیٹا ہے (آن چین ذخیرہ نہیں کیا گیا)، جبکہ چین ڈیٹا واضح ہے اور خود چین پر ذخیرہ کیا گیا ہے ([source](https://ethereum.stackexchange.com/questions/359/where-is-the-state-data-stored))۔ + +اس ٹیوٹوریل کے لیے، ہم آن چین ڈیٹا پر توجہ مرکوز کریں گے جسے Dune Analytics کے ذریعے SQL کے ساتھ _کوئری_ کیا جا سکتا ہے۔ + +جیسا کہ اوپر بیان کیا گیا ہے، ہر بلاک میں ٹرانزیکشنز کی ایک فہرست ہوتی ہے، ہم اسے ایک مخصوص بلاک کے لیے فلٹر کرکے کوئری کر سکتے ہیں۔ ہم سب سے حالیہ بلاک، 12396854 کو آزمائیں گے: + +```sql +SELECT * FROM ethereum."transactions" +WHERE block_number = 12396854 +ORDER BY block_time DESC` +``` + +Dune پر SQL آؤٹ پٹ یہ ہے: + +![](./list_of_txn.png) + +چین میں شامل کیا جانے والا یہ واحد بلاک Ethereum ورچوئل مشین ([EVM](/developers/docs/evm/)) کی حالت کو بدل دیتا ہے۔ درجنوں، کبھی کبھی سینکڑوں ٹرانزیکشنز ایک ساتھ تصدیق کی جاتی ہیں۔ اس مخصوص معاملے میں، 222 ٹرانزیکشنز شامل تھیں۔ + +یہ دیکھنے کے لیے کہ کتنے واقعی کامیاب ہوئے، ہم کامیاب ٹرانزیکشنز کو گننے کے لیے ایک اور فلٹر شامل کریں گے: + +```sql +WITH temp_table AS ( + SELECT * FROM ethereum."transactions" + WHERE block_number = 12396854 AND success = true + ORDER BY block_time DESC +) +SELECT + COUNT(success) AS num_successful_txn +FROM temp_table +``` + +بلاک 12396854 کے لیے، کل 222 ٹرانزیکشنز میں سے، 204 کی کامیابی سے تصدیق کی گئی: + +![](./successful_txn.png) + +ٹرانزیکشن کی درخواستیں فی سیکنڈ درجنوں بار ہوتی ہیں، لیکن بلاکس تقریباً ہر 15 سیکنڈ میں ایک بار کمٹ کیے جاتے ہیں ([source](/developers/docs/blocks/))۔ + +یہ دیکھنے کے لیے کہ تقریباً ہر 15 سیکنڈ میں ایک بلاک تیار ہوتا ہے، ہم ایک دن میں سیکنڈز کی تعداد (86400) کو 15 سے تقسیم کر کے روزانہ بلاکس کی تخمینی اوسط تعداد (~ 5760) حاصل کر سکتے ہیں۔ + +روزانہ تیار ہونے والے Ethereum بلاکس (2016 - حال) کا چارٹ یہ ہے: + +![](./daily_blocks.png) + +اس مدت میں روزانہ تیار ہونے والے بلاکس کی اوسط تعداد ~5,874 ہے: + +![](./avg_daily_blocks.png) + +کوئریز یہ ہیں: + +```sql +# 2016 سے روزانہ تیار ہونے والے بلاکس کی تعداد کا تصور کرنے کے لیے کوئری + +SELECT + DATE_TRUNC('day', time) AS dt, + COUNT(*) AS block_count +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 + +# روزانہ تیار ہونے والے بلاکس کی اوسط تعداد + +WITH temp_table AS ( +SELECT + DATE_TRUNC('day', time) AS dt, + COUNT(*) AS block_count +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +) +SELECT + AVG(block_count) AS avg_block_count +FROM temp_table +``` + +2016 سے روزانہ تیار ہونے والے بلاکس کی اوسط تعداد 5,874 پر اس تعداد سے قدرے زیادہ ہے۔ متبادل طور پر، 86400 سیکنڈ کو 5874 اوسط بلاکس سے تقسیم کرنے پر 14.7 سیکنڈ یا تقریباً ہر 15 سیکنڈ میں ایک بلاک آتا ہے۔ + +### گیس {#gas} + +بلاکس سائز میں محدود ہیں۔ زیادہ سے زیادہ بلاک کا سائز متحرک ہے اور نیٹ ورک کی طلب کے مطابق 12,500,000 اور 25,000,000 یونٹس کے درمیان مختلف ہوتا ہے۔ ڈسک کی جگہ اور رفتار کی ضروریات کے لحاظ سے مکمل نوڈس پر دباؤ ڈالنے والے من مانے بڑے بلاک سائز کو روکنے کے لیے حدود کی ضرورت ہوتی ہے ([source](/developers/docs/blocks/))۔ + +بلاک گیس کی حد کا تصور کرنے کا ایک طریقہ یہ ہے کہ اسے دستیاب بلاک کی جگہ کی **سپلائی** کے طور پر سوچا جائے جس میں ٹرانزیکشنز کو بیچ کیا جائے۔ بلاک گیس کی حد کو 2016 سے آج تک کوئری اور تصور کیا جا سکتا ہے: + +![](./avg_gas_limit.png) + +```sql +SELECT + DATE_TRUNC('day', time) AS dt, + AVG(gas_limit) AS avg_block_gas_limit +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +``` + +پھر Ethereum چین پر کیے گئے کمپیوٹنگ کی ادائیگی کے لیے روزانہ استعمال ہونے والی اصل گیس ہے (یعنی ٹرانزیکشن بھیجنا، اسمارٹ کنٹریکٹ کو کال کرنا، NFT منٹ کرنا)۔ یہ دستیاب Ethereum بلاک کی جگہ کے لیے **ڈیمانڈ** ہے: + +![](./daily_gas_used.png) + +```sql +SELECT + DATE_TRUNC('day', time) AS dt, + AVG(gas_used) AS avg_block_gas_used +FROM ethereum."blocks" +GROUP BY dt +OFFSET 1 +``` + +ہم ان دونوں چارٹس کو ایک ساتھ جوڑ کر یہ بھی دیکھ سکتے ہیں کہ **ڈیمانڈ اور سپلائی** کس طرح صف بندی کرتے ہیں: + +![gas_demand_supply](./gas_demand_supply.png) + +لہذا ہم گیس کی قیمتوں کو Ethereum بلاک کی جگہ کی طلب کے ایک فنکشن کے طور پر سمجھ سکتے ہیں، دی گئی دستیاب سپلائی۔ + +آخر میں، ہم Ethereum چین کے لیے اوسط روزانہ گیس کی قیمتوں کو کوئری کرنا چاہیں گے، تاہم، ایسا کرنے سے خاص طور پر طویل کوئری وقت کا نتیجہ ہوگا، لہذا ہم اپنی کوئری کو Ethereum فاؤنڈیشن کی طرف سے فی ٹرانزیکشن ادا کی گئی گیس کی اوسط رقم تک فلٹر کریں گے۔ + +![](./ef_daily_gas.png) + +ہم سالوں کے دوران Ethereum فاؤنڈیشن کے پتے پر کی گئی تمام ٹرانزیکشنز کے لیے ادا کی گئی گیس کی قیمتیں دیکھ سکتے ہیں۔ کوئری یہ ہے: + +```sql +SELECT + block_time, + gas_price / 1e9 AS gas_price_gwei, + value / 1e18 AS eth_sent +FROM ethereum."transactions" +WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' +ORDER BY block_time DESC +``` + +### خلاصہ {#summary} + +اس ٹیوٹوریل کے ساتھ، ہم آن چین ڈیٹا کو کوئری کرکے اور اس کا احساس حاصل کرکے Ethereum کے بنیادی تصورات اور Ethereum بلاک چین کے کام کرنے کے طریقے کو سمجھتے ہیں۔ + +اس ٹیوٹوریل میں استعمال ہونے والا تمام کوڈ رکھنے والا ڈیش بورڈ [یہاں](https://dune.com/paulapivat/Learn-Ethereum) پایا جا سکتا ہے۔ + +web3 کو دریافت کرنے کے لیے ڈیٹا کے مزید استعمال کے لیے [مجھے ٹویٹر پر تلاش کریں](https://twitter.com/paulapivat)۔ diff --git a/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md b/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md new file mode 100644 index 00000000000..48b65b59bfc --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md @@ -0,0 +1,62 @@ +--- +title: "ایونٹس کے ساتھ سمارٹ معاہدوں سے ڈیٹا لاگ کرنا" +description: "اسمارٹ کنٹریکٹ ایونٹس کا تعارف اور آپ ڈیٹا لاگ کرنے کے لیے انہیں کیسے استعمال کر سکتے ہیں۔" +author: "jdourlens" +tags: [ "اسمارٹ معاہدات", "remix", "solidity", "ایونٹس" ] +skill: intermediate +lang: ur-in +published: 2020-04-03 +source: EthereumDev +sourceUrl: https://ethereumdev.io/logging-data-with-events/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +سولیڈٹی میں، [ایونٹس](/developers/docs/smart-contracts/anatomy/#events-and-logs) بھیجے گئے سگنل ہیں جنہیں سمارٹ معاہدے فائر کر سکتے ہیں۔ Dapps، یا ایتھیریم JSON-RPC API سے منسلک کوئی بھی چیز، ان ایونٹس کو سن سکتی ہے اور اسی کے مطابق کارروائی کر سکتی ہے۔ ایک ایونٹ کو انڈیکس بھی کیا جا سکتا ہے تاکہ بعد میں ایونٹ کی تاریخ کو تلاش کیا جا سکے۔ + +## ایونٹس {#events} + +اس مضمون کو لکھنے کے وقت ایتھیریم بلاک چین پر سب سے عام ایونٹ ٹرانسفر ایونٹ ہے جو ERC20 ٹوکنز کے ذریعے خارج ہوتا ہے جب کوئی ٹوکنز منتقل کرتا ہے۔ + +```solidity +event Transfer(address indexed from, address indexed to, uint256 value); +``` + +ایونٹ کے دستخط کا اعلان کنٹریکٹ کوڈ کے اندر کیا جاتا ہے اور اسے emit کلیدی لفظ کے ساتھ خارج کیا جا سکتا ہے۔ مثال کے طور پر، ٹرانسفر ایونٹ لاگ کرتا ہے کہ ٹرانسفر کس نے بھیجا (_from_)، کس کو بھیجا (_to_) اور کتنے ٹوکن منتقل کیے گئے (_value_)۔ + +اگر ہم اپنے کاؤنٹر سمارٹ معاہدے پر واپس جائیں اور ہر بار قدر میں تبدیلی کو لاگ کرنے کا فیصلہ کریں۔ چونکہ اس معاہدے کا مقصد تعینات کرنا نہیں ہے بلکہ اسے بڑھا کر ایک اور معاہدہ بنانے کی بنیاد کے طور پر کام کرنا ہے: اسے ایک تجریدی معاہدہ کہا جاتا ہے۔ ہماری کاؤنٹر مثال کے معاملے میں، یہ اس طرح نظر آئے گا: + +```solidity +pragma solidity 0.5.17; + +contract Counter { + + event ValueChanged(uint oldValue, uint256 newValue); + + // گنتی کی تعداد رکھنے کے لیے غیر دستخط شدہ int قسم کا نجی متغیر + uint256 private count = 0; + + // فنکشن جو ہمارے کاؤنٹر کو بڑھاتا ہے + function increment() public { + count += 1; + emit ValueChanged(count - 1, count); + } + + // گنتی کی قدر حاصل کرنے کے لیے گیٹر + function getCount() public view returns (uint256) { + return count; + } + +} +``` + +نوٹ کریں کہ: + +- **لائن 5** : ہم اپنے ایونٹ اور اس میں کیا شامل ہے، پرانی قدر اور نئی قدر کا اعلان کرتے ہیں۔ + +- **لائن 13** : جب ہم اپنے گنتی متغیر کو بڑھاتے ہیں، تو ہم ایونٹ خارج کرتے ہیں۔ + +اگر ہم اب معاہدہ تعینات کرتے ہیں اور انکریمنٹ فنکشن کو کال کرتے ہیں، تو ہم دیکھیں گے کہ اگر آپ لاگز نامی ایک صف کے اندر نئی ٹرانزیکشن پر کلک کرتے ہیں تو Remix اسے خود بخود ڈسپلے کر دے گا۔ + +![ری مکس اسکرین شاٹ](./remix-screenshot.png) + +لاگز آپ کے سمارٹ معاہدوں کو ڈی بگ کرنے کے لیے واقعی مفید ہیں لیکن اگر آپ مختلف لوگوں کے ذریعے استعمال کی جانے والی ایپلیکیشنز بناتے ہیں تو یہ بھی اہم ہیں اور آپ کے سمارٹ معاہدے کے استعمال کو ٹریک کرنے اور سمجھنے کے لیے تجزیات کرنا آسان بناتے ہیں۔ ٹرانزیکشنز کے ذریعے تیار کردہ لاگز مشہور بلاک ایکسپلوررز میں دکھائے جاتے ہیں اور آپ مثال کے طور پر مخصوص ایونٹس کو سننے اور ان کے ہونے پر کارروائی کرنے کے لیے آف چین اسکرپٹ بنانے کے لیے بھی ان کا استعمال کر سکتے ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md new file mode 100644 index 00000000000..eafa36df48b --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md @@ -0,0 +1,247 @@ +--- +title: "آف لائن ڈیٹا کی سالمیت کے لیے مرکل پروفس" +description: "ایسے ڈیٹا کے لیے آن چین ڈیٹا کی سالمیت کو یقینی بنانا جو زیادہ تر آف چین اسٹور کیا جاتا ہے" +author: Ori Pomerantz +tags: [ "اسٹوریج" ] +skill: advanced +lang: ur-in +published: 2021-12-30 +--- + +## تعارف {#introduction} + +مثالی طور پر ہم ہر چیز کو Ethereum اسٹوریج میں اسٹور کرنا چاہیں گے، جو ہزاروں کمپیوٹرز میں اسٹور ہوتا ہے اور اس میں +انتہائی زیادہ دستیابی (ڈیٹا کو سنسر نہیں کیا جا سکتا) اور سالمیت (ڈیٹا کو غیر مجاز طریقے سے تبدیل نہیں کیا جا سکتا) ہوتی ہے، لیکن 32-بائٹ ورڈ کو اسٹور کرنے پر عام طور پر 20,000 گیس خرچ ہوتی ہے۔ جب میں یہ لکھ رہا ہوں، تو یہ لاگت $6.60 کے برابر ہے۔ 21 سینٹ فی بائٹ پر یہ بہت سے استعمالات کے لیے بہت مہنگا ہے۔ + +اس مسئلے کو حل کرنے کے لیے Ethereum ایکو سسٹم نے [ڈیٹا کو وکندریقرت طریقے سے اسٹور کرنے کے بہت سے متبادل طریقے](/developers/docs/storage/) تیار کیے ہیں۔ عام طور پر ان میں دستیابی اور قیمت کے درمیان ایک سمجھوتہ شامل ہوتا ہے۔ تاہم، سالمیت کو عام طور پر یقینی بنایا جاتا ہے۔ + +اس مضمون میں آپ سیکھیں گے کہ [مرکل پروفس](https://computersciencewiki.org/index.php/Merkle_proof) کا استعمال کرتے ہوئے، بلاک چین پر ڈیٹا اسٹور کیے بغیر ڈیٹا کی سالمیت کو **کیسے** یقینی بنایا جائے۔ + +## یہ کیسے کام کرتا ہے؟ {#how-does-it-work} + +نظریاتی طور پر ہم صرف ڈیٹا کا ہیش آن چین اسٹور کر سکتے ہیں، اور تمام ڈیٹا کو ان ٹرانزیکشنز میں بھیج سکتے ہیں جن میں اس کی ضرورت ہوتی ہے۔ تاہم، یہ اب بھی بہت مہنگا ہے۔ ایک ٹرانزیکشن میں ایک بائٹ ڈیٹا کی لاگت تقریباً 16 گیس ہوتی ہے، جو فی الحال تقریباً آدھا سینٹ، یا تقریباً 5 ڈالر فی کلو بائٹ ہے۔ 5000 ڈالر فی میگا بائٹ پر، یہ بہت سے استعمالات کے لیے اب بھی بہت مہنگا ہے، یہاں تک کہ ڈیٹا کو ہیش کرنے کی اضافی لاگت کے بغیر بھی۔ + +اس کا حل یہ ہے کہ ڈیٹا کے مختلف سب سیٹس کو بار بار ہیش کیا جائے، تاکہ جس ڈیٹا کو آپ کو بھیجنے کی ضرورت نہیں ہے اس کے لیے آپ صرف ایک ہیش بھیج سکیں۔ آپ یہ ایک مرکل ٹری کا استعمال کرتے ہوئے کرتے ہیں، جو ایک ٹری ڈیٹا اسٹرکچر ہے جہاں ہر نوڈ اس کے نیچے موجود نوڈس کا ہیش ہوتا ہے: + +![مرکل ٹری](tree.png) + +روٹ ہیش واحد حصہ ہے جسے آن چین اسٹور کرنے کی ضرورت ہے۔ ایک خاص قدر کو ثابت کرنے کے لیے، آپ وہ تمام ہیش فراہم کرتے ہیں جنہیں روٹ حاصل کرنے کے لیے اس کے ساتھ ملانے کی ضرورت ہوتی ہے۔ مثال کے طور پر، `C` کو ثابت کرنے کے لیے آپ `D`، `H(A-B)`، اور `H(E-H)` فراہم کرتے ہیں۔ + +![C کی قدر کا ثبوت](proof-c.png) + +## عمل درآمد {#implementation} + +[نمونہ کوڈ یہاں فراہم کیا گیا ہے](https://github.com/qbzzt/merkle-proofs-for-offline-data-integrity)۔ + +### آف چین کوڈ {#offchain-code} + +اس مضمون میں ہم آف چین حسابات کے لیے JavaScript کا استعمال کرتے ہیں۔ زیادہ تر وکندریقرت ایپلی کیشنز کا آف چین جزو JavaScript میں ہوتا ہے۔ + +#### مرکل روٹ بنانا {#creating-the-merkle-root} + +سب سے پہلے ہمیں چین کو مرکل روٹ فراہم کرنے کی ضرورت ہے۔ + +```javascript +const ethers = require("ethers") +``` + +[ہم ethers پیکیج سے ہیش فنکشن کا استعمال کرتے ہیں](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256)۔ + +```javascript +// وہ خام ڈیٹا جس کی سالمیت کی ہمیں تصدیق کرنی ہے۔ پہلے دو بائٹس +// ایک صارف کی شناخت ہیں، اور آخری دو بائٹس اس صارف کے پاس موجود ٹوکنز کی +// مقدار ہیں۔ +const dataArray = [ + 0x0bad0010, 0x60a70020, 0xbeef0030, 0xdead0040, 0xca110050, 0x0e660060, + 0xface0070, 0xbad00080, 0x060d0091, +] +``` + +ہر اندراج کو ایک 256-بٹ انٹیجر میں انکوڈ کرنے سے، مثال کے طور پر JSON استعمال کرنے کے مقابلے میں، کم پڑھنے کے قابل کوڈ بنتا ہے۔ تاہم، اس کا مطلب ہے کہ کنٹریکٹ میں ڈیٹا کو بازیافت کرنے کے لیے کافی کم پروسیسنگ کی ضرورت ہوتی ہے، اس لیے گیس کی لاگت بہت کم ہوتی ہے۔ [آپ آن چین پر JSON پڑھ سکتے ہیں](https://github.com/chrisdotn/jsmnSol)، لیکن اگر اس سے بچا جا سکے تو یہ ایک برا خیال ہے۔ + +```javascript +// ہیش ویلیوز کا ایرے، بطور BigInts +const hashArray = dataArray +``` + +اس معاملے میں ہمارا ڈیٹا شروع میں 256-بٹ ویلیوز ہے، اس لیے کسی پروسیسنگ کی ضرورت نہیں ہے۔ اگر ہم زیادہ پیچیدہ ڈیٹا اسٹرکچر، جیسے کہ اسٹرنگز، استعمال کرتے ہیں، تو ہمیں یہ یقینی بنانا ہوگا کہ ہم ہیشز کا ایک ایرے حاصل کرنے کے لیے پہلے ڈیٹا کو ہیش کریں۔ نوٹ کریں کہ یہ اس لیے بھی ہے کہ ہمیں اس بات کی پرواہ نہیں ہے کہ آیا صارفین دوسرے صارفین کی معلومات جانتے ہیں۔ بصورت دیگر ہمیں ہیش کرنا پڑتا تاکہ صارف 1 کو صارف 0 کی قدر معلوم نہ ہو، صارف 2 کو صارف 3 کی قدر معلوم نہ ہو، وغیرہ۔ + +```javascript +// ہیش فنکشن جس اسٹرنگ کی توقع کرتا ہے اور جو BigInt +// ہم ہر جگہ استعمال کرتے ہیں، ان کے درمیان تبدیل کریں۔ +const hash = (x) => + BigInt(ethers.utils.keccak256("0x" + x.toString(16).padStart(64, 0))) +``` + +ethers ہیش فنکشن ایک ہیکساڈیسیمل نمبر کے ساتھ ایک JavaScript اسٹرنگ حاصل کرنے کی توقع رکھتا ہے، جیسے `0x60A7`، اور اسی ساخت کے ساتھ ایک اور اسٹرنگ کے ساتھ جواب دیتا ہے۔ تاہم، باقی کوڈ کے لیے `BigInt` کا استعمال کرنا آسان ہے، اس لیے ہم ایک ہیکساڈیسیمل اسٹرنگ میں تبدیل کرتے ہیں اور پھر واپس۔ + +```javascript +// ایک جوڑے کا سیمیٹریکل ہیش تاکہ ہمیں پرواہ نہ ہو کہ ترتیب الٹ دی گئی ہے۔ +const pairHash = (a, b) => hash(hash(a) ^ hash(b)) +``` + +یہ فنکشن سیمیٹریکل ہے (a [xor](https://en.wikipedia.org/wiki/Exclusive_or) b کا ہیش)۔ اس کا مطلب ہے کہ جب ہم مرکل پروف کی جانچ کرتے ہیں تو ہمیں اس بارے میں فکر کرنے کی ضرورت نہیں ہے کہ پروف سے حاصل کردہ قدر کو حسابی قدر سے پہلے رکھنا ہے یا بعد میں۔ مرکل پروف کی جانچ آن چین کی جاتی ہے، لہذا ہمیں وہاں جتنا کم کام کرنے کی ضرورت ہوگی، اتنا ہی بہتر ہے۔ + +انتباہ: +کرپٹوگرافی جتنی نظر آتی ہے اس سے زیادہ مشکل ہے۔ +اس مضمون کے ابتدائی ورژن میں ہیش فنکشن `hash(a^b)` تھا۔ +یہ ایک **برا** خیال تھا کیونکہ اس کا مطلب یہ تھا کہ اگر آپ کو `a` اور `b` کی جائز قدریں معلوم ہوتیں تو آپ کسی بھی مطلوبہ `a'` قدر کو ثابت کرنے کے لیے `b' = a^b^a'` کا استعمال کر سکتے تھے۔ +اس فنکشن کے ساتھ آپ کو `b'` کا حساب لگانا ہوگا تاکہ `hash(a') ^ hash(b')` ایک معلوم قدر (روٹ کے راستے پر اگلی شاخ) کے برابر ہو، جو کہ بہت زیادہ مشکل ہے۔ + +```javascript +// یہ قدر یہ ظاہر کرنے کے لیے کہ ایک خاص شاخ خالی ہے، اس میں +// کوئی قدر نہیں ہے +const empty = 0n +``` + +جب قدروں کی تعداد دو کی انٹیجر پاور نہیں ہوتی ہے تو ہمیں خالی شاخوں کو ہینڈل کرنے کی ضرورت ہوتی ہے۔ یہ پروگرام جس طرح سے یہ کرتا ہے وہ یہ ہے کہ صفر کو ایک پلیس ہولڈر کے طور پر رکھتا ہے۔ + +![غائب شاخوں کے ساتھ مرکل ٹری](merkle-empty-hash.png) + +```javascript +// ایک ہیش ایرے کے ٹری میں ایک لیول اوپر کا حساب لگائیں، ہر جوڑے کا +// ترتیب سے ہیش لے کر +const oneLevelUp = (inputArray) => { + var result = [] + var inp = [...inputArray] // ان پٹ پر اوور رائٹنگ سے بچنے کے لیے // اگر ضروری ہو تو ایک خالی قدر شامل کریں (ہمیں تمام لیوز کو // جوڑا بنانے کی ضرورت ہے) + + if (inp.length % 2 === 1) inp.push(empty) + + for (var i = 0; i < inp.length; i += 2) + result.push(pairHash(inp[i], inp[i + 1])) + + return result +} // oneLevelUp +``` + +یہ فنکشن موجودہ لیئر پر قدروں کے جوڑوں کو ہیش کرکے مرکل ٹری میں ایک لیول "اوپر چڑھتا" ہے۔ نوٹ کریں کہ یہ سب سے موثر عمل درآمد نہیں ہے، ہم ان پٹ کو کاپی کرنے سے بچ سکتے تھے اور لوپ میں مناسب ہونے پر صرف `hashEmpty` شامل کر سکتے تھے، لیکن یہ کوڈ پڑھنے کی اہلیت کے لیے بہتر بنایا گیا ہے۔ + +```javascript +const getMerkleRoot = (inputArray) => { + var result + + result = [...inputArray] // ٹری پر اس وقت تک چڑھیں جب تک کہ صرف ایک قدر نہ رہ جائے، جو کہ // روٹ ہے۔ // // اگر کسی لیئر میں اندراجات کی تعداد طاق ہے تو // oneLevelUp میں موجود کوڈ ایک خالی قدر شامل کرتا ہے، لہذا اگر ہمارے پاس، مثال کے طور پر، // 10 لیوز ہیں تو ہمارے پاس دوسری لیئر میں 5 شاخیں، تیسری میں 3 // شاخیں، چوتھی میں 2 ہوں گی اور روٹ پانچواں ہے + + while (result.length > 1) result = oneLevelUp(result) + + return result[0] +} +``` + +روٹ حاصل کرنے کے لیے، اس وقت تک چڑھیں جب تک کہ صرف ایک قدر باقی نہ رہ جائے۔ + +#### مرکل پروف بنانا {#creating-a-merkle-proof} + +مرکل پروف وہ قدریں ہیں جنہیں ثابت کی جانے والی قدر کے ساتھ ہیش کرکے مرکل روٹ واپس حاصل کیا جاتا ہے۔ ثابت کرنے کی قدر اکثر دوسرے ڈیٹا سے دستیاب ہوتی ہے، اس لیے میں اسے کوڈ کے حصے کے طور پر فراہم کرنے کے بجائے الگ سے فراہم کرنا پسند کرتا ہوں۔ + +```javascript +// مرکل پروف ان اندراجات کی فہرست کی قدر پر مشتمل ہوتا ہے جن کے ساتھ +// ہیش کرنا ہے۔ چونکہ ہم ایک سیمیٹریکل ہیش فنکشن استعمال کرتے ہیں، ہمیں +// پروف کی تصدیق کے لیے آئٹم کے مقام کی ضرورت نہیں ہے، صرف اسے بنانے کے لیے +const getMerkleProof = (inputArray, n) => { +    var result = [], currentLayer = [...inputArray], currentN = n + +    // جب تک ہم سب سے اوپر نہ پہنچ جائیں +    while (currentLayer.length > 1) { +        // کوئی طاق لمبائی کی لیئرز نہیں +        if (currentLayer.length % 2) +            currentLayer.push(empty) + +        result.push(currentN % 2 +               // اگر currentN طاق ہے، تو اس سے پہلے کی قدر کے ساتھ پروف میں شامل کریں +            ? currentLayer[currentN-1] +               // اگر یہ جفت ہے، تو اس کے بعد کی قدر شامل کریں +            : currentLayer[currentN+1]) + +``` + +ہم `(v[0],v[1])`، `(v[2],v[3])`، وغیرہ کو ہیش کرتے ہیں۔ لہذا جفت قدروں کے لیے ہمیں اگلی قدر کی ضرورت ہے، اور طاق قدروں کے لیے پچھلی قدر کی۔ + +```javascript +        // اگلی لیئر پر جائیں +        currentN = Math.floor(currentN/2) +        currentLayer = oneLevelUp(currentLayer) +    }   // جبکہ currentLayer.length > 1 + +    return result +}   // getMerkleProof +``` + +### آن چین کوڈ {#onchain-code} + +آخر میں ہمارے پاس وہ کوڈ ہے جو پروف کی جانچ کرتا ہے۔ آن چین کوڈ [Solidity](https://docs.soliditylang.org/en/v0.8.11/) میں لکھا گیا ہے۔ یہاں آپٹیمائزیشن بہت زیادہ اہم ہے کیونکہ گیس نسبتاً مہنگی ہے۔ + +```solidity +//SPDX-License-Identifier: Public Domain +pragma solidity ^0.8.0; + +import "hardhat/console.sol"; +``` + +میں نے یہ [Hardhat ڈیولپمنٹ انوائرمنٹ](https://hardhat.org/) کا استعمال کرتے ہوئے لکھا ہے، جو ہمیں ڈیولپمنٹ کے دوران [Solidity سے کنسول آؤٹ پٹ](https://hardhat.org/docs/cookbook/debug-logs) حاصل کرنے کی اجازت دیتا ہے۔ + +```solidity + +contract MerkleProof { +    uint merkleRoot; + +    function getRoot() public view returns (uint) { +      return merkleRoot; +    } + +    // انتہائی غیر محفوظ، پروڈکشن کوڈ میں اس فنکشن +    // تک رسائی کو سختی سے محدود کیا جانا چاہیے، شاید کسی +    // مالک تک +    function setRoot(uint _merkleRoot) external { +      merkleRoot = _merkleRoot; +    }   // setRoot +``` + +مرکل روٹ کے لیے سیٹ اور گیٹ فنکشنز۔ پروڈکشن سسٹم میں ہر کسی کو مرکل روٹ کو اپ ڈیٹ کرنے کی اجازت دینا ایک _انتہائی برا خیال_ ہے۔ میں یہاں نمونہ کوڈ کی سادگی کی خاطر ایسا کرتا ہوں۔ **اسے ایسے سسٹم پر نہ کریں جہاں ڈیٹا کی سالمیت واقعی اہمیت رکھتی ہو**۔ + +```solidity +    function hash(uint _a) internal pure returns(uint) { +      return uint(keccak256(abi.encode(_a))); +    } + +    function pairHash(uint _a, uint _b) internal pure returns(uint) { +      return hash(hash(_a) ^ hash(_b)); +    } +``` + +یہ فنکشن ایک جوڑے کا ہیش بناتا ہے۔ یہ `hash` اور `pairHash` کے لیے JavaScript کوڈ کا صرف Solidity ترجمہ ہے۔ + +**نوٹ:** یہ پڑھنے کی اہلیت کے لیے آپٹیمائزیشن کا ایک اور معاملہ ہے۔ [فنکشن کی تعریف](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm) کی بنیاد پر، ڈیٹا کو [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) قدر کے طور پر اسٹور کرنا اور تبادلوں سے بچنا ممکن ہو سکتا ہے۔ + +```solidity +    // مرکل پروف کی تصدیق کریں +    function verifyProof(uint _value, uint[] calldata _proof) +        public view returns (bool) { +      uint temp = _value; +      uint i; + +      for(i=0; i<_proof.length; i++) { +        temp = pairHash(temp, _proof[i]); +      } + +      return temp == merkleRoot; +    } + +}  // MarkleProof +``` + +ریاضیاتی اشارے میں مرکل پروف کی تصدیق اس طرح نظر آتی ہے: `H(proof_n, H(proof_n-1, H(proof_n-2, ...` H(proof_1, H(proof_0, value))...)))`۔ یہ کوڈ اسے نافذ کرتا ہے۔ + +## مرکل پروفس اور رول اپس آپس میں نہیں ملتے {#merkle-proofs-and-rollups} + +مرکل پروفس [رول اپس](/developers/docs/scaling/#rollups) کے ساتھ اچھی طرح کام نہیں کرتے ہیں۔ اس کی وجہ یہ ہے کہ رول اپس تمام ٹرانزیکشن ڈیٹا L1 پر لکھتے ہیں، لیکن L2 پر پروسیس کرتے ہیں۔ ایک ٹرانزیکشن کے ساتھ مرکل پروف بھیجنے کی لاگت اوسطاً 638 گیس فی لیئر ہے (فی الحال کال ڈیٹا میں ایک بائٹ کی لاگت 16 گیس ہے اگر یہ صفر نہیں ہے، اور 4 ہے اگر یہ صفر ہے)۔ اگر ہمارے پاس 1024 الفاظ کا ڈیٹا ہے، تو مرکل پروف کے لیے دس لیئرز، یا کل 6380 گیس کی ضرورت ہوتی ہے۔ + +مثال کے طور پر [Optimism](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m) کو دیکھیں، L1 گیس لکھنے پر تقریباً 100 gwei اور L2 گیس پر 0.001 gwei لاگت آتی ہے (یہ عام قیمت ہے، یہ بھیڑ کے ساتھ بڑھ سکتی ہے)۔ لہذا ایک L1 گیس کی لاگت پر ہم L2 پروسیسنگ پر ایک لاکھ گیس خرچ کر سکتے ہیں۔ یہ فرض کرتے ہوئے کہ ہم اسٹوریج کو اوور رائٹ نہیں کرتے ہیں، اس کا مطلب ہے کہ ہم ایک L1 گیس کی قیمت پر L2 پر اسٹوریج میں تقریباً پانچ الفاظ لکھ سکتے ہیں۔ ایک مرکل پروف کے لیے ہم پورے 1024 الفاظ اسٹوریج میں لکھ سکتے ہیں (یہ فرض کرتے ہوئے کہ انہیں شروع میں آن چین کیلکولیٹ کیا جا سکتا ہے، بجائے اس کے کہ ٹرانزیکشن میں فراہم کیا جائے) اور پھر بھی زیادہ تر گیس بچی رہے گی۔ + +## نتیجہ {#conclusion} + +حقیقی زندگی میں آپ شاید کبھی بھی خود سے مرکل ٹریز کو نافذ نہیں کریں گے۔ ایسی معروف اور آڈٹ شدہ لائبریریاں ہیں جنہیں آپ استعمال کر سکتے ہیں اور عام طور پر یہ بہتر ہے کہ آپ خود کرپٹوگرافک پرائمیٹیوز کو نافذ نہ کریں۔ لیکن مجھے امید ہے کہ اب آپ مرکل پروفس کو بہتر طور پر سمجھتے ہیں اور یہ فیصلہ کر سکتے ہیں کہ انہیں کب استعمال کرنا چاہیے۔ + +نوٹ کریں کہ جب مرکل پروفس _سالمیت_ کو محفوظ رکھتے ہیں، وہ _دستیابی_ کو محفوظ نہیں رکھتے ہیں۔ یہ جاننا کہ کوئی اور آپ کے اثاثے نہیں لے سکتا، یہ چھوٹی سی تسلی ہے اگر ڈیٹا اسٹوریج رسائی کو مسترد کرنے کا فیصلہ کرتا ہے اور آپ ان تک رسائی کے لیے مرکل ٹری بھی نہیں بنا سکتے ہیں۔ لہذا مرکل ٹریز کو کسی قسم کے وکندریقرت اسٹوریج، جیسے IPFS کے ساتھ بہترین طریقے سے استعمال کیا جاتا ہے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md b/public/content/translations/ur/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md new file mode 100644 index 00000000000..6f615f5395e --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/monitoring-geth-with-influxdb-and-grafana/index.md @@ -0,0 +1,151 @@ +--- +title: "InfluxDB اور Grafana کے ساتھ Geth کی نگرانی" +description: "کارکردگی کو ٹریک کرنے اور مسائل کی شناخت کرنے کے لیے InfluxDB اور Grafana کا استعمال کرتے ہوئے اپنے Geth نوڈ کے لیے نگرانی سیٹ اپ کریں۔" +author: "Mario Havel" +tags: [ "کلائنٹس", "نوڈز" ] +skill: intermediate +lang: ur-in +published: 2021-01-13 +--- + +یہ ٹیوٹوریل آپ کو اپنے Geth نوڈ کے لیے نگرانی سیٹ اپ کرنے میں مدد کرے گا تاکہ آپ اس کی کارکردگی کو بہتر طور پر سمجھ سکیں اور ممکنہ مسائل کی شناخت کر سکیں۔ + +## شرائط {#prerequisites} + +- آپ کو پہلے سے ہی Geth کا ایک انسٹنس چلا رہے ہونا چاہئے۔ +- زیادہ تر اقدامات اور مثالیں linux ماحول کے لیے ہیں، بنیادی ٹرمینل کا علم مددگار ثابت ہوگا۔ +- Geth کے میٹرکس کے سوٹ کا یہ ویڈیو جائزہ دیکھیں: [Péter Szilágyi کے ذریعہ ایک Ethereum انفراسٹرکچر کی نگرانی](https://www.youtube.com/watch?v=cOBab8IJMYI)۔ + +## نگرانی کا اسٹیک {#monitoring-stack} + +ایک Ethereum کلائنٹ بہت سارا ڈیٹا اکٹھا کرتا ہے جسے ایک کرونولوجیکل ڈیٹا بیس کی شکل میں پڑھا جا سکتا ہے۔ نگرانی کو آسان بنانے کے لیے، آپ اسے ڈیٹا ویژولائزیشن سافٹ ویئر میں فیڈ کر سکتے ہیں۔ متعدد اختیارات دستیاب ہیں: + +- [Prometheus](https://prometheus.io/) (pull model) +- [InfluxDB](https://www.influxdata.com/get-influxdb/) (push model) +- [Telegraf](https://www.influxdata.com/get-influxdb/) +- [Grafana](https://www.grafana.com/) +- [Datadog](https://www.datadoghq.com/) +- [Chronograf](https://www.influxdata.com/time-series-platform/chronograf/) + +[Geth Prometheus Exporter](https://github.com/hunterlong/gethexporter) بھی ہے، جو InfluxDB اور Grafana کے ساتھ پہلے سے کنفیگر کیا گیا ایک آپشن ہے۔ + +اس ٹیوٹوریل میں، ہم آپ کے Geth کلائنٹ کو ایک ڈیٹا بیس بنانے کے لیے InfluxDB میں ڈیٹا پش کرنے کے لیے، اور ڈیٹا کا گراف ویژولائزیشن بنانے کے لیے Grafana کے لیے سیٹ اپ کریں گے۔ اسے دستی طور پر کرنے سے آپ کو اس عمل کو بہتر طور پر سمجھنے، اس میں تبدیلی کرنے، اور مختلف ماحول میں اسے ڈیپلائے کرنے میں مدد ملے گی۔ + +## InfluxDB سیٹ اپ کرنا {#setting-up-influxdb} + +سب سے پہلے، آئیے InfluxDB کو ڈاؤن لوڈ اور انسٹال کریں۔ ڈاؤن لوڈ کے مختلف اختیارات [Influxdata ریلیز پیج](https://portal.influxdata.com/downloads/) پر مل سکتے ہیں۔ اپنے ماحول کے مطابق ایک کا انتخاب کریں۔ +آپ اسے ایک [ریپوزٹری](https://repos.influxdata.com/) سے بھی انسٹال کر سکتے ہیں۔ مثال کے طور پر Debian پر مبنی ڈسٹری بیوشن میں: + +``` +curl -tlsv1.3 --proto =https -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add +source /etc/lsb-release +echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list +sudo apt update +sudo apt install influxdb -y +sudo systemctl enable influxdb +sudo systemctl start influxdb +sudo apt install influxdb-client +``` + +InfluxDB کو کامیابی سے انسٹال کرنے کے بعد، یقینی بنائیں کہ یہ بیک گراؤنڈ میں چل رہا ہے۔ ڈیفالٹ کے طور پر، یہ `localhost:8086` پر قابل رسائی ہے۔ +`influx` کلائنٹ استعمال کرنے سے پہلے، آپ کو ایڈمن مراعات کے ساتھ ایک نیا صارف بنانا ہوگا۔ یہ صارف اعلیٰ سطح کے انتظام، ڈیٹا بیس اور صارفین بنانے کے لیے کام کرے گا۔ + +``` +curl -XPOST "http://localhost:8086/query" --data-urlencode "q=CREATE USER username WITH PASSWORD 'password' WITH ALL PRIVILEGES" +``` + +اب آپ اس صارف کے ساتھ [InfluxDB شیل](https://docs.influxdata.com/influxdb/v1.8/tools/shell/) میں داخل ہونے کے لیے influx کلائنٹ کا استعمال کر سکتے ہیں۔ + +``` +influx -username 'username' -password 'password' +``` + +اس کے شیل میں InfluxDB کے ساتھ براہ راست بات چیت کرتے ہوئے، آپ geth میٹرکس کے لیے ڈیٹا بیس اور صارف بنا سکتے ہیں۔ + +``` +create database geth +create user geth with password choosepassword +``` + +تخلیق شدہ اندراجات کی تصدیق کریں: + +``` +show databases +show users +``` + +InfluxDB شیل چھوڑ دیں۔ + +``` +exit +``` + +InfluxDB چل رہا ہے اور Geth سے میٹرکس کو اسٹور کرنے کے لیے کنفیگر کیا گیا ہے۔ + +## Geth کی تیاری {#preparing-geth} + +ڈیٹا بیس سیٹ اپ کرنے کے بعد، ہمیں Geth میں میٹرکس کلیکشن کو فعال کرنے کی ضرورت ہے۔ `geth --help` میں `METRICS AND STATS OPTIONS` پر دھیان دیں۔ وہاں متعدد اختیارات مل سکتے ہیں، اس معاملے میں ہم چاہتے ہیں کہ Geth، InfluxDB میں ڈیٹا پش کرے۔ +بنیادی سیٹ اپ اس اینڈ پوائنٹ کی وضاحت کرتا ہے جہاں InfluxDB قابل رسائی ہے اور ڈیٹا بیس کے لیے توثیق۔ + +``` +geth --metrics --metrics.influxdb --metrics.influxdb.endpoint "http://0.0.0.0:8086" --metrics.influxdb.username "geth" --metrics.influxdb.password "chosenpassword" +``` + +یہ فلیگس کلائنٹ کو شروع کرنے والے کمانڈ میں شامل کیے جا سکتے ہیں یا کنفیگریشن فائل میں محفوظ کیے جا سکتے ہیں۔ + +آپ تصدیق کر سکتے ہیں کہ Geth کامیابی سے ڈیٹا پش کر رہا ہے، مثال کے طور پر ڈیٹا بیس میں میٹرکس کی فہرست بنا کر۔ InfluxDB شیل میں: + +``` +use geth +show measurements +``` + +## Grafana سیٹ اپ کرنا {#setting-up-grafana} + +اگلا مرحلہ Grafana کو انسٹال کرنا ہے جو ڈیٹا کو گرافیکل طور پر بیان کرے گا۔ Grafana دستاویزات میں اپنے ماحول کے لیے انسٹالیشن کے عمل پر عمل کریں۔ اگر آپ دوسری صورت میں نہیں چاہتے ہیں تو OSS ورژن انسٹال کرنا یقینی بنائیں۔ +ریپوزٹری کا استعمال کرتے ہوئے Debian ڈسٹری بیوشنز کے لیے انسٹالیشن کے مثال کے اقدامات: + +``` +curl -tlsv1.3 --proto =https -sL https://packages.grafana.com/gpg.key | sudo apt-key add - +echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list +sudo apt update +sudo apt install grafana +sudo systemctl enable grafana-server +sudo systemctl start grafana-server +``` + +جب آپ Grafana چلا رہے ہوں، تو اسے `localhost:3000` پر قابل رسائی ہونا چاہئے۔ +اس پاتھ تک رسائی کے لیے اپنا پسندیدہ براؤزر استعمال کریں، پھر ڈیفالٹ اسناد (صارف: `admin` اور پاس ورڈ: `admin`) کے ساتھ لاگ ان کریں۔ جب کہا جائے تو ڈیفالٹ پاس ورڈ تبدیل کریں اور محفوظ کریں۔ + +![](./grafana1.png) + +آپ کو Grafana کے ہوم پیج پر ری ڈائریکٹ کر دیا جائے گا۔ سب سے پہلے، اپنا سورس ڈیٹا سیٹ اپ کریں۔ بائیں بار میں کنفیگریشن آئیکن پر کلک کریں اور "Data sources" منتخب کریں۔ + +![](./grafana2.png) + +ابھی تک کوئی ڈیٹا سورس نہیں بنایا گیا ہے، ایک کی وضاحت کرنے کے لیے "Add data source" پر کلک کریں۔ + +![](./grafana3.png) + +اس سیٹ اپ کے لیے، "InfluxDB" منتخب کریں اور آگے بڑھیں۔ + +![](./grafana4.png) + +اگر آپ ایک ہی مشین پر ٹولز چلا رہے ہیں تو ڈیٹا سورس کنفیگریشن کافی سیدھا ہے۔ آپ کو ڈیٹا بیس تک رسائی کے لیے InfluxDB ایڈریس اور تفصیلات سیٹ کرنے کی ضرورت ہے۔ نیچے دی گئی تصویر دیکھیں۔ + +![](./grafana5.png) + +اگر سب کچھ مکمل ہے اور InfluxDB قابل رسائی ہے، تو "Save and test" پر کلک کریں اور تصدیق کے پاپ اپ ہونے کا انتظار کریں۔ + +![](./grafana6.png) + +Grafana اب InfluxDB سے ڈیٹا پڑھنے کے لیے سیٹ اپ ہے۔ اب آپ کو ایک ڈیش بورڈ بنانے کی ضرورت ہے جو اس کی تشریح اور اسے ظاہر کرے گا۔ ڈیش بورڈز کی خصوصیات JSON فائلوں میں انکوڈ کی جاتی ہیں جنہیں کوئی بھی بنا سکتا ہے اور آسانی سے امپورٹ کیا جا سکتا ہے۔ بائیں بار پر، "Create and Import" پر کلک کریں۔ + +![](./grafana7.png) + +Geth مانیٹرنگ ڈیش بورڈ کے لیے، [اس ڈیش بورڈ](https://grafana.com/grafana/dashboards/13877/) کی ID کاپی کریں اور اسے Grafana میں "Import page" میں پیسٹ کریں۔ ڈیش بورڈ کو محفوظ کرنے کے بعد، یہ اس طرح نظر آنا چاہئے: + +![](./grafana8.png) + +آپ اپنے ڈیش بورڈز میں ترمیم کر سکتے ہیں۔ ہر پینل کو ایڈٹ کیا، منتقل کیا، ہٹایا یا شامل کیا جا سکتا ہے۔ آپ اپنی کنفیگریشنز کو تبدیل کر سکتے ہیں۔ یہ آپ پر منحصر ہے! ڈیش بورڈز کیسے کام کرتے ہیں اس کے بارے میں مزید جاننے کے لیے، [Grafana کی دستاویزات](https://grafana.com/docs/grafana/latest/dashboards/) سے رجوع کریں۔ +آپ کو [Alerting](https://grafana.com/docs/grafana/latest/alerting/) میں بھی دلچسپی ہو سکتی ہے۔ یہ آپ کو اس وقت کے لیے الرٹ نوٹیفکیشنز سیٹ اپ کرنے دیتا ہے جب میٹرکس کچھ خاص ویلیوز تک پہنچ جاتے ہیں۔ مختلف کمیونیکیشن چینلز معاون ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/nft-minter/index.md b/public/content/translations/ur/developers/tutorials/nft-minter/index.md new file mode 100644 index 00000000000..0e6c46f3fc8 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/nft-minter/index.md @@ -0,0 +1,874 @@ +--- +title: "NFT منٹر ٹیوٹوریل" +description: "اس ٹیوٹوریل میں، آپ ایک NFT منٹر بنائیں گے اور MetaMask اور Web3 ٹولز کا استعمال کرتے ہوئے اپنے اسمارٹ کنٹریکٹ کو React فرنٹ اینڈ سے جوڑ کر ایک فل اسٹیک dApp بنانا سیکھیں گے۔" +author: "smudgil" +tags: + [ + "solidity", + "NFT", + "alchemy", + "اسمارٹ معاہدات", + "فرنٹ اینڈ", + "Pinata" + ] +skill: intermediate +lang: ur-in +published: 2021-10-06 +--- + +Web2 پس منظر سے آنے والے ڈیولپرز کے لیے سب سے بڑے چیلنجوں میں سے ایک یہ ہے کہ وہ اپنے اسمارٹ کنٹریکٹ کو فرنٹ اینڈ پروجیکٹ سے کیسے جوڑیں اور اس کے ساتھ تعامل کریں۔ + +ایک NFT منٹر بنا کر — ایک سادہ UI جہاں آپ اپنے ڈیجیٹل اثاثے کا لنک، ایک عنوان، اور ایک تفصیل درج کر سکتے ہیں — آپ سیکھیں گے کہ کیسے: + +- اپنے فرنٹ اینڈ پروجیکٹ کے ذریعے MetaMask سے جڑیں +- اپنے فرنٹ اینڈ سے اسمارٹ کنٹریکٹ طریقوں کو کال کریں +- MetaMask کا استعمال کرتے ہوئے ٹرانزیکشنز پر دستخط کریں + +اس ٹیوٹوریل میں، ہم اپنے فرنٹ اینڈ فریم ورک کے طور پر [React](https://react.dev/) کا استعمال کریں گے۔ چونکہ یہ ٹیوٹوریل بنیادی طور پر Web3 ڈیولپمنٹ پر مرکوز ہے، ہم React کے بنیادی اصولوں کو سمجھنے میں زیادہ وقت نہیں گزاریں گے۔ اس کے بجائے، ہم اپنے پروجیکٹ میں فعالیت (functionality) لانے پر توجہ مرکوز کریں گے۔ + +ایک شرط کے طور پر، آپ کو React کی ابتدائی سطح کی سمجھ ہونی چاہیے— یہ جاننا کہ کمپونینٹس، پروپس، useState/useEffect، اور بنیادی فنکشن کالنگ کیسے کام کرتی ہے۔ اگر آپ نے پہلے ان میں سے کسی بھی اصطلاح کے بارے میں نہیں سنا ہے، تو آپ یہ [Intro to React tutorial](https://react.dev/learn/tutorial-tic-tac-toe) دیکھنا چاہیں گے۔ بصری طور پر سیکھنے والوں کے لیے، ہم Net Ninja کی طرف سے اس بہترین [Full Modern React Tutorial](https://www.youtube.com/playlist?list=PL4cUxeGkcC9gZD-Tvwfod2gaISzfRiP9d) ویڈیو سیریز کی پرزور سفارش کرتے ہیں۔ + +اور اگر آپ نے پہلے سے ایسا نہیں کیا ہے، تو آپ کو اس ٹیوٹوریل کو مکمل کرنے کے ساتھ ساتھ بلاک چین پر کچھ بھی بنانے کے لیے یقینی طور پر ایک Alchemy اکاؤنٹ کی ضرورت ہوگی۔ [یہاں](https://alchemy.com/) ایک مفت اکاؤنٹ کے لیے سائن اپ کریں۔ + +مزید تاخیر کے بغیر، آئیے شروع کریں! + +## NFTs بنانا 101 {#making-nfts-101} + +کسی بھی کوڈ کو دیکھنے سے پہلے، یہ سمجھنا ضروری ہے کہ NFT بنانا کیسے کام کرتا ہے۔ اس میں دو مراحل شامل ہیں: + +### Ethereum بلاک چین پر ایک NFT اسمارٹ کنٹریکٹ شائع کریں {#publish-nft} + +دو NFT اسمارٹ کنٹریکٹ معیارات کے درمیان سب سے بڑا فرق یہ ہے کہ ERC-1155 ایک ملٹی ٹوکن معیار ہے اور اس میں بیچ کی فعالیت شامل ہے، جبکہ ERC-721 ایک سنگل ٹوکن معیار ہے اور اس لیے ایک وقت میں صرف ایک ٹوکن کی منتقلی کی حمایت کرتا ہے۔ + +### منٹنگ فنکشن کو کال کریں {#minting-function} + +عام طور پر، اس منٹنگ فنکشن کے لیے آپ کو پیرامیٹرز کے طور پر دو متغیرات (variables) پاس کرنے کی ضرورت ہوتی ہے، پہلا `recipient`، جو اس پتے کی وضاحت کرتا ہے جو آپ کا تازہ منٹ کیا ہوا NFT وصول کرے گا، اور دوسرا NFT کا `tokenURI`، ایک اسٹرنگ جو NFT کے میٹا ڈیٹا کو بیان کرنے والے JSON دستاویز میں حل ہوتا ہے۔ + +ایک NFT کا میٹا ڈیٹا ہی دراصل اسے زندگی بخشتا ہے، جو اسے نام، تفصیل، تصویر (یا مختلف ڈیجیٹل اثاثہ)، اور دیگر صفات جیسی خصوصیات رکھنے کی اجازت دیتا ہے۔ یہاں [tokenURI کی ایک مثال](https://gateway.pinata.cloud/ipfs/QmSvBcb4tjdFpajGJhbFAWeK3JAxCdNQLQtr6ZdiSi42V2) ہے، جس میں ایک NFT کا میٹا ڈیٹا ہوتا ہے۔ + +اس ٹیوٹوریل میں، ہم حصہ 2 پر توجہ مرکوز کرنے جا رہے ہیں، یعنی ہمارے React UI کا استعمال کرتے ہوئے ایک موجودہ NFT کے اسمارٹ کنٹریکٹ منٹنگ فنکشن کو کال کرنا۔ + +اس ٹیوٹوریل میں ہم جس ERC-721 NFT اسمارٹ کنٹریکٹ کو کال کریں گے اس کا [لنک یہاں ہے](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE)۔ اگر آپ یہ جاننا چاہتے ہیں کہ ہم نے اسے کیسے بنایا، تو ہم پرزور سفارش کرتے ہیں کہ آپ ہمارا دوسرا ٹیوٹوریل، ["How to Create an NFT"](https://www.alchemy.com/docs/how-to-create-an-nft) دیکھیں۔ + +بہت خوب، اب جب کہ ہم سمجھ گئے ہیں کہ NFT بنانا کیسے کام کرتا ہے، آئیے اپنی اسٹارٹر فائلیں کلون کریں! + +## اسٹارٹر فائلیں کلون کریں {#clone-the-starter-files} + +سب سے پہلے، اس پروجیکٹ کے لیے اسٹارٹر فائلیں حاصل کرنے کے لیے [nft-minter-tutorial GitHub repository](https://github.com/alchemyplatform/nft-minter-tutorial) پر جائیں۔ اس ریپوزٹری کو اپنے مقامی ماحول میں کلون کریں۔ + +جب آپ اس کلون کی ہوئی `nft-minter-tutorial` ریپوزٹری کو کھولیں گے، تو آپ دیکھیں گے کہ اس میں دو فولڈرز ہیں: `minter-starter-files` اور `nft-minter`۔ + +- `minter-starter-files` میں اس پروجیکٹ کے لیے اسٹارٹر فائلیں (بنیادی طور پر React UI) ہیں۔ اس ٹیوٹوریل میں، **ہم اس ڈائریکٹری میں کام کریں گے**، جہاں آپ سیکھیں گے کہ اس UI کو اپنے Ethereum والیٹ اور ایک NFT اسمارٹ کنٹریکٹ سے جوڑ کر اسے کیسے فعال بنایا جائے۔ +- `nft-minter` میں پورا مکمل ٹیوٹوریل ہے اور اگر آپ کہیں پھنس جاتے ہیں تو یہ آپ کے لیے ایک **حوالے** کے طور پر موجود ہے۔ + +اس کے بعد، اپنے کوڈ ایڈیٹر میں `minter-starter-files` کی اپنی کاپی کھولیں، اور پھر اپنے `src` فولڈر میں جائیں۔ + +ہمارا لکھا ہوا سارا کوڈ `src` فولڈر کے تحت رہے گا۔ ہم `Minter.js` کمپونینٹ میں ترمیم کریں گے اور اپنے پروجیکٹ کو Web3 کی فعالیت دینے کے لیے اضافی javascript فائلیں لکھیں گے۔ + +## مرحلہ 2: ہماری اسٹارٹر فائلیں دیکھیں {#step-2-check-out-our-starter-files} + +کوڈنگ شروع کرنے سے پہلے، یہ دیکھنا ضروری ہے کہ اسٹارٹر فائلوں میں ہمارے لیے پہلے سے کیا فراہم کیا گیا ہے۔ + +### اپنا react پروجیکٹ چلائیں {#get-your-react-project-running} + +آئیے اپنے براؤزر میں React پروجیکٹ چلا کر شروع کریں۔ React کی خوبصورتی یہ ہے کہ ایک بار جب ہمارا پروجیکٹ ہمارے براؤزر میں چل رہا ہو، تو ہمارے ذریعے محفوظ کی گئی کوئی بھی تبدیلی ہمارے براؤزر میں لائیو اپ ڈیٹ ہو جائے گی۔ + +پروجیکٹ کو چلانے کے لیے، `minter-starter-files` فولڈر کی روٹ ڈائرکٹری میں جائیں، اور پروجیکٹ کی ڈیپینڈینسیز (dependencies) کو انسٹال کرنے کے لیے اپنے ٹرمینل میں `npm install` چلائیں: + +```bash +cd minter-starter-files +npm install +``` + +ان کے انسٹال ہونے کے بعد، اپنے ٹرمینل میں `npm start` چلائیں: + +```bash +npm start +``` + +ایسا کرنے سے آپ کے براؤزر میں http://localhost:3000/ کھل جائے گا، جہاں آپ کو ہمارے پروجیکٹ کا فرنٹ اینڈ نظر آئے گا۔ اس میں 3 فیلڈز ہونے چاہئیں: آپ کے NFT کے اثاثے کا لنک داخل کرنے کی جگہ، اپنے NFT کا نام درج کرنے کی جگہ، اور تفصیل فراہم کرنے کی جگہ۔ + +اگر آپ "Connect Wallet" یا "Mint NFT" بٹنوں پر کلک کرنے کی کوشش کرتے ہیں، تو آپ دیکھیں گے کہ وہ کام نہیں کرتے—اس کی وجہ یہ ہے کہ ہمیں ابھی بھی ان کی فعالیت کو پروگرام کرنے کی ضرورت ہے! :\) + +### Minter.js کمپونینٹ {#minter-js} + +**نوٹ:** یقینی بنائیں کہ آپ `minter-starter-files` فولڈر میں ہیں نہ کہ `nft-minter` فولڈر میں! + +آئیے اپنے ایڈیٹر میں `src` فولڈر میں واپس جائیں اور `Minter.js` فائل کھولیں۔ یہ بہت ضروری ہے کہ ہم اس فائل میں ہر چیز کو سمجھیں، کیونکہ یہ بنیادی React کمپونینٹ ہے جس پر ہم کام کریں گے۔ + +اس فائل کے اوپری حصے میں، ہمارے پاس ہمارے اسٹیٹ متغیرات (state variables) ہیں جنہیں ہم مخصوص ایونٹس کے بعد اپ ڈیٹ کریں گے۔ + +```javascript +//اسٹیٹ متغیرات +const [walletAddress, setWallet] = useState("") +const [status, setStatus] = useState("") +const [name, setName] = useState("") +const [description, setDescription] = useState("") +const [url, setURL] = useState("") +``` + +React اسٹیٹ متغیرات (state variables) یا اسٹیٹ ہکس (state hooks) کے بارے میں کبھی نہیں سنا؟ [ان](https://legacy.reactjs.org/docs/hooks-state.html) دستاویزات کو دیکھیں۔ + +یہاں ہر متغیر کی نمائندگی دی گئی ہے: + +- `walletAddress` - ایک اسٹرنگ جو صارف کے والیٹ کا پتہ محفوظ کرتا ہے +- `status` - ایک اسٹرنگ جس میں UI کے نیچے دکھانے کے لیے ایک پیغام ہوتا ہے +- `name` - ایک اسٹرنگ جو NFT کا نام محفوظ کرتا ہے +- `description` - ایک اسٹرنگ جو NFT کی تفصیل محفوظ کرتا ہے +- `url` - ایک اسٹرنگ جو NFT کے ڈیجیٹل اثاثے کا لنک ہے + +اسٹیٹ متغیرات کے بعد، آپ کو تین غیر نافذ شدہ فنکشنز نظر آئیں گے: `useEffect`، `connectWalletPressed`، اور `onMintPressed`۔ آپ دیکھیں گے کہ یہ تمام فنکشنز `async` ہیں، اس کی وجہ یہ ہے کہ ہم ان میں غیر مطابقت پذیر (asynchronous) API کالز کریں گے! ان کے نام ان کی فعالیتوں کے ہم نام ہیں: + +```javascript +useEffect(async () => { + //TODO: نافذ کریں +}, []) + +const connectWalletPressed = async () => { + //TODO: نافذ کریں +} + +const onMintPressed = async () => { + //TODO: نافذ کریں +} +``` + +- [`useEffect`](https://legacy.reactjs.org/docs/hooks-effect.html) - یہ ایک React ہک ہے جسے آپ کے کمپونینٹ کے رینڈر ہونے کے بعد کال کیا جاتا ہے۔ چونکہ اس میں ایک خالی اری `[]` پروپ پاس کیا گیا ہے (لائن 3 دیکھیں)، اسے صرف کمپونینٹ کے _پہلے_ رینڈر پر کال کیا جائے گا۔ یہاں ہم اپنے والیٹ لسنر اور ایک اور والیٹ فنکشن کو کال کریں گے تاکہ ہمارے UI کو اپ ڈیٹ کیا جا سکے تاکہ یہ ظاہر ہو سکے کہ آیا کوئی والیٹ پہلے سے جڑا ہوا ہے۔ +- `connectWalletPressed` - اس فنکشن کو صارف کے MetaMask والیٹ کو ہمارے dApp سے جوڑنے کے لیے کال کیا جائے گا۔ +- `onMintPressed` - اس فنکشن کو صارف کے NFT کو منٹ کرنے کے لیے کال کیا جائے گا۔ + +اس فائل کے آخر کے قریب، ہمارے پاس ہمارے کمپونینٹ کا UI ہے۔ اگر آپ اس کوڈ کو غور سے اسکین کرتے ہیں، تو آپ دیکھیں گے کہ جب ان کے متعلقہ ٹیکسٹ فیلڈز میں ان پٹ تبدیل ہوتا ہے تو ہم اپنے `url`، `name`، اور `description` اسٹیٹ متغیرات کو اپ ڈیٹ کرتے ہیں۔ + +آپ یہ بھی دیکھیں گے کہ جب بالترتیب `mintButton` اور `walletButton` IDs والے بٹنوں پر کلک کیا جاتا ہے تو `connectWalletPressed` اور `onMintPressed` کو کال کیا جاتا ہے۔ + +```javascript +//ہمارے کمپونینٹ کا UI +return ( +
+ + +

+

🧙‍♂️ Alchemy NFT منٹر

+

+ بس اپنے اثاثے کا لنک، نام، اور تفصیل شامل کریں، پھر "Mint" دبائیں۔ +

+
+

🖼 اثاثہ کا لنک:

+ setURL(event.target.value)} + /> +

🤔 نام:

+ setName(event.target.value)} + /> +

✍️ تفصیل:

+ setDescription(event.target.value)} + /> +
+ +

{status}

+
+) +``` + +آخر میں، آئیے اس بات پر غور کریں کہ یہ Minter کمپونینٹ کہاں شامل کیا گیا ہے۔ + +اگر آپ `App.js` فائل پر جاتے ہیں، جو React کا مرکزی کمپونینٹ ہے جو دیگر تمام کمپونینٹس کے لیے کنٹینر کے طور پر کام کرتا ہے، تو آپ دیکھیں گے کہ ہمارا Minter کمپونینٹ لائن 7 پر انجیکٹ کیا گیا ہے۔ + +**اس ٹیوٹوریل میں، ہم صرف `Minter.js` فائل میں ترمیم کریں گے اور اپنے `src` فولڈر میں فائلیں شامل کریں گے۔** + +اب جب کہ ہم سمجھ گئے ہیں کہ ہم کس چیز کے ساتھ کام کر رہے ہیں، آئیے اپنا Ethereum والیٹ سیٹ اپ کریں! + +## اپنا Ethereum والیٹ سیٹ اپ کریں {#set-up-your-ethereum-wallet} + +صارفین کو آپ کے اسمارٹ کنٹریکٹ کے ساتھ تعامل کرنے کے قابل ہونے کے لیے، انہیں اپنے Ethereum والیٹ کو آپ کے dApp سے جوڑنے کی ضرورت ہوگی۔ + +### MetaMask ڈاؤن لوڈ کریں {#download-metamask} + +اس ٹیوٹوریل کے لیے، ہم MetaMask استعمال کریں گے، جو براؤزر میں ایک ورچوئل والیٹ ہے جو آپ کے Ethereum اکاؤنٹ ایڈریس کو منظم کرنے کے لیے استعمال ہوتا ہے۔ اگر آپ Ethereum پر ٹرانزیکشنز کے کام کرنے کے بارے میں مزید سمجھنا چاہتے ہیں، تو [یہ صفحہ](/developers/docs/transactions/) دیکھیں۔ + +آپ [یہاں](https://metamask.io/download) مفت میں MetaMask اکاؤنٹ ڈاؤن لوڈ اور بنا سکتے ہیں۔ جب آپ ایک اکاؤنٹ بنا رہے ہوں، یا اگر آپ کے پاس پہلے سے ہی ایک اکاؤنٹ ہے، تو یقینی بنائیں کہ اوپر دائیں جانب "Ropsten Test Network" پر سوئچ کریں (تاکہ ہم اصلی پیسے سے نمٹ نہ رہے ہوں)۔ + +### ایک Faucet سے ether شامل کریں {#add-ether-from-faucet} + +اپنے NFTs کو منٹ کرنے (یا Ethereum بلاک چین پر کسی بھی ٹرانزیکشن پر دستخط کرنے) کے لیے، ہمیں کچھ جعلی Eth کی ضرورت ہوگی۔ Eth حاصل کرنے کے لیے آپ [Ropsten faucet](https://faucet.ropsten.be/) پر جا سکتے ہیں اور اپنا Ropsten اکاؤنٹ کا پتہ درج کر سکتے ہیں، پھر "Send Ropsten Eth" پر کلک کریں۔ اس کے فوراً بعد آپ کو اپنے 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 کے برابر ہے۔ + +اف! ہمارا جعلی پیسہ سب وہیں ہے! + +## MetaMask کو اپنے UI سے جوڑیں {#connect-metamask-to-your-UI} + +اب جب کہ ہمارا MetaMask والیٹ سیٹ اپ ہو گیا ہے، آئیے اپنے dApp کو اس سے جوڑتے ہیں! + +چونکہ ہم [MVC](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) پیراڈائم کی پابندی کرنا چاہتے ہیں، ہم ایک الگ فائل بنائیں گے جس میں ہمارے dApp کی منطق، ڈیٹا اور قواعد کو منظم کرنے کے لیے ہمارے فنکشنز ہوں گے، اور پھر ان فنکشنز کو اپنے فرنٹ اینڈ (ہمارے Minter.js کمپونینٹ) میں پاس کریں گے۔ + +### `connectWallet` فنکشن {#connect-wallet-function} + +ایسا کرنے کے لیے، آئیے اپنی `src` ڈائریکٹری میں `utils` نام کا ایک نیا فولڈر بنائیں اور اس کے اندر `interact.js` نام کی ایک فائل شامل کریں، جس میں ہمارے تمام والیٹ اور اسمارٹ کنٹریکٹ کے تعامل کے فنکشنز ہوں گے۔ + +ہماری `interact.js` فائل میں، ہم ایک `connectWallet` فنکشن لکھیں گے، جسے ہم پھر اپنے `Minter.js` کمپونینٹ میں امپورٹ اور کال کریں گے۔ + +اپنی `interact.js` فائل میں، درج ذیل شامل کریں + +```javascript +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 انسٹال کرنا ہوگا۔ + +**ہمارے لکھے ہوئے زیادہ تر فنکشنز JSON آبجیکٹ واپس کریں گے جن کا استعمال ہم اپنے اسٹیٹ متغیرات اور UI کو اپ ڈیٹ کرنے کے لیے کر سکتے ہیں۔** + +اب اگر `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` پیغام ہوگا جو یہ ظاہر کرے گا کہ صارف نے کنکشن کو مسترد کر دیا ہے۔ + +### اپنے Minter.js UI کمپونینٹ میں connectWallet فنکشن شامل کریں {#add-connect-wallet} + +اب جب کہ ہم نے یہ `connectWallet` فنکشن لکھ لیا ہے، آئیے اسے اپنے `Minter.js` کمپونینٹ سے جوڑتے ہیں۔ + +سب سے پہلے، ہمیں `Minter.js` فائل کے اوپری حصے میں `import { connectWallet } from "./utils/interact.js";` شامل کرکے اپنے فنکشن کو اپنی `Minter.js` فائل میں امپورٹ کرنا ہوگا۔ آپ کی `Minter.js` کی پہلی 11 لائنیں اب اس طرح نظر آنی چاہئیں: + +```javascript +import { useEffect, useState } from "react"; +import { connectWallet } from "./utils/interact.js"; + +const Minter = (props) => { + + //اسٹیٹ متغیرات + const [walletAddress, setWallet] = useState(""); + const [status, setStatus] = useState(""); + const [name, setName] = useState(""); + const [description, setDescription] = useState(""); + const [url, setURL] = useState(""); +``` + +پھر، اپنے `connectWalletPressed` فنکشن کے اندر، ہم اپنے امپورٹ کردہ `connectWallet` فنکشن کو اس طرح کال کریں گے: + +```javascript +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +دیکھیں کہ ہماری زیادہ تر فعالیت `interact.js` فائل سے ہمارے `Minter.js` کمپونینٹ سے کیسے الگ کی گئی ہے؟ یہ اس لیے ہے تاکہ ہم M-V-C پیراڈائم کی تعمیل کریں! + +`connectWalletPressed` میں، ہم صرف اپنے امپورٹ کردہ `connectWallet` فنکشن پر ایک await کال کرتے ہیں، اور اس کے جواب کا استعمال کرتے ہوئے، ہم اپنے `status` اور `walletAddress` متغیرات کو ان کے اسٹیٹ ہکس کے ذریعے اپ ڈیٹ کرتے ہیں۔ + +اب، آئیے دونوں فائلوں `Minter.js` اور `interact.js` کو محفوظ کریں اور اب تک اپنے UI کی جانچ کریں۔ + +اپنے براؤزر کو localhost:3000 پر کھولیں، اور صفحہ کے اوپر دائیں جانب "Connect Wallet" بٹن دبائیں۔ + +اگر آپ نے MetaMask انسٹال کیا ہوا ہے، تو آپ سے اپنے والیٹ کو اپنے dApp سے جوڑنے کا کہا جائے گا۔ جڑنے کی دعوت قبول کریں۔ + +آپ کو دیکھنا چاہیے کہ والیٹ بٹن اب یہ ظاہر کرتا ہے کہ آپ کا پتہ جڑ گیا ہے۔ + +اگلا، صفحہ کو ریفریش کرنے کی کوشش کریں... یہ عجیب ہے۔ ہمارا والیٹ بٹن ہمیں MetaMask سے جڑنے کا کہہ رہا ہے، حالانکہ یہ پہلے سے ہی جڑا ہوا ہے... + +لیکن فکر نہ کریں! ہم اسے `getCurrentWalletConnected` نامی فنکشن کو نافذ کرکے آسانی سے ٹھیک کر سکتے ہیں، جو یہ چیک کرے گا کہ آیا کوئی پتہ پہلے سے ہی ہمارے dApp سے جڑا ہوا ہے اور اسی کے مطابق ہمارے UI کو اپ ڈیٹ کرے گا! + +### getCurrentWalletConnected فنکشن {#get-current-wallet} + +اپنی `interact.js` فائل میں، درج ذیل `getCurrentWalletConnected` فنکشن شامل کریں: + +```javascript +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 پتے ہوتے ہیں۔ + +اس فنکشن کو عملی طور پر دیکھنے کے لیے، آئیے اسے اپنے `Minter.js` کمپونینٹ کے `useEffect` فنکشن میں کال کریں۔ + +جیسا کہ ہم نے `connectWallet` کے لیے کیا تھا، ہمیں اس فنکشن کو اپنی `interact.js` فائل سے اپنی `Minter.js` فائل میں اس طرح امپورٹ کرنا ہوگا: + +```javascript +import { useEffect, useState } from "react" +import { + connectWallet, + getCurrentWalletConnected, //یہاں امپورٹ کریں +} from "./utils/interact.js" +``` + +اب، ہم اسے صرف اپنے `useEffect` فنکشن میں کال کرتے ہیں: + +```javascript +useEffect(async () => { + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +نوٹ کریں، ہم اپنے `walletAddress` اور `status` اسٹیٹ متغیرات کو اپ ڈیٹ کرنے کے لیے `getCurrentWalletConnected` پر اپنی کال کے جواب کا استعمال کرتے ہیں۔ + +ایک بار جب آپ یہ کوڈ شامل کر لیں، تو اپنے براؤزر ونڈو کو ریفریش کرنے کی کوشش کریں۔ بٹن کو کہنا چاہیے کہ آپ جڑے ہوئے ہیں، اور آپ کے جڑے ہوئے والیٹ کے پتے کا ایک پیش نظارہ دکھانا چاہیے - یہاں تک کہ آپ کے ریفریش کرنے کے بعد بھی! + +### addWalletListener نافذ کریں {#implement-add-wallet-listener} + +ہمارے dApp والیٹ سیٹ اپ کا آخری مرحلہ والیٹ لسنر کو نافذ کرنا ہے تاکہ جب ہمارے والیٹ کی حالت تبدیل ہو تو ہمارا UI اپ ڈیٹ ہو، جیسے جب صارف منقطع ہوتا ہے یا اکاؤنٹس تبدیل کرتا ہے۔ + +اپنی `Minter.js` فائل میں، `addWalletListener` نامی ایک فنکشن شامل کریں جو درج ذیل کی طرح نظر آتا ہے: + +```javascript +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 +useEffect(async () => { + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +اور voila! ہم نے اپنی تمام والیٹ کی فعالیت کی پروگرامنگ مکمل کر لی ہے! اب جب کہ ہمارا والیٹ سیٹ اپ ہو گیا ہے، آئیے معلوم کریں کہ اپنا NFT کیسے منٹ کیا جائے! + +## NFT میٹا ڈیٹا 101 {#nft-metadata-101} + +تو یاد ہے اس ٹیوٹوریل کے مرحلہ 0 میں ہم نے جس NFT میٹا ڈیٹا کے بارے میں بات کی تھی — یہ ایک NFT کو زندگی بخشتا ہے، جس سے اسے ڈیجیٹل اثاثہ، نام، تفصیل، اور دیگر صفات جیسی خصوصیات رکھنے کی اجازت ملتی ہے۔ + +ہمیں اس میٹا ڈیٹا کو JSON آبجیکٹ کے طور پر کنفیگر کرنے اور اسے ذخیرہ کرنے کی ضرورت ہوگی، تاکہ ہم اسے اپنے اسمارٹ کنٹریکٹ کے `mintNFT` فنکشن کو کال کرتے وقت `tokenURI` پیرامیٹر کے طور پر پاس کر سکیں۔ + +"Link to Asset"، "Name"، "Description" فیلڈز میں موجود متن ہمارے NFT کے میٹا ڈیٹا کی مختلف خصوصیات پر مشتمل ہوگا۔ ہم اس میٹا ڈیٹا کو JSON آبجیکٹ کے طور پر فارمیٹ کریں گے، لیکن ہمارے پاس کچھ اختیارات ہیں کہ ہم اس JSON آبجیکٹ کو کہاں ذخیرہ کر سکتے ہیں: + +- ہم اسے Ethereum بلاک چین پر ذخیرہ کر سکتے ہیں؛ تاہم، ایسا کرنا بہت مہنگا ہوگا۔ +- ہم اسے ایک مرکزی سرور پر ذخیرہ کر سکتے ہیں، جیسے AWS یا Firebase۔ لیکن یہ ہمارے وکندریقرت کے اصول کو شکست دے گا۔ +- ہم IPFS، ایک وکندریقرت پروٹوکول اور پیئر ٹو پیئر نیٹ ورک کا استعمال کر سکتے ہیں جو ایک تقسیم شدہ فائل سسٹم میں ڈیٹا کو ذخیرہ کرنے اور شیئر کرنے کے لیے ہے۔ چونکہ یہ پروٹوکول وکندریقرت اور مفت ہے، یہ ہمارا بہترین آپشن ہے! + +IPFS پر اپنے میٹا ڈیٹا کو ذخیرہ کرنے کے لیے، ہم [Pinata](https://pinata.cloud/) کا استعمال کریں گے، جو ایک آسان IPFS API اور ٹول کٹ ہے۔ اگلے مرحلے میں، ہم بالکل وضاحت کریں گے کہ یہ کیسے کرنا ہے! + +## اپنے میٹا ڈیٹا کو IPFS پر پن کرنے کے لیے Pinata کا استعمال کریں {#use-pinata-to-pin-your-metadata-to-IPFS} + +اگر آپ کے پاس [Pinata](https://pinata.cloud/) اکاؤنٹ نہیں ہے، تو [یہاں](https://app.pinata.cloud/auth/signup) ایک مفت اکاؤنٹ کے لیے سائن اپ کریں اور اپنے ای میل اور اکاؤنٹ کی تصدیق کے لیے مراحل مکمل کریں۔ + +### اپنی Pinata API کی (key) بنائیں {#create-pinata-api-key} + +[https://pinata.cloud/keys](https://pinata.cloud/keys) صفحہ پر جائیں، پھر سب سے اوپر "New Key" بٹن کو منتخب کریں، ایڈمن ویجیٹ کو فعال کے طور پر سیٹ کریں، اور اپنی کی (key) کو نام دیں۔ + +پھر آپ کو اپنی API کی معلومات کے ساتھ ایک پاپ اپ دکھایا جائے گا۔ اسے کسی محفوظ جگہ پر رکھنا یقینی بنائیں۔ + +اب جب کہ ہماری کی (key) سیٹ اپ ہو گئی ہے، آئیے اسے اپنے پروجیکٹ میں شامل کریں تاکہ ہم اسے استعمال کر سکیں۔ + +### ایک .env فائل بنائیں {#create-a-env} + +ہم اپنی Pinata کی (key) اور سیکرٹ کو ایک انوائرمنٹ فائل میں محفوظ طریقے سے ذخیرہ کر سکتے ہیں۔ آئیے اپنی پروجیکٹ ڈائرکٹری میں [dotenv package](https://www.npmjs.com/package/dotenv) انسٹال کریں۔ + +اپنے ٹرمینل میں ایک نیا ٹیب کھولیں (مقامی ہوسٹ چلانے والے سے الگ) اور یقینی بنائیں کہ آپ `minter-starter-files` فولڈر میں ہیں، پھر اپنے ٹرمینل میں درج ذیل کمانڈ چلائیں: + +```text +npm install dotenv --save +``` + +اس کے بعد، اپنی کمانڈ لائن پر درج ذیل درج کرکے اپنی `minter-starter-files` کی روٹ ڈائرکٹری میں ایک `.env` فائل بنائیں: + +```javascript +vim.env +``` + +یہ آپ کی `.env` فائل کو vim (ایک ٹیکسٹ ایڈیٹر) میں کھول دے گا۔ اسے محفوظ کرنے کے لیے اپنے کی بورڈ پر "esc" + ":" + "q" اسی ترتیب میں دبائیں۔ + +اس کے بعد، VSCode میں، اپنی `.env` فائل پر جائیں اور اپنی Pinata API کی (key) اور API سیکرٹ کو اس میں شامل کریں، اس طرح: + +```text +REACT_APP_PINATA_KEY = +REACT_APP_PINATA_SECRET = +``` + +فائل کو محفوظ کریں، اور پھر آپ اپنے JSON میٹا ڈیٹا کو IPFS پر اپ لوڈ کرنے کے لیے فنکشن لکھنا شروع کرنے کے لیے تیار ہیں! + +### pinJSONToIPFS نافذ کریں {#pin-json-to-ipfs} + +خوش قسمتی سے ہمارے لیے، Pinata کے پاس [خاص طور پر JSON ڈیٹا کو IPFS پر اپ لوڈ کرنے کے لیے ایک API](https://docs.pinata.cloud/api-reference/endpoint/ipfs/pin-json-to-ipfs#pin-json) ہے اور axios کے ساتھ ایک آسان JavaScript مثال ہے جسے ہم کچھ معمولی ترمیم کے ساتھ استعمال کر سکتے ہیں۔ + +اپنے `utils` فولڈر میں، آئیے `pinata.js` نام کی ایک اور فائل بنائیں اور پھر .env فائل سے اپنی Pinata سیکرٹ اور کی (key) کو اس طرح امپورٹ کریں: + +```javascript +require("dotenv").config() +const key = process.env.REACT_APP_PINATA_KEY +const secret = process.env.REACT_APP_PINATA_SECRET +``` + +اس کے بعد، نیچے سے اضافی کوڈ کو اپنی `pinata.js` فائل میں پیسٹ کریں۔ فکر نہ کریں، ہم ہر چیز کا مطلب سمجھائیں گے! + +```javascript +require("dotenv").config() +const key = process.env.REACT_APP_PINATA_KEY +const secret = process.env.REACT_APP_PINATA_SECRET + +const axios = require("axios") + +export const pinJSONToIPFS = async (JSONBody) => { + const url = `https://api.pinata.cloud/pinning/pinJSONToIPFS` + //making axios POST request to Pinata ⬇️ + return axios + .post(url, JSONBody, { + headers: { + pinata_api_key: key, + pinata_secret_api_key: secret, + }, + }) + .then(function (response) { + return { + success: true, + pinataUrl: + "https://gateway.pinata.cloud/ipfs/" + response.data.IpfsHash, + } + }) + .catch(function (error) { + console.log(error) + return { + success: false, + message: error.message, + } + }) +} +``` + +تو یہ کوڈ بالکل کیا کرتا ہے؟ + +سب سے پہلے، یہ [axios](https://www.npmjs.com/package/axios) امپورٹ کرتا ہے، جو براؤزر اور node.js کے لیے ایک پرامس پر مبنی HTTP کلائنٹ ہے، جسے ہم Pinata سے درخواست کرنے کے لیے استعمال کریں گے۔ + +پھر ہمارے پاس ہمارا غیر مطابقت پذیر فنکشن `pinJSONToIPFS` ہے، جو اپنے ان پٹ کے طور پر `JSONBody` لیتا ہے اور اپنے ہیڈر میں Pinata api کی (key) اور سیکرٹ لیتا ہے، یہ سب ان کے `pinJSONToIPFS` API پر POST کی درخواست کرنے کے لیے ہے۔ + +- اگر یہ POST درخواست کامیاب ہوتی ہے، تو ہمارا فنکشن ایک JSON آبجیکٹ واپس کرتا ہے جس میں `success` بولین true ہوتا ہے اور `pinataUrl` ہوتا ہے جہاں ہمارا میٹا ڈیٹا پن کیا گیا تھا۔ ہم اس `pinataUrl` کو اپنے اسمارٹ کنٹریکٹ کے منٹ فنکشن میں `tokenURI` ان پٹ کے طور پر استعمال کریں گے۔ +- اگر یہ پوسٹ درخواست ناکام ہو جاتی ہے، تو ہمارا فنکشن ایک JSON آبجیکٹ واپس کرتا ہے جس میں `success` بولین false ہوتا ہے اور ایک `message` اسٹرنگ ہوتی ہے جو ہماری غلطی کو بتاتی ہے۔ + +ہمارے `connectWallet` فنکشن کی واپسی کی اقسام کی طرح، ہم JSON آبجیکٹ واپس کر رہے ہیں تاکہ ہم ان کے پیرامیٹرز کا استعمال اپنے اسٹیٹ متغیرات اور UI کو اپ ڈیٹ کرنے کے لیے کر سکیں۔ + +## اپنا اسمارٹ کنٹریکٹ لوڈ کریں {#load-your-smart-contract} + +اب جب کہ ہمارے پاس اپنے `pinJSONToIPFS` فنکشن کے ذریعے اپنے NFT میٹا ڈیٹا کو IPFS پر اپ لوڈ کرنے کا ایک طریقہ ہے، ہمیں اپنے اسمارٹ کنٹریکٹ کا ایک نمونہ لوڈ کرنے کا ایک طریقہ درکار ہوگا تاکہ ہم اس کے `mintNFT` فنکشن کو کال کر سکیں۔ + +جیسا کہ ہم نے پہلے ذکر کیا، اس ٹیوٹوریل میں ہم [یہ موجودہ NFT اسمارٹ کنٹریکٹ](https://ropsten.etherscan.io/address/0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE) استعمال کریں گے؛ تاہم، اگر آپ یہ جاننا چاہتے ہیں کہ ہم نے اسے کیسے بنایا، یا خود ایک بنانا چاہتے ہیں، تو ہم پرزور سفارش کرتے ہیں کہ آپ ہمارا دوسرا ٹیوٹوریل، ["How to Create an NFT"](https://www.alchemy.com/docs/how-to-create-an-nft) دیکھیں۔ + +### کنٹریکٹ ABI {#contract-abi} + +اگر آپ نے ہماری فائلوں کا بغور جائزہ لیا ہے، تو آپ نے دیکھا ہوگا کہ ہماری `src` ڈائرکٹری میں، ایک `contract-abi.json` فائل ہے۔ ایک ABI یہ بتانے کے لیے ضروری ہے کہ ایک کنٹریکٹ کس فنکشن کو طلب کرے گا اور یہ بھی یقینی بنانے کے لیے کہ فنکشن آپ کی متوقع شکل میں ڈیٹا واپس کرے گا۔ + +Ethereum بلاک چین سے جڑنے اور اپنا اسمارٹ کنٹریکٹ لوڈ کرنے کے لیے ہمیں ایک Alchemy API کی (key) اور Alchemy Web3 API کی بھی ضرورت ہوگی۔ + +### اپنی Alchemy API کی (key) بنائیں {#create-alchemy-api} + +اگر آپ کے پاس پہلے سے Alchemy اکاؤنٹ نہیں ہے، تو [یہاں مفت میں سائن اپ کریں۔](https://alchemy.com/?a=eth-org-nft-minter) + +ایک بار جب آپ Alchemy اکاؤنٹ بنا لیں، تو آپ ایک ایپ بنا کر API کلید تیار کر سکتے ہیں۔ یہ ہمیں Ropsten ٹیسٹ نیٹ ورک سے درخواستیں کرنے کی اجازت دے گا۔ + +نیو بار میں "Apps" پر ہوور کرکے اور "Create App" پر کلک کرکے اپنے Alchemy ڈیش بورڈ میں "Create App" صفحہ پر جائیں۔ + +اپنی ایپ کو نام دیں ہم نے "My First NFT!" کا انتخاب کیا، ایک مختصر تفصیل پیش کریں، اپنی ایپ کی بک کیپنگ کے لیے استعمال ہونے والے ماحول کے لیے "Staging" کو منتخب کریں، اور اپنے نیٹ ورک کے لیے "Ropsten" کا انتخاب کریں۔ + +“Create app” پر کلک کریں اور بس! آپ کی ایپ نیچے دی گئی ٹیبل میں ظاہر ہونی چاہیے۔ + +بہت خوب تو اب جب کہ ہم نے اپنا HTTP Alchemy API URL بنا لیا ہے، اسے اپنے کلپ بورڈ پر کاپی کریں... + +... اور پھر آئیے اسے اپنی `.env` فائل میں شامل کریں۔ مجموعی طور پر، آپ کی .env فائل اس طرح نظر آنی چاہیے: + +```text +REACT_APP_PINATA_KEY = +REACT_APP_PINATA_SECRET = +REACT_APP_ALCHEMY_KEY = https://eth-ropsten.alchemyapi.io/v2/ +``` + +اب جب کہ ہمارے پاس ہمارا کنٹریکٹ ABI اور ہماری Alchemy API کی (key) ہے، ہم [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) کا استعمال کرتے ہوئے اپنا اسمارٹ کنٹریکٹ لوڈ کرنے کے لیے تیار ہیں۔ + +### اپنا Alchemy Web3 اینڈ پوائنٹ اور کنٹریکٹ سیٹ اپ کریں {#setup-alchemy-endpoint} + +سب سے پہلے، اگر آپ کے پاس پہلے سے نہیں ہے، تو آپ کو ٹرمینل میں ہوم ڈائرکٹری: `nft-minter-tutorial` پر جا کر [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) انسٹال کرنے کی ضرورت ہوگی: + +```text +cd .. +npm install @alch/alchemy-web3 +``` + +اس کے بعد آئیے اپنی `interact.js` فائل پر واپس چلتے ہیں۔ فائل کے اوپری حصے میں، اپنی .env فائل سے اپنی Alchemy کی (key) امپورٹ کرنے اور اپنا Alchemy Web3 اینڈ پوائنٹ سیٹ اپ کرنے کے لیے درج ذیل کوڈ شامل کریں: + +```javascript +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) +``` + +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) [Web3.js](https://docs.web3js.org/) کے ارد گرد ایک ریپر ہے، جو بہتر API طریقے اور دیگر اہم فوائد فراہم کرتا ہے تاکہ آپ کی زندگی کو ایک web3 ڈیولپر کے طور پر آسان بنایا جا سکے۔ یہ کم سے کم کنفیگریشن کی ضرورت کے لیے ڈیزائن کیا گیا ہے تاکہ آپ اسے اپنی ایپ میں فوراً استعمال کرنا شروع کر سکیں! + +اگلا، آئیے اپنی فائل میں اپنا کنٹریکٹ ABI اور کنٹریکٹ کا پتہ شامل کریں۔ + +```javascript +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 = "0x4C4a07F737Bf57F6632B6CAB089B78f62385aCaE" +``` + +ایک بار جب ہمارے پاس یہ دونوں ہو جائیں، تو ہم اپنا منٹ فنکشن کوڈ کرنا شروع کرنے کے لیے تیار ہیں! + +## mintNFT فنکشن نافذ کریں {#implement-the-mintnft-function} + +اپنی `interact.js` فائل کے اندر، آئیے اپنے فنکشن، `mintNFT` کی وضاحت کریں، جو ہم نامی طور پر ہمارا NFT منٹ کرے گا۔ + +چونکہ ہم متعدد غیر مطابقت پذیر کالز کریں گے (Pinata سے اپنے میٹا ڈیٹا کو IPFS پر پن کرنے کے لیے، Alchemy Web3 سے اپنا اسمارٹ کنٹریکٹ لوڈ کرنے کے لیے، اور MetaMask سے اپنے ٹرانزیکشنز پر دستخط کرنے کے لیے)، ہمارا فنکشن بھی غیر مطابقت پذیر ہوگا۔ + +ہمارے فنکشن میں تین ان پٹ ہمارے ڈیجیٹل اثاثے کا `url`، `name`، اور `description` ہوں گے۔ `connectWallet` فنکشن کے نیچے درج ذیل فنکشن کا دستخط شامل کریں: + +```javascript +export const mintNFT = async (url, name, description) => {} +``` + +### ان پٹ کی خرابی کو ہینڈل کرنا {#input-error-handling} + +فطرتاً، فنکشن کے آغاز میں کسی قسم کی ان پٹ کی خرابی کو ہینڈل کرنا سمجھ میں آتا ہے، تاکہ اگر ہمارے ان پٹ پیرامیٹرز درست نہ ہوں تو ہم اس فنکشن سے باہر نکل جائیں۔ اپنے فنکشن کے اندر، آئیے درج ذیل کوڈ شامل کریں: + +```javascript +export const mintNFT = async (url, name, description) => { + //خرابی کو ہینڈل کرنا + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + } + } +} +``` + +بنیادی طور پر، اگر کوئی بھی ان پٹ پیرامیٹر ایک خالی اسٹرنگ ہے، تو ہم ایک JSON آبجیکٹ واپس کرتے ہیں جہاں `success` بولین false ہوتا ہے، اور `status` اسٹرنگ یہ بتاتی ہے کہ ہمارے UI میں تمام فیلڈز مکمل ہونے چاہئیں۔ + +### میٹا ڈیٹا کو IPFS پر اپ لوڈ کریں {#upload-metadata-to-ipfs} + +ایک بار جب ہم جان لیں کہ ہمارا میٹا ڈیٹا مناسب طریقے سے فارمیٹ کیا گیا ہے، تو اگلا مرحلہ اسے JSON آبجیکٹ میں لپیٹنا اور اسے اپنے لکھے ہوئے `pinJSONToIPFS` کے ذریعے IPFS پر اپ لوڈ کرنا ہے! + +ایسا کرنے کے لیے، ہمیں پہلے اپنی `interact.js` فائل میں `pinJSONToIPFS` فنکشن کو امپورٹ کرنا ہوگا۔ `interact.js` کے بالکل اوپر، آئیے شامل کریں: + +```javascript +import { pinJSONToIPFS } from "./pinata.js" +``` + +یاد رہے کہ `pinJSONToIPFS` ایک JSON باڈی لیتا ہے۔ تو اس پر کال کرنے سے پہلے، ہمیں اپنے `url`، `name`، اور `description` پیرامیٹرز کو JSON آبجیکٹ میں فارمیٹ کرنے کی ضرورت ہوگی۔ + +آئیے اپنے کوڈ کو `metadata` نامی ایک JSON آبجیکٹ بنانے کے لیے اپ ڈیٹ کریں اور پھر اس `metadata` پیرامیٹر کے ساتھ `pinJSONToIPFS` پر کال کریں: + +```javascript +export const mintNFT = async (url, name, description) => { + //خرابی کو ہینڈل کرنا + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + } + } + + //میٹا ڈیٹا بنائیں + const metadata = new Object() + metadata.name = name + metadata.image = url + metadata.description = description + + //pinata کال کریں + const pinataResponse = await pinJSONToIPFS(metadata) + if (!pinataResponse.success) { + return { + success: false, + status: "😢 آپ کا tokenURI اپ لوڈ کرتے وقت کچھ غلط ہو گیا۔", + } + } + const tokenURI = pinataResponse.pinataUrl +} +``` + +نوٹ کریں، ہم `pinJSONToIPFS(metadata)` پر اپنی کال کا جواب `pinataResponse` آبجیکٹ میں محفوظ کرتے ہیں۔ پھر، ہم اس آبجیکٹ کو کسی بھی خرابی کے لیے پارس کرتے ہیں۔ + +اگر کوئی خرابی ہوتی ہے، تو ہم ایک JSON آبجیکٹ واپس کرتے ہیں جہاں `success` بولین false ہوتا ہے اور ہماری `status` اسٹرنگ بتاتی ہے کہ ہماری کال ناکام ہوگئی۔ ورنہ، ہم `pinataResponse` سے `pinataURL` نکالتے ہیں اور اسے اپنے `tokenURI` متغیر کے طور پر محفوظ کرتے ہیں۔ + +اب وقت آگیا ہے کہ ہم اپنے اسمارٹ کنٹریکٹ کو Alchemy Web3 API کا استعمال کرتے ہوئے لوڈ کریں جسے ہم نے اپنی فائل کے اوپری حصے میں شروع کیا تھا۔ کنٹریکٹ کو `window.contract` عالمی متغیر پر سیٹ کرنے کے لیے `mintNFT` فنکشن کے نیچے کوڈ کی درج ذیل لائن شامل کریں: + +```javascript +window.contract = await new web3.eth.Contract(contractABI, contractAddress) +``` + +ہمارے `mintNFT` فنکشن میں شامل کرنے والی آخری چیز ہمارا Ethereum ٹرانزیکشن ہے: + +```javascript +//اپنا Ethereum ٹرانزیکشن سیٹ اپ کریں +const transactionParameters = { + to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ + from: window.ethereum.selectedAddress, // صارف کے فعال پتے سے مماثل ہونا چاہیے۔ + data: window.contract.methods + .mintNFT(window.ethereum.selectedAddress, tokenURI) + .encodeABI(), //NFT اسمارٹ کنٹریکٹ پر کال کریں +} + +//MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + success: true, + status: + "✅ Etherscan پر اپنے ٹرانزیکشن کو دیکھیں: https://ropsten.etherscan.io/tx/" + + txHash, + } +} catch (error) { + return { + success: false, + status: "😥 کچھ غلط ہو گیا: " + error.message, + } +} +``` + +اگر آپ پہلے سے ہی Ethereum ٹرانزیکشنز سے واقف ہیں، تو آپ دیکھیں گے کہ ساخت آپ نے جو دیکھا ہے اس سے کافی ملتی جلتی ہے۔ + +- سب سے پہلے، ہم اپنے ٹرانزیکشنز پیرامیٹرز سیٹ اپ کرتے ہیں۔ + - `to` وصول کنندہ کا پتہ (ہمارا اسمارٹ کنٹریکٹ) بتاتا ہے + - `from` ٹرانزیکشن کے دستخط کنندہ (صارف کا MetaMask سے جڑا ہوا پتہ: `window.ethereum.selectedAddress`) کی وضاحت کرتا ہے + - `data` میں ہمارے اسمارٹ کنٹریکٹ `mintNFT` میتھڈ پر کال شامل ہے، جو ہمارے `tokenURI` اور صارف کے والیٹ پتے، `window.ethereum.selectedAddress`، کو ان پٹ کے طور پر وصول کرتا ہے۔ +- پھر، ہم ایک await کال، `window.ethereum.request` کرتے ہیں، جہاں ہم MetaMask سے ٹرانزیکشن پر دستخط کرنے کو کہتے ہیں۔ نوٹ کریں، اس درخواست میں، ہم اپنے eth میتھڈ (eth_SentTransaction) کی وضاحت کر رہے ہیں اور اپنے `transactionParameters` پاس کر رہے ہیں۔ اس مقام پر، MetaMask براؤزر میں کھل جائے گا، اور صارف سے ٹرانزیکشن پر دستخط کرنے یا مسترد کرنے کا کہے گا۔ + - اگر ٹرانزیکشن کامیاب ہو جاتا ہے، تو فنکشن ایک JSON آبجیکٹ واپس کرے گا جہاں بولین `success` کو true پر سیٹ کیا گیا ہے اور `status` اسٹرنگ صارف کو اپنے ٹرانزیکشن کے بارے میں مزید معلومات کے لیے Etherscan چیک کرنے کا کہتی ہے۔ + - اگر ٹرانزیکشن ناکام ہو جاتا ہے، تو فنکشن ایک JSON آبجیکٹ واپس کرے گا جہاں `success` بولین کو false پر سیٹ کیا گیا ہے، اور `status` اسٹرنگ غلطی کا پیغام بتاتی ہے۔ + +مجموعی طور پر، ہمارا `mintNFT` فنکشن اس طرح نظر آنا چاہیے: + +```javascript +export const mintNFT = async (url, name, description) => { + //خرابی کو ہینڈل کرنا + if (url.trim() == "" || name.trim() == "" || description.trim() == "") { + return { + success: false, + status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + } + } + + //میٹا ڈیٹا بنائیں + const metadata = new Object() + metadata.name = name + metadata.image = url + metadata.description = description + + //pinata پن کی درخواست + const pinataResponse = await pinJSONToIPFS(metadata) + if (!pinataResponse.success) { + return { + success: false, + status: "😢 آپ کا tokenURI اپ لوڈ کرتے وقت کچھ غلط ہو گیا۔", + } + } + const tokenURI = pinataResponse.pinataUrl + + //اسمارٹ کنٹریکٹ لوڈ کریں + window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract(); + + //اپنا Ethereum ٹرانزیکشن سیٹ اپ کریں + const transactionParameters = { + to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ + from: window.ethereum.selectedAddress, // صارف کے فعال پتے سے مماثل ہونا چاہیے۔ + data: window.contract.methods + .mintNFT(window.ethereum.selectedAddress, tokenURI) + .encodeABI(), //NFT اسمارٹ کنٹریکٹ پر کال کریں + } + + //MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں + try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + success: true, + status: + "✅ Etherscan پر اپنے ٹرانزیکشن کو دیکھیں: https://ropsten.etherscan.io/tx/" + + txHash, + } + } catch (error) { + return { + success: false, + status: "😥 کچھ غلط ہو گیا: " + error.message, + } + } +} +``` + +یہ ایک بہت بڑا فنکشن ہے! اب، ہمیں صرف اپنے `mintNFT` فنکشن کو اپنے `Minter.js` کمپونینٹ سے جوڑنے کی ضرورت ہے... + +## mintNFT کو ہمارے Minter.js فرنٹ اینڈ سے جوڑیں {#connect-our-frontend} + +اپنی `Minter.js` فائل کھولیں اور اوپر کی `import { connectWallet, getCurrentWalletConnected } from "./utils/interact.js";` لائن کو اپ ڈیٹ کرکے یہ کریں: + +```javascript +import { + connectWallet, + getCurrentWalletConnected, + mintNFT, +} from "./utils/interact.js" +``` + +آخر میں، اپنے امپورٹ کردہ `mintNFT` فنکشن پر await کال کرنے کے لیے `onMintPressed` فنکشن کو نافذ کریں اور `status` اسٹیٹ متغیر کو اپ ڈیٹ کریں تاکہ یہ ظاہر ہو سکے کہ ہمارا ٹرانزیکشن کامیاب ہوا یا ناکام: + +```javascript +const onMintPressed = async () => { + const { status } = await mintNFT(url, name, description) + setStatus(status) +} +``` + +## اپنا NFT ایک لائیو ویب سائٹ پر تعینات کریں {#deploy-your-NFT} + +صارفین کے ساتھ تعامل کے لیے اپنے پروجیکٹ کو لائیو کرنے کے لیے تیار ہیں؟ اپنے منٹر کو ایک لائیو ویب سائٹ پر تعینات کرنے کے لیے [یہ ٹیوٹوریل](https://docs.alchemy.com/alchemy/tutorials/nft-minter/how-do-i-deploy-nfts-online) دیکھیں۔ + +ایک آخری قدم... + +## بلاک چین کی دنیا میں طوفان برپا کریں {#take-the-blockchain-world-by-storm} + +مذاق کر رہا ہوں، آپ ٹیوٹوریل کے آخر تک پہنچ گئے ہیں! + +خلاصہ یہ کہ، ایک NFT منٹر بنا کر، آپ نے کامیابی سے سیکھا کہ: + +- اپنے فرنٹ اینڈ پروجیکٹ کے ذریعے MetaMask سے جڑیں +- اپنے فرنٹ اینڈ سے اسمارٹ کنٹریکٹ طریقوں کو کال کریں +- MetaMask کا استعمال کرتے ہوئے ٹرانزیکشنز پر دستخط کریں + +یقیناً، آپ اپنے والیٹ میں اپنے dApp کے ذریعے منٹ کیے گئے NFTs کو دکھانا چاہیں گے — تو ہمارا فوری ٹیوٹوریل [اپنے NFT کو اپنے والیٹ میں کیسے دیکھیں](https://www.alchemy.com/docs/how-to-view-your-nft-in-your-mobile-wallet) ضرور دیکھیں۔ + +اور، ہمیشہ کی طرح، اگر آپ کے کوئی سوالات ہیں، تو ہم [Alchemy Discord](https://discord.gg/gWuC7zB) میں مدد کے لیے موجود ہیں۔ ہم یہ دیکھنے کے لیے انتظار نہیں کر سکتے کہ آپ اس ٹیوٹوریل کے تصورات کو اپنے مستقبل کے پروجیکٹس پر کیسے لاگو کرتے ہیں! diff --git a/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md new file mode 100644 index 00000000000..496e13470c4 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md @@ -0,0 +1,1354 @@ +--- +title: "Optimism معیاری برج کنٹریکٹ واک تھرو" +description: "Optimism کے لیے معیاری برج کیسے کام کرتا ہے؟ یہ اس طرح کیوں کام کرتا ہے؟" +author: Ori Pomerantz +tags: [ "solidity", "برج", "لیئر 2" ] +skill: intermediate +published: 2022-03-30 +lang: ur-in +--- + +[Optimism](https://www.optimism.io/) ایک [Optimistic Rollup](/developers/docs/scaling/optimistic-rollups/) ہے۔ +Optimistic rollups ٹرانزیکشنز کو Ethereum Mainnet (جسے layer 1 یا L1 بھی کہا جاتا ہے) کے مقابلے میں بہت کم قیمت پر پراسیس کر سکتے ہیں کیونکہ ٹرانزیکشنز کو نیٹ ورک پر ہر نوڈ کے بجائے صرف چند نوڈز کے ذریعے پراسیس کیا جاتا ہے۔ +ایک ہی وقت میں، تمام ڈیٹا L1 پر لکھا جاتا ہے تاکہ Mainnet کی تمام سالمیت اور دستیابی کی ضمانتوں کے ساتھ ہر چیز کو ثابت اور دوبارہ تعمیر کیا جا سکے۔ + +Optimism (یا کسی دوسرے L2) پر L1 اثاثے استعمال کرنے کے لیے، اثاثوں کو [bridged](/bridges/#prerequisites) کرنے کی ضرورت ہے۔ +اس کو حاصل کرنے کا ایک طریقہ یہ ہے کہ صارفین L1 پر اثاثوں (ETH اور [ERC-20 tokens](/developers/docs/standards/tokens/erc-20/) سب سے عام ہیں) کو لاک کریں، اور L2 پر استعمال کرنے کے لیے مساوی اثاثے حاصل کریں۔ +بالآخر، جو بھی ان کے ساتھ ختم ہوتا ہے وہ انہیں واپس L1 پر برج کرنا چاہے گا۔ +ایسا کرتے وقت، اثاثے L2 پر جلا دیے جاتے ہیں اور پھر L1 پر صارف کو واپس جاری کر دیے جاتے ہیں۔ + +یہ وہ طریقہ ہے جس سے [Optimism standard bridge](https://docs.optimism.io/app-developers/bridging/standard-bridge) کام کرتا ہے۔ +اس مضمون میں ہم اس برج کے سورس کوڈ کا جائزہ لیتے ہیں تاکہ یہ دیکھیں کہ یہ کیسے کام کرتا ہے اور اسے اچھی طرح سے لکھے گئے Solidity کوڈ کی مثال کے طور پر مطالعہ کریں۔ + +## کنٹرول فلو {#control-flows} + +برج کے دو اہم فلو ہیں: + +- ڈپازٹ (L1 سے L2 تک) +- واپسی (L2 سے L1 تک) + +### ڈپازٹ فلو {#deposit-flow} + +#### لیئر 1 {#deposit-flow-layer-1} + +1. اگر ERC-20 جمع کر رہے ہیں، تو جمع کنندہ برج کو جمع کی جا رہی رقم خرچ کرنے کی اجازت دیتا ہے +2. جمع کنندہ L1 برج کو کال کرتا ہے (`depositERC20`, `depositERC20To`, `depositETH`, یا `depositETHTo`) +3. L1 برج برجڈ اثاثے کا قبضہ لیتا ہے + - ETH: اثاثہ کال کے حصے کے طور پر جمع کنندہ کے ذریعے منتقل کیا جاتا ہے + - ERC-20: اثاثہ برج کے ذریعے جمع کنندہ کی طرف سے فراہم کردہ الاؤنس کا استعمال کرتے ہوئے خود کو منتقل کیا جاتا ہے +4. L1 برج L2 برج پر `finalizeDeposit` کو کال کرنے کے لیے کراس ڈومین میسج میکانزم کا استعمال کرتا ہے + +#### لیئر 2 {#deposit-flow-layer-2} + +5. L2 برج `finalizeDeposit` کی کال کی تصدیق کرتا ہے کہ یہ جائز ہے: + - کراس ڈومین میسج کنٹریکٹ سے آیا ہے + - اصل میں L1 پر برج سے تھا +6. L2 برج چیک کرتا ہے کہ آیا L2 پر ERC-20 ٹوکن کنٹریکٹ درست ہے: + - L2 کنٹریکٹ رپورٹ کرتا ہے کہ اس کا L1 ہم منصب وہی ہے جہاں سے L1 پر ٹوکن آئے تھے + - L2 کنٹریکٹ رپورٹ کرتا ہے کہ یہ درست انٹرفیس کو سپورٹ کرتا ہے ([using ERC-165](https://eips.ethereum.org/EIPS/eip-165)). +7. اگر L2 کنٹریکٹ درست ہے، تو اسے مناسب ایڈریس پر مناسب تعداد میں ٹوکن منٹ کرنے کے لیے کال کریں۔ اگر نہیں، تو صارف کو L1 پر ٹوکن کا دعویٰ کرنے کی اجازت دینے کے لیے واپسی کا عمل شروع کریں۔ + +### واپسی کا فلو {#withdrawal-flow} + +#### لیئر 2 {#withdrawal-flow-layer-2} + +1. واپس لینے والا L2 برج (`withdraw` یا `withdrawTo`) کو کال کرتا ہے +2. L2 برج `msg.sender` سے تعلق رکھنے والے ٹوکنز کی مناسب تعداد کو جلا دیتا ہے +3. L2 برج کراس ڈومین میسج میکانزم کا استعمال L1 برج پر `finalizeETHWithdrawal` یا `finalizeERC20Withdrawal` کو کال کرنے کے لیے کرتا ہے + +#### لیئر 1 {#withdrawal-flow-layer-1} + +4. L1 برج `finalizeETHWithdrawal` یا `finalizeERC20Withdrawal` کی کال کی تصدیق کرتا ہے کہ یہ جائز ہے: + - کراس ڈومین میسج میکانزم سے آیا ہے + - اصل میں L2 پر برج سے تھا +5. L1 برج مناسب اثاثہ (ETH یا ERC-20) کو مناسب ایڈریس پر منتقل کرتا ہے + +## لیئر 1 کوڈ {#layer-1-code} + +یہ وہ کوڈ ہے جو L1، Ethereum Mainnet پر چلتا ہے۔ + +### IL1ERC20Bridge {#IL1ERC20Bridge} + +[یہ انٹرفیس یہاں بیان کیا گیا ہے](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1ERC20Bridge.sol)۔ +اس میں ERC-20 ٹوکنز کو برج کرنے کے لیے درکار فنکشنز اور تعریفیں شامل ہیں۔ + +```solidity +// SPDX-License-Identifier: MIT +``` + +[Optimism کا زیادہ تر کوڈ MIT لائسنس کے تحت جاری کیا گیا ہے](https://help.optimism.io/hc/en-us/articles/4411908707995-What-software-license-does-Optimism-use-). + +```solidity +pragma solidity >0.5.0 <0.9.0; +``` + +لکھنے کے وقت Solidity کا تازہ ترین ورژن 0.8.12 ہے۔ +جب تک ورژن 0.9.0 جاری نہیں ہو جاتا، ہم نہیں جانتے کہ یہ کوڈ اس کے ساتھ مطابقت رکھتا ہے یا نہیں۔ + +```solidity +/** + * @title IL1ERC20Bridge + */ +interface IL1ERC20Bridge { + /********** + * ایونٹس * + **********/ + + event ERC20DepositInitiated( +``` + +Optimism برج کی اصطلاح میں _ڈپازٹ_ کا مطلب L1 سے L2 میں منتقلی ہے، اور _واپسی_ کا مطلب L2 سے L1 میں منتقلی ہے۔ + +```solidity + address indexed _l1Token, + address indexed _l2Token, +``` + +زیادہ تر معاملات میں L1 پر ERC-20 کا ایڈریس L2 پر مساوی ERC-20 کے ایڈریس کے برابر نہیں ہوتا ہے۔ +[آپ ٹوکن ایڈریس کی فہرست یہاں دیکھ سکتے ہیں](https://static.optimism.io/optimism.tokenlist.json)۔ +`chainId` 1 والا ایڈریس L1 (Mainnet) پر ہے اور `chainId` 10 والا ایڈریس L2 (Optimism) پر ہے۔ +دیگر دو `chainId` قدریں Kovan ٹیسٹ نیٹ ورک (42) اور Optimistic Kovan ٹیسٹ نیٹ ورک (69) کے لیے ہیں۔ + +```solidity + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); +``` + +منتقلی میں نوٹس شامل کرنا ممکن ہے، اس صورت میں انہیں ان ایونٹس میں شامل کیا جاتا ہے جو ان کی رپورٹ کرتے ہیں۔ + +```solidity + event ERC20WithdrawalFinalized( + address indexed _l1Token, + address indexed _l2Token, + address indexed _from, + address _to, + uint256 _amount, + bytes _data + ); +``` + +وہی برج کنٹریکٹ دونوں سمتوں میں منتقلی کو سنبھالتا ہے۔ +L1 برج کے معاملے میں، اس کا مطلب ہے ڈپازٹ کا آغاز اور واپسی کی حتمی شکل۔ + +```solidity + + /******************** + * پبلک فنکشنز * + ********************/ + + /** + * @dev متعلقہ L2 برج کنٹریکٹ کا ایڈریس حاصل کریں۔ + * @return متعلقہ L2 برج کنٹریکٹ کا ایڈریس۔ + */ + function l2TokenBridge() external returns (address); +``` + +اس فنکشن کی واقعی ضرورت نہیں ہے، کیونکہ L2 پر یہ ایک پہلے سے تعینات کنٹریکٹ ہے، لہذا یہ ہمیشہ ایڈریس `0x4200000000000000000000000000000000000010` پر ہوتا ہے۔ +یہاں L2 برج کے ساتھ ہم آہنگی کے لیے ہے، کیونکہ L1 برج کا ایڈریس جاننا معمولی بات نہیں ہے۔ + +```solidity + /** + * @dev L2 پر کالر کے بیلنس میں ERC20 کی رقم جمع کریں۔ + * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں + * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس + * @param _amount جمع کرنے کے لیے ERC20 کی رقم + * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ + * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function depositERC20( + address _l1Token, + address _l2Token, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; +``` + +`_l2Gas` پیرامیٹر L2 گیس کی وہ مقدار ہے جو ٹرانزیکشن خرچ کرنے کی اجازت ہے۔ +[ایک مخصوص (اعلی) حد تک، یہ مفت ہے](https://community.optimism.io/docs/developers/bridge/messaging/#for-l1-%E2%87%92-l2-transactions-2)، لہذا جب تک ERC-20 کنٹریکٹ منٹنگ کے وقت کچھ واقعی عجیب کام نہیں کرتا، یہ کوئی مسئلہ نہیں ہونا چاہئے۔ +یہ فنکشن عام منظر نامے کا خیال رکھتا ہے، جہاں ایک صارف ایک مختلف بلاک چین پر ایک ہی ایڈریس پر اثاثوں کو برج کرتا ہے۔ + +```solidity + /** + * @dev L2 پر وصول کنندہ کے بیلنس میں ERC20 کی رقم جمع کریں۔ + * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں + * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس + * @param _to L2 ایڈریس جس پر واپسی کریڈٹ کی جائے گی۔ + * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ + * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ + * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function depositERC20To( + address _l1Token, + address _l2Token, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) external; +``` + +یہ فنکشن تقریباً `depositERC20` جیسا ہی ہے، لیکن یہ آپ کو ERC-20 کو ایک مختلف ایڈریس پر بھیجنے دیتا ہے۔ + +```solidity + /************************* + * کراس چین فنکشنز * + *************************/ + + /** + * @dev L2 سے L1 تک کی واپسی کو مکمل کریں، اور فنڈز کو + * L1 ERC20 ٹوکن کے وصول کنندہ کے بیلنس میں کریڈٹ کریں۔ + * اگر L2 سے شروع کی گئی واپسی کو حتمی شکل نہیں دی گئی ہے تو یہ کال ناکام ہو جائے گی۔ + * + * @param _l1Token L1 ٹوکن کا ایڈریس جس کے لیے finalizeWithdrawal کرنا ہے۔ + * @param _l2Token L2 ٹوکن کا ایڈریس جہاں سے واپسی شروع کی گئی تھی۔ + * @param _from منتقلی شروع کرنے والا L2 ایڈریس۔ + * @param _to L1 ایڈریس جس پر واپسی کریڈٹ کی جائے گی۔ + * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ + * @param _data L2 پر بھیجنے والے کی طرف سے فراہم کردہ ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} +``` + +Optimism میں واپسی (اور L2 سے L1 تک کے دیگر پیغامات) دو مرحلوں کا عمل ہے: + +1. L2 پر ایک ابتدائی ٹرانزیکشن۔ +2. L1 پر ایک حتمی یا دعویٰ کرنے والی ٹرانزیکشن۔ + یہ ٹرانزیکشن L2 ٹرانزیکشن کے لیے [fault challenge period](https://community.optimism.io/docs/how-optimism-works/#fault-proofs) کے ختم ہونے کے بعد ہونا ضروری ہے۔ + +### IL1StandardBridge {#il1standardbridge} + +[یہ انٹرفیس یہاں بیان کیا گیا ہے](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/IL1StandardBridge.sol)۔ +اس فائل میں ETH کے لیے ایونٹ اور فنکشن کی تعریفیں ہیں۔ +یہ تعریفیں ERC-20 کے لیے اوپر `IL1ERC20Bridge` میں بیان کردہ تعریفوں سے بہت ملتی جلتی ہیں۔ + +برج انٹرفیس کو دو فائلوں کے درمیان تقسیم کیا گیا ہے کیونکہ کچھ ERC-20 ٹوکنز کو اپنی مرضی کے مطابق پروسیسنگ کی ضرورت ہوتی ہے اور معیاری برج کے ذریعے انہیں ہینڈل نہیں کیا جا سکتا۔ +اس طرح کسٹم برج جو ایسے ٹوکن کو ہینڈل کرتا ہے وہ `IL1ERC20Bridge` کو لاگو کر سکتا ہے اور اسے ETH کو بھی برج کرنے کی ضرورت نہیں ہوتی ہے۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +import "./IL1ERC20Bridge.sol"; + +/** + * @title IL1StandardBridge + */ +interface IL1StandardBridge is IL1ERC20Bridge { + /********** + * ایونٹس * + **********/ + event ETHDepositInitiated( + address indexed _from, + address indexed _to, + uint256 _amount, + bytes _data + ); +``` + +یہ ایونٹ تقریباً ERC-20 ورژن (`ERC20DepositInitiated`) جیسا ہی ہے، سوائے L1 اور L2 ٹوکن ایڈریس کے۔ +دیگر ایونٹس اور فنکشنز کے لیے بھی یہی سچ ہے۔ + +```solidity + event ETHWithdrawalFinalized( + . + . + . + ); + + /******************** + * پبلک فنکشنز * + ********************/ + + /** + * @dev L2 پر کالر کے بیلنس میں ETH کی رقم جمع کریں۔ + . + . + . + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; + + /** + * @dev L2 پر وصول کنندہ کے بیلنس میں ETH کی رقم جمع کریں۔ + . + . + . + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable; + + /************************* + * کراس چین فنکشنز * + *************************/ + + /** + * @dev L2 سے L1 تک کی واپسی کو مکمل کریں، اور فنڈز کو + * L1 ETH ٹوکن کے وصول کنندہ کے بیلنس میں کریڈٹ کریں۔ چونکہ صرف xDomainMessenger ہی اس فنکشن کو کال کر سکتا ہے، اس لیے اسے + * واپسی کے حتمی ہونے سے پہلے کبھی کال نہیں کیا جائے گا۔ + . + . + . + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external; +} +``` + +### CrossDomainEnabled {#crossdomainenabled} + +[یہ کنٹریکٹ](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/CrossDomainEnabled.sol) دونوں برجز ([L1](#the-l1-bridge-contract) اور [L2](#the-l2-bridge-contract)) کے ذریعے وراثت میں ملا ہے تاکہ دوسری لیئر کو پیغامات بھیج سکیں۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity >0.5.0 <0.9.0; + +/* انٹرفیس امپورٹس */ +import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; +``` + +[یہ انٹرفیس](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/bridge/ICrossDomainMessenger.sol) کنٹریکٹ کو بتاتا ہے کہ کراس ڈومین میسنجر کا استعمال کرتے ہوئے دوسری لیئر کو پیغامات کیسے بھیجیں۔ +یہ کراس ڈومین میسنجر ایک بالکل مختلف نظام ہے، اور اس کا اپنا مضمون ہونا چاہیے، جو مجھے امید ہے کہ مستقبل میں لکھوں گا۔ + +```solidity +/** + * @title CrossDomainEnabled + * @dev کراس ڈومین کمیونیکیشن کرنے والے کنٹریکٹس کے لیے ہیلپر کنٹریکٹ + * + * استعمال شدہ کمپائلر: وراثت میں ملنے والے کنٹریکٹ کے ذریعے بیان کیا گیا ہے + */ +contract CrossDomainEnabled { + /************* + * متغیرات * + *************/ + + // دوسرے ڈومین سے پیغامات بھیجنے اور وصول کرنے کے لیے استعمال ہونے والا میسنجر کنٹریکٹ۔ + address public messenger; + + /*************** + * کنسٹرکٹر * + ***************/ + + /** + * @param _messenger موجودہ لیئر پر CrossDomainMessenger کا ایڈریس۔ + */ + constructor(address _messenger) { + messenger = _messenger; + } +``` + +ایک پیرامیٹر جو کنٹریکٹ کو جاننے کی ضرورت ہے، وہ اس لیئر پر کراس ڈومین میسنجر کا ایڈریس ہے۔ +یہ پیرامیٹر ایک بار کنسٹرکٹر میں سیٹ کیا جاتا ہے، اور کبھی تبدیل نہیں ہوتا ہے۔ + +```solidity + + /********************** + * فنکشن موڈیفائرز * + **********************/ + + /** + * نافذ کرتا ہے کہ ترمیم شدہ فنکشن صرف ایک مخصوص کراس ڈومین اکاؤنٹ کے ذریعے کال کیا جا سکتا ہے۔ + * @param _sourceDomainAccount اصل ڈومین پر واحد اکاؤنٹ جو + * اس فنکشن کو کال کرنے کے لیے مستند ہے۔ + */ + modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { +``` + +کراس ڈومین میسجنگ بلاک چین پر کسی بھی کنٹریکٹ کے ذریعے قابل رسائی ہے جہاں یہ چل رہا ہے (یا تو Ethereum mainnet یا Optimism)۔ +لیکن ہمیں ہر طرف برج کی ضرورت ہے تاکہ وہ _صرف_ کچھ پیغامات پر بھروسہ کرے اگر وہ دوسری طرف کے برج سے آتے ہیں۔ + +```solidity + require( + msg.sender == address(getCrossDomainMessenger()), + "OVM_XCHAIN: میسنجر کنٹریکٹ غیر مستند" + ); +``` + +صرف مناسب کراس ڈومین میسنجر (`messenger`, جیسا کہ آپ نیچے دیکھتے ہیں) سے آنے والے پیغامات پر بھروسہ کیا جا سکتا ہے۔ + +```solidity + + require( + getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, + "OVM_XCHAIN: کراس ڈومین پیغام کا غلط بھیجنے والا" + ); +``` + +کراس ڈومین میسنجر جس طرح سے دوسری لیئر کے ساتھ پیغام بھیجنے والے ایڈریس کو فراہم کرتا ہے وہ ہے [ `.xDomainMessageSender()` فنکشن](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1CrossDomainMessenger.sol#L122-L128)۔ +جب تک اسے اس ٹرانزیکشن میں کال کیا جاتا ہے جو پیغام کے ذریعے شروع کی گئی تھی، یہ یہ معلومات فراہم کر سکتا ہے۔ + +ہمیں یہ یقینی بنانا ہوگا کہ ہمیں موصول ہونے والا پیغام دوسرے برج سے آیا ہے۔ + +```solidity + _; + } + + /********************** + * اندرونی فنکشنز * + **********************/ + + /** + * میسنجر حاصل کرتا ہے، عام طور پر اسٹوریج سے۔ یہ فنکشن اس صورت میں ظاہر ہوتا ہے جب کسی چائلڈ کنٹریکٹ + * کو اوور رائڈ کرنے کی ضرورت ہو۔ + * @return کراس ڈومین میسنجر کنٹریکٹ کا ایڈریس جو استعمال کیا جانا چاہئے۔ + */ + function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { + return ICrossDomainMessenger(messenger); + } +``` + +یہ فنکشن کراس ڈومین میسنجر کو واپس کرتا ہے۔ +ہم متغیر `messenger` کے بجائے ایک فنکشن استعمال کرتے ہیں تاکہ اس سے وراثت میں ملنے والے کنٹریکٹس کو ایک الگورتھم استعمال کرنے کی اجازت دی جا سکے تاکہ یہ بتایا جا سکے کہ کون سا کراس ڈومین میسنجر استعمال کرنا ہے۔ + +```solidity + + /** + * دوسرے ڈومین پر ایک اکاؤنٹ کو ایک پیغام بھیجتا ہے + * @param _crossDomainTarget منزل کے ڈومین پر مطلوبہ وصول کنندہ + * @param _message ہدف کو بھیجنے کے لیے ڈیٹا (عام طور پر ایک فنکشن کے لیے کال ڈیٹا + * `onlyFromCrossDomainAccount()` کے ساتھ) + * @param _gasLimit ہدف ڈومین پر پیغام کی رسید کے لیے گیس کی حد۔ + */ + function sendCrossDomainMessage( + address _crossDomainTarget, + uint32 _gasLimit, + bytes memory _message +``` + +آخر میں، وہ فنکشن جو دوسری لیئر کو ایک پیغام بھیجتا ہے۔ + +```solidity + ) internal { + // slither-disable-next-line reentrancy-events, reentrancy-benign +``` + +[Slither](https://github.com/crytic/slither) ایک جامد تجزیہ کار ہے جسے Optimism ہر کنٹریکٹ پر کمزوریوں اور دیگر ممکنہ مسائل کو تلاش کرنے کے لیے چلاتا ہے۔ +اس معاملے میں، مندرجہ ذیل لائن دو کمزوریوں کو متحرک کرتی ہے: + +1. [Reentrancy events](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3) +2. [Benign reentrancy](https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-2) + +```solidity + getCrossDomainMessenger().sendMessage(_crossDomainTarget, _message, _gasLimit); + } +} +``` + +اس معاملے میں ہم reentrancy کے بارے میں فکر مند نہیں ہیں کیونکہ ہم جانتے ہیں کہ `getCrossDomainMessenger()` ایک قابل اعتماد ایڈریس واپس کرتا ہے، چاہے Slither کو یہ جاننے کا کوئی طریقہ نہ ہو۔ + +### L1 برج کنٹریکٹ {#the-l1-bridge-contract} + +[اس کنٹریکٹ کا سورس کوڈ یہاں ہے](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L1/messaging/L1StandardBridge.sol)۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; +``` + +انٹرفیس دوسرے کنٹریکٹس کا حصہ ہو سکتے ہیں، لہذا انہیں Solidity ورژن کی ایک وسیع رینج کو سپورٹ کرنا ہوگا۔ +لیکن برج خود ہمارا کنٹریکٹ ہے، اور ہم اس بارے میں سخت ہو سکتے ہیں کہ یہ کون سا Solidity ورژن استعمال کرتا ہے۔ + +```solidity +/* انٹرفیس امپورٹس */ +import { IL1StandardBridge } from "./IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; +``` + +[IL1ERC20Bridge](#IL1ERC20Bridge) اور [IL1StandardBridge](#IL1StandardBridge) اوپر بیان کیے گئے ہیں۔ + +```solidity +import { IL2ERC20Bridge } from "../../L2/messaging/IL2ERC20Bridge.sol"; +``` + +[یہ انٹرفیس](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) ہمیں L2 پر معیاری برج کو کنٹرول کرنے کے لیے پیغامات بنانے دیتا ہے۔ + +```solidity +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +``` + +[یہ انٹرفیس](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) ہمیں ERC-20 کنٹریکٹس کو کنٹرول کرنے دیتا ہے۔ +[آپ اس کے بارے میں مزید یہاں پڑھ سکتے ہیں](/developers/tutorials/erc20-annotated-code/#the-interface)۔ + +```solidity +/* لائبریری امپورٹس */ +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +``` + +[جیسا کہ اوپر بیان کیا گیا ہے](#crossdomainenabled)، یہ کنٹریکٹ انٹر لیئر میسجنگ کے لیے استعمال ہوتا ہے۔ + +```solidity +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; +``` + +[`Lib_PredeployAddresses`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/libraries/constants/Lib_PredeployAddresses.sol) میں L2 کنٹریکٹس کے ایڈریس ہیں جن کا ہمیشہ ایک ہی ایڈریس ہوتا ہے۔ اس میں L2 پر معیاری برج شامل ہے۔ + +```solidity +import { Address } from "@openzeppelin/contracts/utils/Address.sol"; +``` + +[OpenZeppelin کی ایڈریس یوٹیلیٹیز](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol)۔ اس کا استعمال کنٹریکٹ ایڈریس اور بیرونی طور پر ملکیت والے اکاؤنٹس (EOA) سے تعلق رکھنے والوں کے درمیان فرق کرنے کے لیے کیا جاتا ہے۔ + +نوٹ کریں کہ یہ ایک بہترین حل نہیں ہے، کیونکہ براہ راست کالز اور کنٹریکٹ کے کنسٹرکٹر سے کی گئی کالز کے درمیان فرق کرنے کا کوئی طریقہ نہیں ہے، لیکن کم از کم یہ ہمیں کچھ عام صارف کی غلطیوں کی نشاندہی کرنے اور انہیں روکنے دیتا ہے۔ + +```solidity +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +``` + +[ERC-20 معیار](https://eips.ethereum.org/EIPS/eip-20) ایک کنٹریکٹ کے لیے ناکامی کی رپورٹ کرنے کے دو طریقے سپورٹ کرتا ہے: + +1. واپس کریں +2. `false` واپس کریں + +دونوں صورتوں کو ہینڈل کرنے سے ہمارا کوڈ مزید پیچیدہ ہو جائے گا، لہذا اس کے بجائے ہم [OpenZeppelin کا `SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) استعمال کرتے ہیں، جو یقینی بناتا ہے کہ [تمام ناکامیوں کے نتیجے میں ایک ریورٹ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L96) ہو۔ + +```solidity +/** + * @title L1StandardBridge + * @dev L1 ETH اور ERC20 برج ایک کنٹریکٹ ہے جو جمع شدہ L1 فنڈز اور + * L2 پر استعمال ہونے والے معیاری ٹوکنز کو اسٹور کرتا ہے۔ یہ ایک متعلقہ L2 برج کو سنکرونائز کرتا ہے، اسے ڈپازٹ کے بارے میں مطلع کرتا ہے + * اور نئی حتمی واپسیوں کے لیے اسے سنتا ہے۔ + * + */ +contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { + using SafeERC20 for IERC20; +``` + +یہ لائن ہے کہ ہم `IERC20` انٹرفیس استعمال کرتے وقت ہر بار `SafeERC20` ریپر استعمال کرنے کی وضاحت کیسے کرتے ہیں۔ + +```solidity + + /******************************** + * بیرونی کنٹریکٹ کے حوالے * + ********************************/ + + address public l2TokenBridge; +``` + +[L2StandardBridge](#the-l2-bridge-contract) کا ایڈریس۔ + +```solidity + + // L1 ٹوکن کو L2 ٹوکن سے جمع شدہ L1 ٹوکن کے بیلنس پر میپ کرتا ہے + mapping(address => mapping(address => uint256)) public deposits; +``` + +اس طرح کی ایک ڈبل [mapping](https://www.tutorialspoint.com/solidity/solidity_mappings.htm) وہ طریقہ ہے جس سے آپ ایک [دو جہتی اسپارس ارے](https://en.wikipedia.org/wiki/Sparse_matrix) کی تعریف کرتے ہیں۔ +اس ڈیٹا ڈھانچے میں قدروں کی شناخت `deposit[L1 token addr][L2 token addr]` کے طور پر کی جاتی ہے۔ +پہلے سے طے شدہ قدر صفر ہے۔ +صرف وہ سیلز جو ایک مختلف قدر پر سیٹ ہیں اسٹوریج میں لکھے جاتے ہیں۔ + +```solidity + + /*************** + * کنسٹرکٹر * + ***************/ + + // یہ کنٹریکٹ ایک پراکسی کے پیچھے رہتا ہے، لہذا کنسٹرکٹر پیرامیٹرز استعمال نہیں ہوں گے۔ + constructor() CrossDomainEnabled(address(0)) {} +``` + +اسٹوریج میں تمام متغیرات کو کاپی کیے بغیر اس کنٹریکٹ کو اپ گریڈ کرنے کے قابل ہونا چاہتے ہیں۔ +ایسا کرنے کے لیے ہم ایک [`Proxy`](https://docs.openzeppelin.com/contracts/3.x/api/proxy) کا استعمال کرتے ہیں، ایک کنٹریکٹ جو [`delegatecall`](https://solidity-by-example.org/delegatecall/) کا استعمال کرتا ہے تاکہ کالز کو ایک علیحدہ کنٹریکٹ میں منتقل کیا جا سکے جس کا ایڈریس پراکسی کنٹریکٹ کے ذریعے اسٹور کیا جاتا ہے (جب آپ اپ گریڈ کرتے ہیں تو آپ پراکسی کو اس ایڈریس کو تبدیل کرنے کے لیے کہتے ہیں)۔ +جب آپ `delegatecall` استعمال کرتے ہیں تو اسٹوریج _کالنگ_ کنٹریکٹ کا اسٹوریج رہتا ہے، لہذا تمام کنٹریکٹ اسٹیٹ متغیرات کی قدریں غیر متاثر رہتی ہیں۔ + +اس پیٹرن کا ایک اثر یہ ہے کہ کنٹریکٹ کا اسٹوریج جو `delegatecall` کا _کال کیا گیا_ ہے استعمال نہیں ہوتا ہے اور اس لیے اسے بھیجی گئی کنسٹرکٹر قدریں کوئی معنی نہیں رکھتیں۔ +یہی وجہ ہے کہ ہم `CrossDomainEnabled` کنسٹرکٹر کو ایک بے معنی قدر فراہم کر سکتے ہیں۔ +یہی وجہ ہے کہ نیچے دی گئی شروعات کنسٹرکٹر سے الگ ہے۔ + +```solidity + /****************** + * شروعات * + ******************/ + + /** + * @param _l1messenger کراس چین کمیونیکیشنز کے لیے استعمال ہونے والا L1 میسنجر ایڈریس۔ + * @param _l2TokenBridge L2 معیاری برج ایڈریس۔ + */ + // slither-disable-next-line external-function +``` + +یہ [Slither ٹیسٹ](https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external) ان فنکشنز کی نشاندہی کرتا ہے جو کنٹریکٹ کوڈ سے کال نہیں کیے جاتے ہیں اور اس لیے انہیں `public` کے بجائے `external` قرار دیا جا سکتا ہے۔ +`external` فنکشنز کی گیس کی لاگت کم ہو سکتی ہے، کیونکہ انہیں کال ڈیٹا میں پیرامیٹرز فراہم کیے جا سکتے ہیں۔ +`public` قرار دیے گئے فنکشنز کو کنٹریکٹ کے اندر سے قابل رسائی ہونا چاہیے۔ +کنٹریکٹس اپنے کال ڈیٹا میں ترمیم نہیں کر سکتے، لہذا پیرامیٹرز میموری میں ہونے چاہئیں۔ +جب ایسے فنکشن کو بیرونی طور پر کال کیا جاتا ہے، تو کال ڈیٹا کو میموری میں کاپی کرنا ضروری ہوتا ہے، جس میں گیس خرچ ہوتی ہے۔ +اس معاملے میں فنکشن صرف ایک بار کال کیا جاتا ہے، لہذا نااہلی ہمارے لیے کوئی معنی نہیں رکھتی۔ + +```solidity + function initialize(address _l1messenger, address _l2TokenBridge) public { + require(messenger == address(0), "کنٹریکٹ پہلے ہی شروع کیا جا چکا ہے۔"); +``` + +`initialize` فنکشن کو صرف ایک بار کال کیا جانا چاہیے۔ +اگر L1 کراس ڈومین میسنجر یا L2 ٹوکن برج کا ایڈریس تبدیل ہوتا ہے، تو ہم ایک نیا پراکسی اور ایک نیا برج بناتے ہیں جو اسے کال کرتا ہے۔ +یہ ہونے کا امکان نہیں ہے سوائے اس کے کہ جب پورا نظام اپ گریڈ کیا جائے، جو کہ ایک بہت ہی نایاب واقعہ ہے۔ + +نوٹ کریں کہ اس فنکشن میں کوئی ایسا میکانزم نہیں ہے جو اس بات کو محدود کرے کہ اسے _کون_ کال کر سکتا ہے۔ +اس کا مطلب ہے کہ نظریاتی طور پر ایک حملہ آور اس وقت تک انتظار کر سکتا ہے جب تک کہ ہم پراکسی اور برج کا پہلا ورژن تعینات نہ کر دیں اور پھر [front-run](https://solidity-by-example.org/hacks/front-running/) کریں تاکہ جائز صارف سے پہلے `initialize` فنکشن تک پہنچ سکیں۔ لیکن اسے روکنے کے دو طریقے ہیں: + +1. اگر کنٹریکٹس براہ راست EOA کے ذریعے نہیں بلکہ [ایک ٹرانزیکشن میں جس میں دوسرا کنٹریکٹ انہیں بناتا ہے](https://medium.com/upstate-interactive/creating-a-contract-with-a-smart-contract-bdb67c5c8595) تعینات کیے گئے ہیں تو پورا عمل ایٹمی ہو سکتا ہے، اور کسی بھی دوسری ٹرانزیکشن کے عملدرآمد سے پہلے ختم ہو سکتا ہے۔ +2. اگر `initialize` کی جائز کال ناکام ہو جاتی ہے تو نئے بنائے گئے پراکسی اور برج کو نظر انداز کرنا اور نئے بنانا ہمیشہ ممکن ہوتا ہے۔ + +```solidity + messenger = _l1messenger; + l2TokenBridge = _l2TokenBridge; + } +``` + +یہ وہ دو پیرامیٹرز ہیں جو برج کو جاننے کی ضرورت ہے۔ + +```solidity + + /************** + * جمع کرنا * + **************/ + + /** @dev موڈیفائر جس میں بھیجنے والے کو EOA ہونا ضروری ہے۔ اس چیک کو ایک بدنیتی پر مبنی + * کنٹریکٹ کے ذریعے initcode کے ذریعے بائی پاس کیا جا سکتا ہے، لیکن یہ اس صارف کی غلطی کا خیال رکھتا ہے جس سے ہم بچنا چاہتے ہیں۔ + */ + modifier onlyEOA() { + // کنٹریکٹس سے ڈپازٹ روکنے کے لیے استعمال کیا جاتا ہے (حادثاتی طور پر کھوئے ہوئے ٹوکن سے بچنے کے لیے) + require(!Address.isContract(msg.sender), "اکاؤنٹ EOA نہیں ہے"); + _; + } +``` + +یہی وجہ ہے کہ ہمیں OpenZeppelin کی `Address` یوٹیلیٹیز کی ضرورت تھی۔ + +```solidity + /** + * @dev اس فنکشن کو بغیر کسی ڈیٹا کے + * L2 پر کالر کے بیلنس میں ETH کی رقم جمع کرنے کے لیے کال کیا جا سکتا ہے۔ + * چونکہ وصول کرنے والا فنکشن ڈیٹا نہیں لیتا، لہذا ایک قدامت پسند + * پہلے سے طے شدہ رقم L2 کو بھیجی جاتی ہے۔ + */ + receive() external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes("")); + } +``` + +یہ فنکشن جانچ کے مقاصد کے لیے موجود ہے۔ +نوٹ کریں کہ یہ انٹرفیس کی تعریفوں میں ظاہر نہیں ہوتا - یہ عام استعمال کے لیے نہیں ہے۔ + +```solidity + /** + * @inheritdoc IL1StandardBridge + */ + function depositETH(uint32 _l2Gas, bytes calldata _data) external payable onlyEOA { + _initiateETHDeposit(msg.sender, msg.sender, _l2Gas, _data); + } + + /** + * @inheritdoc IL1StandardBridge + */ + function depositETHTo( + address _to, + uint32 _l2Gas, + bytes calldata _data + ) external payable { + _initiateETHDeposit(msg.sender, _to, _l2Gas, _data); + } +``` + +یہ دو فنکشنز `_initiateETHDeposit` کے ارد گرد ریپر ہیں، وہ فنکشن جو اصل ETH ڈپازٹ کو ہینڈل کرتا ہے۔ + +```solidity + /** + * @dev ETH کو اسٹور کرکے اور L2 ETH گیٹ وے کو + * ڈپازٹ کے بارے میں مطلع کرکے ڈپازٹ کے لیے منطق انجام دیتا ہے۔ + * @param _from L1 پر ڈپازٹ نکالنے کے لیے اکاؤنٹ۔ + * @param _to L2 پر ڈپازٹ دینے کے لیے اکاؤنٹ۔ + * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ + * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function _initiateETHDeposit( + address _from, + address _to, + uint32 _l2Gas, + bytes memory _data + ) internal { + // finalizeDeposit کال کے لیے کال ڈیٹا تعمیر کریں + bytes memory message = abi.encodeWithSelector( +``` + +کراس ڈومین پیغامات جس طرح کام کرتے ہیں وہ یہ ہے کہ منزل کا کنٹریکٹ پیغام کے ساتھ اس کے کال ڈیٹا کے طور پر کال کیا جاتا ہے۔ +Solidity کنٹریکٹس ہمیشہ اپنے کال ڈیٹا کی تشریح +[ABI وضاحتوں](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html) کے مطابق کرتے ہیں۔ +Solidity فنکشن [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#abi-encoding-and-decoding-functions) وہ کال ڈیٹا بناتا ہے۔ + +```solidity + IL2ERC20Bridge.finalizeDeposit.selector, + address(0), + Lib_PredeployAddresses.OVM_ETH, + _from, + _to, + msg.value, + _data + ); +``` + +یہاں پیغام یہ ہے کہ ان پیرامیٹرز کے ساتھ [`finalizeDeposit` فنکشن](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol#L141-L148) کو کال کریں: + +| پیرامیٹر | قدر | مطلب | +| ------------------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| \_l1Token | address(0) | L1 پر ETH (جو کہ ERC-20 ٹوکن نہیں ہے) کے لیے کھڑے ہونے کی خاص قدر | +| \_l2Token | Lib_PredeployAddresses.OVM_ETH | Optimism پر ETH کا انتظام کرنے والا L2 کنٹریکٹ، `0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000` (یہ کنٹریکٹ صرف اندرونی Optimism استعمال کے لیے ہے) | +| \_from | \_from | L1 پر وہ ایڈریس جو ETH بھیجتا ہے | +| \_to | \_to | L2 پر وہ ایڈریس جو ETH وصول کرتا ہے | +| رقم | msg.value | بھیجے گئے wei کی رقم (جو پہلے ہی برج کو بھیجی جا چکی ہے) | +| \_data | \_data | ڈپازٹ کے ساتھ منسلک کرنے کے لیے اضافی ڈیٹا | + +```solidity + // L2 میں کال ڈیٹا بھیجیں + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); +``` + +کراس ڈومین میسنجر کے ذریعے پیغام بھیجیں۔ + +```solidity + // slither-disable-next-line reentrancy-events + emit ETHDepositInitiated(_from, _to, msg.value, _data); + } +``` + +اس منتقلی کے بارے میں سننے والی کسی بھی وکندریقرت ایپلیکیشن کو مطلع کرنے کے لیے ایک ایونٹ خارج کریں۔ + +```solidity + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20( + . + . + . + ) external virtual onlyEOA { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, msg.sender, _amount, _l2Gas, _data); + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function depositERC20To( + . + . + . + ) external virtual { + _initiateERC20Deposit(_l1Token, _l2Token, msg.sender, _to, _amount, _l2Gas, _data); + } +``` + +یہ دو فنکشنز `_initiateERC20Deposit` کے ارد گرد ریپر ہیں، وہ فنکشن جو اصل ERC-20 ڈپازٹ کو ہینڈل کرتا ہے۔ + +```solidity + /** + * @dev L2 جمع شدہ ٹوکن + * کنٹریکٹ کو ڈپازٹ کے بارے میں مطلع کرکے اور L1 فنڈز کو لاک کرنے کے لیے ایک ہینڈلر کو کال کرکے ڈپازٹ کے لیے منطق انجام دیتا ہے۔ (مثلاً، transferFrom) + * + * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں + * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس + * @param _from L1 پر ڈپازٹ نکالنے کے لیے اکاؤنٹ + * @param _to L2 پر ڈپازٹ دینے کے لیے اکاؤنٹ + * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ + * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ + * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function _initiateERC20Deposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l2Gas, + bytes calldata _data + ) internal { +``` + +یہ فنکشن اوپر `_initiateETHDeposit` سے ملتا جلتا ہے، چند اہم فرق کے ساتھ۔ +پہلا فرق یہ ہے کہ یہ فنکشن ٹوکن ایڈریس اور منتقل کرنے کی رقم پیرامیٹرز کے طور پر وصول کرتا ہے۔ +ETH کے معاملے میں برج کو کال میں پہلے ہی برج اکاؤنٹ (`msg.value`) میں اثاثے کی منتقلی شامل ہے۔ + +```solidity + // جب L1 پر ڈپازٹ شروع کیا جاتا ہے، تو L1 برج فنڈز کو مستقبل + // کی واپسیوں کے لیے خود کو منتقل کرتا ہے۔ safeTransferFrom یہ بھی چیک کرتا ہے کہ آیا کنٹریکٹ میں کوڈ ہے، لہذا یہ ناکام ہو جائے گا اگر + // _from ایک EOA یا address(0) ہے۔ + // slither-disable-next-line reentrancy-events, reentrancy-benign + IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount); +``` + +ERC-20 ٹوکن کی منتقلی ETH سے ایک مختلف عمل کی پیروی کرتی ہے: + +1. صارف (`_from`) برج کو مناسب ٹوکن منتقل کرنے کی اجازت دیتا ہے۔ +2. صارف برج کو ٹوکن کنٹریکٹ کے ایڈریس، رقم وغیرہ کے ساتھ کال کرتا ہے۔ +3. برج ڈپازٹ کے عمل کے حصے کے طور پر ٹوکن (خود کو) منتقل کرتا ہے۔ + +پہلا قدم آخری دو سے الگ ٹرانزیکشن میں ہو سکتا ہے۔ +تاہم، فرنٹ رننگ کوئی مسئلہ نہیں ہے کیونکہ دو فنکشنز جو `_initiateERC20Deposit` (`depositERC20` اور `depositERC20To`) کو کال کرتے ہیں وہ اس فنکشن کو صرف `msg.sender` کے ساتھ `_from` پیرامیٹر کے طور پر کال کرتے ہیں۔ + +```solidity + // _l2Token.finalizeDeposit(_to, _amount) کے لیے کال ڈیٹا تعمیر کریں + bytes memory message = abi.encodeWithSelector( + IL2ERC20Bridge.finalizeDeposit.selector, + _l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + + // L2 میں کال ڈیٹا بھیجیں + // slither-disable-next-line reentrancy-events, reentrancy-benign + sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); + + // slither-disable-next-line reentrancy-benign + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] + _amount; +``` + +جمع شدہ ٹوکن کی رقم `deposits` ڈیٹا ڈھانچے میں شامل کریں۔ +L2 پر متعدد ایڈریس ہو سکتے ہیں جو ایک ہی L1 ERC-20 ٹوکن کے مطابق ہوں، لہذا ڈپازٹ کا ٹریک رکھنے کے لیے برج کے L1 ERC-20 ٹوکن کے بیلنس کا استعمال کافی نہیں ہے۔ + +```solidity + + // slither-disable-next-line reentrancy-events + emit ERC20DepositInitiated(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + /************************* + * کراس چین فنکشنز * + *************************/ + + /** + * @inheritdoc IL1StandardBridge + */ + function finalizeETHWithdrawal( + address _from, + address _to, + uint256 _amount, + bytes calldata _data +``` + +L2 برج L2 کراس ڈومین میسنجر کو ایک پیغام بھیجتا ہے جس کی وجہ سے L1 کراس ڈومین میسنجر اس فنکشن کو کال کرتا ہے (ایک بار جب [وہ ٹرانزیکشن جو پیغام کو حتمی شکل دیتا ہے](https://community.optimism.io/docs/developers/bridge/messaging/#fees-for-l2-%E2%87%92-l1-transactions) L1 پر جمع ہو جاتا ہے، یقیناً)۔ + +```solidity + ) external onlyFromCrossDomainAccount(l2TokenBridge) { +``` + +یقینی بنائیں کہ یہ ایک _جائز_ پیغام ہے، جو کراس ڈومین میسنجر سے آرہا ہے اور L2 ٹوکن برج سے شروع ہو رہا ہے۔ +یہ فنکشن برج سے ETH نکالنے کے لیے استعمال ہوتا ہے، لہذا ہمیں یہ یقینی بنانا ہوگا کہ اسے صرف مجاز کالر کے ذریعے ہی کال کیا جائے۔ + +```solidity + // slither-disable-next-line reentrancy-events + (bool success, ) = _to.call{ value: _amount }(new bytes(0)); +``` + +ETH منتقل کرنے کا طریقہ یہ ہے کہ وصول کنندہ کو `msg.value` میں wei کی رقم کے ساتھ کال کریں۔ + +```solidity + require(success, "TransferHelper::safeTransferETH: ETH منتقلی ناکام"); + + // slither-disable-next-line reentrancy-events + emit ETHWithdrawalFinalized(_from, _to, _amount, _data); +``` + +واپسی کے بارے میں ایک ایونٹ خارج کریں۔ + +```solidity + } + + /** + * @inheritdoc IL1ERC20Bridge + */ + function finalizeERC20Withdrawal( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data + ) external onlyFromCrossDomainAccount(l2TokenBridge) { +``` + +یہ فنکشن اوپر `finalizeETHWithdrawal` سے ملتا جلتا ہے، ERC-20 ٹوکنز کے لیے ضروری تبدیلیوں کے ساتھ۔ + +```solidity + deposits[_l1Token][_l2Token] = deposits[_l1Token][_l2Token] - _amount; +``` + +`deposits` ڈیٹا ڈھانچے کو اپ ڈیٹ کریں۔ + +```solidity + + // جب L1 پر واپسی کو حتمی شکل دی جاتی ہے، تو L1 برج فنڈز کو واپس لینے والے کو منتقل کرتا ہے + // slither-disable-next-line reentrancy-events + IERC20(_l1Token).safeTransfer(_to, _amount); + + // slither-disable-next-line reentrancy-events + emit ERC20WithdrawalFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); + } + + + /***************************** + * عارضی - ETH کی منتقلی * + *****************************/ + + /** + * @dev اکاؤنٹ میں ETH بیلنس شامل کرتا ہے۔ اس کا مقصد ETH + * کو پرانے گیٹ وے سے نئے گیٹ وے میں منتقل کرنے کی اجازت دینا ہے۔ + * نوٹ: یہ صرف ایک اپ گریڈ کے لیے چھوڑ دیا گیا ہے تاکہ ہم پرانے کنٹریکٹ سے + * منتقل شدہ ETH وصول کر سکیں + */ + function donateETH() external payable {} +} +``` + +برج کا ایک پہلے کا نفاذ تھا۔ +جب ہم نفاذ سے اس کی طرف منتقل ہوئے، تو ہمیں تمام اثاثے منتقل کرنے پڑے۔ +ERC-20 ٹوکن صرف منتقل کیے جا سکتے ہیں۔ +تاہم، ایک کنٹریکٹ میں ETH منتقل کرنے کے لیے آپ کو اس کنٹریکٹ کی منظوری کی ضرورت ہے، جو کہ `donateETH` ہمیں فراہم کرتا ہے۔ + +## L2 پر ERC-20 ٹوکنز {#erc-20-tokens-on-l2} + +ایک ERC-20 ٹوکن کو معیاری برج میں فٹ ہونے کے لیے، اسے معیاری برج، اور _صرف_ معیاری برج کو ٹوکن منٹ کرنے کی اجازت دینی ہوگی۔ +یہ ضروری ہے کیونکہ برجز کو یہ یقینی بنانا ہوگا کہ Optimism پر گردش کرنے والے ٹوکنز کی تعداد L1 برج کنٹریکٹ کے اندر لاک کیے گئے ٹوکنز کی تعداد کے برابر ہو۔ +اگر L2 پر بہت زیادہ ٹوکنز ہیں تو کچھ صارفین اپنے اثاثوں کو L1 پر واپس برج نہیں کر پائیں گے۔ +ایک قابل اعتماد برج کے بجائے، ہم بنیادی طور پر [فرکشنل ریزرو بینکنگ](https://www.investopedia.com/terms/f/fractionalreservebanking.asp) کو دوبارہ بنائیں گے۔ +اگر L1 پر بہت زیادہ ٹوکنز ہیں، تو ان میں سے کچھ ٹوکنز برج کنٹریکٹ کے اندر ہمیشہ کے لیے لاک ہو جائیں گے کیونکہ L2 ٹوکنز کو جلائے بغیر انہیں جاری کرنے کا کوئی طریقہ نہیں ہے۔ + +### IL2StandardERC20 {#il2standarderc20} + +L2 پر ہر ERC-20 ٹوکن جو معیاری برج کا استعمال کرتا ہے اسے [یہ انٹرفیس](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/IL2StandardERC20.sol) فراہم کرنا ہوگا، جس میں وہ فنکشنز اور ایونٹس ہیں جن کی معیاری برج کو ضرورت ہے۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +``` + +[معیاری ERC-20 انٹرفیس](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol) میں `mint` اور `burn` فنکشنز شامل نہیں ہیں۔ +ان طریقوں کی ضرورت [ERC-20 معیار](https://eips.ethereum.org/EIPS/eip-20) کے ذریعہ نہیں ہے، جو ٹوکن بنانے اور تباہ کرنے کے میکانزم کو غیر متعین چھوڑ دیتا ہے۔ + +```solidity +import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; +``` + +[ERC-165 انٹرفیس](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol) اس بات کی وضاحت کے لیے استعمال ہوتا ہے کہ ایک کنٹریکٹ کون سے فنکشنز فراہم کرتا ہے۔ +[آپ معیار یہاں پڑھ سکتے ہیں](https://eips.ethereum.org/EIPS/eip-165)۔ + +```solidity +interface IL2StandardERC20 is IERC20, IERC165 { + function l1Token() external returns (address); +``` + +یہ فنکشن L1 ٹوکن کا ایڈریس فراہم کرتا ہے جو اس کنٹریکٹ سے برجڈ ہے۔ +نوٹ کریں کہ ہمارے پاس مخالف سمت میں اسی طرح کا فنکشن نہیں ہے۔ +ہمیں کسی بھی L1 ٹوکن کو برج کرنے کے قابل ہونے کی ضرورت ہے، چاہے L2 سپورٹ کی منصوبہ بندی کی گئی ہو یا نہیں جب اسے لاگو کیا گیا تھا۔ + +```solidity + + function mint(address _to, uint256 _amount) external; + + function burn(address _from, uint256 _amount) external; + + event Mint(address indexed _account, uint256 _amount); + event Burn(address indexed _account, uint256 _amount); +} +``` + +ٹوکن منٹ (بنانے) اور جلانے (تباہ کرنے) کے لیے فنکشنز اور ایونٹس۔ +برج کو واحد ادارہ ہونا چاہئے جو ان فنکشنز کو چلا سکتا ہے تاکہ یہ یقینی بنایا جا سکے کہ ٹوکنز کی تعداد درست ہے (L1 پر لاک کیے گئے ٹوکنز کی تعداد کے برابر)۔ + +### L2StandardERC20 {#L2StandardERC20} + +[یہ `IL2StandardERC20` انٹرفیس کا ہمارا نفاذ ہے](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/standards/L2StandardERC20.sol)۔ +جب تک آپ کو کسی قسم کی اپنی مرضی کی منطق کی ضرورت نہ ہو، آپ کو یہ استعمال کرنا چاہیے۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +``` + +[OpenZeppelin ERC-20 کنٹریکٹ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)۔ +Optimism پہیے کو دوبارہ ایجاد کرنے میں یقین نہیں رکھتا، خاص طور پر جب پہیہ اچھی طرح سے آڈٹ کیا گیا ہو اور اثاثوں کو رکھنے کے لیے کافی قابل اعتماد ہونے کی ضرورت ہو۔ + +```solidity +import "./IL2StandardERC20.sol"; + +contract L2StandardERC20 is IL2StandardERC20, ERC20 { + address public l1Token; + address public l2Bridge; +``` + +یہ دو اضافی کنفیگریشن پیرامیٹرز ہیں جن کی ہمیں ضرورت ہے اور ERC-20 عام طور پر نہیں کرتا ہے۔ + +```solidity + + /** + * @param _l2Bridge L2 معیاری برج کا ایڈریس۔ + * @param _l1Token متعلقہ L1 ٹوکن کا ایڈریس۔ + * @param _name ERC20 نام۔ + * @param _symbol ERC20 علامت۔ + */ + constructor( + address _l2Bridge, + address _l1Token, + string memory _name, + string memory _symbol + ) ERC20(_name, _symbol) { + l1Token = _l1Token; + l2Bridge = _l2Bridge; + } +``` + +پہلے اس کنٹریکٹ کے لیے کنسٹرکٹر کو کال کریں جس سے ہم وراثت میں ہیں (`ERC20(_name, _symbol)`) اور پھر اپنے متغیرات سیٹ کریں۔ + +```solidity + + modifier onlyL2Bridge() { + require(msg.sender == l2Bridge, "صرف L2 برج منٹ اور برن کر سکتا ہے"); + _; + } + + + // slither-disable-next-line external-function + function supportsInterface(bytes4 _interfaceId) public pure returns (bool) { + bytes4 firstSupportedInterface = bytes4(keccak256("supportsInterface(bytes4)")); // ERC165 + bytes4 secondSupportedInterface = IL2StandardERC20.l1Token.selector ^ + IL2StandardERC20.mint.selector ^ + IL2StandardERC20.burn.selector; + return _interfaceId == firstSupportedInterface || _interfaceId == secondSupportedInterface; + } +``` + +یہ وہ طریقہ ہے جس سے [ERC-165](https://eips.ethereum.org/EIPS/eip-165) کام کرتا ہے۔ +ہر انٹرفیس معاون فنکشنز کی ایک تعداد ہے، اور اس کی شناخت ان فنکشنز کے [ABI فنکشن سلیکٹرز](https://docs.soliditylang.org/en/v0.8.12/abi-spec.html#function-selector) کے [exclusive or](https://en.wikipedia.org/wiki/Exclusive_or) کے طور پر کی جاتی ہے۔ + +L2 برج ERC-165 کو ایک سینیٹی چیک کے طور پر استعمال کرتا ہے تاکہ یہ یقینی بنایا جا سکے کہ جس ERC-20 کنٹریکٹ کو یہ اثاثے بھیجتا ہے وہ `IL2StandardERC20` ہے۔ + +**نوٹ:** `supportsInterface` کو غلط جواب دینے سے بدمعاش کنٹریکٹ کو روکنے کے لیے کچھ بھی نہیں ہے، لہذا یہ ایک سینیٹی چیک میکانزم ہے، _سیکیورٹی میکانزم نہیں_۔ + +```solidity + // slither-disable-next-line external-function + function mint(address _to, uint256 _amount) public virtual onlyL2Bridge { + _mint(_to, _amount); + + emit Mint(_to, _amount); + } + + // slither-disable-next-line external-function + function burn(address _from, uint256 _amount) public virtual onlyL2Bridge { + _burn(_from, _amount); + + emit Burn(_from, _amount); + } +} +``` + +صرف L2 برج کو اثاثے منٹ اور برن کرنے کی اجازت ہے۔ + +_mint`اور`_burn` دراصل [OpenZeppelin ERC-20 کنٹریکٹ](/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn) میں بیان کیے گئے ہیں۔ +وہ کنٹریکٹ صرف انہیں بیرونی طور پر ظاہر نہیں کرتا، کیونکہ ٹوکن منٹ اور برن کرنے کی شرائط اتنی ہی متنوع ہیں جتنی ERC-20 استعمال کرنے کے طریقے۔ + +## L2 برج کوڈ {#l2-bridge-code} + +یہ وہ کوڈ ہے جو Optimism پر برج کو چلاتا ہے۔ +[اس کنٹریکٹ کا ماخذ یہاں ہے](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/L2StandardBridge.sol)۔ + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.9; + +/* انٹرفیس امپورٹس */ +import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; +import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; +import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; +``` + +[IL2ERC20Bridge](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts/contracts/L2/messaging/IL2ERC20Bridge.sol) انٹرفیس اوپر دیکھے گئے [L1 کے مساوی](#IL1ERC20Bridge) سے بہت ملتا جلتا ہے۔ +دو اہم فرق ہیں: + +1. L1 پر آپ ڈپازٹ شروع کرتے ہیں اور واپسیوں کو حتمی شکل دیتے ہیں۔ + یہاں آپ واپسی شروع کرتے ہیں اور ڈپازٹ کو حتمی شکل دیتے ہیں۔ +2. L1 پر ETH اور ERC-20 ٹوکنز کے درمیان فرق کرنا ضروری ہے۔ + L2 پر ہم دونوں کے لیے ایک ہی فنکشنز استعمال کر سکتے ہیں کیونکہ اندرونی طور پر Optimism پر ETH بیلنس کو ایڈریس [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://explorer.optimism.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000) والے ERC-20 ٹوکن کے طور پر ہینڈل کیا جاتا ہے۔ + +```solidity +/* لائبریری امپورٹس */ +import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; +import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; +import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; + +/* کنٹریکٹ امپورٹس */ +import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; + +/** + * @title L2StandardBridge + * @dev L2 معیاری برج ایک کنٹریکٹ ہے جو L1 معیاری برج کے ساتھ مل کر + * L1 اور L2 کے درمیان ETH اور ERC20 منتقلی کو فعال کرتا ہے۔ + * یہ کنٹریکٹ نئے ٹوکنز کے لیے ایک منٹر کے طور پر کام کرتا ہے جب یہ L1 معیاری برج میں ڈپازٹ کے بارے میں سنتا ہے۔ + * یہ کنٹریکٹ واپسی کے لیے مطلوبہ ٹوکنز کے برنر کے طور پر بھی کام کرتا ہے، L1 برج کو L1 فنڈز جاری کرنے کے بارے میں مطلع کرتا ہے۔ + */ +contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { + /******************************** + * بیرونی کنٹریکٹ کے حوالے * + ********************************/ + + address public l1TokenBridge; +``` + +L1 برج کے ایڈریس کا ٹریک رکھیں۔ +نوٹ کریں کہ L1 کے مساوی کے برعکس، یہاں ہمیں اس متغیر کی _ضرورت_ ہے۔ +L1 برج کا ایڈریس پہلے سے معلوم نہیں ہے۔ + +```solidity + + /*************** + * کنسٹرکٹر * + ***************/ + + /** + * @param _l2CrossDomainMessenger اس کنٹریکٹ کے ذریعے استعمال ہونے والا کراس ڈومین میسنجر۔ + * @param _l1TokenBridge مرکزی چین پر تعینات L1 برج کا ایڈریس۔ + */ + constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) + CrossDomainEnabled(_l2CrossDomainMessenger) + { + l1TokenBridge = _l1TokenBridge; + } + + /*************** + * واپسی * + ***************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdraw( + address _l2Token, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, msg.sender, _amount, _l1Gas, _data); + } + + /** + * @inheritdoc IL2ERC20Bridge + */ + function withdrawTo( + address _l2Token, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) external virtual { + _initiateWithdrawal(_l2Token, msg.sender, _to, _amount, _l1Gas, _data); + } +``` + +یہ دو فنکشنز واپسی شروع کرتے ہیں۔ +نوٹ کریں کہ L1 ٹوکن ایڈریس کی وضاحت کرنے کی کوئی ضرورت نہیں ہے۔ +L2 ٹوکنز سے توقع کی جاتی ہے کہ وہ ہمیں L1 کے مساوی ایڈریس بتائیں گے۔ + +```solidity + + /** + * @dev ٹوکن کو جلا کر اور + * L1 ٹوکن گیٹ وے کو واپسی کے بارے میں مطلع کرکے واپسی کے لیے منطق انجام دیتا ہے۔ + * @param _l2Token L2 ٹوکن کا ایڈریس جہاں سے واپسی شروع کی گئی ہے۔ + * @param _from L2 پر واپسی نکالنے کے لیے اکاؤنٹ۔ + * @param _to L1 پر واپسی دینے کے لیے اکاؤنٹ۔ + * @param _amount واپس لینے کے لیے ٹوکن کی رقم۔ + * @param _l1Gas غیر استعمال شدہ، لیکن ممکنہ فارورڈ مطابقت کے تحفظات کے لیے شامل ہے۔ + * @param _data L1 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا + * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ + * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + */ + function _initiateWithdrawal( + address _l2Token, + address _from, + address _to, + uint256 _amount, + uint32 _l1Gas, + bytes calldata _data + ) internal { + // جب واپسی شروع کی جاتی ہے، تو ہم بعد میں L2 + // کے استعمال کو روکنے کے لیے واپس لینے والے کے فنڈز کو جلا دیتے ہیں + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).burn(msg.sender, _amount); +``` + +نوٹ کریں کہ ہم `_from` پیرامیٹر پر انحصار نہیں کر رہے ہیں بلکہ `msg.sender` پر کر رہے ہیں جسے جعلی بنانا بہت مشکل ہے (جہاں تک میں جانتا ہوں، ناممکن)۔ + +```solidity + + // l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) کے لیے کال ڈیٹا تعمیر کریں + // slither-disable-next-line reentrancy-events + address l1Token = IL2StandardERC20(_l2Token).l1Token(); + bytes memory message; + + if (_l2Token == Lib_PredeployAddresses.OVM_ETH) { +``` + +L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ + +```solidity + message = abi.encodeWithSelector( + IL1StandardBridge.finalizeETHWithdrawal.selector, + _from, + _to, + _amount, + _data + ); + } else { + message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + l1Token, + _l2Token, + _from, + _to, + _amount, + _data + ); + } + + // L1 برج کو پیغام بھیجیں + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); + + // slither-disable-next-line reentrancy-events + emit WithdrawalInitiated(l1Token, _l2Token, msg.sender, _to, _amount, _data); + } + + /************************************ + * کراس چین فنکشن: جمع کرنا * + ************************************/ + + /** + * @inheritdoc IL2ERC20Bridge + */ + function finalizeDeposit( + address _l1Token, + address _l2Token, + address _from, + address _to, + uint256 _amount, + bytes calldata _data +``` + +اس فنکشن کو `L1StandardBridge` کے ذریعے کال کیا جاتا ہے۔ + +```solidity + ) external virtual onlyFromCrossDomainAccount(l1TokenBridge) { +``` + +یقینی بنائیں کہ پیغام کا ماخذ جائز ہے۔ +یہ اہم ہے کیونکہ یہ فنکشن `_mint` کو کال کرتا ہے اور اس کا استعمال ایسے ٹوکن دینے کے لیے کیا جا سکتا ہے جو L1 پر برج کے ملکیت والے ٹوکنز کے تحت نہیں آتے ہیں۔ + +```solidity + // چیک کریں کہ ہدف ٹوکن مطابقت رکھتا ہے اور + // تصدیق کریں کہ L1 پر جمع شدہ ٹوکن یہاں L2 جمع شدہ ٹوکن کی نمائندگی سے میل کھاتا ہے + if ( + // slither-disable-next-line reentrancy-events + ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && + _l1Token == IL2StandardERC20(_l2Token).l1Token() +``` + +سینیٹی چیکس: + +1. درست انٹرفیس سپورٹ کیا جاتا ہے +2. L2 ERC-20 کنٹریکٹ کا L1 ایڈریس ٹوکنز کے L1 ماخذ سے میل کھاتا ہے + +```solidity + ) { + // جب ڈپازٹ کو حتمی شکل دی جاتی ہے، تو ہم L2 پر اکاؤنٹ کو اتنی ہی رقم + // کے ٹوکنز کے ساتھ کریڈٹ کرتے ہیں۔ + // slither-disable-next-line reentrancy-events + IL2StandardERC20(_l2Token).mint(_to, _amount); + // slither-disable-next-line reentrancy-events + emit DepositFinalized(_l1Token, _l2Token, _from, _to, _amount, _data); +``` + +اگر سینیٹی چیکس پاس ہو جاتے ہیں، تو ڈپازٹ کو حتمی شکل دیں: + +1. ٹوکن منٹ کریں +2. مناسب ایونٹ خارج کریں + +```solidity + } else { + // یا تو L2 ٹوکن جس میں جمع کیا جا رہا ہے، اس کے L1 ٹوکن کے + // درست ایڈریس کے بارے میں اختلاف کرتا ہے، یا درست انٹرفیس کو سپورٹ نہیں کرتا ہے۔ + // یہ صرف اس صورت میں ہونا چاہئے جب کوئی بدنیتی پر مبنی L2 ٹوکن ہو، یا اگر کوئی صارف کسی طرح + // جمع کرنے کے لیے غلط L2 ٹوکن ایڈریس کی وضاحت کرے۔ + // دونوں صورتوں میں، ہم یہاں عمل کو روکتے ہیں اور ایک واپسی کا + // پیغام بناتے ہیں تاکہ صارفین کچھ معاملات میں اپنے فنڈز نکال سکیں۔ + // بدنیتی پر مبنی ٹوکن کنٹریکٹس کو مکمل طور پر روکنے کا کوئی طریقہ نہیں ہے، لیکن یہ + // صارف کی غلطی کو محدود کرتا ہے اور بدنیتی پر مبنی کنٹریکٹ کے رویے کی کچھ شکلوں کو کم کرتا ہے۔ +``` + +اگر کسی صارف نے غلط L2 ٹوکن ایڈریس کا استعمال کرکے قابل شناخت غلطی کی ہے، تو ہم ڈپازٹ کو منسوخ کرنا چاہتے ہیں اور L1 پر ٹوکن واپس کرنا چاہتے ہیں۔ +L2 سے ایسا کرنے کا واحد طریقہ یہ ہے کہ ایک پیغام بھیجا جائے جسے فالٹ چیلنج کی مدت کا انتظار کرنا پڑے گا، لیکن یہ صارف کے لیے ٹوکن کو مستقل طور پر کھونے سے بہت بہتر ہے۔ + +```solidity + bytes memory message = abi.encodeWithSelector( + IL1ERC20Bridge.finalizeERC20Withdrawal.selector, + _l1Token, + _l2Token, + _to, // ڈپازٹ کو بھیجنے والے کو واپس بھیجنے کے لیے یہاں _to اور _from کو تبدیل کیا + _from, + _amount, + _data + ); + + // L1 برج کو پیغام بھیجیں + // slither-disable-next-line reentrancy-events + sendCrossDomainMessage(l1TokenBridge, 0, message); + // slither-disable-next-line reentrancy-events + emit DepositFailed(_l1Token, _l2Token, _from, _to, _amount, _data); + } + } +} +``` + +## نتیجہ {#conclusion} + +معیاری برج اثاثوں کی منتقلی کے لیے سب سے زیادہ لچکدار میکانزم ہے۔ +تاہم، چونکہ یہ بہت عام ہے، اس لیے یہ استعمال کرنے کے لیے ہمیشہ سب سے آسان میکانزم نہیں ہے۔ +خاص طور پر واپسی کے لیے، زیادہ تر صارفین [تھرڈ پارٹی برجز](https://optimism.io/apps#bridge) کا استعمال کرنا پسند کرتے ہیں جو چیلنج کی مدت کا انتظار نہیں کرتے اور واپسی کو حتمی شکل دینے کے لیے Merkle پروف کی ضرورت نہیں ہوتی۔ + +یہ برجز عام طور پر L1 پر اثاثے رکھ کر کام کرتے ہیں، جو وہ فوری طور پر ایک چھوٹی سی فیس کے لیے فراہم کرتے ہیں (اکثر معیاری برج کی واپسی کے لیے گیس کی لاگت سے کم)۔ +جب برج (یا اسے چلانے والے لوگ) L1 اثاثوں کی کمی کا اندازہ لگاتے ہیں تو یہ L2 سے کافی اثاثے منتقل کرتا ہے۔ چونکہ یہ بہت بڑی واپسی ہیں، واپسی کی لاگت ایک بڑی رقم پر تقسیم کی جاتی ہے اور یہ ایک بہت چھوٹا فیصد ہے۔ + +امید ہے کہ اس مضمون نے آپ کو لیئر 2 کے کام کرنے کے طریقے، اور واضح اور محفوظ Solidity کوڈ لکھنے کے بارے میں مزید سمجھنے میں مدد کی ہوگی۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/reverse-engineering-a-contract/index.md b/public/content/translations/ur/developers/tutorials/reverse-engineering-a-contract/index.md new file mode 100644 index 00000000000..314b06e852b --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/reverse-engineering-a-contract/index.md @@ -0,0 +1,744 @@ +--- +title: "ایک کنٹریکٹ کی ریورس انجینئرنگ" +description: "جب آپ کے پاس سورس کوڈ نہ ہو تو کنٹریکٹ کو کیسے سمجھیں" +author: Ori Pomerantz +lang: ur-in +tags: [ "evm", "opcodes" ] +skill: advanced +published: 2021-12-30 +--- + +## تعارف {#introduction} + +_بلاک چین پر کوئی راز نہیں ہیں_، جو کچھ بھی ہوتا ہے وہ مستقل، قابل تصدیق، اور عوامی طور پر دستیاب ہے۔ مثالی طور پر، [کنٹریکٹس کا سورس کوڈ Etherscan پر شائع اور تصدیق شدہ ہونا چاہیے](https://etherscan.io/address/0xb8901acb165ed027e32754e0ffe830802919727f#code)۔ تاہم، [ہمیشہ ایسا نہیں ہوتا](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#code)۔ اس مضمون میں آپ بغیر سورس کوڈ والے کنٹریکٹ، [`0x2510c039cc3b061d79e564b38836da87e31b342f`](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f) کو دیکھ کر کنٹریکٹس کی ریورس انجینئرنگ کرنا سیکھیں گے۔ + +ریورس کمپائلرز موجود ہیں، لیکن وہ ہمیشہ [قابل استعمال نتائج](https://etherscan.io/bytecode-decompiler?a=0x2510c039cc3b061d79e564b38836da87e31b342f) نہیں دیتے۔ اس مضمون میں آپ [opcodes](https://github.com/wolflo/evm-opcodes) سے ایک کنٹریکٹ کو دستی طور پر ریورس انجینئر کرنا اور سمجھنا سیکھیں گے، اور ساتھ ہی ایک ڈی کمپائلر کے نتائج کی تشریح کرنا بھی سیکھیں گے۔ + +اس مضمون کو سمجھنے کے لیے آپ کو EVM کی بنیادی باتیں پہلے سے معلوم ہونی چاہئیں، اور EVM اسمبلر سے کم از کم کچھ حد تک واقف ہونا چاہیے۔ [آپ ان موضوعات کے بارے میں یہاں پڑھ سکتے ہیں](https://medium.com/mycrypto/the-ethereum-virtual-machine-how-does-it-work-9abac2b7c9e)۔ + +## قابل عمل کوڈ تیار کریں {#prepare-the-executable-code} + +آپ کنٹریکٹ کے لیے Etherscan پر جا کر، **کنٹریکٹ** ٹیب پر کلک کرکے اور پھر **Switch to Opcodes View** پر کلک کرکے opcodes حاصل کرسکتے ہیں۔ آپ کو ایک ویو ملتا ہے جس میں ہر لائن پر ایک opcode ہوتا ہے۔ + +![Etherscan سے Opcode ویو](opcode-view.png) + +تاہم، جمپس کو سمجھنے کے لیے، آپ کو یہ جاننا ہوگا کہ کوڈ میں ہر opcode کہاں واقع ہے۔ ایسا کرنے کے لیے، ایک طریقہ یہ ہے کہ ایک Google Spreadsheet کھولیں اور کالم C میں opcodes پیسٹ کریں۔ [آپ اس پہلے سے تیار شدہ اسپریڈشیٹ کی ایک کاپی بنا کر درج ذیل مراحل کو چھوڑ سکتے ہیں](https://docs.google.com/spreadsheets/d/1tKmTJiNjUwHbW64wCKOSJxHjmh0bAUapt6btUYE7kDA/edit?usp=sharing)۔ + +اگلا مرحلہ کوڈ کے صحیح مقامات حاصل کرنا ہے تاکہ ہم جمپس کو سمجھ سکیں۔ ہم کالم B میں opcode کا سائز، اور کالم A میں مقام (ہیکسا ڈیسیمل میں) رکھیں گے۔ سیل `B1` میں یہ فنکشن ٹائپ کریں اور پھر اسے کوڈ کے آخر تک باقی کالم B کے لیے کاپی اور پیسٹ کریں۔ ایسا کرنے کے بعد آپ کالم B کو چھپا سکتے ہیں۔ + +``` +=1+IF(REGEXMATCH(C1,\"PUSH\"),REGEXEXTRACT(C1,\"PUSH(\\d+)\"),0) +``` + +پہلے یہ فنکشن خود opcode کے لیے ایک بائٹ کا اضافہ کرتا ہے، اور پھر `PUSH` کو تلاش کرتا ہے۔ پش opcodes خاص ہوتے ہیں کیونکہ انہیں پش کی جانے والی ویلیو کے لیے اضافی بائٹس کی ضرورت ہوتی ہے۔ اگر opcode ایک `PUSH` ہے، تو ہم بائٹس کی تعداد نکالتے ہیں اور اسے جوڑ دیتے ہیں۔ + +`A1` میں پہلا آفسیٹ، صفر ڈالیں۔ پھر، `A2` میں، یہ فنکشن ڈالیں اور اسے دوبارہ کالم A کے باقی حصے کے لیے کاپی اور پیسٹ کریں: + +``` +=dec2hex(hex2dec(A1)+B1) +``` + +ہمیں اس فنکشن کی ضرورت ہے تاکہ یہ ہمیں ہیکسا ڈیسیمل ویلیو دے کیونکہ جمپس (`JUMP` اور `JUMPI`) سے پہلے پش کی جانے والی ویلیوز ہمیں ہیکسا ڈیسیمل میں دی جاتی ہیں۔ + +## انٹری پوائنٹ (0x00) {#the-entry-point-0x00} + +کنٹریکٹس ہمیشہ پہلے بائٹ سے ایگزیکیوٹ ہوتے ہیں۔ یہ کوڈ کا ابتدائی حصہ ہے: + +| آفسیٹ | Opcode | اسٹیک (opcode کے بعد) | +| ----: | ------------ | ---------------------------------------------- | +| 0 | PUSH1 0x80 | 0x80 | +| 2 | PUSH1 0x40 | 0x40, 0x80 | +| 4 | MSTORE | خالی | +| 5 | PUSH1 0x04 | 0x04 | +| 7 | CALLDATASIZE | CALLDATASIZE 0x04 | +| 8 | LT | CALLDATASIZE\<4 | +| 9 | PUSH2 0x005e | 0x5E CALLDATASIZE\<4 | +| C | JUMPI | خالی | + +یہ کوڈ دو کام کرتا ہے: + +1. 0x80 کو 32 بائٹ ویلیو کے طور پر میموری کے مقامات 0x40-0x5F پر لکھیں (0x80 کو 0x5F میں اسٹور کیا جاتا ہے، اور 0x40-0x5E سب صفر ہیں)۔ +2. calldata کا سائز پڑھیں۔ عام طور پر ایک Ethereum کنٹریکٹ کے لیے کال ڈیٹا [ABI (ایپلیکیشن بائنری انٹرفیس)](https://docs.soliditylang.org/en/v0.8.10/abi-spec.html) کی پیروی کرتا ہے، جس کے لیے فنکشن سلیکٹر کے لیے کم از کم چار بائٹس کی ضرورت ہوتی ہے۔ اگر کال ڈیٹا کا سائز چار سے کم ہے، تو 0x5E پر جمپ کریں۔ + +![اس حصے کے لیے فلو چارٹ](flowchart-entry.png) + +### 0x5E پر ہینڈلر (غیر-ABI کال ڈیٹا کے لیے) {#the-handler-at-0x5e-for-non-abi-call-data} + +| آفسیٹ | Opcode | +| ----: | ------------ | +| 5E | JUMPDEST | +| 5F | CALLDATASIZE | +| 60 | PUSH2 0x007c | +| 63 | JUMPI | + +یہ سنیپٹ `JUMPDEST` سے شروع ہوتا ہے۔ EVM (Ethereum ورچوئل مشین) پروگرام ایک استثناء (exception) دیتے ہیں اگر آپ کسی ایسے opcode پر جمپ کرتے ہیں جو `JUMPDEST` نہیں ہے۔ پھر یہ CALLDATASIZE کو دیکھتا ہے، اور اگر یہ "درست" ہے (یعنی، صفر نہیں ہے) تو 0x7C پر جمپ کرتا ہے۔ ہم اس پر نیچے بات کریں گے۔ + +| آفسیٹ | Opcode | اسٹیک (opcode کے بعد) | +| ----: | ---------- | -------------------------------------------------------------------------------------- | +| 64 | CALLVALUE | کال کے ذریعے فراہم کردہ [Wei](/glossary/#wei)۔ Solidity میں `msg.value` کہلاتا ہے۔ | +| 65 | PUSH1 0x06 | 6 CALLVALUE | +| 67 | PUSH1 0x00 | 0 6 CALLVALUE | +| 69 | DUP3 | CALLVALUE 0 6 CALLVALUE | +| 6A | DUP3 | 6 CALLVALUE 0 6 CALLVALUE | +| 6B | SLOAD | Storage[6] CALLVALUE 0 6 CALLVALUE | + +لہذا جب کوئی کال ڈیٹا نہیں ہوتا ہے تو ہم Storage[6] کی ویلیو پڑھتے ہیں۔ ہمیں ابھی تک نہیں معلوم کہ یہ ویلیو کیا ہے، لیکن ہم ان ٹرانزیکشنز کو تلاش کر سکتے ہیں جو کنٹریکٹ نے بغیر کال ڈیٹا کے وصول کی ہیں۔ وہ ٹرانزیکشنز جو بغیر کسی کال ڈیٹا کے صرف ETH ٹرانسفر کرتی ہیں (اور اس لیے کوئی میتھڈ نہیں) Etherscan میں ان کا میتھڈ `Transfer` ہوتا ہے۔ درحقیقت، [کنٹریکٹ کو موصول ہونے والی سب سے پہلی ٹرانزیکشن](https://etherscan.io/tx/0xeec75287a583c36bcc7ca87685ab41603494516a0f5986d18de96c8e630762e7) ایک ٹرانسفر ہے۔ + +اگر ہم اس ٹرانزیکشن میں دیکھیں اور **Click to see More** پر کلک کریں، تو ہم دیکھتے ہیں کہ کال ڈیٹا، جسے ان پٹ ڈیٹا کہا جاتا ہے، واقعی خالی (`0x`) ہے۔ یہ بھی نوٹ کریں کہ ویلیو 1.559 ETH ہے، جو بعد میں متعلقہ ہوگا۔ + +![کال ڈیٹا خالی ہے](calldata-empty.png) + +اگلا، **اسٹیٹ** ٹیب پر کلک کریں اور جس کنٹریکٹ کی ہم ریورس انجینئرنگ کر رہے ہیں اسے پھیلائیں (0x2510...)۔ آپ دیکھ سکتے ہیں کہ ٹرانزیکشن کے دوران `Storage[6]` تبدیل ہوا، اور اگر آپ Hex کو **نمبر** میں تبدیل کرتے ہیں، تو آپ دیکھتے ہیں کہ یہ 1,559,000,000,000,000,000 ہو گیا، جو wei میں منتقل کی گئی ویلیو ہے (میں نے وضاحت کے لیے کوما شامل کیے ہیں)، اور یہ اگلے کنٹریکٹ کی ویلیو کے مطابق ہے۔ + +![Storage[6] میں تبدیلی](storage6.png) + +اگر ہم اسی مدت کی [دیگر `Transfer` ٹرانزیکشنز](https://etherscan.io/tx/0xf708d306de39c422472f43cb975d97b866fd5d6a6863db627067167cbf93d84d1#statechange) کی وجہ سے ہونے والی اسٹیٹ تبدیلیوں کو دیکھیں تو ہم دیکھتے ہیں کہ `Storage[6]` نے کچھ وقت کے لیے کنٹریکٹ کی ویلیو کو ٹریک کیا۔ ابھی کے لیے ہم اسے `Value*` کہیں گے۔ ستارے کا نشان (`*`) ہمیں یاد دلاتا ہے کہ ہم ابھی تک نہیں _جانتے_ کہ یہ متغیر کیا کرتا ہے، لیکن یہ صرف کنٹریکٹ کی ویلیو کو ٹریک کرنے کے لیے نہیں ہو سکتا کیونکہ اسٹوریج، جو بہت مہنگا ہے، استعمال کرنے کی کوئی ضرورت نہیں ہے، جب آپ `ADDRESS BALANCE` استعمال کرکے اپنے اکاؤنٹس کا بیلنس حاصل کرسکتے ہیں۔ پہلا opcode کنٹریکٹ کا اپنا ایڈریس پش کرتا ہے۔ دوسرا والا اسٹیک کے اوپری حصے میں موجود ایڈریس کو پڑھتا ہے اور اسے اس ایڈریس کے بیلنس سے بدل دیتا ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------- | +| 6C | PUSH2 0x0075 | 0x75 Value\* CALLVALUE 0 6 CALLVALUE | +| 6F | SWAP2 | CALLVALUE Value\* 0x75 0 6 CALLVALUE | +| 70 | SWAP1 | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 71 | PUSH2 0x01a7 | 0x01A7 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 74 | JUMP | | + +ہم اس کوڈ کو جمپ ڈیسٹینیشن پر ٹریس کرنا جاری رکھیں گے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------- | ----------------------------------------------------------- | +| 1A7 | JUMPDEST | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1A8 | PUSH1 0x00 | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AA | DUP3 | CALLVALUE 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AB | NOT | 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | + +`NOT` بٹ وائز ہے، لہذا یہ کال ویلیو میں ہر بٹ کی ویلیو کو الٹ دیتا ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------------------------------------ | +| 1AC | DUP3 | Value\* 2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AD | GT | Value\*>2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AE | ISZERO | Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1AF | PUSH2 0x01df | 0x01DF Value\*\<=2^256-CALLVALUE-1 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1B2 | JUMPI | | + +ہم جمپ کرتے ہیں اگر `Value*`، 2^256-CALLVALUE-1 سے چھوٹا یا اس کے برابر ہو۔ یہ اوور فلو کو روکنے کی منطق کی طرح لگتا ہے۔ اور درحقیقت، ہم دیکھتے ہیں کہ کچھ بے معنی آپریشنز کے بعد (میموری میں لکھنا حذف ہونے والا ہے، مثال کے طور پر) آفسیٹ 0x01DE پر کنٹریکٹ ریورٹ ہوجاتا ہے اگر اوور فلو کا پتہ چلتا ہے، جو کہ عام رویہ ہے۔ + +نوٹ کریں کہ اس طرح کا اوور فلو انتہائی غیر متوقع ہے، کیونکہ اس کے لیے کال ویلیو اور `Value*` کا موازنہ 2^256 wei، تقریباً 10^59 ETH سے کرنا ہوگا۔ [لکھنے کے وقت، کل ETH سپلائی دو سو ملین سے کم ہے](https://etherscan.io/stat/supply)۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | -------- | ----------------------------------------- | +| 1DF | JUMPDEST | 0x00 Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E0 | POP | Value\* CALLVALUE 0x75 0 6 CALLVALUE | +| 1E1 | ADD | Value\*+CALLVALUE 0x75 0 6 CALLVALUE | +| 1E2 | SWAP1 | 0x75 Value\*+CALLVALUE 0 6 CALLVALUE | +| 1E3 | JUMP | | + +اگر ہم یہاں پہنچ گئے تو، `Value* + CALLVALUE` حاصل کریں اور آفسیٹ 0x75 پر جمپ کریں۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | -------- | ------------------------------- | +| 75 | JUMPDEST | Value\*+CALLVALUE 0 6 CALLVALUE | +| 76 | SWAP1 | 0 Value\*+CALLVALUE 6 CALLVALUE | +| 77 | SWAP2 | 6 Value\*+CALLVALUE 0 CALLVALUE | +| 78 | SSTORE | 0 CALLVALUE | + +اگر ہم یہاں پہنچتے ہیں (جس کے لیے کال ڈیٹا کا خالی ہونا ضروری ہے) تو ہم `Value*` میں کال ویلیو کا اضافہ کرتے ہیں۔ یہ اس کے مطابق ہے جو ہم کہتے ہیں کہ `Transfer` ٹرانزیکشنز کرتی ہیں۔ + +| آفسیٹ | Opcode | +| ----: | ------ | +| 79 | POP | +| 7A | POP | +| 7B | STOP | + +آخر میں، اسٹیک کو صاف کریں (جو ضروری نہیں ہے) اور ٹرانزیکشن کے کامیاب اختتام کا اشارہ دیں۔ + +اس سب کا خلاصہ کرنے کے لیے، یہاں ابتدائی کوڈ کے لیے ایک فلو چارٹ ہے۔ + +![انٹری پوائنٹ فلو چارٹ](flowchart-entry.png) + +## 0x7C پر ہینڈلر {#the-handler-at-0x7c} + +میں نے جان بوجھ کر ہیڈنگ میں یہ نہیں بتایا کہ یہ ہینڈلر کیا کرتا ہے۔ مقصد آپ کو یہ سکھانا نہیں ہے کہ یہ مخصوص کنٹریکٹ کیسے کام کرتا ہے، بلکہ یہ سکھانا ہے کہ کنٹریکٹس کو کیسے ریورس انجینئر کیا جائے۔ آپ اسی طرح سیکھیں گے جیسے میں نے کوڈ کی پیروی کرکے سیکھا تھا۔ + +ہم یہاں کئی جگہوں سے آتے ہیں: + +- اگر 1، 2، یا 3 بائٹس کا کال ڈیٹا ہے (آفسیٹ 0x63 سے) +- اگر میتھڈ سگنیچر نامعلوم ہے (آفسیٹس 0x42 اور 0x5D سے) + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------ | +| 7C | JUMPDEST | | +| 7D | PUSH1 0x00 | 0x00 | +| 7F | PUSH2 0x009d | 0x9D 0x00 | +| 82 | PUSH1 0x03 | 0x03 0x9D 0x00 | +| 84 | SLOAD | Storage[3] 0x9D 0x00 | + +یہ ایک اور اسٹوریج سیل ہے، جسے میں کسی بھی ٹرانزیکشن میں نہیں ڈھونڈ سکا لہذا یہ جاننا مشکل ہے کہ اس کا کیا مطلب ہے۔ نیچے دیا گیا کوڈ اسے مزید واضح کر دے گا۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| 85 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xff....ff Storage[3] 0x9D 0x00 | +| 9A | AND | Storage[3]-بطور-ایڈریس 0x9D 0x00 | + +یہ opcodes اس ویلیو کو جو ہم Storage[3] سے پڑھتے ہیں، اسے 160 بٹس تک چھوٹا کر دیتے ہیں، جو کہ ایک Ethereum ایڈریس کی لمبائی ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------ | ------------------------------------------------------------------------------------ | +| 9B | SWAP1 | 0x9D Storage[3]-بطور-ایڈریس 0x00 | +| 9C | JUMP | Storage[3]-بطور-ایڈریس 0x00 | + +یہ جمپ فالتو ہے، کیونکہ ہم اگلے opcode پر جا رہے ہیں۔ یہ کوڈ اتنا گیس-ایفیشنٹ نہیں ہے جتنا ہو سکتا تھا۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| 9D | JUMPDEST | Storage[3]-بطور-ایڈریس 0x00 | +| 9E | SWAP1 | 0x00 Storage[3]-بطور-ایڈریس | +| 9F | POP | Storage[3]-بطور-ایڈریس | +| A0 | PUSH1 0x40 | 0x40 Storage[3]-بطور-ایڈریس | +| A2 | MLOAD | Mem[0x40] Storage[3]-بطور-ایڈریس | + +کوڈ کے بالکل شروع میں ہم نے Mem[0x40] کو 0x80 پر سیٹ کیا تھا۔ اگر ہم بعد میں 0x40 کو تلاش کریں تو ہم دیکھتے ہیں کہ ہم اسے تبدیل نہیں کرتے ہیں - لہذا ہم فرض کر سکتے ہیں کہ یہ 0x80 ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------------------------------------ | +| A3 | CALLDATASIZE | CALLDATASIZE 0x80 Storage[3]-بطور-ایڈریس | +| A4 | PUSH1 0x00 | 0x00 CALLDATASIZE 0x80 Storage[3]-بطور-ایڈریس | +| A6 | DUP3 | 0x80 0x00 CALLDATASIZE 0x80 Storage[3]-بطور-ایڈریس | +| A7 | CALLDATACOPY | 0x80 Storage[3]-بطور-ایڈریس | + +تمام کال ڈیٹا کو میموری میں کاپی کریں، 0x80 سے شروع کرتے ہوئے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| A8 | PUSH1 0x00 | 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AA | DUP1 | 0x00 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AB | CALLDATASIZE | CALLDATASIZE 0x00 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AC | DUP4 | 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AD | DUP6 | Storage[3]-بطور-ایڈریس 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AE | GAS | GAS Storage[3]-بطور-ایڈریس 0x80 CALLDATASIZE 0x00 0x00 0x80 Storage[3]-بطور-ایڈریس | +| AF | DELEGATE_CALL | | + +اب چیزیں بہت واضح ہو گئی ہیں۔ یہ کنٹریکٹ ایک [پراکسی](https://blog.openzeppelin.com/proxy-patterns/) کے طور پر کام کر سکتا ہے، جو اصل کام کرنے کے لیے Storage[3] میں موجود ایڈریس کو کال کرتا ہے۔ `DELEGATE_CALL` ایک الگ کنٹریکٹ کو کال کرتا ہے، لیکن اسی اسٹوریج میں رہتا ہے۔ اس کا مطلب یہ ہے کہ ڈیلیگیٹڈ کنٹریکٹ، جس کے لیے ہم ایک پراکسی ہیں، اسی اسٹوریج اسپیس تک رسائی حاصل کرتا ہے۔ کال کے پیرامیٹرز یہ ہیں: + +- _گیس_: باقی تمام گیس +- _کال کیا گیا ایڈریس_: Storage[3]-بطور-ایڈریس +- _کال ڈیٹا_: CALLDATASIZE بائٹس 0x80 سے شروع ہوتی ہیں، جہاں ہم نے اصل کال ڈیٹا ڈالا تھا +- _ریٹرن ڈیٹا_: کوئی نہیں (0x00 - 0x00) ہم ریٹرن ڈیٹا دوسرے طریقوں سے حاصل کریں گے (نیچے دیکھیں) + +| آفسیٹ | Opcode | اسٹیک | +| ----: | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| B0 | RETURNDATASIZE | RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B1 | DUP1 | RETURNDATASIZE RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B2 | PUSH1 0x00 | 0x00 RETURNDATASIZE RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B4 | DUP5 | 0x80 0x00 RETURNDATASIZE RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B5 | RETURNDATACOPY | RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | + +یہاں ہم تمام ریٹرن ڈیٹا کو 0x80 سے شروع ہونے والے میموری بفر میں کاپی کرتے ہیں۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| B6 | DUP2 | (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B7 | DUP1 | (((کال کی کامیابی/ناکامی))) (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B8 | ISZERO | (((کیا کال ناکام ہوئی))) (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| B9 | PUSH2 0x00c0 | 0xC0 (((کیا کال ناکام ہوئی))) (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| BC | JUMPI | (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| BD | DUP2 | RETURNDATASIZE (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| BE | DUP5 | 0x80 RETURNDATASIZE (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| BF | RETURN | | + +لہذا کال کے بعد ہم ریٹرن ڈیٹا کو بفر 0x80 - 0x80+RETURNDATASIZE میں کاپی کرتے ہیں، اور اگر کال کامیاب ہوتی ہے تو ہم بالکل اسی بفر کے ساتھ `RETURN` کرتے ہیں۔ + +### DELEGATECALL ناکام {#delegatecall-failed} + +اگر ہم یہاں، 0xC0 پر پہنچتے ہیں، تو اس کا مطلب ہے کہ ہم نے جس کنٹریکٹ کو کال کیا تھا وہ ریورٹ ہو گیا ہے۔ چونکہ ہم اس کنٹریکٹ کے لیے صرف ایک پراکسی ہیں، ہم وہی ڈیٹا واپس کرنا چاہتے ہیں اور ریورٹ بھی کرنا چاہتے ہیں۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| C0 | JUMPDEST | (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| C1 | DUP2 | RETURNDATASIZE (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| C2 | DUP5 | 0x80 RETURNDATASIZE (((کال کی کامیابی/ناکامی))) RETURNDATASIZE (((کال کی کامیابی/ناکامی))) 0x80 Storage[3]-بطور-ایڈریس | +| C3 | REVERT | | + +لہذا ہم اسی بفر کے ساتھ `REVERT` کرتے ہیں جو ہم نے پہلے `RETURN` کے لیے استعمال کیا تھا: 0x80 - 0x80+RETURNDATASIZE + +![پراکسی پر کال کرنے کا فلو چارٹ](flowchart-proxy.png) + +## ABI کالز {#abi-calls} + +اگر کال ڈیٹا کا سائز چار بائٹس یا اس سے زیادہ ہے تو یہ ایک درست ABI کال ہو سکتی ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | --------------------------------------------------------------------------------------------------------------------- | +| D | PUSH1 0x00 | 0x00 | +| F | CALLDATALOAD | (((کال ڈیٹا کا پہلا لفظ (256 بٹس)))) | +| 10 | PUSH1 0xe0 | 0xE0 (((کال ڈیٹا کا پہلا لفظ (256 بٹس)))) | +| 12 | SHR | (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | + +Etherscan ہمیں بتاتا ہے کہ `1C` ایک نامعلوم opcode ہے، کیونکہ [اسے Etherscan کے اس فیچر کو لکھنے کے بعد شامل کیا گیا تھا](https://eips.ethereum.org/EIPS/eip-145) اور انہوں نے اسے اپ ڈیٹ نہیں کیا ہے۔ ایک [اپ ٹو ڈیٹ opcode ٹیبل](https://github.com/wolflo/evm-opcodes) ہمیں دکھاتا ہے کہ یہ شفٹ رائٹ ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 13 | DUP1 | (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس))) (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | +| 14 | PUSH4 0x3cd8045e | 0x3CD8045E (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس))) (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | +| 19 | GT | 0x3CD8045E>کال-ڈیٹا-کے-پہلے-32-بٹس (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | +| 1A | PUSH2 0x0043 | 0x43 0x3CD8045E>کال-ڈیٹا-کے-پہلے-32-بٹس (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | +| 1D | JUMPI | (((کال ڈیٹا کے پہلے 32 بٹس (4 بائٹس)))) | + +اس طرح میتھڈ سگنیچر میچنگ ٹیسٹس کو دو حصوں میں تقسیم کرنے سے اوسطاً آدھے ٹیسٹ بچ جاتے ہیں۔ اس کے فوراً بعد آنے والا کوڈ اور 0x43 میں موجود کوڈ ایک ہی پیٹرن کی پیروی کرتا ہے: کال ڈیٹا کے پہلے 32 بٹس کو `DUP1` کریں، `PUSH4 (((میتھڈ سگنیچر))`، برابری کی جانچ کے لیے `EQ` چلائیں، اور پھر اگر میتھڈ سگنیچر میچ کرتا ہے تو `JUMPI` کریں۔ یہاں میتھڈ سگنیچرز، ان کے ایڈریسز، اور اگر معلوم ہو تو [متعلقہ میتھڈ ڈیفینیشن](https://www.4byte.directory/) ہیں: + +| میتھڈ | میتھڈ سگنیچر | جمپ کرنے کے لیے آفسیٹ | +| --------------------------------------------------------------------------------------------------------- | ------------ | --------------------- | +| [splitter()](https://www.4byte.directory/signatures/?bytes4_signature=0x3cd8045e) | 0x3cd8045e | 0x0103 | +| ؟؟؟ | 0x81e580d3 | 0x0138 | +| [currentWindow()](https://www.4byte.directory/signatures/?bytes4_signature=0xba0bafb4) | 0xba0bafb4 | 0x0158 | +| ؟؟؟ | 0x1f135823 | 0x00C4 | +| [merkleRoot()](https://www.4byte.directory/signatures/?bytes4_signature=0x2eb4a7ab) | 0x2eb4a7ab | 0x00ED | + +اگر کوئی میچ نہیں ملتا ہے، تو کوڈ [پراکسی ہینڈلر پر 0x7C](#the-handler-at-0x7c) پر جمپ کرتا ہے، اس امید پر کہ جس کنٹریکٹ کے لیے ہم پراکسی ہیں اس کا کوئی میچ ہوگا۔ + +![ABI کالز فلو چارٹ](flowchart-abi.png) + +## splitter() {#splitter} + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ----------------------------- | +| 103 | JUMPDEST | | +| 104 | CALLVALUE | CALLVALUE | +| 105 | DUP1 | CALLVALUE CALLVALUE | +| 106 | ISZERO | CALLVALUE==0 CALLVALUE | +| 107 | PUSH2 0x010f | 0x010F CALLVALUE==0 CALLVALUE | +| 10A | JUMPI | CALLVALUE | +| 10B | PUSH1 0x00 | 0x00 CALLVALUE | +| 10D | DUP1 | 0x00 0x00 CALLVALUE | +| 10E | REVERT | | + +یہ فنکشن سب سے پہلے یہ چیک کرتا ہے کہ کال نے کوئی ETH نہیں بھیجا ہے۔ یہ فنکشن [`payable`](https://solidity-by-example.org/payable/) نہیں ہے۔ اگر کسی نے ہمیں ETH بھیجا ہے تو یہ ایک غلطی ہونی چاہیے اور ہم `REVERT` کرنا چاہتے ہیں تاکہ اس ETH کو ایسی جگہ رکھنے سے بچا جا سکے جہاں وہ اسے واپس نہ لے سکیں۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| 10F | JUMPDEST | | +| 110 | POP | | +| 111 | PUSH1 0x03 | 0x03 | +| 113 | SLOAD | (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) | +| 114 | PUSH1 0x40 | 0x40 (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) | +| 116 | MLOAD | 0x80 (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) | +| 117 | PUSH20 0xffffffffffffffffffffffffffffffffffffffff | 0xFF...FF 0x80 (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) | +| 12C | SWAP1 | 0x80 0xFF...FF (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) | +| 12D | SWAP2 | (((Storage[3] یعنی وہ کنٹریکٹ جس کے لیے ہم پراکسی ہیں))) 0xFF...FF 0x80 | +| 12E | AND | پراکسی ایڈریس 0x80 | +| 12F | DUP2 | 0x80 پراکسی ایڈریس 0x80 | +| 130 | MSTORE | 0x80 | + +اور 0x80 میں اب پراکسی ایڈریس موجود ہے + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | --------- | +| 131 | PUSH1 0x20 | 0x20 0x80 | +| 133 | ADD | 0xA0 | +| 134 | PUSH2 0x00e4 | 0xE4 0xA0 | +| 137 | JUMP | 0xA0 | + +### E4 کوڈ {#the-e4-code} + +یہ پہلی بار ہے جب ہم یہ لائنیں دیکھ رہے ہیں، لیکن یہ دیگر میتھڈز کے ساتھ بھی شیئر کی گئی ہیں (نیچے دیکھیں)۔ لہذا ہم اسٹیک میں موجود ویلیو کو X کہیں گے، اور بس یاد رکھیں گے کہ `splitter()` میں اس X کی ویلیو 0xA0 ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------- | ----------- | +| E4 | JUMPDEST | X | +| E5 | PUSH1 0x40 | 0x40 X | +| E7 | MLOAD | 0x80 X | +| E8 | DUP1 | 0x80 0x80 X | +| E9 | SWAP2 | X 0x80 0x80 | +| EA | SUB | X-0x80 0x80 | +| EB | SWAP1 | 0x80 X-0x80 | +| EC | RETURN | | + +لہذا یہ کوڈ اسٹیک میں ایک میموری پوائنٹر (X) وصول کرتا ہے، اور کنٹریکٹ کو ایک ایسے بفر کے ساتھ `RETURN` کرنے کا سبب بنتا ہے جو 0x80 - X ہے۔ + +`splitter()` کے معاملے میں، یہ وہ ایڈریس واپس کرتا ہے جس کے لیے ہم پراکسی ہیں۔ `RETURN` بفر کو 0x80-0x9F میں واپس کرتا ہے، جو وہ جگہ ہے جہاں ہم نے یہ ڈیٹا لکھا تھا (اوپر آفسیٹ 0x130)۔ + +## currentWindow() {#currentwindow} + +آفسیٹس 0x158-0x163 میں موجود کوڈ اس سے مماثل ہے جو ہم نے `splitter()` میں 0x103-0x10E میں دیکھا تھا (`JUMPI` کی منزل کے علاوہ)، لہذا ہم جانتے ہیں کہ `currentWindow()` بھی `payable` نہیں ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------ | +| 164 | JUMPDEST | | +| 165 | POP | | +| 166 | PUSH2 0x00da | 0xDA | +| 169 | PUSH1 0x01 | 0x01 0xDA | +| 16B | SLOAD | Storage[1] 0xDA | +| 16C | DUP2 | 0xDA Storage[1] 0xDA | +| 16D | JUMP | Storage[1] 0xDA | + +### DA کوڈ {#the-da-code} + +یہ کوڈ دیگر میتھڈز کے ساتھ بھی شیئر کیا گیا ہے۔ لہذا ہم اسٹیک میں موجود ویلیو کو Y کہیں گے، اور بس یاد رکھیں گے کہ `currentWindow()` میں اس Y کی ویلیو Storage[1] ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------- | ---------------- | +| DA | JUMPDEST | Y 0xDA | +| DB | PUSH1 0x40 | 0x40 Y 0xDA | +| DD | MLOAD | 0x80 Y 0xDA | +| DE | SWAP1 | Y 0x80 0xDA | +| DF | DUP2 | 0x80 Y 0x80 0xDA | +| E0 | MSTORE | 0x80 0xDA | + +Y کو 0x80-0x9F پر لکھیں۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ---------- | -------------- | +| E1 | PUSH1 0x20 | 0x20 0x80 0xDA | +| E3 | ADD | 0xA0 0xDA | + +اور باقی کی وضاحت [اوپر](#the-e4-code) پہلے ہی کی جا چکی ہے۔ لہذا 0xDA پر جمپ اسٹیک ٹاپ (Y) کو 0x80-0x9F پر لکھتے ہیں، اور اس ویلیو کو واپس کرتے ہیں۔ `currentWindow()` کے معاملے میں، یہ Storage[1] واپس کرتا ہے۔ + +## merkleRoot() {#merkleroot} + +آفسیٹس 0xED-0xF8 میں موجود کوڈ اس سے مماثل ہے جو ہم نے `splitter()` میں 0x103-0x10E میں دیکھا تھا (`JUMPI` کی منزل کے علاوہ)، لہذا ہم جانتے ہیں کہ `merkleRoot()` بھی `payable` نہیں ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------ | +| F9 | JUMPDEST | | +| FA | POP | | +| FB | PUSH2 0x00da | 0xDA | +| FE | PUSH1 0x00 | 0x00 0xDA | +| 100 | SLOAD | Storage[0] 0xDA | +| 101 | DUP2 | 0xDA Storage[0] 0xDA | +| 102 | JUMP | Storage[0] 0xDA | + +جمپ کے بعد کیا ہوتا ہے [یہ ہم پہلے ہی معلوم کر چکے ہیں](#the-da-code)۔ لہذا `merkleRoot()`، Storage[0] واپس کرتا ہے۔ + +## 0x81e580d3 {#0x81e580d3} + +آفسیٹس 0x138-0x143 میں موجود کوڈ اس سے مماثل ہے جو ہم نے `splitter()` میں 0x103-0x10E میں دیکھا تھا (`JUMPI` کی منزل کے علاوہ)، لہذا ہم جانتے ہیں کہ یہ فنکشن بھی `payable` نہیں ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ------------------------------------------------------------------------------- | +| 144 | JUMPDEST | | +| 145 | POP | | +| 146 | PUSH2 0x00da | 0xDA | +| 149 | PUSH2 0x0153 | 0x0153 0xDA | +| 14C | CALLDATASIZE | CALLDATASIZE 0x0153 0xDA | +| 14D | PUSH1 0x04 | 0x04 CALLDATASIZE 0x0153 0xDA | +| 14F | PUSH2 0x018f | 0x018F 0x04 CALLDATASIZE 0x0153 0xDA | +| 152 | JUMP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 18F | JUMPDEST | 0x04 CALLDATASIZE 0x0153 0xDA | +| 190 | PUSH1 0x00 | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 192 | PUSH1 0x20 | 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 194 | DUP3 | 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 195 | DUP5 | CALLDATASIZE 0x04 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 196 | SUB | CALLDATASIZE-4 0x20 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 197 | SLT | CALLDATASIZE-4\<32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 198 | ISZERO | CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 199 | PUSH2 0x01a0 | 0x01A0 CALLDATASIZE-4>=32 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19C | JUMPI | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | + +ایسا لگتا ہے کہ یہ فنکشن کم از کم 32 بائٹس (ایک لفظ) کال ڈیٹا لیتا ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------ | -------------------------------------------- | +| 19D | DUP1 | 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19E | DUP2 | 0x00 0x00 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 19F | REVERT | | + +اگر اسے کال ڈیٹا نہیں ملتا ہے تو ٹرانزیکشن بغیر کسی ریٹرن ڈیٹا کے ریورٹ ہو جاتی ہے۔ + +آئیے دیکھتے ہیں کہ اگر فنکشن کو _واقعی_ وہ کال ڈیٹا ملتا ہے جس کی اسے ضرورت ہے۔ + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | ----------------------------------------------------------- | +| 1A0 | JUMPDEST | 0x00 0x04 CALLDATASIZE 0x0153 0xDA | +| 1A1 | POP | 0x04 CALLDATASIZE 0x0153 0xDA | +| 1A2 | CALLDATALOAD | calldataload(4) CALLDATASIZE 0x0153 0xDA | + +`calldataload(4)` میتھڈ سگنیچر کے _بعد_ کال ڈیٹا کا پہلا لفظ ہے + +| آفسیٹ | Opcode | اسٹیک | +| ----: | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1A3 | SWAP2 | 0x0153 CALLDATASIZE calldataload(4) 0xDA | +| 1A4 | SWAP1 | CALLDATASIZE 0x0153 calldataload(4) 0xDA | +| 1A5 | POP | 0x0153 calldataload(4) 0xDA | +| 1A6 | JUMP | calldataload(4) 0xDA | +| 153 | JUMPDEST | calldataload(4) 0xDA | +| 154 | PUSH2 0x016e | 0x016E calldataload(4) 0xDA | +| 157 | JUMP | calldataload(4) 0xDA | +| 16E | JUMPDEST | calldataload(4) 0xDA | +| 16F | PUSH1 0x04 | 0x04 calldataload(4) 0xDA | +| 171 | DUP2 | calldataload(4) 0x04 calldataload(4) 0xDA | +| 172 | DUP2 | 0x04 calldataload(4) 0x04 calldataload(4) 0xDA | +| 173 | SLOAD | Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +| 174 | DUP2 | calldataload(4) Storage[4] calldataload(4) 0x04 calldataload(4) 0xDA | +| 175 | LT | calldataload(4)\)` ہے، اور دوسرا `isClaimed()` ہے، لہذا یہ ایک ایئر ڈراپ کنٹریکٹ کی طرح لگتا ہے۔ باقی کو opcode-به-opcode دیکھنے کے بجائے، ہم [ڈی کمپائلر کو آزما سکتے ہیں](https://etherscan.io/bytecode-decompiler?a=0x2f81e57ff4f4d83b40a9f719fd892d8e806e0761)، جو اس کنٹریکٹ سے تین فنکشنز کے لیے قابل استعمال نتائج دیتا ہے۔ باقی کی ریورس انجینئرنگ قارئین کے لیے ایک مشق کے طور پر چھوڑی گئی ہے۔ + +### scaleAmountByPercentage {#scaleamountbypercentage} + +یہ وہ ہے جو ڈی کمپائلر ہمیں اس فنکشن کے لیے دیتا ہے: + +```python +def unknown8ffb5c97(uint256 _param1, uint256 _param2) payable: + require calldata.size - 4 >=′ 64 + if _param1 and _param2 > -1 / _param1: + revert with 0, 17 + return (_param1 * _param2 / 100 * 10^6) +``` + +پہلا `require` یہ جانچتا ہے کہ کال ڈیٹا میں، فنکشن سگنیچر کے چار بائٹس کے علاوہ، کم از کم 64 بائٹس ہیں، جو دو پیرامیٹرز کے لیے کافی ہیں۔ اگر نہیں تو ظاہر ہے کچھ گڑبڑ ہے۔ + +`if` اسٹیٹمنٹ یہ چیک کرتا ہے کہ `_param1` صفر نہیں ہے، اور یہ کہ `_param1 * _param2` منفی نہیں ہے۔ یہ شاید ریپ اراؤنڈ کے کیسز کو روکنے کے لیے ہے۔ + +آخر میں، فنکشن ایک اسکیلڈ ویلیو واپس کرتا ہے۔ + +### claim {#claim} + +جو کوڈ ڈی کمپائلر بناتا ہے وہ پیچیدہ ہے، اور اس کا سارا حصہ ہمارے لیے متعلقہ نہیں ہے۔ میں اس کے کچھ حصوں کو چھوڑنے جا رہا ہوں تاکہ ان لائنوں پر توجہ مرکوز کی جا سکے جو میرے خیال میں مفید معلومات فراہم کرتی ہیں۔ + +```python +def unknown2e7ba6ef(uint256 _param1, uint256 _param2, uint256 _param3, array _param4) payable: + ... + require _param2 == addr(_param2) + ... + if currentWindow <= _param1: + revert with 0, 'cannot claim for a future window' +``` + +ہم یہاں دو اہم چیزیں دیکھتے ہیں: + +- `_param2`، اگرچہ اسے `uint256` کے طور پر ڈکلیئر کیا گیا ہے، دراصل ایک ایڈریس ہے +- `_param1` وہ ونڈو ہے جس کا دعوی کیا جا رہا ہے، جو `currentWindow` یا اس سے پہلے کی ہونی چاہیے۔ + +```python + ... + if stor5[_claimWindow][addr(_claimFor)]: + revert with 0, 'Account already claimed the given window' +``` + +تو اب ہم جانتے ہیں کہ Storage[5] ونڈوز اور ایڈریسز کا ایک ایرے ہے، اور یہ کہ کیا ایڈریس نے اس ونڈو کے لیے انعام کا دعوی کیا ہے۔ + +```python + ... + idx = 0 + s = 0 + while idx < _param4.length: + ... + if s + sha3(mem[(32 * _param4.length) + 328 len mem[(32 * _param4.length) + 296]]) > mem[(32 * idx) + 296]: + mem[mem[64] + 32] = mem[(32 * idx) + 296] + ... + s = sha3(mem[_62 + 32 len mem[_62]]) + continue + ... + s = sha3(mem[_66 + 32 len mem[_66]]) + continue + if unknown2eb4a7ab != s: + revert with 0, 'Invalid proof' +``` + +ہم جانتے ہیں کہ `unknown2eb4a7ab` دراصل فنکشن `merkleRoot()` ہے، لہذا یہ کوڈ ایسا لگتا ہے جیسے یہ ایک [merkle proof](https://medium.com/crypto-0-nite/merkle-proofs-explained-6dd429623dc5) کی تصدیق کر رہا ہے۔ اس کا مطلب یہ ہے کہ `_param4` ایک merkle proof ہے۔ + +```python + call addr(_param2) with: + value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei + gas 30000 wei +``` + +یہ وہ طریقہ ہے جس سے ایک کنٹریکٹ اپنے ETH کو دوسرے ایڈریس (کنٹریکٹ یا بیرونی ملکیت والے) میں منتقل کرتا ہے۔ یہ اسے ایک ایسی ویلیو کے ساتھ کال کرتا ہے جو منتقل کی جانے والی رقم ہے۔ تو ایسا لگتا ہے کہ یہ ETH کا ایک ایئر ڈراپ ہے۔ + +```python + if not return_data.size: + if not ext_call.success: + require ext_code.size(stor2) + call stor2.deposit() with: + value unknown81e580d3[_param1] * _param3 / 100 * 10^6 wei +``` + +نچلی دو لائنیں ہمیں بتاتی ہیں کہ Storage[2] بھی ایک کنٹریکٹ ہے جسے ہم کال کرتے ہیں۔ اگر ہم [کنسٹرکٹر ٹرانزیکشن کو دیکھیں](https://etherscan.io/tx/0xa1ea0549fb349eb7d3aff90e1d6ce7469fdfdcd59a2fd9b8d1f5e420c0d05b58#statechange) تو ہم دیکھتے ہیں کہ یہ کنٹریکٹ [0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2) ہے، جو ایک Wrapped Ether کنٹریکٹ ہے [جس کا سورس کوڈ Etherscan پر اپ لوڈ کیا گیا ہے](https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code)۔ + +تو ایسا لگتا ہے کہ کنٹریکٹس `_param2` کو ETH بھیجنے کی کوشش کرتے ہیں۔ اگر یہ کر سکتا ہے تو بہت اچھا۔ اگر نہیں، تو یہ [WETH](https://weth.tkn.eth.limo/) بھیجنے کی کوشش کرتا ہے۔ اگر `_param2` ایک بیرونی ملکیت والا اکاؤنٹ (EOA) ہے تو یہ ہمیشہ ETH وصول کر سکتا ہے، لیکن کنٹریکٹس ETH وصول کرنے سے انکار کر سکتے ہیں۔ تاہم، WETH ایک ERC-20 ہے اور کنٹریکٹس اسے قبول کرنے سے انکار نہیں کر سکتے۔ + +```python + ... + log 0xdbd5389f: addr(_param2), unknown81e580d3[_param1] * _param3 / 100 * 10^6, bool(ext_call.success) +``` + +فنکشن کے آخر میں ہم دیکھتے ہیں کہ ایک لاگ انٹری تیار کی جا رہی ہے۔ [تیار کردہ لاگ انٹریز کو دیکھیں](https://etherscan.io/address/0x2510c039cc3b061d79e564b38836da87e31b342f#events) اور اس موضوع پر فلٹر کریں جو `0xdbd5...` سے شروع ہوتا ہے۔ اگر ہم [ان ٹرانزیکشنز میں سے کسی ایک پر کلک کرتے ہیں جس نے ایسی انٹری تیار کی ہے](https://etherscan.io/tx/0xe7d3b7e00f645af17dfbbd010478ef4af235896c65b6548def1fe95b3b7d2274) تو ہم دیکھتے ہیں کہ واقعی یہ ایک دعوے کی طرح لگتا ہے - اکاؤنٹ نے اس کنٹریکٹ کو ایک پیغام بھیجا جس کی ہم ریورس انجینئرنگ کر رہے ہیں، اور بدلے میں اسے ETH ملا۔ + +![ایک دعوے کی ٹرانزیکشن](claim-tx.png) + +### 1e7df9d3 {#1e7df9d3} + +یہ فنکشن اوپر [`claim`](#claim) سے بہت ملتا جلتا ہے۔ یہ ایک merkle proof بھی چیک کرتا ہے، پہلے کو ETH منتقل کرنے کی کوشش کرتا ہے، اور اسی قسم کی لاگ انٹری تیار کرتا ہے۔ + +```python +def unknown1e7df9d3(uint256 _param1, uint256 _param2, array _param3) payable: + ... + idx = 0 + s = 0 + while idx < _param3.length: + if idx >= mem[96]: + revert with 0, 50 + _55 = mem[(32 * idx) + 128] + if s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]]) > mem[(32 * idx) + 128]: + ... + s = sha3(mem[_58 + 32 len mem[_58]]) + continue + mem[mem[64] + 32] = s + sha3(mem[(32 * _param3.length) + 160 len mem[(32 * _param3.length) + 128]]) + ... + if unknown2eb4a7ab != s: + revert with 0, 'Invalid proof' + ... + call addr(_param1) with: + value s wei + gas 30000 wei + if not return_data.size: + if not ext_call.success: + require ext_code.size(stor2) + call stor2.deposit() with: + value s wei + gas gas_remaining wei + ... + log 0xdbd5389f: addr(_param1), s, bool(ext_call.success) +``` + +بنیادی فرق یہ ہے کہ پہلا پیرامیٹر، یعنی جس ونڈو سے ودڈرا کرنا ہے، وہ وہاں نہیں ہے۔ اس کے بجائے، ان تمام ونڈوز پر ایک لوپ ہے جن کا دعوی کیا جا سکتا ہے۔ + +```python + idx = 0 + s = 0 + while idx < currentWindow: + ... + if stor5[mem[0]]: + if idx == -1: + revert with 0, 17 + idx = idx + 1 + s = s + continue + ... + stor5[idx][addr(_param1)] = 1 + if idx >= unknown81e580d3.length: + revert with 0, 50 + mem[0] = 4 + if unknown81e580d3[idx] and _param2 > -1 / unknown81e580d3[idx]: + revert with 0, 17 + if s > !(unknown81e580d3[idx] * _param2 / 100 * 10^6): + revert with 0, 17 + if idx == -1: + revert with 0, 17 + idx = idx + 1 + s = s + (unknown81e580d3[idx] * _param2 / 100 * 10^6) + continue +``` + +لہذا یہ ایک `claim` کا ویرینٹ لگتا ہے جو تمام ونڈوز کا دعوی کرتا ہے۔ + +## نتیجہ {#conclusion} + +اب تک آپ کو یہ جان لینا چاہیے کہ ان کنٹریکٹس کو کیسے سمجھا جائے جن کا سورس کوڈ دستیاب نہیں ہے، یا تو opcodes کا استعمال کرکے یا (جب یہ کام کرتا ہے) ڈی کمپائلر کا استعمال کرکے۔ جیسا کہ اس مضمون کی طوالت سے ظاہر ہے، ایک کنٹریکٹ کی ریورس انجینئرنگ کوئی معمولی کام نہیں ہے، لیکن ایک ایسے نظام میں جہاں سیکیورٹی ضروری ہے، یہ ایک اہم ہنر ہے کہ کنٹریکٹس کے وعدے کے مطابق کام کرنے کی تصدیق کی جا سکے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md new file mode 100644 index 00000000000..a65345098e8 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md @@ -0,0 +1,184 @@ +--- +title: "Raspeberry Pi 4 پر ایک ایتھیریم نوڈ چلائیں" +description: "اپنے Raspberry Pi 4 کو فلیش کریں، ایک ایتھرنیٹ کیبل لگائیں، SSD ڈسک کو جوڑیں اور Raspberry Pi 4 کو ایک مکمل ایتھیریم نوڈ + ویلیڈیٹر میں تبدیل کرنے کے لئے ڈیوائس کو پاور اپ کریں" +author: "EthereumOnArm" +tags: [ "کلائنٹس", "ایگزیکیوشن لیئر", "کنسینسس لیئر", "نوڈز" ] +lang: ur-in +skill: intermediate +published: 2022-06-10 +source: Ethereum on ARM +sourceUrl: https://ethereum-on-arm-documentation.readthedocs.io/en/latest/ +--- + +**ARM پر ایتھیریم ایک کسٹم لینکس امیج ہے جو Raspberry Pi کو ایتھیریم نوڈ میں تبدیل کر سکتا ہے۔** + +ARM پر ایتھیریم کا استعمال کرکے Raspberry Pi کو ایتھیریم نوڈ میں تبدیل کرنے کے لئے، درج ذیل ہارڈویئر کی سفارش کی جاتی ہے: + +- Raspberry 4 (model B 8GB), Odroid M1 or Rock 5B (8GB/16GB RAM) board +- مائیکرو ایس ڈی کارڈ (کم از کم 16 جی بی کلاس 10) +- کم از کم 2 TB SSD USB 3.0 ڈسک یا USB سے SATA کیس کے ساتھ ایک SSD۔ +- پاور سپلائی +- ایتھرنیٹ کیبل +- پورٹ فارورڈنگ (مزید معلومات کے لئے کلائنٹس دیکھیں) +- ہیٹ سنک اور پنکھے کے ساتھ ایک کیس +- USB کی بورڈ، مانیٹر اور HDMI کیبل (مائیکرو-HDMI) (اختیاری) + +## ARM پر ایتھیریم کیوں چلائیں؟ {#why-run-ethereum-on-arm} + +ARM بورڈز بہت سستے، لچکدار، چھوٹے کمپیوٹر ہیں۔ یہ ایتھیریم نوڈس چلانے کے لئے اچھے انتخاب ہیں کیونکہ انہیں سستے میں خریدا جا سکتا ہے، اس طرح کنفیگر کیا جا سکتا ہے کہ ان کے تمام وسائل صرف نوڈ پر مرکوز ہوں، جس سے وہ موثر بن جاتے ہیں، وہ کم مقدار میں بجلی استعمال کرتے ہیں اور جسمانی طور پر چھوٹے ہوتے ہیں تاکہ وہ کسی بھی گھر میں غیر محسوس طریقے سے فٹ ہو سکیں۔ نوڈس کو اسپن اپ کرنا بھی بہت آسان ہے کیونکہ Raspberry Pi کے مائیکرو ایس ڈی کو پہلے سے تیار کردہ امیج کے ساتھ آسانی سے فلیش کیا جا سکتا ہے، جس میں کسی سافٹ ویئر کو ڈاؤن لوڈ یا بنانے کی ضرورت نہیں ہوتی۔ + +## یہ کیسے کام کرتا ہے؟ {#how-does-it-work} + +Raspberry Pi کا میموری کارڈ پہلے سے تیار کردہ امیج کے ساتھ فلیش کیا جاتا ہے۔ اس امیج میں ایتھیریم نوڈ چلانے کے لئے درکار ہر چیز موجود ہے۔ فلیش شدہ کارڈ کے ساتھ، صارف کو صرف Raspberry Pi کو پاور آن کرنا ہے۔ نوڈ کو چلانے کے لئے درکار تمام پروسیسز خود بخود شروع ہو جاتے ہیں۔ یہ اس لئے کام کرتا ہے کیونکہ میموری کارڈ میں ایک لینکس پر مبنی آپریٹنگ سسٹم (OS) ہوتا ہے جس کے اوپر سسٹم لیول کے پروسیسز خود بخود چلتے ہیں جو یونٹ کو ایک ایتھیریم نوڈ میں تبدیل کر دیتے ہیں۔ + +ایتھیریم کو مقبول Raspberry Pi لینکس OS "Raspbian" کا استعمال کرکے نہیں چلایا جا سکتا کیونکہ Raspbian اب بھی 32-بٹ آرکیٹیکچر کا استعمال کرتا ہے جس کی وجہ سے ایتھیریم صارفین کو میموری کے مسائل کا سامنا کرنا پڑتا ہے اور کنسنسس کلائنٹس 32-بٹ بائنریز کو سپورٹ نہیں کرتے ہیں۔ اس پر قابو پانے کے لئے، Ethereum on Arm ٹیم "Armbian" نامی ایک مقامی 64-بٹ OS پر منتقل ہو گئی۔ + +**امیجز تمام ضروری مراحل کا خیال رکھتی ہیں**، ماحول کو ترتیب دینے اور SSD ڈسک کو فارمیٹ کرنے سے لے کر ایتھیریم سافٹ ویئر کو انسٹال کرنے اور چلانے کے ساتھ ساتھ بلاکچین سنکرونائزیشن شروع کرنے تک۔ + +## ایگزیکیوشن اور کنسنسس کلائنٹس پر نوٹ {#note-on-execution-and-consensus-clients} + +ARM پر ایتھیریم امیج میں پہلے سے تیار کردہ ایگزیکیوشن اور کنسنسس کلائنٹس بطور سروسز شامل ہیں۔ ایک ایتھیریم نوڈ کو دونوں کلائنٹس کو سنک اور چلانے کی ضرورت ہوتی ہے۔ آپ کو صرف امیج ڈاؤن لوڈ اور فلیش کرنا ہے اور پھر سروسز شروع کرنی ہیں۔ امیج درج ذیل ایگزیکیوشن کلائنٹس کے ساتھ پہلے سے لوڈ شدہ ہے: + +- Geth +- Nethermind +- Besu + +اور درج ذیل کنسنسس کلائنٹس: + +- Lighthouse +- Nimbus +- Prysm +- Teku + +آپ کو چلانے کے لئے ہر ایک میں سے ایک کا انتخاب کرنا چاہئے - تمام ایگزیکیوشن کلائنٹس تمام کنسنسس کلائنٹس کے ساتھ مطابقت رکھتے ہیں۔ اگر آپ واضح طور پر کسی کلائنٹ کا انتخاب نہیں کرتے ہیں، تو نوڈ اپنے ڈیفالٹس - Geth اور Lighthouse - پر واپس آ جائے گا اور بورڈ کے پاور اپ ہونے پر انہیں خود بخود چلا دے گا۔ آپ کو اپنے راؤٹر پر پورٹ 30303 کھولنا ہوگا تاکہ Geth پیئرز کو تلاش اور ان سے منسلک ہو سکے۔ + +## امیج ڈاؤن لوڈ کرنا {#downloading-the-image} + +Raspberry Pi 4 ایتھیریم امیج ایک "پلگ اینڈ پلے" امیج ہے جو خود بخود ایگزیکیوشن اور کنسنسس کلائنٹس دونوں کو انسٹال اور سیٹ اپ کرتا ہے، انہیں ایک دوسرے سے بات کرنے اور ایتھیریم نیٹ ورک سے منسلک ہونے کے لئے کنفیگر کرتا ہے۔ صارف کو صرف ایک سادہ کمانڈ کا استعمال کرکے اپنے پروسیسز شروع کرنے کی ضرورت ہے۔ + +[Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1) سے Raspberry Pi امیج ڈاؤن لوڈ کریں اور SHA256 ہیش کی تصدیق کریں: + +```sh +# ڈاؤن لوڈ کی گئی امیج والی ڈائریکٹری سے +shasum -a 256 ethonarm_22.04.00.img.zip +# ہیش کا آؤٹ پٹ ہونا چاہئے: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f +``` + +نوٹ کریں کہ Rock 5B اور Odroid M1 بورڈز کے لئے امیجز Ethereum-on-Arm [ڈاؤن لوڈز پیج](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html) پر دستیاب ہیں۔ + +## مائیکرو ایس ڈی کو فلیش کرنا {#flashing-the-microsd} + +جو مائیکرو ایس ڈی کارڈ Raspberry Pi کے لئے استعمال کیا جائے گا اسے پہلے ڈیسک ٹاپ یا لیپ ٹاپ میں ڈالا جانا چاہئے تاکہ اسے فلیش کیا جا سکے۔ پھر، درج ذیل ٹرمینل کمانڈز ڈاؤن لوڈ کی گئی امیج کو ایس ڈی کارڈ پر فلیش کریں گے: + +```shell +# مائیکرو ایس ڈی کارڈ کا نام چیک کریں +sudo fdisk -l + +>> sdxxx +``` + +نام کو صحیح طریقے سے حاصل کرنا بہت ضروری ہے کیونکہ اگلی کمانڈ میں `dd` شامل ہے جو کارڈ پر امیج کو پش کرنے سے پہلے اس کے موجودہ مواد کو مکمل طور پر مٹا دیتا ہے۔ جاری رکھنے کے لئے، زپ شدہ امیج والی ڈائریکٹری پر جائیں: + +```shell +# امیج کو ان زپ اور فلیش کریں +unzip ethonarm_22.04.00.img.zip +sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress +``` + +کارڈ اب فلیش ہو چکا ہے، لہذا اسے Raspberry Pi میں ڈالا جا سکتا ہے۔ + +## نوڈ شروع کریں {#start-the-node} + +ایس ڈی کارڈ کو Raspberry Pi میں ڈالنے کے بعد، ایتھرنیٹ کیبل اور SSD کو جوڑیں اور پھر پاور آن کریں۔ OS بوٹ اپ ہو گا اور خود بخود پہلے سے کنفیگر شدہ کام انجام دینا شروع کر دے گا جو Raspberry Pi کو ایک ایتھیریم نوڈ میں تبدیل کرتے ہیں، بشمول کلائنٹ سافٹ ویئر کو انسٹال کرنا اور بنانا۔ اس میں شاید 10-15 منٹ لگیں گے۔ + +ایک بار جب سب کچھ انسٹال اور کنفیگر ہو جائے، تو ssh کنکشن کے ذریعے ڈیوائس میں لاگ ان کریں یا اگر بورڈ سے مانیٹر اور کی بورڈ منسلک ہو تو براہ راست ٹرمینل کا استعمال کریں۔ لاگ ان کرنے کے لئے `ethereum` اکاؤنٹ کا استعمال کریں، کیونکہ اس کے پاس نوڈ شروع کرنے کے لئے درکار اجازتیں ہیں۔ + +```shell +صارف: ethereum +پاس ورڈ: ethereum +``` + +ڈیفالٹ ایگزیکیوشن کلائنٹ، Geth، خود بخود شروع ہو جائے گا۔ آپ درج ذیل ٹرمینل کمانڈ کا استعمال کرکے لاگز کو چیک کرکے اس کی تصدیق کر سکتے ہیں: + +```sh +sudo journalctl -u geth -f +``` + +کنسنسس کلائنٹ کو واضح طور پر شروع کرنے کی ضرورت ہے۔ ایسا کرنے کے لئے، پہلے اپنے راؤٹر پر پورٹ 9000 کھولیں تاکہ Lighthouse پیئرز کو تلاش اور ان سے منسلک ہو سکے۔ پھر لائٹ ہاؤس سروس کو فعال اور شروع کریں: + +```sh +sudo systemctl enable lighthouse-beacon +sudo systemctl start lighthouse-beacon +``` + +لاگز کا استعمال کرکے کلائنٹ کو چیک کریں: + +```sh +sudo journalctl -u lighthouse-beacon +``` + +نوٹ کریں کہ کنسنسس کلائنٹ چند منٹوں میں سنک ہو جائے گا کیونکہ یہ چیک پوائنٹ سنک کا استعمال کرتا ہے۔ ایگزیکیوشن کلائنٹ میں زیادہ وقت لگے گا - ممکنہ طور پر کئی گھنٹے، اور یہ تب تک شروع نہیں ہو گا جب تک کہ کنسنسس کلائنٹ پہلے ہی سنکنگ ختم نہ کر لے۔ (اس کی وجہ یہ ہے کہ ایگزیکیوشن کلائنٹ کو سنک کرنے کے لئے ایک ہدف کی ضرورت ہوتی ہے، جو سنک شدہ کنسنسس کلائنٹ فراہم کرتا ہے)۔ + +Geth اور Lighthouse سروسز کے چلنے اور سنک ہونے کے ساتھ، آپ کا Raspberry Pi اب ایک ایتھیریم نوڈ ہے! ایتھیریم نیٹ ورک کے ساتھ تعامل کرنے کا سب سے عام طریقہ Geth کے جاوا اسکرپٹ کنسول کا استعمال کرنا ہے، جسے پورٹ 8545 پر Geth کلائنٹ سے منسلک کیا جا سکتا ہے۔ Curl جیسے ریکوئسٹ ٹول کا استعمال کرکے JSON آبجیکٹس کے طور پر فارمیٹ شدہ کمانڈز کو جمع کرنا بھی ممکن ہے۔ مزید [Geth دستاویزات](https://geth.ethereum.org/) میں دیکھیں۔ + +Geth کو ایک Grafana ڈیش بورڈ پر میٹرکس رپورٹ کرنے کے لئے پہلے سے کنفیگر کیا گیا ہے جسے براؤزر میں دیکھا جا سکتا ہے۔ مزید جدید صارفین اس فیچر کا استعمال `ipaddress:3000` پر جا کر، `user: admin` اور `passwd: ethereum` پاس کرکے اپنے نوڈ کی صحت کی نگرانی کے لئے کرنا چاہ سکتے ہیں۔ + +## ویلیڈیٹرز {#validators} + +کنسنسس کلائنٹ میں اختیاری طور پر ایک ویلیڈیٹر بھی شامل کیا جا سکتا ہے۔ ویلیڈیٹر سافٹ ویئر آپ کے نوڈ کو کنسنسس میں فعال طور پر حصہ لینے کی اجازت دیتا ہے اور نیٹ ورک کو کرپٹو اکنامک سیکیورٹی فراہم کرتا ہے۔ آپ کو اس کام کے لئے ETH میں انعام دیا جاتا ہے۔ ایک ویلیڈیٹر چلانے کے لئے، آپ کے پاس پہلے 32 ETH ہونا چاہئے، جو ڈیپازٹ کنٹریکٹ میں جمع کرانا ضروری ہے۔ ڈیپازٹ [لانچ پیڈ](https://launchpad.ethereum.org/) پر مرحلہ وار گائیڈ پر عمل کرکے کیا جا سکتا ہے۔ یہ ڈیسک ٹاپ/لیپ ٹاپ پر کریں، لیکن کیز (keys) نہ بنائیں — یہ براہ راست Raspberry Pi پر کیا جا سکتا ہے۔ + +Raspberry Pi پر ایک ٹرمینل کھولیں اور ڈیپازٹ کیز بنانے کے لئے درج ذیل کمانڈ چلائیں: + +``` +sudo apt-get update +sudo apt-get install staking-deposit-cli +cd && deposit new-mnemonic --num_validators 1 +``` + +(یا [staking-deposit-cli](https://github.com/ethereum/staking-deposit-cli) ڈاؤن لوڈ کریں تاکہ اسے ایئر گیپڈ مشین پر چلایا جا سکے، اور `deposit new-mnemnonic` کمانڈ چلائیں) + +نیمونک فریز کو محفوظ رکھیں! مذکورہ بالا کمانڈ نے نوڈ کے کیسٹور میں دو فائلیں بنائیں: ویلیڈیٹر کیز اور ایک ڈیپازٹ ڈیٹا فائل۔ ڈیپازٹ ڈیٹا کو لانچ پیڈ میں اپ لوڈ کرنے کی ضرورت ہے، لہذا اسے Raspberry Pi سے ڈیسک ٹاپ/لیپ ٹاپ پر کاپی کرنا ضروری ہے۔ یہ ssh کنکشن یا کسی دوسرے کاپی/پیسٹ طریقے کا استعمال کرکے کیا جا سکتا ہے۔ + +ایک بار جب ڈیپازٹ ڈیٹا فائل لانچ پیڈ چلانے والے کمپیوٹر پر دستیاب ہو جاتی ہے، تو اسے لانچ پیڈ اسکرین پر `+` پر ڈریگ اور ڈراپ کیا جا سکتا ہے۔ ڈیپازٹ کنٹریکٹ کو ٹرانزیکشن بھیجنے کے لئے اسکرین پر دی گئی ہدایات پر عمل کریں۔ + +واپس Raspberry Pi پر، ایک ویلیڈیٹر شروع کیا جا سکتا ہے۔ اس کے لئے ویلیڈیٹر کیز کو امپورٹ کرنے، انعامات جمع کرنے کے لئے ایڈریس سیٹ کرنے، اور پھر پہلے سے کنفیگر شدہ ویلیڈیٹر پروسیس شروع کرنے کی ضرورت ہوتی ہے۔ نیچے دی گئی مثال Lighthouse کے لئے ہے — دوسرے کنسنسس کلائنٹس کے لئے ہدایات [Ethereum on Arm docs](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) پر دستیاب ہیں: + +```shell +# ویلیڈیٹر کیز امپورٹ کریں +lighthouse account validator import --directory=/home/ethereum/validator_keys + +# انعام کا ایڈریس سیٹ کریں +sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf + +# ویلیڈیٹر شروع کریں +sudo systemctl start lighthouse-validator +``` + +مبارک ہو، اب آپ کے پاس Raspberry Pi پر ایک مکمل ایتھیریم نوڈ اور ویلیڈیٹر چل رہا ہے! + +## مزید تفصیلات {#more-details} + +اس صفحے نے Raspberry Pi کا استعمال کرکے Geth-Lighthouse نوڈ اور ویلیڈیٹر کو کیسے سیٹ اپ کیا جائے اس کا ایک جائزہ دیا۔ مزید تفصیلی ہدایات [Ethereum-on-Arm ویب سائٹ](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/index.html) پر دستیاب ہیں۔ + +## فیڈ بیک کی تعریف کی جاتی ہے {#feedback-appreciated} + +ہم جانتے ہیں کہ Raspberry Pi کا ایک بہت بڑا صارف بیس ہے جو ایتھیریم نیٹ ورک کی صحت پر بہت مثبت اثر ڈال سکتا ہے۔ +براہ کرم اس ٹیوٹوریل میں تفصیلات کو دیکھیں، ٹیسٹ نیٹس پر چلانے کی کوشش کریں، Ethereum on Arm GitHub کو چیک کریں، فیڈ بیک دیں، مسائل اٹھائیں اور پل ریکوئسٹس کریں اور ٹیکنالوجی اور دستاویزات کو آگے بڑھانے میں مدد کریں! + +## حوالہ جات {#references} + +1. https://ubuntu.com/download/raspberry-pi +2. https://wikipedia.org/wiki/Port_forwarding +3. https://prometheus.io +4. https://grafana.com +5. https://forum.armbian.com/topic/5565-zram-vs-swap/ +6. https://geth.ethereum.org +7. https://nethermind.io +8. https://www.hyperledger.org/projects/besu +9. https://github.com/prysmaticlabs/prysm +10. https://lighthouse.sigmaprime.io +11. https://ethersphere.github.io/swarm-home +12. https://raiden.network +13. https://ipfs.io +14. https://status.im +15. https://vipnode.org diff --git a/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md b/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md new file mode 100644 index 00000000000..cd13821ad5b --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md @@ -0,0 +1,470 @@ +--- +title: "اسکیم ٹوکنز کے ذریعہ استعمال ہونے والی کچھ ترکیبیں اور ان کا پتہ لگانے کا طریقہ" +description: "اس ٹیوٹوریل میں ہم ایک اسکیم ٹوکن کا تجزیہ کرتے ہیں تاکہ یہ دیکھ سکیں کہ اسکامرس کونسی ترکیبیں استعمال کرتے ہیں، وہ انہیں کیسے نافذ کرتے ہیں، اور ہم ان کا پتہ کیسے لگا سکتے ہیں۔" +author: Ori Pomerantz +tags: + [ + "اسکیم", + "solidity", + "erc-20", + "javascript", + "typescript" + ] +skill: intermediate +published: 2023-09-15 +lang: ur-in +--- + +اس ٹیوٹوریل میں ہم [ایک اسکیم ٹوکن](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code) کا تجزیہ کرتے ہیں تاکہ یہ دیکھ سکیں کہ اسکامرس کونسی ترکیبیں استعمال کرتے ہیں اور وہ انہیں کیسے نافذ کرتے ہیں۔ ٹیوٹوریل کے اختتام تک آپ کو ERC-20 ٹوکن معاہدوں، ان کی صلاحیتوں، اور شکوک و شبہات کی ضرورت کیوں ہے اس کا ایک زیادہ جامع نظریہ حاصل ہو جائے گا۔ پھر ہم اس اسکیم ٹوکن کے ذریعہ جاری کردہ ایونٹس کو دیکھتے ہیں اور دیکھتے ہیں کہ ہم خود بخود اس کی شناخت کیسے کرسکتے ہیں کہ یہ قانونی نہیں ہے۔ + +## اسکیم ٹوکنز - وہ کیا ہیں، لوگ انہیں کیوں کرتے ہیں، اور ان سے کیسے بچا جائے {#scam-tokens} + +ایتھیریم کے سب سے عام استعمالات میں سے ایک یہ ہے کہ ایک گروپ ایک قابل تجارت ٹوکن بنائے، ایک طرح سے ان کی اپنی کرنسی۔ تاہم، جہاں کہیں بھی جائز استعمال کے معاملات ہیں جو قدر لاتے ہیں، وہاں مجرم بھی ہیں جو اس قدر کو اپنے لیے چرانے کی کوشش کرتے ہیں۔ + +آپ اس موضوع کے بارے میں مزید [ethereum.org پر کہیں اور](/guides/how-to-id-scam-tokens/) صارف کے نقطہ نظر سے پڑھ سکتے ہیں۔ یہ ٹیوٹوریل ایک اسکیم ٹوکن کا تجزیہ کرنے پر مرکوز ہے تاکہ یہ دیکھا جا سکے کہ یہ کیسے کیا جاتا ہے اور اس کا پتہ کیسے لگایا جا سکتا ہے۔ + +### مجھے کیسے پتہ چلے گا کہ wARB ایک اسکیم ہے؟ {#warb-scam} + +جس ٹوکن کا ہم تجزیہ کر رہے ہیں وہ [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code) ہے، جو کہ قانونی [ARB ٹوکن](https://etherscan.io/token/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1) کے برابر ہونے کا بہانہ کرتا ہے۔ + +یہ جاننے کا سب سے آسان طریقہ کہ کونسا ٹوکن قانونی ہے، اس کی اصلی تنظیم [Arbitrum](https://arbitrum.foundation/) کو دیکھنا ہے۔ جائز پتے [ان کی دستاویزات](https://docs.arbitrum.foundation/deployment-addresses#token) میں بتائے گئے ہیں۔ + +### سورس کوڈ کیوں دستیاب ہے؟ {#why-source} + +عام طور پر ہم توقع کرتے ہیں کہ جو لوگ دوسروں کو اسکیم کرنے کی کوشش کرتے ہیں وہ خفیہ ہوتے ہیں، اور واقعی بہت سے اسکیم ٹوکنز کا کوڈ دستیاب نہیں ہوتا ہے (مثال کے طور پر، [یہ والا](https://optimistic.etherscan.io/token/0x15992f382d8c46d667b10dc8456dc36651af1452#code) اور [یہ والا](https://optimistic.etherscan.io/token/0x026b623eb4aada7de37ef25256854f9235207178#code))۔ + +تاہم، قانونی ٹوکن عام طور پر اپنے سورس کوڈ کو شائع کرتے ہیں، لہذا قانونی نظر آنے کے لیے اسکیم ٹوکنز کے مصنفین کبھی کبھی ایسا ہی کرتے ہیں۔ [wARB](https://etherscan.io/token/0xb047c8032b99841713b8e3872f06cf32beb27b82#code) ان ٹوکنز میں سے ایک ہے جن کا سورس کوڈ دستیاب ہے، جس سے اسے سمجھنا آسان ہو جاتا ہے۔ + +جبکہ کنٹریکٹ ڈیپلائرز یہ انتخاب کر سکتے ہیں کہ سورس کوڈ کو شائع کرنا ہے یا نہیں، وہ _غلط_ سورس کوڈ شائع نہیں کر سکتے۔ بلاک ایکسپلورر فراہم کردہ سورس کوڈ کو آزادانہ طور پر کمپائل کرتا ہے، اور اگر اسے بالکل وہی بائٹ کوڈ نہیں ملتا ہے، تو وہ اس سورس کوڈ کو مسترد کر دیتا ہے۔ [آپ اس بارے میں Etherscan سائٹ پر مزید پڑھ سکتے ہیں](https://etherscan.io/verifyContract)۔ + +## جائز ERC-20 ٹوکنز سے موازنہ {#compare-legit-erc20} + +ہم اس ٹوکن کا موازنہ قانونی ERC-20 ٹوکنز سے کرنے جا رہے ہیں۔ اگر آپ اس بات سے واقف نہیں ہیں کہ قانونی ERC-20 ٹوکن عام طور پر کیسے لکھے جاتے ہیں، [تو یہ ٹیوٹوریل دیکھیں](/developers/tutorials/erc20-annotated-code/)۔ + +### مراعات یافتہ پتوں کے لیے مستقل {#constants-for-privileged-addresses} + +معاہدوں کو کبھی کبھی مراعات یافتہ پتوں کی ضرورت ہوتی ہے۔ طویل مدتی استعمال کے لیے بنائے گئے معاہدے کچھ مراعات یافتہ پتوں کو ان پتوں کو تبدیل کرنے کی اجازت دیتے ہیں، مثال کے طور پر ایک نئے ملٹی سگ معاہدے کے استعمال کو فعال کرنے کے لیے۔ ایسا کرنے کے کئی طریقے ہیں۔ + +[`HOP` ٹوکن کنٹریکٹ](https://etherscan.io/address/0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc#code) [`Ownable`](https://docs.openzeppelin.com/contracts/2.x/access-control#ownership-and-ownable) پیٹرن کا استعمال کرتا ہے۔ مراعات یافتہ پتہ اسٹوریج میں رکھا جاتا ہے، ایک فیلڈ میں جسے `_owner` کہا جاتا ہے (تیسری فائل، `Ownable.sol` دیکھیں)۔ + +```solidity +abstract contract Ownable is Context { + address private _owner; + . + . + . +} +``` + +[`ARB` ٹوکن کنٹریکٹ](https://etherscan.io/address/0xad0c361ef902a7d9851ca7dcc85535da2d3c6fc7#code) کا براہ راست کوئی مراعات یافتہ پتہ نہیں ہے۔ تاہم، اسے کسی کی ضرورت نہیں ہے۔ یہ [ایڈریس `0xb50721bcf8d664c30412cfbc6cf7a15145234ad1`](https://etherscan.io/address/0xb50721bcf8d664c30412cfbc6cf7a15145234ad1#code) پر [`پراکسی`](https://docs.openzeppelin.com/contracts/5.x/api/proxy) کے پیچھے بیٹھتا ہے۔ اس معاہدے کا ایک مراعات یافتہ پتہ ہے (چوتھی فائل، `ERC1967Upgrade.sol` دیکھیں) جسے اپ گریڈ کے لیے استعمال کیا جا سکتا ہے۔ + +```solidity + /** + * @dev EIP1967 ایڈمن سلاٹ میں ایک نیا پتہ اسٹور کرتا ہے۔ + */ + function _setAdmin(address newAdmin) private { + require(newAdmin != address(0), "ERC1967: new admin is the zero address"); + StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; + } +``` + +اس کے برعکس، `wARB` کنٹریکٹ میں ایک ہارڈ کوڈڈ `contract_owner` ہے۔ + +```solidity +contract WrappedArbitrum is Context, IERC20 { + . + . + . + address deployer = 0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1; + address public contract_owner = 0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33; + . + . + . +} +``` + +[یہ کنٹریکٹ کا مالک](https://etherscan.io/address/0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33) ایسا کنٹریکٹ نہیں ہے جسے مختلف اوقات میں مختلف اکاؤنٹس کے ذریعے کنٹرول کیا جا سکے، بلکہ ایک [بیرونی ملکیت والا اکاؤنٹ](/developers/docs/accounts/#externally-owned-accounts-and-key-pairs) ہے۔ اس کا مطلب یہ ہے کہ یہ شاید کسی فرد کے ذریعہ قلیل مدتی استعمال کے لئے ڈیزائن کیا گیا ہے، بجائے اس کے کہ ایک ERC-20 کو کنٹرول کرنے کے لئے طویل مدتی حل کے طور پر جو قابل قدر رہے گا۔ + +اور واقعی، اگر ہم Etherscan میں دیکھیں تو ہم دیکھتے ہیں کہ اسکیمر نے اس معاہدے کو صرف 12 گھنٹے کے لیے استعمال کیا ([پہلی ٹرانزیکشن](https://etherscan.io/tx/0xf49136198c3f925fcb401870a669d43cecb537bde36eb8b41df77f06d5f6fbc2) سے [آخری ٹرانزیکشن](https://etherscan.io/tx/0xdfd6e717157354e64bbd5d6adf16761e5a5b3f914b1948d3545d39633244d47b) تک) 19 مئی 2023 کے دوران۔ + +### جعلی `_transfer` فنکشن {#the-fake-transfer-function} + +یہ معیاری ہے کہ اصل منتقلی [اندرونی `_transfer` فنکشن](/developers/tutorials/erc20-annotated-code/#the-_transfer-function-_transfer) کا استعمال کرتے ہوئے ہوتی ہے۔ + +`wARB` میں یہ فنکشن تقریباً جائز لگتا ہے: + +```solidity + function _transfer(address sender, address recipient, uint256 amount) internal virtual{ + require(sender != address(0), "ERC20: صفر پتے سے منتقلی"); + require(recipient != address(0), "ERC20: صفر پتے پر منتقلی"); + + _beforeTokenTransfer(sender, recipient, amount); + + _balances[sender] = _balances[sender].sub(amount, "ERC20: منتقلی کی رقم بیلنس سے زیادہ ہے"); + _balances[recipient] = _balances[recipient].add(amount); + if (sender == contract_owner){ + sender = deployer; + } + emit Transfer(sender, recipient, amount); + } +``` + +مشکوک حصہ یہ ہے: + +```solidity + if (sender == contract_owner){ + sender = deployer; + } + emit Transfer(sender, recipient, amount); +``` + +اگر کنٹریکٹ کا مالک ٹوکن بھیجتا ہے، تو `Transfer` ایونٹ کیوں دکھاتا ہے کہ وہ `deployer` سے آئے ہیں؟ + +تاہم، ایک اور اہم مسئلہ ہے۔ اس `_transfer` فنکشن کو کون کال کرتا ہے؟ اسے باہر سے کال نہیں کیا جا سکتا، اسے `internal` نشان زد کیا گیا ہے۔ اور ہمارے پاس موجود کوڈ میں `_transfer` کی کوئی کال شامل نہیں ہے۔ ظاہر ہے، یہ یہاں ایک دھوکے کے طور پر ہے۔ + +```solidity + function transfer(address recipient, uint256 amount) public virtual override returns (bool) { + _f_(_msgSender(), recipient, amount); + return true; + } + + function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { + _f_(sender, recipient, amount); + _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: منتقلی کی رقم الاؤنس سے زیادہ ہے")); + return true; + } +``` + +جب ہم ٹوکن منتقل کرنے کے لیے کال کیے جانے والے فنکشنز، `transfer` اور `transferFrom` کو دیکھتے ہیں، تو ہم دیکھتے ہیں کہ وہ ایک بالکل مختلف فنکشن `_f_` کو کال کرتے ہیں۔ + +### اصلی `_f_` فنکشن {#the-real-f-function} + +```solidity + function _f_(address sender, address recipient, uint256 amount) internal _mod_(sender,recipient,amount) virtual { + require(sender != address(0), "ERC20: صفر پتے سے منتقلی"); + require(recipient != address(0), "ERC20: صفر پتے پر منتقلی"); + + _beforeTokenTransfer(sender, recipient, amount); + + _balances[sender] = _balances[sender].sub(amount, "ERC20: منتقلی کی رقم بیلنس سے زیادہ ہے"); + _balances[recipient] = _balances[recipient].add(amount); + if (sender == contract_owner){ + + sender = deployer; + } + emit Transfer(sender, recipient, amount); + } +``` + +اس فنکشن میں دو ممکنہ خطرے کی علامتیں ہیں۔ + +- [فنکشن موڈیفائر](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) `_mod_` کا استعمال۔ تاہم، جب ہم سورس کوڈ میں دیکھتے ہیں تو ہمیں معلوم ہوتا ہے کہ `_mod_` دراصل بے ضرر ہے۔ + + ```solidity + modifier _mod_(address sender, address recipient, uint256 amount){ + _; + } + ``` + +- وہی مسئلہ جو ہم نے `_transfer` میں دیکھا تھا، جو یہ ہے کہ جب `contract_owner` ٹوکن بھیجتا ہے تو وہ `deployer` سے آتے ہوئے دکھائی دیتے ہیں۔ + +### جعلی ایونٹس کا فنکشن `dropNewTokens` {#the-fake-events-function-dropNewTokens} + +اب ہم ایک ایسی چیز پر آتے ہیں جو ایک حقیقی اسکیم کی طرح نظر آتی ہے۔ میں نے پڑھنے میں آسانی کے لیے فنکشن میں تھوڑی ترمیم کی ہے، لیکن یہ فعال طور پر مساوی ہے۔ + +```solidity +function dropNewTokens(address uPool, + address[] memory eReceiver, + uint256[] memory eAmounts) public auth() +``` + +اس فنکشن میں `auth()` موڈیفائر ہے، جس کا مطلب ہے کہ اسے صرف کنٹریکٹ کا مالک ہی کال کر سکتا ہے۔ + +```solidity +modifier auth() { + require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + _; +} +``` + +یہ پابندی بالکل منطقی ہے، کیونکہ ہم نہیں چاہیں گے کہ بے ترتیب اکاؤنٹس ٹوکن تقسیم کریں۔ تاہم، باقی فنکشن مشکوک ہے۔ + +```solidity +{ + for (uint256 i = 0; i < eReceiver.length; i++) { + emit Transfer(uPool, eReceiver[i], eAmounts[i]); + } +} +``` + +ایک پول اکاؤنٹ سے وصول کنندگان کی ایک صف میں رقوم کی ایک صف میں منتقل کرنے کا ایک فنکشن بالکل منطقی ہے۔ بہت سے استعمال کے معاملات ہیں جن میں آپ ایک ہی ذریعہ سے متعدد مقامات پر ٹوکن تقسیم کرنا چاہیں گے، جیسے پے رول، ایئر ڈراپس وغیرہ۔ یہ ایک ہی ٹرانزیکشن میں کرنا (گیس میں) سستا ہے بجائے اس کے کہ متعدد ٹرانزیکشنز جاری کی جائیں، یا یہاں تک کہ ایک ہی ٹرانزیکشن کے حصے کے طور پر ایک مختلف کنٹریکٹ سے ERC-20 کو متعدد بار کال کیا جائے۔ + +`dropNewTokens` ایسا نہیں کرتا ہے۔ یہ [`Transfer` ایونٹس](https://eips.ethereum.org/EIPS/eip-20#transfer-1) خارج کرتا ہے، لیکن اصل میں کوئی ٹوکن منتقل نہیں کرتا ہے۔ آف چین ایپلیکیشنز کو ایک ایسی منتقلی کے بارے میں بتا کر الجھانے کی کوئی جائز وجہ نہیں ہے جو واقعی نہیں ہوئی تھی۔ + +### جلانے والا `Approve` فنکشن {#the-burning-approve-function} + +ERC-20 کنٹریکٹس میں الاؤنس کے لیے [ایک `approve` فنکشن](/developers/tutorials/erc20-annotated-code/#approve) ہونا چاہیے، اور واقعی ہمارے اسکیم ٹوکن میں ایسا فنکشن ہے، اور یہ درست بھی ہے۔ تاہم، چونکہ Solidity C سے ماخوذ ہے، یہ کیس کے لحاظ سے اہم ہے۔ `Approve` اور `approve` مختلف اسٹرنگز ہیں۔ + +نیز، فعالیت کا تعلق `approve` سے نہیں ہے۔ + +```solidity + function Approve( + address[] memory holders) +``` + +اس فنکشن کو ٹوکن کے ہولڈرز کے لیے پتوں کی ایک صف کے ساتھ کال کیا جاتا ہے۔ + +```solidity + public approver() { +``` + +`approver()` موڈیفائر اس بات کو یقینی بناتا ہے کہ صرف `contract_owner` کو اس فنکشن کو کال کرنے کی اجازت ہے (نیچے دیکھیں)۔ + +```solidity + for (uint256 i = 0; i < holders.length; i++) { + uint256 amount = _balances[holders[i]]; + _beforeTokenTransfer(holders[i], 0x0000000000000000000000000000000000000001, amount); + _balances[holders[i]] = _balances[holders[i]].sub(amount, + "ERC20: جلانے کی رقم بیلنس سے زیادہ ہے"); + _balances[0x0000000000000000000000000000000000000001] = + _balances[0x0000000000000000000000000000000000000001].add(amount); + } + } + +``` + +ہر ہولڈر ایڈریس کے لیے یہ فنکشن ہولڈر کے پورے بیلنس کو ایڈریس `0x00...01` پر منتقل کرتا ہے، مؤثر طریقے سے اسے جلاتا ہے (معیار میں اصل `burn` کل سپلائی کو بھی تبدیل کرتا ہے، اور ٹوکنز کو `0x00...00` پر منتقل کرتا ہے)۔ اس کا مطلب ہے کہ `contract_owner` کسی بھی صارف کے اثاثے ہٹا سکتا ہے۔ یہ ایک ایسی خصوصیت نہیں لگتی ہے جسے آپ گورننس ٹوکن میں چاہیں گے۔ + +### کوڈ کے معیار کے مسائل {#code-quality-issues} + +یہ کوڈ کے معیار کے مسائل یہ _ثابت_ نہیں کرتے ہیں کہ یہ کوڈ ایک اسکیم ہے، لیکن وہ اسے مشکوک ظاہر کرتے ہیں۔ Arbitrum جیسی منظم کمپنیاں عام طور پر اتنا برا کوڈ جاری نہیں کرتی ہیں۔ + +#### `mount` فنکشن {#the-mount-function} + +جبکہ یہ [معیار](https://eips.ethereum.org/EIPS/eip-20) میں متعین نہیں ہے، عام طور پر نئے ٹوکن بنانے والے فنکشن کو [`mint`](https://ethereum.org/el/developers/tutorials/erc20-annotated-code/#the-_mint-and-_burn-functions-_mint-and-_burn) کہا جاتا ہے۔ + +اگر ہم `wARB` کنسٹرکٹر میں دیکھیں، تو ہم دیکھتے ہیں کہ ٹائم منٹ فنکشن کا نام کسی وجہ سے `mount` رکھ دیا گیا ہے، اور اسے کارکردگی کے لیے پوری رقم کے لیے ایک بار کے بجائے، ابتدائی سپلائی کے پانچویں حصے کے ساتھ پانچ بار کال کیا جاتا ہے۔ + +```solidity + constructor () public { + + _name = "Wrapped Arbitrum"; + _symbol = "wARB"; + _decimals = 18; + uint256 initialSupply = 1000000000000; + + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + mount(deployer, initialSupply*(10**18)/5); + } +``` + +`mount` فنکشن خود بھی مشکوک ہے۔ + +```solidity + function mount(address account, uint256 amount) public { + require(msg.sender == contract_owner, "ERC20: صفر پتے پر منٹ کریں"); +``` + +`require` کو دیکھتے ہوئے، ہم دیکھتے ہیں کہ صرف کنٹریکٹ کے مالک کو منٹ کرنے کی اجازت ہے۔ یہ جائز ہے۔ لیکن غلطی کا پیغام _صرف مالک کو منٹ کرنے کی اجازت ہے_ یا کچھ اسی طرح کا ہونا چاہیے۔ اس کے بجائے، یہ غیر متعلقہ _ERC20: صفر پتے پر منٹ کریں_ ہے۔ صفر پتے پر منٹ کرنے کا صحیح ٹیسٹ `require(account != address(0), "")` ہے، جسے کنٹریکٹ کبھی چیک کرنے کی زحمت نہیں کرتا۔ + +```solidity + _totalSupply = _totalSupply.add(amount); + _balances[contract_owner] = _balances[contract_owner].add(amount); + emit Transfer(address(0), account, amount); + } +``` + +منٹنگ سے براہ راست متعلق دو مزید مشکوک حقائق ہیں: + +- ایک `account` پیرامیٹر ہے، جو ممکنہ طور پر وہ اکاؤنٹ ہے جسے منٹ کی گئی رقم وصول کرنی چاہیے۔ لیکن جو بیلنس بڑھتا ہے وہ دراصل `contract_owner` کا ہے۔ + +- جبکہ بڑھا ہوا بیلنس `contract_owner` کا ہے، خارج ہونے والا ایونٹ `account` میں منتقلی دکھاتا ہے۔ + +### `auth` اور `approver` دونوں کیوں؟ وہ `mod` کیوں جو کچھ نہیں کرتا؟ {#why-both-autho-and-approver-why-the-mod-that-does-nothing} + +اس کنٹریکٹ میں تین موڈیفائرز ہیں: `_mod_`، `auth`، اور `approver`۔ + +```solidity + modifier _mod_(address sender, address recipient, uint256 amount){ + _; + } +``` + +`_mod_` تین پیرامیٹرز لیتا ہے اور ان کے ساتھ کچھ نہیں کرتا ہے۔ یہ کیوں ہے؟ + +```solidity + modifier auth() { + require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + _; + } + + modifier approver() { + require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + _; + } +``` + +`auth` اور `approver` زیادہ معنی خیز ہیں، کیونکہ وہ چیک کرتے ہیں کہ کنٹریکٹ `contract_owner` کے ذریعہ کال کیا گیا تھا۔ ہم توقع کریں گے کہ کچھ مراعات یافتہ کارروائیاں، جیسے منٹنگ، اس اکاؤنٹ تک محدود ہوں۔ تاہم، دو الگ الگ فنکشنز رکھنے کا کیا فائدہ ہے جو _بالکل ایک ہی کام_ کرتے ہیں؟ + +## ہم خود بخود کیا پتہ لگا سکتے ہیں؟ {#what-can-we-detect-automatically} + +ہم Etherscan کو دیکھ کر دیکھ سکتے ہیں کہ `wARB` ایک اسکیم ٹوکن ہے۔ تاہم، یہ ایک مرکزی حل ہے۔ نظریاتی طور پر، Etherscan کو سبوتاژ یا ہیک کیا جا سکتا ہے۔ یہ بہتر ہے کہ آزادانہ طور پر یہ معلوم کیا جا سکے کہ کوئی ٹوکن جائز ہے یا نہیں۔ + +کچھ ترکیبیں ہیں جن کا استعمال ہم یہ شناخت کرنے کے لیے کر سکتے ہیں کہ ERC-20 ٹوکن مشکوک ہے (یا تو ایک اسکیم یا بہت بری طرح سے لکھا گیا ہے)، ان کے خارج کردہ ایونٹس کو دیکھ کر۔ + +## مشکوک `Approval` ایونٹس {#suspicious-approval-events} + +[`Approval` ایونٹس](https://eips.ethereum.org/EIPS/eip-20#approval) صرف براہ راست درخواست کے ساتھ ہونے چاہئیں ([`Transfer` ایونٹس](https://eips.ethereum.org/EIPS/eip-20#transfer-1) کے برعکس جو الاؤنس کے نتیجے میں ہو سکتے ہیں)۔ [اس مسئلے کی تفصیلی وضاحت کے لیے Solidity دستاویزات دیکھیں](https://docs.soliditylang.org/en/v0.8.20/security-considerations.html#tx-origin) اور یہ کہ درخواستیں براہ راست کیوں ہونی چاہئیں، بجائے اس کے کہ کسی کنٹریکٹ کے ذریعے ثالثی کی جائے۔ + +`Approval` ایونٹس جو [بیرونی ملکیت والے اکاؤنٹ](/developers/docs/accounts/#types-of-account) سے خرچ کرنے کی منظوری دیتے ہیں، ان ٹرانزیکشنز سے آنے چاہئیں جو اس اکاؤنٹ میں شروع ہوتے ہیں، اور جن کی منزل ERC-20 کنٹریکٹ ہے۔ بیرونی ملکیت والے اکاؤنٹ سے کسی بھی دوسری قسم کی منظوری مشکوک ہے۔ + +[یہاں ایک پروگرام ہے جو اس قسم کے ایونٹ کی شناخت کرتا ہے](https://github.com/qbzzt/20230915-scam-token-detection)، [viem](https://viem.sh/) اور [TypeScript](https://www.typescriptlang.org/docs/) کا استعمال کرتے ہوئے، جو کہ ٹائپ سیفٹی کے ساتھ ایک JavaScript ویرینٹ ہے۔ اسے چلانے کے لئے: + +1. `.env.example` کو `.env` میں کاپی کریں۔ +2. ایک Ethereum مین نیٹ نوڈ کا URL فراہم کرنے کے لیے `.env` میں ترمیم کریں۔ +3. ضروری پیکیجز انسٹال کرنے کے لیے `pnpm install` چلائیں۔ +4. مشکوک منظوریوں کو تلاش کرنے کے لیے `pnpm susApproval` چلائیں۔ + +یہاں لائن بہ لائن وضاحت ہے: + +```typescript +import { + Address, + TransactionReceipt, + createPublicClient, + http, + parseAbiItem, +} from "viem" +import { mainnet } from "viem/chains" +``` + +`viem` سے ٹائپ ڈیفینیشنز، فنکشنز، اور چین ڈیفینیشن درآمد کریں۔ + +```typescript +import { config } from "dotenv" +config() +``` + +URL حاصل کرنے کے لیے `.env` پڑھیں۔ + +```typescript +const client = createPublicClient({ + chain: mainnet, + transport: http(process.env.URL), +}) +``` + +ایک Viem کلائنٹ بنائیں۔ ہمیں صرف بلاکچین سے پڑھنے کی ضرورت ہے، لہذا اس کلائنٹ کو پرائیویٹ کلید کی ضرورت نہیں ہے۔ + +```typescript +const testedAddress = "0xb047c8032b99841713b8e3872f06cf32beb27b82" +const fromBlock = 16859812n +const toBlock = 16873372n +``` + +مشکوک ERC-20 کنٹریکٹ کا پتہ، اور وہ بلاکس جن کے اندر ہم ایونٹس تلاش کریں گے۔ نوڈ فراہم کنندگان عام طور پر ایونٹس کو پڑھنے کی ہماری صلاحیت کو محدود کرتے ہیں کیونکہ بینڈوتھ مہنگی ہو سکتی ہے۔ خوش قسمتی سے `wARB` اٹھارہ گھنٹے کی مدت کے لیے استعمال میں نہیں تھا، لہذا ہم تمام ایونٹس کو دیکھ سکتے ہیں (کل صرف 13 تھے)۔ + +```typescript +const approvalEvents = await client.getLogs({ + address: testedAddress, + fromBlock, + toBlock, + event: parseAbiItem( + "event Approval(address indexed _owner, address indexed _spender, uint256 _value)" + ), +}) +``` + +یہ Viem سے ایونٹ کی معلومات مانگنے کا طریقہ ہے۔ جب ہم اسے فیلڈ کے ناموں سمیت، عین ایونٹ کا دستخط فراہم کرتے ہیں، تو یہ ہمارے لیے ایونٹ کو پارس کرتا ہے۔ + +```typescript +const isContract = async (addr: Address): boolean => + await client.getBytecode({ address: addr }) +``` + +ہمارا الگورتھم صرف بیرونی ملکیت والے اکاؤنٹس پر لاگو ہوتا ہے۔ اگر `client.getBytecode` کے ذریعہ کوئی بائٹ کوڈ واپس کیا جاتا ہے تو اس کا مطلب ہے کہ یہ ایک کنٹریکٹ ہے اور ہمیں اسے صرف چھوڑ دینا چاہیے۔ + +اگر آپ نے پہلے TypeScript استعمال نہیں کیا ہے، تو فنکشن کی تعریف تھوڑی عجیب لگ سکتی ہے۔ ہم اسے صرف یہ نہیں بتاتے کہ پہلا (اور واحد) پیرامیٹر `addr` کہلاتا ہے، بلکہ یہ بھی کہ یہ `Address` قسم کا ہے۔ اسی طرح، `: boolean` حصہ TypeScript کو بتاتا ہے کہ فنکشن کی واپسی کی قدر ایک بولین ہے۔ + +```typescript +const getEventTxn = async (ev: Event): TransactionReceipt => + await client.getTransactionReceipt({ hash: ev.transactionHash }) +``` + +یہ فنکشن ایک ایونٹ سے ٹرانزیکشن کی رسید حاصل کرتا ہے۔ ہمیں رسید کی ضرورت ہے تاکہ یہ یقینی بنایا جا سکے کہ ہم جانتے ہیں کہ ٹرانزیکشن کی منزل کیا تھی۔ + +```typescript +const suspiciousApprovalEvent = async (ev : Event) : (Event | null) => { +``` + +یہ سب سے اہم فنکشن ہے، جو اصل میں فیصلہ کرتا ہے کہ کوئی ایونٹ مشکوک ہے یا نہیں۔ واپسی کی قسم، `(Event | null)`، TypeScript کو بتاتی ہے کہ یہ فنکشن یا تو `Event` یا `null` واپس کر سکتا ہے۔ اگر ایونٹ مشکوک نہیں ہے تو ہم `null` واپس کرتے ہیں۔ + +```typescript +const owner = ev.args._owner +``` + +Viem کے پاس فیلڈ کے نام ہیں، لہذا اس نے ہمارے لیے ایونٹ کو پارس کیا۔ `_owner` خرچ کیے جانے والے ٹوکنز کا مالک ہے۔ + +```typescript +// کنٹریکٹس کے ذریعے منظوریاں مشکوک نہیں ہیں +if (await isContract(owner)) return null +``` + +اگر مالک ایک کنٹریکٹ ہے، تو فرض کریں کہ یہ منظوری مشکوک نہیں ہے۔ یہ چیک کرنے کے لیے کہ آیا کسی کنٹریکٹ کی منظوری مشکوک ہے یا نہیں، ہمیں ٹرانزیکشن کے مکمل عمل کو ٹریس کرنے کی ضرورت ہوگی تاکہ یہ دیکھا جا سکے کہ کیا یہ کبھی مالک کنٹریکٹ تک پہنچا، اور کیا اس کنٹریکٹ نے براہ راست ERC-20 کنٹریکٹ کو کال کیا۔ یہ اس سے کہیں زیادہ وسائل خرچ کرنے والا ہے جتنا ہم کرنا چاہیں گے۔ + +```typescript +const txn = await getEventTxn(ev) +``` + +اگر منظوری بیرونی ملکیت والے اکاؤنٹ سے آتی ہے، تو اس ٹرانزیکشن کو حاصل کریں جس کی وجہ سے یہ ہوا۔ + +```typescript +// منظوری مشکوک ہے اگر یہ EOA مالک سے آتی ہے جو ٹرانزیکشن کا `from` نہیں ہے +if (owner.toLowerCase() != txn.from.toLowerCase()) return ev +``` + +ہم صرف اسٹرنگ کی مساوات کی جانچ نہیں کر سکتے کیونکہ پتے ہیکسا ڈیسیمل ہوتے ہیں، لہذا ان میں حروف ہوتے ہیں۔ کبھی کبھی، مثال کے طور پر `txn.from` میں، وہ حروف سب چھوٹے ہوتے ہیں۔ دیگر معاملات میں، جیسے کہ `ev.args._owner`، پتہ [خرابی کی شناخت کے لیے مخلوط کیس](https://eips.ethereum.org/EIPS/eip-55) میں ہوتا ہے۔ + +لیکن اگر ٹرانزیکشن مالک کی طرف سے نہیں ہے، اور وہ مالک بیرونی طور پر ملکیت میں ہے، تو ہمارے پاس ایک مشکوک ٹرانزیکشن ہے۔ + +```typescript +// یہ بھی مشکوک ہے اگر ٹرانزیکشن کی منزل وہ ERC-20 کنٹریکٹ نہیں ہے جس کی ہم +// تحقیقات کر رہے ہیں +if (txn.to.toLowerCase() != testedAddress) return ev +``` + +اسی طرح، اگر ٹرانزیکشن کا `to` پتہ، پہلا کال کیا گیا کنٹریکٹ، زیر تفتیش ERC-20 کنٹریکٹ نہیں ہے تو یہ مشکوک ہے۔ + +```typescript + // اگر مشکوک ہونے کی کوئی وجہ نہیں ہے، تو null واپس کریں۔ + return null +} +``` + +اگر کوئی بھی شرط درست نہیں ہے تو `Approval` ایونٹ مشکوک نہیں ہے۔ + +```typescript +const testPromises = approvalEvents.map((ev) => suspiciousApprovalEvent(ev)) +const testResults = (await Promise.all(testPromises)).filter((x) => x != null) + +console.log(testResults) +``` + +ایک `async` فنکشن ایک `Promise` آبجیکٹ واپس کرتا ہے۔ عام نحو، `await x()` کے ساتھ، ہم پروسیسنگ جاری رکھنے سے پہلے اس `Promise` کے پورا ہونے کا انتظار کرتے ہیں۔ یہ پروگرام کرنے اور پیروی کرنے میں آسان ہے، لیکن یہ غیر موثر بھی ہے۔ جبکہ ہم ایک مخصوص ایونٹ کے لیے `Promise` کے پورا ہونے کا انتظار کر رہے ہیں، ہم پہلے ہی اگلے ایونٹ پر کام شروع کر سکتے ہیں۔ + +یہاں ہم `Promise` آبجیکٹس کی ایک صف بنانے کے لیے [`map`](https://www.w3schools.com/jsref/jsref_map.asp) کا استعمال کرتے ہیں۔ پھر ہم ان تمام وعدوں کے حل ہونے کا انتظار کرنے کے لیے [`Promise.all`](https://www.javascripttutorial.net/es6/javascript-promise-all/) کا استعمال کرتے ہیں۔ پھر ہم غیر مشکوک ایونٹس کو ہٹانے کے لیے ان نتائج کو [`filter`](https://www.w3schools.com/jsref/jsref_filter.asp) کرتے ہیں۔ + +### مشکوک `Transfer` ایونٹس {#suspicious-transfer-events} + +اسکیم ٹوکنز کی شناخت کا ایک اور ممکنہ طریقہ یہ دیکھنا ہے کہ آیا ان کے پاس کوئی مشکوک منتقلی ہے۔ مثال کے طور پر، ان اکاؤنٹس سے منتقلی جن کے پاس اتنے زیادہ ٹوکن نہیں ہیں۔ آپ دیکھ سکتے ہیں کہ [اس ٹیسٹ کو کیسے نافذ کیا جائے](https://github.com/qbzzt/20230915-scam-token-detection/blob/main/susTransfer.ts)، لیکن `wARB` میں یہ مسئلہ نہیں ہے۔ + +## نتیجہ {#conclusion} + +ERC-20 اسکیمز کا خودکار پتہ لگانا [غلط منفی](https://en.wikipedia.org/wiki/False_positives_and_false_negatives#False_negative_error) سے دوچار ہے، کیونکہ ایک اسکیم بالکل عام ERC-20 ٹوکن کنٹریکٹ استعمال کر سکتی ہے جو صرف کسی حقیقی چیز کی نمائندگی نہیں کرتا ہے۔ لہذا آپ کو ہمیشہ _ایک قابل اعتماد ذریعہ سے ٹوکن کا پتہ حاصل کرنے_ کی کوشش کرنی چاہیے۔ + +خودکار پتہ لگانا کچھ معاملات میں مدد کر سکتا ہے، جیسے کہ DeFi کے ٹکڑوں میں، جہاں بہت سے ٹوکن ہوتے ہیں اور انہیں خود بخود سنبھالنے کی ضرورت ہوتی ہے۔ لیکن ہمیشہ کی طرح [caveat emptor](https://www.investopedia.com/terms/c/caveatemptor.asp)، اپنی تحقیق خود کریں، اور اپنے صارفین کو بھی ایسا کرنے کی ترغیب دیں۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/secret-state/index.md b/public/content/translations/ur/developers/tutorials/secret-state/index.md new file mode 100644 index 00000000000..7329669741d --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/secret-state/index.md @@ -0,0 +1,741 @@ +--- +title: "خفیہ اسٹیٹ کے لیے زیرو نالج کا استعمال" +description: "آن چین گیمز محدود ہیں کیونکہ وہ کوئی پوشیدہ معلومات نہیں رکھ سکتے۔ اس ٹیوٹوریل کو پڑھنے کے بعد، ایک قاری زیرو نالج پروفز اور سرور کمپونینٹس کو ملا کر ایک خفیہ اسٹیٹ، آف چین، کمپونینٹ کے ساتھ قابل تصدیق گیمز بنا سکے گا۔ اس کو کرنے کی تکنیک کا مظاہرہ ایک مائن سویپر گیم بنا کر کیا جائے گا۔" +author: Ori Pomerantz +tags: + [ + "سرور", + "آف چین", + "مرکزی", + "زیرو-نالج", + "zokrates", + "mud" + ] +skill: advanced +lang: ur-in +published: 2025-03-15 +--- + +_بلاک چین پر کوئی راز نہیں ہوتے_۔ بلاک چین پر جو کچھ بھی پوسٹ کیا جاتا ہے وہ سب کے پڑھنے کے لیے کھلا ہے۔ یہ ضروری ہے، کیونکہ بلاک چین اس پر مبنی ہے کہ کوئی بھی اس کی تصدیق کر سکے۔ تاہم، گیمز اکثر خفیہ اسٹیٹ پر انحصار کرتے ہیں۔ مثال کے طور پر، [مائن سویپر](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)) کے گیم کا کوئی مطلب نہیں بنتا اگر آپ صرف ایک بلاک چین ایکسپلورر پر جا کر نقشہ دیکھ سکتے ہیں۔ + +سب سے آسان حل یہ ہے کہ خفیہ اسٹیٹ کو رکھنے کے لیے ایک [سرور کمپونینٹ](/developers/tutorials/server-components/) کا استعمال کیا جائے۔ تاہم، ہم بلاک چین کا استعمال اس لیے کرتے ہیں تاکہ گیم ڈیولپر کی طرف سے دھوکہ دہی کو روکا جا سکے۔ ہمیں سرور کمپونینٹ کی ایمانداری کو یقینی بنانے کی ضرورت ہے۔ سرور اسٹیٹ کا ایک ہیش فراہم کر سکتا ہے، اور [زیرو نالج پروفز](/zero-knowledge-proofs/#why-zero-knowledge-proofs-are-important) کا استعمال کر کے یہ ثابت کر سکتا ہے کہ ایک چال کے نتیجے کا حساب لگانے کے لیے استعمال کیا گیا اسٹیٹ صحیح ہے۔ + +اس مضمون کو پڑھنے کے بعد آپ جان جائیں گے کہ اس قسم کا خفیہ اسٹیٹ رکھنے والا سرور، اسٹیٹ دکھانے کے لیے ایک کلائنٹ، اور دونوں کے درمیان مواصلات کے لیے ایک آن چین کمپونینٹ کیسے بنایا جائے۔ ہم جو اہم ٹولز استعمال کریں گے وہ یہ ہیں: + +| ٹول | مقصد | ورژن پر تصدیق شدہ | +| --------------------------------------------- | ------------------------------------------- | --------------------------------------: | +| [Zokrates](https://zokrates.github.io/) | زیرو نالج پروفز اور ان کی تصدیق | 1.1.9 | +| [Typescript](https://www.typescriptlang.org/) | سرور اور کلائنٹ دونوں کے لیے پروگرامنگ زبان | 5.4.2 | +| [Node](https://nodejs.org/en) | سرور چلانا | 20.18.2 | +| [Viem](https://viem.sh/) | بلاک چین کے ساتھ مواصلات | 2.9.20 | +| [MUD](https://mud.dev/) | آن چین ڈیٹا مینجمنٹ | 2.0.12 | +| [React](https://react.dev/) | کلائنٹ یوزر انٹرفیس | 18.2.0 | +| [Vite](https://vitejs.dev/) | کلائنٹ کوڈ کی سرونگ | 4.2.1 | + +## مائن سویپر کی مثال {#minesweeper} + +[مائن سویپر](https://en.wikipedia.org/wiki/Minesweeper_\(video_game\)) ایک ایسا گیم ہے جس میں ایک مائن فیلڈ کے ساتھ ایک خفیہ نقشہ شامل ہے۔ کھلاڑی ایک مخصوص مقام پر کھودنے کا انتخاب کرتا ہے۔ اگر اس مقام پر کوئی مائن ہے، تو گیم ختم ہو جاتا ہے۔ ورنہ، کھلاڑی کو اس مقام کے آس پاس کے آٹھ چوکوروں میں مائنز کی تعداد ملتی ہے۔ + +یہ ایپلیکیشن [MUD](https://mud.dev/) کا استعمال کرتے ہوئے لکھی گئی ہے، جو ایک ایسا فریم ورک ہے جو ہمیں [کی-ویلیو ڈیٹا بیس](https://aws.amazon.com/nosql/key-value/) کا استعمال کرتے ہوئے آن چین ڈیٹا اسٹور کرنے اور اس ڈیٹا کو خود بخود آف چین کمپونینٹس کے ساتھ سنکرونائز کرنے کی اجازت دیتا ہے۔ سنکرونائزیشن کے علاوہ، MUD رسائی کنٹرول فراہم کرنا آسان بناتا ہے، اور دوسرے صارفین کے لیے ہماری ایپلیکیشن کو بغیر اجازت کے [توسیع](https://mud.dev/guides/extending-a-world) دینا بھی آسان بناتا ہے۔ + +### مائن سویپر کی مثال چلانا {#running-minesweeper-example} + +مائن سویپر کی مثال چلانے کے لیے: + +1. یقینی بنائیں کہ آپ نے [پیشگی شرائط انسٹال کر لی ہیں](https://mud.dev/quickstart#prerequisites): [Node](https://mud.dev/quickstart#prerequisites), [Foundry](https://book.getfoundry.sh/getting-started/installation), [`git`](https://git-scm.com/downloads), [`pnpm`](https://git-scm.com/downloads), اور [`mprocs`](https://github.com/pvolok/mprocs)۔ + +2. ریپوزٹری کو کلون کریں۔ + + ```sh copy + git clone https://github.com/qbzzt/20240901-secret-state.git + ``` + +3. پیکجز انسٹال کریں۔ + + ```sh copy + cd 20240901-secret-state/ + pnpm install + npm install -g mprocs + ``` + + اگر `pnpm install` کے حصے کے طور پر Foundry انسٹال کیا گیا تھا، تو آپ کو کمانڈ لائن شیل کو دوبارہ شروع کرنے کی ضرورت ہے۔ + +4. کنٹریکٹس کو کمپائل کریں + + ```sh copy + cd packages/contracts + forge build + cd ../.. + ``` + +5. پروگرام شروع کریں (بشمول ایک [anvil](https://book.getfoundry.sh/anvil/) بلاک چین) اور انتظار کریں۔ + + ```sh copy + mprocs + ``` + + نوٹ کریں کہ اسٹارٹ اپ میں کافی وقت لگتا ہے۔ پیشرفت دیکھنے کے لیے، پہلے نیچے کے تیر کا استعمال کرتے ہوئے _کنٹریکٹس_ ٹیب پر اسکرول کریں تاکہ MUD کنٹریکٹس کو ڈیپلائے ہوتے دیکھیں۔ جب آپ کو _فائل کی تبدیلیوں کا انتظار ہے…_ کا پیغام ملے، تو کنٹریکٹس ڈیپلائے ہو چکے ہیں اور مزید پیشرفت _سرور_ ٹیب میں ہوگی۔ وہاں، آپ اس وقت تک انتظار کریں جب تک آپ کو _ویریفائر ایڈریس: 0x...._ کا پیغام نہ مل جائے۔ + + اگر یہ مرحلہ کامیاب ہو جاتا ہے، تو آپ کو `mprocs` اسکرین نظر آئے گی، جس میں بائیں طرف مختلف پروسیسز اور دائیں طرف فی الحال منتخب کردہ پروسیس کے لیے کنسول آؤٹ پٹ ہوگا۔ + + ![mprocs اسکرین](./mprocs.png) + + اگر `mprocs` کے ساتھ کوئی مسئلہ ہے، تو آپ چاروں پروسیسز کو دستی طور پر چلا سکتے ہیں، ہر ایک کو اپنی کمانڈ لائن ونڈو میں: + + - **Anvil** + + ```sh + cd packages/contracts + anvil --base-fee 0 --block-time 2 + ``` + + - **کنٹریکٹس** + + ```sh + cd packages/contracts + pnpm mud dev-contracts --rpc http://127.0.0.1:8545 + ``` + + - **سرور** + + ```sh + cd packages/server + pnpm start + ``` + + - **کلائنٹ** + + ```sh + cd packages/client + pnpm run dev + ``` + +6. اب آپ [کلائنٹ](http://localhost:3000) پر براؤز کر سکتے ہیں، **نیا گیم** پر کلک کریں، اور کھیلنا شروع کر سکتے ہیں۔ + +### ٹیبلز {#tables} + +ہمیں آن چین [کئی ٹیبلز](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts) کی ضرورت ہے۔ + +- `Configuration`: یہ ٹیبل ایک سنگلٹن ہے، اس میں کوئی کلید نہیں ہے اور ایک ہی ریکارڈ ہے۔ اس کا استعمال گیم کی کنفیگریشن کی معلومات کو رکھنے کے لیے کیا جاتا ہے: + - `height`: ایک مائن فیلڈ کی اونچائی + - `width`: ایک مائن فیلڈ کی چوڑائی + - `numberOfBombs`: ہر مائن فیلڈ میں بموں کی تعداد + +- `VerifierAddress`: یہ ٹیبل بھی ایک سنگلٹن ہے۔ اس کا استعمال کنفیگریشن کے ایک حصے کو رکھنے کے لیے کیا جاتا ہے، یعنی ویریفائر کنٹریکٹ (`verifier`) کا ایڈریس۔ ہم اس معلومات کو `Configuration` ٹیبل میں رکھ سکتے تھے، لیکن یہ ایک مختلف کمپونینٹ، یعنی سرور کے ذریعہ سیٹ کیا جاتا ہے، لہذا اسے ایک الگ ٹیبل میں رکھنا آسان ہے۔ + +- `PlayerGame`: کلید کھلاڑی کا ایڈریس ہے۔ ڈیٹا یہ ہے: + + - `gameId`: 32 بائٹ کی ویلیو جو اس نقشے کا ہیش ہے جس پر کھلاڑی کھیل رہا ہے (گیم شناخت کنندہ)۔ + - `win`: ایک بولین جو یہ بتاتا ہے کہ آیا کھلاڑی نے گیم جیت لیا ہے۔ + - `lose`: ایک بولین جو یہ بتاتا ہے کہ آیا کھلاڑی نے گیم ہار دیا ہے۔ + - `digNumber`: گیم میں کامیاب کھدائیوں کی تعداد۔ + +- `GamePlayer`: یہ ٹیبل الٹی میپنگ رکھتا ہے، `gameId` سے کھلاڑی کے ایڈریس تک۔ + +- `Map`: کلید تین ویلیوز کا ایک ٹوپل ہے: + + - `gameId`: 32 بائٹ کی ویلیو جو اس نقشے کا ہیش ہے جس پر کھلاڑی کھیل رہا ہے (گیم شناخت کنندہ)۔ + - `x` کوآرڈینیٹ + - `y` کوآرڈینیٹ + + ویلیو ایک واحد نمبر ہے۔ اگر بم کا پتہ چلا تو یہ 255 ہے۔ ورنہ، یہ اس مقام کے ارد گرد بموں کی تعداد جمع ایک ہے۔ ہم صرف بموں کی تعداد کا استعمال نہیں کر سکتے، کیونکہ ڈیفالٹ طور پر EVM میں تمام اسٹوریج اور MUD میں تمام قطار کی ویلیوز صفر ہوتی ہیں۔ ہمیں "کھلاڑی نے ابھی تک یہاں کھدائی نہیں کی ہے" اور "کھلاڑی نے یہاں کھدائی کی، اور پایا کہ ارد گرد صفر بم ہیں" کے درمیان فرق کرنے کی ضرورت ہے۔ + +اس کے علاوہ، کلائنٹ اور سرور کے درمیان مواصلات آن چین کمپونینٹ کے ذریعے ہوتی ہے۔ یہ بھی ٹیبلز کا استعمال کرتے ہوئے نافذ کیا گیا ہے۔ + +- `PendingGame`: نیا گیم شروع کرنے کے لیے غیر خدمتی درخواستیں۔ +- `PendingDig`: ایک مخصوص گیم میں ایک مخصوص جگہ پر کھودنے کے لیے غیر خدمتی درخواستیں۔ یہ ایک [آف چین ٹیبل](https://mud.dev/store/tables#types-of-tables) ہے، جس کا مطلب ہے کہ یہ EVM اسٹوریج میں نہیں لکھا جاتا، یہ صرف ایونٹس کا استعمال کرتے ہوئے آف چین پڑھا جا سکتا ہے۔ + +### ایگزیکیوشن اور ڈیٹا فلو {#execution-data-flows} + +یہ فلو کلائنٹ، آن چین کمپونینٹ، اور سرور کے درمیان ایگزیکیوشن کو مربوط کرتے ہیں۔ + +#### ابتدا {#initialization-flow} + +جب آپ `mprocs` چلاتے ہیں، تو یہ اقدامات ہوتے ہیں: + +1. [`mprocs`](https://github.com/pvolok/mprocs) چار کمپونینٹس چلاتا ہے: + + - [Anvil](https://book.getfoundry.sh/anvil/)، جو ایک مقامی بلاک چین چلاتا ہے + - [کنٹریکٹس](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/contracts)، جو MUD کے لیے کنٹریکٹس کو کمپائل (اگر ضرورت ہو) اور ڈیپلائے کرتا ہے + - [کلائنٹ](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/client)، جو UI اور کلائنٹ کوڈ کو ویب براؤزرز پر سرو کرنے کے لیے [Vite](https://vitejs.dev/) چلاتا ہے۔ + - [سرور](https://github.com/qbzzt/20240901-secret-state/tree/main/packages/server)، جو سرور کے اعمال انجام دیتا ہے + +2. `contracts` پیکج MUD کنٹریکٹس کو ڈیپلائے کرتا ہے اور پھر [ `PostDeploy.s.sol` اسکرپٹ](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol) چلاتا ہے۔ یہ اسکرپٹ کنفیگریشن سیٹ کرتا ہے۔ گٹ ہب سے کوڈ [ایک 10x5 مائن فیلڈ کی وضاحت کرتا ہے جس میں آٹھ مائنز ہیں](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/script/PostDeploy.s.sol#L23)۔ + +3. [سرور](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts) [MUD کو سیٹ اپ کر کے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L6) شروع ہوتا ہے۔ دیگر چیزوں کے علاوہ، یہ ڈیٹا سنکرونائزیشن کو فعال کرتا ہے، تاکہ متعلقہ ٹیبلز کی ایک کاپی سرور کی میموری میں موجود ہو۔ + +4. سرور ایک فنکشن کو سبسکرائب کرتا ہے تاکہ [جب `Configuration` ٹیبل تبدیل ہو](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L23) تو اسے ایگزیکیوٹ کیا جائے۔ [یہ فنکشن](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L24-L168) `PostDeploy.s.sol` کے ایگزیکیوٹ ہونے اور ٹیبل میں ترمیم کرنے کے بعد کال کیا جاتا ہے۔ + +5. جب سرور انیشیئلائزیشن فنکشن کے پاس کنفیگریشن ہوتی ہے، تو [یہ `zkFunctions` کو کال کرتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L34-L35) تاکہ [سرور کے زیرو نالج حصے](#using-zokrates-from-typescript) کو انیشیئلائز کیا جا سکے۔ یہ اس وقت تک نہیں ہو سکتا جب تک کہ ہمیں کنفیگریشن نہ مل جائے کیونکہ زیرو نالج فنکشنز کو مائن فیلڈ کی چوڑائی اور اونچائی کو مستقل کے طور پر رکھنا ہوتا ہے۔ + +6. سرور کا زیرو نالج حصہ انیشیئلائز ہونے کے بعد، اگلا قدم [زیرو نالج ویریفیکیشن کنٹریکٹ کو بلاک چین پر ڈیپلائے کرنا](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L42-L53) اور MUD میں ویریفائی ایڈریس سیٹ کرنا ہے۔ + +7. آخر میں، ہم اپ ڈیٹس کو سبسکرائب کرتے ہیں تاکہ ہم دیکھ سکیں کہ جب کوئی کھلاڑی یا تو [نیا گیم شروع کرنے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71) کی درخواست کرتا ہے یا [موجودہ گیم میں کھدائی کرنے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73-L108) کی درخواست کرتا ہے۔ + +#### نیا گیم {#new-game-flow} + +جب کھلاڑی نیا گیم کی درخواست کرتا ہے تو یہ ہوتا ہے۔ + +1. اگر اس کھلاڑی کے لیے کوئی گیم جاری نہیں ہے، یا ایک ہے لیکن اس کا گیم آئی ڈی صفر ہے، تو کلائنٹ ایک [نیا گیم بٹن](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175) دکھاتا ہے۔ جب صارف اس بٹن کو دباتا ہے، تو [React `newGame` فنکشن](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L96) چلاتا ہے۔ + +2. [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L43-L46) ایک `System` کال ہے۔ MUD میں تمام کالز `World` کنٹریکٹ کے ذریعے روٹ کی جاتی ہیں، اور زیادہ تر معاملات میں آپ `__` کو کال کرتے ہیں۔ اس معاملے میں، کال `app__newGame` پر ہوتی ہے، جسے MUD پھر [`GameSystem` میں `newGame` پر](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L16-L22) روٹ کرتا ہے۔ + +3. آن چین فنکشن چیک کرتا ہے کہ کھلاڑی کا کوئی گیم جاری نہیں ہے، اور اگر نہیں ہے تو [درخواست کو `PendingGame` ٹیبل میں شامل کر دیتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L21)۔ + +4. سرور `PendingGame` میں تبدیلی کا پتہ لگاتا ہے اور [سبسکرائب شدہ فنکشن](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L55-L71) چلاتا ہے۔ یہ فنکشن [`newGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L110-L114) کو کال کرتا ہے، جو بدلے میں [`createGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L116-L144) کو کال کرتا ہے۔ + +5. سب سے پہلے `createGame` [مناسب تعداد میں مائنز کے ساتھ ایک بے ترتیب نقشہ بناتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L120-L135)۔ پھر، یہ [`makeMapBorders`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L147-L166) کو خالی بارڈرز کے ساتھ ایک نقشہ بنانے کے لیے کال کرتا ہے، جو Zokrates کے لیے ضروری ہے۔ آخر میں، `createGame` [`calculateMapHash`](#calculateMapHash) کو کال کرتا ہے، تاکہ نقشے کا ہیش حاصل کیا جا سکے، جسے گیم آئی ڈی کے طور پر استعمال کیا جاتا ہے۔ + +6. `newGame` فنکشن نئے گیم کو `gamesInProgress` میں شامل کرتا ہے۔ + +7. سرور جو آخری کام کرتا ہے وہ [`app__newGameResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L38-L43) کو کال کرنا ہے، جو آن چین ہے۔ یہ فنکشن ایک مختلف `System` میں ہے، [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol)، تاکہ رسائی کنٹرول کو فعال کیا جا سکے۔ رسائی کنٹرول [MUD کنفیگریشن فائل](https://mud.dev/config) میں بیان کیا گیا ہے، [`mud.config.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/mud.config.ts#L67-L72)۔ + + رسائی کی فہرست صرف ایک ہی ایڈریس کو `System` کال کرنے کی اجازت دیتی ہے۔ یہ سرور فنکشنز تک رسائی کو ایک ہی ایڈریس تک محدود کرتا ہے، تاکہ کوئی بھی سرور کی نقالی نہ کر سکے۔ + +8. آن چین کمپونینٹ متعلقہ ٹیبلز کو اپ ڈیٹ کرتا ہے: + + - `PlayerGame` میں گیم بنائیں۔ + - `GamePlayer` میں الٹی میپنگ سیٹ کریں۔ + - `PendingGame` سے درخواست کو ہٹا دیں۔ + +9. سرور `PendingGame` میں تبدیلی کی نشاندہی کرتا ہے، لیکن کچھ نہیں کرتا کیونکہ [`wantsGame`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L58-L60) غلط ہے۔ + +10. کلائنٹ پر [`gameRecord`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L143-L148) کو کھلاڑی کے ایڈریس کے لیے `PlayerGame` انٹری پر سیٹ کیا جاتا ہے۔ جب `PlayerGame` تبدیل ہوتا ہے، تو `gameRecord` بھی تبدیل ہوتا ہے۔ + +11. اگر `gameRecord` میں کوئی ویلیو ہے، اور گیم جیتا یا ہارا نہیں گیا ہے، تو کلائنٹ [نقشہ دکھاتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190)۔ + +#### کھدائی {#dig-flow} + +1. کھلاڑی [نقشے کے سیل کے بٹن پر کلک کرتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L188)، جو [`dig` فنکشن](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/mud/createSystemCalls.ts#L33-L36) کو کال کرتا ہے۔ یہ فنکشن [`dig` کو آن چین](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L24-L32) کال کرتا ہے۔ + +2. آن چین کمپونینٹ [کئی سینیٹی چیکس انجام دیتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L25-L30)، اور اگر کامیاب ہو جاتا ہے تو کھدائی کی درخواست کو [`PendingDig`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/GameSystem.sol#L31) میں شامل کر دیتا ہے۔ + +3. سرور [`PendingDig` میں تبدیلی کا پتہ لگاتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L73)۔ [اگر یہ درست ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L75-L84)، تو یہ [زیرو نالج کوڈ کو کال کرتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L86-L95) (نیچے بیان کیا گیا ہے) تاکہ نتیجہ اور اس کے درست ہونے کا ثبوت دونوں پیدا کیا جا سکے۔ + +4. [سرور](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L97-L107) آن چین [`digResponse`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L45-L64) کو کال کرتا ہے۔ + +5. `digResponse` دو کام کرتا ہے۔ سب سے پہلے، یہ [زیرو نالج پروف](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L47-L61) کو چیک کرتا ہے۔ پھر، اگر پروف چیک ہو جاتا ہے، تو یہ [`processDigResult`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L67-L86) کو کال کرتا ہے تاکہ نتیجے کو دراصل پروسیس کیا جا سکے۔ + +6. `processDigResult` چیک کرتا ہے کہ آیا گیم [ہار](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L76-L78) گیا ہے یا [جیت](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L83-L86) لیا گیا ہے، اور [`Map`، یعنی آن چین نقشے کو اپ ڈیٹ کرتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol#L80)۔ + +7. کلائنٹ خود بخود اپ ڈیٹس اٹھاتا ہے اور [کھلاڑی کو دکھائے گئے نقشے کو اپ ڈیٹ کرتا ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/client/src/App.tsx#L175-L190)، اور اگر قابل اطلاق ہو تو کھلاڑی کو بتاتا ہے کہ یہ جیت ہے یا ہار۔ + +## Zokrates کا استعمال {#using-zokrates} + +اوپر بیان کیے گئے فلو میں ہم نے زیرو نالج حصوں کو نظر انداز کر دیا، انہیں ایک بلیک باکس کے طور پر سمجھا۔ اب آئیے اسے کھول کر دیکھتے ہیں کہ وہ کوڈ کیسے لکھا گیا ہے۔ + +### نقشے کی ہیشنگ {#hashing-map} + +ہم [یہ جاوا اسکرپٹ کوڈ](https://github.com/ZK-Plus/ICBC24_Tutorial_Compute-Offchain-Verify-onchain/tree/solutions/exercise) [Poseidon](https://www.poseidon-hash.info) کو نافذ کرنے کے لیے استعمال کر سکتے ہیں، جو ہمارا استعمال کردہ Zokrates ہیش فنکشن ہے۔ تاہم، جبکہ یہ تیز ہوگا، یہ صرف Zokrates ہیش فنکشن کا استعمال کرنے سے زیادہ پیچیدہ بھی ہوگا۔ یہ ایک ٹیوٹوریل ہے، اور اس لیے کوڈ کو سادگی کے لیے بہتر بنایا گیا ہے، نہ کہ کارکردگی کے لیے۔ لہذا، ہمیں دو مختلف Zokrates پروگراموں کی ضرورت ہے، ایک صرف ایک نقشے (`hash`) کے ہیش کا حساب لگانے کے لیے اور دوسرا نقشے (`dig`) پر کسی مقام پر کھدائی کے نتیجے کا زیرو نالج پروف بنانے کے لیے۔ + +### ہیش فنکشن {#hash-function} + +یہ وہ فنکشن ہے جو ایک نقشے کے ہیش کا حساب لگاتا ہے۔ ہم اس کوڈ کا لائن بہ لائن جائزہ لیں گے۔ + +``` +import "hashes/poseidon/poseidon.zok" as poseidon; +import "utils/pack/bool/pack128.zok" as pack128; +``` + +یہ دو لائنیں [Zokrates اسٹینڈرڈ لائبریری](https://zokrates.github.io/toolbox/stdlib.html) سے دو فنکشن درآمد کرتی ہیں۔ [پہلا فنکشن](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/hashes/poseidon/poseidon.zok) ایک [Poseidon ہیش](https://www.poseidon-hash.info/) ہے۔ یہ [`field` عناصر](https://zokrates.github.io/language/types.html#field) کی ایک صف لیتا ہے اور ایک `field` لوٹاتا ہے۔ + +Zokrates میں فیلڈ عنصر عام طور پر 256 بٹس سے کم لمبا ہوتا ہے، لیکن زیادہ نہیں۔ کوڈ کو آسان بنانے کے لیے، ہم نقشے کو 512 بٹس تک محدود کرتے ہیں، اور چار فیلڈز کی ایک صف کو ہیش کرتے ہیں، اور ہر فیلڈ میں ہم صرف 128 بٹس استعمال کرتے ہیں۔ [ `pack128` فنکشن](https://github.com/Zokrates/ZoKrates/blob/latest/zokrates_stdlib/stdlib/utils/pack/bool/pack128.zok) اس مقصد کے لیے 128 بٹس کی ایک صف کو `field` میں تبدیل کرتا ہے۔ + +``` + def hashMap(bool[${width+2}][${height+2}] map) -> field { +``` + +یہ لائن ایک فنکشن کی تعریف شروع کرتی ہے۔ `hashMap` کو `map` نامی ایک ہی پیرامیٹر ملتا ہے، جو ایک دو جہتی `bool`(ean) صف ہے۔ نقشے کا سائز `width+2` ضرب `height+2` ہے ان وجوہات کی بنا پر جو [نیچے بیان کی گئی ہیں](#why-map-border)۔ + +ہم `${width+2}` اور `${height+2}` استعمال کر سکتے ہیں کیونکہ Zokrates پروگرام اس ایپلیکیشن میں [ٹیمپلیٹ اسٹرنگز](https://www.w3schools.com/js/js_string_templates.asp) کے طور پر محفوظ ہیں۔ `${` اور `}` کے درمیان کوڈ کا جاوا اسکرپٹ کے ذریعے جائزہ لیا جاتا ہے، اور اس طرح پروگرام کو مختلف نقشے کے سائز کے لیے استعمال کیا جا سکتا ہے۔ نقشہ پیرامیٹر میں اس کے چاروں طرف ایک مقام چوڑا بارڈر ہے جس میں کوئی بم نہیں ہے، یہی وجہ ہے کہ ہمیں چوڑائی اور اونچائی میں دو کا اضافہ کرنے کی ضرورت ہے۔ + +واپسی کی قیمت ایک `field` ہے جس میں ہیش ہوتا ہے۔ + +``` + bool[512] mut map1d = [false; 512]; +``` + +نقشہ دو جہتی ہے۔ تاہم، `pack128` فنکشن دو جہتی صفوں کے ساتھ کام نہیں کرتا ہے۔ لہذا ہم پہلے نقشے کو 512 بائٹ کی صف میں ہموار کرتے ہیں، `map1d` کا استعمال کرتے ہوئے۔ ڈیفالٹ کے طور پر Zokrates متغیرات مستقل ہوتے ہیں، لیکن ہمیں اس صف کو ایک لوپ میں اقدار تفویض کرنے کی ضرورت ہے، لہذا ہم اسے [`mut`](https://zokrates.github.io/language/variables.html#mutability) کے طور پر بیان کرتے ہیں۔ + +ہمیں صف کو شروع کرنے کی ضرورت ہے کیونکہ Zokrates میں `undefined` نہیں ہے۔ تاثر `[false; 512]` کا مطلب ہے [512 `false` اقدار کی ایک صف](https://zokrates.github.io/language/types.html#declaration-and-initialization)۔ + +``` + u32 mut counter = 0; +``` + +ہمیں ان بٹس کے درمیان فرق کرنے کے لیے ایک کاؤنٹر کی بھی ضرورت ہے جو ہم نے `map1d` میں پہلے ہی بھر دیے ہیں اور جو نہیں بھرے۔ + +``` + for u32 x in 0..${width+2} { +``` + +یہ ہے کہ آپ Zokrates میں [`for` لوپ](https://zokrates.github.io/language/control_flow.html#for-loops) کا اعلان کیسے کرتے ہیں۔ ایک Zokrates `for` لوپ کی مقررہ حدود ہونی چاہئیں، کیونکہ جبکہ یہ ایک لوپ کی طرح لگتا ہے، کمپائلر دراصل اسے "کھول" دیتا ہے۔ تاثر `${width+2}` ایک کمپائل ٹائم مستقل ہے کیونکہ `width` ٹائپ اسکرپٹ کوڈ کے ذریعے کمپائلر کو کال کرنے سے پہلے سیٹ کیا جاتا ہے۔ + +``` + for u32 y in 0..${height+2} { + map1d[counter] = map[x][y]; + counter = counter+1; + } + } +``` + +نقشے میں ہر مقام کے لیے، اس قدر کو `map1d` صف میں ڈالیں اور کاؤنٹر میں اضافہ کریں۔ + +``` + field[4] hashMe = [ + pack128(map1d[0..128]), + pack128(map1d[128..256]), + pack128(map1d[256..384]), + pack128(map1d[384..512]) + ]; +``` + +`pack128` `map1d` سے چار `field` اقدار کی ایک صف بنانے کے لیے۔ Zokrates میں `array[a..b]` کا مطلب ہے صف کا وہ ٹکڑا جو `a` سے شروع ہوتا ہے اور `b-1` پر ختم ہوتا ہے۔ + +``` + return poseidon(hashMe); +} +``` + +اس صف کو ہیش میں تبدیل کرنے کے لیے `poseidon` کا استعمال کریں۔ + +### ہیش پروگرام {#hash-program} + +سرور کو گیم شناخت کنندہ بنانے کے لیے براہ راست `hashMap` کو کال کرنے کی ضرورت ہے۔ تاہم، Zokrates صرف `main` فنکشن کو شروع کرنے کے لیے کال کر سکتا ہے، لہذا ہم ایک `main` کے ساتھ ایک پروگرام بناتے ہیں جو ہیش فنکشن کو کال کرتا ہے۔ + +``` +${hashFragment} + +def main(bool[${width+2}][${height+2}] map) -> field { + return hashMap(map); +} +``` + +### کھدائی پروگرام {#dig-program} + +یہ ایپلیکیشن کا زیرو نالج حصہ کا دل ہے، جہاں ہم وہ ثبوت تیار کرتے ہیں جو کھدائی کے نتائج کی تصدیق کے لیے استعمال ہوتے ہیں۔ + +``` +${hashFragment} + +// مقام (x,y) میں مائنز کی تعداد +def map2mineCount(bool[${width+2}][${height+2}] map, u32 x, u32 y) -> u8 { + return if map[x+1][y+1] { 1 } else { 0 }; +} +``` + +#### نقشے کا بارڈر کیوں {#why-map-border} + +زیرو نالج پروف [حسابی سرکٹس](https://medium.com/web3studio/simple-explanations-of-arithmetic-circuits-and-zero-knowledge-proofs-806e59a79785) کا استعمال کرتے ہیں، جن میں `if` اسٹیٹمنٹ کا کوئی آسان مساوی نہیں ہوتا ہے۔ اس کے بجائے، وہ [مشروط آپریٹر](https://en.wikipedia.org/wiki/Ternary_conditional_operator) کے مساوی کا استعمال کرتے ہیں۔ اگر `a` صفر یا ایک ہو سکتا ہے، تو آپ `if a { b } else { c }` کا حساب `ab+(1-a)c` کے طور پر کر سکتے ہیں۔ + +اس کی وجہ سے، ایک Zokrates `if` اسٹیٹمنٹ ہمیشہ دونوں شاخوں کا جائزہ لیتا ہے۔ مثال کے طور پر، اگر آپ کے پاس یہ کوڈ ہے: + +``` +bool[5] arr = [false; 5]; +u32 index=10; +return if index>4 { 0 } else { arr[index] } +``` + +اس میں خرابی ہوگی، کیونکہ اسے `arr[10]` کا حساب لگانے کی ضرورت ہے، چاہے وہ قدر بعد میں صفر سے ضرب دی جائے۔ + +یہی وجہ ہے کہ ہمیں نقشے کے چاروں طرف ایک مقام چوڑا بارڈر کی ضرورت ہے۔ ہمیں کسی مقام کے ارد گرد مائنز کی کل تعداد کا حساب لگانے کی ضرورت ہے، اور اس کا مطلب ہے کہ ہمیں اس مقام سے ایک قطار اوپر اور نیچے، بائیں اور دائیں کو دیکھنے کی ضرورت ہے، جہاں ہم کھدائی کر رہے ہیں۔ جس کا مطلب ہے کہ وہ مقام Zokrates کو فراہم کردہ نقشے کی صف میں موجود ہونا چاہیے۔ + +``` +def main(private bool[${width+2}][${height+2}] map, u32 x, u32 y) -> (field, u8) { +``` + +ڈیفالٹ کے طور پر Zokrates ثبوتوں میں ان کے ان پٹ شامل ہوتے ہیں۔ یہ جاننا کوئی فائدہ مند نہیں ہے کہ کسی جگہ کے ارد گرد پانچ مائنز ہیں جب تک کہ آپ کو حقیقت میں یہ نہ معلوم ہو کہ وہ کون سی جگہ ہے (اور آپ اسے صرف اپنی درخواست سے نہیں ملا سکتے، کیونکہ تب پروور مختلف اقدار کا استعمال کر سکتا ہے اور آپ کو اس کے بارے میں نہیں بتا سکتا)۔ تاہم، ہمیں نقشے کو خفیہ رکھنے کی ضرورت ہے، جبکہ اسے Zokrates کو فراہم کرتے ہوئے۔ حل یہ ہے کہ ایک `private` پیرامیٹر کا استعمال کیا جائے، ایک ایسا جو ثبوت سے _ظاہر_ نہیں ہوتا ہے۔ + +اس سے غلط استعمال کا ایک اور راستہ کھلتا ہے۔ پروور صحیح کوآرڈینیٹس کا استعمال کر سکتا ہے، لیکن مقام کے ارد گرد کسی بھی تعداد میں مائنز کے ساتھ ایک نقشہ بنا سکتا ہے، اور ممکنہ طور پر خود مقام پر بھی۔ اس غلط استعمال کو روکنے کے لیے، ہم زیرو نالج پروف کو نقشے کا ہیش شامل کرتے ہیں، جو گیم شناخت کنندہ ہے۔ + +``` + return (hashMap(map), +``` + +یہاں واپسی کی قیمت ایک ٹوپل ہے جس میں نقشہ ہیش صف اور کھدائی کا نتیجہ شامل ہے۔ + +``` + if map2mineCount(map, x, y) > 0 { 0xFF } else { +``` + +اگر خود مقام پر کوئی بم ہو تو ہم 255 کو ایک خاص قدر کے طور پر استعمال کرتے ہیں۔ + +``` + map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) + + map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) + + map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1) + } + ); +} +``` + +اگر کھلاڑی نے کسی مائن کو نہیں مارا ہے، تو مقام کے ارد گرد کے علاقے کے لیے مائن کاؤنٹ شامل کریں اور اسے واپس کریں۔ + +### TypeScript سے Zokrates کا استعمال {#using-zokrates-from-typescript} + +Zokrates کا ایک کمانڈ لائن انٹرفیس ہے، لیکن اس پروگرام میں ہم اسے [TypeScript کوڈ](https://zokrates.github.io/toolbox/zokrates_js.html) میں استعمال کرتے ہیں۔ + +Zokrates تعریفوں پر مشتمل لائبریری کو [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts) کہا جاتا ہے۔ + +```typescript +import { initialize as zokratesInitialize } from "zokrates-js" +``` + +[Zokrates جاوا اسکرپٹ بائنڈنگز](https://zokrates.github.io/toolbox/zokrates_js.html) کو درآمد کریں۔ ہمیں صرف [`initialize`](https://zokrates.github.io/toolbox/zokrates_js.html#initialize) فنکشن کی ضرورت ہے کیونکہ یہ ایک وعدہ لوٹاتا ہے جو تمام Zokrates تعریفوں کو حل کرتا ہے۔ + +```typescript +export const zkFunctions = async (width: number, height: number) : Promise => { +``` + +Zokrates کی طرح، ہم بھی صرف ایک فنکشن برآمد کرتے ہیں، جو [غیر ہم آہنگ](https://www.w3schools.com/js/js_async.asp) بھی ہے۔ جب یہ بالآخر واپس آتا ہے، تو یہ کئی فنکشن فراہم کرتا ہے جیسا کہ ہم نیچے دیکھیں گے۔ + +```typescript +const zokrates = await zokratesInitialize() +``` + +Zokrates کو شروع کریں، لائبریری سے ہمیں ہر چیز حاصل کریں۔ + +```typescript +const hashFragment = ` + import "utils/pack/bool/pack128.zok" as pack128; + import "hashes/poseidon/poseidon.zok" as poseidon; + . + . + . + } + ` + +const hashProgram = ` + ${hashFragment} + . + . + . + ` + +const digProgram = ` + ${hashFragment} + . + . + . + ` +``` + +اگلا ہمارے پاس ہیش فنکشن اور دو Zokrates پروگرام ہیں جو ہم نے اوپر دیکھے۔ + +```typescript +const digCompiled = zokrates.compile(digProgram) +const hashCompiled = zokrates.compile(hashProgram) +``` + +یہاں ہم ان پروگراموں کو کمپائل کرتے ہیں۔ + +```typescript +// زیرو نالج تصدیق کے لیے کیز بنائیں۔ +// ایک پروڈکشن سسٹم پر آپ ایک سیٹ اپ تقریب کا استعمال کرنا چاہیں گے۔ +// (https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). +const keySetupResults = zokrates.setup(digCompiled.program, "") +const verifierKey = keySetupResults.vk +const proverKey = keySetupResults.pk +``` + +ایک پروڈکشن سسٹم پر ہم ایک زیادہ پیچیدہ [سیٹ اپ تقریب](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony) کا استعمال کر سکتے ہیں، لیکن یہ ایک مظاہرے کے لیے کافی ہے۔ یہ کوئی مسئلہ نہیں ہے کہ صارفین پروور کی جان سکتے ہیں - وہ پھر بھی اسے چیزوں کو ثابت کرنے کے لیے استعمال نہیں کر سکتے جب تک کہ وہ سچ نہ ہوں۔ کیونکہ ہم اینٹروپی کی وضاحت کرتے ہیں (دوسرا پیرامیٹر، `""`)، نتائج ہمیشہ ایک جیسے ہی ہوں گے۔ + +**نوٹ:** Zokrates پروگراموں کی تالیف اور کلید کی تخلیق سست عمل ہیں۔ انہیں ہر بار دہرانے کی ضرورت نہیں ہے، صرف اس وقت جب نقشے کا سائز تبدیل ہوتا ہے۔ ایک پروڈکشن سسٹم پر آپ انہیں ایک بار کریں گے، اور پھر آؤٹ پٹ کو اسٹور کریں گے۔ میں یہاں صرف سادگی کی خاطر ایسا نہیں کر رہا ہوں۔ + +#### `calculateMapHash` {#calculateMapHash} + +```typescript +const calculateMapHash = function (hashMe: boolean[][]): string { + return ( + "0x" + + BigInt(zokrates.computeWitness(hashCompiled, [hashMe]).output.slice(1, -1)) + .toString(16) + .padStart(64, "0") + ) +} +``` + +[`computeWitness`](https://zokrates.github.io/toolbox/zokrates_js.html#computewitnessartifacts-args-options) فنکشن دراصل Zokrates پروگرام چلاتا ہے۔ یہ دو فیلڈز کے ساتھ ایک ڈھانچہ لوٹاتا ہے: `output`، جو ایک JSON سٹرنگ کے طور پر پروگرام کا آؤٹ پٹ ہے، اور `witness`، جو نتیجے کا زیرو نالج پروف بنانے کے لیے درکار معلومات ہے۔ یہاں ہمیں صرف آؤٹ پٹ کی ضرورت ہے۔ + +آؤٹ پٹ `"31337"` کی شکل میں ایک سٹرنگ ہے، جو کوٹیشن مارکس میں بند ایک اعشاریہ نمبر ہے۔ لیکن `viem` کے لیے ہمیں جو آؤٹ پٹ چاہیے وہ `0x60A7` کی شکل میں ایک ہیکساڈیسیمل نمبر ہے۔ لہذا ہم کوٹیشن مارکس کو ہٹانے کے لیے `.slice(1,-1)` کا استعمال کرتے ہیں اور پھر باقی سٹرنگ کو، جو ایک اعشاریہ نمبر ہے، ایک [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) میں تبدیل کرنے کے لیے `BigInt` کا استعمال کرتے ہیں۔ `.toString(16)` اس `BigInt` کو ایک ہیکساڈیسیمل سٹرنگ میں تبدیل کرتا ہے، اور `"0x"+` ہیکساڈیسیمل نمبروں کے لیے مارکر شامل کرتا ہے۔ + +```typescript +// کھودیں اور نتیجے کا زیرو نالج پروف لوٹائیں +// (سرور سائیڈ کوڈ) +``` + +زیرو نالج پروف میں عوامی ان پٹس (`x` اور `y`) اور نتائج (نقشے کا ہیش اور بموں کی تعداد) شامل ہیں۔ + +```typescript + const zkDig = function(map: boolean[][], x: number, y: number) : any { + if (x<0 || x>=width || y<0 || y>=height) + throw new Error("نقشے سے باہر کھدائی کی کوشش کی جا رہی ہے") +``` + +یہ چیک کرنا کہ آیا کوئی انڈیکس Zokrates میں حد سے باہر ہے، ایک مسئلہ ہے، لہذا ہم اسے یہاں کرتے ہیں۔ + +```typescript +const runResults = zokrates.computeWitness(digCompiled, [map, `${x}`, `${y}`]) +``` + +کھدائی پروگرام پر عمل کریں۔ + +```typescript + const proof = zokrates.generateProof( + digCompiled.program, + runResults.witness, + proverKey) + + return proof + } +``` + +[`generateProof`](https://zokrates.github.io/toolbox/zokrates_js.html#generateproofprogram-witness-provingkey-entropy) کا استعمال کریں اور ثبوت واپس کریں۔ + +```typescript +const solidityVerifier = ` + // نقشے کا سائز: ${width} x ${height} + \n${zokrates.exportSolidityVerifier(verifierKey)} + ` +``` + +ایک Solidity ویریفائر، ایک سمارٹ کنٹریکٹ جسے ہم بلاک چین پر تعینات کر سکتے ہیں اور `digCompiled.program` کے ذریعے تیار کردہ ثبوتوں کی تصدیق کے لیے استعمال کر سکتے ہیں۔ + +```typescript + return { + zkDig, + calculateMapHash, + solidityVerifier, + } +} +``` + +آخر میں، ہر وہ چیز واپس کریں جس کی دوسرے کوڈ کو ضرورت ہو سکتی ہے۔ + +## سیکیورٹی ٹیسٹ {#security-tests} + +سیکیورٹی ٹیسٹ اہم ہیں کیونکہ ایک فنکشنلٹی بگ بالآخر خود کو ظاہر کر دے گا۔ لیکن اگر ایپلیکیشن غیر محفوظ ہے، تو یہ ممکنہ طور پر ایک طویل عرصے تک چھپی رہے گی اس سے پہلے کہ یہ کسی کے دھوکہ دہی اور دوسروں سے تعلق رکھنے والے وسائل سے بچ نکلنے سے ظاہر ہو۔ + +### اجازتیں {#permissions} + +اس گیم میں ایک مراعات یافتہ ادارہ ہے، سرور۔ یہ واحد صارف ہے جسے [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol) میں فنکشنز کو کال کرنے کی اجازت ہے۔ ہم [`cast`](https://book.getfoundry.sh/cast/) کا استعمال کر سکتے ہیں تاکہ یہ تصدیق کی جا سکے کہ اجازت یافتہ فنکشنز کی کالز صرف سرور اکاؤنٹ کے طور پر ہی کی جا سکتی ہیں۔ + +[سرور کی نجی کلید `setupNetwork.ts` میں ہے](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/mud/setupNetwork.ts#L52)۔ + +1. `anvil` (بلاک چین) چلانے والے کمپیوٹر پر، یہ ماحولیاتی متغیرات سیٹ کریں۔ + + ```sh copy + WORLD_ADDRESS=0x8d8b6b8414e1e3dcfd4168561b9be6bd3bf6ec4b + UNAUTHORIZED_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a + AUTHORIZED_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d + ``` + +2. `cast` کا استعمال کریں تاکہ تصدیق کنندہ کا پتہ ایک غیر مجاز پتے کے طور پر سیٹ کرنے کی کوشش کی جا سکے۔ + + ```sh copy + cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $UNAUTHORIZED_KEY + ``` + + نہ صرف `cast` ایک ناکامی کی اطلاع دیتا ہے، بلکہ آپ براؤزر پر گیم میں **MUD Dev Tools** کھول سکتے ہیں، **ٹیبلز** پر کلک کر سکتے ہیں، اور **app\_\_VerifierAddress** کو منتخب کر سکتے ہیں۔ دیکھیں کہ پتہ صفر نہیں ہے۔ + +3. ویریفائر ایڈریس کو سرور کے ایڈریس کے طور پر سیٹ کریں۔ + + ```sh copy + cast send $WORLD_ADDRESS 'app__setVerifier(address)' `cast address-zero` --private-key $AUTHORIZED_KEY + ``` + + **app\_\_VerifiedAddress** میں پتہ اب صفر ہونا چاہیے۔ + +ایک ہی `System` میں تمام MUD فنکشنز ایک ہی ایکسیس کنٹرول سے گزرتے ہیں، لہذا میں اس ٹیسٹ کو کافی سمجھتا ہوں۔ اگر آپ نہیں کرتے ہیں، تو آپ [`ServerSystem`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/contracts/src/systems/ServerSystem.sol) میں دیگر فنکشنز کو چیک کر سکتے ہیں۔ + +### زیرو نالج کے غلط استعمال {#zero-knowledge-abuses} + +Zokrates کی تصدیق کے لیے ریاضی اس ٹیوٹوریل (اور میری صلاحیتوں) کے دائرہ سے باہر ہے۔ تاہم، ہم زیرو نالج کوڈ پر مختلف چیک چلا سکتے ہیں تاکہ یہ تصدیق کی جا سکے کہ اگر اسے صحیح طریقے سے نہیں کیا گیا تو یہ ناکام ہو جاتا ہے۔ ان تمام ٹیسٹوں کے لیے ہمیں [`zero-knowledge.ts`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts) کو تبدیل کرنے اور پوری ایپلیکیشن کو دوبارہ شروع کرنے کی ضرورت ہوگی۔ سرور پروسیس کو دوبارہ شروع کرنا کافی نہیں ہے، کیونکہ یہ ایپلیکیشن کو ایک ناممکن حالت میں ڈال دیتا ہے (کھلاڑی کا ایک گیم جاری ہے، لیکن گیم اب سرور کے لیے دستیاب نہیں ہے)۔ + +#### غلط جواب {#wrong-answer} + +سب سے آسان امکان زیرو نالج پروف میں غلط جواب فراہم کرنا ہے۔ ایسا کرنے کے لیے، ہم `zkDig` کے اندر جاتے ہیں اور [لائن 91 میں ترمیم کرتے ہیں](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L91): + +```ts +proof.inputs[3] = "0x" + "1".padStart(64, "0") +``` + +اس کا مطلب ہے کہ ہم ہمیشہ دعویٰ کریں گے کہ ایک بم ہے، چاہے صحیح جواب کچھ بھی ہو۔ اس ورژن کے ساتھ کھیلنے کی کوشش کریں، اور آپ `pnpm dev` اسکرین کے **سرور** ٹیب میں یہ خرابی دیکھیں گے: + +``` + cause: { + code: 3, + message: 'execution reverted: revert: Zero knowledge verification fail', + data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000 +00000000000000000000000000000000000000000000000205a65726f206b6e6f776c6564676520766572696669636174696f6 +e206661696c' + }, +``` + +تو اس قسم کی دھوکہ دہی ناکام ہو جاتی ہے۔ + +#### غلط ثبوت {#wrong-proof} + +کیا ہوتا ہے اگر ہم صحیح معلومات فراہم کریں، لیکن ثبوت کا ڈیٹا غلط ہو؟ اب، لائن 91 کو اس سے بدل دیں: + +```ts +proof.proof = { + a: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")], + b: [ + ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")], + ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")], + ], + c: ["0x" + "1".padStart(64, "0"), "0x" + "2".padStart(64, "0")], +} +``` + +یہ اب بھی ناکام رہتا ہے، لیکن اب یہ بغیر کسی وجہ کے ناکام ہوجاتا ہے کیونکہ یہ ویریفائر کال کے دوران ہوتا ہے۔ + +### ایک صارف زیرو ٹرسٹ کوڈ کی تصدیق کیسے کر سکتا ہے؟ {#user-verify-zero-trust} + +اسمارٹ معاہدوں کی تصدیق کرنا نسبتاً آسان ہے۔ عام طور پر، ڈیولپر سورس کوڈ کو ایک بلاک ایکسپلورر پر شائع کرتا ہے، اور بلاک ایکسپلورر اس بات کی تصدیق کرتا ہے کہ سورس کوڈ [معاہدے کی تعیناتی کے لین دین](/developers/docs/smart-contracts/deploying/) میں کوڈ کو کمپائل کرتا ہے۔ MUD `System`s کے معاملے میں یہ [تھوڑا زیادہ پیچیدہ](https://mud.dev/cli/verify) ہے، لیکن زیادہ نہیں۔ + +یہ زیرو نالج کے ساتھ زیادہ مشکل ہے۔ ویریفائر میں کچھ مستقل شامل ہوتے ہیں اور ان پر کچھ حسابات چلاتے ہیں۔ یہ آپ کو نہیں بتاتا کہ کیا ثابت کیا جا رہا ہے۔ + +```solidity + function verifyingKey() pure internal returns (VerifyingKey memory vk) { + vk.alpha = Pairing.G1Point(uint256(0x0f43f4fe7b5c2326fed4ac6ed2f4003ab9ab4ea6f667c2bdd77afb068617ee16), uint256(0x25a77832283f9726935219b5f4678842cda465631e72dbb24708a97ba5d0ce6f)); + vk.beta = Pairing.G2Point([uint256(0x2cebd0fbd21aca01910581537b21ae4fed46bc0e524c055059aa164ba0a6b62b), uint256(0x18fd4a7bc386cf03a95af7163d5359165acc4e7961cb46519e6d9ee4a1e2b7e9)], [uint256(0x11449dee0199ef6d8eebfe43b548e875c69e7ce37705ee9a00c81fe52f11a009), uint256(0x066d0c83b32800d3f335bb9e8ed5e2924cf00e77e6ec28178592eac9898e1a00)]); +``` + +حل، کم از کم جب تک بلاک ایکسپلوررز اپنے صارف انٹرفیس میں Zokrates کی تصدیق شامل نہیں کر لیتے، یہ ہے کہ ایپلیکیشن ڈیولپرز Zokrates پروگراموں کو دستیاب کرائیں، اور کم از کم کچھ صارفین انہیں مناسب تصدیقی کلید کے ساتھ خود کمپائل کریں۔ + +ایسا کرنے کے لیے: + +1. [Zokrates انسٹال کریں](https://zokrates.github.io/gettingstarted.html)۔ + +2. ایک فائل بنائیں، `dig.zok`، Zokrates پروگرام کے ساتھ۔ نیچے دیا گیا کوڈ یہ فرض کرتا ہے کہ آپ نے اصل نقشے کا سائز، 10x5، رکھا ہے۔ + + ```zokrates + import "utils/pack/bool/pack128.zok" as pack128; + import "hashes/poseidon/poseidon.zok" as poseidon; + + def hashMap(bool[12][7] map) -> field { + bool[512] mut map1d = [false; 512]; + u32 mut counter = 0; + + for u32 x in 0..12 { + for u32 y in 0..7 { + map1d[counter] = map[x][y]; + counter = counter+1; + } + } + + field[4] hashMe = [ + pack128(map1d[0..128]), + pack128(map1d[128..256]), + pack128(map1d[256..384]), + pack128(map1d[384..512]) + ]; + + return poseidon(hashMe); + } + + + // The number of mines in location (x,y) + def map2mineCount(bool[12][7] map, u32 x, u32 y) -> u8 { + return if map[x+1][y+1] { 1 } else { 0 }; + } + + def main(private bool[12][7] map, u32 x, u32 y) -> (field, u8) { + return (hashMap(map) , + if map2mineCount(map, x, y) > 0 { 0xFF } else { + map2mineCount(map, x-1, y-1) + map2mineCount(map, x, y-1) + map2mineCount(map, x+1, y-1) + + map2mineCount(map, x-1, y) + map2mineCount(map, x+1, y) + + map2mineCount(map, x-1, y+1) + map2mineCount(map, x, y+1) + map2mineCount(map, x+1, y+1) + } + ); + } + ``` + +3. Zokrates کوڈ کو کمپائل کریں اور تصدیقی کلید بنائیں۔ تصدیقی کلید اسی اینٹروپی کے ساتھ بنانی ہوگی جو اصل سرور میں استعمال کی گئی تھی، [اس معاملے میں ایک خالی سٹرنگ](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L67)۔ + + ```sh copy + zokrates compile --input dig.zok + zokrates setup -e "" + ``` + +4. اپنا Solidity ویریفائر خود بنائیں، اور تصدیق کریں کہ یہ بلاک چین پر موجود ویریفائر سے فنکشنل طور پر یکساں ہے (سرور ایک تبصرہ شامل کرتا ہے، لیکن یہ اہم نہیں ہے)۔ + + ```sh copy + zokrates export-verifier + diff verifier.sol ~/20240901-secret-state/packages/contracts/src/verifier.sol + ``` + +## ڈیزائن کے فیصلے {#design} + +کسی بھی کافی پیچیدہ ایپلیکیشن میں مسابقتی ڈیزائن کے اہداف ہوتے ہیں جن کے لیے سمجھوتہ کی ضرورت ہوتی ہے۔ آئیے کچھ سمجھوتوں کو دیکھتے ہیں اور یہ کہ موجودہ حل دوسرے اختیارات سے کیوں بہتر ہے۔ + +### زیرو نالج کیوں {#why-zero-knowledge} + +مائن سویپر کے لیے آپ کو حقیقت میں زیرو نالج کی ضرورت نہیں ہے۔ سرور ہمیشہ نقشہ رکھ سکتا ہے، اور پھر گیم ختم ہونے پر اس سب کو ظاہر کر سکتا ہے۔ پھر، گیم کے اختتام پر، سمارٹ کنٹریکٹ نقشے کے ہیش کا حساب لگا سکتا ہے، تصدیق کر سکتا ہے کہ یہ میل کھاتا ہے، اور اگر ایسا نہیں ہوتا ہے تو سرور کو سزا دے سکتا ہے یا گیم کو مکمل طور پر نظر انداز کر سکتا ہے۔ + +میں نے یہ آسان حل استعمال نہیں کیا کیونکہ یہ صرف اچھی طرح سے متعین اختتامی حالت والے مختصر گیمز کے لیے کام کرتا ہے۔ جب ایک گیم ممکنہ طور پر لامحدود ہو (جیسے کہ [خود مختار دنیاؤں](https://0xparc.org/blog/autonomous-worlds) کے معاملے میں)، آپ کو ایک ایسے حل کی ضرورت ہے جو حالت کو _ظاہر کیے بغیر_ ثابت کرے۔ + +ایک ٹیوٹوریل کے طور پر اس مضمون کو ایک مختصر گیم کی ضرورت تھی جو سمجھنے میں آسان ہو، لیکن یہ تکنیک طویل گیمز کے لیے سب سے زیادہ مفید ہے۔ + +### Zokrates کیوں؟ {#why-zokrates} + +[Zokrates](https://zokrates.github.io/) واحد زیرو نالج لائبریری دستیاب نہیں ہے، لیکن یہ ایک عام، [امپیریٹو](https://en.wikipedia.org/wiki/Imperative_programming) پروگرامنگ زبان کی طرح ہے اور بولین متغیرات کو سپورٹ کرتی ہے۔ + +آپ کی ایپلیکیشن کے لیے، مختلف ضروریات کے ساتھ، آپ [Circum](https://docs.circom.io/getting-started/installation/) یا [Cairo](https://www.cairo-lang.org/tutorials/getting-started-with-cairo/) کا استعمال کرنا پسند کر سکتے ہیں۔ + +### Zokrates کو کب کمپائل کریں {#when-compile-zokrates} + +اس پروگرام میں ہم Zokrates پروگراموں کو [ہر بار سرور شروع ہونے پر](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L60-L61) کمپائل کرتے ہیں۔ یہ واضح طور پر وسائل کا ضیاع ہے، لیکن یہ ایک ٹیوٹوریل ہے، جو سادگی کے لیے بہتر بنایا گیا ہے۔ + +اگر میں پروڈکشن لیول کی ایپلیکیشن لکھ رہا ہوتا، تو میں چیک کرتا کہ آیا میرے پاس اس مائن فیلڈ سائز پر کمپائل شدہ Zokrates پروگراموں کے ساتھ ایک فائل ہے، اور اگر ایسا ہے تو اسے استعمال کرتا۔ یہی بات آن چین پر ویریفائر کنٹریکٹ کی تعیناتی پر بھی لاگو ہوتی ہے۔ + +### ویریفائر اور پروور کیز بنانا {#key-creation} + +[کلید کی تخلیق](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L63-L69) ایک اور خالص حساب ہے جسے ایک دیے گئے مائن فیلڈ سائز کے لیے ایک سے زیادہ بار کرنے کی ضرورت نہیں ہے۔ ایک بار پھر، یہ صرف سادگی کی خاطر ایک بار کیا جاتا ہے۔ + +مزید برآں، ہم [ایک سیٹ اپ تقریب](https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony) کا استعمال کر سکتے ہیں۔ ایک سیٹ اپ تقریب کا فائدہ یہ ہے کہ آپ کو زیرو نالج پروف پر دھوکہ دینے کے لیے یا تو اینٹروپی یا ہر شریک سے کچھ درمیانی نتیجہ کی ضرورت ہوتی ہے۔ اگر کم از کم ایک تقریب کا شریک ایماندار ہے اور اس معلومات کو حذف کر دیتا ہے، تو زیرو نالج پروف کچھ حملوں سے محفوظ ہیں۔ تاہم، یہ تصدیق کرنے کا _کوئی میکانزم_ نہیں ہے کہ معلومات کو ہر جگہ سے حذف کر دیا گیا ہے۔ اگر زیرو نالج پروف انتہائی اہم ہیں، تو آپ سیٹ اپ تقریب میں حصہ لینا چاہتے ہیں۔ + +یہاں ہم [پرپیچوئل پاورز آف ٹاؤ](https://github.com/privacy-scaling-explorations/perpetualpowersoftau) پر انحصار کرتے ہیں، جس میں درجنوں شرکاء تھے۔ یہ شاید کافی محفوظ ہے، اور بہت آسان ہے۔ ہم کلید کی تخلیق کے دوران اینٹروپی بھی شامل نہیں کرتے ہیں، جس سے صارفین کے لیے [زیرو نالج کنفیگریشن کی تصدیق کرنا](#user-verify-zero-trust) آسان ہو جاتا ہے۔ + +### کہاں تصدیق کریں {#where-verification} + +ہم زیرو نالج پروف کو یا تو آن چین (جس پر گیس خرچ ہوتی ہے) یا کلائنٹ میں ( [`verify`](https://zokrates.github.io/toolbox/zokrates_js.html#verifyverificationkey-proof) کا استعمال کرتے ہوئے) تصدیق کر سکتے ہیں۔ میں نے پہلا انتخاب کیا، کیونکہ یہ آپ کو [ویریفائر کی تصدیق کرنے](#user-verify-zero-trust) کی اجازت دیتا ہے اور پھر اس بات پر بھروسہ کرتا ہے کہ جب تک اس کے لیے کنٹریکٹ کا پتہ وہی رہتا ہے، اس میں کوئی تبدیلی نہیں آتی ہے۔ اگر کلائنٹ پر تصدیق کی جاتی، تو آپ کو ہر بار کلائنٹ ڈاؤن لوڈ کرنے پر موصول ہونے والے کوڈ کی تصدیق کرنی پڑتی۔ + +نیز، جبکہ یہ گیم سنگل پلیئر ہے، بہت سے بلاک چین گیمز ملٹی پلیئر ہیں۔ آن چین تصدیق کا مطلب ہے کہ آپ صرف ایک بار زیرو نالج پروف کی تصدیق کرتے ہیں۔ اسے کلائنٹ میں کرنے کے لیے ہر کلائنٹ کو آزادانہ طور پر تصدیق کرنے کی ضرورت ہوگی۔ + +### نقشے کو TypeScript یا Zokrates میں فلیٹ کریں؟ {#where-flatten} + +عام طور پر، جب پروسیسنگ یا تو TypeScript یا Zokrates میں کی جا سکتی ہے، تو اسے TypeScript میں کرنا بہتر ہے، جو بہت تیز ہے، اور زیرو نالج پروف کی ضرورت نہیں ہے۔ یہی وجہ ہے، مثال کے طور پر، کہ ہم Zokrates کو ہیش فراہم نہیں کرتے ہیں اور اسے یہ تصدیق کرنے کے لیے کہتے ہیں کہ یہ درست ہے۔ ہیشنگ کو Zokrates کے اندر کرنا پڑتا ہے، لیکن واپس کیے گئے ہیش اور آن چین ہیش کے درمیان مماثلت اس کے باہر ہو سکتی ہے۔ + +تاہم، ہم اب بھی [Zokrates میں نقشے کو فلیٹ کرتے ہیں](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L15-L20)، جبکہ ہم اسے TypeScript میں کر سکتے تھے۔ وجہ یہ ہے کہ دوسرے اختیارات، میری رائے میں، بدتر ہیں۔ + +- Zokrates کوڈ کو بولین کی ایک جہتی صف فراہم کریں، اور دو جہتی نقشہ حاصل کرنے کے لیے `x*(height+2) + +y` جیسے تاثر کا استعمال کریں۔ یہ [کوڈ](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/zero-knowledge.ts#L44-L47) کو قدرے زیادہ پیچیدہ بنا دے گا، لہذا میں نے فیصلہ کیا کہ کارکردگی کا فائدہ ایک ٹیوٹوریل کے لیے اس کے قابل نہیں ہے۔ + +- Zokrates کو ایک جہتی صف اور دو جہتی صف دونوں بھیجیں۔ تاہم، اس حل سے ہمیں کچھ حاصل نہیں ہوتا۔ Zokrates کوڈ کو یہ تصدیق کرنی ہوگی کہ اسے فراہم کردہ ایک جہتی صف واقعی دو جہتی صف کی صحیح نمائندگی ہے۔ تو کارکردگی میں کوئی فائدہ نہیں ہوگا۔ + +- Zokrates میں دو جہتی صف کو فلیٹ کریں۔ یہ سب سے آسان آپشن ہے، لہذا میں نے اسے منتخب کیا۔ + +### نقشوں کو کہاں اسٹور کریں {#where-store-maps} + +اس ایپلیکیشن میں [`gamesInProgress`](https://github.com/qbzzt/20240901-secret-state/blob/main/packages/server/src/app.ts#L20) صرف میموری میں ایک متغیر ہے۔ اس کا مطلب ہے کہ اگر آپ کا سرور مر جاتا ہے اور اسے دوبارہ شروع کرنے کی ضرورت ہے، تو اس میں محفوظ تمام معلومات ضائع ہو جاتی ہیں۔ نہ صرف کھلاڑی اپنا کھیل جاری رکھنے سے قاصر ہیں، بلکہ وہ نیا کھیل بھی شروع نہیں کر سکتے کیونکہ آن چین جزو سوچتا ہے کہ ان کا ابھی بھی ایک کھیل جاری ہے۔ + +یہ واضح طور پر ایک پروڈکشن سسٹم کے لیے خراب ڈیزائن ہے، جس میں آپ اس معلومات کو ایک ڈیٹا بیس میں محفوظ کریں گے۔ میں نے یہاں ایک متغیر کا استعمال صرف اس لیے کیا کیونکہ یہ ایک ٹیوٹوریل ہے اور سادگی سب سے اہم غور ہے۔ + +## نتیجہ: کن حالات میں یہ مناسب تکنیک ہے؟ {#conclusion} + +تو، اب آپ جانتے ہیں کہ ایک سرور کے ساتھ ایک گیم کیسے لکھنا ہے جو خفیہ حالت کو اسٹور کرتا ہے جو آن چین سے تعلق نہیں رکھتا۔ لیکن کن معاملات میں آپ کو ایسا کرنا چاہیے؟ دو اہم غور ہیں۔ + +- _طویل چلنے والا کھیل_: [جیسا کہ اوپر ذکر کیا گیا ہے](#why-zero-knowledge)، ایک مختصر کھیل میں آپ صرف کھیل ختم ہونے کے بعد حالت کو شائع کر سکتے ہیں اور پھر ہر چیز کی تصدیق کروا سکتے ہیں۔ لیکن یہ ایک آپشن نہیں ہے جب کھیل میں لمبا یا غیر معینہ وقت لگتا ہے، اور حالت کو خفیہ رکھنے کی ضرورت ہے۔ + +- _کچھ مرکزیت قابل قبول_: زیرو نالج پروف سالمیت کی تصدیق کر سکتے ہیں، کہ کوئی ادارہ نتائج کو جعلی نہیں بنا رہا ہے۔ جو وہ نہیں کر سکتے وہ یہ یقینی بنانا ہے کہ ادارہ اب بھی دستیاب ہوگا اور پیغامات کا جواب دے گا۔ ان حالات میں جہاں دستیابی کو بھی غیر مرکزی کرنے کی ضرورت ہے، زیرو نالج پروف ایک کافی حل نہیں ہیں، اور آپ کو [ملٹی پارٹی کمپیوٹیشن](https://en.wikipedia.org/wiki/Secure_multi-party_computation) کی ضرورت ہے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ + +### اعترافات {#acknowledgements} + +- الوارو الونسو نے اس مضمون کا ایک مسودہ پڑھا اور Zokrates کے بارے میں میری کچھ غلط فہمیوں کو دور کیا۔ + +کوئی بھی باقی غلطیاں میری ذمہ داری ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/secure-development-workflow/index.md b/public/content/translations/ur/developers/tutorials/secure-development-workflow/index.md new file mode 100644 index 00000000000..23660856a59 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/secure-development-workflow/index.md @@ -0,0 +1,52 @@ +--- +title: "اسمارٹ کنٹریکٹ سیکورٹی چیک لسٹ" +description: "محفوظ اسمارٹ کنٹریکٹس لکھنے کے لیے ایک تجویز کردہ ورک فلو" +author: "Trailofbits" +tags: [ "اسمارٹ معاہدات", "سیکورٹی", "solidity" ] +skill: intermediate +lang: ur-in +published: 2020-09-07 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/workflow.md +--- + +## اسمارٹ کنٹریکٹ ڈیولپمنٹ چیک لسٹ {#smart-contract-development-checklist} + +یہاں ایک اعلیٰ سطحی عمل ہے جس پر عمل کرنے کی ہم تجویز کرتے ہیں جب آپ اپنے اسمارٹ کنٹریکٹس لکھتے ہیں۔ + +معلوم سیکورٹی مسائل کے لیے چیک کریں: + +- [Slither](https://github.com/crytic/slither) کے ساتھ اپنے کنٹریکٹس کا جائزہ لیں۔ اس میں عام کمزوریوں کے لیے 40 سے زیادہ بلٹ ان ڈیٹیکٹرز ہیں۔ اسے نئے کوڈ کے ساتھ ہر چیک ان پر چلائیں اور یقینی بنائیں کہ اسے ایک کلین رپورٹ ملے (یا بعض مسائل کو خاموش کرنے کے لیے ٹرائج موڈ استعمال کریں)۔ +- [Crytic](https://crytic.io/) کے ساتھ اپنے کنٹریکٹس کا جائزہ لیں۔ یہ 50 ایسے مسائل کی جانچ کرتا ہے جو Slither نہیں کرتا۔ Crytic، GitHub پر Pull Requests میں سیکورٹی مسائل کو آسانی سے سامنے لا کر آپ کی ٹیم کو ایک دوسرے کے کام سے باخبر رہنے میں بھی مدد کر سکتا ہے۔ + +اپنے کنٹریکٹ کے خصوصی فیچرز پر غور کریں: + +- کیا آپ کے کنٹریکٹس اپ گریڈ کے قابل ہیں؟ [`slither-check-upgradeability`](https://github.com/crytic/slither/wiki/Upgradeability-Checks) یا [Crytic](https://blog.trailofbits.com/2020/06/12/upgradeable-contracts-made-safer-with-crytic/) کے ساتھ خامیوں کے لیے اپنے اپ گریڈیبلٹی کوڈ کا جائزہ لیں۔ ہم نے 17 ایسے طریقوں کو دستاویز کیا ہے جن سے اپ گریڈز غلط ہو سکتے ہیں۔ +- کیا آپ کے کنٹریکٹس ERCs کے مطابق ہونے کا دعویٰ کرتے ہیں؟ انھیں [`slither-check-erc`](https://github.com/crytic/slither/wiki/ERC-Conformance) سے چیک کریں۔ یہ ٹول چھ عام اسپیکس سے انحراف کو فوری طور پر شناخت کرتا ہے۔ +- کیا آپ تھرڈ پارٹی ٹوکنز کے ساتھ انٹیگریٹ کرتے ہیں؟ بیرونی کنٹریکٹس پر انحصار کرنے سے پہلے ہمارے [ٹوکن انٹیگریشن چیک لسٹ](/developers/tutorials/token-integration-checklist/) کا جائزہ لیں۔ + +اپنے کوڈ کے اہم سیکورٹی فیچرز کا بصری طور پر معائنہ کریں: + +- Slither کے [inheritance-graph](https://github.com/trailofbits/slither/wiki/Printer-documentation#inheritance-graph) پرنٹر کا جائزہ لیں۔ نادانستہ شیڈونگ اور C3 لینیئرائزیشن کے مسائل سے بچیں۔ +- Slither کے [function-summary](https://github.com/trailofbits/slither/wiki/Printer-documentation#function-summary) پرنٹر کا جائزہ لیں۔ یہ فنکشن کی ویزیبلٹی اور رسائی کے کنٹرولز کو رپورٹ کرتا ہے۔ +- Slither کے [vars-and-auth](https://github.com/trailofbits/slither/wiki/Printer-documentation#variables-written-and-authorization) پرنٹر کا جائزہ لیں۔ یہ اسٹیٹ ویری ایبلز پر رسائی کے کنٹرولز کو رپورٹ کرتا ہے۔ + +اہم سیکورٹی پراپرٹیز کو دستاویز کریں اور ان کا جائزہ لینے کے لیے آٹومیٹڈ ٹیسٹ جنریٹرز کا استعمال کریں: + +- [اپنے کوڈ کے لیے سیکورٹی پراپرٹیز کو دستاویز کرنا](/developers/tutorials/guide-to-smart-contract-security-tools/) سیکھیں۔ پہلے تو یہ مشکل ہے، لیکن یہ ایک اچھا نتیجہ حاصل کرنے کے لیے سب سے اہم سرگرمی ہے۔ یہ اس ٹیوٹوریل میں کسی بھی جدید تکنیک کو استعمال کرنے کے لیے ایک پیشگی شرط بھی ہے۔ +- Solidity میں سیکورٹی پراپرٹیز کی وضاحت کریں، [Echidna](https://github.com/crytic/echidna) اور [Manticore](https://manticore.readthedocs.io/en/latest/verifier.html) کے ساتھ استعمال کے لیے۔ اپنی اسٹیٹ مشین، رسائی کے کنٹرولز، حسابی کارروائیوں، بیرونی تعاملات، اور معیارات کی مطابقت پر توجہ دیں۔ +- [Slither's Python API](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) کے ساتھ سیکورٹی پراپرٹیز کی وضاحت کریں۔ انہیریٹنس، ویری ایبل ڈیپنڈنسیس، رسائی کے کنٹرولز، اور دیگر ساختی مسائل پر توجہ دیں۔ +- [Crytic](https://crytic.io) کے ساتھ ہر کمٹ پر اپنے پراپرٹی ٹیسٹ چلائیں۔ Crytic سیکورٹی پراپرٹی ٹیسٹ کو استعمال اور ان کا جائزہ لے سکتا ہے تاکہ آپ کی ٹیم میں ہر کوئی آسانی سے دیکھ سکے کہ وہ GitHub پر پاس ہو گئے ہیں۔ ناکام ٹیسٹ کمٹس کو بلاک کر سکتے ہیں۔ + +آخر میں، ان مسائل سے آگاہ رہیں جنہیں آٹومیٹڈ ٹولز آسانی سے نہیں ڈھونڈ سکتے: + +- پرائیویسی کی کمی: جب آپ کے ٹرانزیکشنز پول میں قطار میں ہوتے ہیں تو ہر کوئی انہیں دیکھ سکتا ہے +- فرنٹ رننگ ٹرانزیکشنز +- کرپٹوگرافک آپریشنز +- بیرونی DeFi کمپونینٹس کے ساتھ پرخطر تعاملات + +## مدد طلب کریں {#ask-for-help} + +[Ethereum آفس آورز](https://calendly.com/dan-trailofbits/office-hours) ہر منگل کی سہ پہر کو ہوتے ہیں۔ یہ 1 گھنٹے کے، 1-آن-1 سیشنز سیکورٹی کے بارے میں آپ کے کسی بھی سوال کو پوچھنے، ہمارے ٹولز کا استعمال کرتے ہوئے ٹربل شوٹ کرنے، اور ماہرین سے اپنے موجودہ نقطہ نظر کے بارے میں فیڈبیک حاصل کرنے کا ایک موقع ہیں۔ ہم اس گائیڈ پر کام کرنے میں آپ کی مدد کریں گے۔ + +ہمارے Slack میں شامل ہوں: [Empire Hacking](https://join.slack.com/t/empirehacking/shared_invite/zt-h97bbrj8-1jwuiU33nnzg67JcvIciUw)۔ اگر آپ کے کوئی سوالات ہیں تو ہم #crytic اور #ethereum چینلز میں ہمیشہ دستیاب ہیں۔ diff --git a/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md b/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md new file mode 100644 index 00000000000..6e9e1706ed3 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md @@ -0,0 +1,210 @@ +--- +title: "ethers.js کا استعمال کرتے ہوئے ٹوکن بھیجنا" +description: "ethers.js کا استعمال کرتے ہوئے ٹوکن بھیجنے کے لیے ابتدائی افراد کے لیے دوستانہ گائیڈ۔" +author: Kim YongJun +tags: [ "ETHERS.JS", "ERC-20", "ٹوکنز" ] +skill: beginner +lang: ur-in +published: 2021-04-06 +--- + +## ethers.js(5.0) کا استعمال کرتے ہوئے ٹوکن بھیجیں {#send-token} + +### اس ٹیوٹوریل میں آپ سیکھیں گے کہ کیسے {#you-learn-about} + +- ethers.js امپورٹ کریں +- ٹوکن منتقل کریں +- نیٹ ورک ٹریفک کی صورتحال کے مطابق گیس کی قیمت مقرر کریں + +### شروع کرنے کے لیے {#to-get-started} + +شروع کرنے کے لیے، ہمیں سب سے پہلے اپنے javascript میں ethers.js لائبریری امپورٹ کرنی ہوگی +ethers.js(5.0) شامل کریں + +### انسٹال کرنا {#install-ethersjs} + +```shell +/home/ricmoo> npm install --save ethers +``` + +براؤزر میں ES6 + +```html + +``` + +براؤزر میں ES3(UMD) + +```html + +``` + +### پیرامیٹرز {#param} + +1. **`contract_address`**: ٹوکن کنٹریکٹ کا پتہ (کنٹریکٹ ایڈریس کی ضرورت اس وقت ہوتی ہے جب آپ جو ٹوکن منتقل کرنا چاہتے ہیں وہ ether نہ ہو) +2. **`send_token_amount`**: وہ رقم جو آپ وصول کنندہ کو بھیجنا چاہتے ہیں +3. **`to_address`**: وصول کنندہ کا پتہ +4. **`send_account`**: بھیجنے والے کا پتہ +5. **`private_key`**: ٹرانزیکشن پر دستخط کرنے اور دراصل ٹوکن منتقل کرنے کے لیے بھیجنے والے کی نجی کلید + +## نوٹس {#notice} + +`signTransaction(tx)` کو ہٹا دیا گیا ہے کیونکہ `sendTransaction()` اسے اندرونی طور پر کرتا ہے۔ + +## بھیجنے کے طریقہ کار {#procedure} + +### 1۔ نیٹ ورک سے جڑیں (ٹیسٹ نیٹ) {#connect-to-network} + +#### پرووائڈر سیٹ کریں (Infura) {#set-provider} + +Ropsten ٹیسٹ نیٹ سے جڑیں + +```javascript +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") +``` + +### 2۔ والیٹ بنائیں {#create-wallet} + +```javascript +let wallet = new ethers.Wallet(private_key) +``` + +### 3۔ والیٹ کو نیٹ سے جوڑیں {#connect-wallet-to-net} + +```javascript +let walletSigner = wallet.connect(window.ethersProvider) +``` + +### 4. موجودہ گیس کی قیمت حاصل کریں {#get-gas} + +```javascript +window.ethersProvider.getGasPrice() // گیس کی قیمت +``` + +### 5. ٹرانزیکشن کی وضاحت کریں {#define-transaction} + +نیچے بیان کردہ یہ متغیرات `send_token()` پر منحصر ہیں + +### ٹرانزیکشن پیرامیٹرز {#transaction-params} + +1. **`send_account`**: ٹوکن بھیجنے والے کا پتہ +2. **`to_address`**: ٹوکن وصول کرنے والے کا پتہ +3. **`send_token_amount`**: بھیجے جانے والے ٹوکنز کی مقدار +4. **`gas_limit`**: گیس کی حد +5. **`gas_price`**: گیس کی قیمت + +[استعمال کرنے کا طریقہ جاننے کے لیے نیچے دیکھیں](#how-to-use) + +```javascript +const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount(send_account, "latest"), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, +} +``` + +### 6. منتقل کریں {#transfer} + +```javascript +walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("بھیجنا مکمل!") +}) +``` + +## اسے کیسے استعمال کریں {#how-to-use} + +```javascript +let private_key = + "41559d28e936dc92104ff30691519693fc753ffbee6251a611b9aa1878f12a4d" +let send_token_amount = "1" +let to_address = "0x4c10D2734Fb76D3236E522509181CC3Ba8DE0e80" +let send_address = "0xda27a282B5B6c5229699891CfA6b900A716539E6" +let gas_limit = "0x100000" +let wallet = new ethers.Wallet(private_key) +let walletSigner = wallet.connect(window.ethersProvider) +let contract_address = "" +window.ethersProvider = new ethers.providers.InfuraProvider("ropsten") + +send_token( + contract_address, + send_token_amount, + to_address, + send_address, + private_key +) +``` + +### کامیاب! {#success} + +![کامیابی سے مکمل ہوئی ٹرانزیکشن کی تصویر](./successful-transaction.png) + +## send_token() {#send-token-method} + +```javascript +function send_token( + contract_address, + send_token_amount, + to_address, + send_account, + private_key +) { + let wallet = new ethers.Wallet(private_key) + let walletSigner = wallet.connect(window.ethersProvider) + + window.ethersProvider.getGasPrice().then((currentGasPrice) => { + let gas_price = ethers.utils.hexlify(parseInt(currentGasPrice)) + console.log(`gas_price: ${gas_price}`) + + if (contract_address) { + // عام ٹوکن بھیجیں + let contract = new ethers.Contract( + contract_address, + send_abi, + walletSigner + ) + + // کتنے ٹوکنز؟ + let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18) + console.log(`numberOfTokens: ${numberOfTokens}`) + + // ٹوکنز بھیجیں + contract.transfer(to_address, numberOfTokens).then((transferResult) => { + console.dir(transferResult) + alert("ٹوکن بھیج دیا گیا") + }) + } // ether بھیجیں + else { + const tx = { + from: send_account, + to: to_address, + value: ethers.utils.parseEther(send_token_amount), + nonce: window.ethersProvider.getTransactionCount( + send_account, + "latest" + ), + gasLimit: ethers.utils.hexlify(gas_limit), // 100000 + gasPrice: gas_price, + } + console.dir(tx) + try { + walletSigner.sendTransaction(tx).then((transaction) => { + console.dir(transaction) + alert("بھیجنا مکمل!") + }) + } catch (error) { + alert("بھیجنے میں ناکام!!") + } + } + }) +} +``` diff --git a/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md b/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md new file mode 100644 index 00000000000..d2cd65b24c3 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md @@ -0,0 +1,208 @@ +--- +title: "Web3 کا استعمال کرتے ہوئے لین دین بھیجنا" +description: "یہ Web3 کا استعمال کرتے ہوئے Ethereum لین دین بھیجنے کے لیے ایک ابتدائی دوستانہ گائیڈ ہے۔ Ethereum بلاک چین پر لین دین بھیجنے کے لیے تین اہم مراحل ہیں: تخلیق کریں، دستخط کریں، اور براڈکاسٹ کریں۔ ہم ان تینوں پر عمل کریں گے۔" +author: "Elan Halpern" +tags: [ "لین دین", "web3.js", "alchemy" ] +skill: beginner +lang: ur-in +published: 2020-11-04 +source: Alchemy docs +sourceUrl: https://www.alchemy.com/docs/how-to-send-transactions-on-ethereum +--- + +یہ Web3 کا استعمال کرتے ہوئے Ethereum لین دین بھیجنے کے لیے ایک ابتدائی دوستانہ گائیڈ ہے۔ Ethereum بلاک چین پر لین دین بھیجنے کے لیے تین اہم مراحل ہیں: تخلیق کریں، دستخط کریں، اور براڈکاسٹ کریں۔ ہم ان تینوں پر عمل کریں گے، امید ہے کہ آپ کے تمام سوالوں کے جواب مل جائیں گے! اس ٹیوٹوریل میں، ہم اپنے لین دین کو Ethereum چین پر بھیجنے کے لیے [Alchemy](https://www.alchemy.com/) کا استعمال کریں گے۔ آپ [یہاں ایک مفت Alchemy اکاؤنٹ بنا سکتے ہیں](https://auth.alchemyapi.io/signup)۔ + +**نوٹ:** یہ گائیڈ آپ کی ایپ کے لیے _بیک اینڈ_ پر آپ کے لین دین پر دستخط کرنے کے لیے ہے۔ اگر آپ فرنٹ اینڈ پر اپنے لین دین پر دستخط کو مربوط کرنا چاہتے ہیں، تو [براؤزر فراہم کنندہ کے ساتھ Web3 کو مربوط کرنے](https://docs.alchemy.com/reference/api-overview#with-a-browser-provider) کی جانچ کریں۔ + +## بنیادی باتیں {#the-basics} + +زیادہ تر بلاک چین ڈویلپرز کی طرح جب وہ پہلی بار شروع کرتے ہیں، تو ہو سکتا ہے کہ آپ نے لین دین بھیجنے کے طریقے پر کچھ تحقیق کی ہو (ایسی چیز جو بہت آسان ہونی چاہیے) اور بہت سارے گائیڈز کا سامنا کیا ہو، ہر ایک مختلف باتیں کہہ رہا ہو اور آپ کو تھوڑا مغلوب اور الجھن میں ڈال دیا ہو۔ اگر آپ بھی اسی حال میں ہیں، تو فکر نہ کریں؛ ہم سب کبھی نہ کبھی اس حال میں تھے! تو، شروع کرنے سے پہلے، آئیے کچھ چیزوں کو سیدھا کر لیں: + +### 1. Alchemy آپ کی نجی کلیدوں کو ذخیرہ نہیں کرتا ہے {#alchemy-does-not-store-your-private-keys} + +- اس کا مطلب ہے کہ Alchemy آپ کی طرف سے لین دین پر دستخط اور بھیج نہیں سکتا ہے۔ اس کی وجہ سیکورٹی کے مقاصد ہیں۔ Alchemy کبھی بھی آپ سے اپنی نجی کلید شیئر کرنے کے لیے نہیں کہے گا، اور آپ کو کبھی بھی اپنی نجی کلید کسی میزبان نوڈ (یا اس معاملے میں کسی کے ساتھ) شیئر نہیں کرنی چاہیے۔ +- آپ Alchemy کے کور API کا استعمال کرتے ہوئے بلاک چین سے پڑھ سکتے ہیں، لیکن اس پر لکھنے کے لیے آپ کو Alchemy کے ذریعے بھیجنے سے پہلے اپنے لین دین پر دستخط کرنے کے لیے کچھ اور استعمال کرنے کی ضرورت ہوگی (یہ کسی بھی دوسرے [نوڈ سروس](/developers/docs/nodes-and-clients/nodes-as-a-service/) کے لیے بھی ایسا ہی ہے)۔ + +### 2. ایک “دستخط کنندہ” کیا ہے؟ {#what-is-a-signer} + +- دستخط کنندگان آپ کے لیے آپ کی نجی کلید کا استعمال کرتے ہوئے لین دین پر دستخط کریں گے۔ اس ٹیوٹوریل میں ہم اپنے لین دین پر دستخط کرنے کے لیے [Alchemy web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3) کا استعمال کریں گے، لیکن آپ کوئی دوسری web3 لائبریری بھی استعمال کر سکتے ہیں۔ +- فرنٹ اینڈ پر، دستخط کنندہ کی ایک اچھی مثال [MetaMask](https://metamask.io/) ہوگی، جو آپ کی طرف سے لین دین پر دستخط اور بھیجے گا۔ + +### 3. مجھے اپنے لین دین پر دستخط کرنے کی ضرورت کیوں ہے؟ {#why-do-i-need-to-sign-my-transactions} + +- ہر وہ صارف جو Ethereum نیٹ ورک پر لین دین بھیجنا چاہتا ہے اسے لین دین پر دستخط کرنا ہوگا (اپنی نجی کلید کا استعمال کرتے ہوئے)، تاکہ یہ تصدیق کی جا سکے کہ لین دین کا ماخذ وہی ہے جس کا وہ دعویٰ کرتا ہے۔ +- اس نجی کلید کی حفاظت کرنا بہت ضروری ہے، کیونکہ اس تک رسائی آپ کے Ethereum اکاؤنٹ پر مکمل کنٹرول فراہم کرتی ہے، جس سے آپ (یا رسائی رکھنے والے کسی بھی شخص) کو آپ کی طرف سے لین دین کرنے کی اجازت ملتی ہے۔ + +### 4. میں اپنی نجی کلید کی حفاظت کیسے کروں؟ {#how-do-i-protect-my-private-key} + +- اپنی نجی کلید کی حفاظت کرنے اور اسے لین دین بھیجنے کے لیے استعمال کرنے کے بہت سے طریقے ہیں۔ اس ٹیوٹوریل میں ہم ایک `.env` فائل کا استعمال کریں گے۔ تاہم، آپ ایک علیحدہ فراہم کنندہ بھی استعمال کر سکتے ہیں جو نجی کلیدوں کو ذخیرہ کرتا ہے، ایک کیسٹور فائل، یا دیگر اختیارات استعمال کر سکتے ہیں۔ + +### 5. `eth_sendTransaction` اور `eth_sendRawTransaction` کے درمیان کیا فرق ہے؟ {#difference-between-send-and-send-raw} + +`eth_sendTransaction` اور `eth_sendRawTransaction` دونوں Ethereum API فنکشنز ہیں جو Ethereum نیٹ ورک پر لین دین کو براڈکاسٹ کرتے ہیں تاکہ اسے مستقبل کے بلاک میں شامل کیا جا سکے۔ وہ لین دین پر دستخط کو سنبھالنے کے طریقے میں مختلف ہیں۔ + +- [`eth_sendTransaction`](https://docs.web3js.org/api/web3-eth/function/sendTransaction) کا استعمال _بغیر دستخط شدہ_ لین دین بھیجنے کے لیے کیا جاتا ہے، جس کا مطلب ہے کہ جس نوڈ پر آپ بھیج رہے ہیں اسے آپ کی نجی کلید کا انتظام کرنا چاہیے تاکہ وہ اسے چین پر براڈکاسٹ کرنے سے پہلے لین دین پر دستخط کر سکے۔ چونکہ Alchemy صارف کی نجی کلیدوں کو نہیں رکھتا ہے، اس لیے وہ اس طریقے کی حمایت نہیں کرتے ہیں۔ +- [`eth_sendRawTransaction`](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_sendrawtransaction) کا استعمال ان لین دین کو براڈکاسٹ کرنے کے لیے کیا جاتا ہے جن پر پہلے ہی دستخط ہو چکے ہیں۔ اس کا مطلب ہے کہ آپ کو پہلے [`signTransaction(tx, private_key)`](https://docs.web3js.org/api/web3-eth-accounts/function/signTransaction) کا استعمال کرنا ہوگا، پھر نتیجہ کو `eth_sendRawTransaction` میں پاس کرنا ہوگا۔ + +web3 کا استعمال کرتے وقت، `eth_sendRawTransaction` کو فنکشن [web3.eth.sendSignedTransaction](https://docs.web3js.org/api/web3-eth/function/sendSignedTransaction) کو کال کرکے رسائی حاصل کی جاتی ہے۔ + +اس ٹیوٹوریل میں ہم یہی استعمال کریں گے۔ + +### 6. web3 لائبریری کیا ہے؟ {#what-is-the-web3-library} + +- Web3.js معیاری JSON-RPC کالز کے ارد گرد ایک ریپر لائبریری ہے جو Ethereum کی ڈیولپمنٹ میں استعمال کرنا کافی عام ہے۔ +- مختلف زبانوں کے لیے بہت سی web3 لائبریریاں ہیں۔ اس ٹیوٹوریل میں ہم [Alchemy Web3](https://docs.alchemy.com/reference/api-overview) کا استعمال کریں گے جو JavaScript میں لکھی گئی ہے۔ آپ [یہاں](https://docs.alchemyapi.io/guides/getting-started#other-web3-libraries) دیگر اختیارات جیسے [ethers.js](https://docs.ethers.org/v5/) دیکھ سکتے ہیں۔ + +ٹھیک ہے، اب جب کہ ہم نے ان میں سے کچھ سوالات کو راستے سے ہٹا دیا ہے، آئیے ٹیوٹوریل کی طرف بڑھتے ہیں۔ Alchemy [discord](https://discord.gg/gWuC7zB) میں کسی بھی وقت سوالات پوچھنے کے لیے آزاد محسوس کریں! + +### 7. محفوظ، گیس-آپٹمائزڈ، اور نجی لین دین کیسے بھیجیں؟ {#how-to-send-secure-gas-optimized-and-private-transactions} + +- [Alchemy کے پاس Transact APIs کا ایک مجموعہ ہے](https://docs.alchemy.com/reference/transact-api-quickstart)۔ آپ ان کا استعمال مضبوط لین دین بھیجنے، لین دین ہونے سے پہلے ان کی تقلید کرنے، نجی لین دین بھیجنے، اور گیس-آپٹمائزڈ لین دین بھیجنے کے لیے کر سکتے ہیں۔ +- آپ [Notify API](https://docs.alchemy.com/docs/alchemy-notify) کا استعمال بھی کر سکتے ہیں تاکہ آپ کو مطلع کیا جا سکے جب آپ کا لین دین میمپول سے کھینچ کر چین میں شامل کیا جائے۔ + +**نوٹ:** اس گائیڈ کے لیے Alchemy اکاؤنٹ، ایک Ethereum ایڈریس یا MetaMask والیٹ، NodeJs، اور npm انسٹال ہونا ضروری ہے۔ اگر نہیں، تو ان اقدامات پر عمل کریں: + +1. [ایک مفت Alchemy اکاؤنٹ بنائیں](https://auth.alchemyapi.io/signup) +2. [MetaMask اکاؤنٹ بنائیں](https://metamask.io/) (یا ایک Ethereum ایڈریس حاصل کریں) +3. [NodeJs اور NPM انسٹال کرنے کے لیے ان اقدامات پر عمل کریں](https://docs.alchemy.com/alchemy/guides/alchemy-for-macs) + +## اپنا لین دین بھیجنے کے اقدامات {#steps-to-sending-your-transaction} + +### 1. Sepolia ٹیسٹ نیٹ پر ایک Alchemy ایپ بنائیں {#create-an-alchemy-app-on-the-sepolia-testnet} + +اپنے [Alchemy ڈیش بورڈ](https://dashboard.alchemyapi.io/) پر جائیں اور ایک نئی ایپ بنائیں، اپنے نیٹ ورک کے لیے Sepolia (یا کوئی دوسرا ٹیسٹ نیٹ) کا انتخاب کریں۔ + +### 2. Sepolia فاسیٹ سے ETH کی درخواست کریں {#request-eth-from-sepolia-faucet} + +ETH حاصل کرنے کے لیے [Alchemy Sepolia فاسیٹ](https://www.sepoliafaucet.com/) پر دی گئی ہدایات پر عمل کریں۔ یقینی بنائیں کہ آپ اپنا **Sepolia** Ethereum ایڈریس (MetaMask سے) شامل کریں اور کوئی دوسرا نیٹ ورک نہیں۔ ہدایات پر عمل کرنے کے بعد، دوبارہ چیک کریں کہ آپ نے اپنے والیٹ میں ETH وصول کر لیا ہے۔ + +### 3. ایک نئی پراجیکٹ ڈائرکٹری بنائیں اور اس میں `cd` کریں {#create-a-new-project-direction} + +کمانڈ لائن (macs کے لیے ٹرمینل) سے ایک نئی پراجیکٹ ڈائرکٹری بنائیں اور اس میں نیویگیٹ کریں: + +``` +mkdir sendtx-example +cd sendtx-example +``` + +### 4. Alchemy Web3 (یا کوئی بھی web3 لائبریری) انسٹال کریں {#install-alchemy-web3} + +[Alchemy Web3](https://docs.alchemy.com/reference/api-overview) انسٹال کرنے کے لیے اپنی پراجیکٹ ڈائرکٹری میں درج ذیل کمانڈ چلائیں: + +نوٹ، اگر آپ ethers.js لائبریری استعمال کرنا چاہتے ہیں، تو [یہاں دی گئی ہدایات پر عمل کریں](https://docs.alchemy.com/docs/how-to-send-transactions-on-ethereum)۔ + +``` +npm install @alch/alchemy-web3 +``` + +### 5. dotenv انسٹال کریں {#install-dotenv} + +ہم اپنی API کلید اور نجی کلید کو محفوظ طریقے سے ذخیرہ کرنے کے لیے ایک `.env` فائل استعمال کریں گے۔ + +``` +npm install dotenv --save +``` + +### 6. `.env` فائل بنائیں {#create-the-dotenv-file} + +اپنی پراجیکٹ ڈائرکٹری میں ایک `.env` فائل بنائیں اور درج ذیل شامل کریں (“`your-api-url`" اور "`your-private-key`" کو تبدیل کرتے ہوئے) + +- اپنا Alchemy API URL تلاش کرنے کے لیے، اپنے ڈیش بورڈ پر ابھی بنائی گئی ایپ کے ایپ تفصیلات کے صفحے پر جائیں، اوپر دائیں کونے میں “View Key” پر کلک کریں، اور HTTP URL حاصل کریں۔ +- MetaMask کا استعمال کرتے ہوئے اپنی نجی کلید تلاش کرنے کے لیے، یہ [گائیڈ](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key) دیکھیں۔ + +``` +API_URL = "your-api-url" +PRIVATE_KEY = "your-private-key" +``` + + + + +.env کو کمٹ نہ کریں! براہ کرم یقینی بنائیں کہ آپ اپنی .env فائل کسی کے ساتھ شیئر یا ظاہر نہ کریں، کیونکہ ایسا کرنے سے آپ اپنے رازوں پر سمجھوتہ کر رہے ہیں۔ اگر آپ ورژن کنٹرول استعمال کر رہے ہیں، تو اپنی .env کو gitignore فائل میں شامل کریں۔ + + + + +### 7. `sendTx.js` فائل بنائیں {#create-sendtx-js} + +بہت اچھا، اب جب کہ ہمارا حساس ڈیٹا ایک `.env` فائل میں محفوظ ہے، آئیے کوڈنگ شروع کرتے ہیں۔ ہمارے بھیجنے والے لین دین کی مثال کے لیے، ہم ETH کو Sepolia فاسیٹ پر واپس بھیجیں گے۔ + +ایک `sendTx.js` فائل بنائیں، جہاں ہم اپنے مثال کے لین دین کو کنفیگر اور بھیجیں گے، اور اس میں کوڈ کی درج ذیل لائنیں شامل کریں: + +``` +async function main() { + require('dotenv').config(); + const { API_URL, PRIVATE_KEY } = process.env; + const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); + const web3 = createAlchemyWeb3(API_URL); + const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: اس ایڈریس کو اپنے عوامی ایڈریس سے تبدیل کریں + + const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // نونس 0 سے گننا شروع کرتا ہے + + const transaction = { + 'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // eth واپس کرنے کے لیے فاسیٹ ایڈریس + 'value': 1000000000000000000, // 1 ETH + 'gas': 30000, + 'nonce': nonce, + // پیغام بھیجنے یا سمارٹ کنٹریکٹ پر عمل کرنے کے لیے اختیاری ڈیٹا فیلڈ + }; + + const signedTx = await web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY); + + web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(error, hash) { + if (!error) { + console.log("🎉 آپ کے لین دین کا ہیش یہ ہے: ", hash, "\n اپنے لین دین کی حیثیت دیکھنے کے لیے Alchemy's Mempool کو چیک کریں!"); + } else { + console.log("❗آپ کا لین دین جمع کراتے وقت کچھ غلط ہو گیا:", error) + } + }); +} + +main(); +``` + +یقینی بنائیں کہ آپ **لائن 6** پر موجود ایڈریس کو اپنے عوامی ایڈریس سے تبدیل کریں۔ + +اب، اس کوڈ کو چلانے سے پہلے، آئیے یہاں کچھ اجزاء کے بارے میں بات کرتے ہیں۔ + +- `nonce`: نونس کی تفصیلات کا استعمال آپ کے ایڈریس سے بھیجے گئے لین دین کی تعداد پر نظر رکھنے کے لیے کیا جاتا ہے۔ ہمیں اس کی ضرورت سیکورٹی کے مقاصد اور [ری پلے حملوں](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce) کو روکنے کے لیے ہے۔ اپنے ایڈریس سے بھیجے گئے لین دین کی تعداد حاصل کرنے کے لیے ہم [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount) کا استعمال کرتے ہیں۔ +- `transaction`: لین دین کی آبجیکٹ کے کچھ پہلو ہیں جن کی ہمیں وضاحت کرنے کی ضرورت ہے۔ + - `to`: یہ وہ ایڈریس ہے جس پر ہم ETH بھیجنا چاہتے ہیں۔ اس معاملے میں، ہم ETH کو [Sepolia فاسیٹ](https://sepoliafaucet.com/) پر واپس بھیج رہے ہیں جس سے ہم نے ابتدائی طور پر درخواست کی تھی۔ + - `value`: یہ وہ رقم ہے جسے ہم بھیجنا چاہتے ہیں، جو Wei میں بیان کی گئی ہے جہاں 10^18 Wei = 1 ETH + - `gas`: اپنے لین دین میں شامل کرنے کے لیے گیس کی صحیح مقدار کا تعین کرنے کے بہت سے طریقے ہیں۔ Alchemy کے پاس ایک [گیس پرائس ویب ہک](https://docs.alchemyapi.io/guides/alchemy-notify#address-activity-1) بھی ہے جو آپ کو مطلع کرتا ہے جب گیس کی قیمت ایک خاص حد کے اندر آ جاتی ہے۔ Mainnet لین دین کے لیے، گیس کی صحیح مقدار کا تعین کرنے کے لیے [ETH Gas Station](https://ethgasstation.info/) جیسے گیس ایسٹیمیٹر کو چیک کرنا ایک اچھا عمل ہے۔ 21000 گیس کی کم از کم مقدار ہے جو Ethereum پر ایک آپریشن استعمال کرے گا، لہذا اس بات کو یقینی بنانے کے لیے کہ ہمارا لین دین انجام دیا جائے گا ہم یہاں 30000 ڈالتے ہیں۔ + - `nonce`: اوپر نونس کی تعریف دیکھیں۔ نونس صفر سے گننا شروع کرتا ہے۔ + - [اختیاری] ڈیٹا: آپ کی منتقلی کے ساتھ اضافی معلومات بھیجنے، یا اسمارٹ کنٹریکٹ کو کال کرنے کے لیے استعمال کیا جاتا ہے، بیلنس کی منتقلی کے لیے ضروری نہیں، نیچے دیا گیا نوٹ دیکھیں۔ +- `signedTx`: اپنے لین دین کی آبجیکٹ پر دستخط کرنے کے لیے ہم `PRIVATE_KEY` کے ساتھ `signTransaction` طریقہ استعمال کریں گے۔ +- `sendSignedTransaction`: ایک بار جب ہمارے پاس دستخط شدہ لین دین ہو جاتا ہے، تو ہم اسے `sendSignedTransaction` کا استعمال کرتے ہوئے بعد کے بلاک میں شامل کرنے کے لیے بھیج سکتے ہیں۔ + +**ڈیٹا پر ایک نوٹ** +Ethereum میں دو اہم قسم کے لین دین بھیجے جا سکتے ہیں۔ + +- بیلنس کی منتقلی: ایک ایڈریس سے دوسرے ایڈریس پر ETH بھیجیں۔ کوئی ڈیٹا فیلڈ درکار نہیں، تاہم، اگر آپ اپنے لین دین کے ساتھ اضافی معلومات بھیجنا چاہتے ہیں، تو آپ اس فیلڈ میں HEX فارمیٹ میں وہ معلومات شامل کر سکتے ہیں۔ + - مثال کے طور پر، فرض کریں کہ ہم ایک IPFS دستاویز کا ہیش Ethereum چین پر لکھنا چاہتے ہیں تاکہ اسے ایک ناقابل تغیر ٹائم اسٹیمپ دیا جا سکے۔ ہمارا ڈیٹا فیلڈ پھر اس طرح نظر آنا چاہئے: `web3.utils.toHex('IPFS ہیش')`۔ اور اب کوئی بھی چین سے استفسار کر سکتا ہے اور دیکھ سکتا ہے کہ وہ دستاویز کب شامل کی گئی تھی۔ +- اسمارٹ کنٹریکٹ لین دین: چین پر کچھ اسمارٹ کنٹریکٹ کوڈ پر عمل کریں۔ اس معاملے میں، ڈیٹا فیلڈ میں وہ اسمارٹ فنکشن ہونا چاہئے جسے آپ کسی بھی پیرامیٹرز کے ساتھ عمل کرنا چاہتے ہیں۔ + - ایک عملی مثال کے لیے، اس [ہیلو ورلڈ ٹیوٹوریل](https://docs.alchemyapi.io/alchemy/tutorials/hello-world-smart-contract#step-8-create-the-transaction) میں مرحلہ 8 دیکھیں۔ + +### 8. `node sendTx.js` کا استعمال کرتے ہوئے کوڈ چلائیں {#run-the-code-using-node-sendtx-js} + +اپنے ٹرمینل یا کمانڈ لائن پر واپس جائیں اور چلائیں: + +``` +node sendTx.js +``` + +### 9. Mempool میں اپنا لین دین دیکھیں {#see-your-transaction-in-the-mempool} + +اپنے Alchemy ڈیش بورڈ میں [Mempool صفحہ](https://dashboard.alchemyapi.io/mempool) کھولیں اور اپنا لین دین تلاش کرنے کے لیے بنائی گئی ایپ کے ذریعے فلٹر کریں۔ یہ وہ جگہ ہے جہاں ہم اپنے لین دین کی منتقلی کو زیر التواء حالت سے مائنڈ حالت (اگر کامیاب ہو) یا غیر کامیاب ہونے پر ڈراپڈ حالت میں دیکھ سکتے ہیں۔ یقینی بنائیں کہ اسے "All" پر رکھیں تاکہ آپ "mined"، "pending"، اور "dropped" لین دین کو کیپچر کر سکیں۔ آپ ایڈریس `0x31b98d14007bdee637298086988a0bbd31184523` پر بھیجے گئے لین دین کو تلاش کرکے بھی اپنا لین دین تلاش کر سکتے ہیں۔ + +ایک بار جب آپ اسے تلاش کر لیں تو اپنے لین دین کی تفصیلات دیکھنے کے لیے، tx ہیش کو منتخب کریں، جو آپ کو اس طرح کے منظر پر لے جائے گا: + +![Mempool واچر اسکرین شاٹ](./mempool.png) + +وہاں سے آپ سرخ رنگ میں دائرے والے آئیکن پر کلک کرکے Etherscan پر اپنا لین دین دیکھ سکتے ہیں! + +**یپییییی!** آپ نے ابھی Alchemy کا استعمال کرتے ہوئے اپنا پہلا Ethereum لین دین بھیجا ہے 🎉\*\* + +_اس گائیڈ کے بارے میں رائے اور تجاویز کے لیے، براہ کرم Alchemy's [Discord](https://discord.gg/A39JVCM) پر Elan کو پیغام دیں!_ + +_اصل میں [https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy](https://docs.alchemyapi.io/tutorials/sending-transactions-using-web3-and-alchemy) پر شائع ہوا_ diff --git a/public/content/translations/ur/developers/tutorials/server-components/index.md b/public/content/translations/ur/developers/tutorials/server-components/index.md new file mode 100644 index 00000000000..a96c5096cd0 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/server-components/index.md @@ -0,0 +1,295 @@ +--- +title: "web3 ایپس کے لیے سرور اجزاء اور ایجنٹس" +description: "اس ٹیوٹوریل کو پڑھنے کے بعد، آپ TypeScript سرورز لکھنے کے قابل ہو جائیں گے جو ایک بلاک چین پر ایونٹس کو سنتے ہیں اور اسی کے مطابق اپنے ٹرانزیکشنز کے ساتھ جواب دیتے ہیں۔ یہ آپ کو مرکزی ایپلی کیشنز (کیونکہ سرور ناکامی کا ایک نقطہ ہے) لکھنے کے قابل بنائے گا، لیکن آپ web3 اداروں کے ساتھ تعامل کر سکتے ہیں۔ یہی تکنیک ایک ایسا ایجنٹ لکھنے کے لیے بھی استعمال کی جا سکتی ہیں جو لوپ میں انسان کے بغیر آن چین ایونٹس کا جواب دیتا ہے۔" + +author: Ori Pomerantz +lang: ur-in +tags: [ "ایجنٹ", "سرور", "آف چین" ] +skill: beginner +published: 2024-07-15 +--- + +## تعارف {#introduction} + +زیادہ تر معاملات میں، ایک غیر مرکزی ایپ سافٹ ویئر تقسیم کرنے کے لیے ایک سرور کا استعمال کرتی ہے، لیکن تمام حقیقی تعامل کلائنٹ (عام طور پر، ویب براؤزر) اور بلاک چین کے درمیان ہوتا ہے۔ + +![ویب سرور، کلائنٹ، اور بلاک چین کے درمیان عام تعامل](./fig-1.svg) + +تاہم، کچھ ایسے معاملات ہیں جہاں ایک ایپلی کیشن کو آزادانہ طور پر چلنے والے سرور جزو سے فائدہ ہوگا۔ ایسا سرور ٹرانزیکشنز جاری کرکے ایونٹس، اور دیگر ذرائع، جیسے API سے آنے والی درخواستوں کا جواب دینے کے قابل ہوگا۔ + +![سرور کے اضافے کے ساتھ تعامل](./fig-2.svg) + +ایسے کئی ممکنہ کام ہیں جو ایسا سرور پورا کر سکتا ہے۔ + +- خفیہ اسٹیٹ کا ہولڈر۔ گیمنگ میں یہ اکثر مفید ہوتا ہے کہ گیم کو معلوم تمام معلومات کھلاڑیوں کو دستیاب نہ ہوں۔ تاہم، _بلاک چین پر کوئی راز نہیں ہیں_، بلاک چین میں موجود کوئی بھی معلومات کسی کے لیے بھی معلوم کرنا آسان ہے۔ لہذا، اگر گیم اسٹیٹ کے کچھ حصے کو خفیہ رکھنا ہے، تو اسے کہیں اور ذخیرہ کرنا ہوگا (اور ممکنہ طور پر اس اسٹیٹ کے اثرات کی تصدیق [zero-knowledge proofs](/zero-knowledge-proofs) کا استعمال کرتے ہوئے کی جائے)۔ + +- مرکزی اوریکل۔ اگر داؤ کافی کم ہے، تو ایک بیرونی سرور جو آن لائن کچھ معلومات پڑھتا ہے اور پھر اسے چین پر پوسٹ کرتا ہے، [oracle](/developers/docs/oracles/) کے طور پر استعمال کرنے کے لیے کافی اچھا ہو سکتا ہے۔ + +- ایجنٹ۔ بلاک چین پر بغیر کسی ٹرانزیکشن کے اسے فعال کرنے کے لیے کچھ نہیں ہوتا ہے۔ ایک سرور صارف کی جانب سے [arbitrage](/developers/docs/mev/#mev-examples-dex-arbitrage) جیسے اعمال انجام دینے کے لیے کام کر سکتا ہے جب موقع ملے۔ + +## نمونہ پروگرام {#sample-program} + +آپ [github](https://github.com/qbzzt/20240715-server-component) پر ایک نمونہ سرور دیکھ سکتے ہیں۔ یہ سرور [اس کنٹریکٹ](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=contract_code) سے آنے والے ایونٹس کو سنتا ہے، جو Hardhat کے Greeter کا ایک ترمیم شدہ ورژن ہے۔ جب گریٹنگ تبدیل کی جاتی ہے، تو یہ اسے واپس تبدیل کر دیتا ہے۔ + +اسے چلانے کے لئے: + +1. ریپوزٹری کو کلون کریں۔ + + ```sh copy + git clone https://github.com/qbzzt/20240715-server-component.git + cd 20240715-server-component + ``` + +2. ضروری پیکجز انسٹال کریں۔ اگر آپ کے پاس یہ پہلے سے نہیں ہے، تو [پہلے Node انسٹال کریں](https://nodejs.org/en/download/package-manager)۔ + + ```sh copy + npm install + ``` + +3. Holesky ٹیسٹ نیٹ پر ETH رکھنے والے اکاؤنٹ کی پرائیویٹ کی کی وضاحت کے لیے `.env` میں ترمیم کریں۔ اگر آپ کے پاس Holesky پر ETH نہیں ہے، تو آپ [یہ faucet استعمال کر سکتے ہیں](https://holesky-faucet.pk910.de/)۔ + + ```sh filename=".env" copy + PRIVATE_KEY=0x <پرائیویٹ کی یہاں ڈالیں> + ``` + +4. سرور شروع کریں۔ + + ```sh copy + npm start + ``` + +5. [بلاک ایکسپلورر](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=write_contract) پر جائیں، اور پرائیویٹ کی والے ایڈریس سے مختلف ایڈریس کا استعمال کرتے ہوئے گریٹنگ میں ترمیم کریں۔ دیکھیں کہ گریٹنگ خود بخود واپس تبدیل ہو جاتی ہے۔ + +### یہ کیسے کام کرتا ہے؟ {#how-it-works} + +سرور جزو لکھنے کا طریقہ سمجھنے کا سب سے آسان طریقہ یہ ہے کہ نمونے کو لائن بہ لائن پڑھا جائے۔ + +#### `src/app.ts` {#src-app-ts} + +پروگرام کا بڑا حصہ [`src/app.ts`](https://github.com/qbzzt/20240715-server-component/blob/main/src/app.ts) میں موجود ہے۔ + +##### پیشگی مطلوبہ اشیاء بنانا + +```typescript +import { + createPublicClient, + createWalletClient, + getContract, + http, + Address, +} from "viem" +``` + +یہ وہ [Viem](https://viem.sh/) ادارے ہیں جن کی ہمیں ضرورت ہے، فنکشنز اور [`Address` قسم](https://viem.sh/docs/glossary/types#address)۔ یہ سرور [TypeScript](https://www.typescriptlang.org/) میں لکھا گیا ہے، جو JavaScript کی ایک توسیع ہے جو اسے [مضبوطی سے ٹائپ شدہ](https://en.wikipedia.org/wiki/Strong_and_weak_typing) بناتی ہے۔ + +```typescript +import { privateKeyToAccount } from "viem/accounts" +``` + +[یہ فنکشن](https://viem.sh/docs/accounts/privateKey) ہمیں ایک پرائیویٹ کی کے مطابق والیٹ کی معلومات، بشمول ایڈریس، بنانے دیتا ہے۔ + +```typescript +import { holesky } from "viem/chains" +``` + +Viem میں بلاک چین استعمال کرنے کے لیے آپ کو اس کی تعریف درآمد کرنے کی ضرورت ہے۔ اس معاملے میں، ہم [Holesky](https://github.com/eth-clients/holesky) ٹیسٹ بلاک چین سے جڑنا چاہتے ہیں۔ + +```typescript +// یہ ہے کہ ہم .env میں موجود تعریفوں کو process.env میں کیسے شامل کرتے ہیں۔ +import * as dotenv from "dotenv" +dotenv.config() +``` + +یہ ہے کہ ہم `.env` کو ماحول میں کیسے پڑھتے ہیں۔ ہمیں پرائیویٹ کی کے لیے اس کی ضرورت ہے (بعد میں دیکھیں)۔ + +```typescript +const greeterAddress : Address = "0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6" +const greeterABI = [ + { + "inputs": [ + { + "internalType": "string", + "name": "_greeting", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + . + . + . + { + "inputs": [ + { + "internalType": "string", + "name": "_greeting", + "type": "string" + } + ], + "name": "setGreeting", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] as const +``` + +کنٹریکٹ استعمال کرنے کے لیے ہمیں اس کے ایڈریس اور اس کے لیے [ABI](/glossary/#abi) کی ضرورت ہے۔ ہم یہاں دونوں فراہم کرتے ہیں۔ + +JavaScript (اور اس لیے TypeScript) میں آپ کسی مستقل کو نئی قدر تفویض نہیں کر سکتے، لیکن آپ اس میں ذخیرہ شدہ آبجیکٹ میں ترمیم _کر سکتے_ ہیں۔ `as const` لاحقہ کا استعمال کرکے ہم TypeScript کو بتا رہے ہیں کہ فہرست خود مستقل ہے اور اسے تبدیل نہیں کیا جا سکتا۔ + +```typescript +const publicClient = createPublicClient({ + chain: holesky, + transport: http(), +}) +``` + +ایک Viem [پبلک کلائنٹ](https://viem.sh/docs/clients/public.html) بنائیں۔ پبلک کلائنٹس کے پاس منسلک پرائیویٹ کی نہیں ہوتی، اور اس لیے وہ ٹرانزیکشنز نہیں بھیج سکتے۔ وہ [`view` فنکشنز](https://www.tutorialspoint.com/solidity/solidity_view_functions.htm) کو کال کر سکتے ہیں، اکاؤنٹ بیلنس پڑھ سکتے ہیں، وغیرہ۔ + +```typescript +const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`) +``` + +ماحولیاتی متغیرات [`process.env`](https://www.totaltypescript.com/how-to-strongly-type-process-env) میں دستیاب ہیں۔ تاہم، TypeScript مضبوطی سے ٹائپ شدہ ہے۔ ایک ماحولیاتی متغیر کوئی بھی سٹرنگ، یا خالی ہو سکتا ہے، لہذا ایک ماحولیاتی متغیر کی قسم `string | undefined` ہے۔ تاہم، Viem میں ایک کی کو `0x${string}` (`0x` کے بعد ایک سٹرنگ) کے طور پر بیان کیا گیا ہے۔ یہاں ہم TypeScript کو بتاتے ہیں کہ `PRIVATE_KEY` ماحولیاتی متغیر اس قسم کا ہوگا۔ اگر ایسا نہیں ہے، تو ہمیں ایک رن ٹائم ایرر ملے گا۔ + +[`privateKeyToAccount`](https://viem.sh/docs/accounts/privateKey) فنکشن پھر اس پرائیویٹ کی کا استعمال کرکے ایک مکمل اکاؤنٹ آبجیکٹ بناتا ہے۔ + +```typescript +const walletClient = createWalletClient({ + account, + chain: holesky, + transport: http(), +}) +``` + +اگلا، ہم اکاؤنٹ آبجیکٹ کا استعمال کرکے ایک [والیٹ کلائنٹ](https://viem.sh/docs/clients/wallet) بناتے ہیں۔ اس کلائنٹ کے پاس ایک پرائیویٹ کی اور ایک ایڈریس ہے، لہذا اسے ٹرانزیکشنز بھیجنے کے لیے استعمال کیا جا سکتا ہے۔ + +```typescript +const greeter = getContract({ + address: greeterAddress, + abi: greeterABI, + client: { public: publicClient, wallet: walletClient }, +}) +``` + +اب جب کہ ہمارے پاس تمام پیشگی شرائط ہیں، ہم آخر کار ایک [کنٹریکٹ انسٹنس](https://viem.sh/docs/contract/getContract) بنا سکتے ہیں۔ ہم اس کنٹریکٹ انسٹنس کا استعمال آن چین کنٹریکٹ کے ساتھ بات چیت کرنے کے لیے کریں گے۔ + +##### بلاک چین سے پڑھنا + +```typescript +console.log(`Current greeting:`, await greeter.read.greet()) +``` + +کنٹریکٹ کے فنکشنز جو صرف پڑھنے کے لیے ہیں ([`view`](https://www.tutorialspoint.com/solidity/solidity_view_functions.htm) اور [`pure`](https://www.tutorialspoint.com/solidity/solidity_pure_functions.htm)) `read` کے تحت دستیاب ہیں۔ اس معاملے میں، ہم اسے [`greet`](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=read_contract#cfae3217) فنکشن تک رسائی حاصل کرنے کے لیے استعمال کرتے ہیں، جو گریٹنگ واپس کرتا ہے۔ + +JavaScript سنگل تھریڈڈ ہے، لہذا جب ہم ایک طویل چلنے والے عمل کو شروع کرتے ہیں تو ہمیں [یہ بتانا ہوگا کہ ہم اسے غیر مطابقت پذیر طریقے سے کرتے ہیں](https://eloquentjavascript.net/11_async.html#h-XvLsfAhtsE)۔ بلاک چین کو کال کرنا، یہاں تک کہ صرف پڑھنے کے آپریشن کے لیے، کمپیوٹر اور بلاک چین نوڈ کے درمیان راؤنڈ ٹرپ کی ضرورت ہوتی ہے۔ یہی وجہ ہے کہ ہم یہاں بتاتے ہیں کہ کوڈ کو نتیجے کے لیے `await` کرنے کی ضرورت ہے۔ + +اگر آپ اس میں دلچسپی رکھتے ہیں کہ یہ کیسے کام کرتا ہے تو آپ [یہاں اس کے بارے میں پڑھ سکتے ہیں](https://www.w3schools.com/js/js_promise.asp)، لیکن عملی طور پر آپ کو صرف یہ جاننے کی ضرورت ہے کہ اگر آپ کوئی ایسا آپریشن شروع کرتے ہیں جس میں زیادہ وقت لگتا ہے تو آپ نتائج کا `await` کریں، اور یہ کہ کوئی بھی فنکشن جو ایسا کرتا ہے اسے `async` کے طور پر اعلان کرنا ہوگا۔ + +##### ٹرانزیکشنز جاری کرنا + +```typescript +const setGreeting = async (greeting: string): Promise => { +``` + +یہ وہ فنکشن ہے جسے آپ گریٹنگ کو تبدیل کرنے والے ٹرانزیکشن کو جاری کرنے کے لیے کال کرتے ہیں۔ چونکہ یہ ایک طویل آپریشن ہے، اس لیے فنکشن کو `async` کے طور پر اعلان کیا گیا ہے۔ اندرونی نفاذ کی وجہ سے، کسی بھی `async` فنکشن کو `Promise` آبجیکٹ واپس کرنے کی ضرورت ہے۔ اس معاملے میں، `Promise` کا مطلب ہے کہ ہم یہ نہیں بتاتے کہ `Promise` میں بالکل کیا واپس کیا جائے گا۔ + +```typescript +const txHash = await greeter.write.setGreeting([greeting]) +``` + +کنٹریکٹ انسٹنس کے `write` فیلڈ میں وہ تمام فنکشنز ہیں جو بلاک چین اسٹیٹ پر لکھتے ہیں (وہ جن کے لیے ٹرانزیکشن بھیجنے کی ضرورت ہوتی ہے)، جیسے کہ [`setGreeting`](https://eth-holesky.blockscout.com/address/0xB8f6460Dc30c44401Be26B0d6eD250873d8a50A6?tab=write_contract#a4136862)۔ پیرامیٹرز، اگر کوئی ہیں، تو ایک فہرست کے طور پر فراہم کیے جاتے ہیں، اور فنکشن ٹرانزیکشن کا ہیش واپس کرتا ہے۔ + +```typescript + console.log(`Working on a fix, see https://eth-holesky.blockscout.com/tx/${txHash}`) + + return txHash +} +``` + +ٹرانزیکشن کے ہیش کی اطلاع دیں (اسے دیکھنے کے لیے بلاک ایکسپلورر کے یو آر ایل کے حصے کے طور پر) اور اسے واپس کریں۔ + +##### ایونٹس کا جواب دینا + +```typescript +greeter.watchEvent.SetGreeting({ +``` + +[`watchEvent` فنکشن](https://viem.sh/docs/actions/public/watchEvent) آپ کو یہ بتانے دیتا ہے کہ جب کوئی ایونٹ خارج ہوتا ہے تو ایک فنکشن چلنا ہے۔ اگر آپ صرف ایک قسم کے ایونٹ کا خیال رکھتے ہیں (اس معاملے میں، `SetGreeting`)، تو آپ اپنے آپ کو اس ایونٹ کی قسم تک محدود رکھنے کے لیے اس نحو کا استعمال کر سکتے ہیں۔ + +```typescript + onLogs: logs => { +``` + +`onLogs` فنکشن کو اس وقت کال کیا جاتا ہے جب لاگ اندراجات ہوں۔ Ethereum میں "لاگ" اور "ایونٹ" عام طور پر قابل تبادلہ ہیں۔ + +```typescript +console.log( + `Address ${logs[0].args.sender} changed the greeting to ${logs[0].args.greeting}` +) +``` + +متعدد ایونٹس ہو سکتے ہیں، لیکن سادگی کے لیے ہم صرف پہلے والے کا خیال رکھتے ہیں۔ `logs[0].args` ایونٹ کے دلائل ہیں، اس معاملے میں `sender` اور `greeting`۔ + +```typescript + if (logs[0].args.sender != account.address) + setGreeting(`${account.address} insists on it being Hello!`) + } +}) +``` + +اگر بھیجنے والا یہ سرور _نہیں_ ہے، تو گریٹنگ کو تبدیل کرنے کے لیے `setGreeting` کا استعمال کریں۔ + +#### `package.json` {#package-json} + +[یہ فائل](https://github.com/qbzzt/20240715-server-component/blob/main/package.json) [Node.js](https://nodejs.org/en) کنفیگریشن کو کنٹرول کرتی ہے۔ یہ مضمون صرف اہم تعریفوں کی وضاحت کرتا ہے۔ + +```json +{ + "main": "dist/index.js", +``` + +یہ تعریف بتاتی ہے کہ کون سی JavaScript فائل چلانی ہے۔ + +```json + "scripts": { + "start": "tsc && node dist/app.js", + }, +``` + +اسکرپٹس مختلف ایپلی کیشن ایکشنز ہیں۔ اس معاملے میں، ہمارے پاس صرف `start` ہے، جو سرور کو کمپائل کرتا ہے اور پھر چلاتا ہے۔ `tsc` کمانڈ `typescript` پیکیج کا حصہ ہے اور TypeScript کو JavaScript میں کمپائل کرتا ہے۔ اگر آپ اسے دستی طور پر چلانا چاہتے ہیں، تو یہ `node_modules/.bin` میں واقع ہے۔ دوسرا کمانڈ سرور کو چلاتا ہے۔ + +```json + "type": "module", +``` + +JavaScript نوڈ ایپلی کیشنز کی متعدد اقسام ہیں۔ `module` قسم ہمیں ٹاپ لیول کوڈ میں `await` رکھنے دیتی ہے، جو اس وقت اہم ہے جب آپ سست (اور وہاں غیر مطابقت پذیر) آپریشن کرتے ہیں۔ + +```json + "devDependencies": { + "@types/node": "^20.14.2", + "typescript": "^5.4.5" + }, +``` + +یہ وہ پیکیجز ہیں جن کی صرف ڈیولپمنٹ کے لیے ضرورت ہے۔ یہاں ہمیں `typescript` کی ضرورت ہے اور چونکہ ہم اسے Node.js کے ساتھ استعمال کر رہے ہیں، اس لیے ہم نوڈ متغیرات اور آبجیکٹس، جیسے `process` کے لیے بھی اقسام حاصل کر رہے ہیں۔ [`^` نوٹیشن](https://github.com/npm/node-semver?tab=readme-ov-file#caret-ranges-123-025-004) کا مطلب ہے کہ ورژن یا ایک اعلیٰ ورژن جس میں بریکنگ تبدیلیاں نہ ہوں۔ ورژن نمبروں کے معنی کے بارے میں مزید معلومات کے لیے [یہاں](https://semver.org) دیکھیں۔ + +```json + "dependencies": { + "dotenv": "^16.4.5", + "viem": "2.14.1" + } +} +``` + +یہ وہ پیکیجز ہیں جن کی رن ٹائم پر ضرورت ہوتی ہے، جب `dist/app.js` چل رہا ہو۔ + +## نتیجہ {#conclusion} + +مرکزی سرور جو ہم نے یہاں بنایا ہے وہ اپنا کام کرتا ہے، جو ایک صارف کے لیے ایک ایجنٹ کے طور پر کام کرنا ہے۔ کوئی بھی دوسرا شخص جو چاہتا ہے کہ ڈیپ کام کرتا رہے اور گیس خرچ کرنے کو تیار ہے، وہ اپنے ایڈریس کے ساتھ سرور کا ایک نیا انسٹنس چلا سکتا ہے۔ + +تاہم، یہ صرف اس وقت کام کرتا ہے جب مرکزی سرور کے اعمال کی آسانی سے تصدیق کی جا سکے۔ اگر مرکزی سرور کے پاس کوئی خفیہ اسٹیٹ کی معلومات ہے، یا مشکل حسابات چلاتا ہے، تو یہ ایک مرکزی ادارہ ہے جس پر آپ کو ایپلی کیشن استعمال کرنے کے لیے بھروسہ کرنے کی ضرورت ہے، جو بالکل وہی ہے جس سے بلاک چینز بچنے کی کوشش کرتے ہیں۔ مستقبل کے ایک مضمون میں میں یہ دکھانے کا ارادہ رکھتا ہوں کہ اس مسئلے سے نمٹنے کے لیے [zero-knowledge proofs](/zero-knowledge-proofs) کا استعمال کیسے کیا جائے۔ + +[میرے مزید کام کے لیے یہاں دیکھیں](https://cryptodocguy.pro/)۔ diff --git a/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md b/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md new file mode 100644 index 00000000000..55ee0d2e638 --- /dev/null +++ b/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md @@ -0,0 +1,92 @@ +--- +title: "JavaScript میں Ethereum بلاک چین استعمال کرنے کے لئے web3.js سیٹ اپ کریں" +description: "سیکھیں کہ JavaScript ایپلیکیشنز سے Ethereum بلاک چین کے ساتھ تعامل کرنے کے لئے web3.js لائبریری کو کیسے سیٹ اپ اور کنفیگر کیا جائے۔" +author: "jdourlens" +tags: [ "web3.js", "javascript" ] +skill: beginner +lang: ur-in +published: 2020-04-11 +source: EthereumDev +sourceUrl: https://ethereumdev.io/setup-web3js-to-use-the-ethereum-blockchain-in-javascript/ +address: "0x19dE91Af973F404EDF5B4c093983a7c6E3EC8ccE" +--- + +اس ٹیوٹوریل میں، ہم دیکھیں گے کہ Ethereum بلاک چین کے ساتھ تعامل کرنے کے لئے [web3.js](https://web3js.readthedocs.io/) کے ساتھ کیسے شروعات کی جائے۔ Web3.js کو فرنٹ اینڈز اور بیک اینڈز دونوں میں بلاک چین سے ڈیٹا پڑھنے، ٹرانزیکشنز کرنے اور یہاں تک کہ سمارٹ کنٹریکٹس ڈیپلائے کرنے کے لیے استعمال کیا جا سکتا ہے۔ + +پہلا قدم اپنے پروجیکٹ میں web3.js کو شامل کرنا ہے۔ اسے ویب پیج میں استعمال کرنے کے لیے، آپ JSDeliver جیسے CDN کا استعمال کرتے ہوئے لائبریری کو براہ راست امپورٹ کر سکتے ہیں۔ + +```html + +``` + +اگر آپ لائبریری کو اپنے بیک اینڈ یا فرنٹ اینڈ پروجیکٹ میں استعمال کرنے کے لیے انسٹال کرنا چاہتے ہیں جو بلڈ کا استعمال کرتا ہے تو آپ اسے npm کا استعمال کرتے ہوئے انسٹال کر سکتے ہیں: + +```bash +npm install web3 --save +``` + +پھر Web3.js کو Node.js اسکرپٹ یا Browserify فرنٹ اینڈ پروجیکٹ میں امپورٹ کرنے کے لیے، آپ JavaScript کی مندرجہ ذیل لائن استعمال کر سکتے ہیں: + +```js +const Web3 = require("web3") +``` + +اب جب کہ ہم نے پروجیکٹ میں لائبریری کو شامل کر لیا ہے، ہمیں اسے انیشلائز کرنے کی ضرورت ہے۔ آپ کے پروجیکٹ کو بلاک چین کے ساتھ کمیونیکیٹ کرنے کے قابل ہونا چاہیے۔ زیادہ تر Ethereum لائبریریاں RPC کالز کے ذریعے ایک [نوڈ](/developers/docs/nodes-and-clients/) کے ساتھ کمیونیکیٹ کرتی ہیں۔ اپنے Web3 پرووائیڈر کو شروع کرنے کے لیے، ہم پرووائیڈر کے URL کو کنسٹرکٹر کے طور پر پاس کرتے ہوئے ایک Web3 انسٹینس بنائیں گے۔ اگر آپ کے کمپیوٹر پر کوئی نوڈ یا [ganache انسٹینس چل رہا ہے](https://ethereumdev.io/testing-your-smart-contract-with-existing-protocols-ganache-fork/) تو یہ اس طرح نظر آئے گا: + +```js +const web3 = new Web3("http://localhost:8545") +``` + +اگر آپ براہ راست کسی ہوسٹڈ نوڈ تک رسائی حاصل کرنا چاہتے ہیں تو آپ [نوڈز ایز اے سروس](/developers/docs/nodes-and-clients/nodes-as-a-service) پر آپشنز تلاش کر سکتے ہیں۔ + +```js +const web3 = new Web3("https://cloudflare-eth.com") +``` + +یہ جانچنے کے لیے کہ ہم نے اپنے Web3 انسٹینس کو صحیح طریقے سے کنفیگر کیا ہے، ہم `getBlockNumber` فنکشن کا استعمال کرتے ہوئے تازہ ترین بلاک نمبر حاصل کرنے کی کوشش کریں گے۔ یہ فنکشن ایک پیرامیٹر کے طور پر کال بیک کو قبول کرتا ہے اور بلاک نمبر کو ایک انٹیجر کے طور پر واپس کرتا ہے۔ + +```js +var Web3 = require("web3") +const web3 = new Web3("https://cloudflare-eth.com") + +web3.eth.getBlockNumber(function (error, result) { + console.log(result) +}) +``` + +اگر آپ اس پروگرام کو چلاتے ہیں، تو یہ صرف تازہ ترین بلاک نمبر پرنٹ کرے گا: یعنی بلاک چین کا سب سے اوپر والا حصہ۔ آپ اپنے کوڈ میں نیسٹنگ کال بیکس سے بچنے کے لیے `await/async` فنکشن کالز کا بھی استعمال کر سکتے ہیں: + +```js +async function getBlockNumber() { + const latestBlockNumber = await web3.eth.getBlockNumber() + console.log(latestBlockNumber) + return latestBlockNumber +} + +getBlockNumber() +``` + +آپ Web3 انسٹینس پر دستیاب تمام فنکشنز کو [web3.js کی آفیشل ڈاکومنٹیشن](https://docs.web3js.org/) میں دیکھ سکتے ہیں۔ + +زیادہ تر Web3 لائبریریاں ایسنکرونس ہوتی ہیں کیونکہ بیک گراؤنڈ میں لائبریری نوڈ کو JSON-RPC کالز کرتی ہے جو نتیجہ واپس بھیجتا ہے۔ + + + +اگر آپ براؤزر میں کام کر رہے ہیں، تو کچھ والیٹس براہ راست ایک Web3 انسٹینس انجیکٹ کرتے ہیں اور آپ کو جب بھی ممکن ہو اسے استعمال کرنے کی کوشش کرنی چاہیے، خاص طور پر اگر آپ ٹرانزیکشنز کرنے کے لیے صارف کے Ethereum ایڈریس کے ساتھ تعامل کرنے کا ارادہ رکھتے ہیں۔ + +یہاں یہ پتہ لگانے کے لیے سنیپٹ ہے کہ آیا MetaMask والیٹ دستیاب ہے اور اگر ہے تو اسے فعال کرنے کی کوشش کریں۔ یہ بعد میں آپ کو صارف کا بیلنس پڑھنے اور انہیں ان ٹرانزیکشنز کی توثیق کرنے کے قابل بنائے گا جو آپ ان سے Ethereum بلاک چین پر کروانا چاہتے ہیں: + +```js +if (window.ethereum != null) { + state.web3 = new Web3(window.ethereum) + try { + // اگر ضرورت ہو تو اکاؤنٹ تک رسائی کی درخواست کریں + await window.ethereum.enable() + // اکاؤنٹس اب ظاہر ہو گئے ہیں + } catch (error) { + // صارف نے اکاؤنٹ تک رسائی سے انکار کر دیا... + } +} +``` + +web3.js کے متبادل جیسے [Ethers.js](https://docs.ethers.io/) موجود ہیں اور عام طور پر استعمال بھی ہوتے ہیں۔ اگلے ٹیوٹوریل میں ہم دیکھیں گے کہ [بلاک چین پر نئے آنے والے بلاکس کو آسانی سے کیسے سنا جائے اور دیکھیں کہ ان میں کیا ہے](https://ethereumdev.io/listening-to-new-transactions-happening-on-the-blockchain/)۔ From fa5a9f97c6a6a74a489049e7e660273f7130e7f4 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Sun, 15 Feb 2026 17:51:04 +0000 Subject: [PATCH 2/2] fix(i18n): restore English code blocks in Urdu developer tutorials Crowdin translated text inside code fences (comments, string literals, CLI output) across 17 tutorial files, which would break copy-paste code examples. Restored all affected code blocks from the English source. --- .../index.md | 30 +- .../index.md | 2 +- .../how-to-use-tellor-as-your-oracle/index.md | 2 +- .../how-to-write-and-deploy-an-nft/index.md | 22 +- .../index.md | 8 +- .../index.md | 4 +- .../logging-events-smart-contracts/index.md | 6 +- .../index.md | 52 +-- .../developers/tutorials/nft-minter/index.md | 108 +++--- .../index.md | 333 +++++++++--------- .../tutorials/run-node-raspberry-pi/index.md | 18 +- .../tutorials/scam-token-tricks/index.md | 36 +- .../tutorials/secret-state/index.md | 14 +- .../tutorials/send-token-ethersjs/index.md | 20 +- .../index.md | 12 +- .../tutorials/server-components/index.md | 4 +- .../index.md | 6 +- 17 files changed, 340 insertions(+), 337 deletions(-) diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md index 47c472e1fa1..cbe44364908 100644 --- a/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/ur/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/index.md @@ -74,7 +74,7 @@ DSE کیسے کام کرتا ہے اس کی بصیرت حاصل کرنے کے ل function f(uint a){ if (a == 65) { - // ایک بگ موجود ہے + // A bug is present } } @@ -95,7 +95,7 @@ Manticore ہر پاتھ کے تمام ایگزیکیوشن پر مکمل کنٹ ```solidity function unsafe_add(uint a, uint b) returns(uint c){ - c = a + b; // کوئی اوور فلو تحفظ نہیں + c = a + b; // no overflow protection return c; } ``` @@ -228,7 +228,7 @@ contract Simple { } } ''' -# کنٹریکٹ شروع کریں +# Initiate the contract contract_account = m.solidity_create_contract(source_code, owner=user_account) ``` @@ -295,7 +295,7 @@ contract_account.f(symbolic_var, caller=user_account, value=0) `m.workspace` وہ ڈائریکٹری ہے جو تمام تیار کردہ فائلوں کے لیے آؤٹ پٹ ڈائریکٹری کے طور پر استعمال ہوتی ہے: ```python -print("نتائج {} میں ہیں".format(m.workspace)) +print("Results are in {}".format(m.workspace)) ``` ### ایکسپلوریشن کو ختم کریں {#terminate-the-exploration} @@ -320,8 +320,8 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) -print("نتائج {} میں ہیں".format(m.workspace)) -m.finalize() # ایکسپلوریشن کو روکیں +print("Results are in {}".format(m.workspace)) +m.finalize() # stop the exploration ``` اوپر دیا گیا تمام کوڈ آپ [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) میں تلاش کر سکتے ہیں @@ -351,7 +351,7 @@ contract Simple { ```python for state in m.all_states: - # اسٹیٹ کے ساتھ کچھ کریں + # do something with state ``` آپ اسٹیٹ کی معلومات تک رسائی حاصل کر سکتے ہیں۔ مثال کے طور پر: @@ -399,12 +399,11 @@ contract_account = m.solidity_create_contract(source_code, owner=user_account) symbolic_var = m.make_symbolic_value() contract_account.f(symbolic_var) -## چیک کریں کہ کیا کوئی ایگزیکیوشن REVERT یا INVALID کے ساتھ ختم ہوتا ہے - +## Check if an execution ends with a REVERT or INVALID for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: - print('تھرو ملا {}'.format(m.workspace)) + print('Throw found {}'.format(m.workspace)) m.generate_testcase(state, 'ThrowFound') ``` @@ -482,7 +481,7 @@ m.transaction(caller=user_account, ```python state.constrain(symbolic_var != 65) if solver.check(state.constraints): - # اسٹیٹ قابل عمل ہے + # state is feasible ``` ### خلاصہ: پابندیاں شامل کرنا {#summary-adding-constraints} @@ -508,19 +507,18 @@ contract_account.f(symbolic_var) no_bug_found = True -## چیک کریں کہ کیا کوئی ایگزیکیوشن REVERT یا INVALID کے ساتھ ختم ہوتا ہے - +## Check if an execution ends with a REVERT or INVALID for state in m.terminated_states: last_tx = state.platform.transactions[-1] if last_tx.result in ['REVERT', 'INVALID']: - # ہم اس پاتھ پر غور نہیں کرتے جہاں a == 65 ہے + # we do not consider the path were a == 65 condition = symbolic_var != 65 if m.generate_testcase(state, name="BugFound", only_if=condition): - print(f'بگ ملا، نتائج {m.workspace} میں ہیں') + print(f'Bug found, results are in {m.workspace}') no_bug_found = False if no_bug_found: - print(f'کوئی بگ نہیں ملا') + print(f'No bug found') ``` اوپر دیا گیا تمام کوڈ آپ [`example_run.py`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/manticore/examples/example_run.py) میں تلاش کر سکتے ہیں diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md index f898caf8f19..018b7d2489e 100644 --- a/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md +++ b/public/content/translations/ur/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/index.md @@ -119,7 +119,7 @@ class HasAddition(ExpressionVisitor): if expression.type == BinaryOperationType.ADDITION: self._result = True -visitor = HasAddition(expression) # ایکسپریشن وہ ایکسپریشن ہے جس کی جانچ کی جانی ہے +visitor = HasAddition(expression) # expression is the expression to be tested print(f'The expression {expression} has a addition: {visitor.result()}') ``` diff --git a/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md b/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md index b74d5fc2bbe..cb73723653d 100644 --- a/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md +++ b/public/content/translations/ur/developers/tutorials/how-to-use-tellor-as-your-oracle/index.md @@ -56,7 +56,7 @@ import "usingtellor/contracts/UsingTellor.sol"; contract PriceContract is UsingTellor { uint256 public btcPrice; - //اس کنٹریکٹ کو اب UsingTellor کے تمام فنکشنز تک رسائی حاصل ہے + //This Contract now has access to all functions in UsingTellor constructor(address payable _tellorAddress) UsingTellor(_tellorAddress) public {} diff --git a/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md b/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md index cf2a844b3ce..7090038759f 100644 --- a/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md +++ b/public/content/translations/ur/developers/tutorials/how-to-write-and-deploy-an-nft/index.md @@ -82,7 +82,7 @@ Ethereum بلاک چین سے درخواستیں کرنے کے بہت سے طر ```json package name: (my-nft) version: (1.0.0) - description: میرا پہلا NFT! + description: My first NFT! entry point: (index.js) test command: git repository: @@ -94,7 +94,7 @@ Ethereum بلاک چین سے درخواستیں کرنے کے بہت سے طر { "name": "my-nft", "version": "1.0.0", - "description": "میرا پہلا NFT!", + "description": "My first NFT!", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -137,11 +137,11 @@ Hardhat آپ کے Ethereum سافٹ ویئر کو کمپائل، ڈیپلوئے 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 بنائیں - چھوڑ دیں + 👷 Welcome to Hardhat v2.0.11 👷‍ + ? What do you want to do? … + Create a sample project + ❯ Create an empty hardhat.config.js + Quit ``` یہ ہمارے لیے ایک hardhat.config.js فائل تیار کرے گا جہاں ہم اپنے پروجیکٹ کے لیے تمام سیٹ اپ کی وضاحت کریں گے (مرحلہ 13 پر)۔ @@ -170,7 +170,7 @@ Hardhat آپ کے Ethereum سافٹ ویئر کو کمپائل، ڈیپلوئے 2. ذیل میں ہمارا NFT اسمارٹ کنٹریکٹ کوڈ ہے، جسے ہم نے [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc721) لائبریری کے ERC-721 نفاذ پر مبنی کیا ہے۔ نیچے دیئے گئے مواد کو اپنی MyNFT.sol فائل میں کاپی اور پیسٹ کریں۔ ```solidity - //کنٹریکٹ [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) پر مبنی ہے + //Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721) // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -319,10 +319,10 @@ Hardhat اضافی ٹولنگ اور توسیع شدہ فعالیت کے لیے async function main() { const MyNFT = await ethers.getContractFactory("MyNFT") - // ڈیپلوئمنٹ شروع کریں، ایک وعدہ واپس کریں جو ایک کنٹریکٹ آبجیکٹ میں حل ہو + // Start deployment, returning a promise that resolves to a contract object const myNFT = await MyNFT.deploy() await myNFT.deployed() - console.log("کنٹریکٹ اس ایڈریس پر ڈیپلوئے کیا گیا:", myNFT.address) + console.log("Contract deployed to address:", myNFT.address) } main() @@ -358,7 +358,7 @@ ContractFactory پر deploy() کو کال کرنے سے ڈیپلوئمنٹ شر پھر آپ کو کچھ اس طرح نظر آنا چاہیے: ``` - کنٹریکٹ اس ایڈریس پر ڈیپلوئے کیا گیا: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 + Contract deployed to address: 0x4C5266cCc4b3F426965d2f51b6D910325a0E7650 ``` اگر ہم [Sepolia etherscan](https://sepolia.etherscan.io/) پر جائیں اور اپنے کنٹریکٹ ایڈریس کو تلاش کریں تو ہمیں یہ دیکھنے کے قابل ہونا چاہئے کہ یہ کامیابی سے ڈیپلوئے ہو گیا ہے۔ اگر آپ اسے فوراً نہیں دیکھ سکتے ہیں، تو براہ کرم تھوڑی دیر انتظار کریں کیونکہ اس میں کچھ وقت لگ سکتا ہے۔ ٹرانزیکشن کچھ اس طرح نظر آئے گی: diff --git a/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md b/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md index 434ff69e3d0..b2f206c1775 100644 --- a/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md +++ b/public/content/translations/ur/developers/tutorials/interact-with-other-contracts-from-solidity/index.md @@ -33,12 +33,12 @@ contract Counter { modifier onlyOwner(address caller) { - require(caller == _owner, "آپ معاہدے کے مالک نہیں ہیں"); + require(caller == _owner, "You're not the owner of the contract"); _; } modifier onlyFactory() { - require(msg.sender == _factory, "آپ کو فیکٹری استعمال کرنے کی ضرورت ہے"); + require(msg.sender == _factory, "You need to use the factory"); _; } @@ -122,12 +122,12 @@ contract Counter { modifier onlyOwner(address caller) { - require(caller == _owner, "آپ معاہدے کے مالک نہیں ہیں"); + require(caller == _owner, "You're not the owner of the contract"); _; } modifier onlyFactory() { - require(msg.sender == _factory, "آپ کو فیکٹری استعمال کرنے کی ضرورت ہے"); + require(msg.sender == _factory, "You need to use the factory"); _; } diff --git a/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md b/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md index 81ee317b711..c20a9ef67ff 100644 --- a/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md +++ b/public/content/translations/ur/developers/tutorials/learn-foundational-ethereum-topics-with-sql/index.md @@ -182,7 +182,7 @@ FROM temp_table کوئریز یہ ہیں: ```sql -# 2016 سے روزانہ تیار ہونے والے بلاکس کی تعداد کا تصور کرنے کے لیے کوئری +# query to visualize number of blocks produced daily since 2016 SELECT DATE_TRUNC('day', time) AS dt, @@ -191,7 +191,7 @@ FROM ethereum."blocks" GROUP BY dt OFFSET 1 -# روزانہ تیار ہونے والے بلاکس کی اوسط تعداد +# average number of blocks produced per day WITH temp_table AS ( SELECT diff --git a/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md b/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md index 48b65b59bfc..6285adab694 100644 --- a/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md +++ b/public/content/translations/ur/developers/tutorials/logging-events-smart-contracts/index.md @@ -32,16 +32,16 @@ contract Counter { event ValueChanged(uint oldValue, uint256 newValue); - // گنتی کی تعداد رکھنے کے لیے غیر دستخط شدہ int قسم کا نجی متغیر + // Private variable of type unsigned int to keep the number of counts uint256 private count = 0; - // فنکشن جو ہمارے کاؤنٹر کو بڑھاتا ہے + // Function that increments our counter function increment() public { count += 1; emit ValueChanged(count - 1, count); } - // گنتی کی قدر حاصل کرنے کے لیے گیٹر + // Getter to get the count value function getCount() public view returns (uint256) { return count; } diff --git a/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md b/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md index eafa36df48b..061a0332e29 100644 --- a/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md +++ b/public/content/translations/ur/developers/tutorials/merkle-proofs-for-offline-data-integrity/index.md @@ -48,9 +48,9 @@ const ethers = require("ethers") [ہم ethers پیکیج سے ہیش فنکشن کا استعمال کرتے ہیں](https://docs.ethers.io/v5/api/utils/hashing/#utils-keccak256)۔ ```javascript -// وہ خام ڈیٹا جس کی سالمیت کی ہمیں تصدیق کرنی ہے۔ پہلے دو بائٹس -// ایک صارف کی شناخت ہیں، اور آخری دو بائٹس اس صارف کے پاس موجود ٹوکنز کی -// مقدار ہیں۔ +// The raw data whose integrity we have to verify. The first two bytes a +// are a user identifier, and the last two bytes the amount of tokens the +// user owns at present. const dataArray = [ 0x0bad0010, 0x60a70020, 0xbeef0030, 0xdead0040, 0xca110050, 0x0e660060, 0xface0070, 0xbad00080, 0x060d0091, @@ -60,15 +60,15 @@ const dataArray = [ ہر اندراج کو ایک 256-بٹ انٹیجر میں انکوڈ کرنے سے، مثال کے طور پر JSON استعمال کرنے کے مقابلے میں، کم پڑھنے کے قابل کوڈ بنتا ہے۔ تاہم، اس کا مطلب ہے کہ کنٹریکٹ میں ڈیٹا کو بازیافت کرنے کے لیے کافی کم پروسیسنگ کی ضرورت ہوتی ہے، اس لیے گیس کی لاگت بہت کم ہوتی ہے۔ [آپ آن چین پر JSON پڑھ سکتے ہیں](https://github.com/chrisdotn/jsmnSol)، لیکن اگر اس سے بچا جا سکے تو یہ ایک برا خیال ہے۔ ```javascript -// ہیش ویلیوز کا ایرے، بطور BigInts +// The array of hash values, as BigInts const hashArray = dataArray ``` اس معاملے میں ہمارا ڈیٹا شروع میں 256-بٹ ویلیوز ہے، اس لیے کسی پروسیسنگ کی ضرورت نہیں ہے۔ اگر ہم زیادہ پیچیدہ ڈیٹا اسٹرکچر، جیسے کہ اسٹرنگز، استعمال کرتے ہیں، تو ہمیں یہ یقینی بنانا ہوگا کہ ہم ہیشز کا ایک ایرے حاصل کرنے کے لیے پہلے ڈیٹا کو ہیش کریں۔ نوٹ کریں کہ یہ اس لیے بھی ہے کہ ہمیں اس بات کی پرواہ نہیں ہے کہ آیا صارفین دوسرے صارفین کی معلومات جانتے ہیں۔ بصورت دیگر ہمیں ہیش کرنا پڑتا تاکہ صارف 1 کو صارف 0 کی قدر معلوم نہ ہو، صارف 2 کو صارف 3 کی قدر معلوم نہ ہو، وغیرہ۔ ```javascript -// ہیش فنکشن جس اسٹرنگ کی توقع کرتا ہے اور جو BigInt -// ہم ہر جگہ استعمال کرتے ہیں، ان کے درمیان تبدیل کریں۔ +// Convert between the string the hash function expects and the +// BigInt we use everywhere else. const hash = (x) => BigInt(ethers.utils.keccak256("0x" + x.toString(16).padStart(64, 0))) ``` @@ -76,7 +76,7 @@ const hash = (x) => ethers ہیش فنکشن ایک ہیکساڈیسیمل نمبر کے ساتھ ایک JavaScript اسٹرنگ حاصل کرنے کی توقع رکھتا ہے، جیسے `0x60A7`، اور اسی ساخت کے ساتھ ایک اور اسٹرنگ کے ساتھ جواب دیتا ہے۔ تاہم، باقی کوڈ کے لیے `BigInt` کا استعمال کرنا آسان ہے، اس لیے ہم ایک ہیکساڈیسیمل اسٹرنگ میں تبدیل کرتے ہیں اور پھر واپس۔ ```javascript -// ایک جوڑے کا سیمیٹریکل ہیش تاکہ ہمیں پرواہ نہ ہو کہ ترتیب الٹ دی گئی ہے۔ +// Symmetrical hash of a pair so we won't care if the order is reversed. const pairHash = (a, b) => hash(hash(a) ^ hash(b)) ``` @@ -89,8 +89,8 @@ const pairHash = (a, b) => hash(hash(a) ^ hash(b)) اس فنکشن کے ساتھ آپ کو `b'` کا حساب لگانا ہوگا تاکہ `hash(a') ^ hash(b')` ایک معلوم قدر (روٹ کے راستے پر اگلی شاخ) کے برابر ہو، جو کہ بہت زیادہ مشکل ہے۔ ```javascript -// یہ قدر یہ ظاہر کرنے کے لیے کہ ایک خاص شاخ خالی ہے، اس میں -// کوئی قدر نہیں ہے +// The value to denote that a certain branch is empty, doesn't +// have a value const empty = 0n ``` @@ -99,11 +99,11 @@ const empty = 0n ![غائب شاخوں کے ساتھ مرکل ٹری](merkle-empty-hash.png) ```javascript -// ایک ہیش ایرے کے ٹری میں ایک لیول اوپر کا حساب لگائیں، ہر جوڑے کا -// ترتیب سے ہیش لے کر +// Calculate one level up the tree of a hash array by taking the hash of +// each pair in sequence const oneLevelUp = (inputArray) => { var result = [] - var inp = [...inputArray] // ان پٹ پر اوور رائٹنگ سے بچنے کے لیے // اگر ضروری ہو تو ایک خالی قدر شامل کریں (ہمیں تمام لیوز کو // جوڑا بنانے کی ضرورت ہے) + var inp = [...inputArray] // To avoid over writing the input // Add an empty value if necessary (we need all the leaves to be // paired) if (inp.length % 2 === 1) inp.push(empty) @@ -120,7 +120,7 @@ const oneLevelUp = (inputArray) => { const getMerkleRoot = (inputArray) => { var result - result = [...inputArray] // ٹری پر اس وقت تک چڑھیں جب تک کہ صرف ایک قدر نہ رہ جائے، جو کہ // روٹ ہے۔ // // اگر کسی لیئر میں اندراجات کی تعداد طاق ہے تو // oneLevelUp میں موجود کوڈ ایک خالی قدر شامل کرتا ہے، لہذا اگر ہمارے پاس، مثال کے طور پر، // 10 لیوز ہیں تو ہمارے پاس دوسری لیئر میں 5 شاخیں، تیسری میں 3 // شاخیں، چوتھی میں 2 ہوں گی اور روٹ پانچواں ہے + result = [...inputArray] // Climb up the tree until there is only one value, that is the // root. // // If a layer has an odd number of entries the // code in oneLevelUp adds an empty value, so if we have, for example, // 10 leaves we'll have 5 branches in the second layer, 3 // branches in the third, 2 in the fourth and the root is the fifth while (result.length > 1) result = oneLevelUp(result) @@ -135,22 +135,22 @@ const getMerkleRoot = (inputArray) => { مرکل پروف وہ قدریں ہیں جنہیں ثابت کی جانے والی قدر کے ساتھ ہیش کرکے مرکل روٹ واپس حاصل کیا جاتا ہے۔ ثابت کرنے کی قدر اکثر دوسرے ڈیٹا سے دستیاب ہوتی ہے، اس لیے میں اسے کوڈ کے حصے کے طور پر فراہم کرنے کے بجائے الگ سے فراہم کرنا پسند کرتا ہوں۔ ```javascript -// مرکل پروف ان اندراجات کی فہرست کی قدر پر مشتمل ہوتا ہے جن کے ساتھ -// ہیش کرنا ہے۔ چونکہ ہم ایک سیمیٹریکل ہیش فنکشن استعمال کرتے ہیں، ہمیں -// پروف کی تصدیق کے لیے آئٹم کے مقام کی ضرورت نہیں ہے، صرف اسے بنانے کے لیے +// A merkle proof consists of the value of the list of entries to +// hash with. Because we use a symmetrical hash function, we don't +// need the item's location to verify the proof, only to create it const getMerkleProof = (inputArray, n) => {     var result = [], currentLayer = [...inputArray], currentN = n -    // جب تک ہم سب سے اوپر نہ پہنچ جائیں +    // Until we reach the top     while (currentLayer.length > 1) { -        // کوئی طاق لمبائی کی لیئرز نہیں +        // No odd length layers         if (currentLayer.length % 2)             currentLayer.push(empty)         result.push(currentN % 2 -               // اگر currentN طاق ہے، تو اس سے پہلے کی قدر کے ساتھ پروف میں شامل کریں +               // If currentN is odd, add with the value before it to the proof             ? currentLayer[currentN-1] -               // اگر یہ جفت ہے، تو اس کے بعد کی قدر شامل کریں +               // If it is even, add the value after it             : currentLayer[currentN+1]) ``` @@ -158,10 +158,10 @@ const getMerkleProof = (inputArray, n) => { ہم `(v[0],v[1])`، `(v[2],v[3])`، وغیرہ کو ہیش کرتے ہیں۔ لہذا جفت قدروں کے لیے ہمیں اگلی قدر کی ضرورت ہے، اور طاق قدروں کے لیے پچھلی قدر کی۔ ```javascript -        // اگلی لیئر پر جائیں +        // Move to the next layer up         currentN = Math.floor(currentN/2)         currentLayer = oneLevelUp(currentLayer) -    }   // جبکہ currentLayer.length > 1 +    }   // while currentLayer.length > 1     return result }   // getMerkleProof @@ -189,9 +189,9 @@ contract MerkleProof {       return merkleRoot;     } -    // انتہائی غیر محفوظ، پروڈکشن کوڈ میں اس فنکشن -    // تک رسائی کو سختی سے محدود کیا جانا چاہیے، شاید کسی -    // مالک تک +    // Extremely insecure, in production code access to +    // this function MUST BE strictly limited, probably to an +    // owner     function setRoot(uint _merkleRoot) external {       merkleRoot = _merkleRoot;     }   // setRoot @@ -214,7 +214,7 @@ contract MerkleProof { **نوٹ:** یہ پڑھنے کی اہلیت کے لیے آپٹیمائزیشن کا ایک اور معاملہ ہے۔ [فنکشن کی تعریف](https://www.tutorialspoint.com/solidity/solidity_cryptographic_functions.htm) کی بنیاد پر، ڈیٹا کو [`bytes32`](https://docs.soliditylang.org/en/v0.5.3/types.html#fixed-size-byte-arrays) قدر کے طور پر اسٹور کرنا اور تبادلوں سے بچنا ممکن ہو سکتا ہے۔ ```solidity -    // مرکل پروف کی تصدیق کریں +    // Verify a Merkle proof     function verifyProof(uint _value, uint[] calldata _proof)         public view returns (bool) {       uint temp = _value; diff --git a/public/content/translations/ur/developers/tutorials/nft-minter/index.md b/public/content/translations/ur/developers/tutorials/nft-minter/index.md index 0e6c46f3fc8..acd59970ed0 100644 --- a/public/content/translations/ur/developers/tutorials/nft-minter/index.md +++ b/public/content/translations/ur/developers/tutorials/nft-minter/index.md @@ -99,7 +99,7 @@ npm start اس فائل کے اوپری حصے میں، ہمارے پاس ہمارے اسٹیٹ متغیرات (state variables) ہیں جنہیں ہم مخصوص ایونٹس کے بعد اپ ڈیٹ کریں گے۔ ```javascript -//اسٹیٹ متغیرات +//State variables const [walletAddress, setWallet] = useState("") const [status, setStatus] = useState("") const [name, setName] = useState("") @@ -121,15 +121,15 @@ React اسٹیٹ متغیرات (state variables) یا اسٹیٹ ہکس (state ```javascript useEffect(async () => { - //TODO: نافذ کریں + //TODO: implement }, []) const connectWalletPressed = async () => { - //TODO: نافذ کریں + //TODO: implement } const onMintPressed = async () => { - //TODO: نافذ کریں + //TODO: implement } ``` @@ -142,50 +142,50 @@ const onMintPressed = async () => { آپ یہ بھی دیکھیں گے کہ جب بالترتیب `mintButton` اور `walletButton` IDs والے بٹنوں پر کلک کیا جاتا ہے تو `connectWalletPressed` اور `onMintPressed` کو کال کیا جاتا ہے۔ ```javascript -//ہمارے کمپونینٹ کا UI +//the UI of our component return (


-

🧙‍♂️ Alchemy NFT منٹر

+

🧙‍♂️ Alchemy NFT Minter

- بس اپنے اثاثے کا لنک، نام، اور تفصیل شامل کریں، پھر "Mint" دبائیں۔ + Simply add your asset's link, name, and description, then press "Mint."

-

🖼 اثاثہ کا لنک:

+

🖼 Link to asset:

setURL(event.target.value)} /> -

🤔 نام:

+

🤔 Name:

setName(event.target.value)} /> -

✍️ تفصیل:

+

✍️ Description:

setDescription(event.target.value)} />

{status}

-
+ ) ``` @@ -245,7 +245,7 @@ export const connectWallet = async () => { method: "eth_requestAccounts", }) const obj = { - status: "👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔", + status: "👆🏽 Write a message in the text-field above.", address: addressArray[0], } return obj @@ -263,7 +263,8 @@ export const connectWallet = async () => {

{" "} 🦊 - آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + You must install MetaMask, a virtual Ethereum wallet, in your + browser.

@@ -302,7 +303,7 @@ import { connectWallet } from "./utils/interact.js"; const Minter = (props) => { - //اسٹیٹ متغیرات + //State variables const [walletAddress, setWallet] = useState(""); const [status, setStatus] = useState(""); const [name, setName] = useState(""); @@ -350,12 +351,12 @@ export const getCurrentWalletConnected = async () => { if (addressArray.length > 0) { return { address: addressArray[0], - status: "👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔", + status: "👆🏽 Write a message in the text-field above.", } } else { return { address: "", - status: "🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔", + status: "🦊 Connect to MetaMask using the top right button.", } } } catch (err) { @@ -372,7 +373,8 @@ export const getCurrentWalletConnected = async () => {

{" "} 🦊 - آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + You must install MetaMask, a virtual Ethereum wallet, in your + browser.

@@ -394,7 +396,7 @@ export const getCurrentWalletConnected = async () => { import { useEffect, useState } from "react" import { connectWallet, - getCurrentWalletConnected, //یہاں امپورٹ کریں + getCurrentWalletConnected, //import here } from "./utils/interact.js" ``` @@ -424,10 +426,10 @@ function addWalletListener() { window.ethereum.on("accountsChanged", (accounts) => { if (accounts.length > 0) { setWallet(accounts[0]) - setStatus("👆🏽 اوپر ٹیکسٹ فیلڈ میں ایک پیغام لکھیں۔") + setStatus("👆🏽 Write a message in the text-field above.") } else { setWallet("") - setStatus("🦊 اوپر دائیں بٹن کا استعمال کرتے ہوئے MetaMask سے جڑیں۔") + setStatus("🦊 Connect to MetaMask using the top right button.") } }) } else { @@ -435,7 +437,7 @@ function addWalletListener() {

{" "} 🦊 - آپ کو اپنے براؤزر میں MetaMask، ایک ورچوئل Ethereum والیٹ، انسٹال کرنا ہوگا۔ + You must install MetaMask, a virtual Ethereum wallet, in your browser.

) @@ -663,11 +665,11 @@ export const mintNFT = async (url, name, description) => {} ```javascript export const mintNFT = async (url, name, description) => { - //خرابی کو ہینڈل کرنا + //error handling if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + status: "❗Please make sure all fields are completed before minting.", } } } @@ -691,26 +693,26 @@ import { pinJSONToIPFS } from "./pinata.js" ```javascript export const mintNFT = async (url, name, description) => { - //خرابی کو ہینڈل کرنا + //error handling if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + status: "❗Please make sure all fields are completed before minting.", } } - //میٹا ڈیٹا بنائیں + //make metadata const metadata = new Object() metadata.name = name metadata.image = url metadata.description = description - //pinata کال کریں + //make pinata call const pinataResponse = await pinJSONToIPFS(metadata) if (!pinataResponse.success) { return { success: false, - status: "😢 آپ کا tokenURI اپ لوڈ کرتے وقت کچھ غلط ہو گیا۔", + status: "😢 Something went wrong while uploading your tokenURI.", } } const tokenURI = pinataResponse.pinataUrl @@ -730,16 +732,16 @@ window.contract = await new web3.eth.Contract(contractABI, contractAddress) ہمارے `mintNFT` فنکشن میں شامل کرنے والی آخری چیز ہمارا Ethereum ٹرانزیکشن ہے: ```javascript -//اپنا Ethereum ٹرانزیکشن سیٹ اپ کریں +//set up your Ethereum transaction const transactionParameters = { - to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ - from: window.ethereum.selectedAddress, // صارف کے فعال پتے سے مماثل ہونا چاہیے۔ + to: contractAddress, // Required except during contract publications. + from: window.ethereum.selectedAddress, // must match user's active address. data: window.contract.methods .mintNFT(window.ethereum.selectedAddress, tokenURI) - .encodeABI(), //NFT اسمارٹ کنٹریکٹ پر کال کریں + .encodeABI(), //make call to NFT smart contract } -//MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں +//sign the transaction via MetaMask try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -748,13 +750,13 @@ try { return { success: true, status: - "✅ Etherscan پر اپنے ٹرانزیکشن کو دیکھیں: https://ropsten.etherscan.io/tx/" + + "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + txHash, } } catch (error) { return { success: false, - status: "😥 کچھ غلط ہو گیا: " + error.message, + status: "😥 Something went wrong: " + error.message, } } ``` @@ -773,43 +775,43 @@ try { ```javascript export const mintNFT = async (url, name, description) => { - //خرابی کو ہینڈل کرنا + //error handling if (url.trim() == "" || name.trim() == "" || description.trim() == "") { return { success: false, - status: "❗براہ کرم یقینی بنائیں کہ منٹ کرنے سے پہلے تمام فیلڈز مکمل ہیں۔", + status: "❗Please make sure all fields are completed before minting.", } } - //میٹا ڈیٹا بنائیں + //make metadata const metadata = new Object() metadata.name = name metadata.image = url metadata.description = description - //pinata پن کی درخواست + //pinata pin request const pinataResponse = await pinJSONToIPFS(metadata) if (!pinataResponse.success) { return { success: false, - status: "😢 آپ کا tokenURI اپ لوڈ کرتے وقت کچھ غلط ہو گیا۔", + status: "😢 Something went wrong while uploading your tokenURI.", } } const tokenURI = pinataResponse.pinataUrl - //اسمارٹ کنٹریکٹ لوڈ کریں + //load smart contract window.contract = await new web3.eth.Contract(contractABI, contractAddress) //loadContract(); - //اپنا Ethereum ٹرانزیکشن سیٹ اپ کریں + //set up your Ethereum transaction const transactionParameters = { - to: contractAddress, // کنٹریکٹ کی اشاعت کے دوران کے علاوہ ضروری ہے۔ - from: window.ethereum.selectedAddress, // صارف کے فعال پتے سے مماثل ہونا چاہیے۔ + to: contractAddress, // Required except during contract publications. + from: window.ethereum.selectedAddress, // must match user's active address. data: window.contract.methods .mintNFT(window.ethereum.selectedAddress, tokenURI) - .encodeABI(), //NFT اسمارٹ کنٹریکٹ پر کال کریں + .encodeABI(), //make call to NFT smart contract } - //MetaMask کے ذریعے ٹرانزیکشن پر دستخط کریں + //sign transaction via MetaMask try { const txHash = await window.ethereum.request({ method: "eth_sendTransaction", @@ -818,13 +820,13 @@ export const mintNFT = async (url, name, description) => { return { success: true, status: - "✅ Etherscan پر اپنے ٹرانزیکشن کو دیکھیں: https://ropsten.etherscan.io/tx/" + + "✅ Check out your transaction on Etherscan: https://ropsten.etherscan.io/tx/" + txHash, } } catch (error) { return { success: false, - status: "😥 کچھ غلط ہو گیا: " + error.message, + status: "😥 Something went wrong: " + error.message, } } } diff --git a/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md b/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md index 496e13470c4..431c97d0e02 100644 --- a/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md +++ b/public/content/translations/ur/developers/tutorials/optimism-std-bridge-annotated-code/index.md @@ -91,7 +91,7 @@ pragma solidity >0.5.0 <0.9.0; */ interface IL1ERC20Bridge { /********** - * ایونٹس * + * Events * **********/ event ERC20DepositInitiated( @@ -136,12 +136,12 @@ L1 برج کے معاملے میں، اس کا مطلب ہے ڈپازٹ کا آ ```solidity /******************** - * پبلک فنکشنز * + * Public Functions * ********************/ /** - * @dev متعلقہ L2 برج کنٹریکٹ کا ایڈریس حاصل کریں۔ - * @return متعلقہ L2 برج کنٹریکٹ کا ایڈریس۔ + * @dev get the address of the corresponding L2 bridge contract. + * @return Address of the corresponding L2 bridge contract. */ function l2TokenBridge() external returns (address); ``` @@ -151,14 +151,14 @@ L1 برج کے معاملے میں، اس کا مطلب ہے ڈپازٹ کا آ ```solidity /** - * @dev L2 پر کالر کے بیلنس میں ERC20 کی رقم جمع کریں۔ - * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں - * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس - * @param _amount جمع کرنے کے لیے ERC20 کی رقم - * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ - * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @dev deposit an amount of the ERC20 to the caller's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _amount Amount of the ERC20 to deposit + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function depositERC20( address _l1Token, @@ -175,15 +175,15 @@ L1 برج کے معاملے میں، اس کا مطلب ہے ڈپازٹ کا آ ```solidity /** - * @dev L2 پر وصول کنندہ کے بیلنس میں ERC20 کی رقم جمع کریں۔ - * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں - * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس - * @param _to L2 ایڈریس جس پر واپسی کریڈٹ کی جائے گی۔ - * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ - * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ - * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @dev deposit an amount of ERC20 to a recipient's balance on L2. + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _to L2 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function depositERC20To( address _l1Token, @@ -199,22 +199,22 @@ L1 برج کے معاملے میں، اس کا مطلب ہے ڈپازٹ کا آ ```solidity /************************* - * کراس چین فنکشنز * + * Cross-chain Functions * *************************/ /** - * @dev L2 سے L1 تک کی واپسی کو مکمل کریں، اور فنڈز کو - * L1 ERC20 ٹوکن کے وصول کنندہ کے بیلنس میں کریڈٹ کریں۔ - * اگر L2 سے شروع کی گئی واپسی کو حتمی شکل نہیں دی گئی ہے تو یہ کال ناکام ہو جائے گی۔ + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ERC20 token. + * This call will fail if the initialized withdrawal from L2 has not been finalized. * - * @param _l1Token L1 ٹوکن کا ایڈریس جس کے لیے finalizeWithdrawal کرنا ہے۔ - * @param _l2Token L2 ٹوکن کا ایڈریس جہاں سے واپسی شروع کی گئی تھی۔ - * @param _from منتقلی شروع کرنے والا L2 ایڈریس۔ - * @param _to L1 ایڈریس جس پر واپسی کریڈٹ کی جائے گی۔ - * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ - * @param _data L2 پر بھیجنے والے کی طرف سے فراہم کردہ ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @param _l1Token Address of L1 token to finalizeWithdrawal for. + * @param _l2Token Address of L2 token where withdrawal was initiated. + * @param _from L2 address initiating the transfer. + * @param _to L1 address to credit the withdrawal to. + * @param _amount Amount of the ERC20 to deposit. + * @param _data Data provided by the sender on L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function finalizeERC20Withdrawal( address _l1Token, @@ -253,7 +253,7 @@ import "./IL1ERC20Bridge.sol"; */ interface IL1StandardBridge is IL1ERC20Bridge { /********** - * ایونٹس * + * Events * **********/ event ETHDepositInitiated( address indexed _from, @@ -274,11 +274,11 @@ interface IL1StandardBridge is IL1ERC20Bridge { ); /******************** - * پبلک فنکشنز * + * Public Functions * ********************/ /** - * @dev L2 پر کالر کے بیلنس میں ETH کی رقم جمع کریں۔ + * @dev Deposit an amount of the ETH to the caller's balance on L2. . . . @@ -286,7 +286,7 @@ interface IL1StandardBridge is IL1ERC20Bridge { function depositETH(uint32 _l2Gas, bytes calldata _data) external payable; /** - * @dev L2 پر وصول کنندہ کے بیلنس میں ETH کی رقم جمع کریں۔ + * @dev Deposit an amount of ETH to a recipient's balance on L2. . . . @@ -298,13 +298,13 @@ interface IL1StandardBridge is IL1ERC20Bridge { ) external payable; /************************* - * کراس چین فنکشنز * + * Cross-chain Functions * *************************/ /** - * @dev L2 سے L1 تک کی واپسی کو مکمل کریں، اور فنڈز کو - * L1 ETH ٹوکن کے وصول کنندہ کے بیلنس میں کریڈٹ کریں۔ چونکہ صرف xDomainMessenger ہی اس فنکشن کو کال کر سکتا ہے، اس لیے اسے - * واپسی کے حتمی ہونے سے پہلے کبھی کال نہیں کیا جائے گا۔ + * @dev Complete a withdrawal from L2 to L1, and credit funds to the recipient's balance of the + * L1 ETH token. Since only the xDomainMessenger can call this function, it will never be called + * before the withdrawal is finalized. . . . @@ -326,7 +326,7 @@ interface IL1StandardBridge is IL1ERC20Bridge { // SPDX-License-Identifier: MIT pragma solidity >0.5.0 <0.9.0; -/* انٹرفیس امپورٹس */ +/* Interface Imports */ import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; ``` @@ -336,24 +336,24 @@ import { ICrossDomainMessenger } from "./ICrossDomainMessenger.sol"; ```solidity /** * @title CrossDomainEnabled - * @dev کراس ڈومین کمیونیکیشن کرنے والے کنٹریکٹس کے لیے ہیلپر کنٹریکٹ + * @dev Helper contract for contracts performing cross-domain communications * - * استعمال شدہ کمپائلر: وراثت میں ملنے والے کنٹریکٹ کے ذریعے بیان کیا گیا ہے + * Compiler used: defined by inheriting contract */ contract CrossDomainEnabled { /************* - * متغیرات * + * Variables * *************/ - // دوسرے ڈومین سے پیغامات بھیجنے اور وصول کرنے کے لیے استعمال ہونے والا میسنجر کنٹریکٹ۔ + // Messenger contract used to send and receive messages from the other domain. address public messenger; /*************** - * کنسٹرکٹر * + * Constructor * ***************/ /** - * @param _messenger موجودہ لیئر پر CrossDomainMessenger کا ایڈریس۔ + * @param _messenger Address of the CrossDomainMessenger on the current layer. */ constructor(address _messenger) { messenger = _messenger; @@ -366,13 +366,13 @@ contract CrossDomainEnabled { ```solidity /********************** - * فنکشن موڈیفائرز * + * Function Modifiers * **********************/ /** - * نافذ کرتا ہے کہ ترمیم شدہ فنکشن صرف ایک مخصوص کراس ڈومین اکاؤنٹ کے ذریعے کال کیا جا سکتا ہے۔ - * @param _sourceDomainAccount اصل ڈومین پر واحد اکاؤنٹ جو - * اس فنکشن کو کال کرنے کے لیے مستند ہے۔ + * Enforces that the modified function is only callable by a specific cross-domain account. + * @param _sourceDomainAccount The only account on the originating domain which is + * authenticated to call this function. */ modifier onlyFromCrossDomainAccount(address _sourceDomainAccount) { ``` @@ -383,7 +383,7 @@ contract CrossDomainEnabled { ```solidity require( msg.sender == address(getCrossDomainMessenger()), - "OVM_XCHAIN: میسنجر کنٹریکٹ غیر مستند" + "OVM_XCHAIN: messenger contract unauthenticated" ); ``` @@ -393,7 +393,7 @@ contract CrossDomainEnabled { require( getCrossDomainMessenger().xDomainMessageSender() == _sourceDomainAccount, - "OVM_XCHAIN: کراس ڈومین پیغام کا غلط بھیجنے والا" + "OVM_XCHAIN: wrong sender of cross-domain message" ); ``` @@ -403,17 +403,18 @@ contract CrossDomainEnabled { ہمیں یہ یقینی بنانا ہوگا کہ ہمیں موصول ہونے والا پیغام دوسرے برج سے آیا ہے۔ ```solidity + _; } /********************** - * اندرونی فنکشنز * + * Internal Functions * **********************/ /** - * میسنجر حاصل کرتا ہے، عام طور پر اسٹوریج سے۔ یہ فنکشن اس صورت میں ظاہر ہوتا ہے جب کسی چائلڈ کنٹریکٹ - * کو اوور رائڈ کرنے کی ضرورت ہو۔ - * @return کراس ڈومین میسنجر کنٹریکٹ کا ایڈریس جو استعمال کیا جانا چاہئے۔ + * Gets the messenger, usually from storage. This function is exposed in case a child contract + * needs to override. + * @return The address of the cross-domain messenger contract which should be used. */ function getCrossDomainMessenger() internal virtual returns (ICrossDomainMessenger) { return ICrossDomainMessenger(messenger); @@ -426,11 +427,11 @@ contract CrossDomainEnabled { ```solidity /** - * دوسرے ڈومین پر ایک اکاؤنٹ کو ایک پیغام بھیجتا ہے - * @param _crossDomainTarget منزل کے ڈومین پر مطلوبہ وصول کنندہ - * @param _message ہدف کو بھیجنے کے لیے ڈیٹا (عام طور پر ایک فنکشن کے لیے کال ڈیٹا - * `onlyFromCrossDomainAccount()` کے ساتھ) - * @param _gasLimit ہدف ڈومین پر پیغام کی رسید کے لیے گیس کی حد۔ + * Sends a message to an account on another domain + * @param _crossDomainTarget The intended recipient on the destination domain + * @param _message The data to send to the target (usually calldata to a function with + * `onlyFromCrossDomainAccount()`) + * @param _gasLimit The gasLimit for the receipt of the message on the target domain. */ function sendCrossDomainMessage( address _crossDomainTarget, @@ -472,7 +473,7 @@ pragma solidity ^0.8.9; لیکن برج خود ہمارا کنٹریکٹ ہے، اور ہم اس بارے میں سخت ہو سکتے ہیں کہ یہ کون سا Solidity ورژن استعمال کرتا ہے۔ ```solidity -/* انٹرفیس امپورٹس */ +/* Interface Imports */ import { IL1StandardBridge } from "./IL1StandardBridge.sol"; import { IL1ERC20Bridge } from "./IL1ERC20Bridge.sol"; ``` @@ -493,7 +494,7 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; [آپ اس کے بارے میں مزید یہاں پڑھ سکتے ہیں](/developers/tutorials/erc20-annotated-code/#the-interface)۔ ```solidity -/* لائبریری امپورٹس */ +/* Library Imports */ import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; ``` @@ -527,9 +528,9 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s ```solidity /** * @title L1StandardBridge - * @dev L1 ETH اور ERC20 برج ایک کنٹریکٹ ہے جو جمع شدہ L1 فنڈز اور - * L2 پر استعمال ہونے والے معیاری ٹوکنز کو اسٹور کرتا ہے۔ یہ ایک متعلقہ L2 برج کو سنکرونائز کرتا ہے، اسے ڈپازٹ کے بارے میں مطلع کرتا ہے - * اور نئی حتمی واپسیوں کے لیے اسے سنتا ہے۔ + * @dev The L1 ETH and ERC20 Bridge is a contract which stores deposited L1 funds and standard + * tokens that are in use on L2. It synchronizes a corresponding L2 Bridge, informing it of deposits + * and listening to it for newly finalized withdrawals. * */ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { @@ -541,7 +542,7 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /******************************** - * بیرونی کنٹریکٹ کے حوالے * + * External Contract References * ********************************/ address public l2TokenBridge; @@ -551,7 +552,7 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity - // L1 ٹوکن کو L2 ٹوکن سے جمع شدہ L1 ٹوکن کے بیلنس پر میپ کرتا ہے + // Maps L1 token to L2 token to balance of the L1 token deposited mapping(address => mapping(address => uint256)) public deposits; ``` @@ -563,10 +564,10 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /*************** - * کنسٹرکٹر * + * Constructor * ***************/ - // یہ کنٹریکٹ ایک پراکسی کے پیچھے رہتا ہے، لہذا کنسٹرکٹر پیرامیٹرز استعمال نہیں ہوں گے۔ + // This contract lives behind a proxy, so the constructor parameters will go unused. constructor() CrossDomainEnabled(address(0)) {} ``` @@ -580,12 +581,12 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /****************** - * شروعات * + * Initialization * ******************/ /** - * @param _l1messenger کراس چین کمیونیکیشنز کے لیے استعمال ہونے والا L1 میسنجر ایڈریس۔ - * @param _l2TokenBridge L2 معیاری برج ایڈریس۔ + * @param _l1messenger L1 Messenger address being used for cross-chain communications. + * @param _l2TokenBridge L2 standard bridge address. */ // slither-disable-next-line external-function ``` @@ -599,7 +600,7 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity function initialize(address _l1messenger, address _l2TokenBridge) public { - require(messenger == address(0), "کنٹریکٹ پہلے ہی شروع کیا جا چکا ہے۔"); + require(messenger == address(0), "Contract has already been initialized."); ``` `initialize` فنکشن کو صرف ایک بار کال کیا جانا چاہیے۔ @@ -623,15 +624,15 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /************** - * جمع کرنا * + * Depositing * **************/ - /** @dev موڈیفائر جس میں بھیجنے والے کو EOA ہونا ضروری ہے۔ اس چیک کو ایک بدنیتی پر مبنی - * کنٹریکٹ کے ذریعے initcode کے ذریعے بائی پاس کیا جا سکتا ہے، لیکن یہ اس صارف کی غلطی کا خیال رکھتا ہے جس سے ہم بچنا چاہتے ہیں۔ + /** @dev Modifier requiring sender to be EOA. This check could be bypassed by a malicious + * contract via initcode, but it takes care of the user error we want to avoid. */ modifier onlyEOA() { - // کنٹریکٹس سے ڈپازٹ روکنے کے لیے استعمال کیا جاتا ہے (حادثاتی طور پر کھوئے ہوئے ٹوکن سے بچنے کے لیے) - require(!Address.isContract(msg.sender), "اکاؤنٹ EOA نہیں ہے"); + // Used to stop deposits from contracts (avoid accidentally lost tokens) + require(!Address.isContract(msg.sender), "Account not EOA"); _; } ``` @@ -640,10 +641,10 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /** - * @dev اس فنکشن کو بغیر کسی ڈیٹا کے - * L2 پر کالر کے بیلنس میں ETH کی رقم جمع کرنے کے لیے کال کیا جا سکتا ہے۔ - * چونکہ وصول کرنے والا فنکشن ڈیٹا نہیں لیتا، لہذا ایک قدامت پسند - * پہلے سے طے شدہ رقم L2 کو بھیجی جاتی ہے۔ + * @dev This function can be called with no data + * to deposit an amount of ETH to the caller's balance on L2. + * Since the receive function doesn't take data, a conservative + * default amount is forwarded to L2. */ receive() external payable onlyEOA { _initiateETHDeposit(msg.sender, msg.sender, 200_000, bytes("")); @@ -677,14 +678,14 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { ```solidity /** - * @dev ETH کو اسٹور کرکے اور L2 ETH گیٹ وے کو - * ڈپازٹ کے بارے میں مطلع کرکے ڈپازٹ کے لیے منطق انجام دیتا ہے۔ - * @param _from L1 پر ڈپازٹ نکالنے کے لیے اکاؤنٹ۔ - * @param _to L2 پر ڈپازٹ دینے کے لیے اکاؤنٹ۔ - * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ - * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @dev Performs the logic for deposits by storing the ETH and informing the L2 ETH Gateway of + * the deposit. + * @param _from Account to pull the deposit from on L1. + * @param _to Account to give the deposit to on L2. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function _initiateETHDeposit( address _from, @@ -692,7 +693,7 @@ contract L1StandardBridge is IL1StandardBridge, CrossDomainEnabled { uint32 _l2Gas, bytes memory _data ) internal { - // finalizeDeposit کال کے لیے کال ڈیٹا تعمیر کریں + // Construct calldata for finalizeDeposit call bytes memory message = abi.encodeWithSelector( ``` @@ -724,7 +725,7 @@ Solidity فنکشن [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/ | \_data | \_data | ڈپازٹ کے ساتھ منسلک کرنے کے لیے اضافی ڈیٹا | ```solidity - // L2 میں کال ڈیٹا بھیجیں + // Send calldata into L2 // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); ``` @@ -767,18 +768,18 @@ Solidity فنکشن [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/ ```solidity /** - * @dev L2 جمع شدہ ٹوکن - * کنٹریکٹ کو ڈپازٹ کے بارے میں مطلع کرکے اور L1 فنڈز کو لاک کرنے کے لیے ایک ہینڈلر کو کال کرکے ڈپازٹ کے لیے منطق انجام دیتا ہے۔ (مثلاً، transferFrom) + * @dev Performs the logic for deposits by informing the L2 Deposited Token + * contract of the deposit and calling a handler to lock the L1 funds. (e.g., transferFrom) * - * @param _l1Token L1 ERC20 کا ایڈریس جسے ہم جمع کر رہے ہیں - * @param _l2Token L1 متعلقہ L2 ERC20 کا ایڈریس - * @param _from L1 پر ڈپازٹ نکالنے کے لیے اکاؤنٹ - * @param _to L2 پر ڈپازٹ دینے کے لیے اکاؤنٹ - * @param _amount جمع کرنے کے لیے ERC20 کی رقم۔ - * @param _l2Gas L2 پر ڈپازٹ مکمل کرنے کے لیے درکار گیس کی حد۔ - * @param _data L2 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @param _l1Token Address of the L1 ERC20 we are depositing + * @param _l2Token Address of the L1 respective L2 ERC20 + * @param _from Account to pull the deposit from on L1 + * @param _to Account to give the deposit to on L2 + * @param _amount Amount of the ERC20 to deposit. + * @param _l2Gas Gas limit required to complete the deposit on L2. + * @param _data Optional data to forward to L2. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function _initiateERC20Deposit( address _l1Token, @@ -796,9 +797,9 @@ Solidity فنکشن [`abi.encodeWithSelector`](https://docs.soliditylang.org/en/ ETH کے معاملے میں برج کو کال میں پہلے ہی برج اکاؤنٹ (`msg.value`) میں اثاثے کی منتقلی شامل ہے۔ ```solidity - // جب L1 پر ڈپازٹ شروع کیا جاتا ہے، تو L1 برج فنڈز کو مستقبل - // کی واپسیوں کے لیے خود کو منتقل کرتا ہے۔ safeTransferFrom یہ بھی چیک کرتا ہے کہ آیا کنٹریکٹ میں کوڈ ہے، لہذا یہ ناکام ہو جائے گا اگر - // _from ایک EOA یا address(0) ہے۔ + // When a deposit is initiated on L1, the L1 Bridge transfers the funds to itself for future + // withdrawals. safeTransferFrom also checks if the contract has code, so this will fail if + // _from is an EOA or address(0). // slither-disable-next-line reentrancy-events, reentrancy-benign IERC20(_l1Token).safeTransferFrom(_from, address(this), _amount); ``` @@ -813,7 +814,7 @@ ERC-20 ٹوکن کی منتقلی ETH سے ایک مختلف عمل کی پیر تاہم، فرنٹ رننگ کوئی مسئلہ نہیں ہے کیونکہ دو فنکشنز جو `_initiateERC20Deposit` (`depositERC20` اور `depositERC20To`) کو کال کرتے ہیں وہ اس فنکشن کو صرف `msg.sender` کے ساتھ `_from` پیرامیٹر کے طور پر کال کرتے ہیں۔ ```solidity - // _l2Token.finalizeDeposit(_to, _amount) کے لیے کال ڈیٹا تعمیر کریں + // Construct calldata for _l2Token.finalizeDeposit(_to, _amount) bytes memory message = abi.encodeWithSelector( IL2ERC20Bridge.finalizeDeposit.selector, _l1Token, @@ -824,7 +825,7 @@ ERC-20 ٹوکن کی منتقلی ETH سے ایک مختلف عمل کی پیر _data ); - // L2 میں کال ڈیٹا بھیجیں + // Send calldata into L2 // slither-disable-next-line reentrancy-events, reentrancy-benign sendCrossDomainMessage(l2TokenBridge, _l2Gas, message); @@ -842,7 +843,7 @@ L2 پر متعدد ایڈریس ہو سکتے ہیں جو ایک ہی L1 ERC-20 } /************************* - * کراس چین فنکشنز * + * Cross-chain Functions * *************************/ /** @@ -872,7 +873,7 @@ L2 برج L2 کراس ڈومین میسنجر کو ایک پیغام بھیجت ETH منتقل کرنے کا طریقہ یہ ہے کہ وصول کنندہ کو `msg.value` میں wei کی رقم کے ساتھ کال کریں۔ ```solidity - require(success, "TransferHelper::safeTransferETH: ETH منتقلی ناکام"); + require(success, "TransferHelper::safeTransferETH: ETH transfer failed"); // slither-disable-next-line reentrancy-events emit ETHWithdrawalFinalized(_from, _to, _amount, _data); @@ -906,7 +907,7 @@ ETH منتقل کرنے کا طریقہ یہ ہے کہ وصول کنندہ کو ```solidity - // جب L1 پر واپسی کو حتمی شکل دی جاتی ہے، تو L1 برج فنڈز کو واپس لینے والے کو منتقل کرتا ہے + // When a withdrawal is finalized on L1, the L1 Bridge transfers the funds to the withdrawer // slither-disable-next-line reentrancy-events IERC20(_l1Token).safeTransfer(_to, _amount); @@ -916,14 +917,14 @@ ETH منتقل کرنے کا طریقہ یہ ہے کہ وصول کنندہ کو /***************************** - * عارضی - ETH کی منتقلی * + * Temporary - Migrating ETH * *****************************/ /** - * @dev اکاؤنٹ میں ETH بیلنس شامل کرتا ہے۔ اس کا مقصد ETH - * کو پرانے گیٹ وے سے نئے گیٹ وے میں منتقل کرنے کی اجازت دینا ہے۔ - * نوٹ: یہ صرف ایک اپ گریڈ کے لیے چھوڑ دیا گیا ہے تاکہ ہم پرانے کنٹریکٹ سے - * منتقل شدہ ETH وصول کر سکیں + * @dev Adds ETH balance to the account. This is meant to allow for ETH + * to be migrated from an old gateway to a new gateway. + * NOTE: This is left for one upgrade only so we are able to receive the migrated ETH from the + * old contract */ function donateETH() external payable {} } @@ -1014,10 +1015,10 @@ contract L2StandardERC20 is IL2StandardERC20, ERC20 { ```solidity /** - * @param _l2Bridge L2 معیاری برج کا ایڈریس۔ - * @param _l1Token متعلقہ L1 ٹوکن کا ایڈریس۔ - * @param _name ERC20 نام۔ - * @param _symbol ERC20 علامت۔ + * @param _l2Bridge Address of the L2 standard bridge. + * @param _l1Token Address of the corresponding L1 token. + * @param _name ERC20 name. + * @param _symbol ERC20 symbol. */ constructor( address _l2Bridge, @@ -1035,7 +1036,7 @@ contract L2StandardERC20 is IL2StandardERC20, ERC20 { ```solidity modifier onlyL2Bridge() { - require(msg.sender == l2Bridge, "صرف L2 برج منٹ اور برن کر سکتا ہے"); + require(msg.sender == l2Bridge, "Only L2 Bridge can mint and burn"); _; } @@ -1088,7 +1089,7 @@ _mint`اور`_burn` دراصل [OpenZeppelin ERC-20 کنٹریکٹ](/developers/ // SPDX-License-Identifier: MIT pragma solidity ^0.8.9; -/* انٹرفیس امپورٹس */ +/* Interface Imports */ import { IL1StandardBridge } from "../../L1/messaging/IL1StandardBridge.sol"; import { IL1ERC20Bridge } from "../../L1/messaging/IL1ERC20Bridge.sol"; import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; @@ -1103,24 +1104,26 @@ import { IL2ERC20Bridge } from "./IL2ERC20Bridge.sol"; L2 پر ہم دونوں کے لیے ایک ہی فنکشنز استعمال کر سکتے ہیں کیونکہ اندرونی طور پر Optimism پر ETH بیلنس کو ایڈریس [0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000](https://explorer.optimism.io/address/0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000) والے ERC-20 ٹوکن کے طور پر ہینڈل کیا جاتا ہے۔ ```solidity -/* لائبریری امپورٹس */ +/* Library Imports */ import { ERC165Checker } from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; import { CrossDomainEnabled } from "../../libraries/bridge/CrossDomainEnabled.sol"; import { Lib_PredeployAddresses } from "../../libraries/constants/Lib_PredeployAddresses.sol"; -/* کنٹریکٹ امپورٹس */ +/* Contract Imports */ import { IL2StandardERC20 } from "../../standards/IL2StandardERC20.sol"; /** * @title L2StandardBridge - * @dev L2 معیاری برج ایک کنٹریکٹ ہے جو L1 معیاری برج کے ساتھ مل کر - * L1 اور L2 کے درمیان ETH اور ERC20 منتقلی کو فعال کرتا ہے۔ - * یہ کنٹریکٹ نئے ٹوکنز کے لیے ایک منٹر کے طور پر کام کرتا ہے جب یہ L1 معیاری برج میں ڈپازٹ کے بارے میں سنتا ہے۔ - * یہ کنٹریکٹ واپسی کے لیے مطلوبہ ٹوکنز کے برنر کے طور پر بھی کام کرتا ہے، L1 برج کو L1 فنڈز جاری کرنے کے بارے میں مطلع کرتا ہے۔ + * @dev The L2 Standard bridge is a contract which works together with the L1 Standard bridge to + * enable ETH and ERC20 transitions between L1 and L2. + * This contract acts as a minter for new tokens when it hears about deposits into the L1 Standard + * bridge. + * This contract also acts as a burner of the tokens intended for withdrawal, informing the L1 + * bridge to release L1 funds. */ contract L2StandardBridge is IL2ERC20Bridge, CrossDomainEnabled { /******************************** - * بیرونی کنٹریکٹ کے حوالے * + * External Contract References * ********************************/ address public l1TokenBridge; @@ -1133,12 +1136,12 @@ L1 برج کا ایڈریس پہلے سے معلوم نہیں ہے۔ ```solidity /*************** - * کنسٹرکٹر * + * Constructor * ***************/ /** - * @param _l2CrossDomainMessenger اس کنٹریکٹ کے ذریعے استعمال ہونے والا کراس ڈومین میسنجر۔ - * @param _l1TokenBridge مرکزی چین پر تعینات L1 برج کا ایڈریس۔ + * @param _l2CrossDomainMessenger Cross-domain messenger used by this contract. + * @param _l1TokenBridge Address of the L1 bridge deployed to the main chain. */ constructor(address _l2CrossDomainMessenger, address _l1TokenBridge) CrossDomainEnabled(_l2CrossDomainMessenger) @@ -1147,7 +1150,7 @@ L1 برج کا ایڈریس پہلے سے معلوم نہیں ہے۔ } /*************** - * واپسی * + * Withdrawing * ***************/ /** @@ -1183,16 +1186,16 @@ L2 ٹوکنز سے توقع کی جاتی ہے کہ وہ ہمیں L1 کے مسا ```solidity /** - * @dev ٹوکن کو جلا کر اور - * L1 ٹوکن گیٹ وے کو واپسی کے بارے میں مطلع کرکے واپسی کے لیے منطق انجام دیتا ہے۔ - * @param _l2Token L2 ٹوکن کا ایڈریس جہاں سے واپسی شروع کی گئی ہے۔ - * @param _from L2 پر واپسی نکالنے کے لیے اکاؤنٹ۔ - * @param _to L1 پر واپسی دینے کے لیے اکاؤنٹ۔ - * @param _amount واپس لینے کے لیے ٹوکن کی رقم۔ - * @param _l1Gas غیر استعمال شدہ، لیکن ممکنہ فارورڈ مطابقت کے تحفظات کے لیے شامل ہے۔ - * @param _data L1 کو فارورڈ کرنے کے لیے اختیاری ڈیٹا۔ یہ ڈیٹا - * صرف بیرونی کنٹریکٹس کی سہولت کے لیے فراہم کیا گیا ہے۔ زیادہ سے زیادہ - * لمبائی نافذ کرنے کے علاوہ، یہ کنٹریکٹس اس کے مواد کے بارے میں کوئی ضمانت نہیں دیتے ہیں۔ + * @dev Performs the logic for withdrawals by burning the token and informing + * the L1 token Gateway of the withdrawal. + * @param _l2Token Address of L2 token where withdrawal is initiated. + * @param _from Account to pull the withdrawal from on L2. + * @param _to Account to give the withdrawal to on L1. + * @param _amount Amount of the token to withdraw. + * @param _l1Gas Unused, but included for potential forward compatibility considerations. + * @param _data Optional data to forward to L1. This data is provided + * solely as a convenience for external contracts. Aside from enforcing a maximum + * length, these contracts provide no guarantees about its content. */ function _initiateWithdrawal( address _l2Token, @@ -1202,8 +1205,8 @@ L2 ٹوکنز سے توقع کی جاتی ہے کہ وہ ہمیں L1 کے مسا uint32 _l1Gas, bytes calldata _data ) internal { - // جب واپسی شروع کی جاتی ہے، تو ہم بعد میں L2 - // کے استعمال کو روکنے کے لیے واپس لینے والے کے فنڈز کو جلا دیتے ہیں + // When a withdrawal is initiated, we burn the withdrawer's funds to prevent subsequent L2 + // usage // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).burn(msg.sender, _amount); ``` @@ -1212,7 +1215,7 @@ L2 ٹوکنز سے توقع کی جاتی ہے کہ وہ ہمیں L1 کے مسا ```solidity - // l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) کے لیے کال ڈیٹا تعمیر کریں + // Construct calldata for l1TokenBridge.finalizeERC20Withdrawal(_to, _amount) // slither-disable-next-line reentrancy-events address l1Token = IL2StandardERC20(_l2Token).l1Token(); bytes memory message; @@ -1242,7 +1245,7 @@ L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ ); } - // L1 برج کو پیغام بھیجیں + // Send message up to L1 bridge // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, _l1Gas, message); @@ -1251,7 +1254,7 @@ L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ } /************************************ - * کراس چین فنکشن: جمع کرنا * + * Cross-chain Function: Depositing * ************************************/ /** @@ -1276,8 +1279,8 @@ L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ یہ اہم ہے کیونکہ یہ فنکشن `_mint` کو کال کرتا ہے اور اس کا استعمال ایسے ٹوکن دینے کے لیے کیا جا سکتا ہے جو L1 پر برج کے ملکیت والے ٹوکنز کے تحت نہیں آتے ہیں۔ ```solidity - // چیک کریں کہ ہدف ٹوکن مطابقت رکھتا ہے اور - // تصدیق کریں کہ L1 پر جمع شدہ ٹوکن یہاں L2 جمع شدہ ٹوکن کی نمائندگی سے میل کھاتا ہے + // Check the target token is compliant and + // verify the deposited token on L1 matches the L2 deposited token representation here if ( // slither-disable-next-line reentrancy-events ERC165Checker.supportsInterface(_l2Token, 0x1d1d8b63) && @@ -1291,8 +1294,8 @@ L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ ```solidity ) { - // جب ڈپازٹ کو حتمی شکل دی جاتی ہے، تو ہم L2 پر اکاؤنٹ کو اتنی ہی رقم - // کے ٹوکنز کے ساتھ کریڈٹ کرتے ہیں۔ + // When a deposit is finalized, we credit the account on L2 with the same amount of + // tokens. // slither-disable-next-line reentrancy-events IL2StandardERC20(_l2Token).mint(_to, _amount); // slither-disable-next-line reentrancy-events @@ -1306,14 +1309,14 @@ L1 پر ETH اور ERC-20 کے درمیان فرق کرنا ضروری ہے۔ ```solidity } else { - // یا تو L2 ٹوکن جس میں جمع کیا جا رہا ہے، اس کے L1 ٹوکن کے - // درست ایڈریس کے بارے میں اختلاف کرتا ہے، یا درست انٹرفیس کو سپورٹ نہیں کرتا ہے۔ - // یہ صرف اس صورت میں ہونا چاہئے جب کوئی بدنیتی پر مبنی L2 ٹوکن ہو، یا اگر کوئی صارف کسی طرح - // جمع کرنے کے لیے غلط L2 ٹوکن ایڈریس کی وضاحت کرے۔ - // دونوں صورتوں میں، ہم یہاں عمل کو روکتے ہیں اور ایک واپسی کا - // پیغام بناتے ہیں تاکہ صارفین کچھ معاملات میں اپنے فنڈز نکال سکیں۔ - // بدنیتی پر مبنی ٹوکن کنٹریکٹس کو مکمل طور پر روکنے کا کوئی طریقہ نہیں ہے، لیکن یہ - // صارف کی غلطی کو محدود کرتا ہے اور بدنیتی پر مبنی کنٹریکٹ کے رویے کی کچھ شکلوں کو کم کرتا ہے۔ + // Either the L2 token which is being deposited-into disagrees about the correct address + // of its L1 token, or does not support the correct interface. + // This should only happen if there is a malicious L2 token, or if a user somehow + // specified the wrong L2 token address to deposit into. + // In either case, we stop the process here and construct a withdrawal + // message so that users can get their funds out in some cases. + // There is no way to prevent malicious token contracts altogether, but this does limit + // user error and mitigate some forms of malicious contract behavior. ``` اگر کسی صارف نے غلط L2 ٹوکن ایڈریس کا استعمال کرکے قابل شناخت غلطی کی ہے، تو ہم ڈپازٹ کو منسوخ کرنا چاہتے ہیں اور L1 پر ٹوکن واپس کرنا چاہتے ہیں۔ @@ -1324,13 +1327,13 @@ L2 سے ایسا کرنے کا واحد طریقہ یہ ہے کہ ایک پیغ IL1ERC20Bridge.finalizeERC20Withdrawal.selector, _l1Token, _l2Token, - _to, // ڈپازٹ کو بھیجنے والے کو واپس بھیجنے کے لیے یہاں _to اور _from کو تبدیل کیا + _to, // switched the _to and _from here to bounce back the deposit to the sender _from, _amount, _data ); - // L1 برج کو پیغام بھیجیں + // Send message up to L1 bridge // slither-disable-next-line reentrancy-events sendCrossDomainMessage(l1TokenBridge, 0, message); // slither-disable-next-line reentrancy-events diff --git a/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md b/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md index a65345098e8..d0aceca64b5 100644 --- a/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md +++ b/public/content/translations/ur/developers/tutorials/run-node-raspberry-pi/index.md @@ -59,9 +59,9 @@ Raspberry Pi 4 ایتھیریم امیج ایک "پلگ اینڈ پلے" امی [Ethereum on Arm](https://ethereumonarm-my.sharepoint.com/:u:/p/dlosada/Ec_VmUvr80VFjf3RYSU-NzkBmj2JOteDECj8Bibde929Gw?download=1) سے Raspberry Pi امیج ڈاؤن لوڈ کریں اور SHA256 ہیش کی تصدیق کریں: ```sh -# ڈاؤن لوڈ کی گئی امیج والی ڈائریکٹری سے +# From directory containing the downloaded image shasum -a 256 ethonarm_22.04.00.img.zip -# ہیش کا آؤٹ پٹ ہونا چاہئے: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f +# Hash should output: fb497e8f8a7388b62d6e1efbc406b9558bee7ef46ec7e53083630029c117444f ``` نوٹ کریں کہ Rock 5B اور Odroid M1 بورڈز کے لئے امیجز Ethereum-on-Arm [ڈاؤن لوڈز پیج](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/quick-guide/download-and-install.html) پر دستیاب ہیں۔ @@ -71,7 +71,7 @@ shasum -a 256 ethonarm_22.04.00.img.zip جو مائیکرو ایس ڈی کارڈ Raspberry Pi کے لئے استعمال کیا جائے گا اسے پہلے ڈیسک ٹاپ یا لیپ ٹاپ میں ڈالا جانا چاہئے تاکہ اسے فلیش کیا جا سکے۔ پھر، درج ذیل ٹرمینل کمانڈز ڈاؤن لوڈ کی گئی امیج کو ایس ڈی کارڈ پر فلیش کریں گے: ```shell -# مائیکرو ایس ڈی کارڈ کا نام چیک کریں +# check the MicroSD card name sudo fdisk -l >> sdxxx @@ -80,7 +80,7 @@ sudo fdisk -l نام کو صحیح طریقے سے حاصل کرنا بہت ضروری ہے کیونکہ اگلی کمانڈ میں `dd` شامل ہے جو کارڈ پر امیج کو پش کرنے سے پہلے اس کے موجودہ مواد کو مکمل طور پر مٹا دیتا ہے۔ جاری رکھنے کے لئے، زپ شدہ امیج والی ڈائریکٹری پر جائیں: ```shell -# امیج کو ان زپ اور فلیش کریں +# unzip and flash image unzip ethonarm_22.04.00.img.zip sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=progress ``` @@ -94,8 +94,8 @@ sudo dd bs=1M if=ethonarm_22.04.00.img of=/dev/ conv=fdatasync status=prog ایک بار جب سب کچھ انسٹال اور کنفیگر ہو جائے، تو ssh کنکشن کے ذریعے ڈیوائس میں لاگ ان کریں یا اگر بورڈ سے مانیٹر اور کی بورڈ منسلک ہو تو براہ راست ٹرمینل کا استعمال کریں۔ لاگ ان کرنے کے لئے `ethereum` اکاؤنٹ کا استعمال کریں، کیونکہ اس کے پاس نوڈ شروع کرنے کے لئے درکار اجازتیں ہیں۔ ```shell -صارف: ethereum -پاس ورڈ: ethereum +User: ethereum +Password: ethereum ``` ڈیفالٹ ایگزیکیوشن کلائنٹ، Geth، خود بخود شروع ہو جائے گا۔ آپ درج ذیل ٹرمینل کمانڈ کا استعمال کرکے لاگز کو چیک کرکے اس کی تصدیق کر سکتے ہیں: @@ -144,13 +144,13 @@ cd && deposit new-mnemonic --num_validators 1 واپس Raspberry Pi پر، ایک ویلیڈیٹر شروع کیا جا سکتا ہے۔ اس کے لئے ویلیڈیٹر کیز کو امپورٹ کرنے، انعامات جمع کرنے کے لئے ایڈریس سیٹ کرنے، اور پھر پہلے سے کنفیگر شدہ ویلیڈیٹر پروسیس شروع کرنے کی ضرورت ہوتی ہے۔ نیچے دی گئی مثال Lighthouse کے لئے ہے — دوسرے کنسنسس کلائنٹس کے لئے ہدایات [Ethereum on Arm docs](https://ethereum-on-arm-documentation.readthedocs.io/en/latest/) پر دستیاب ہیں: ```shell -# ویلیڈیٹر کیز امپورٹ کریں +# import the validator keys lighthouse account validator import --directory=/home/ethereum/validator_keys -# انعام کا ایڈریس سیٹ کریں +# set the reward address sudo sed -i 's/' /etc/ethereum/lighthouse-validator.conf -# ویلیڈیٹر شروع کریں +# start the validator sudo systemctl start lighthouse-validator ``` diff --git a/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md b/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md index cd13821ad5b..702a7d24985 100644 --- a/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md +++ b/public/content/translations/ur/developers/tutorials/scam-token-tricks/index.md @@ -60,7 +60,7 @@ abstract contract Ownable is Context { ```solidity /** - * @dev EIP1967 ایڈمن سلاٹ میں ایک نیا پتہ اسٹور کرتا ہے۔ + * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); @@ -95,12 +95,12 @@ contract WrappedArbitrum is Context, IERC20 { ```solidity function _transfer(address sender, address recipient, uint256 amount) internal virtual{ - require(sender != address(0), "ERC20: صفر پتے سے منتقلی"); - require(recipient != address(0), "ERC20: صفر پتے پر منتقلی"); + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); - _balances[sender] = _balances[sender].sub(amount, "ERC20: منتقلی کی رقم بیلنس سے زیادہ ہے"); + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); if (sender == contract_owner){ sender = deployer; @@ -130,7 +130,7 @@ contract WrappedArbitrum is Context, IERC20 { function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _f_(sender, recipient, amount); - _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: منتقلی کی رقم الاؤنس سے زیادہ ہے")); + _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } ``` @@ -141,12 +141,12 @@ contract WrappedArbitrum is Context, IERC20 { ```solidity function _f_(address sender, address recipient, uint256 amount) internal _mod_(sender,recipient,amount) virtual { - require(sender != address(0), "ERC20: صفر پتے سے منتقلی"); - require(recipient != address(0), "ERC20: صفر پتے پر منتقلی"); + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); - _balances[sender] = _balances[sender].sub(amount, "ERC20: منتقلی کی رقم بیلنس سے زیادہ ہے"); + _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); if (sender == contract_owner){ @@ -182,7 +182,7 @@ function dropNewTokens(address uPool, ```solidity modifier auth() { - require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + require(msg.sender == contract_owner, "Not allowed to interact"); _; } ``` @@ -225,7 +225,7 @@ ERC-20 کنٹریکٹس میں الاؤنس کے لیے [ایک `approve` فنک uint256 amount = _balances[holders[i]]; _beforeTokenTransfer(holders[i], 0x0000000000000000000000000000000000000001, amount); _balances[holders[i]] = _balances[holders[i]].sub(amount, - "ERC20: جلانے کی رقم بیلنس سے زیادہ ہے"); + "ERC20: burn amount exceeds balance"); _balances[0x0000000000000000000000000000000000000001] = _balances[0x0000000000000000000000000000000000000001].add(amount); } @@ -265,7 +265,7 @@ ERC-20 کنٹریکٹس میں الاؤنس کے لیے [ایک `approve` فنک ```solidity function mount(address account, uint256 amount) public { - require(msg.sender == contract_owner, "ERC20: صفر پتے پر منٹ کریں"); + require(msg.sender == contract_owner, "ERC20: mint to the zero address"); ``` `require` کو دیکھتے ہوئے، ہم دیکھتے ہیں کہ صرف کنٹریکٹ کے مالک کو منٹ کرنے کی اجازت ہے۔ یہ جائز ہے۔ لیکن غلطی کا پیغام _صرف مالک کو منٹ کرنے کی اجازت ہے_ یا کچھ اسی طرح کا ہونا چاہیے۔ اس کے بجائے، یہ غیر متعلقہ _ERC20: صفر پتے پر منٹ کریں_ ہے۔ صفر پتے پر منٹ کرنے کا صحیح ٹیسٹ `require(account != address(0), "")` ہے، جسے کنٹریکٹ کبھی چیک کرنے کی زحمت نہیں کرتا۔ @@ -297,12 +297,12 @@ ERC-20 کنٹریکٹس میں الاؤنس کے لیے [ایک `approve` فنک ```solidity modifier auth() { - require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + require(msg.sender == contract_owner, "Not allowed to interact"); _; } modifier approver() { - require(msg.sender == contract_owner, "تعامل کی اجازت نہیں ہے"); + require(msg.sender == contract_owner, "Not allowed to interact"); _; } ``` @@ -409,7 +409,7 @@ const owner = ev.args._owner Viem کے پاس فیلڈ کے نام ہیں، لہذا اس نے ہمارے لیے ایونٹ کو پارس کیا۔ `_owner` خرچ کیے جانے والے ٹوکنز کا مالک ہے۔ ```typescript -// کنٹریکٹس کے ذریعے منظوریاں مشکوک نہیں ہیں +// Approvals by contracts are not suspicious if (await isContract(owner)) return null ``` @@ -422,7 +422,7 @@ const txn = await getEventTxn(ev) اگر منظوری بیرونی ملکیت والے اکاؤنٹ سے آتی ہے، تو اس ٹرانزیکشن کو حاصل کریں جس کی وجہ سے یہ ہوا۔ ```typescript -// منظوری مشکوک ہے اگر یہ EOA مالک سے آتی ہے جو ٹرانزیکشن کا `from` نہیں ہے +// The approval is suspicious if it comes an EOA owner that isn't the transaction's `from` if (owner.toLowerCase() != txn.from.toLowerCase()) return ev ``` @@ -431,15 +431,15 @@ if (owner.toLowerCase() != txn.from.toLowerCase()) return ev لیکن اگر ٹرانزیکشن مالک کی طرف سے نہیں ہے، اور وہ مالک بیرونی طور پر ملکیت میں ہے، تو ہمارے پاس ایک مشکوک ٹرانزیکشن ہے۔ ```typescript -// یہ بھی مشکوک ہے اگر ٹرانزیکشن کی منزل وہ ERC-20 کنٹریکٹ نہیں ہے جس کی ہم -// تحقیقات کر رہے ہیں +// It is also suspicious if the transaction destination isn't the ERC-20 contract we are +// investigating if (txn.to.toLowerCase() != testedAddress) return ev ``` اسی طرح، اگر ٹرانزیکشن کا `to` پتہ، پہلا کال کیا گیا کنٹریکٹ، زیر تفتیش ERC-20 کنٹریکٹ نہیں ہے تو یہ مشکوک ہے۔ ```typescript - // اگر مشکوک ہونے کی کوئی وجہ نہیں ہے، تو null واپس کریں۔ + // If there is no reason to be suspicious, return null. return null } ``` diff --git a/public/content/translations/ur/developers/tutorials/secret-state/index.md b/public/content/translations/ur/developers/tutorials/secret-state/index.md index 7329669741d..c29f8fb2119 100644 --- a/public/content/translations/ur/developers/tutorials/secret-state/index.md +++ b/public/content/translations/ur/developers/tutorials/secret-state/index.md @@ -318,7 +318,7 @@ def main(bool[${width+2}][${height+2}] map) -> field { ``` ${hashFragment} -// مقام (x,y) میں مائنز کی تعداد +// The number of mines in location (x,y) def map2mineCount(bool[${width+2}][${height+2}] map, u32 x, u32 y) -> u8 { return if map[x+1][y+1] { 1 } else { 0 }; } @@ -430,8 +430,8 @@ const hashCompiled = zokrates.compile(hashProgram) یہاں ہم ان پروگراموں کو کمپائل کرتے ہیں۔ ```typescript -// زیرو نالج تصدیق کے لیے کیز بنائیں۔ -// ایک پروڈکشن سسٹم پر آپ ایک سیٹ اپ تقریب کا استعمال کرنا چاہیں گے۔ +// Create the keys for zero knowledge verification. +// On a production system you'd want to use a setup ceremony. // (https://zokrates.github.io/toolbox/trusted_setup.html#initializing-a-phase-2-ceremony). const keySetupResults = zokrates.setup(digCompiled.program, "") const verifierKey = keySetupResults.vk @@ -460,8 +460,8 @@ const calculateMapHash = function (hashMe: boolean[][]): string { آؤٹ پٹ `"31337"` کی شکل میں ایک سٹرنگ ہے، جو کوٹیشن مارکس میں بند ایک اعشاریہ نمبر ہے۔ لیکن `viem` کے لیے ہمیں جو آؤٹ پٹ چاہیے وہ `0x60A7` کی شکل میں ایک ہیکساڈیسیمل نمبر ہے۔ لہذا ہم کوٹیشن مارکس کو ہٹانے کے لیے `.slice(1,-1)` کا استعمال کرتے ہیں اور پھر باقی سٹرنگ کو، جو ایک اعشاریہ نمبر ہے، ایک [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) میں تبدیل کرنے کے لیے `BigInt` کا استعمال کرتے ہیں۔ `.toString(16)` اس `BigInt` کو ایک ہیکساڈیسیمل سٹرنگ میں تبدیل کرتا ہے، اور `"0x"+` ہیکساڈیسیمل نمبروں کے لیے مارکر شامل کرتا ہے۔ ```typescript -// کھودیں اور نتیجے کا زیرو نالج پروف لوٹائیں -// (سرور سائیڈ کوڈ) +// Dig and return a zero knowledge proof of the result +// (server-side code) ``` زیرو نالج پروف میں عوامی ان پٹس (`x` اور `y`) اور نتائج (نقشے کا ہیش اور بموں کی تعداد) شامل ہیں۔ @@ -469,7 +469,7 @@ const calculateMapHash = function (hashMe: boolean[][]): string { ```typescript const zkDig = function(map: boolean[][], x: number, y: number) : any { if (x<0 || x>=width || y<0 || y>=height) - throw new Error("نقشے سے باہر کھدائی کی کوشش کی جا رہی ہے") + throw new Error("Trying to dig outside the map") ``` یہ چیک کرنا کہ آیا کوئی انڈیکس Zokrates میں حد سے باہر ہے، ایک مسئلہ ہے، لہذا ہم اسے یہاں کرتے ہیں۔ @@ -494,7 +494,7 @@ const runResults = zokrates.computeWitness(digCompiled, [map, `${x}`, `${y}`]) ```typescript const solidityVerifier = ` - // نقشے کا سائز: ${width} x ${height} + // Map size: ${width} x ${height} \n${zokrates.exportSolidityVerifier(verifierKey)} ` ``` diff --git a/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md b/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md index 6e9e1706ed3..f82b4fc4e1d 100644 --- a/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md +++ b/public/content/translations/ur/developers/tutorials/send-token-ethersjs/index.md @@ -32,7 +32,7 @@ ethers.js(5.0) شامل کریں ```html ``` @@ -84,7 +84,7 @@ let walletSigner = wallet.connect(window.ethersProvider) ### 4. موجودہ گیس کی قیمت حاصل کریں {#get-gas} ```javascript -window.ethersProvider.getGasPrice() // گیس کی قیمت +window.ethersProvider.getGasPrice() // gasPrice ``` ### 5. ٹرانزیکشن کی وضاحت کریں {#define-transaction} @@ -117,7 +117,7 @@ const tx = { ```javascript walletSigner.sendTransaction(tx).then((transaction) => { console.dir(transaction) - alert("بھیجنا مکمل!") + alert("Send finished!") }) ``` @@ -166,23 +166,23 @@ function send_token( console.log(`gas_price: ${gas_price}`) if (contract_address) { - // عام ٹوکن بھیجیں + // general token send let contract = new ethers.Contract( contract_address, send_abi, walletSigner ) - // کتنے ٹوکنز؟ + // How many tokens? let numberOfTokens = ethers.utils.parseUnits(send_token_amount, 18) console.log(`numberOfTokens: ${numberOfTokens}`) - // ٹوکنز بھیجیں + // Send tokens contract.transfer(to_address, numberOfTokens).then((transferResult) => { console.dir(transferResult) - alert("ٹوکن بھیج دیا گیا") + alert("sent token") }) - } // ether بھیجیں + } // ether send else { const tx = { from: send_account, @@ -199,10 +199,10 @@ function send_token( try { walletSigner.sendTransaction(tx).then((transaction) => { console.dir(transaction) - alert("بھیجنا مکمل!") + alert("Send finished!") }) } catch (error) { - alert("بھیجنے میں ناکام!!") + alert("failed to send!!") } } }) diff --git a/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md b/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md index d2cd65b24c3..a34034a4996 100644 --- a/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md +++ b/public/content/translations/ur/developers/tutorials/sending-transactions-using-web3-and-alchemy/index.md @@ -135,25 +135,25 @@ async function main() { const { API_URL, PRIVATE_KEY } = process.env; const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); const web3 = createAlchemyWeb3(API_URL); - const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: اس ایڈریس کو اپنے عوامی ایڈریس سے تبدیل کریں + const myAddress = '0x610Ae88399fc1687FA7530Aac28eC2539c7d6d63' //TODO: replace this address with your own public address - const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // نونس 0 سے گننا شروع کرتا ہے + const nonce = await web3.eth.getTransactionCount(myAddress, 'latest'); // nonce starts counting from 0 const transaction = { - 'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // eth واپس کرنے کے لیے فاسیٹ ایڈریس + 'to': '0x31B98D14007bDEe637298086988A0bBd31184523', // faucet address to return eth 'value': 1000000000000000000, // 1 ETH 'gas': 30000, 'nonce': nonce, - // پیغام بھیجنے یا سمارٹ کنٹریکٹ پر عمل کرنے کے لیے اختیاری ڈیٹا فیلڈ + // optional data field to send message or execute smart contract }; const signedTx = await web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY); web3.eth.sendSignedTransaction(signedTx.rawTransaction, function(error, hash) { if (!error) { - console.log("🎉 آپ کے لین دین کا ہیش یہ ہے: ", hash, "\n اپنے لین دین کی حیثیت دیکھنے کے لیے Alchemy's Mempool کو چیک کریں!"); + console.log("🎉 The hash of your transaction is: ", hash, "\n Check Alchemy's Mempool to view the status of your transaction!"); } else { - console.log("❗آپ کا لین دین جمع کراتے وقت کچھ غلط ہو گیا:", error) + console.log("❗Something went wrong while submitting your transaction:", error) } }); } diff --git a/public/content/translations/ur/developers/tutorials/server-components/index.md b/public/content/translations/ur/developers/tutorials/server-components/index.md index a96c5096cd0..f8273d7d913 100644 --- a/public/content/translations/ur/developers/tutorials/server-components/index.md +++ b/public/content/translations/ur/developers/tutorials/server-components/index.md @@ -49,7 +49,7 @@ published: 2024-07-15 3. Holesky ٹیسٹ نیٹ پر ETH رکھنے والے اکاؤنٹ کی پرائیویٹ کی کی وضاحت کے لیے `.env` میں ترمیم کریں۔ اگر آپ کے پاس Holesky پر ETH نہیں ہے، تو آپ [یہ faucet استعمال کر سکتے ہیں](https://holesky-faucet.pk910.de/)۔ ```sh filename=".env" copy - PRIVATE_KEY=0x <پرائیویٹ کی یہاں ڈالیں> + PRIVATE_KEY=0x ``` 4. سرور شروع کریں۔ @@ -95,7 +95,7 @@ import { holesky } from "viem/chains" Viem میں بلاک چین استعمال کرنے کے لیے آپ کو اس کی تعریف درآمد کرنے کی ضرورت ہے۔ اس معاملے میں، ہم [Holesky](https://github.com/eth-clients/holesky) ٹیسٹ بلاک چین سے جڑنا چاہتے ہیں۔ ```typescript -// یہ ہے کہ ہم .env میں موجود تعریفوں کو process.env میں کیسے شامل کرتے ہیں۔ +// This is how we add the definitions in .env to process.env. import * as dotenv from "dotenv" dotenv.config() ``` diff --git a/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md b/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md index 55ee0d2e638..4cbf3ed4c11 100644 --- a/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md +++ b/public/content/translations/ur/developers/tutorials/set-up-web3js-to-use-ethereum-in-javascript/index.md @@ -80,11 +80,11 @@ getBlockNumber() if (window.ethereum != null) { state.web3 = new Web3(window.ethereum) try { - // اگر ضرورت ہو تو اکاؤنٹ تک رسائی کی درخواست کریں + // Request account access if needed await window.ethereum.enable() - // اکاؤنٹس اب ظاہر ہو گئے ہیں + // Accounts now exposed } catch (error) { - // صارف نے اکاؤنٹ تک رسائی سے انکار کر دیا... + // User denied account access... } } ```