From b15910ff491677cd4937ff3bc9affa1fda17aa64 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:13:30 +0000 Subject: [PATCH 1/9] i18n(mr): translation import part 04 of 13 (23 files) --- .../web3-secret-storage/index.md | 195 +++++++++++ .../dex-design-best-practice/index.md | 219 ++++++++++++ .../heuristics-for-web3/index.md | 138 ++++++++ .../mr/developers/docs/design-and-ux/index.md | 86 +++++ .../docs/development-networks/index.md | 71 ++++ .../developers/docs/ethereum-stack/index.md | 61 ++++ .../mr/developers/docs/evm/index.md | 88 +++++ .../mr/developers/docs/evm/opcodes/index.md | 177 ++++++++++ .../mr/developers/docs/frameworks/index.md | 156 +++++++++ .../mr/developers/docs/gas/index.md | 151 +++++++++ .../mr/developers/docs/ides/index.md | 64 ++++ .../translations/mr/developers/docs/index.md | 25 ++ .../developers/docs/intro-to-ether/index.md | 78 +++++ .../docs/intro-to-ethereum/index.md | 124 +++++++ .../mr/developers/docs/mev/index.md | 221 ++++++++++++ .../developers/docs/networking-layer/index.md | 163 +++++++++ .../network-addresses/index.md | 39 +++ .../networking-layer/portal-network/index.md | 89 +++++ .../mr/developers/docs/networks/index.md | 216 ++++++++++++ .../nodes-and-clients/archive-nodes/index.md | 81 +++++ .../docs/nodes-and-clients/bootnodes/index.md | 31 ++ .../client-diversity/index.md | 132 ++++++++ .../docs/nodes-and-clients/index.md | 319 ++++++++++++++++++ 23 files changed, 2924 insertions(+) create mode 100644 public/content/translations/mr/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md create mode 100644 public/content/translations/mr/developers/docs/design-and-ux/dex-design-best-practice/index.md create mode 100644 public/content/translations/mr/developers/docs/design-and-ux/heuristics-for-web3/index.md create mode 100644 public/content/translations/mr/developers/docs/design-and-ux/index.md create mode 100644 public/content/translations/mr/developers/docs/development-networks/index.md create mode 100644 public/content/translations/mr/developers/docs/ethereum-stack/index.md create mode 100644 public/content/translations/mr/developers/docs/evm/index.md create mode 100644 public/content/translations/mr/developers/docs/evm/opcodes/index.md create mode 100644 public/content/translations/mr/developers/docs/frameworks/index.md create mode 100644 public/content/translations/mr/developers/docs/gas/index.md create mode 100644 public/content/translations/mr/developers/docs/ides/index.md create mode 100644 public/content/translations/mr/developers/docs/index.md create mode 100644 public/content/translations/mr/developers/docs/intro-to-ether/index.md create mode 100644 public/content/translations/mr/developers/docs/intro-to-ethereum/index.md create mode 100644 public/content/translations/mr/developers/docs/mev/index.md create mode 100644 public/content/translations/mr/developers/docs/networking-layer/index.md create mode 100644 public/content/translations/mr/developers/docs/networking-layer/network-addresses/index.md create mode 100644 public/content/translations/mr/developers/docs/networking-layer/portal-network/index.md create mode 100644 public/content/translations/mr/developers/docs/networks/index.md create mode 100644 public/content/translations/mr/developers/docs/nodes-and-clients/archive-nodes/index.md create mode 100644 public/content/translations/mr/developers/docs/nodes-and-clients/bootnodes/index.md create mode 100644 public/content/translations/mr/developers/docs/nodes-and-clients/client-diversity/index.md create mode 100644 public/content/translations/mr/developers/docs/nodes-and-clients/index.md diff --git a/public/content/translations/mr/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md b/public/content/translations/mr/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md new file mode 100644 index 00000000000..f4cf8d5ed21 --- /dev/null +++ b/public/content/translations/mr/developers/docs/data-structures-and-encoding/web3-secret-storage/index.md @@ -0,0 +1,195 @@ +--- +title: "Web3 गुप्त स्टोरेजची व्याख्या" +description: "web3 गुप्त स्टोरेजची औपचारिक व्याख्या" +lang: mr +sidebarDepth: 2 +--- + +तुमचा ॲप Ethereum वर काम करण्यासाठी, तुम्ही web3.js लायब्ररीद्वारे प्रदान केलेला web3 ऑब्जेक्ट वापरू शकता. आतल्या बाजूला ते RPC कॉलद्वारे स्थानिक नोडशी संवाद साधते. [web3](https://github.com/ethereum/web3.js/) कोणत्याही Ethereum नोडसोबत काम करते जे RPC लेयर उघड करते. + +`web3` मध्ये `eth` ऑब्जेक्ट आहे - web3.eth. + +```js +var fs = require("fs") +var recognizer = require("ethereum-keyfile-recognizer") + +fs.readFile("keyfile.json", (err, data) => { + var json = JSON.parse(data) + var result = recognizer(json) +}) + +/** परिणाम + * [ 'web3', 3 ] web3 (v3) कीफाइल + * [ 'ethersale', undefined ] Ethersale कीफाइल + * null अवैध कीफाइल + */ +``` + +हे दस्तऐवज Web3 गुप्त स्टोरेज व्याख्येच्या **आवृत्ती 3** चे वर्णन करते. + +## व्याख्या {#definition} + +फाईलचे प्रत्यक्ष एन्कोडिंग आणि डीकोडिंग आवृत्ती 1 पासून मोठ्या प्रमाणात अपरिवर्तित आहे, फक्त क्रिप्टो अल्गोरिदम आता AES-128-CBC पर्यंत मर्यादित नाही (AES-128-CTR ही आता किमान आवश्यकता आहे). बहुतेक अर्थ/अल्गोरिदम आवृत्ती 1 प्रमाणेच आहेत, `mac` वगळता, जे `ciphertext` सह साधित की च्या दुसऱ्या-डावीकडील 16 बाइट्सच्या एकत्रिकरणाचे SHA3 (keccak-256) म्हणून दिले जाते. + +गुप्त की फाइल्स थेट `~/.web3/keystore` (Unix-सारख्या प्रणालींसाठी) आणि `~/AppData/Web3/keystore` (Windows साठी) मध्ये साठवल्या जातात. त्यांना कोणतेही नाव दिले जाऊ शकते, परंतु एक चांगला संकेत म्हणजे `.json`, जिथे `` हा गुप्त की ला दिलेला 128-बिट UUID आहे (गुप्त की च्या ॲड्रेससाठी गोपनीयता-संरक्षक प्रॉक्सी). + +अशा सर्व फाइल्सना एक संबंधित पासवर्ड असतो. दिलेल्या `.json` फाइलची गुप्त की मिळवण्यासाठी, प्रथम फाइलची एन्क्रिप्शन की मिळवा; हे फाइलचा पासवर्ड घेऊन आणि `kdf` की द्वारे वर्णन केल्यानुसार की डेरिवेशन फंक्शनमधून पास करून केले जाते. KDF फंक्शनसाठी KDF-अवलंबित स्थिर आणि डायनॅमिक पॅरामीटर्सचे वर्णन `kdfparams` की मध्ये केले आहे. + +PBKDF2 ला सर्व किमान-अनुरूप अंमलबजावणीद्वारे समर्थित करणे आवश्यक आहे, जे खालीलप्रमाणे दर्शविले आहे: + +- `kdf`: `pbkdf2` + +PBKDF2 साठी, kdfparams मध्ये समाविष्ट आहे: + +- `prf`: `hmac-sha256` असणे आवश्यक आहे (भविष्यात वाढवले जाऊ शकते); +- `c`: पुनरावृत्तींची संख्या; +- `salt`: PBKDF ला पास केलेला सॉल्ट; +- `dklen`: साधित की साठी लांबी. >= 32 असणे आवश्यक आहे. + +एकदा फाईलची की मिळवल्यानंतर, MAC च्या डेरिवेशनद्वारे त्याची पडताळणी केली पाहिजे. MAC ची गणना साधित की च्या दुसऱ्या-डावीकडील 16 बाइट्स आणि `ciphertext` की च्या सामग्रीच्या एकत्रिकरणाने तयार झालेल्या बाइट ॲरेच्या SHA3 (keccak-256) हॅश म्हणून केली पाहिजे, म्हणजे: + +```js +KECCAK(DK[16..31] ++ ) +``` + +(जिथे `++` हा कॉनकेटिनेशन ऑपरेटर आहे) + +या मूल्याची तुलना `mac` की च्या सामग्रीशी केली पाहिजे; जर ते वेगळे असतील, तर पर्यायी पासवर्डची विनंती केली पाहिजे (किंवा ऑपरेशन रद्द केले पाहिजे). + +फाईलच्या कीची पडताळणी केल्यानंतर, सिफर टेक्स्ट (`ciphertext` की फाईलमध्ये) `cipher` की द्वारे निर्दिष्ट सिमेट्रिक एन्क्रिप्शन अल्गोरिदम वापरून आणि `cipherparams` की द्वारे पॅरामेटराइज करून डिक्रिप्ट केले जाऊ शकते. जर साधित की चा आकार आणि अल्गोरिदमच्या कीचा आकार जुळत नसेल, तर साधित की चे शून्य पॅडेड, उजवीकडील बाइट्स अल्गोरिदमची की म्हणून वापरले पाहिजेत. + +सर्व किमान-अनुरूप अंमलबजावणीने AES-128-CTR अल्गोरिदमला समर्थन दिले पाहिजे, जे खालीलप्रमाणे दर्शविले आहे: + +- `cipher: aes-128-ctr` + +हे सिफर खालील पॅरामीटर्स घेते, जे cipherparams की साठी की म्हणून दिले जातात: + +- `iv`: सिफरसाठी 128-बिट इनिशियलायझेशन वेक्टर. + +सिफरसाठी की ही साधित की चे डावीकडील 16 बाइट्स आहेत, म्हणजे `DK[0..15]` + +गुप्त कीची निर्मिती/एन्क्रिप्शन मूलतः या सूचनांच्या उलट असावी. `uuid`, `salt` आणि `iv` खरोखरच यादृच्छिक असल्याची खात्री करा. + +`version` फील्ड व्यतिरिक्त, जे आवृत्तीचे "हार्ड" ओळखकर्ता म्हणून काम केले पाहिजे, अंमलबजावणी स्वरूपातील लहान, नॉन-ब्रेकिंग बदलांचा मागोवा घेण्यासाठी `minorversion` देखील वापरू शकतात. + +## चाचणी व्हेक्टर्स {#test-vectors} + +तपशील: + +- `ॲड्रेस`: `008aeeda4d805471df9b2a5b0f38a0c3bcba786b` +- `ICAP`: `XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67` +- `UUID`: `3198bc9c-6672-5ab3-d9954942343ae5b6` +- `पासवर्ड`: `testpassword` +- `गुप्त`: `7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d` + +### PBKDF2-SHA-256 {#PBKDF2-SHA-256} + +`AES-128-CTR` आणि `PBKDF2-SHA-256` वापरून चाचणी व्हेक्टर: + +`~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json` ची फाइल सामग्री: + +```json +{ + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "6087dab2f9fdbbfaddc31a909735c1e6" + }, + "ciphertext": "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", + "kdf": "pbkdf2", + "kdfparams": { + "c": 262144, + "dklen": 32, + "prf": "hmac-sha256", + "salt": "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd" + }, + "mac": "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2" + }, + "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6", + "version": 3 +} +``` + +**मध्यस्थ**: + +`साधित की`: `f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551` +`MAC बॉडी`: `e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46` +`MAC`: `517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2` +`सिफर की`: `f06d69cdc7da0faffb1008270bca38f5` + +### Scrypt {#scrypt} + +AES-128-CTR आणि Scrypt वापरून चाचणी व्हेक्टर: + +```json +{ + "crypto": { + "cipher": "aes-128-ctr", + "cipherparams": { + "iv": "740770fce12ce862af21264dab25f1da" + }, + "ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2", + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034" + }, + "mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c" + }, + "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6", + "version": 3 +} +``` + +**मध्यस्थ**: + +`साधित की`: `7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d` +`MAC बॉडी`: `edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2` +`MAC`: `337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c` +`सिफर की`: `7446f59ecc301d2d79bc3302650d8a5c` + +## आवृत्ती 1 मधील बदल {#alterations-from-v2} + +ही आवृत्ती [येथे](https://github.com/ethereum/homestead-guide/blob/master/old-docs-for-reference/go-ethereum-wiki.rst/Passphrase-protected-key-store-spec.rst) प्रकाशित आवृत्ती 1 मधील अनेक विसंगती दूर करते. थोडक्यात ते खालीलप्रमाणे आहेत: + +- कॅपिटलायझेशन अयोग्य आणि विसंगत आहे (scrypt लोअरकेस, Kdf मिक्स्ड-केस, MAC अप्परकेस). +- ॲड्रेस अनावश्यक आहे आणि गोपनीयतेशी तडजोड करतो. +- `Salt` हे मूलतः की डेरिवेशन फंक्शनचे एक पॅरामीटर आहे आणि ते त्याच्याशी संबंधित असले पाहिजे, सर्वसाधारणपणे क्रिप्टोशी नाही. +- _SaltLen_ अनावश्यक (फक्त Salt पासून मिळवा). +- की डेरिवेशन फंक्शन दिले आहे, तरीही क्रिप्टो अल्गोरिदम हार्ड स्पेसिफाइड आहे. +- `Version` हे मूलतः अंकीय आहे तरीही एक स्ट्रिंग आहे (स्ट्रिंगसह संरचित आवृत्ती शक्य आहे, परंतु क्वचितच बदलणाऱ्या कॉन्फिगरेशन फाइल स्वरूपासाठी कार्यक्षेत्राबाहेर मानले जाऊ शकते). +- `KDF` आणि `cipher` या संकल्पना काल्पनिकदृष्ट्या एकसारख्या आहेत तरीही त्या वेगवेगळ्या प्रकारे आयोजित केल्या आहेत. +- `MAC` ची गणना एका व्हाइटस्पेस अज्ञेयवादी डेटाच्या तुकड्याद्वारे केली जाते(!) + +पूर्वी लिंक केलेल्या पृष्ठावरील उदाहरणाप्रमाणे कार्यात्मकदृष्ट्या समतुल्य असलेली खालील फाइल देण्यासाठी स्वरूपात बदल केले गेले आहेत: + +```json +{ + "crypto": { + "cipher": "aes-128-cbc", + "ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b", + "cipherparams": { + "iv": "16d67ba0ce5a339ff2f07951253e6ba8" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91" + }, + "mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd", + "version": 1 + }, + "id": "0498f19a-59db-4d54-ac95-33901b4f1870", + "version": 2 +} +``` + +## आवृत्ती 2 मधील बदल {#alterations-from-v2} + +आवृत्ती 2 ही अनेक बग्ससह एक सुरुवातीची C++ अंमलबजावणी होती. त्यातील सर्व आवश्यक गोष्टी अपरिवर्तित आहेत. diff --git a/public/content/translations/mr/developers/docs/design-and-ux/dex-design-best-practice/index.md b/public/content/translations/mr/developers/docs/design-and-ux/dex-design-best-practice/index.md new file mode 100644 index 00000000000..43c2311516c --- /dev/null +++ b/public/content/translations/mr/developers/docs/design-and-ux/dex-design-best-practice/index.md @@ -0,0 +1,219 @@ +--- +title: "विकेंद्रित एक्सचेंज (DEX) डिझाइनमधील सर्वोत्तम पद्धती" +description: "टोकन्स स्वॅप करण्यासाठी UX/UI निर्णयांचे स्पष्टीकरण देणारे मार्गदर्शक." +lang: mr +--- + +2018 मध्ये Uniswap च्या लाँचपासून, अनेक वेगवेगळ्या चेन्सवर शेकडो विकेंद्रित एक्सचेंज लाँच झाले आहेत. +यापैकी अनेकांनी नवीन घटक सादर केले किंवा स्वतःचा ट्विस्ट जोडला, परंतु इंटरफेस सामान्यतः तसाच राहिला आहे. + +याचे एक कारण [जेकबचा नियम](https://lawsofux.com/jakobs-law/) आहे: + +> वापरकर्ते आपला बहुतेक वेळ इतर साइट्सवर घालवतात. याचा अर्थ असा की वापरकर्त्यांना तुमची साइट त्यांना आधीच माहीत असलेल्या इतर सर्व साइट्सप्रमाणेच काम करणे पसंत आहे. + +Uniswap, Pancakeswap आणि Sushiswap सारख्या सुरुवातीच्या इनोव्हेटर्समुळे, DeFi वापरकर्त्यांना DEX कसा दिसतो याची एक सामूहिक कल्पना आहे. +या कारणास्तव, "सर्वोत्तम पद्धत" सारखे काहीतरी आता उदयास येत आहे. आम्ही पाहतो की अधिकाधिक डिझाइन निर्णय साइट्सवर प्रमाणित केले जात आहेत. तुम्ही DEXes च्या उत्क्रांतीला थेट चाचणीचे एक मोठे उदाहरण म्हणून पाहू शकता. ज्या गोष्टींनी काम केले त्या राहिल्या, ज्यांनी नाही केले त्या बाहेर फेकल्या गेल्या. व्यक्तिमत्त्वासाठी अजूनही जागा आहे, परंतु काही विशिष्ट मानके आहेत ज्यांचे पालन DEX ने केले पाहिजे. + +हा लेख खालील गोष्टींचा सारांश आहे: + +- काय समाविष्ट करावे +- ते शक्य तितके वापरण्यायोग्य कसे बनवायचे +- डिझाइन सानुकूलित करण्याचे मुख्य मार्ग + +सर्व उदाहरण वायरफ्रेम विशेषतः या लेखासाठी बनवले गेले होते, जरी ते सर्व वास्तविक प्रकल्पांवर आधारित असले तरी. + +फिग्मा किट देखील तळाशी समाविष्ट आहे - ते वापरण्यास मोकळ्या मनाने आणि आपल्या स्वतःच्या वायरफ्रेम्सला गती द्या! + +## DEX ची मूलभूत रचना {#basic-anatomy-of-a-dex} + +UI मध्ये साधारणपणे तीन घटक असतात: + +1. मुख्य फॉर्म +2. बटण +3. तपशील पॅनेल + +![जेनेरिक DEX UI, तीन मुख्य घटक दर्शविते](./1.png) + +## फरक {#variations} + +या लेखात ही एक सामान्य थीम असेल, परंतु हे घटक आयोजित करण्याचे विविध मार्ग आहेत. "तपशील पॅनेल" असू शकते: + +- बटणाच्या वर +- बटणाच्या खाली +- एकॉर्डियन पॅनेलमध्ये लपवलेले +- आणि/किंवा “पूर्वावलोकन” मोडलवर + +एन.बी. एक “पूर्वावलोकन” मोडल पर्यायी आहे, परंतु तुम्ही मुख्य UI वर खूप कमी तपशील दाखवत असाल तर ते आवश्यक बनते. + +## मुख्य फॉर्मची रचना {#structure-of-the-main-form} + +हा तो बॉक्स आहे जिथे तुम्ही प्रत्यक्षात कोणते टोकन स्वॅप करायचे आहे ते निवडता. घटकामध्ये एका ओळीत इनपुट फील्ड आणि एक लहान बटण असते. + +DEXes सामान्यतः एका ओळीच्या वर आणि एका ओळीच्या खाली अतिरिक्त तपशील प्रदर्शित करतात, जरी हे वेगळ्या प्रकारे कॉन्फिगर केले जाऊ शकते. + +![इनपुट ओळ, वर आणि खाली तपशील ओळीसह](./2.png) + +## फरक {#variations2} + +येथे दोन UI भिन्नता दर्शविल्या आहेत; एक कोणत्याही सीमांशिवाय, एक अतिशय खुले डिझाइन तयार करते आणि एक जिथे इनपुट ओळीला एक सीमा आहे, त्या घटकावर लक्ष केंद्रित करते. + +![मुख्य फॉर्मच्या दोन UI भिन्नता](./3.png) + +ही मूलभूत रचना डिझाइनमध्ये **माहितीचे चार मुख्य भाग** दाखवण्याची परवानगी देते: प्रत्येक कोपऱ्यात एक. फक्त एक वरची/खालची ओळ असल्यास, फक्त दोन जागा आहेत. + +DeFi च्या उत्क्रांती दरम्यान, येथे अनेक वेगवेगळ्या गोष्टी समाविष्ट केल्या गेल्या आहेत. + +## समाविष्ट करण्यासाठी मुख्य माहिती {#key-info-to-include} + +- वॉलेटमधील शिल्लक +- कमाल बटण +- फियाट समतुल्य +- मिळणाऱ्या रकमेवर किंमतीचा प्रभाव + +DeFi च्या सुरुवातीच्या दिवसांमध्ये, फियाट समतुल्य अनेकदा गहाळ होते. तुम्ही कोणत्याही प्रकारचा Web3 प्रकल्प तयार करत असाल, तर फियाट समतुल्य दर्शवणे आवश्यक आहे. वापरकर्ते अजूनही स्थानिक चलनांच्या बाबतीत विचार करतात, म्हणून वास्तविक जगाच्या मानसिक मॉडेल्सशी जुळण्यासाठी, हे समाविष्ट केले पाहिजे. + +दुसऱ्या फील्डवर (जिथे तुम्ही स्वॅप करत असलेले टोकन निवडता) तुम्ही इनपुट रक्कम आणि अंदाजित आउटपुट रकमांमधील फरक मोजून फियाट चलन रकमेच्या पुढे किमतीचा परिणाम देखील समाविष्ट करू शकता. हा समाविष्ट करण्यासाठी एक उपयुक्त तपशील आहे. + +टक्केवारी बटणे (उदा., 25%, 50%, 75%) एक उपयुक्त वैशिष्ट्य असू शकतात, परंतु ते अधिक जागा घेतात, अधिक कॉल टू अॅक्शन जोडतात आणि अधिक मानसिक भार टाकतात. टक्केवारी स्लाइडर्सचेही तसेच आहे. यापैकी काही UI निर्णय तुमच्या ब्रँड आणि तुमच्या वापरकर्ता प्रकारावर अवलंबून असतील. + +अतिरिक्त तपशील मुख्य फॉर्मच्या खाली दर्शविले जाऊ शकतात. या प्रकारची माहिती बहुतेक प्रो वापरकर्त्यांसाठी असल्याने, हे करणे अर्थपूर्ण आहे: + +- ते शक्य तितके कमी ठेवा, किंवा; +- ते एकॉर्डियन पॅनेलमध्ये लपवा + +![मुख्य फॉर्मच्या कोपऱ्यात दर्शविलेले तपशील](./4.png) + +## समाविष्ट करण्यासाठी अतिरिक्त माहिती {#extra-info-to-include} + +- टोकन किंमत +- स्लिपेज +- किमान प्राप्त +- अपेक्षित आउटपुट +- किंमतीचा प्रभाव +- गॅस खर्चाचा अंदाज +- इतर शुल्क +- ऑर्डर रूटिंग + +वादग्रस्तपणे, यापैकी काही तपशील पर्यायी असू शकतात. + +ऑर्डर रूटिंग मनोरंजक आहे, परंतु बहुतेक वापरकर्त्यांसाठी फारसा फरक पडत नाही. + +काही इतर तपशील फक्त तीच गोष्ट वेगवेगळ्या प्रकारे पुन्हा सांगतात. उदाहरणार्थ, "किमान प्राप्त" आणि "स्लिपेज" हे एकाच नाण्याच्या दोन बाजू आहेत. तुमचे स्लिपेज 1% वर सेट असल्यास, तुम्हाला मिळणारी किमान अपेक्षित रक्कम = अपेक्षित आउटपुट - 1%. काही UI अपेक्षित रक्कम, किमान रक्कम आणि स्लिपेज दाखवतील... जे उपयुक्त आहे पण कदाचित अनावश्यक आहे. + +बहुतेक वापरकर्ते तरीही डीफॉल्ट स्लिपेज ठेवतील. + +"किंमत परिणाम" अनेकदा "to" फील्डमध्ये फियाट समतुल्यच्या पुढे कंसात दर्शविला जातो. हा जोडण्यासाठी एक उत्तम ux तपशील आहे, परंतु जर तो येथे दर्शविला असेल तर तो खाली पुन्हा दाखवण्याची खरोखर गरज आहे का? आणि मग पुन्हा पूर्वावलोकन स्क्रीनवर? + +अनेक वापरकर्ते (विशेषतः जे कमी प्रमाणात स्वॅप करतात) या तपशीलांची पर्वा करणार नाहीत; ते फक्त एक संख्या टाकतील आणि स्वॅप दाबतील. + +![काही तपशील तीच गोष्ट दाखवतात](./5.png) + +नेमके कोणते तपशील दाखवले जातील हे तुमच्या प्रेक्षक आणि तुम्हाला अॅपमध्ये कोणत्या प्रकारची भावना हवी आहे यावर अवलंबून असेल. + +तुम्ही तपशील पॅनेलमध्ये स्लिपेज टॉलरन्स समाविष्ट केल्यास, तुम्ही ते थेट येथून संपादन करण्यायोग्य देखील बनवले पाहिजे. हे "एक्सेलेटर" चे एक चांगले उदाहरण आहे; एक सुबक UX युक्ती जी अॅपच्या सामान्य उपयोगितेवर परिणाम न करता अनुभवी वापरकर्त्यांच्या प्रवाहांना गती देऊ शकते. + +![तपशील पॅनेलमधून स्लिपेज नियंत्रित केले जाऊ शकते](./6.png) + +एका स्क्रीनवरील केवळ एका विशिष्ट माहितीबद्दलच नव्हे, तर संपूर्ण प्रवाहाबद्दल काळजीपूर्वक विचार करणे ही एक चांगली कल्पना आहे: मुख्य फॉर्ममध्ये संख्या प्रविष्ट करणे → तपशील स्कॅन करणे → पूर्वावलोकन स्क्रीनवर क्लिक करणे (तुमच्याकडे पूर्वावलोकन स्क्रीन असल्यास). +तपशील पॅनेल नेहमी दृश्यमान असावे की वापरकर्त्याला ते विस्तारित करण्यासाठी क्लिक करणे आवश्यक आहे? +तुम्ही पूर्वावलोकन स्क्रीन जोडून घर्षण निर्माण करावे का? हे वापरकर्त्याला हळू करण्यास आणि त्यांच्या व्यापाराचा विचार करण्यास भाग पाडते, जे उपयुक्त असू शकते. पण त्यांना पुन्हा तीच सर्व माहिती बघायची आहे का? या क्षणी त्यांच्यासाठी सर्वात उपयुक्त काय आहे? + +## डिझाइन पर्याय {#design-options} + +नमूद केल्याप्रमाणे, यापैकी बरेच काही तुमच्या वैयक्तिक शैलीवर अवलंबून असते +तुमचा वापरकर्ता कोण आहे? +तुमचा ब्रँड कोणता आहे? +तुम्हाला प्रत्येक तपशील दाखवणारा “प्रो” इंटरफेस हवा आहे की तुम्हाला मिनिमलिस्ट व्हायचे आहे? +जरी तुम्ही सर्व शक्य माहिती हवी असलेल्या प्रो वापरकर्त्यांना लक्ष्य करत असाल, तरीही तुम्हाला ॲलन कूपरचे शहाणपणाचे शब्द लक्षात ठेवले पाहिजेत: + +> तुमचा इंटरफेस कितीही सुंदर असो, कितीही छान असो, तो कमी असता तर बरे झाले असते. + +### रचना {#structure} + +- डावीकडे टोकन किंवा उजवीकडे टोकन +- 2 ओळी किंवा 3 +- बटणाच्या वर किंवा खाली तपशील +- तपशील विस्तृत, लहान केलेले किंवा न दर्शवलेले + +### घटक शैली {#component-style} + +- रिकामे +- बाह्यरेखित +- भरलेले + +केवळ UX च्या दृष्टिकोनातून, UI शैली तुम्हाला वाटते त्यापेक्षा कमी महत्त्वाची आहे. दृष्य ट्रेंड चक्रात येतात आणि जातात, आणि बरीचशी पसंती व्यक्तिनिष्ठ असते. + +याची अनुभूती घेण्याचा - आणि विविध भिन्न कॉन्फिगरेशनबद्दल विचार करण्याचा सर्वात सोपा मार्ग म्हणजे काही उदाहरणे पाहणे आणि नंतर स्वतः काही प्रयोग करणे. + +समाविष्ट फिग्मा किटमध्ये रिकामे, बाह्यरेखित आणि भरलेले घटक आहेत. + +हे सर्व एकत्र ठेवण्याचे वेगवेगळे मार्ग पाहण्यासाठी खालील उदाहरणे पहा: + +![भरलेल्या शैलीमध्ये 3 ओळी](./7.png) + +![बाह्यरेखित शैलीमध्ये 3 ओळी](./8.png) + +![रिकाम्या शैलीमध्ये 2 ओळी](./9.png) + +![बाह्यरेखित शैलीमध्ये 3 ओळी, तपशील पॅनेलसह](./10.png) + +![बाह्यरेखित शैलीमध्ये इनपुट ओळीसह 3 ओळी](./11.png) + +![भरलेल्या शैलीमध्ये 2 ओळी](./12.png) + +## पण टोकन कोणत्या बाजूला जावे? {#but-which-side-should-the-token-go-on} + +मुख्य गोष्ट अशी आहे की यामुळे उपयोगितेवर फारसा फरक पडण्याची शक्यता नाही. तथापि, काही गोष्टी लक्षात ठेवण्यासारख्या आहेत, ज्या तुम्हाला एका किंवा दुसऱ्या मार्गावर प्रभावित करू शकतात. + +वेळेनुसार फॅशनमध्ये बदल पाहणे थोडे मनोरंजक आहे. Uniswap ने सुरुवातीला टोकन डावीकडे ठेवले होते, परंतु नंतर ते उजवीकडे हलवले. Sushiswap ने देखील डिझाइन अपग्रेड दरम्यान हा बदल केला. सर्व नाही, पण बहुतेक प्रोटोकॉल्सने त्याचे अनुकरण केले आहे. + +आर्थिक संकेतांनुसार पारंपारिकपणे चलन चिन्ह संख्येच्या आधी ठेवले जाते, उदा., $50, €50, £50, परंतु आपण 50 डॉलर्स, 50 युरो, 50 पाउंड असे _म्हणतो_. + +सर्वसाधारण वापरकर्त्याला - विशेषतः जो डावीकडून उजवीकडे, वरपासून खालपर्यंत वाचतो - उजवीकडील टोकन अधिक नैसर्गिक वाटू शकते. + +![डावीकडे टोकन असलेला UI](./13.png) + +डावीकडे टोकन आणि उजवीकडे सर्व संख्या ठेवणे आनंददायक सममित दिसते, जे एक प्लस आहे, परंतु या लेआउटमध्ये आणखी एक तोटा आहे. + +सान्निध्याचा नियम सांगतो की जवळ असलेल्या वस्तू संबंधित म्हणून समजल्या जातात. त्यानुसार, आम्हाला संबंधित वस्तू एकमेकांच्या शेजारी ठेवायच्या आहेत. टोकन शिल्लक थेट टोकनशी संबंधित आहे, आणि जेव्हा नवीन टोकन निवडले जाते तेव्हा ते बदलेल. म्हणून, टोकन शिल्लक टोकन निवड बटणाच्या पुढे असणे थोडे अधिक अर्थपूर्ण आहे. ते टोकनच्या खाली हलवले जाऊ शकते, परंतु ते लेआउटची सममिती मोडते. + +शेवटी, दोन्ही पर्यायांसाठी प्लस आणि मायनस आहेत, परंतु उजवीकडील टोकनकडे कल कसा दिसतो हे मनोरंजक आहे. + +## बटणाचे वर्तन {#button-behavior} + +Approve साठी वेगळे बटण ठेवू नका. Approve साठी वेगळा क्लिक देखील ठेवू नका. वापरकर्त्याला स्वॅप करायचे आहे, म्हणून बटणावर फक्त “स्वॅप” म्हणा आणि पहिली पायरी म्हणून मंजुरी सुरू करा. एक मोडल स्टेपरसह प्रगती दर्शवू शकतो, किंवा एक साधे “tx 1 of 2 - approving” सूचना. + +![approve आणि swap साठी वेगळ्या बटणांसह UI](./14.png) + +![approve असे लिहिलेले एक बटण असलेले UI](./15.png) + +### संदर्भानुसार मदतीसाठी बटण {#button-as-contextual-help} + +बटण अलर्ट म्हणून दुहेरी कर्तव्य करू शकते! + +हे खरेतर Web3 बाहेर एक असामान्य डिझाइन पॅटर्न आहे, परंतु त्याच्या आत ते मानक बनले आहे. ही एक चांगली नवकल्पना आहे कारण ती जागा वाचवते आणि लक्ष केंद्रित ठेवते. + +जर मुख्य क्रिया - SWAP - त्रुटीमुळे अनुपलब्ध असेल, तर कारण बटणासह स्पष्ट केले जाऊ शकते, उदा: + +- नेटवर्क स्विच करा +- वॉलेट कनेक्ट करा +- विविध त्रुटी + +बटण **आवश्यक असलेल्या कृतीसाठी मॅप** केले जाऊ शकते. उदाहरणार्थ, वापरकर्ता चुकीच्या नेटवर्कवर असल्यामुळे स्वॅप करू शकत नसल्यास, बटणावर "Ethereum वर स्विच करा" असे लिहिलेले असावे आणि जेव्हा वापरकर्ता बटणावर क्लिक करतो, तेव्हा ते नेटवर्क Ethereum वर स्विच झाले पाहिजे. यामुळे वापरकर्त्याचा प्रवाह लक्षणीयरीत्या वेगवान होतो. + +![मुख्य CTA वरून सुरू होणाऱ्या मुख्य क्रिया](./16.png) + +![मुख्य CTA मध्ये दर्शविलेला त्रुटी संदेश](./17.png) + +## या figma फाइलसह स्वतःचे तयार करा {#build-your-own-with-this-figma-file} + +अनेक प्रोटोकॉलच्या कठोर परिश्रमामुळे, DEX डिझाइनमध्ये खूप सुधारणा झाली आहे. आम्हाला माहित आहे की वापरकर्त्याला कोणती माहिती हवी आहे, ती कशी दाखवावी, आणि प्रवाह शक्य तितका सुरळीत कसा करावा. +आशा आहे की हा लेख UX तत्त्वांचे एक ठोस विहंगावलोकन प्रदान करतो. + +तुम्हाला प्रयोग करायचे असल्यास, कृपया फिग्मा वायरफ्रेम किट वापरण्यास मोकळ्या मनाने. हे शक्य तितके सोपे ठेवले आहे, परंतु विविध मार्गांनी मूलभूत रचना तयार करण्यासाठी पुरेशी लवचिकता आहे. + +[Figma वायरफ्रेम किट](https://www.figma.com/community/file/1393606680816807382/dex-wireframes-kit) + +DeFi विकसित होत राहील, आणि सुधारणेसाठी नेहमीच जागा असते. + +शुभेच्छा! diff --git a/public/content/translations/mr/developers/docs/design-and-ux/heuristics-for-web3/index.md b/public/content/translations/mr/developers/docs/design-and-ux/heuristics-for-web3/index.md new file mode 100644 index 00000000000..182ed9ea633 --- /dev/null +++ b/public/content/translations/mr/developers/docs/design-and-ux/heuristics-for-web3/index.md @@ -0,0 +1,138 @@ +--- +title: "Web3 इंटरफेस डिझाइनसाठी 7 मार्गदर्शक तत्वे" +description: "Web3 ची उपयोगिता सुधारण्यासाठीची तत्त्वे" +lang: mr +--- + +उपयोगिता मार्गदर्शक तत्वे हे व्यापक 'अंगठ्याचे नियम' आहेत जे तुम्ही तुमच्या साइटची उपयोगिता मोजण्यासाठी वापरू शकता. +येथील 7 मार्गदर्शक तत्वे विशेषतः Web3 साठी तयार केली आहेत आणि जेकब निल्सनच्या [इंटरॅक्शन डिझाइनसाठी 10 सामान्य तत्त्वे](https://www.nngroup.com/articles/ten-usability-heuristics/) सोबत वापरली पाहिजेत. + +## web3 साठी सात उपयोगिता मार्गदर्शक तत्वे {#seven-usability-heuristics-for-web3} + +1. कृतीनंतर प्रतिक्रिया येते +2. सुरक्षा आणि विश्वास +3. सर्वात महत्त्वाची माहिती स्पष्ट आहे +4. समजण्यायोग्य परिभाषा +5. कृती शक्य तितक्या लहान असाव्यात +6. नेटवर्क कनेक्शन दृश्यमान आणि लवचिक आहेत +7. ॲपमधून नियंत्रण, वॉलेटमधून नाही + +## व्याख्या आणि उदाहरणे {#definitions-and-examples} + +### १. कृतीनंतर प्रतिक्रिया येते {#feedback-follows-action} + +**जेव्हा काहीतरी घडले आहे किंवा घडत आहे, तेव्हा ते स्पष्ट असले पाहिजे.** + +वापरकर्ते त्यांच्या मागील कृतींच्या परिणामावर आधारित पुढील कृती ठरवतात. म्हणून त्यांना सिस्टमच्या स्थितीबद्दल माहिती देत राहणे आवश्यक आहे. Web3 मध्ये हे विशेषतः महत्त्वाचे आहे कारण व्यवहारांना ब्लॉकचेनवर नोंद होण्यासाठी काही वेळा थोडा वेळ लागू शकतो. जर त्यांना थांबायला सांगणारी कोणतीही प्रतिक्रिया नसेल, तर वापरकर्त्यांना काही घडले आहे की नाही याची खात्री नसते. + +**टिपा:** + +- मेसेजिंग, नोटिफिकेशन्स आणि इतर अलर्टद्वारे वापरकर्त्याला माहिती द्या. +- प्रतीक्षा कालावधी स्पष्टपणे कळवा. +- जर एखाद्या कृतीला काही सेकंदांपेक्षा जास्त वेळ लागणार असेल, तर टायमर किंवा ॲनिमेशनद्वारे वापरकर्त्याला दिलासा द्या जेणेकरून त्यांना काहीतरी घडत आहे असे वाटेल. +- जर प्रक्रियेत अनेक पायऱ्या असतील, तर प्रत्येक पायरी दाखवा. + +**उदाहरण:** +व्यवहारात समाविष्ट असलेली प्रत्येक पायरी दाखवल्याने वापरकर्त्यांना ते प्रक्रियेत कोठे आहेत हे जाणून घेण्यास मदत होते. योग्य आयकॉन वापरकर्त्याला त्यांच्या कृतींची स्थिती कळवतात. + +![टोकन स्वॅप करताना वापरकर्त्याला प्रत्येक पायरीबद्दल माहिती देणे](./Image1.png) + +### २. सुरक्षा आणि विश्वास अंतर्भूत आहेत {#security-and-trust-are-backed-in} + +सुरक्षेला प्राधान्य दिले पाहिजे आणि वापरकर्त्यासाठी यावर जोर दिला पाहिजे. +लोकांना त्यांच्या डेटाची खूप काळजी असते. वापरकर्त्यांसाठी सुरक्षितता ही अनेकदा प्राथमिक चिंता असते, म्हणून डिझाइनच्या सर्व स्तरांवर तिचा विचार केला पाहिजे. तुम्ही नेहमी तुमच्या वापरकर्त्यांचा विश्वास मिळवण्याचा प्रयत्न केला पाहिजे, पण तुम्ही हे कसे करता याचा अर्थ वेगवेगळ्या ॲप्सवर वेगळा असू शकतो. तो नंतरचा विचार नसावा, तर संपूर्ण प्रक्रियेत जाणीवपूर्वक डिझाइन केले पाहिजे. अंतिम UI तसेच सोशल चॅनेल आणि डॉक्युमेंटेशनसह संपूर्ण वापरकर्ता अनुभवातून विश्वास निर्माण करा. विकेंद्रीकरणाची पातळी, ट्रेझरी मल्टी-सिग स्थिती आणि टीम डॉक्स आहे की नाही, यासारख्या गोष्टी वापरकर्त्यांच्या विश्वासावर परिणाम करतात + +**टिपा:** + +- तुमच्या ऑडिटची अभिमानाने यादी करा +- अनेक ऑडिट मिळवा +- तुम्ही डिझाइन केलेल्या कोणत्याही सुरक्षा वैशिष्ट्यांची जाहिरात करा +- अंतर्निहित इंटिग्रेशन्ससह संभाव्य धोके ठळकपणे सांगा +- धोरणांची जटिलता कळवा +- तुमच्या वापरकर्त्यांच्या सुरक्षिततेच्या धारणेवर परिणाम करणाऱ्या UI-व्यतिरिक्त समस्यांचा विचार करा + +**उदाहरण:** +फूटरमध्ये तुमचे ऑडिट ठळक आकारात समाविष्ट करा. + +![वेबसाइटच्या फूटरमध्ये संदर्भित ऑडिट](./Image2.png) + +### ३. सर्वात महत्त्वाची माहिती स्पष्ट आहे {#the-most-important-info-is-obvious} + +जटिल प्रणालींसाठी, केवळ सर्वात संबंधित डेटा दाखवा. सर्वात महत्त्वाचे काय आहे ते ठरवा आणि ते दाखवण्यास प्राधान्य द्या. +खूप जास्त माहिती गोंधळात टाकणारी असते आणि वापरकर्ते निर्णय घेताना सहसा माहितीच्या एकाच तुकड्यावर लक्ष केंद्रित करतात. DeFi मध्ये, हे बहुधा यील्ड ॲप्सवर APR आणि लेंडिंग ॲप्सवर LTV असेल. + +**टिपा:** + +- वापरकर्ता संशोधन सर्वात महत्त्वाचे मेट्रिक उघड करेल +- मुख्य माहिती मोठी आणि इतर तपशील लहान आणि नजरेत न भरणारे ठेवा +- लोक वाचत नाहीत, ते स्कॅन करतात; तुमचे डिझाइन स्कॅन करण्यायोग्य असल्याची खात्री करा + +**उदाहरण:** पूर्ण रंगातील मोठे टोकन स्कॅन करताना सहज सापडतात. APR मोठा आहे आणि ॲक्सेंट रंगात हायलाइट केलेला आहे. + +![टोकन आणि APR सहज शोधता येतात](./Image3.png) + +### ४. स्पष्ट परिभाषा {#clear-terminology} + +परिभाषा समजण्यायोग्य आणि योग्य असावी. +तांत्रिक शब्दजाल एक मोठा अडथळा असू शकतो, कारण त्यासाठी पूर्णपणे नवीन मानसिक मॉडेल तयार करणे आवश्यक असते. वापरकर्ते डिझाइनला त्यांना आधीच माहित असलेल्या शब्द, वाक्ये आणि संकल्पनांशी जोडू शकत नाहीत. सर्व काही गोंधळात टाकणारे आणि अपरिचित वाटते, आणि ते वापरण्याचा प्रयत्न करण्याआधीच एक कठीण शिकण्याची प्रक्रिया असते. एक वापरकर्ता काही पैसे वाचवण्याच्या इच्छेने DeFi कडे येऊ शकतो आणि त्याला काय मिळते ते म्हणजे: मायनिंग, फार्मिंग, स्टेकिंग, एमिशन्स, ब्राइब्स, वॉल्ट्स, लॉकर्स, veTokens, वेस्टिंग, इपॉक्स, विकेंद्रीकृत अल्गोरिदम, प्रोटोकॉल-ओन्ड लिक्विडिटी... +असे सोपे शब्द वापरण्याचा प्रयत्न करा जे लोकांच्या सर्वात मोठ्या गटाला समजतील. फक्त तुमच्या प्रोजेक्टसाठी नवीन शब्द तयार करू नका. + +**टिपा:** + +- सोपी आणि सुसंगत परिभाषा वापरा +- शक्य तितकी विद्यमान भाषा वापरा +- तुमचे स्वतःचे शब्द तयार करू नका +- संकेत जसे दिसतील तसे त्यांचे पालन करा +- वापरकर्त्यांना शक्य तितके शिक्षित करा + +**उदाहरण:** +“तुमचे रिवॉर्ड्स” हा एक व्यापकपणे समजला जाणारा, तटस्थ शब्द आहे; या प्रोजेक्टसाठी बनवलेला नवीन शब्द नाही. वास्तविक जगाच्या मानसिक मॉडेलशी जुळण्यासाठी रिवॉर्ड्स USD मध्ये दर्शविले जातात, जरी रिवॉर्ड्स स्वतः दुसऱ्या टोकनमध्ये असले तरी. + +![यू.एस. मध्ये दर्शविलेले टोकन रिवॉर्ड्स डॉलर्स](./Image4.png) + +### ५. कृती शक्य तितक्या लहान असाव्यात {#actions-are-as-short-as-possible} + +उप-कृती एकत्र करून वापरकर्त्याच्या परस्परसंवादाला गती द्या. +हे स्मार्ट कॉन्ट्रॅक्ट स्तरावर तसेच UI मध्ये केले जाऊ शकते. एक सामान्य कृती पूर्ण करण्यासाठी वापरकर्त्याला सिस्टमच्या एका भागातून दुसऱ्या भागात जाण्याची - किंवा सिस्टम पूर्णपणे सोडण्याची गरज पडू नये. + +**टिपा:** + +- शक्य असेल तिथे "Approve" ला इतर कृतींसह एकत्र करा +- स्वाक्षरी करण्याच्या पायऱ्या शक्य तितक्या जवळ एकत्र करा + +**उदाहरण:** “लिक्विडिटी ॲड करणे” आणि “स्टेक करणे” एकत्र करणे हे ॲक्सलरेटरचे एक सोपे उदाहरण आहे जे वापरकर्त्याचा वेळ आणि गॅस दोन्ही वाचवते. + +![डिपॉझिट आणि स्टेक क्रिया एकत्र करण्यासाठी स्विच दर्शवणारा मॉडेल](./Image5.png) + +### 6. नेटवर्क कनेक्शन दृश्यमान आणि लवचिक आहेत {#network-connections-are-visible-and-flexible} + +वापरकर्त्याला ते कोणत्या नेटवर्कशी कनेक्ट आहेत याची माहिती द्या आणि नेटवर्क बदलण्यासाठी स्पष्ट शॉर्टकट प्रदान करा. +मल्टीचेन ॲप्सवर हे विशेषतः महत्त्वाचे आहे. डिस्कनेक्ट असताना किंवा नॉन-सपोर्टेड नेटवर्कशी कनेक्ट असतानाही ॲपची मुख्य कार्ये दृश्यमान असावीत. + +**टिपा:** + +- डिस्कनेक्ट असताना शक्य तितके ॲप दाखवा +- वापरकर्ता सध्या कोणत्या नेटवर्कशी कनेक्ट आहे ते दाखवा +- नेटवर्क बदलण्यासाठी वापरकर्त्याला वॉलेटमध्ये जाऊ देऊ नका +- जर ॲपला वापरकर्त्याला नेटवर्क बदलण्याची आवश्यकता असेल, तर मुख्य कॉल टू ॲक्शनमधून कृतीसाठी प्रॉम्प्ट करा +- जर ॲपमध्ये अनेक नेटवर्कसाठी मार्केट्स किंवा वॉल्ट्स असतील, तर वापरकर्ता सध्या कोणता संच पाहत आहे हे स्पष्टपणे सांगा + +**उदाहरण:** वापरकर्त्याला ते कोणत्या नेटवर्कशी कनेक्ट आहेत ते ॲपबारमध्ये दाखवा आणि त्यांना ते बदलण्याची परवानगी द्या. + +![कनेक्ट केलेले नेटवर्क दर्शविणारे ड्रॉपडाउन बटण](./Image6.png) + +### 7. ॲपमधून नियंत्रण, वॉलेटमधून नाही {#control-from-the-app-not-the-wallet} + +UI ने वापरकर्त्याला त्यांना माहित असणे आवश्यक असलेल्या सर्व गोष्टी सांगाव्यात आणि त्यांना जे काही करायचे आहे त्यावर नियंत्रण द्यावे. +Web3 मध्ये, काही कृती तुम्ही UI मध्ये करता आणि काही कृती तुम्ही वॉलेटमध्ये करता. सामान्यतः, तुम्ही UI मध्ये एक कृती सुरू करता आणि नंतर वॉलेटमध्ये तिची पुष्टी करता. जर हे दोन धागे काळजीपूर्वक एकत्रित केले नाहीत तर वापरकर्त्यांना अस्वस्थ वाटू शकते. + +**टिपा:** + +- UI मधील प्रतिक्रियेद्वारे सिस्टमची स्थिती कळवा +- त्यांच्या इतिहासाची नोंद ठेवा +- जुन्या व्यवहारांसाठी ब्लॉक एक्सप्लोरर्सच्या लिंक प्रदान करा +- नेटवर्क बदलण्यासाठी शॉर्टकट प्रदान करा. + +**उदाहरण:** एक सूक्ष्म कंटेनर वापरकर्त्याला त्यांच्या वॉलेटमध्ये कोणते संबंधित टोकन आहेत हे दाखवतो आणि मुख्य CTA नेटवर्क बदलण्यासाठी एक शॉर्टकट प्रदान करतो. + +![मुख्य CTA वापरकर्त्याला नेटवर्क स्विच करण्यासाठी प्रॉम्प्ट करत आहे](./Image7.png) diff --git a/public/content/translations/mr/developers/docs/design-and-ux/index.md b/public/content/translations/mr/developers/docs/design-and-ux/index.md new file mode 100644 index 00000000000..a2418ec4a95 --- /dev/null +++ b/public/content/translations/mr/developers/docs/design-and-ux/index.md @@ -0,0 +1,86 @@ +--- +title: "वेब3 मध्ये डिझाइन आणि यूएक्स" +description: "वेब3 स्पेस आणि Ethereum मध्ये यूएक्स डिझाइन आणि संशोधनाची ओळख" +lang: mr +--- + +तुम्ही Ethereum सह डिझाइन करण्यासाठी नवीन आहात का? तुमच्यासाठी ही योग्य जागा आहे. Ethereum समुदायाने तुम्हाला वेब3 डिझाइन आणि संशोधनाच्या मूलभूत गोष्टींची ओळख करून देण्यासाठी संसाधने लिहिली आहेत. तुम्ही अशा मुख्य संकल्पनांबद्दल शिकाल ज्या तुम्हाला परिचित असलेल्या इतर ॲप डिझाइनपेक्षा वेगळ्या असू शकतात. + +प्रथम वेब3 ची अधिक मूलभूत माहिती हवी आहे का? [**लर्न हब**](/learn/) पहा. + +## वापरकर्ता संशोधनापासून सुरुवात करा {#start-with-user-research} + +प्रभावी डिझाइन हे केवळ दृष्यदृष्ट्या आकर्षक वापरकर्ता इंटरफेस तयार करण्याच्या पलीकडे जाते. यात वापरकर्त्याच्या गरजा, उद्दिष्ट्ये आणि प्रेरक घटकांची सखोल समज मिळवणे समाविष्ट आहे. म्हणून, आम्ही सर्व डिझाइनर्सना जोरदार शिफारस करतो की त्यांनी त्यांचे कार्य विचारपूर्वक आणि हेतुपुरस्सर आहे हे सुनिश्चित करण्यासाठी, [**डबल डायमंड प्रक्रियेसारखी**](https://en.wikipedia.org/wiki/Double_Diamond_\(design_process_model\)) डिझाइन प्रक्रिया स्वीकारावी. + +- [वेब3 ला अधिक यूएक्स संशोधक आणि डिझाइनर्सची गरज आहे](https://blog.akasha.org/akasha-conversations-9-web3-needs-more-ux-researchers-and-designers) - सध्याच्या डिझाइन परिपक्वतेचा आढावा +- [वेब3 मधील यूएक्स संशोधनासाठी एक सोपा मार्गदर्शक](https://uxplanet.org/a-complete-guide-to-ux-research-for-web-3-0-products-d6bead20ebb1) - संशोधन कसे करावे यासाठी सोपा मार्गदर्शक +- [वेब3 मध्ये यूएक्स निर्णय कसे घ्यावेत](https://archive.devcon.org/archive/watch/6/data-empathy-how-to-approach-ux-decisions-in-web3/) - संख्यात्मक आणि गुणात्मक संशोधनाचा आणि दोघांमधील फरकांचा संक्षिप्त आढावा (व्हिडिओ, 6 मिनिटे) +- [वेब3 मध्ये यूएक्स संशोधक असणे](https://medium.com/@georgia.rakusen/what-its-like-being-a-user-researcher-in-web3-6a4bcc096849) - वेब3 मध्ये यूएक्स संशोधक असण्याचा अनुभव कसा असतो यावर एक वैयक्तिक दृष्टिकोन + +## वेब3 मधील संशोधन अभ्यास {#research-in-web3} + +ही वेब3 मध्ये केलेल्या वापरकर्ता संशोधनाची एक क्युरेट केलेली यादी आहे जी डिझाइन आणि उत्पादन निर्णयांमध्ये मदत करू शकते किंवा स्वतःचा अभ्यास करण्यासाठी प्रेरणा म्हणून काम करू शकते. + +| लक्ष केंद्रित करण्याचे क्षेत्र | नाव | +| :-------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| क्रिप्टो ऑनबोर्डिंग | [द रिओन पल्स 2024: क्रिप्टो ग्राहक भावना आणि वापर](https://reown.com/blog/unveiling-walletconnects-consumer-crypto-report) | +| क्रिप्टो ऑनबोर्डिंग | [CRADL: क्रिप्टोकरन्सीमधील यूएक्स](https://docs.google.com/presentation/d/1s2OPSH5sMJzxRYaJSSRTe8W2iIoZx0PseIV-WeZWD1s/edit?usp=sharing) | +| क्रिप्टो ऑनबोर्डिंग | [CRADL: क्रिप्टोकरन्सीसाठी ऑनबोर्डिंग](https://docs.google.com/presentation/d/1R9nFuzA-R6SxaGCKhoMbE4Vxe0JxQSTiHXind3LVq_w/edit?usp=sharing) | +| क्रिप्टो ऑनबोर्डिंग | [Bitcoin यूएक्स अहवाल](https://github.com/patestevao/BitcoinUX-report/blob/master/report.md) | +| क्रिप्टो ऑनबोर्डिंग | [ConSensys: जगभरातील वेब3 धारणाची स्थिती 2023](https://consensys.io/insight-report/web3-and-crypto-global-survey-2023) | +| क्रिप्टो ऑनबोर्डिंग | [NEAR: दत्तक घेण्याच्या दिशेने प्रवास वेगवान करणे](https://drive.google.com/file/d/1VuaQP4QSaQxR5ddQKTMGI0b0rWdP7uGn/view) | +| स्टेकिंग | [OpenUX: रॉकेट पूल नोड ऑपरेटर यूएक्स](https://storage.googleapis.com/rocketpool/RocketPool-NodeOperator-UX-Report-Jan-2024.pdf) | +| स्टेकिंग | [स्टेकिंग: मुख्य ट्रेंड, टेकअवे आणि अंदाज - Eth स्टेकर](https://lookerstudio.google.com/u/0/reporting/cafcee00-e1af-4148-bae8-442a88ac75fa/page/p_ja2srdhh2c?s=hmbTWDh9hJo) | +| स्टेकिंग | [मल्टी ॲप स्टेकिंग](https://github.com/threshold-network/UX-User-Research/blob/main/Multi-App%20Staking%20\(MAS\)/iterative-user-study/MAS%20Iterative%20User%20Study.pdf) | +| DAO | [2022 DAO संशोधन अपडेट: DAO बिल्डर्सना कशाची गरज आहे?](https://blog.aragon.org/2022-dao-research-update/) | +| DeFi | [कव्हरेज पूल](https://github.com/threshold-network/UX-User-Research/tree/main/Keep%20Coverage%20Pool) | +| DeFi | [ConSensys: DeFi वापरकर्ता संशोधन अहवाल 2022](https://cdn2.hubspot.net/hubfs/4795067/ConsenSys%20Codefi-Defi%20User%20ResearchReport.pdf) | +| मेटाव्हर्स | [मेटाव्हर्स: वापरकर्ता संशोधन अहवाल](https://www.politico.com/f/?id=00000187-7685-d820-a7e7-7e85d1420000) | +| मेटाव्हर्स | [सफारीवर जात आहे: मेटाव्हर्समधील वापरकर्त्यांचे संशोधन](https://archive.devcon.org/archive/watch/6/going-on-safari-researching-users-in-the-metaverse/?tab=YouTube) (व्हिडिओ, 27 मिनिटे) | + +## वेब3 साठी डिझाइन {#design-for-web3} + +- [वेब3 यूएक्स डिझाइन हँडबुक](https://web3ux.design/) - वेब3 ॲप्स डिझाइन करण्यासाठी व्यावहारिक मार्गदर्शक +- [वेब3 डिझाइनची तत्त्वे](https://medium.com/@lyricalpolymath/web3-design-principles-f21db2f240c1) - ब्लॉकचेन-आधारित dapps साठी यूएक्स नियमांची एक चौकट +- [ब्लॉकचेन डिझाइनची तत्त्वे](https://medium.com/design-ibm/blockchain-design-principles-599c5c067b6e) - IBM मधील ब्लॉकचेन डिझाइन टीमने शिकलेले धडे +- [Neueux.com](https://neueux.com/apps) - विविध फिल्टरिंग पर्यायांसह वापरकर्ता प्रवाहांची यूआय लायब्ररी +- [वेब3 चे उपयोगिता संकट: तुम्हाला काय माहित असणे आवश्यक आहे!](https://www.youtube.com/watch?v=oBSXT_6YDzg) - डेव्हलपर-केंद्रित प्रोजेक्ट बिल्डिंगच्या त्रुटींवर एक पॅनेल चर्चा (व्हिडिओ, 34 मिनिटे) + +## सुरुवात करणे {#getting-started} + +- [वेब3 साठी ह्युरिस्टिक्स](/developers/docs/design-and-ux/heuristics-for-web3/) - वेब3 इंटरफेस डिझाइनसाठी 7 ह्युरिस्टिक्स +- [DEX डिझाइन सर्वोत्तम पद्धती](/developers/docs/design-and-ux/dex-design-best-practice/) - विकेंद्रीकृत एक्सचेंज डिझाइन करण्यासाठी एक मार्गदर्शक + +## वेब3 डिझाइन केस स्टडीज {#design-case-studies} + +- [Deep Work Studio](https://www.deepwork.studio/case-studies) +- [OpenSea वर एनएफटी विकणे](https://builtformars.com/case-studies/opensea) +- [वॉलेट यूएक्स टियरडाउन: वॉलेट्सना कसे बदलण्याची गरज आहे](https://www.youtube.com/watch?v=oTpuxYj8JWI&ab_channel=ETHDenver) (व्हिडिओ, 20 मिनिटे) + +## डिझाइन बाउंटीज {#bounties} + +- [Dework](https://app.dework.xyz/bounties) +- [बिल्डबॉक्स हॅकथॉन्स](https://app.buidlbox.io/) +- [ETHGlobal हॅकथॉन्स](https://ethglobal.com/) + +## डिझाइन DAO आणि समुदाय {#design-daos-and-communities} + +व्यावसायिक समुदाय-चालित संस्थांमध्ये सामील व्हा किंवा इतर सदस्यांसह डिझाइन आणि संशोधनाशी संबंधित विषय आणि ट्रेंडवर चर्चा करण्यासाठी डिझाइन गटांमध्ये सामील व्हा. + +- [Vectordao.com](https://vectordao.com/) +- [Deepwork.studio](https://www.deepwork.studio/) +- [We3.co](https://we3.co/) +- [Openux.xyz](https://openux.xyz/) + +## डिझाइन सिस्टीम आणि इतर डिझाइन संसाधने {#design-systems-and-resources} + +- [Optimism डिझाइन](https://www.figma.com/@optimism) (Figma) +- [Ethereum.org डिझाइन सिस्टीम](https://www.figma.com/@ethdotorg) (Figma) +- [फिनिटी, पॉलीगॉनची एक डिझाइन सिस्टीम](https://www.figma.com/community/file/1073921725197233598/finity-design-system) (Figma) +- [क्लेरोस डिझाइन सिस्टीम](https://www.figma.com/community/file/999852250110186964/kleros-design-system) (Figma) +- [सेफ डिझाइन सिस्टीम](https://www.figma.com/community/file/1337417127407098506/safe-design-system) (Figma) +- [ENS डिझाइन सिस्टीम](https://thorin.ens.domains/) +- [मिरर डिझाइन सिस्टीम](https://degen-xyz.vercel.app/) + +**या पृष्ठावर सूचीबद्ध केलेले लेख आणि प्रकल्प अधिकृत समर्थन नाहीत**, आणि केवळ माहितीच्या उद्देशाने प्रदान केले आहेत. +आम्ही आमच्या [सूचीकरण धोरणातील](/contributing/design/adding-design-resources) निकषांवर आधारित या पृष्ठावर दुवे जोडतो. तुम्हाला एखादा प्रकल्प/लेख जोडायचा असल्यास, [GitHub](https://github.com/ethereum/ethereum-org-website/blob/dev/public/content/developers/docs/design-and-ux/index.md) वर हे पृष्ठ संपादित करा. diff --git a/public/content/translations/mr/developers/docs/development-networks/index.md b/public/content/translations/mr/developers/docs/development-networks/index.md new file mode 100644 index 00000000000..5dad0544fda --- /dev/null +++ b/public/content/translations/mr/developers/docs/development-networks/index.md @@ -0,0 +1,71 @@ +--- +title: "विकास नेटवर्क" +description: "विकास नेटवर्क आणि Ethereum ॲप्लिकेशन्स तयार करण्यात मदत करण्यासाठी उपलब्ध साधनांचे एक अवलोकन." +lang: mr +--- + +स्मार्ट कॉन्ट्रॅक्ट्ससह Ethereum ॲप्लिकेशन तयार करताना, ते कसे काम करते हे पाहण्यासाठी, तुम्ही ते तैनात करण्यापूर्वी स्थानिक नेटवर्कवर चालवू इच्छित असाल. + +ज्याप्रमाणे तुम्ही वेब डेव्हलपमेंटसाठी तुमच्या संगणकावर स्थानिक सर्व्हर चालवू शकता, त्याचप्रमाणे तुम्ही तुमच्या dapp ची चाचणी घेण्यासाठी स्थानिक ब्लॉकचेन इन्स्टन्स तयार करण्याकरिता विकास नेटवर्क वापरू शकता. हे Ethereum विकास नेटवर्क अशी वैशिष्ट्ये प्रदान करतात जे सार्वजनिक टेस्टनेटपेक्षा खूप जलद पुनरावृत्ती करण्यास परवानगी देतात (उदाहरणार्थ तुम्हाला टेस्टनेट फॉसेटमधून ETH मिळवण्याची गरज नाही). + +## पूर्वतयारी {#prerequisites} + +विकास नेटवर्कमध्ये जाण्यापूर्वी, तुम्ही [Ethereum स्टॅकची मूलभूत माहिती](/developers/docs/ethereum-stack/) आणि [Ethereum नेटवर्क्स](/developers/docs/networks/) समजून घेतले पाहिजे. + +## विकास नेटवर्क म्हणजे काय? {#what-is-a-development-network} + +विकास नेटवर्क हे मूलत: Ethereum क्लायंट (Ethereum ची अंमलबजावणी) आहेत जे विशेषतः स्थानिक विकासासाठी डिझाइन केलेले आहेत. + +**स्थानिक पातळीवर प्रमाणित Ethereum नोड का चालवू नये?** + +तुम्ही [नोड चालवू](/developers/docs/nodes-and-clients/#running-your-own-node) _शकता_ परंतु विकास नेटवर्क विकासासाठीच तयार केलेले असल्यामुळे, ते अनेकदा सोयीस्कर वैशिष्ट्यांसह येतात जसे की: + +- तुमच्या स्थानिक ब्लॉकचेनला डेटासह (उदा. ETH शिल्लक असलेली खाती) निश्चितपणे सीड करणे +- मिळणाऱ्या प्रत्येक व्यवहारासह त्वरित, क्रमाने आणि कोणत्याही विलंबाशिवाय ब्लॉक्स तयार करणे +- वर्धित डीबगिंग आणि लॉगिंग कार्यक्षमता + +## उपलब्ध साधने {#available-projects} + +**टीप**: बहुतेक [विकास फ्रेमवर्कमध्ये](/developers/docs/frameworks/) अंगभूत विकास नेटवर्क समाविष्ट असते. तुमचे स्थानिक विकास वातावरण [सेट अप करण्यासाठी](/developers/local-environment/) आम्ही फ्रेमवर्कने सुरुवात करण्याची शिफारस करतो. + +### Hardhat नेटवर्क {#hardhat-network} + +विकासासाठी डिझाइन केलेले एक स्थानिक Ethereum नेटवर्क. हे तुम्हाला तुमचे कॉन्ट्रॅक्ट्स तैनात करण्यास, तुमच्या चाचण्या चालवण्यास आणि तुमचा कोड डीबग करण्यास अनुमती देते. + +Hardhat नेटवर्क हे Hardhat सोबत अंगभूत येते, जे व्यावसायिकांसाठी एक Ethereum विकास वातावरण आहे. + +- [वेबसाइट](https://hardhat.org/) +- [GitHub](https://github.com/NomicFoundation/hardhat) + +### स्थानिक बीकन चेन्स {#local-beacon-chains} + +काही कन्सेन्सस क्लायंट्सकडे चाचणीच्या उद्देशाने स्थानिक बीकन चेन्स सुरू करण्यासाठी अंगभूत साधने आहेत. Lighthouse, Nimbus आणि Lodestar साठी सूचना उपलब्ध आहेत: + +- [Lodestar वापरून स्थानिक टेस्टनेट](https://chainsafe.github.io/lodestar/contribution/advanced-topics/setting-up-a-testnet#post-merge-local-testnet/) +- [Lighthouse वापरून स्थानिक टेस्टनेट](https://lighthouse-book.sigmaprime.io/setup.html#local-testnets) + +### सार्वजनिक Ethereum टेस्ट-चेन्स {#public-beacon-testchains} + +Ethereum च्या दोन सार्वजनिक चाचणी अंमलबजावणी देखील आहेत: Sepolia आणि Hoodi. दीर्घकालीन समर्थनासह शिफारस केलेले टेस्टनेट Hoodi आहे, ज्यावर कोणीही प्रमाणित करण्यास स्वतंत्र आहे. Sepolia एक परवानगी असलेला व्हॅलिडेटर सेट वापरते, याचा अर्थ या टेस्टनेटवर नवीन व्हॅलिडेटर्ससाठी सामान्य प्रवेश नाही. + +- [Hoodi स्टिकिंग लॉन्चपॅड](https://hoodi.launchpad.ethereum.org/) + +### Kurtosis Ethereum पॅकेज {#kurtosis} + +Kurtosis ही मल्टी-कंटेनर चाचणी वातावरणासाठी एक बिल्ड सिस्टम आहे जी विकासकांना स्थानिक पातळीवर ब्लॉकचेन नेटवर्कचे पुनरुत्पादक इन्स्टन्स सुरू करण्यास सक्षम करते. + +Ethereum Kurtosis पॅकेजचा वापर Docker किंवा Kubernetes वर पॅरामिटरायझ करण्यायोग्य, अत्यंत स्केलेबल आणि खाजगी Ethereum टेस्टनेट त्वरित सुरू करण्यासाठी केला जाऊ शकतो. हे पॅकेज सर्व प्रमुख एक्झिक्युशन लेयर (EL) आणि कन्सेन्सस लेयर (CL) क्लायंट्सना समर्थन देते. Kurtosis Ethereum कोर इन्फ्रास्ट्रक्चरशी संबंधित व्हॅलिडेशन आणि टेस्टिंग वर्कफ्लोमध्ये वापरण्यासाठी प्रतिनिधी नेटवर्कसाठी सर्व स्थानिक पोर्ट मॅपिंग आणि सर्व्हिस कनेक्शन सुरेखपणे हाताळते. + +- [Ethereum नेटवर्क पॅकेज](https://github.com/kurtosis-tech/ethereum-package) +- [वेबसाइट](https://www.kurtosis.com/) +- [GitHub](https://github.com/kurtosis-tech/kurtosis) +- [डॉक्युमेंटेशन](https://docs.kurtosis.com/) + +## पुढील वाचन {#further-reading} + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ + +## संबंधित विषय {#related-topics} + +- [डेव्हलपमेंट फ्रेमवर्क्स](/developers/docs/frameworks/) +- [स्थानिक विकास वातावरण सेट अप करा](/developers/local-environment/) diff --git a/public/content/translations/mr/developers/docs/ethereum-stack/index.md b/public/content/translations/mr/developers/docs/ethereum-stack/index.md new file mode 100644 index 00000000000..62700fa0270 --- /dev/null +++ b/public/content/translations/mr/developers/docs/ethereum-stack/index.md @@ -0,0 +1,61 @@ +--- +title: "इथेरियम स्टॅकची ओळख" +description: "इथेरियम स्टॅकच्या विविध स्तरांचा आढावा आणि ते एकत्र कसे जुळतात." +lang: mr +--- + +कोणत्याही सॉफ्टवेअर स्टॅकप्रमाणे, संपूर्ण "इथेरियम स्टॅक" तुमच्या ध्येयांनुसार प्रोजेक्ट-दर-प्रोजेक्ट बदलू शकतो. + +तथापि, इथेरियमचे काही मुख्य घटक आहेत जे सॉफ्टवेअर ॲप्लिकेशन्स इथेरियम ब्लॉकचेनशी कसे संवाद साधतात याचे मानसिक मॉडेल प्रदान करण्यात मदत करतात. स्टॅकचे स्तर समजून घेतल्यास, इथेरियमला सॉफ्टवेअर प्रोजेक्ट्समध्ये कोणत्या विविध मार्गांनी एकत्रित केले जाऊ शकते हे समजण्यास तुम्हाला मदत होईल. + +## स्तर 1: इथेरियम व्हर्च्युअल मशीन {#ethereum-virtual-machine} + +[इथेरियम व्हर्च्युअल मशीन (EVM)](/developers/docs/evm/) हे इथेरियमवरील स्मार्ट कॉन्ट्रॅक्ट्ससाठी रनटाइम एन्व्हायरनमेंट आहे. इथेरियम ब्लॉकचेनवरील सर्व स्मार्ट कॉन्ट्रॅक्ट्स आणि स्टेटमधील बदल [ट्रान्झॅक्शन्स](/developers/docs/transactions/) द्वारे कार्यान्वित केले जातात. EVM इथेरियम नेटवर्कवरील सर्व ट्रान्झॅक्शन प्रोसेसिंग हाताळते. + +कोणत्याही व्हर्च्युअल मशीनप्रमाणे, EVM कार्यान्वित होणाऱ्या कोड आणि कार्यान्वित करणाऱ्या मशीन (एक इथेरियम नोड) यांच्यामध्ये अमूर्ततेचा एक स्तर तयार करते. सध्या, EVM जगभर वितरित असलेल्या हजारो नोड्सवर चालत आहे. + +आंतरिकरित्या, EVM विशिष्ट कार्ये कार्यान्वित करण्यासाठी ऑपकोड निर्देशांचा एक संच वापरते. हे (140 अद्वितीय) ऑपकोड्स EVM ला [ट्युरिंग-कम्प्लीट](https://en.wikipedia.org/wiki/Turing_completeness) बनवतात, याचा अर्थ पुरेशी संसाधने दिल्यास EVM जवळजवळ कोणतीही गणना करण्यास सक्षम आहे. + +एक डॅप डेव्हलपर म्हणून, तुम्हाला EVM बद्दल जास्त काही जाणून घेण्याची आवश्यकता नाही, फक्त हे की ते अस्तित्वात आहे आणि ते डाउनटाइमशिवाय इथेरियमवरील सर्व ॲप्लिकेशन्सना विश्वसनीयरित्या शक्ती देते. + +## स्तर 2: स्मार्ट कॉन्ट्रॅक्ट्स {#smart-contracts} + +[स्मार्ट कॉन्ट्रॅक्ट्स](/developers/docs/smart-contracts/) हे कार्यान्वित करण्यायोग्य प्रोग्राम्स आहेत जे इथेरियम ब्लॉकचेनवर चालतात. + +स्मार्ट कॉन्ट्रॅक्ट्स विशिष्ट [प्रोग्रामिंग भाषा](/developers/docs/smart-contracts/languages/) वापरून लिहिले जातात, जे EVM बाईटकोडमध्ये (ऑपकोड्स नावाचे निम्न-स्तरीय मशीन निर्देश) कंपाइल होतात. + +स्मार्ट कॉन्ट्रॅक्ट्स केवळ ओपन सोर्स लायब्ररी म्हणूनच काम करत नाहीत, तर ते मूलतः ओपन API सेवा आहेत ज्या नेहमी चालू असतात आणि बंद केल्या जाऊ शकत नाहीत. स्मार्ट कॉन्ट्रॅक्ट्स सार्वजनिक फंक्शन्स प्रदान करतात ज्यांच्याशी वापरकर्ते आणि ॲप्लिकेशन्स ([डॅप्स](/developers/docs/dapps/)) परवानगीशिवाय संवाद साधू शकतात. कोणतेही ॲप्लिकेशन कार्यक्षमता तयार करण्यासाठी तैनात केलेल्या स्मार्ट कॉन्ट्रॅक्ट्ससह एकत्रित होऊ शकते, जसे की [डेटा फीड](/developers/docs/oracles/) जोडणे किंवा टोकन स्वॅपला सपोर्ट देणे. याव्यतिरिक्त, त्यांच्या ॲप्लिकेशनच्या गरजा पूर्ण करण्यासाठी सानुकूल कार्यक्षमता जोडण्याकरिता कोणीही इथेरियमवर नवीन स्मार्ट कॉन्ट्रॅक्ट्स तैनात करू शकतो. + +एक डॅप डेव्हलपर म्हणून, तुम्हाला इथेरियम ब्लॉकचेनवर सानुकूल कार्यक्षमता जोडायची असेल तरच स्मार्ट कॉन्ट्रॅक्ट्स लिहिण्याची आवश्यकता असेल. तुम्हाला आढळेल की तुम्ही तुमच्या प्रोजेक्टच्या बहुतेक किंवा सर्व गरजा केवळ विद्यमान स्मार्ट कॉन्ट्रॅक्ट्ससह एकत्रित करून पूर्ण करू शकता, उदाहरणार्थ जर तुम्हाला स्टेबलकॉइन्समधील पेमेंटला सपोर्ट करायचा असेल किंवा टोकन्सची विकेंद्रित देवाणघेवाण सक्षम करायची असेल. + +## स्तर 3: इथेरियम नोड्स {#ethereum-nodes} + +एखाद्या ॲप्लिकेशनला इथेरियम ब्लॉकचेनशी संवाद साधण्यासाठी, त्याला [इथेरियम नोड](/developers/docs/nodes-and-clients/) शी कनेक्ट होणे आवश्यक आहे. नोडशी कनेक्ट केल्याने तुम्हाला ब्लॉकचेन डेटा वाचता येतो आणि/किंवा नेटवर्कवर ट्रान्झॅक्शन्स पाठवता येतात. + +इथेरियम नोड्स हे सॉफ्टवेअर चालवणारे संगणक आहेत - एक इथेरियम क्लायंट. क्लायंट हे इथेरियमचे असे अंमलबजावणी आहे जे प्रत्येक ब्लॉकमधील सर्व ट्रान्झॅक्शन्सची पडताळणी करते, नेटवर्क सुरक्षित आणि डेटा अचूक ठेवते. **इथेरियम नोड्स म्हणजेच इथेरियम ब्लॉकचेन**. ते एकत्रितपणे इथेरियम ब्लॉकचेनची स्टेट संग्रहित करतात आणि ब्लॉकचेन स्टेटमध्ये बदल करण्यासाठी ट्रान्झॅक्शन्सवर एकमत साधतात. + +तुमच्या ॲप्लिकेशनला इथेरियम नोडशी ([JSON-RPC API](/developers/docs/apis/json-rpc/) द्वारे) कनेक्ट करून, तुमचे ॲप्लिकेशन ब्लॉकचेनमधून डेटा वाचू शकते (जसे की वापरकर्त्याच्या खात्यातील शिल्लक) तसेच नेटवर्कवर नवीन ट्रान्झॅक्शन्स प्रसारित करू शकते (जसे की वापरकर्ता खात्यांमध्ये ETH हस्तांतरित करणे किंवा स्मार्ट कॉन्ट्रॅक्ट्सची फंक्शन्स कार्यान्वित करणे). + +## स्तर 4: इथेरियम क्लायंट APIs {#ethereum-client-apis} + +अनेक सोयीस्कर लायब्ररी (इथेरियमच्या ओपन सोर्स समुदायाद्वारे तयार केलेल्या आणि सांभाळलेल्या) तुमच्या ॲप्लिकेशन्सना इथेरियम ब्लॉकचेनशी कनेक्ट करण्याची आणि संवाद साधण्याची परवानगी देतात. + +जर तुमचे वापरकर्त्यासमोरचे ॲप्लिकेशन वेब ॲप असेल, तर तुम्ही तुमच्या फ्रंटएंडमध्ये थेट [JavaScript API](/developers/docs/apis/javascript/) `npm install` करणे निवडू शकता. किंवा कदाचित तुम्ही [Python](/developers/docs/programming-languages/python/) किंवा [Java](/developers/docs/programming-languages/java/) API वापरून ही कार्यक्षमता सर्व्हर-साइडला लागू करणे निवडाल. + +हे APIs स्टॅकचा आवश्यक भाग नसले तरी, ते इथेरियम नोडशी थेट संवाद साधण्यामधील बरीचशी गुंतागुंत दूर करतात. ते युटिलिटी फंक्शन्स (उदा. ETH चे Gwei मध्ये रूपांतर करणे) देखील प्रदान करतात, त्यामुळे एक डेव्हलपर म्हणून तुम्ही इथेरियम क्लायंटच्या गुंतागुंतीला सामोरे जाण्यात कमी वेळ घालवू शकता आणि तुमच्या ॲप्लिकेशनसाठी विशिष्ट कार्यक्षमतेवर अधिक लक्ष केंद्रित करू शकता. + +## स्तर 5: अंतिम-वापरकर्ता ॲप्लिकेशन्स {#end-user-applications} + +स्टॅकच्या सर्वात वरच्या स्तरावर वापरकर्त्यासमोरचे ॲप्लिकेशन्स आहेत. हे तेच मानक ॲप्लिकेशन्स आहेत जे तुम्ही आज नियमितपणे वापरता आणि तयार करता: प्रामुख्याने वेब आणि मोबाईल ॲप्स. + +तुम्ही हे युझर इंटरफेस विकसित करण्याची पद्धत मूलतः अपरिवर्तित राहते. अनेकदा वापरकर्त्यांना हे जाणून घेण्याची आवश्यकता नसते की ते वापरत असलेले ॲप्लिकेशन ब्लॉकचेन वापरून तयार केले आहे. + +## तुमचा स्टॅक निवडण्यासाठी तयार आहात? {#ready-to-choose-your-stack} + +तुमच्या इथेरियम ॲप्लिकेशनसाठी [स्थानिक विकास पर्यावरण सेट करण्यासाठी](/developers/local-environment/) आमचे मार्गदर्शक पहा. + +## पुढील वाचन {#further-reading} + +- [वेब 3.0 ॲप्लिकेशनची रचना](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) - _प्रीती कासिरेड्डी_ + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ diff --git a/public/content/translations/mr/developers/docs/evm/index.md b/public/content/translations/mr/developers/docs/evm/index.md new file mode 100644 index 00000000000..564ec0ef25d --- /dev/null +++ b/public/content/translations/mr/developers/docs/evm/index.md @@ -0,0 +1,88 @@ +--- +title: "इथेरियम व्हर्च्युअल मशीन (EVM)" +description: "इथेरियम व्हर्च्युअल मशीनचा परिचय आणि ते स्थिती, व्यवहार आणि स्मार्ट कॉन्ट्रॅक्ट्सशी कसे संबंधित आहे." +lang: mr +--- + +इथेरियम व्हर्च्युअल मशीन (EVM) हे एक विकेंद्रित आभासी पर्यावरण आहे जे सर्व इथेरियम नोड्सवर सातत्याने आणि सुरक्षितपणे कोड कार्यान्वित करते. नोड्स स्मार्ट कॉन्ट्रॅक्ट्स कार्यान्वित करण्यासाठी EVM चालवतात, [ऑपरेशन्स](/developers/docs/evm/opcodes/) साठी आवश्यक संगणकीय प्रयत्नांचे मोजमाप करण्यासाठी "[गॅस](/developers/docs/gas/)" वापरतात, ज्यामुळे कार्यक्षम संसाधन वाटप आणि नेटवर्क सुरक्षा सुनिश्चित होते. + +## पूर्वतयारी {#prerequisites} + +EVM समजून घेण्यासाठी संगणक विज्ञानातील [बाईट्स](https://wikipedia.org/wiki/Byte), [मेमरी](https://wikipedia.org/wiki/Computer_memory), आणि [स्टॅक](https://wikipedia.org/wiki/Stack_\(abstract_data_type\)) यासारख्या सामान्य शब्दावलीची काही मूलभूत माहिती असणे आवश्यक आहे. [हॅश फंक्शन्स](https://wikipedia.org/wiki/Cryptographic_hash_function) आणि [मर्केल ट्री](https://wikipedia.org/wiki/Merkle_tree) यांसारख्या क्रिप्टोग्राफी/ब्लॉकचेन संकल्पनांशी परिचित असणे देखील उपयुक्त ठरेल. + +## लेजरपासून स्टेट मशीनपर्यंत {#from-ledger-to-state-machine} + +'वितरित लेजर' हे साधर्म्य अनेकदा Bitcoin सारख्या ब्लॉकचेनचे वर्णन करण्यासाठी वापरले जाते, जे क्रिप्टोग्राफीची मूलभूत साधने वापरून विकेंद्रित चलन सक्षम करतात. लेजर क्रियाकलापांची नोंद ठेवते, ज्याला अशा नियमांच्या संचाचे पालन करणे आवश्यक आहे, जे लेजरमध्ये बदल करण्यासाठी एखादी व्यक्ती काय करू शकते आणि काय करू शकत नाही हे नियंत्रित करतात. उदाहरणार्थ, एक Bitcoin पत्ता त्याला पूर्वी मिळालेल्या Bitcoin पेक्षा जास्त Bitcoin खर्च करू शकत नाही. हे नियम Bitcoin आणि इतर अनेक ब्लॉकचेनवरील सर्व व्यवहारांना आधार देतात. + +इथेरियमचे स्वतःचे मूळ क्रिप्टोकरन्सी (इथर) असले तरी, जे जवळजवळ समान अंतर्ज्ञानी नियमांचे पालन करते, ते एक अधिक शक्तिशाली कार्य देखील सक्षम करते: [स्मार्ट कॉन्ट्रॅक्ट्स](/developers/docs/smart-contracts/). या अधिक जटिल वैशिष्ट्यासाठी, अधिक अत्याधुनिक साधर्म्याची आवश्यकता आहे. वितरित लेजरऐवजी, इथेरियम एक वितरित [स्टेट मशीन](https://wikipedia.org/wiki/Finite-state_machine) आहे. इथेरियमची स्थिती ही एक मोठी डेटा रचना आहे जी केवळ सर्व खाती आणि शिल्लकच नाही, तर एक _मशीन स्थिती_ देखील ठेवते, जी पूर्वनिर्धारित नियमांनुसार ब्लॉक ते ब्लॉक बदलू शकते आणि जी कोणताही मशीन कोड कार्यान्वित करू शकते. ब्लॉक ते ब्लॉक स्थिती बदलण्याचे विशिष्ट नियम EVM द्वारे परिभाषित केले जातात. + +![EVM ची रचना दर्शविणारा एक आकृती](./evm.png) +_[इथेरियम EVM सचित्र](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित आकृती_ + +## इथेरियम स्टेट ट्रान्झिशन फंक्शन {#the-ethereum-state-transition-function} + +EVM गणितीय कार्याप्रमाणे वागते: इनपुट दिल्यावर, ते एक निश्चित आउटपुट तयार करते. त्यामुळे इथेरियमचे अधिक औपचारिकपणे **स्टेट ट्रान्झिशन फंक्शन** म्हणून वर्णन करणे खूप उपयुक्त आहे: + +``` +Y(S, T)= S' +``` + +एक जुनी वैध स्थिती `(S)` आणि वैध व्यवहारांचा नवीन संच `(T)` दिल्यास, इथेरियम स्टेट ट्रान्झिशन फंक्शन `Y(S, T)` एक नवीन वैध आउटपुट स्थिती `S'` तयार करते + +### स्थिती {#state} + +इथेरियमच्या संदर्भात, स्थिती ही [सुधारित मर्केल पॅट्रिशिया ट्राय](/developers/docs/data-structures-and-encoding/patricia-merkle-trie/) नावाची एक प्रचंड डेटा रचना आहे, जी सर्व [खाती](/developers/docs/accounts/) हॅशद्वारे जोडलेली ठेवते आणि ब्लॉकचेनवर संग्रहित एकाच रूट हॅशमध्ये कमी करता येते. + +### व्यवहार {#transactions} + +व्यवहार हे खात्यांमधून क्रिप्टोग्राफिकली स्वाक्षरी केलेल्या सूचना आहेत. दोन प्रकारचे व्यवहार आहेत: ज्यामुळे मेसेज कॉल्स होतात आणि ज्यामुळे कॉन्ट्रॅक्ट निर्मिती होते. + +कॉन्ट्रॅक्ट निर्मितीमुळे एक नवीन कॉन्ट्रॅक्ट खाते तयार होते ज्यामध्ये संकलित [स्मार्ट कॉन्ट्रॅक्ट](/developers/docs/smart-contracts/anatomy/) बायटकोड असतो. जेव्हा दुसरे खाते त्या कॉन्ट्रॅक्टला मेसेज कॉल करते, तेव्हा ते त्याचा बायटकोड कार्यान्वित करते. + +## EVM सूचना {#evm-instructions} + +EVM एक [स्टॅक मशीन](https://wikipedia.org/wiki/Stack_machine) म्हणून कार्यान्वित होते ज्याची खोली 1024 आयटम आहे. प्रत्येक आयटम एक 256-बिट शब्द आहे, जो 256-बिट क्रिप्टोग्राफीसह (जसे की Keccak-256 हॅश किंवा secp256k1 स्वाक्षरी) वापरण्याच्या सुलभतेसाठी निवडला गेला होता. + +अंमलबजावणी दरम्यान, EVM एक क्षणिक _मेमरी_ (शब्द-पत्ता असलेल्या बाइट ॲरे म्हणून) ठेवते, जी व्यवहारांमध्ये टिकत नाही. + +### क्षणिक स्टोरेज + +क्षणिक स्टोरेज हे प्रति-व्यवहार की-व्हॅल्यू स्टोअर आहे, जे `TSTORE` आणि `TLOAD` ऑपकोड्सद्वारे ऍक्सेस केले जाते. हे त्याच व्यवहारादरम्यान सर्व अंतर्गत कॉल्समध्ये टिकते, पण व्यवहाराच्या शेवटी साफ केले जाते. मेमरीच्या विपरीत, क्षणिक स्टोरेजला एक्झिक्यूशन फ्रेमऐवजी EVM स्थितीचा भाग म्हणून मॉडेल केले आहे, तरीही ते जागतिक स्थितीसाठी वचनबद्ध नाही. क्षणिक स्टोरेज व्यवहारादरम्यान अंतर्गत कॉल्समध्ये गॅस-कार्यक्षम तात्पुरती स्थिती शेअरिंग सक्षम करते. + +### स्टोरेज + +कॉन्ट्रॅक्ट्समध्ये एक मर्केल पॅट्रिशिया _स्टोरेज_ ट्राय (एक शब्द-पत्ता असलेला शब्द ॲरे म्हणून) असतो, जो संबंधित खात्याशी जोडलेला आणि जागतिक स्थितीचा भाग असतो. हे कायमस्वरूपी स्टोरेज क्षणिक स्टोरेजपेक्षा वेगळे आहे, जे फक्त एका व्यवहाराच्या कालावधीसाठी उपलब्ध असते आणि खात्याच्या कायमस्वरूपी स्टोरेज ट्रायचा भाग बनत नाही. + +### ऑपकोड्स + +संकलित स्मार्ट कॉन्ट्रॅक्ट बायटकोड अनेक EVM [ऑपकोड्स](/developers/docs/evm/opcodes) म्हणून कार्यान्वित होतो, जे `XOR`, `AND`, `ADD`, `SUB`, इत्यादींसारखी मानक स्टॅक ऑपरेशन्स करतात. EVM `ADDRESS`, `BALANCE`, `BLOCKHASH`, इत्यादींसारखी अनेक ब्लॉकचेन-विशिष्ट स्टॅक ऑपरेशन्स देखील लागू करते. ऑपकोड संचामध्ये `TSTORE` आणि `TLOAD` चा देखील समावेश आहे, जे क्षणिक स्टोरेजमध्ये प्रवेश प्रदान करतात. + +![EVM ऑपरेशन्ससाठी गॅस कोठे आवश्यक आहे हे दर्शविणारा एक आकृती](../gas/gas.png) +_[इथेरियम EVM सचित्र](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित आकृती_ + +## EVM अंमलबजावणी {#evm-implementations} + +EVM च्या सर्व अंमलबजावणींना इथेरियम यलोपेपरमध्ये वर्णन केलेल्या विनिर्देशनाचे पालन करणे आवश्यक आहे. + +इथेरियमच्या दहा वर्षांच्या इतिहासात, EVM मध्ये अनेक सुधारणा झाल्या आहेत, आणि विविध प्रोग्रामिंग भाषांमध्ये EVM च्या अनेक अंमलबजावणी आहेत. + +[इथेरियम एक्झिक्यूशन क्लायंट्स](/developers/docs/nodes-and-clients/#execution-clients) मध्ये EVM अंमलबजावणीचा समावेश आहे. याव्यतिरिक्त, अनेक स्वतंत्र अंमलबजावणी आहेत, ज्यात समाविष्ट आहे: + +- [Py-EVM](https://github.com/ethereum/py-evm) - _Python_ +- [evmone](https://github.com/ethereum/evmone) - _C++_ +- [ethereumjs-vm](https://github.com/ethereumjs/ethereumjs-vm) - _JavaScript_ +- [revm](https://github.com/bluealloy/revm) - _Rust_ + +## अधिक वाचन {#further-reading} + +- [इथेरियम यलोपेपर](https://ethereum.github.io/yellowpaper/paper.pdf) +- [जेलोपेपर उर्फ KEVM: K मध्ये EVM चे सिमेंटिक्स](https://jellopaper.org/) +- [द बेजपेपर](https://github.com/chronaeon/beigepaper) +- [इथेरियम व्हर्च्युअल मशीन ऑपकोड्स](https://www.ethervm.io/) +- [इथेरियम व्हर्च्युअल मशीन ऑपकोड्स इंटरएक्टिव्ह रेफरन्स](https://www.evm.codes/) +- [Solidity च्या माहितीमधील एक संक्षिप्त परिचय](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#index-6) +- [मास्टरिंग इथेरियम - इथेरियम व्हर्च्युअल मशीन](https://github.com/ethereumbook/ethereumbook/blob/openedition/13evm.asciidoc) + +## संबंधित विषय {#related-topics} + +- [गॅस](/developers/docs/gas/) diff --git a/public/content/translations/mr/developers/docs/evm/opcodes/index.md b/public/content/translations/mr/developers/docs/evm/opcodes/index.md new file mode 100644 index 00000000000..109363988b3 --- /dev/null +++ b/public/content/translations/mr/developers/docs/evm/opcodes/index.md @@ -0,0 +1,177 @@ +--- +title: "EVM साठी ओपकोड्स" +description: "इथेरियम व्हर्च्युअल मशीनसाठी सर्व उपलब्ध ऑपकोड्सची सूची." +lang: mr +--- + +## आढावा {#overview} + +हे [wolflo/evm-opcodes](https://github.com/wolflo/evm-opcodes) येथील EVM संदर्भ पृष्ठाची अद्ययावत आवृत्ती आहे. +[यलो पेपर](https://ethereum.github.io/yellowpaper/paper.pdf), [जेलो पेपर](https://jellopaper.org/evm/) आणि [गेथ](https://github.com/ethereum/go-ethereum) अंमलबजावणीमधून देखील घेतले आहे. +हा एक सुलभ संदर्भ म्हणून आहे, परंतु तो विशेष सखोल नाही. +तुम्हाला अचूकतेची खात्री हवी असल्यास आणि प्रत्येक एज केसबद्दल जागरूक राहायचे असल्यास, जेलो पेपर किंवा क्लायंट अंमलबजावणी वापरण्याचा सल्ला दिला जातो. + +परस्परसंवादी संदर्भ शोधत आहात? [evm.codes](https://www.evm.codes/) पहा. + +डायनॅमिक गॅस खर्चासह ऑपरेशन्ससाठी, [gas.md](https://github.com/wolflo/evm-opcodes/blob/main/gas.md) पहा. + +💡 द्रुत टीप: संपूर्ण ओळी पाहण्यासाठी, डेस्कटॉपवर आडवे स्क्रोल करण्यासाठी `[shift] + scroll` वापरा. + +| स्टॅक | नाव | गॅस | प्रारंभिक स्टॅक | परिणामी स्टॅक | मेम / स्टोरेज | टीप | | +| :---: | :------------- | :---------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| 00 | STOP | 0 | | | | अंमलबजावणी थांबवते | | +| 01 | ADD | 3 | `a, b` | `a + b` | | (u)int256 बेरीज मोड्युलो 2\*\*256 | | +| 02 | MUL | 5 | `a, b` | `a * b` | | (u)int256 गुणाकार मोड्युलो 2\*\*256 | | +| 03 | SUB | 3 | `a, b` | `a - b` | | (u)int256 वजाबाकी मोड्युलो 2\*\*256 | | +| 04 | DIV | 5 | `a, b` | `a // b` | | uint256 भागाकार | | +| 05 | SDIV | 5 | `a, b` | `a // b` | | int256 भागाकार | | +| 06 | MOD | 5 | `a, b` | `a % b` | | uint256 मोड्युलस | | +| 07 | SMOD | 5 | `a, b` | `a % b` | | int256 मोड्युलस | | +| 08 | ADDMOD | 8 | `a, b, N` | `(a + b) % N` | | (u)int256 बेरीज मोड्युलो N | | +| 09 | MULMOD | 8 | `a, b, N` | `(a * b) % N` | | (u)int256 गुणाकार मोड्युलो N | | +| 0A | EXP | [A1](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a1-exp) | `a, b` | `a ** b` | | uint256 घातांक मोड्युलो 2\*\*256 | | +| 0B | SIGNEXTEND | 5 | `b, x` | `SIGNEXTEND(x, b)` | | [साइन वाढवा](https://wikipedia.org/wiki/Sign_extension) `x` ला `(b+1)` बाइट्सपासून 32 बाइट्सपर्यंत | | +| 0C-0F | _अवैध_ | | | | | | | +| 10 | LT | 3 | `a, b` | `a < b` | | uint256 पेक्षा कमी | | +| 11 | GT | 3 | `a, b` | `a > b` | | uint256 पेक्षा मोठे | | +| 12 | SLT | 3 | `a, b` | `a < b` | | int256 पेक्षा कमी | | +| 13 | SGT | 3 | `a, b` | `a > b` | | int256 पेक्षा मोठे | | +| 14 | EQ | 3 | `a, b` | `a == b` | | (u)int256 समानता | | +| 15 | ISZERO | 3 | `a` | `a == 0` | | (u)int256 शून्य आहे | | +| 16 | AND | 3 | `a, b` | `a && b` | | बिटवाईज AND | | +| 17 | OR | 3 | `a, b` | `a \\|\\| b` | | बिटवाईज OR | | +| 18 | XOR | 3 | `a, b` | `a ^ b` | | बिटवाईज XOR | | +| 19 | NOT | 3 | `a` | `~a` | | बिटवाईज NOT | | +| 1A | BYTE | 3 | `i, x` | `(x >> (248 - i * 8)) && 0xFF` | | (u)int256 `x` चा डावीकडून `i`वा बाइट | | +| 1B | SHL | 3 | `shift, val` | `val << shift` | | डावीकडे शिफ्ट करतो | | +| 1C | SHR | 3 | `shift, val` | `val >> shift` | | लॉजिकल शिफ्ट राईट | | +| 1D | SAR | 3 | `shift, val` | `val >> shift` | | अरिथमॅटिक शिफ्ट राईट | | +| 1E-1F | _अवैध_ | | | | | | | +| 20 | KECCAK256 | [A2](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a2-sha3) | `ost, len` | `keccak256(mem[ost:ost+len-1])` | | keccak256 | | +| 21-2F | _अवैध_ | | | | | | | +| 30 | ADDRESS | 2 | `.` | `address(this)` | | अंमलबजावणी करणाऱ्या कराराचा पत्ता | | +| 31 | BALANCE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `addr.balance` | | शिल्लक, wei मध्ये | | +| 32 | ORIGIN | 2 | `.` | `tx.origin` | | tx सुरू करणारा पत्ता | | +| 33 | CALLER | 2 | `.` | `msg.sender` | | msg पाठवणाऱ्याचा पत्ता | | +| 34 | CALLVALUE | 2 | `.` | `msg.value` | | msg मूल्य, wei मध्ये | | +| 35 | CALLDATALOAD | 3 | `idx` | `msg.data[idx:idx+32]` | | निर्देशांक `idx` वरून msg डेटामधून शब्द वाचतो | | +| 36 | CALLDATASIZE | 2 | `.` | `len(msg.data)` | | msg डेटाची लांबी, बाइट्समध्ये | | +| 37 | CALLDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := msg.data[ost:ost+len-1] | msg डेटा कॉपी करतो | | +| 38 | CODESIZE | 2 | `.` | `len(this.code)` | | अंमलबजावणी करणाऱ्या कराराच्या कोडची लांबी, बाइट्समध्ये | | +| 39 | CODECOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | | mem[dstOst:dstOst+len-1] := this.code[ost:ost+len-1] | अंमलबजावणी करणाऱ्या कराराचा बायटेकोड कॉपी करतो | +| 3A | GASPRICE | 2 | `.` | `tx.gasprice` | | tx ची गॅस किंमत, प्रति युनिट गॅस wei मध्ये [\*\*](https://eips.ethereum.org/EIPS/eip-1559#gasprice) | | +| 3B | EXTCODESIZE | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `len(addr.code)` | | addr वरील कोडचा आकार, बाइट्समध्ये | | +| 3C | EXTCODECOPY | [A4](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a4-extcodecopy) | `addr, dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := addr.code[ost:ost+len-1] | `addr` मधून कोड कॉपी करतो | | +| 3D | RETURNDATASIZE | 2 | `.` | `size` | | मागील बाह्य कॉलमधून परत आलेल्या डेटाचा आकार, बाइट्समध्ये | | +| 3E | RETURNDATACOPY | [A3](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a3-copy-operations) | `dstOst, ost, len` | `.` | mem[dstOst:dstOst+len-1] := returndata[ost:ost+len-1] | मागील बाह्य कॉलमधून परत आलेला डेटा कॉपी करतो | | +| 3F | EXTCODEHASH | [A5](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a5-balance-extcodesize-extcodehash) | `addr` | `hash` | | हॅश = addr.exists ? keccak256(addr.code) : 0 | | +| 40 | BLOCKHASH | 20 | `blockNum` | `blockHash(blockNum)` | | | | +| 41 | COINBASE | 2 | `.` | `block.coinbase` | | सध्याच्या ब्लॉकच्या प्रस्तावकचा पत्ता | | +| 42 | TIMESTAMP | 2 | `.` | `block.timestamp` | | सध्याच्या ब्लॉकचा टाइमस्टॅम्प | | +| 43 | NUMBER | 2 | `.` | `block.number` | | सध्याच्या ब्लॉकचा क्रमांक | | +| 44 | PREVRANDAO | 2 | `.` | `randomness beacon` | | रँडमनेस बीकन | | +| 45 | GASLIMIT | 2 | `.` | `block.gaslimit` | | सध्याच्या ब्लॉकची गॅस मर्यादा | | +| 46 | CHAINID | 2 | `.` | `chain_id` | | सध्याचा [चेन आयडी](https://eips.ethereum.org/EIPS/eip-155) स्टॅकवर पुश करतो | | +| 47 | SELFBALANCE | 5 | `.` | `address(this).balance` | | अंमलबजावणी करणाऱ्या कराराची शिल्लक, wei मध्ये | | +| 48 | BASEFEE | 2 | `.` | `block.basefee` | | सध्याच्या ब्लॉकची बेस फी | | +| 49 | BLOBHASH | 3 | `idx` | `tx.blob_versioned_hashes[idx]` | | [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) | | +| 4A | BLOBBASEFEE | 2 | `.` | `block.blobbasefee` | | सध्याच्या ब्लॉकची ब्लॉब बेस फी ([EIP-7516](https://eips.ethereum.org/EIPS/eip-7516)) | | +| 4B-4F | _अवैध_ | | | | | | | +| 50 | POP | 2 | `_anon` | `.` | | स्टॅकच्या वरून आयटम काढून टाकतो आणि टाकून देतो | | +| 51 | MLOAD | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost` | `mem[ost:ost+32]` | | ऑफसेट `ost` वरून मेमरीमधून शब्द वाचतो | | +| 52 | MSTORE | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost:ost+32] := val | मेमरीमध्ये एक शब्द लिहितो | | +| 53 | MSTORE8 | 3[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, val` | `.` | mem[ost] := val && 0xFF | मेमरीमध्ये एकच बाइट लिहितो | | +| 54 | SLOAD | [A6](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a6-sload) | `key` | `storage[key]` | | स्टोरेजमधून शब्द वाचतो | | +| 55 | SSTORE | [A7](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a7-sstore) | `key, val` | `.` | storage[key] := val | स्टोरेजमध्ये शब्द लिहितो | | +| 56 | JUMP | 8 | `dst` | `.` | | `$pc := dst` हे चिन्हांकित करते की `pc` फक्त तेव्हाच नियुक्त केले जाते जेव्हा `dst` एक वैध जंपडेस्ट असेल | | +| 57 | JUMPI | 10 | `dst, condition` | `.` | | `$pc := condition ?` dst : $pc + 1` | | +| 58 | PC | 2 | `.` | `$pc` | | प्रोग्राम काउंटर | | +| 59 | MSIZE | 2 | `.` | `len(mem)` | | सध्याच्या अंमलबजावणी संदर्भात मेमरीचा आकार, बाइट्समध्ये | | +| 5A | GAS | 2 | `.` | `gasRemaining` | | | | +| 5B | JUMPDEST | 1 | | | वैध जंप डेस्टिनेशन चिन्हांकित करतो | एक वैध जंप डेस्टिनेशन उदाहरणार्थ पुश डेटामध्ये नसलेले जंप डेस्टिनेशन | | +| 5C | TLOAD | 100 | `key` | `tstorage[key]` | | क्षणिक स्टोरेजमधून शब्द वाचतो ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) | | +| 5D | TSTORE | 100 | `key, val` | `.` | tstorage[key] := val | क्षणिक स्टोरेजमध्ये शब्द लिहितो ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153)) | | +| 5E | MCOPY | 3+3\*words+[A0](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `dstOst, ost, len` | `.` | mem[dstOst] := mem[ost:ost+len] | मेमरी एका भागातून दुसऱ्या भागात कॉपी करतो ([EIP-5656](https://eips.ethereum.org/EIPS/eip-5656)) | | +| 5F | PUSH0 | 2 | `.` | `uint8` | | स्थिर मूल्य 0 स्टॅकवर पुश करतो | | +| 60 | PUSH1 | 3 | `.` | `uint8` | | स्टॅकवर 1-बाइट मूल्य पुश करतो | | +| 61 | PUSH2 | 3 | `.` | `uint16` | | स्टॅकवर 2-बाइट मूल्य पुश करतो | | +| 62 | PUSH3 | 3 | `.` | `uint24` | | स्टॅकवर 3-बाइट मूल्य पुश करतो | | +| 63 | PUSH4 | 3 | `.` | `uint32` | | स्टॅकवर 4-बाइट मूल्य पुश करतो | | +| 64 | PUSH5 | 3 | `.` | `uint40` | | स्टॅकवर 5-बाइट मूल्य पुश करतो | | +| 65 | PUSH6 | 3 | `.` | `uint48` | | स्टॅकवर 6-बाइट मूल्य पुश करतो | | +| 66 | PUSH7 | 3 | `.` | `uint56` | | स्टॅकवर 7-बाइट मूल्य पुश करतो | | +| 67 | PUSH8 | 3 | `.` | `uint64` | | स्टॅकवर 8-बाइट मूल्य पुश करतो | | +| 68 | PUSH9 | 3 | `.` | `uint72` | | स्टॅकवर 9-बाइट मूल्य पुश करतो | | +| 69 | PUSH10 | 3 | `.` | `uint80` | | स्टॅकवर 10-बाइट मूल्य पुश करतो | | +| 6A | PUSH11 | 3 | `.` | `uint88` | | स्टॅकवर 11-बाइट मूल्य पुश करतो | | +| 6B | PUSH12 | 3 | `.` | `uint96` | | स्टॅकवर 12-बाइट मूल्य पुश करतो | | +| 6C | PUSH13 | 3 | `.` | `uint104` | | स्टॅकवर 13-बाइट मूल्य पुश करतो | | +| 6D | PUSH14 | 3 | `.` | `uint112` | | स्टॅकवर 14-बाइट मूल्य पुश करतो | | +| 6E | PUSH15 | 3 | `.` | `uint120` | | स्टॅकवर 15-बाइट मूल्य पुश करतो | | +| 6F | PUSH16 | 3 | `.` | `uint128` | | स्टॅकवर 16-बाइट मूल्य पुश करतो | | +| 70 | PUSH17 | 3 | `.` | `uint136` | | स्टॅकवर 17-बाइट मूल्य पुश करतो | | +| 71 | PUSH18 | 3 | `.` | `uint144` | | स्टॅकवर 18-बाइट मूल्य पुश करतो | | +| 72 | PUSH19 | 3 | `.` | `uint152` | | स्टॅकवर 19-बाइट मूल्य पुश करतो | | +| 73 | PUSH20 | 3 | `.` | `uint160` | | स्टॅकवर 20-बाइट मूल्य पुश करतो | | +| 74 | PUSH21 | 3 | `.` | `uint168` | | स्टॅकवर 21-बाइट मूल्य पुश करतो | | +| 75 | PUSH22 | 3 | `.` | `uint176` | | स्टॅकवर 22-बाइट मूल्य पुश करतो | | +| 76 | PUSH23 | 3 | `.` | `uint184` | | स्टॅकवर 23-बाइट मूल्य पुश करतो | | +| 77 | PUSH24 | 3 | `.` | `uint192` | | स्टॅकवर 24-बाइट मूल्य पुश करतो | | +| 78 | PUSH25 | 3 | `.` | `uint200` | | स्टॅकवर 25-बाइट मूल्य पुश करतो | | +| 79 | PUSH26 | 3 | `.` | `uint208` | | स्टॅकवर 26-बाइट मूल्य पुश करतो | | +| 7A | PUSH27 | 3 | `.` | `uint216` | | स्टॅकवर 27-बाइट मूल्य पुश करतो | | +| 7B | PUSH28 | 3 | `.` | `uint224` | | स्टॅकवर 28-बाइट मूल्य पुश करतो | | +| 7C | PUSH29 | 3 | `.` | `uint232` | | स्टॅकवर 29-बाइट मूल्य पुश करतो | | +| 7D | PUSH30 | 3 | `.` | `uint240` | | स्टॅकवर 30-बाइट मूल्य पुश करतो | | +| 7E | PUSH31 | 3 | `.` | `uint248` | | स्टॅकवर 31-बाइट मूल्य पुश करतो | | +| 7F | PUSH32 | 3 | `.` | `uint256` | | स्टॅकवर 32-बाइट मूल्य पुश करतो | | +| 80 | DUP1 | 3 | `a` | `a, a` | | स्टॅकवरील पहिल्या मूल्याची प्रतिकृती करतो | | +| 81 | DUP2 | 3 | `_, a` | `a, _, a` | | स्टॅकवरील दुसऱ्या मूल्याची प्रतिकृती करतो | | +| 82 | DUP3 | 3 | `_, _, a` | `a, _, _, a` | | स्टॅकवरील तिसऱ्या मूल्याची प्रतिकृती करतो | | +| 83 | DUP4 | 3 | `_, _, _, a` | `a, _, _, _, a` | | स्टॅकवरील चौथ्या मूल्याची प्रतिकृती करतो | | +| 84 | DUP5 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील पाचव्या मूल्याची प्रतिकृती करतो | | +| 85 | DUP6 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील सहाव्या मूल्याची प्रतिकृती करतो | | +| 86 | DUP7 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील सातव्या मूल्याची प्रतिकृती करतो | | +| 87 | DUP8 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील आठव्या मूल्याची प्रतिकृती करतो | | +| 88 | DUP9 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील नवव्या मूल्याची प्रतिकृती करतो | | +| 89 | DUP10 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील दहाव्या मूल्याची प्रतिकृती करतो | | +| 8A | DUP11 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील अकराव्या मूल्याची प्रतिकृती करतो | | +| 8B | DUP12 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील बाराव्या मूल्याची प्रतिकृती करतो | | +| 8C | DUP13 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील तेराव्या मूल्याची प्रतिकृती करतो | | +| 8D | DUP14 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील चौदाव्या मूल्याची प्रतिकृती करतो | | +| 8E | DUP15 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील पंधराव्या मूल्याची प्रतिकृती करतो | | +| 8F | DUP16 | 3 | `..., a` | `a, ..., a` | | स्टॅकवरील सोळाव्या मूल्याची प्रतिकृती करतो | | +| 90 | SWAP1 | 3 | `a, b` | `b, a` | | | | +| 91 | SWAP2 | 3 | `a, _, b` | `b, _, a` | | | | +| 92 | SWAP3 | 3 | `a, _, _, b` | `b, _, _, a` | | | | +| 93 | SWAP4 | 3 | `a, _, _, _, b` | `b, _, _, _, a` | | | | +| 94 | SWAP5 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 95 | SWAP6 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 96 | SWAP7 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 97 | SWAP8 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 98 | SWAP9 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 99 | SWAP10 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9A | SWAP11 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9B | SWAP12 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9C | SWAP13 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9D | SWAP14 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9E | SWAP15 | 3 | `a, ..., b` | `b, ..., a` | | | | +| 9F | SWAP16 | 3 | `a, ..., b` | `b, ..., a` | | | | +| A0 | LOG0 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len` | `.` | | LOG0(memory[ost:ost+len-1]) | | +| A1 | LOG1 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0` | `.` | | LOG1(memory[ost:ost+len-1], topic0) | | +| A2 | LOG2 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1` | `.` | | LOG2(memory[ost:ost+len-1], topic0, topic1) | | +| A3 | LOG3 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2` | `.` | | LOG3(memory[ost:ost+len-1], topic0, topic1, topic2) | | +| A4 | LOG4 | [A8](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a8-log-operations) | `ost, len, topic0, topic1, topic2, topic3` | `.` | | LOG4(memory[ost:ost+len-1], topic0, topic1, topic2, topic3) | | +| A5-EF | _अवैध_ | | | | | | | +| F0 | CREATE | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len` | `addr` | | addr = keccak256(rlp([address(this), this.nonce])) | | +| F1 | CALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | gas, addr, val, argOst, argLen, retOst, retLen | `success` | mem[retOst:retOst+retLen-1] := returndata | | | +| F2 | CALLCODE | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, val, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] = returndata | DELEGATECALL प्रमाणेच, परंतु मूळ msg.sender आणि msg.value प्रसारित करत नाही | | +| F3 | RETURN | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | return mem[ost:ost+len-1] | | +| F4 | DELEGATECALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | | +| F5 | CREATE2 | [A9](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations) | `val, ost, len, salt` | `addr` | | addr = keccak256(0xff ++ address(this) ++ salt ++ keccak256(mem[ost:ost+len-1]))[12:] | | +| F6-F9 | _अवैध_ | | | | | | | +| FA | STATICCALL | [AA](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#aa-call-operations) | `gas, addr, argOst, argLen, retOst, retLen` | `success` | mem[retOst:retOst+retLen-1] := returndata | | | +| FB-FC | _अवैध_ | | | | | | | +| FD | REVERT | 0[\*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a0-1-memory-expansion) | `ost, len` | `.` | | revert(mem[ost:ost+len-1]) | | +| FE | INVALID | [AF](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#af-invalid) | | | निर्दिष्ट अवैध ऑपकोड - [EIP-141](https://eips.ethereum.org/EIPS/eip-141) | | | +| FF | SELFDESTRUCT | [AB](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#ab-selfdestruct) | `addr` | `.` | | सर्व ETH `addr` ला पाठवते; जर करार तयार केलेल्या त्याच व्यवहारात कार्यान्वित केले तर ते करार नष्ट करते | | diff --git a/public/content/translations/mr/developers/docs/frameworks/index.md b/public/content/translations/mr/developers/docs/frameworks/index.md new file mode 100644 index 00000000000..e9c602b2f2d --- /dev/null +++ b/public/content/translations/mr/developers/docs/frameworks/index.md @@ -0,0 +1,156 @@ +--- +title: "DApp विकास फ्रेमवर्क्स" +description: "फ्रेमवर्कच्या फायद्यांचे अन्वेषण करा आणि उपलब्ध पर्यायांची तुलना करा." +lang: mr +--- + +## फ्रेमवर्कची ओळख {#introduction-to-frameworks} + +एक परिपूर्ण DApp तयार करण्यासाठी +वेगवेगळ्या तंत्रज्ञानाची आवश्यकता असते. सॉफ्टवेअर फ्रेमवर्क्समध्ये अनेक आवश्यक +वैशिष्ट्ये समाविष्ट असतात किंवा तुम्हाला हवी असलेली साधने निवडण्यासाठी सोप्या प्लगइन प्रणाली पुरवतात. + +फ्रेमवर्क्स बऱ्याच आउट-ऑफ-द-बॉक्स कार्यक्षमतेसह येतात, +जसे की: + +- स्थानिक ब्लॉकचेन उदाहरण स्पिन अप करण्यासाठी वैशिष्ट्ये. +- तुमचे स्मार्ट कॉन्ट्रॅक्ट संकलित करण्यासाठी आणि चाचणी करण्यासाठी उपयुक्तता. +- त्याच प्रोजेक्ट/रिपॉझिटरीमध्ये तुमचा वापरकर्ता-केंद्रित ॲप्लिकेशन तयार करण्यासाठी + क्लायंट डेव्हलपमेंट ॲड-ऑन्स. +- Ethereum नेटवर्क्सशी कनेक्ट होण्यासाठी आणि कॉन्ट्रॅक्ट्स तैनात करण्यासाठी + कॉन्फिगरेशन, मग ते स्थानिक पातळीवर चालणाऱ्या इन्स्टन्सवर असो, किंवा Ethereum च्या + सार्वजनिक नेटवर्क्सपैकी एकावर असो. +- विकेंद्रित ॲप वितरण - IPFS सारख्या स्टोरेज + पर्यायांसह एकत्रीकरण. + +## पूर्वतयारी {#prerequisites} + +फ्रेमवर्क्समध्ये खोलवर जाण्यापूर्वी, आम्ही शिफारस करतो की तुम्ही प्रथम आमची [dapps](/developers/docs/dapps/) आणि [Ethereum स्टॅक](/developers/docs/ethereum-stack/) ची ओळख वाचून घ्या. + +## उपलब्ध फ्रेमवर्क्स {#available-frameworks} + +**Foundry** - **_Foundry हे Ethereum ऍप्लिकेशन डेव्हलपमेंटसाठी एक अतिशय वेगवान, पोर्टेबल आणि मॉड्युलर टूलकिट आहे_** + +- [Foundry इंस्टॉल करा](https://book.getfoundry.sh/) +- [Foundry पुस्तक](https://book.getfoundry.sh/) +- [Telegram वर Foundry कम्युनिटी चॅट](https://t.me/foundry_support) +- [ऑसम Foundry](https://github.com/crisgarner/awesome-foundry) + +**Hardhat -** **_व्यावसायिकांसाठी Ethereum विकास वातावरण._** + +- [hardhat.org](https://hardhat.org) +- [GitHub](https://github.com/nomiclabs/hardhat) + +**Ape -** **_पायथनिस्ट, डेटा सायंटिस्ट आणि सुरक्षा व्यावसायिकांसाठी स्मार्ट कॉन्ट्रॅक्ट डेव्हलपमेंट टूल._** + +- [दस्तऐवजीकरण](https://docs.apeworx.io/ape/stable/) +- [GitHub](https://github.com/ApeWorX/ape) + +**Web3j -** **_JVM वर ब्लॉकचेन ऍप्लिकेशन्स विकसित करण्यासाठी एक प्लॅटफॉर्म._** + +- [होमपेज](https://www.web3labs.com/web3j-sdk) +- [दस्तऐवजीकरण](https://docs.web3j.io) +- [GitHub](https://github.com/web3j/web3j) + +**ethers-kt -** **_EVM-आधारित ब्लॉकचेनसाठी Async, उच्च-कार्यक्षमता असलेली Kotlin/Java/Android लायब्ररी._** + +- [GitHub](https://github.com/Kr1ptal/ethers-kt) +- [उदाहरणे](https://github.com/Kr1ptal/ethers-kt/tree/master/examples) +- [Discord](https://discord.gg/rx35NzQGSb) + +**Create Eth App -** **_एका कमांडने Ethereum-सक्षम ॲप्स तयार करा. निवडण्यासाठी UI फ्रेमवर्क्स आणि DeFi टेम्पलेट्सच्या विस्तृत श्रेणीसह येते._** + +- [GitHub](https://github.com/paulrberg/create-eth-app) +- [टेम्पलेट्स](https://github.com/PaulRBerg/create-eth-app/tree/develop/templates) + +**Scaffold-Eth -** **_Ethers.js + Hardhat + web3 साठी React कंपोनंट्स आणि हुक्स: स्मार्ट कॉन्ट्रॅक्ट्सद्वारे चालणाऱ्या विकेंद्रित ॲप्लिकेशन्सची निर्मिती सुरू करण्यासाठी तुम्हाला आवश्यक असलेले सर्वकाही._** + +- [GitHub](https://github.com/scaffold-eth/scaffold-eth-2) + +**Tenderly -** **_Web3 डेव्हलपमेंट प्लॅटफॉर्म जे ब्लॉकचेन डेव्हलपर्सना स्मार्ट कॉन्ट्रॅक्ट्स तयार करणे, तपासणे, डीबग करणे, मॉनिटर करणे, आणि ऑपरेट करण्यास आणि dApp UX सुधारण्यास सक्षम करते._** + +- [वेबसाईट](https://tenderly.co/) +- [दस्तऐवजीकरण](https://docs.tenderly.co/) + +**The Graph -** **_ब्लॉकचेन डेटा कार्यक्षमतेने क्वेरी करण्यासाठी._** + +- [वेबसाईट](https://thegraph.com/) +- [ट्यूटोरियल](/developers/tutorials/the-graph-fixing-web3-data-querying/) + +**Alchemy -** **_Ethereum डेव्हलपमेंट प्लॅटफॉर्म._** + +- [alchemy.com](https://www.alchemy.com/) +- [GitHub](https://github.com/alchemyplatform) +- [Discord](https://discord.com/invite/alchemyplatform) + +**NodeReal -** **_Ethereum डेव्हलपमेंट प्लॅटफॉर्म._** + +- [Nodereal.io](https://nodereal.io/) +- [GitHub](https://github.com/node-real) +- [Discord](https://discord.gg/V5k5gsuE) + +**thirdweb SDK -** **_आमच्या शक्तिशाली SDKs आणि CLI चा वापर करून तुमच्या स्मार्ट कॉन्ट्रॅक्ट्ससोबत संवाद साधू शकणारे web3 ॲप्लिकेशन्स तयार करा._** + +- [दस्तऐवजीकरण](https://portal.thirdweb.com/sdk/) +- [GitHub](https://github.com/thirdweb-dev/) + +**Chainstack -** **_Web3 (Ethereum आणि इतर) डेव्हलपमेंट प्लॅटफॉर्म._** + +- [chainstack.com](https://www.chainstack.com/) +- [GitHub](https://github.com/chainstack) +- [Discord](https://discord.gg/BSb5zfp9AT) + +**Crossmint -** **_एंटरप्राइझ-ग्रेड web3 डेव्हलपमेंट प्लॅटफॉर्म, जो तुम्हाला सर्व प्रमुख EVM चेन्स (आणि इतरांवर) NFT ॲप्लिकेशन्स तयार करण्याची परवानगी देतो._** + +- [वेबसाईट](https://www.crossmint.com) +- [दस्तऐवजीकरण](https://docs.crossmint.com) +- [Discord](https://discord.com/invite/crossmint) + +**Brownie -** **_पायथन-आधारित डेव्हलपमेंट एनव्हायर्नमेंट आणि टेस्टिंग फ्रेमवर्क._** + +- [दस्तऐवजीकरण](https://eth-brownie.readthedocs.io/en/latest/) +- [GitHub](https://github.com/eth-brownie/brownie) +- **Brownie ची देखभाल सध्या केली जात नाही** + +**OpenZeppelin SDK -** **_अल्टिमेट स्मार्ट कॉन्ट्रॅक्ट टूलकिट: साधनांचा एक संच जो तुम्हाला स्मार्ट कॉन्ट्रॅक्ट्स विकसित करणे, कंपाईल करणे, अपग्रेड करणे, तैनात करणे आणि त्यांच्याशी संवाद साधण्यात मदत करतो._** + +- [OpenZeppelin डिफेंडर SDK](https://docs.openzeppelin.com/defender/sdk) +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-sdk) +- [कम्युनिटी फोरम](https://forum.openzeppelin.com/c/support/17) +- **OpenZeppelin SDK चा विकास थांबला आहे** + +**Catapulta -** **_मल्टी-चेन स्मार्ट कॉन्ट्रॅक्ट्स डिप्लॉयमेंट टूल, ब्लॉक एक्सप्लोररमध्ये व्हेरिफिकेशन्स ऑटोमेट करते, डिप्लॉय केलेल्या स्मार्ट कॉन्ट्रॅक्ट्सचा मागोवा ठेवते आणि डिप्लॉयमेंट रिपोर्ट्स शेअर करते, Foundry आणि Hardhat प्रोजेक्ट्ससाठी प्लग-एन-प्ले._** + +- [वेबसाईट](https://catapulta.sh/) +- [दस्तऐवजीकरण](https://catapulta.sh/docs) +- [Github](https://github.com/catapulta-sh) + +**GoldRush (Covalent द्वारा समर्थित) -** **_GoldRush डेव्हलपर्स, विश्लेषक आणि एंटरप्राइझसाठी सर्वात व्यापक ब्लॉकचेन डेटा API सूट प्रदान करते. तुम्ही DeFi डॅशबोर्ड, वॉलेट, ट्रेडिंग बॉट, AI एजंट किंवा कंप्लायन्स प्लॅटफॉर्म तयार करत असाल, डेटा APIs तुम्हाला आवश्यक असलेल्या महत्त्वाच्या ऑनचेन डेटासाठी वेगवान, अचूक आणि डेव्हलपर-फ्रेंडली ऍक्सेस प्रदान करतात_** + +- [वेबसाईट](https://goldrush.dev/) +- [दस्तऐवजीकरण](https://goldrush.dev/docs/chains/ethereum) +- [GitHub](https://github.com/covalenthq) +- [Discord](https://www.covalenthq.com/discord/) + +**Wake -** **_कॉन्ट्रॅक्ट्स टेस्टिंग, फझिंग, डिप्लॉयमेंट, व्हल्नरेबिलिटी स्कॅनिंग आणि कोड नेव्हिगेशनसाठी ऑल-इन-वन पायथन फ्रेमवर्क._** + +- [होमपेज](https://getwake.io/) +- [दस्तऐवजीकरण](https://ackeeblockchain.com/wake/docs/latest/) +- [GitHub](https://github.com/Ackee-Blockchain/wake) +- [VS कोड एक्सटेन्शन](https://marketplace.visualstudio.com/items?itemName=AckeeBlockchain.tools-for-solidity) + +**Veramo -** **_ओपन सोर्स, मॉड्युलर आणि ॲग्नॉस्टिक फ्रेमवर्क जे विकेंद्रित ऍप्लिकेशन डेव्हलपर्ससाठी त्यांच्या ऍप्लिकेशन्समध्ये विकेंद्रित ओळख आणि व्हेरिफायेबल क्रेडेन्शियल्स तयार करणे सोपे करते._** + +- [होमपेज](https://veramo.io/) +- [दस्तऐवजीकरण](https://veramo.io/docs/basics/introduction) +- [GitHub](https://github.com/uport-project/veramo) +- [Discord](https://discord.com/invite/FRRBdjemHV) +- [NPM पॅकेज](https://www.npmjs.com/package/@veramo/core) + +## पुढील वाचन {#further-reading} + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ + +## संबंधित विषय {#related-topics} + +- [स्थानिक विकास वातावरण सेट अप करा](/developers/local-environment/) diff --git a/public/content/translations/mr/developers/docs/gas/index.md b/public/content/translations/mr/developers/docs/gas/index.md new file mode 100644 index 00000000000..f0a4f37bcce --- /dev/null +++ b/public/content/translations/mr/developers/docs/gas/index.md @@ -0,0 +1,151 @@ +--- +title: "गॅस आणि शुल्क" +metaTitle: "इथेरियम गॅस आणि शुल्क: तांत्रिक अवलोकन" +description: "इथेरियम गॅस शुल्काबद्दल जाणून घ्या, ते कसे मोजले जातात आणि नेटवर्क सुरक्षा आणि व्यवहार प्रक्रियेत त्यांची भूमिका काय आहे." +lang: mr +--- + +इथेरियम नेटवर्कसाठी गॅस आवश्यक आहे. हे ते इंधन आहे जे त्याला चालण्यास मदत करते, ज्याप्रमाणे गाडी चालवण्यासाठी पेट्रोलची गरज असते. + +## पूर्वतयारी {#prerequisites} + +हे पान अधिक चांगल्या प्रकारे समजून घेण्यासाठी, आम्ही शिफारस करतो की तुम्ही प्रथम [व्यवहार](/developers/docs/transactions/) आणि [EVM](/developers/docs/evm/) बद्दल वाचा. + +## गॅस म्हणजे काय? {#what-is-gas} + +गॅस म्हणजे इथेरियम नेटवर्कवर विशिष्ट ऑपरेशन्स कार्यान्वित करण्यासाठी आवश्यक असलेल्या संगणकीय प्रयत्नांचे मोजमाप करणारे एकक. + +प्रत्येक इथेरियम व्यवहाराला कार्यान्वित करण्यासाठी संगणकीय संसाधनांची आवश्यकता असल्याने, इथेरियम स्पॅमसाठी असुरक्षित नाही आणि अनंत संगणकीय लूपमध्ये अडकू शकत नाही हे सुनिश्चित करण्यासाठी त्या संसाधनांसाठी पैसे द्यावे लागतात. संगणनासाठीचे पेमेंट गॅस शुल्काच्या स्वरूपात केले जाते. + +गॅस शुल्क म्हणजे **कोणतेही ऑपरेशन करण्यासाठी वापरलेला गॅस, गुणिले प्रति युनिट गॅसची किंमत**. व्यवहार यशस्वी झाला किंवा अयशस्वी झाला तरीही शुल्क भरावे लागते. + +![EVM ऑपरेशन्समध्ये गॅसची कोठे आवश्यकता आहे हे दर्शविणारा आकृती](./gas.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित केलेला आकृती_ + +गॅस शुल्क इथेरियमच्या मूळ चलनात, इथर (ETH) मध्ये भरावे लागते. गॅसच्या किमती सामान्यतः gwei मध्ये उद्धृत केल्या जातात, जे ETH चे एक मूल्यमापन आहे. प्रत्येक gwei एका ETH च्या अब्जाव्या भागाइतका असतो (0.000000001 ETH किंवा 10-9 ETH). + +उदाहरणार्थ, तुमचा गॅस खर्च 0.000000001 इथर आहे असे म्हणण्याऐवजी, तुम्ही म्हणू शकता की तुमचा गॅस खर्च 1 gwei आहे. + +'gwei' हा शब्द 'giga-wei' चा संक्षेप आहे, ज्याचा अर्थ 'अब्ज wei' आहे. एक gwei म्हणजे एक अब्ज wei. Wei स्वतः ([b-money](https://www.investopedia.com/terms/b/bmoney.asp) चे निर्माते, [Wei Dai](https://wikipedia.org/wiki/Wei_Dai) यांच्या नावावरून) ETH चे सर्वात लहान एकक आहे. + +## गॅस शुल्क कसे मोजले जाते? {#how-are-gas-fees-calculated} + +तुम्ही व्यवहार सबमिट करता तेव्हा तुम्ही किती गॅस देण्यास इच्छुक आहात हे तुम्ही सेट करू शकता. विशिष्ट प्रमाणात गॅस ऑफर करून, तुम्ही तुमचा व्यवहार पुढील ब्लॉकमध्ये समाविष्ट करण्यासाठी बोली लावत आहात. जर तुम्ही खूप कमी ऑफर दिली, तर व्हॅलिडेटर्स तुमचा व्यवहार समाविष्ट करण्यासाठी निवडण्याची शक्यता कमी असते, याचा अर्थ तुमचा व्यवहार उशिरा किंवा अजिबात कार्यान्वित होणार नाही. जर तुम्ही खूप जास्त ऑफर दिली, तर तुम्ही काही ETH वाया घालवू शकता. तर, किती पैसे द्यायचे हे तुम्ही कसे सांगू शकता? + +तुम्ही देत असलेला एकूण गॅस दोन घटकांमध्ये विभागलेला आहे: `base fee` आणि `priority fee` (टिप). + +`base fee` प्रोटोकॉलद्वारे सेट केली जाते—तुमचा व्यवहार वैध मानला जाण्यासाठी तुम्हाला किमान ही रक्कम भरावी लागेल. `priority fee` ही एक टिप आहे जी तुम्ही बेस फीमध्ये जोडता, जेणेकरून तुमचा व्यवहार व्हॅलिडेटर्सना आकर्षक वाटेल आणि ते तो पुढील ब्लॉकमध्ये समाविष्ट करण्यासाठी निवडतील. + +फक्त `base fee` भरणारा व्यवहार तांत्रिकदृष्ट्या वैध आहे पण तो समाविष्ट होण्याची शक्यता कमी आहे कारण तो व्हॅलिडेटर्सना इतर कोणत्याही व्यवहारापेक्षा निवडण्यासाठी कोणतेही प्रोत्साहन देत नाही. 'योग्य' `priority` फी तुम्ही तुमचा व्यवहार पाठवता त्यावेळच्या नेटवर्कच्या वापराद्वारे निर्धारित केली जाते—जर जास्त मागणी असेल तर तुम्हाला तुमची `priority` फी जास्त सेट करावी लागेल, पण जेव्हा मागणी कमी असेल तेव्हा तुम्ही कमी पैसे देऊ शकता. + +उदाहरणार्थ, जॉर्डनला टेलरला 1 ETH द्यायचे आहेत असे समजूया. एका ETH हस्तांतरणासाठी 21,000 युनिट्स गॅसची आवश्यकता असते आणि बेस फी 10 gwei आहे. जॉर्डन 2 gwei ची टिप समाविष्ट करतो. + +एकूण शुल्क आता याच्या बरोबर असेल: + +`वापरलेले गॅस युनिट्स * (बेस फी + प्रायॉरिटी फी)` + +जिथे `base fee` हे प्रोटोकॉलद्वारे सेट केलेले मूल्य आहे आणि `priority fee` हे वापरकर्त्याने व्हॅलिडेटरला टिप म्हणून सेट केलेले मूल्य आहे. + +उदा., `21,000 * (10 + 2) = 252,000 gwei` (0.000252 ETH). + +जेव्हा जॉर्डन पैसे पाठवतो, तेव्हा जॉर्डनच्या खात्यातून 1.000252 ETH कापले जातील. टेलरला 1.0000 ETH जमा केले जातील. व्हॅलिडेटरला 0.000042 ETH ची टिप मिळते. 0.00021 ETH ची `base fee` बर्न केली जाते. + +### बेस फी {#base-fee} + +प्रत्येक ब्लॉकसाठी एक बेस फी असते जी राखीव किंमत म्हणून काम करते. ब्लॉकमध्ये समाविष्ट होण्यासाठी पात्र होण्यासाठी, प्रति गॅस ऑफर केलेली किंमत किमान बेस फीच्या बरोबरीची असणे आवश्यक आहे. बेस फीची गणना सध्याच्या ब्लॉकपासून स्वतंत्रपणे केली जाते आणि त्याऐवजी त्याच्या पूर्वीच्या ब्लॉक्सद्वारे निर्धारित केली जाते, ज्यामुळे वापरकर्त्यांसाठी व्यवहार शुल्क अधिक अंदाजित करता येते. जेव्हा ब्लॉक तयार केला जातो तेव्हा ही **बेस फी \"बर्न\" केली जाते**, ज्यामुळे ती चलनातून काढून टाकली जाते. + +बेस फीची गणना एका सूत्रानुसार केली जाते जे मागील ब्लॉकचा आकार (सर्व व्यवहारांसाठी वापरलेला गॅस) आणि लक्ष्य आकार (गॅस मर्यादेच्या अर्धा) यांची तुलना करते. लक्ष्य ब्लॉक आकार लक्ष्यापेक्षा जास्त किंवा कमी असल्यास, बेस फी प्रति ब्लॉक जास्तीत जास्त 12.5% ने वाढेल किंवा कमी होईल. या घातांकी वाढीमुळे ब्लॉकचा आकार अनिश्चित काळासाठी उच्च राहणे आर्थिकदृष्ट्या अव्यवहार्य बनते. + +| ब्लॉक क्रमांक | समाविष्ट गॅस | शुल्क वाढ | सध्याची बेस फी | +| ------------- | -----------: | --------------------: | -------------------------: | +| 1 | 18M | 0% | 100 gwei | +| 2 | 36M | 0% | 100 gwei | +| 3 | 36M | 12.5% | 112.5 gwei | +| 4 | 36M | 12.5% | 126.6 gwei | +| 5 | 36M | 12.5% | 142.4 gwei | +| 6 | 36M | 12.5% | 160.2 gwei | +| 7 | 36M | 12.5% | 180.2 gwei | +| 8 | 36M | 12.5% | 202.7 gwei | + +वरील तक्त्यामध्ये, 36 दशलक्ष गॅस मर्यादा वापरून एक उदाहरण दिले आहे. या उदाहरणाचे अनुसरण करून, ब्लॉक क्रमांक 9 वर व्यवहार तयार करण्यासाठी, एक वॉलेट वापरकर्त्याला निश्चितपणे कळवेल की पुढील ब्लॉकमध्ये जोडली जाणारी **कमाल बेस फी** `current base fee * 112.5%` किंवा `202.7 gwei * 112.5% = 228.1 gwei` आहे. + +हे लक्षात घेणे देखील महत्त्वाचे आहे की संपूर्ण ब्लॉकच्या आधी बेस फी ज्या वेगाने वाढते त्यामुळे आपल्याला पूर्ण ब्लॉक्सचे विस्तारित स्पाइक्स दिसण्याची शक्यता कमी आहे. + +| ब्लॉक क्रमांक | समाविष्ट गॅस | शुल्क वाढ | सध्याची बेस फी | +| --------------------------------------------------- | --------------------------------------------------: | --------------------: | --------------------------------------------------: | +| 30 | 36M | 12.5% | 2705.6 gwei | +| ... | ... | 12.5% | ... | +| 50 | 36M | 12.5% | 28531.3 gwei | +| ... | ... | 12.5% | ... | +| 100 | 36M | 12.5% | 10302608.6 gwei | + +### प्रायॉरिटी फी (टिप्स) {#priority-fee} + +प्रायॉरिटी फी (टिप) व्हॅलिडेटर्सना ब्लॉकमधील व्यवहारांची संख्या वाढवण्यासाठी प्रोत्साहन देते, जे फक्त ब्लॉकच्या गॅस मर्यादेमुळे मर्यादित असते. टिप्सशिवाय, एक विवेकी व्हॅलिडेटर कोणत्याही प्रत्यक्ष एक्झिक्युशन लेयर किंवा कन्सेन्सस लेयर दंडाशिवाय कमी—किंवा अगदी शून्य—व्यवहार समाविष्ट करू शकतो, कारण स्टेकिंग रिवॉर्ड्स ब्लॉकमध्ये किती व्यवहार आहेत यापासून स्वतंत्र असतात. याव्यतिरिक्त, टिप्स वापरकर्त्यांना एकाच ब्लॉकमध्ये प्राधान्यासाठी इतरांपेक्षा जास्त बोली लावण्याची परवानगी देतात, ज्यामुळे प्रभावीपणे तातडीचे संकेत मिळतात. + +### कमाल शुल्क {#maxfee} + +नेटवर्कवर व्यवहार कार्यान्वित करण्यासाठी, वापरकर्ते त्यांच्या व्यवहारासाठी देण्यास इच्छुक असलेली कमाल मर्यादा निर्दिष्ट करू शकतात. हा ऐच्छिक पॅरामीटर `maxFeePerGas` म्हणून ओळखला जातो. व्यवहार कार्यान्वित करण्यासाठी, कमाल शुल्क हे बेस फी आणि टिपच्या बेरजेपेक्षा जास्त असणे आवश्यक आहे. व्यवहार पाठवणाऱ्याला कमाल शुल्क आणि बेस फी व टिपच्या बेरजेमधील फरकाचा परतावा दिला जातो. + +### ब्लॉकचा आकार {#block-size} + +प्रत्येक ब्लॉकचा लक्ष्य आकार सध्याच्या गॅस मर्यादेच्या अर्धा असतो, परंतु नेटवर्कच्या मागणीनुसार ब्लॉकचा आकार वाढेल किंवा कमी होईल, जोपर्यंत ब्लॉकची मर्यादा (लक्ष्य ब्लॉक आकाराच्या 2x) गाठली जात नाही. प्रोटोकॉल _tâtonnement_ प्रक्रियेद्वारे लक्ष्यावर एक समतोल सरासरी ब्लॉक आकार प्राप्त करतो. याचा अर्थ जर ब्लॉकचा आकार लक्ष्य ब्लॉक आकारापेक्षा जास्त असेल, तर प्रोटोकॉल पुढील ब्लॉकसाठी बेस फी वाढवेल. त्याचप्रमाणे, जर ब्लॉकचा आकार लक्ष्य ब्लॉक आकारापेक्षा कमी असेल तर प्रोटोकॉल बेस फी कमी करेल. + +बेस फी समायोजित करण्याची रक्कम सध्याच्या ब्लॉकचा आकार लक्ष्यापासून किती दूर आहे याच्या प्रमाणात असते. ही एक रेषीय गणना आहे जी रिकाम्या ब्लॉकसाठी -12.5% पासून, लक्ष्य आकारावर 0%, ते गॅस मर्यादेपर्यंत पोहोचणाऱ्या ब्लॉकसाठी +12.5% पर्यंत असते. गॅस मर्यादा व्हॅलिडेटर सिग्नलिंगवर आधारित, तसेच नेटवर्क अपग्रेडद्वारे कालांतराने चढ-उतार करू शकते. तुम्ही [येथे गॅस मर्यादेतील कालांतराने होणारे बदल पाहू शकता](https://eth.blockscout.com/stats/averageGasLimit?interval=threeMonths). + +[ब्लॉक्सबद्दल अधिक](/developers/docs/blocks/) + +### व्यवहारात गॅस शुल्काची गणना करणे {#calculating-fees-in-practice} + +तुमचा व्यवहार कार्यान्वित करण्यासाठी तुम्ही किती पैसे देण्यास इच्छुक आहात हे तुम्ही स्पष्टपणे सांगू शकता. तथापि, बहुतेक वॉलेट प्रदाते त्यांच्या वापरकर्त्यांवरील गुंतागुंतीचे प्रमाण कमी करण्यासाठी स्वयंचलितपणे शिफारस केलेले व्यवहार शुल्क (बेस फी + शिफारस केलेली प्रायॉरिटी फी) सेट करतील. + +## गॅस शुल्क का अस्तित्वात आहे? {#why-do-gas-fees-exist} + +थोडक्यात, गॅस शुल्क इथेरियम नेटवर्क सुरक्षित ठेवण्यास मदत करते. नेटवर्कवर कार्यान्वित होणाऱ्या प्रत्येक संगणनासाठी शुल्क आवश्यक करून, आम्ही वाईट कलाकारांना नेटवर्कवर स्पॅम करण्यापासून प्रतिबंधित करतो. कोडमधील अपघाती किंवा प्रतिकूल अनंत लूप किंवा इतर संगणकीय अपव्यय टाळण्यासाठी, प्रत्येक व्यवहाराला कोड एक्झिक्युशनच्या किती संगणकीय पायऱ्या वापरता येतील याची मर्यादा सेट करणे आवश्यक आहे. संगणनेचे मूलभूत एकक \"गॅस\" आहे. + +जरी व्यवहारात मर्यादा समाविष्ट असली तरी, व्यवहारात न वापरलेला कोणताही गॅस वापरकर्त्याला परत केला जातो (उदा., `max fee - (base fee + tip)` परत केला जातो). + +![न वापरलेला गॅस कसा परत केला जातो हे दर्शविणारा आकृती](../transactions/gas-tx.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित केलेला आकृती_ + +## गॅस मर्यादा काय आहे? {#what-is-gas-limit} + +गॅस मर्यादा म्हणजे तुम्ही एका व्यवहारावर खर्च करण्यास इच्छुक असलेल्या गॅसची कमाल रक्कम. [स्मार्ट कॉन्ट्रॅक्ट](/developers/docs/smart-contracts/) समाविष्ट असलेल्या अधिक गुंतागुंतीच्या व्यवहारांना अधिक संगणकीय कामाची आवश्यकता असते, म्हणून त्यांना साध्या पेमेंटपेक्षा जास्त गॅस मर्यादेची आवश्यकता असते. एका मानक ETH हस्तांतरणासाठी 21,000 युनिट्स गॅसची मर्यादा आवश्यक आहे. + +उदाहरणार्थ, जर तुम्ही एका साध्या ETH हस्तांतरणासाठी 50,000 ची गॅस मर्यादा ठेवली, तर EVM 21,000 खर्च करेल आणि तुम्हाला उर्वरित 29,000 परत मिळतील. तथापि, तुम्ही खूप कमी गॅस निर्दिष्ट केल्यास, उदाहरणार्थ, एका साध्या ETH हस्तांतरणासाठी 20,000 ची गॅस मर्यादा, तर व्यवहार प्रमाणीकरण टप्प्यात अयशस्वी होईल. ब्लॉकमध्ये समाविष्ट होण्यापूर्वी ते नाकारले जाईल आणि कोणताही गॅस वापरला जाणार नाही. दुसरीकडे, जर एक्झिक्युशन दरम्यान व्यवहारात गॅस संपला (उदा., स्मार्ट कॉन्ट्रॅक्ट अर्ध्या वाटेत सर्व गॅस वापरतो), तर EVM कोणतेही बदल परत करेल, परंतु प्रदान केलेला सर्व गॅस केलेल्या कामासाठी वापरला जाईल. + +## गॅस शुल्क इतके जास्त का होऊ शकते? {#why-can-gas-fees-get-so-high} + +जास्त गॅस शुल्क इथेरियमच्या लोकप्रियतेमुळे आहे. जर खूप जास्त मागणी असेल, तर वापरकर्त्यांनी इतर वापरकर्त्यांच्या व्यवहारांपेक्षा जास्त बोली लावण्याचा प्रयत्न करण्यासाठी जास्त टिपची रक्कम ऑफर केली पाहिजे. जास्त टिपमुळे तुमचा व्यवहार पुढील ब्लॉकमध्ये जाण्याची शक्यता वाढू शकते. तसेच, अधिक गुंतागुंतीचे स्मार्ट कॉन्ट्रॅक्ट अॅप्स त्यांच्या कार्यांना समर्थन देण्यासाठी बरीच ऑपरेशन्स करत असतील, ज्यामुळे ते खूप गॅस वापरतात. + +## गॅस खर्च कमी करण्यासाठीचे उपक्रम {#initiatives-to-reduce-gas-costs} + +इथेरियम [स्केलेबिलिटी अपग्रेड](/roadmap/) अखेरीस काही गॅस शुल्क समस्यांचे निराकरण करेल, ज्यामुळे प्लॅटफॉर्मला प्रति सेकंद हजारो व्यवहार प्रक्रिया करण्यास आणि जागतिक स्तरावर स्केल करण्यास सक्षम करेल. + +लेअर 2 स्केलिंग हे गॅस खर्च, वापरकर्ता अनुभव आणि स्केलेबिलिटीमध्ये मोठी सुधारणा करण्यासाठी एक प्राथमिक उपक्रम आहे. + +[लेअर 2 स्केलिंगवर अधिक](/developers/docs/scaling/#layer-2-scaling) + +## गॅस शुल्कावर देखरेख ठेवणे {#monitoring-gas-fees} + +जर तुम्हाला गॅसच्या किमतींवर देखरेख ठेवायची असेल, जेणेकरून तुम्ही तुमचे ETH कमी खर्चात पाठवू शकाल, तर तुम्ही अनेक विविध साधने वापरू शकता जसे की: + +- [Etherscan](https://etherscan.io/gastracker) _व्यवहार गॅस किंमत अंदाजक_ +- [Blockscout](https://eth.blockscout.com/gas-tracker) _ओपन सोर्स व्यवहार गॅस किंमत अंदाजक_ +- [ETH Gas Tracker](https://www.ethgastracker.com/) _व्यवहार शुल्क कमी करण्यासाठी आणि पैसे वाचवण्यासाठी इथेरियम आणि L2 गॅसच्या किमतींचे निरीक्षण आणि मागोवा घ्या_ +- [Blocknative ETH Gas Estimator](https://chrome.google.com/webstore/detail/blocknative-eth-gas-estim/ablbagjepecncofimgjmdpnhnfjiecfm) _गॅस अंदाजित करणारे क्रोम एक्सटेंशन जे टाइप 0 लेगसी व्यवहार आणि टाइप 2 EIP-1559 व्यवहार दोन्हीला समर्थन देते._ +- [Cryptoneur Gas Fees Calculator](https://www.cryptoneur.xyz/gas-fees-calculator) _Mainnet, Arbitrum आणि Polygon वरील विविध प्रकारच्या व्यवहारांसाठी तुमच्या स्थानिक चलनात गॅस शुल्काची गणना करा._ + +## संबंधित साधने {#related-tools} + +- [Blocknative's Gas Platform](https://www.blocknative.com/gas) _Blocknative च्या जागतिक मेमपूल डेटा प्लॅटफॉर्मद्वारे समर्थित गॅस अंदाज API_ +- [Gas Network](https://gas.network) ऑनचेन गॅस ओरॅकल्स. 35+ चेन्ससाठी समर्थन. + +## पुढील वाचन {#further-reading} + +- [इथेरियम गॅस स्पष्टीकरण](https://defiprime.com/gas) +- [तुमच्या स्मार्ट कॉन्ट्रॅक्टचा गॅस वापर कमी करणे](https://medium.com/coinmonks/8-ways-of-reducing-the-gas-consumption-of-your-smart-contracts-9a506b339c0a) +- [डेव्हलपर्ससाठी गॅस ऑप्टिमायझेशन स्ट्रॅटेजीज](https://www.alchemy.com/overviews/solidity-gas-optimization) +- [EIP-1559 डॉक्स](https://eips.ethereum.org/EIPS/eip-1559). +- [टिम बेइकोची EIP-1559 संसाधने](https://hackmd.io/@timbeiko/1559-resources) +- [EIP-1559: मेम्सपासून यंत्रणा वेगळे करणे](https://web.archive.org/web/20241126205908/https://research.2077.xyz/eip-1559-separating-mechanisms-from-memes) diff --git a/public/content/translations/mr/developers/docs/ides/index.md b/public/content/translations/mr/developers/docs/ides/index.md new file mode 100644 index 00000000000..ac20008d8d7 --- /dev/null +++ b/public/content/translations/mr/developers/docs/ides/index.md @@ -0,0 +1,64 @@ +--- +title: "इंटिग्रेटेड डेव्हलपमेंट एन्व्हायर्नमेंट्स (IDEs)" +description: "Remix, VS Code, आणि लोकप्रिय प्लगइन्ससह Ethereum विकासासाठी वेब-आधारित आणि डेस्कटॉप IDEs बद्दल जाणून घ्या." +lang: mr +--- + +[इंटिग्रेटेड डेव्हलपमेंट एन्व्हायर्नमेंट (IDE)](https://wikipedia.org/wiki/Integrated_development_environment) सेट करण्याच्या बाबतीत, Ethereum वर ॲप्लिकेशन्स प्रोग्रामिंग करणे हे इतर कोणत्याही सॉफ्टवेअर प्रोजेक्टच्या प्रोग्रामिंगसारखेच आहे. निवडण्यासाठी बरेच पर्याय आहेत, म्हणून शेवटी, तुमच्या पसंतीनुसार सर्वोत्तम अनुकूल असलेला IDE किंवा कोड एडिटर निवडा. तुमच्या Ethereum विकासासाठी सर्वोत्तम IDE निवड बहुधा तोच IDE असेल जो तुम्ही आधीपासून पारंपारिक सॉफ्टवेअर विकासासाठी वापरत आहात. + +## वेब-आधारित IDEs {#web-based-ides} + +तुम्ही [स्थानिक विकास पर्यावरण सेट करण्यापूर्वी](/developers/local-environment/) कोडमध्ये काही फेरफार करू इच्छित असाल, तर हे वेब ॲप्स Ethereum स्मार्ट कॉन्ट्रॅक्ट विकासासाठी खास तयार केलेले आहेत. + +**[Remix](https://remix.ethereum.org/)** - **_अंगभूत स्टॅटिक एनालिसिस आणि टेस्ट ब्लॉकचेन व्हर्च्युअल मशीनसह वेब-आधारित IDE_** + +- [डॉक्स](https://remix-ide.readthedocs.io/en/latest/#) +- [Gitter](https://gitter.im/ethereum/remix) + +**[ChainIDE](https://chainide.com/)** - **_एक क्लाउड-आधारित मल्टी-चेन IDE_** + +- [डॉक्स](https://chainide.gitbook.io/chainide-english-1/) +- [मदत मंच](https://forum.chainide.com/) + +**[Replit (Solidity स्टार्टर - बीटा)](https://replit.com/@replit/Solidity-starter-beta)** - **_हॉट रिलोडिंग, त्रुटी तपासणी आणि फर्स्ट-क्लास टेस्टनेट समर्थनासह Ethereum साठी एक सानुकूल करण्यायोग्य विकास पर्यावरण_** + +- [डॉक्स](https://docs.replit.com/) + +**[Tenderly Sandbox](https://sandbox.tenderly.co/)** - **_एक जलद प्रोटोटाइपिंग पर्यावरण जिथे तुम्ही Solidity आणि JavaScript वापरून ब्राउझरमध्ये स्मार्ट कॉन्ट्रॅक्ट लिहू, कार्यान्वित करू आणि डीबग करू शकता_** + +**[EthFiddle](https://ethfiddle.com/)** - **_वेब-आधारित IDE जो तुम्हाला तुमचा स्मार्ट कॉन्ट्रॅक्ट लिहिण्याची, कंपाईल करण्याची आणि डीबग करण्याची परवानगी देतो_** + +- [Gitter](https://gitter.im/loomnetwork/ethfiddle) + +## डेस्कटॉप IDEs {#desktop-ides} + +बहुतेक प्रस्थापित IDEs मध्ये Ethereum विकासाचा अनुभव वाढवण्यासाठी प्लगइन्स तयार केलेले आहेत. किमान, ते [स्मार्ट कॉन्ट्रॅक्ट भाषांसाठी](/developers/docs/smart-contracts/languages/) सिंटॅक्स हायलाइटिंग प्रदान करतात. + +**Visual Studio Code -** **_अधिकृत Ethereum समर्थनासह व्यावसायिक क्रॉस-प्लॅटफॉर्म IDE_** + +- [Visual Studio Code](https://code.visualstudio.com/) +- [कोड नमुने](https://github.com/Azure-Samples/blockchain/blob/master/blockchain-workbench/application-and-smart-contract-samples/readme.md) +- [GitHub](https://github.com/microsoft/vscode) + +**JetBrains IDEs (IntelliJ IDEA, इत्यादी.) -** **_सॉफ्टवेअर डेव्हलपर्स आणि टीम्ससाठी आवश्यक साधने_** + +- [JetBrains](https://www.jetbrains.com/) +- [GitHub](https://github.com/JetBrains) +- [IntelliJ Solidity](https://github.com/intellij-solidity/intellij-solidity/) + +**Remix Desktop -** **_तुमच्या स्थानिक मशीनवर Remix IDE चा अनुभव घ्या_** + +- [डाउनलोड करा](https://github.com/ethereum/remix-desktop/releases) +- [GitHub](https://github.com/ethereum/remix-desktop) + +## प्लगइन्स आणि एक्सटेन्शन्स {#plugins-extensions} + +- [solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) - Visual Studio Code साठी Ethereum Solidity भाषा +- [Solidity + Hardhat for VS Code](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) - Hardhat टीमद्वारे Solidity आणि Hardhat समर्थन +- [Prettier Solidity](https://github.com/prettier-solidity/prettier-plugin-solidity) - prettier वापरून कोड फॉर्मॅटर + +## पुढील वाचन {#further-reading} + +- [Ethereum IDEs](https://www.alchemy.com/list-of/web3-ides-on-ethereum) _- Alchemy ची Ethereum IDEs ची सूची_ + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ diff --git a/public/content/translations/mr/developers/docs/index.md b/public/content/translations/mr/developers/docs/index.md new file mode 100644 index 00000000000..57f7ff660d2 --- /dev/null +++ b/public/content/translations/mr/developers/docs/index.md @@ -0,0 +1,25 @@ +--- +title: "Ethereum विकास दस्तऐवजीकरण" +description: "ethereum.org विकसक दस्तऐवजीकरण सादर करत आहे." +lang: mr +--- + +हे दस्तऐवजीकरण तुम्हाला Ethereum सह बिल्ड करण्यास मदत करण्यासाठी डिझाइन केलेले आहे. हे एक संकल्पना म्हणून Ethereum समाविष्ट करते, Ethereum टेक स्टॅक स्पष्ट करते, आणि अधिक जटिल ऍप्लिकेशन्स आणि वापर प्रकरणांसाठी प्रगत विषयांचे दस्तऐवजीकरण करते. + +हा एक मुक्त-स्रोत समुदाय प्रयत्न आहे, त्यामुळे नवीन विषय सुचवण्यास, नवीन सामग्री जोडण्यास आणि जिथे तुम्हाला वाटेल तिथे उदाहरणे देण्यास मोकळ्या मनाने. सर्व दस्तऐवजीकरण GitHub द्वारे संपादित केले जाऊ शकते – तुम्हाला कसे करायचे याची खात्री नसल्यास, [या सूचनांचे पालन करा](https://github.com/ethereum/ethereum-org-website/blob/dev/docs/editing-markdown.md). + +## विकास मॉड्यूल {#development-modules} + +हा तुमचा Ethereum विकासातील पहिला प्रयत्न असल्यास, आम्ही सुरुवातीपासून प्रारंभ करण्याची आणि पुस्तकाप्रमाणे पुढे जाण्याची शिफारस करतो. + +### पायाभूत विषय {#foundational-topics} + + + +### Ethereum स्टॅक {#ethereum-stack} + + + +### प्रगत {#advanced} + + diff --git a/public/content/translations/mr/developers/docs/intro-to-ether/index.md b/public/content/translations/mr/developers/docs/intro-to-ether/index.md new file mode 100644 index 00000000000..1b40f8df2f1 --- /dev/null +++ b/public/content/translations/mr/developers/docs/intro-to-ether/index.md @@ -0,0 +1,78 @@ +--- +title: "इथरची तांत्रिक ओळख" +description: "इथर क्रिप्टोकरन्सीची डेव्हलपरसाठी ओळख." +lang: mr +--- + +## पूर्वतयारी {#prerequisites} + +हे पान तुम्हाला अधिक चांगल्या प्रकारे समजण्यास मदत करण्यासाठी, आम्ही शिफारस करतो की तुम्ही प्रथम [इथेरियमची ओळख](/developers/docs/intro-to-ethereum/) वाचा. + +## क्रिप्टोकरन्सी म्हणजे काय? क्रिप्टोकरन्सी म्हणजे काय? + +क्रिप्टोकरन्सी हे ब्लॉकचेन-आधारित लेजरद्वारे सुरक्षित केलेले विनिमयाचे माध्यम आहे. + +विनिमयाचे माध्यम म्हणजे वस्तू आणि सेवांसाठी पेमेंट म्हणून मोठ्या प्रमाणावर स्वीकारलेली कोणतीही गोष्ट, आणि लेजर हा एक डेटा स्टोअर आहे जो व्यवहारांचा मागोवा ठेवतो. ब्लॉकचेन तंत्रज्ञान वापरकर्त्यांना लेजर सांभाळण्यासाठी विश्वासू तृतीय पक्षावर अवलंबून न राहता लेजरवर व्यवहार करण्याची परवानगी देते. + +पहिली क्रिप्टोकरन्सी बिटकॉइन होती, जी सातोशी नाकामोटोने तयार केली होती. २००९ मध्ये बिटकॉइनच्या रिलीझनंतर, लोकांनी अनेक वेगवेगळ्या ब्लॉकचेनवर हजारो क्रिप्टोकरन्सी तयार केल्या आहेत. + +## एथर म्हणजे काय? इथर म्हणजे काय? + +**इथर (ETH)** ही इथेरियम नेटवर्कवर अनेक गोष्टींसाठी वापरली जाणारी क्रिप्टोकरन्सी आहे. मूलतः, हे व्यवहार शुल्कासाठी पेमेंटचे एकमेव स्वीकार्य स्वरूप आहे, आणि [The Merge](/roadmap/merge) नंतर, मेननेटवर ब्लॉक्स प्रमाणित करण्यासाठी आणि प्रस्तावित करण्यासाठी इथर आवश्यक आहे. इथरचा वापर [DeFi](/defi) कर्ज बाजारात तारणाचे प्राथमिक स्वरूप म्हणून, NFT मार्केटप्लेसमध्ये खात्याचे एकक म्हणून, सेवा प्रदान करण्यासाठी किंवा वास्तविक-जगातील वस्तू विकून मिळवलेले पेमेंट म्हणून आणि बरेच काही म्हणून देखील केला जातो. + +इथेरियम डेव्हलपर्सना [**विकेंद्रीकृत ॲप्लिकेशन्स (dapps)**](/developers/docs/dapps) तयार करण्याची परवानगी देते, जे सर्व संगणकीय शक्तीचा एक पूल सामायिक करतात. हा सामायिक पूल मर्यादित आहे, त्यामुळे इथेरियमला ​​ते कोण वापरू शकेल हे ठरवण्यासाठी एका यंत्रणेची आवश्यकता आहे. अन्यथा, एखादे dapp अपघाताने किंवा दुर्भावनापूर्णपणे सर्व नेटवर्क संसाधने वापरू शकते, ज्यामुळे इतरांना त्यात प्रवेश करण्यापासून रोखले जाईल. + +इथर क्रिप्टोकरन्सी इथेरियमच्या संगणकीय शक्तीसाठी एक किंमत यंत्रणा समर्थित करते. जेव्हा वापरकर्त्यांना व्यवहार करायचा असतो, तेव्हा त्यांचा व्यवहार ब्लॉकचेनवर ओळखला जाण्यासाठी त्यांना इथर भरावे लागते. हे वापराचे खर्च [गॅस शुल्क](/developers/docs/gas/) म्हणून ओळखले जातात, आणि गॅस शुल्क व्यवहार कार्यान्वित करण्यासाठी आवश्यक असलेल्या संगणकीय शक्तीच्या प्रमाणावर आणि त्या वेळी संगणकीय शक्तीसाठी नेटवर्क-व्यापी मागणीवर अवलंबून असते. + +म्हणून, जरी एखाद्या दुर्भावनापूर्ण dapp ने अनंत लूप सादर केला तरी, व्यवहार अखेरीस इथर संपल्यावर समाप्त होईल, ज्यामुळे नेटवर्क सामान्य स्थितीत परत येऊ शकेल. + +इथेरियम आणि इथरमध्ये [गोंधळ होणे सामान्य आहे](https://abcnews.go.com/Business/bitcoin-slumps-week-low-amid-renewed-worries-chinese/story?id=78399845) — जेव्हा लोक "इथेरियमची किंमत" चा संदर्भ देतात, तेव्हा ते इथरच्या किंमतीचे वर्णन करत असतात. + +## इथरचे मिंटिंग {#minting-ether} + +मिंटिंग ही एक प्रक्रिया आहे ज्यामध्ये इथेरियम लेजरवर नवीन इथर तयार केला जातो. अंतर्निहित इथेरियम प्रोटोकॉल नवीन इथर तयार करतो, आणि वापरकर्त्यासाठी इथर तयार करणे शक्य नाही. + +प्रत्येक प्रस्तावित ब्लॉकसाठी आणि एकमत साधण्याशी संबंधित इतर व्हॅलिडेटरच्या क्रियेसाठी प्रत्येक इपॉक चेकपॉइंटवर बक्षीस म्हणून इथर मिंट केले जाते. जारी केलेली एकूण रक्कम व्हॅलिडेटर्सच्या संख्येवर आणि त्यांनी किती इथर स्टेक केले आहेत यावर अवलंबून असते. सर्व व्हॅलिडेटर्स प्रामाणिक आणि ऑनलाइन असल्यास आदर्श परिस्थितीत हे एकूण जारीकरण व्हॅलिडेटर्समध्ये समान रीतीने विभागले जाते, परंतु प्रत्यक्षात ते व्हॅलिडेटरच्या कामगिरीनुसार बदलते. एकूण जारी केलेल्या रकमेपैकी सुमारे 1/8 ब्लॉक प्रस्तावकाला जातो; उर्वरित रक्कम इतर व्हॅलिडेटर्समध्ये वितरीत केली जाते. ब्लॉक प्रस्तावकांना व्यवहार शुल्कातून टिप्स आणि MEV-संबंधित उत्पन्न देखील मिळते, परंतु हे पुनर्नवीनीकरण केलेल्या इथरमधून येते, नवीन जारीकरणातून नाही. + +## इथर बर्न करणे {#burning-ether} + +ब्लॉक रिवॉर्ड्सद्वारे इथर तयार करण्याबरोबरच, 'बर्निंग' नावाच्या प्रक्रियेद्वारे इथर नष्ट केले जाऊ शकते. जेव्हा इथर बर्न होते, तेव्हा ते कायमचे चलनातून काढून टाकले जाते. + +इथेरियमवरील प्रत्येक व्यवहारामध्ये इथर बर्न होते. जेव्हा वापरकर्ते त्यांच्या व्यवहारांसाठी पैसे देतात, तेव्हा व्यवहाराच्या मागणीनुसार नेटवर्कद्वारे सेट केलेले बेस गॅस शुल्क नष्ट होते. हे, बदलत्या ब्लॉक आकारांसह आणि कमाल गॅस शुल्कासह, इथेरियमवर व्यवहार शुल्काच्या अंदाजाला सोपे करते. जेव्हा नेटवर्कची मागणी जास्त असते, तेव्हा [ब्लॉक्स](https://eth.blockscout.com/block/22580057) ते मिंट करण्यापेक्षा जास्त इथर बर्न करू शकतात, ज्यामुळे इथर जारीकरणाला प्रभावीपणे ऑफसेट करता येते. + +बेस फी बर्न केल्याने ब्लॉक निर्मात्याच्या व्यवहारांमध्ये फेरफार करण्याच्या क्षमतेत अडथळा येतो. उदाहरणार्थ, जर ब्लॉक निर्मात्यांना बेस फी मिळाली, तर ते त्यांचे स्वतःचे व्यवहार विनामूल्य समाविष्ट करू शकतील आणि इतर प्रत्येकासाठी बेस फी वाढवू शकतील. वैकल्पिकरित्या, ते काही वापरकर्त्यांना ऑफचेन बेस फी परत करू शकतील, ज्यामुळे अधिक अपारदर्शक आणि गुंतागुंतीचे व्यवहार शुल्क बाजार निर्माण होईल. + +## इथरचे डिनॉमिनेशन {#denominations} + +इथेरियमवरील अनेक व्यवहारांचे मूल्य लहान असल्याने, इथरचे अनेक डिनॉमिनेशन आहेत ज्यांचा संदर्भ खात्याची लहान एकके म्हणून दिला जाऊ शकतो. या डिनॉमिनेशनपैकी, Wei आणि gwei विशेषतः महत्त्वाचे आहेत. + +Wei ही इथरची सर्वात लहान संभाव्य रक्कम आहे, आणि परिणामी, [इथेरियम यलोपेपर](https://ethereum.github.io/yellowpaper/paper.pdf) सारख्या अनेक तांत्रिक अंमलबजावणी, सर्व गणना Wei मध्ये आधारित करतील. + +Gwei, गिगा-वेईचे संक्षिप्त रूप, इथेरियमवरील गॅस खर्चाचे वर्णन करण्यासाठी अनेकदा वापरले जाते. + +| डिनॉमिनेशन | इथरमधील मूल्य | सामान्य वापर | +| ---------- | ---------------- | --------------------- | +| Wei | 10-18 | तांत्रिक अंमलबजावणी | +| Gwei | 10-9 | मानव-वाचनीय गॅस शुल्क | + +## इथर हस्तांतरित करणे {#transferring-ether} + +इथेरियमवरील प्रत्येक व्यवहारामध्ये एक `value` फील्ड असते, जे प्रेषकाच्या पत्त्यावरून प्राप्तकर्त्याच्या पत्त्यावर पाठवण्यासाठी हस्तांतरित करायच्या इथरची रक्कम wei मध्ये निर्दिष्ट करते. + +जेव्हा प्राप्तकर्त्याचा पत्ता [स्मार्ट कॉन्ट्रॅक्ट](/developers/docs/smart-contracts/) असतो, तेव्हा स्मार्ट कॉन्ट्रॅक्ट त्याचा कोड कार्यान्वित करतो तेव्हा हा हस्तांतरित केलेला इथर गॅससाठी पैसे देण्यासाठी वापरला जाऊ शकतो. + +[व्यवहारांवर अधिक](/developers/docs/transactions/) + +## इथरची क्वेरी करणे {#querying-ether} + +वापरकर्ते कोणत्याही [खात्याची](/developers/docs/accounts/) इथर शिल्लक खात्याच्या `balance` फील्डची तपासणी करून क्वेरी करू शकतात, जे wei मध्ये डिनॉमिनेटेड इथर होल्डिंग्ज दर्शवते. + +[Etherscan](https://etherscan.io) आणि [Blockscout](https://eth.blockscout.com) ही वेब-आधारित ॲप्लिकेशन्सद्वारे पत्त्यावरील शिल्लक तपासण्यासाठी लोकप्रिय साधने आहेत. उदाहरणार्थ, [हे Blockscout पृष्ठ](https://eth.blockscout.com/address/0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe) Ethereum फाउंडेशनची शिल्लक दर्शवते. वॉलेट्स वापरून किंवा थेट नोड्सना विनंती करून खात्यातील शिलकीची क्वेरी देखील केली जाऊ शकते. + +## पुढील वाचन {#further-reading} + +- [इथर आणि इथेरियमची व्याख्या](https://www.cmegroup.com/education/courses/introduction-to-ether/defining-ether-and-ethereum.html) – _CME Group_ +- [इथेरियम व्हाइटपेपर](/whitepaper/): इथेरियमसाठी मूळ प्रस्ताव. या दस्तऐवजात इथरचे वर्णन आणि त्याच्या निर्मितीमागील प्रेरणा समाविष्ट आहेत. +- [Gwei कॅल्क्युलेटर](https://www.alchemy.com/gwei-calculator): wei, gwei, आणि इथर सहजपणे रूपांतरित करण्यासाठी हा gwei कॅल्क्युलेटर वापरा. फक्त wei, gwei, किंवा ETH ची कोणतीही रक्कम टाका आणि आपोआप रूपांतरणाची गणना करा. + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ diff --git a/public/content/translations/mr/developers/docs/intro-to-ethereum/index.md b/public/content/translations/mr/developers/docs/intro-to-ethereum/index.md new file mode 100644 index 00000000000..872556f0e12 --- /dev/null +++ b/public/content/translations/mr/developers/docs/intro-to-ethereum/index.md @@ -0,0 +1,124 @@ +--- +title: "इथेरियमचा तांत्रिक परिचय" +description: "इथेरियमच्या मुख्य संकल्पनांचा dapp विकसकांसाठी परिचय." +lang: mr +--- + +## ब्लॉकचेन म्हणजे काय? {#what-is-a-blockchain} + +ब्लॉकचेन हा एक सार्वजनिक डेटाबेस आहे जो नेटवर्कमधील अनेक संगणकांवर अद्ययावत केला जातो आणि सामायिक केला जातो. + +"ब्लॉक" म्हणजे डेटा आणि स्थिती "ब्लॉक्स" नावाच्या सलग गटांमध्ये संग्रहित केली जाते. तुम्ही दुसऱ्या कोणाला ETH पाठवल्यास, व्यवहार यशस्वी होण्यासाठी त्याचा डेटा एका ब्लॉकमध्ये जोडला जाणे आवश्यक आहे. + +"चेन" म्हणजे प्रत्येक ब्लॉक क्रिप्टोग्राफिकली त्याच्या मूळ ब्लॉकचा संदर्भ देतो. दुसऱ्या शब्दांत, ब्लॉक्स एकमेकांशी जोडले जातात. त्यानंतरचे सर्व ब्लॉक्स बदलल्याशिवाय ब्लॉकमधील डेटा बदलता येत नाही, ज्यासाठी संपूर्ण नेटवर्कच्या सहमतीची आवश्यकता असेल. + +नेटवर्कमधील प्रत्येक संगणकाने प्रत्येक नवीन ब्लॉक आणि संपूर्ण चेनवर सहमत होणे आवश्यक आहे. हे संगणक "नोड्स" म्हणून ओळखले जातात. ब्लॉकचेनशी संवाद साधणाऱ्या प्रत्येकाकडे समान डेटा असल्याची खात्री नोड्स करतात. हा वितरित करार पूर्ण करण्यासाठी, ब्लॉकचेनला एक सहमती यंत्रणेची आवश्यकता असते. + +इथेरियम [प्रूफ-ऑफ-स्टेक-आधारित सहमती यंत्रणा](/developers/docs/consensus-mechanisms/pos/) वापरते. ज्या कोणालाही चेनमध्ये नवीन ब्लॉक्स जोडायचे आहेत, त्यांनी तारण म्हणून ETH - इथेरियममधील मूळ चलन - स्टेक करणे आणि व्हॅलिडेटर सॉफ्टवेअर चालवणे आवश्यक आहे. हे "व्हॅलिडेटर्स" नंतर ब्लॉक्स प्रस्तावित करण्यासाठी यादृच्छिकपणे निवडले जाऊ शकतात, जे इतर व्हॅलिडेटर्स तपासतात आणि ब्लॉकचेनमध्ये जोडतात. येथे बक्षिसे आणि दंडांची एक प्रणाली आहे जी सहभागींना प्रामाणिक राहण्यासाठी आणि शक्य तितके ऑनलाइन उपलब्ध राहण्यासाठी जोरदारपणे प्रोत्साहित करते. + +ब्लॉकचेन डेटा कसा हॅश केला जातो आणि त्यानंतर ब्लॉक संदर्भांच्या इतिहासात कसा जोडला जातो हे तुम्हाला पाहायचे असेल, तर अँडर्स ब्राउनवर्थ यांचा [हा डेमो](https://andersbrownworth.com/blockchain/blockchain) नक्की पहा आणि खालील सोबतचा व्हिडिओ पहा. + +ब्लॉकचेनमधील हॅशेसविषयी अँडर्स यांचे स्पष्टीकरण पहा: + + + +## अथेरम म्हणजे काय? इथेरियम म्हणजे काय? {#what-is-ethereum} + +इथेरियम एक ब्लॉकचेन आहे ज्यात एक संगणक अंतर्भूत आहे. विकेंद्रित, परवानगी-रहित, सेन्सॉरशिप-प्रतिरोधक पद्धतीने अ‍ॅप्स आणि संस्था तयार करण्यासाठीचा हा पाया आहे. + +इथेरियमच्या विश्वात, एकच, प्रमाणभूत संगणक आहे (ज्याला इथेरियम व्हर्च्युअल मशीन, किंवा EVM म्हणतात) ज्याच्या स्थितीवर इथेरियम नेटवर्कमधील प्रत्येकजण सहमत असतो. इथेरियम नेटवर्कमध्ये सहभागी होणारा प्रत्येकजण (प्रत्येक इथेरियम नोड) या संगणकाच्या स्थितीची एक प्रत ठेवतो. याव्यतिरिक्त, कोणताही सहभागी या संगणकाला कोणतीही गणना करण्यासाठी विनंती प्रसारित करू शकतो. जेव्हा अशी विनंती प्रसारित केली जाते, तेव्हा नेटवर्कवरील इतर सहभागी त्या गणनेची पडताळणी करतात, प्रमाणित करतात आणि ती पार पाडतात ("अंमलात आणतात"). या अंमलबजावणीमुळे EVM च्या स्थितीमध्ये बदल होतो, जो संपूर्ण नेटवर्कमध्ये वचनबद्ध आणि प्रसारित केला जातो. + +गणनेसाठीच्या विनंत्यांना व्यवहार विनंत्या म्हटले जाते; सर्व व्यवहारांची नोंद आणि EVM ची सद्य स्थिती ब्लॉकचेनवर संग्रहित केली जाते, जी नंतर सर्व नोड्सद्वारे संग्रहित केली जाते आणि त्यावर सहमती दर्शवली जाते. + +क्रिप्टोग्राफिक यंत्रणा हे सुनिश्चित करतात की एकदा व्यवहार वैध म्हणून सत्यापित करून ब्लॉकचेनमध्ये जोडले गेल्यावर, नंतर त्यात फेरफार करता येणार नाही. याच यंत्रणा हे देखील सुनिश्चित करतात की सर्व व्यवहार योग्य "परवानग्यांसह" स्वाक्षरी केलेले आणि अंमलात आणले जातात (स्वतः ॲलिस वगळता कोणीही ॲलिसच्या खात्यातून डिजिटल मालमत्ता पाठवू नये). + +## एथर म्हणजे काय? इथर म्हणजे काय? + +**इथर (ETH)** हे इथेरियमचे मूळ क्रिप्टोकरन्सी आहे. ETH चा उद्देश गणनेसाठी एक बाजारपेठ उपलब्ध करून देणे हा आहे. अशी बाजारपेठ सहभागींना व्यवहार विनंत्या सत्यापित करण्यासाठी आणि अंमलात आणण्यासाठी, तसेच नेटवर्कला गणनेची संसाधने पुरवण्यासाठी आर्थिक प्रोत्साहन देते. + +व्यवहार विनंती प्रसारित करणार्‍या कोणत्याही सहभागीने नेटवर्कला बक्षीस म्हणून काही प्रमाणात ETH देऊ करणे आवश्यक आहे. नेटवर्क बक्षीसाचा काही भाग बर्न करेल आणि उर्वरित भाग त्या व्यक्तीला देईल जो अखेरीस व्यवहार सत्यापित करणे, त्याची अंमलबजावणी करणे, त्याला ब्लॉकचेनमध्ये समाविष्ट करणे आणि नेटवर्कवर प्रसारित करण्याचे काम करतो. + +दिलेल्या ETH ची रक्कम गणनेसाठी आवश्यक असलेल्या संसाधनांच्या प्रमाणात असते. हे बक्षीस दुर्भावनापूर्ण सहभागींना अमर्याद गणना किंवा इतर संसाधन-केंद्रित स्क्रिप्ट्सच्या अंमलबजावणीची विनंती करून हेतुपुरस्सर नेटवर्क जाम करण्यापासून देखील प्रतिबंधित करतात, कारण या सहभागींना गणनेच्या संसाधनांसाठी पैसे द्यावे लागतात. + +ETH चा वापर नेटवर्कला तीन मुख्य मार्गांनी क्रिप्टो-आर्थिक सुरक्षा प्रदान करण्यासाठी देखील केला जातो: १) जे व्हॅलिडेटर्स ब्लॉक्स प्रस्तावित करतात किंवा इतर व्हॅलिडेटर्सच्या अप्रामाणिक वर्तनावर बोट ठेवतात त्यांना बक्षीस देण्यासाठी याचा वापर केला जातो; २) हे व्हॅलिडेटर्सद्वारे स्टेक केले जाते, जे अप्रामाणिक वर्तनाविरुद्ध तारण म्हणून काम करते—जर व्हॅलिडेटर्सनी गैरवर्तन करण्याचा प्रयत्न केला तर त्यांचे ETH नष्ट केले जाऊ शकते; ३) नवीन प्रस्तावित ब्लॉक्ससाठी 'मते' तोलण्यासाठी याचा वापर केला जातो, जे सहमती यंत्रणेच्या फोर्क-चॉईस भागात योगदान देते. + +## स्मार्ट करार म्हणजे काय? स्मार्ट कॉन्ट्रॅक्ट्स म्हणजे काय? {#what-are-smart-contracts} + +व्यवहारात, सहभागी प्रत्येक वेळी EVM वर गणनेची विनंती करताना नवीन कोड लिहित नाहीत. त्याऐवजी, ॲप्लिकेशन डेव्हलपर प्रोग्राम्स (कोडचे पुन्हा वापरता येण्याजोगे स्निपेट्स) EVM स्थितीमध्ये अपलोड करतात आणि वापरकर्ते विविध पॅरामीटर्ससह हे कोड स्निपेट्स कार्यान्वित करण्याची विनंती करतात. नेटवर्कवर अपलोड आणि कार्यान्वित केलेल्या प्रोग्राम्सना आम्ही "स्मार्ट कॉन्ट्रॅक्ट्स" म्हणतो. + +अगदी मूलभूत स्तरावर, तुम्ही स्मार्ट कॉन्ट्रॅक्टला एका प्रकारच्या व्हेंडिंग मशीनसारखे समजू शकता: एक स्क्रिप्ट जी, विशिष्ट पॅरामीटर्ससह कॉल केल्यावर, काही अटी पूर्ण झाल्यास काही क्रिया किंवा गणना करते. उदाहरणार्थ, जर कॉलरने विशिष्ट प्राप्तकर्त्याला ETH पाठवले तर एक साधा विक्रेता स्मार्ट कॉन्ट्रॅक्ट डिजिटल मालमत्ता तयार करू शकतो आणि तिची मालकी देऊ शकतो. + +कोणताही डेव्हलपर नेटवर्कला शुल्क देऊन, ब्लॉकचेनचा डेटा लेअर म्हणून वापर करून, एक स्मार्ट कॉन्ट्रॅक्ट तयार करू शकतो आणि तो नेटवर्कसाठी सार्वजनिक करू शकतो. नंतर कोणताही वापरकर्ता पुन्हा नेटवर्कला शुल्क देऊन, त्याचा कोड कार्यान्वित करण्यासाठी स्मार्ट कॉन्ट्रॅक्टला कॉल करू शकतो. + +अशाप्रकारे, स्मार्ट कॉन्ट्रॅक्ट्सद्वारे, डेव्हलपर वापरकर्त्यांसाठी कितीही क्लिष्ट अ‍ॅप्स आणि सेवा जसे की: बाजारपेठा, आर्थिक साधने, खेळ इत्यादी तयार आणि तैनात करू शकतात. + +## परिभाषा {#terminology} + +### ब्लॉकचेन {#blockchain} + +नेटवर्कच्या इतिहासात इथेरियम नेटवर्कवर वचनबद्ध केलेल्या सर्व ब्लॉक्सचा क्रम. असे नाव दिले आहे कारण प्रत्येक ब्लॉकमध्ये मागील ब्लॉकचा संदर्भ असतो, जे आपल्याला सर्व ब्लॉक्सवर (आणि त्यामुळे अचूक इतिहासावर) एक क्रम राखण्यास मदत करते. + +### ETH {#eth} + +**इथर (ETH)** हे इथेरियमचे मूळ क्रिप्टोकरन्सी आहे. वापरकर्ते त्यांच्या कोड अंमलबजावणीच्या विनंत्या पूर्ण करून घेण्यासाठी इतर वापरकर्त्यांना ETH देतात. + +[ETH बद्दल अधिक](/developers/docs/intro-to-ether/) + +### EVM {#evm} + +इथेरियम व्हर्च्युअल मशीन हा जागतिक व्हर्च्युअल संगणक आहे ज्याची स्थिती इथेरियम नेटवर्कवरील प्रत्येक सहभागी संग्रहित करतो आणि त्यावर सहमत असतो. कोणताही सहभागी EVM वर कोणत्याही कोडच्या अंमलबजावणीची विनंती करू शकतो; कोडच्या अंमलबजावणीमुळे EVM ची स्थिती बदलते. + +[EVM बद्दल अधिक](/developers/docs/evm/) + +### नोड्स {#nodes} + +वास्तविक जीवनातील मशीन्स जे EVM स्थिती संग्रहित करत आहेत. EVM स्थिती आणि नवीन स्थिती बदलांविषयी माहिती प्रसारित करण्यासाठी नोड्स एकमेकांशी संवाद साधतात. कोणताही वापरकर्ता नोडमधून कोड अंमलबजावणीची विनंती प्रसारित करून कोडच्या अंमलबजावणीची विनंती देखील करू शकतो. इथेरियम नेटवर्क स्वतः सर्व इथेरियम नोड्स आणि त्यांच्या संवादांचे एकत्रीकरण आहे. + +[नोड्सबद्दल अधिक](/developers/docs/nodes-and-clients/) + +### खाती {#accounts} + +जेथे ETH संग्रहित केले जाते. वापरकर्ते खाती सुरू करू शकतात, खात्यांमध्ये ETH जमा करू शकतात आणि त्यांच्या खात्यांमधून इतर वापरकर्त्यांना ETH हस्तांतरित करू शकतात. खाती आणि खात्यातील शिल्लक EVM मधील एका मोठ्या टेबलमध्ये संग्रहित केली जातात; ते एकूण EVM स्थितीचा एक भाग आहेत. + +[खात्यांबद्दल अधिक](/developers/docs/accounts/) + +### व्यवहार {#transactions} + +"व्यवहार विनंती" ही EVM वरील कोड अंमलबजावणीच्या विनंतीसाठी औपचारिक संज्ञा आहे, आणि "व्यवहार" म्हणजे एक पूर्ण झालेली व्यवहार विनंती आणि EVM स्थितीतील संबंधित बदल. कोणताही वापरकर्ता नोडमधून नेटवर्कवर व्यवहार विनंती प्रसारित करू शकतो. व्यवहार विनंतीने मान्य केलेल्या EVM स्थितीवर परिणाम करण्यासाठी, ती दुसऱ्या नोडद्वारे प्रमाणित, अंमलात आणली आणि "नेटवर्कवर वचनबद्ध" केली जाणे आवश्यक आहे. कोणत्याही कोडच्या अंमलबजावणीमुळे EVM च्या स्थितीत बदल होतो; वचनबद्धतेनंतर, हा स्थिती बदल नेटवर्कमधील सर्व नोड्सवर प्रसारित केला जातो. व्यवहारांची काही उदाहरणे: + +- माझ्या खात्यातून ॲलिसच्या खात्यात X ETH पाठवा. +- काही स्मार्ट कॉन्ट्रॅक्ट कोड EVM स्थितीत प्रकाशित करा. +- EVM मधील X पत्त्यावर असलेल्या स्मार्ट कॉन्ट्रॅक्टचा कोड, Y वितर्कांसह कार्यान्वित करा. + +[व्यवहारांवर अधिक](/developers/docs/transactions/) + +### ब्लॉक्स {#blocks} + +व्यवहारांचे प्रमाण खूप जास्त आहे, म्हणून व्यवहार बॅचमध्ये किंवा ब्लॉक्समध्ये "वचनबद्ध" केले जातात. ब्लॉक्समध्ये साधारणपणे डझनभर ते शेकडो व्यवहार असतात. + +[ब्लॉक्सबद्दल अधिक](/developers/docs/blocks/) + +### स्मार्ट कॉन्ट्रॅक्ट्स {#smart-contracts} + +कोडचा पुन्हा वापरता येण्याजोगा एक स्निपेट (एक प्रोग्राम) जो एक डेव्हलपर EVM स्थितीत प्रकाशित करतो. कोणीही व्यवहार विनंती करून स्मार्ट कॉन्ट्रॅक्ट कोड कार्यान्वित करण्याची विनंती करू शकतो. कारण डेव्हलपर EVM मध्ये कोणतेही कार्यान्वित करण्यायोग्य ॲप्लिकेशन्स (खेळ, बाजारपेठा, आर्थिक साधने, इत्यादी) लिहू शकतात स्मार्ट कॉन्ट्रॅक्ट्स प्रकाशित करून, यांना अनेकदा [dapps, किंवा विकेंद्रित ॲप्स](/developers/docs/dapps/) असेही म्हटले जाते. + +[स्मार्ट कॉन्ट्रॅक्ट्सबद्दल अधिक](/developers/docs/smart-contracts/) + +## पुढील वाचन {#further-reading} + +- [इथेरियम व्हाइटपेपर](/whitepaper/) +- [तरीही, इथेरियम कसे कार्य करते?](https://medium.com/@preethikasireddy/how-does-ethereum-work-anyway-22d1df506369) - _प्रीती कासिरेड्डी_ (**टीप:** हे संसाधन अजूनही मौल्यवान आहे परंतु लक्षात ठेवा की ते [द मर्ज](/roadmap/merge) पूर्वीचे आहे आणि त्यामुळे ते अजूनही इथेरियमच्या प्रूफ-ऑफ-वर्क यंत्रणेचा संदर्भ देते - इथेरियम आता प्रत्यक्षात [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos) वापरून सुरक्षित आहे) + +### तुम्ही पाहून शिकणारे आहात का? {#visual-learner} + +ही व्हिडिओ मालिका पायाभूत विषयांचे सखोल अन्वेषण करते: + + + +[इथेरियम मूलभूत प्लेलिस्ट](https://youtube.com/playlist?list=PLqgutSGloqiJyyoL0zvLVFPS-GMD2wKa5&si=kZTf5I7PKGTXDsOZ) + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ + +## संबंधित ट्युटोरियल्स {#related-tutorials} + +- [डेव्हलपरसाठी इथेरियम मार्गदर्शक, भाग 1](/developers/tutorials/a-developers-guide-to-ethereum-part-one/) _– पायथन आणि web3.py वापरून इथेरियमचे अतिशय नवशिक्या-अनुकूल अन्वेषण_ diff --git a/public/content/translations/mr/developers/docs/mev/index.md b/public/content/translations/mr/developers/docs/mev/index.md new file mode 100644 index 00000000000..5d128e67958 --- /dev/null +++ b/public/content/translations/mr/developers/docs/mev/index.md @@ -0,0 +1,221 @@ +--- +title: "मॅक्सिमम एक्सट्रॅक्टेबल व्हॅल्यू (MEV)" +description: "मॅक्सिमम एक्सट्रॅक्टेबल व्हॅल्यू (MEV) चा परिचय" +lang: mr +--- + +मॅक्सिमल एक्स्ट्रॅक्टेबल व्हॅल्यू (MEV) म्हणजे ब्लॉक रिवॉर्ड आणि गॅस फी व्यतिरिक्त, ब्लॉकमधील ट्रान्झॅक्शनचा समावेश करणे, वगळणे आणि क्रम बदलून ब्लॉक उत्पादनातून काढता येणारे कमाल मूल्य. + +## मॅक्सिमल एक्स्ट्रॅक्टेबल व्हॅल्यू {#maximal-extractable-value} + +मॅक्सिमल एक्स्ट्रॅक्टेबल व्हॅल्यू हे प्रथम [प्रूफ-ऑफ-वर्क](/developers/docs/consensus-mechanisms/pow/) च्या संदर्भात लागू केले गेले होते आणि सुरुवातीला त्याला "मायनर एक्स्ट्रॅक्टेबल व्हॅल्यू" असे संबोधले जात असे. याचे कारण असे की प्रूफ-ऑफ-वर्कमध्ये, मायनर्स ट्रान्झॅक्शनचा समावेश, वगळणे आणि क्रमवारी नियंत्रित करतात. तथापि, [द मर्ज](/roadmap/merge) द्वारे प्रूफ-ऑफ-स्टेकमध्ये संक्रमण झाल्यामुळे, व्हॅलिडेटर्स या भूमिकांसाठी जबाबदार आहेत आणि मायनिंग आता Ethereum प्रोटोकॉलचा भाग नाही. तरीही मूल्य काढण्याच्या पद्धती अस्तित्वात आहेत, म्हणून आता त्याऐवजी "मॅक्सिमल एक्स्ट्रॅक्टेबल व्हॅल्यू" हा शब्द वापरला जातो. + +## पूर्वतयारी {#prerequisites} + +तुम्ही [ट्रान्झॅक्शन्स](/developers/docs/transactions/), [ब्लॉक्स](/developers/docs/blocks/), [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos) आणि [गॅस](/developers/docs/gas/) यांच्याशी परिचित आहात याची खात्री करा. [dapps](/apps/) आणि [DeFi](/defi/) शी ओळख असणे देखील उपयुक्त आहे. + +## MEV एक्स्ट्रॅक्शन {#mev-extraction} + +सिद्धांतानुसार MEV पूर्णपणे व्हॅलिडेटर्सना मिळते कारण ते एकमेव पक्ष आहेत जे फायदेशीर MEV संधीच्या अंमलबजावणीची हमी देऊ शकतात. तथापि, व्यवहारात, MEV चा मोठा भाग "सर्चर्स" म्हणून ओळखल्या जाणाऱ्या स्वतंत्र नेटवर्क सहभागींद्वारे काढला जातो. सर्चर्स फायदेशीर MEV संधी शोधण्यासाठी ब्लॉकचेन डेटावर जटिल अल्गोरिदम चालवतात आणि त्या फायदेशीर ट्रान्झॅक्शन्स नेटवर्कवर स्वयंचलितपणे सबमिट करण्यासाठी बॉट्स वापरतात. + +व्हॅलिडेटर्सना तरीही पूर्ण MEV रकमेचा काही भाग मिळतो कारण सर्चर्स त्यांच्या फायदेशीर ट्रान्झॅक्शन्सना ब्लॉकमध्ये समाविष्ट करण्याची शक्यता वाढवण्याच्या बदल्यात जास्त गॅस फी (जी व्हॅलिडेटरला जाते) देण्यास तयार असतात. सर्चर्स आर्थिकदृष्ट्या तर्कसंगत आहेत असे गृहीत धरल्यास, सर्चर देण्यास तयार असलेली गॅस फी सर्चरच्या MEV च्या १००% पर्यंत असेल (कारण गॅस फी जास्त असल्यास, सर्चरचे नुकसान होईल). + +त्यामुळे, [DEX आर्बिट्राज](#mev-examples-dex-arbitrage) सारख्या काही अत्यंत स्पर्धात्मक MEV संधींसाठी, सर्चर्सना त्यांच्या एकूण MEV महसुलाच्या ९०% किंवा त्याहून अधिक गॅस फी व्हॅलिडेटरला द्यावी लागू शकते कारण अनेक लोकांना तोच फायदेशीर आर्बिट्राज ट्रेड चालवायचा असतो. याचे कारण असे की त्यांचे आर्बिट्राज ट्रान्झॅक्शन चालेल याची हमी देण्याचा एकमेव मार्ग म्हणजे त्यांनी सर्वात जास्त गॅस किंमतीसह ट्रान्झॅक्शन सबमिट करणे. + +### गॅस गोल्फिंग {#mev-extraction-gas-golfing} + +या गतिमानतेमुळे "गॅस गोल्फिंग" मध्ये चांगले असणे — म्हणजेच ट्रान्झॅक्शन्सना अशा प्रकारे प्रोग्रामिंग करणे जेणेकरून ते कमीत कमी गॅस वापरतील — एक स्पर्धात्मक फायदा बनला आहे, कारण यामुळे सर्चर्सना त्यांची एकूण गॅस फी स्थिर ठेवून (कारण गॅस फी = गॅस किंमत \* वापरलेला गॅस) जास्त गॅस किंमत सेट करण्याची अनुमती मिळते. + +काही सुप्रसिद्ध गॅस गोल्फ तंत्रांमध्ये यांचा समावेश आहे: शून्यांच्या लांबलचक स्ट्रिंगने सुरू होणारे पत्ते वापरणे (उदा., [0x0000000000C521824EaFf97Eac7B73B084ef9306](https://eth.blockscout.com/address/0x0000000000C521824EaFf97Eac7B73B084ef9306)) कारण ते संग्रहित करण्यासाठी कमी जागा (आणि त्यामुळे गॅस) घेतात; आणि कॉन्ट्रॅक्टमध्ये लहान [ERC-20](/developers/docs/standards/tokens/erc-20/) टोकन बॅलन्स ठेवणे, कारण स्टोरेज स्लॉट अपडेट करण्यापेक्षा स्टोरेज स्लॉट सुरू करण्यासाठी (बॅलन्स 0 असल्यास) जास्त गॅस लागतो. गॅसचा वापर कमी करण्यासाठी अधिक तंत्रे शोधणे हे सर्चर्समध्ये संशोधनाचे एक सक्रिय क्षेत्र आहे. + +### जनरलाइज्ड फ्रंटरनर्स {#mev-extraction-generalized-frontrunners} + +फायदेशीर MEV संधी शोधण्यासाठी जटिल अल्गोरिदम प्रोग्राम करण्याऐवजी, काही सर्चर्स जनरलाइज्ड फ्रंटरनर्स चालवतात. जनरलाइज्ड फ्रंटरनर्स हे बॉट्स आहेत जे फायदेशीर ट्रान्झॅक्शन्स शोधण्यासाठी मेमपूलवर लक्ष ठेवतात. फ्रंटनरनर संभाव्य फायदेशीर ट्रान्झॅक्शनचा कोड कॉपी करेल, पत्ते फ्रंटनरनरच्या पत्त्यासह बदलेल आणि सुधारित ट्रान्झॅक्शनमुळे फ्रंटनरनरच्या पत्त्यावर नफा होतो की नाही हे तपासण्यासाठी स्थानिक पातळीवर ट्रान्झॅक्शन चालवेल. जर ट्रान्झॅक्शन खरोखरच फायदेशीर असेल, तर फ्रंटनरनर बदललेल्या पत्त्यासह आणि जास्त गॅस किंमतीसह सुधारित ट्रान्झॅक्शन सबमिट करेल, मूळ ट्रान्झॅक्शनला "फ्रंटरनिंग" करेल आणि मूळ सर्चरचा MEV मिळवेल. + +### Flashbots {#mev-extraction-flashbots} + +Flashbots हा एक स्वतंत्र प्रकल्प आहे जो एक्सिक्यूशन क्लायंटना एका सेवेद्वारे विस्तारित करतो ज्यामुळे सर्चर्सना सार्वजनिक मेमपूलमध्ये उघड न करता व्हॅलिडेटर्सना MEV ट्रान्झॅक्शन्स सबमिट करण्याची अनुमती मिळते. यामुळे जनरलाइज्ड फ्रंटरनर्सद्वारे ट्रान्झॅक्शन्सना फ्रंटरन होण्यापासून प्रतिबंधित करते. + +## MEV उदाहरणे {#mev-examples} + +MEV ब्लॉकचेनवर काही मार्गांनी उदयास येते. + +### DEX आर्बिट्राज {#mev-examples-dex-arbitrage} + +[डिसेंट्रलाइज्ड एक्सचेंज](/glossary/#dex) (DEX) आर्बिट्राज ही सर्वात सोपी आणि सर्वात प्रसिद्ध MEV संधी आहे. परिणामी, ही सर्वात स्पर्धात्मक देखील आहे. + +हे असे कार्य करते: जर दोन DEXes दोन वेगवेगळ्या किमतींवर एक टोकन देत असतील, तर कोणीतरी कमी किमतीच्या DEX वर टोकन खरेदी करू शकतो आणि एकाच, अ‍ॅटॉमिक ट्रान्झॅक्शनमध्ये जास्त किमतीच्या DEX वर विकू शकतो. ब्लॉकचेनच्या यांत्रिकीमुळे, हे खरे, जोखीममुक्त आर्बिट्राज आहे. + +येथे एका फायदेशीर आर्बिट्राज ट्रान्झॅक्शनचे [एक उदाहरण आहे](https://eth.blockscout.com/tx/0x5e1657ef0e9be9bc72efefe59a2528d0d730d478cfc9e6cdd09af9f997bb3ef4), जिथे एका सर्चरने Uniswap विरुद्ध Sushiswap वर ETH/DAI जोडीच्या वेगवेगळ्या किंमतींचा फायदा घेऊन 1,000 ETH चे 1,045 ETH मध्ये रूपांतर केले. + +### लिक्विडेशन्स {#mev-examples-liquidations} + +लेंडिंग प्रोटोकॉल लिक्विडेशन्स ही आणखी एक सुप्रसिद्ध MEV संधी आहे. + +Maker आणि Aave सारख्या लेंडिंग प्रोटोकॉलमध्ये वापरकर्त्यांना काही कोलॅटरल (उदा., ETH) जमा करणे आवश्यक असते. हे जमा केलेले कोलॅटरल नंतर इतर वापरकर्त्यांना कर्ज देण्यासाठी वापरले जाते. + +वापरकर्ते नंतर त्यांच्या गरजेनुसार इतरांकडून मालमत्ता आणि टोकन कर्ज घेऊ शकतात (उदा., तुम्हाला MakerDAO गव्हर्नन्स प्रस्तावात मत द्यायचे असल्यास तुम्ही MKR कर्ज घेऊ शकता) त्यांच्या जमा केलेल्या कोलॅटरलच्या ठराविक टक्केवारीपर्यंत. उदाहरणार्थ, जर कर्जाची रक्कम कमाल ३०% असेल, तर प्रोटोकॉलमध्ये १०० DAI जमा करणारा वापरकर्ता दुसऱ्या मालमत्तेच्या ३० DAI पर्यंत कर्ज घेऊ शकतो. प्रोटोकॉल कर्जाच्या क्षमतेची नेमकी टक्केवारी ठरवते. + +कर्जदाराच्या कोलॅटरलचे मूल्य जसे बदलते, तशीच त्यांची कर्ज घेण्याची क्षमताही बदलते. जर, बाजारातील चढउतारामुळे, कर्ज घेतलेल्या मालमत्तेचे मूल्य त्यांच्या कोलॅटरलच्या मूल्याच्या ३०% पेक्षा जास्त झाले (पुन्हा, नेमकी टक्केवारी प्रोटोकॉलद्वारे निर्धारित केली जाते), तर प्रोटोकॉल सामान्यतः कोणालाही कोलॅटरल लिक्विडेट करण्याची परवानगी देतो, ज्यामुळे कर्जदारांना त्वरित पैसे परत मिळतात (हे पारंपारिक फायनान्समध्ये [मार्जिन कॉल्स](https://www.investopedia.com/terms/m/margincall.asp) कसे कार्य करतात यासारखेच आहे). लिक्विडेट झाल्यास, कर्जदाराला सहसा मोठी लिक्विडेशन फी भरावी लागते, ज्यापैकी काही भाग लिक्विडेटरला जातो — इथेच MEV ची संधी निर्माण होते. + +कोणत्या कर्जदारांना लिक्विडेट केले जाऊ शकते हे ठरवण्यासाठी आणि लिक्विडेशन ट्रान्झॅक्शन सबमिट करणारे पहिले होऊन स्वतःसाठी लिक्विडेशन फी गोळा करण्यासाठी सर्चर्स शक्य तितक्या वेगाने ब्लॉकचेन डेटाचे विश्लेषण करण्यासाठी स्पर्धा करतात. + +### सँडविच ट्रेडिंग {#mev-examples-sandwich-trading} + +सँडविच ट्रेडिंग ही MEV एक्स्ट्रॅक्शनची दुसरी सामान्य पद्धत आहे. + +सँडविच करण्यासाठी, एक सर्चर मोठ्या DEX ट्रेड्ससाठी मेमपूलवर लक्ष ठेवेल. उदाहरणार्थ, समजा कोणालातरी Uniswap वर DAI देऊन १०,००० UNI खरेदी करायचे आहेत. या तीव्रतेच्या ट्रेडचा UNI/DAI जोडीवर महत्त्वपूर्ण परिणाम होईल, ज्यामुळे DAI च्या तुलनेत UNI ची किंमत लक्षणीयरीत्या वाढू शकते. + +एक सर्चर UNI/DAI जोडीवर या मोठ्या ट्रेडच्या अंदाजित किंमत प्रभावाची गणना करू शकतो आणि मोठ्या ट्रेडच्या लगेच _आधी_ एक उत्तम खरेदी ऑर्डर कार्यान्वित करू शकतो, स्वस्तात UNI खरेदी करून, नंतर मोठ्या ट्रेडच्या लगेच _नंतर_ विक्री ऑर्डर कार्यान्वित करू शकतो, मोठ्या ऑर्डरमुळे वाढलेल्या किमतीला ते विकून. + +तथापि, सँडविचिंग अधिक जोखमीचे आहे कारण ते अ‍ॅटॉमिक नाही (वर वर्णन केलेल्या DEX आर्बिट्राजच्या विपरीत) आणि ते [salmonella attack](https://github.com/Defi-Cartel/salmonella) ला बळी पडू शकते. + +### NFT MEV {#mev-examples-nfts} + +NFT क्षेत्रात MEV ही एक उदयोन्मुख घटना आहे, आणि ती नेहमीच फायदेशीर नसते. + +तथापि, NFT ट्रान्झॅक्शन्स त्याच ब्लॉकचेनवर होतात ज्यावर इतर सर्व Ethereum ट्रान्झॅक्शन्स होतात, त्यामुळे सर्चर्स NFT मार्केटमध्ये पारंपारिक MEV संधींमध्ये वापरल्या जाणाऱ्या तंत्रांसारखीच तंत्रे वापरू शकतात. + +उदाहरणार्थ, जर एखादा लोकप्रिय NFT ड्रॉप असेल आणि सर्चरला ठराविक NFT किंवा NFTs चा सेट हवा असेल, तर ते अशा प्रकारे ट्रान्झॅक्शन प्रोग्राम करू शकतात की ते NFT खरेदी करण्यासाठी रांगेत पहिले असतील, किंवा ते एकाच ट्रान्झॅक्शनमध्ये NFTs चा संपूर्ण सेट खरेदी करू शकतात. किंवा जर एखादे NFT [चुकून कमी किमतीत सूचीबद्ध झाले](https://www.theblockcrypto.com/post/113546/mistake-sees-69000-cryptopunk-sold-for-less-than-a-cent), तर एक सर्चर इतर खरेदीदारांना फ्रंटरन करून ते स्वस्तात मिळवू शकतो. + +NFT MEV चे एक प्रमुख उदाहरण तेव्हा घडले जेव्हा एका सर्चरने ७ दशलक्ष डॉलर्स खर्च करून प्राइस फ्लोरवर प्रत्येक Cryptopunk [खरेदी केला](https://eth.blockscout.com/address/0x650dCdEB6ecF05aE3CAF30A70966E2F395d5E9E5?tab=txs). एका ब्लॉकचेन संशोधकाने [Twitter वर स्पष्ट केले](https://twitter.com/IvanBogatyy/status/1422232184493121538) की खरेदीदाराने आपली खरेदी गुप्त ठेवण्यासाठी MEV प्रदात्यासोबत कसे काम केले. + +### लाँग टेल {#mev-examples-long-tail} + +DEX आर्बिट्राज, लिक्विडेशन्स आणि सँडविच ट्रेडिंग या सर्व सुप्रसिद्ध MEV संधी आहेत आणि नवीन सर्चर्ससाठी फायदेशीर ठरण्याची शक्यता कमी आहे. तथापि, कमी ज्ञात MEV संधींची एक लाँग टेल आहे (NFT MEV ही अशीच एक संधी आहे). + +जे सर्चर्स नुकतेच सुरुवात करत आहेत त्यांना या लाँग टेलमध्ये MEV शोधून अधिक यश मिळू शकते. Flashbot चा [MEV जॉब बोर्ड](https://github.com/flashbots/mev-job-board) काही उदयोन्मुख संधींची यादी करतो. + +## MEV चे परिणाम {#effects-of-mev} + +MEV पूर्णपणे वाईट नाही — Ethereum वर MEV चे सकारात्मक आणि नकारात्मक दोन्ही परिणाम आहेत. + +### चांगले {#effects-of-mev-the-good} + +अनेक DeFi प्रकल्प त्यांच्या प्रोटोकॉलची उपयुक्तता आणि स्थिरता सुनिश्चित करण्यासाठी आर्थिकदृष्ट्या तर्कसंगत घटकांवर अवलंबून असतात. उदाहरणार्थ, DEX आर्बिट्राज हे सुनिश्चित करते की वापरकर्त्यांना त्यांच्या टोकनसाठी सर्वोत्तम, सर्वात योग्य किंमती मिळतील आणि लेंडिंग प्रोटोकॉल कर्जदारांना पैसे परत मिळतील याची खात्री करण्यासाठी कर्जदार कोलॅटरलायझेशन गुणोत्तराच्या खाली आल्यावर जलद लिक्विडेशनवर अवलंबून असतात. + +आर्थिक अकार्यक्षमता शोधणारे आणि दुरुस्त करणारे आणि प्रोटोकॉलच्या आर्थिक प्रोत्साहनांचा फायदा घेणारे तर्कसंगत सर्चर्स नसतील तर, DeFi प्रोटोकॉल आणि सर्वसाधारणपणे dapps आज जितके मजबूत आहेत तितके मजबूत नसतील. + +### वाईट {#effects-of-mev-the-bad} + +अ‍ॅप्लिकेशन लेयरवर, MEV चे काही प्रकार, जसे की सँडविच ट्रेडिंग, वापरकर्त्यांसाठी निःसंशयपणे वाईट अनुभवाचे कारण ठरतात. सँडविच झालेल्या वापरकर्त्यांना त्यांच्या ट्रेड्सवर वाढीव स्लिपेज आणि खराब एक्सिक्यूशनचा सामना करावा लागतो. + +नेटवर्क लेयरवर, जनरलाइज्ड फ्रंटरनर्स आणि ते अनेकदा सहभागी होणारे गॅस-प्राइस ऑक्शन्स (जेव्हा दोन किंवा अधिक फ्रंटरनर्स त्यांच्या ट्रान्झॅक्शनला पुढील ब्लॉकमध्ये समाविष्ट करण्यासाठी स्पर्धा करतात आणि स्वतःच्या ट्रान्झॅक्शनची गॅस किंमत हळूहळू वाढवतात) यामुळे नेटवर्क कंजेशन आणि सामान्य ट्रान्झॅक्शन्स चालवण्याचा प्रयत्न करणाऱ्या इतर सर्वांसाठी उच्च गॅस किंमती होतात. + +ब्लॉक्सच्या _आत_ काय घडत आहे यापलीकडे, MEV चे ब्लॉक्सच्या _दरम्यान_ हानिकारक परिणाम होऊ शकतात. जर ब्लॉकमध्ये उपलब्ध MEV मानक ब्लॉक रिवॉर्डपेक्षा लक्षणीयरीत्या जास्त असेल, तर व्हॅलिडेटर्सना ब्लॉक्सचे रिऑर्गनायझेशन करण्यासाठी आणि स्वतःसाठी MEV मिळवण्यासाठी प्रोत्साहन मिळू शकते, ज्यामुळे ब्लॉकचेन रि-ऑर्गनायझेशन आणि कन्सेन्सस अस्थिरता निर्माण होते. + +ब्लॉकचेन रि-ऑर्गनायझेशनची ही शक्यता [पूर्वी Bitcoin ब्लॉकचेनवर तपासली गेली आहे](https://dl.acm.org/doi/10.1145/2976749.2978408). Bitcoin चा ब्लॉक रिवॉर्ड अर्धा होत असताना आणि ट्रान्झॅक्शन फी ब्लॉक रिवॉर्डचा अधिकाधिक मोठा भाग बनत असताना, अशी परिस्थिती निर्माण होते जिथे मायनर्ससाठी पुढील ब्लॉकचा रिवॉर्ड सोडून देणे आणि त्याऐवजी जास्त फी असलेले मागील ब्लॉक्स पुन्हा माइन करणे आर्थिकदृष्ट्या तर्कसंगत ठरते. MEV च्या वाढीसह, Ethereum मध्येही अशीच परिस्थिती उद्भवू शकते, ज्यामुळे ब्लॉकचेनच्या अखंडतेला धोका निर्माण होतो. + +## MEV ची स्थिती {#state-of-mev} + +२०२१ च्या सुरुवातीला MEV एक्स्ट्रॅक्शनमध्ये मोठी वाढ झाली, ज्यामुळे वर्षाच्या पहिल्या काही महिन्यांत गॅसच्या किमती प्रचंड वाढल्या. Flashbots च्या MEV रिलेच्या उदयामुळे जनरलाइज्ड फ्रंटरनर्सची प्रभावीता कमी झाली आहे आणि गॅस प्राइस ऑक्शन्स ऑफचेन गेले आहेत, ज्यामुळे सामान्य वापरकर्त्यांसाठी गॅसच्या किमती कमी झाल्या आहेत. + +जरी अनेक सर्चर्स अजूनही MEV मधून चांगली कमाई करत असले तरी, संधी अधिक ज्ञात झाल्यामुळे आणि अधिकाधिक सर्चर्स त्याच संधीसाठी स्पर्धा करत असल्यामुळे, व्हॅलिडेटर्स एकूण MEV महसुलाचा अधिकाधिक भाग मिळवतील (कारण वर वर्णन केल्याप्रमाणेच गॅस ऑक्शन्स Flashbots मध्ये देखील होतात, जरी खासगी असले तरी, आणि व्हॅलिडेटर्स परिणामी गॅस महसूल मिळवतील). MEV फक्त Ethereum पुरते मर्यादित नाही, आणि Ethereum वर संधी अधिक स्पर्धात्मक होत असल्याने, सर्चर्स Binance Smart Chain सारख्या पर्यायी ब्लॉकचेनकडे वळत आहेत, जिथे Ethereum सारख्याच MEV संधी कमी स्पर्धेत अस्तित्वात आहेत. + +दुसरीकडे, प्रूफ-ऑफ-वर्कमधून प्रूफ-ऑफ-स्टेककडे संक्रमण आणि रोलअप वापरून Ethereum ला स्केल करण्याचे चालू प्रयत्न हे सर्व MEV लँडस्केपमध्ये अशा प्रकारे बदल घडवत आहेत जे अद्याप काहीसे अस्पष्ट आहेत. प्रूफ-ऑफ-वर्कमधील संभाव्य मॉडेलच्या तुलनेत, थोडे आगाऊ ज्ञात असलेले हमीपूर्ण ब्लॉक-प्रपोजर्स MEV एक्स्ट्रॅक्शनची गतिशीलता कशी बदलतात किंवा [सिंगल सीक्रेट लीडर इलेक्शन](https://ethresear.ch/t/secret-non-single-leader-election/11789) आणि [डिस्ट्रिब्युटेड व्हॅलिडेटर टेक्नॉलॉजी](/staking/dvt/) लागू झाल्यावर यात कसा व्यत्यय येईल हे अद्याप चांगले ज्ञात नाही. त्याचप्रमाणे, जेव्हा बहुतेक वापरकर्ता क्रियाकलाप Ethereum वरून त्याच्या लेयर 2 रोलअप्स आणि शार्ड्सवर पोर्ट केले जातात तेव्हा कोणत्या MEV संधी अस्तित्वात असतील हे पाहणे बाकी आहे. + +## Ethereum प्रूफ-ऑफ-स्टेक (PoS) मधील MEV {#mev-in-ethereum-proof-of-stake} + +स्पष्ट केल्याप्रमाणे, MEV चे एकूण वापरकर्ता अनुभव आणि कन्सेन्सस-लेयर सुरक्षेवर नकारात्मक परिणाम होतात. परंतु Ethereum चे प्रूफ-ऑफ-स्टेक कन्सेन्ससमध्ये संक्रमण (“द मर्ज” असे संबोधले जाणारे) संभाव्यतः नवीन MEV-संबंधित धोके निर्माण करते: + +### व्हॅलिडेटर केंद्रीकरण {#validator-centralization} + +मर्ज-नंतरच्या Ethereum मध्ये, व्हॅलिडेटर्स (३२ ETH ची सुरक्षा ठेव जमा केलेले) बीकन चेनमध्ये जोडलेल्या ब्लॉक्सच्या वैधतेवर एकमत करतात. ३२ ETH अनेकांच्या आवाक्याबाहेर असू शकत असल्याने, [स्टेकिंग पूलमध्ये सामील होणे](/staking/pools/) हा एक अधिक व्यवहार्य पर्याय असू शकतो. तरीही, [सोलो स्टेकर्स](/staking/solo/) चे निरोगी वितरण आदर्श आहे, कारण ते व्हॅलिडेटर्सचे केंद्रीकरण कमी करते आणि Ethereum ची सुरक्षा सुधारते. + +तथापि, MEV एक्स्ट्रॅक्शन व्हॅलिडेटर केंद्रीकरणाला गती देण्यास सक्षम असल्याचे मानले जाते. याचे एक कारण असे आहे की, व्हॅलिडेटर्स [ब्लॉक प्रस्तावित करण्यासाठी कमी कमाई करतात](/roadmap/merge/issuance/#how-the-merge-impacts-ETH-supply) पूर्वी मायनर्सच्या तुलनेत, MEV एक्स्ट्रॅक्शनने [द मर्ज](/roadmap/merge/) पासून [व्हॅलिडेटर कमाईवर खूप प्रभाव टाकला आहे](https://github.com/flashbots/eth2-research/blob/main/notebooks/mev-in-eth2/eth2-mev-calc.ipynb). + +मोठ्या स्टेकिंग पूल्सकडे MEV संधी मिळवण्यासाठी आवश्यक ऑप्टिमायझेशनमध्ये गुंतवणूक करण्यासाठी अधिक संसाधने असण्याची शक्यता आहे. हे पूल्स जितके जास्त MEV काढतील, तितकीच त्यांची MEV-एक्स्ट्रॅक्शन क्षमता सुधारण्यासाठी (आणि एकूण महसूल वाढवण्यासाठी) त्यांच्याकडे अधिक संसाधने असतील, ज्यामुळे मूलतः [इकोनॉमीज ऑफ स्केल](https://www.investopedia.com/terms/e/economiesofscale.asp#) तयार होतील. + +कमी संसाधने उपलब्ध असल्यामुळे, सोलो स्टेकर्सना MEV संधींमधून नफा मिळवणे शक्य होणार नाही. यामुळे स्वतंत्र व्हॅलिडेटर्सवर त्यांची कमाई वाढवण्यासाठी शक्तिशाली स्टेकिंग पूल्समध्ये सामील होण्याचा दबाव वाढू शकतो, ज्यामुळे Ethereum मधील विकेंद्रीकरण कमी होईल. + +### परमिशन असलेले मेमपूल्स {#permissioned-mempools} + +सँडविचिंग आणि फ्रंटरनिंग हल्ल्यांना प्रतिसाद म्हणून, ट्रेडर्स ट्रान्झॅक्शन गोपनीयतेसाठी व्हॅलिडेटर्ससोबत ऑफचेन सौदे करण्यास सुरुवात करू शकतात. संभाव्य MEV ट्रान्झॅक्शन सार्वजनिक मेमपूलवर पाठवण्याऐवजी, ट्रेडर ते थेट व्हॅलिडेटरला पाठवतो, जो ते एका ब्लॉकमध्ये समाविष्ट करतो आणि ट्रेडर्ससोबत नफा वाटून घेतो. + +“डार्क पूल्स” ही या व्यवस्थेची एक मोठी आवृत्ती आहे आणि ते परमिशन असलेले, केवळ-प्रवेश मेमपूल म्हणून कार्य करतात जे ठराविक फी भरण्यास इच्छुक असलेल्या वापरकर्त्यांसाठी खुले आहेत. हा ट्रेंड Ethereum ची परवानगी नसलेली आणि विश्वास नसलेली वैशिष्ट्ये कमी करेल आणि संभाव्यतः ब्लॉकचेनला “पे-टू-प्ले” यंत्रणेत रूपांतरित करेल जे सर्वाधिक बोली लावणाऱ्याला अनुकूल असेल. + +परमिशन असलेले मेमपूल मागील विभागात वर्णन केलेल्या केंद्रीकरणाच्या धोक्यांनाही गती देतील. अनेक व्हॅलिडेटर्स चालवणारे मोठे पूल्स ट्रेडर्स आणि वापरकर्त्यांना ट्रान्झॅक्शन गोपनीयता देऊ करून फायदा मिळवण्याची शक्यता आहे, ज्यामुळे त्यांचे MEV महसूल वाढेल. + +मर्ज-नंतरच्या Ethereum मध्ये या MEV-संबंधित समस्यांवर मात करणे हे संशोधनाचे एक मुख्य क्षेत्र आहे. आजपर्यंत, द मर्ज नंतर Ethereum च्या विकेंद्रीकरण आणि सुरक्षेवर MEV चा नकारात्मक परिणाम कमी करण्यासाठी प्रस्तावित केलेले दोन उपाय म्हणजे [**प्रपोजर-बिल्डर सेपरेशन (PBS)**](/roadmap/pbs/) आणि [**बिल्डर API**](https://github.com/ethereum/builder-specs). + +### प्रपोजर-बिल्डर सेपरेशन {#proposer-builder-separation} + +प्रूफ-ऑफ-वर्क आणि प्रूफ-ऑफ-स्टेक या दोन्हीमध्ये, एक नोड जो ब्लॉक तयार करतो तो चेनमध्ये जोडण्यासाठी कन्सेन्ससमध्ये सहभागी होणाऱ्या इतर नोड्सना प्रस्तावित करतो. जेव्हा दुसरा मायनर त्यावर (PoW मध्ये) तयार करतो किंवा त्याला बहुसंख्य व्हॅलिडेटर्सकडून (PoS मध्ये) अटेस्टेशन्स मिळतात तेव्हा नवीन ब्लॉक कॅनॉनिकल चेनचा भाग बनतो. + +ब्लॉक प्रोड्युसर आणि ब्लॉक प्रपोजरच्या भूमिकांचे संयोजन हे पूर्वी वर्णन केलेल्या बहुतेक MEV-संबंधित समस्यांना कारणीभूत ठरते. उदाहरणार्थ, कन्सेन्सस नोड्सना MEV कमाई वाढवण्यासाठी [टाइम-बँडिट अटॅक्स](https://www.mev.wiki/attack-examples/time-bandit-attack) मध्ये चेन रिऑर्गनायझेशन सुरू करण्यासाठी प्रोत्साहन दिले जाते. + +[प्रपोजर-बिल्डर सेपरेशन](https://ethresear.ch/t/proposer-block-builder-separation-friendly-fee-market-designs/9725) (PBS) MEV चा प्रभाव कमी करण्यासाठी डिझाइन केले आहे, विशेषतः कन्सेन्सस लेयरवर. PBS चे मुख्य वैशिष्ट्य म्हणजे ब्लॉक प्रोड्युसर आणि ब्लॉक प्रपोजरच्या नियमांचे विभाजन. व्हॅलिडेटर्स अजूनही ब्लॉक्स प्रस्तावित करण्यासाठी आणि त्यावर मतदान करण्यासाठी जबाबदार आहेत, परंतु **ब्लॉक बिल्डर्स** नावाच्या विशेष संस्थांचा एक नवीन वर्ग, ट्रान्झॅक्शन्सची क्रमवारी लावणे आणि ब्लॉक्स तयार करण्याचे काम करतो. + +PBS अंतर्गत, एक ब्लॉक बिल्डर एक ट्रान्झॅक्शन बंडल तयार करतो आणि बीकन चेन ब्लॉकमध्ये (“एक्सिक्यूशन पेलोड” म्हणून) समाविष्ट करण्यासाठी बोली लावतो. पुढील ब्लॉक प्रस्तावित करण्यासाठी निवडलेला व्हॅलिडेटर नंतर विविध बोली तपासतो आणि सर्वाधिक फी असलेला बंडल निवडतो. PBS मूलतः एक लिलाव बाजार तयार करतो, जिथे बिल्डर्स ब्लॉकस्पेस विकणाऱ्या व्हॅलिडेटर्ससोबत वाटाघाटी करतात. + +सध्याचे PBS डिझाइन [कमिट-रिव्हील स्कीम](https://gitcoin.co/blog/commit-reveal-scheme-on-ethereum/) वापरतात ज्यात बिल्डर्स त्यांच्या बोलींसोबत फक्त ब्लॉकच्या सामग्रीसाठी (ब्लॉक हेडर) क्रिप्टोग्राफिक कमिटमेंट प्रकाशित करतात. विजेती बोली स्वीकारल्यानंतर, प्रपोजर एक स्वाक्षरी केलेला ब्लॉक प्रस्ताव तयार करतो ज्यात ब्लॉक हेडर समाविष्ट असतो. स्वाक्षरी केलेला ब्लॉक प्रस्ताव पाहिल्यानंतर ब्लॉक बिल्डरने संपूर्ण ब्लॉक बॉडी प्रकाशित करणे अपेक्षित आहे, आणि अंतिम होण्यापूर्वी त्याला व्हॅलिडेटर्सकडून पुरेसे [अटेस्टेशन्स](/glossary/#attestation) देखील मिळणे आवश्यक आहे. + +#### प्रपोजर-बिल्डर सेपरेशन MEV चा प्रभाव कसा कमी करते? {#how-does-pbs-curb-mev-impact} + +इन-प्रोटोकॉल प्रपोजर-बिल्डर सेपरेशन व्हॅलिडेटर्सच्या कार्यक्षेत्रातून MEV एक्स्ट्रॅक्शन काढून टाकून कन्सेन्ससवर MEV चा प्रभाव कमी करते. त्याऐवजी, विशेष हार्डवेअर चालवणारे ब्लॉक बिल्डर्स पुढे MEV संधी मिळवतील. + +तथापि, यामुळे व्हॅलिडेटर्सना MEV-संबंधित उत्पन्नातून पूर्णपणे वगळले जात नाही, कारण बिल्डर्सना त्यांचे ब्लॉक्स व्हॅलिडेटर्सकडून स्वीकारले जाण्यासाठी उच्च बोली लावावी लागते. तरीही, व्हॅलिडेटर्स आता थेट MEV उत्पन्न ऑप्टिमाइझ करण्यावर लक्ष केंद्रित करत नसल्यामुळे, टाइम-बँडिट हल्ल्यांचा धोका कमी होतो. + +प्रपोजर-बिल्डर सेपरेशन MEV च्या केंद्रीकरणाच्या धोक्यांनाही कमी करते. उदाहरणार्थ, कमिट-रिव्हील स्कीमच्या वापरामुळे बिल्डर्सना व्हॅलिडेटर्सवर MEV संधी चोरणार नाहीत किंवा ती इतर बिल्डर्ससमोर उघड करणार नाहीत यावर विश्वास ठेवण्याची गरज नाही. हे सोलो स्टेकर्ससाठी MEV मधून फायदा मिळवण्याचा अडथळा कमी करते, अन्यथा, बिल्डर्स ऑफचेन प्रतिष्ठा असलेल्या मोठ्या पूल्सना अनुकूलता दर्शविण्याकडे आणि त्यांच्यासोबत ऑफचेन सौदे करण्याकडे कल ठेवतील. + +त्याचप्रमाणे, व्हॅलिडेटर्सना बिल्डर्सवर विश्वास ठेवण्याची गरज नाही की ते ब्लॉक बॉडी रोखून धरणार नाहीत किंवा अवैध ब्लॉक्स प्रकाशित करणार नाहीत कारण पेमेंट बिनशर्त आहे. प्रस्तावित ब्लॉक अनुपलब्ध असला किंवा इतर व्हॅलिडेटर्सद्वारे अवैध घोषित केला गेला तरीही व्हॅलिडेटरची फी प्रक्रिया केली जाते. नंतरच्या बाबतीत, ब्लॉक फक्त टाकून दिला जातो, ज्यामुळे ब्लॉक बिल्डरला सर्व ट्रान्झॅक्शन फी आणि MEV महसूल गमवावा लागतो. + +### बिल्डर API {#builder-api} + +जरी प्रपोजर-बिल्डर सेपरेशन MEV एक्स्ट्रॅक्शनचे परिणाम कमी करण्याचे वचन देत असले तरी, ते लागू करण्यासाठी कन्सेन्सस प्रोटोकॉलमध्ये बदल आवश्यक आहेत. विशेषतः, बीकन चेनवरील [फोर्क चॉइस](/developers/docs/consensus-mechanisms/pos/#fork-choice) नियम अपडेट करणे आवश्यक असेल. [बिल्डर API](https://github.com/ethereum/builder-specs) हा एक तात्पुरता उपाय आहे ज्याचा उद्देश प्रपोजर-बिल्डर सेपरेशनची कार्यरत अंमलबजावणी प्रदान करणे आहे, जरी त्यात जास्त विश्वासाची गृहीतके आहेत. + +बिल्डर API हे [इंजिन API](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md) ची एक सुधारित आवृत्ती आहे, जी कन्सेन्सस लेयर क्लायंटद्वारे एक्सिक्यूशन लेयर क्लायंटकडून एक्सिक्यूशन पेलोडची विनंती करण्यासाठी वापरली जाते. [ऑनेस्ट व्हॅलिडेटर स्पेसिफिकेशन](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/validator.md) मध्ये सांगितल्याप्रमाणे, ब्लॉक प्रस्तावित करण्याच्या कर्तव्यांसाठी निवडलेले व्हॅलिडेटर्स कनेक्टेड एक्सिक्यूशन क्लायंटकडून एक ट्रान्झॅक्शन बंडलची विनंती करतात, जे ते प्रस्तावित बीकन चेन ब्लॉकमध्ये समाविष्ट करतात. + +बिल्डर API व्हॅलिडेटर्स आणि एक्सिक्यूशन-लेयर क्लायंट्समध्ये एक मिडलवेअर म्हणून देखील कार्य करते; परंतु ते वेगळे आहे कारण ते बीकन चेनवरील व्हॅलिडेटर्सना बाह्य संस्थांकडून ब्लॉक्स मिळवण्याची अनुमती देते (एक्सिक्यूशन क्लायंट वापरून स्थानिक पातळीवर ब्लॉक तयार करण्याऐवजी). + +बिल्डर API कसे कार्य करते याचे विहंगावलोकन खाली दिले आहे: + +1. बिल्डर API व्हॅलिडेटरला एक्सिक्यूशन लेयर क्लायंट चालवणार्‍या ब्लॉक बिल्डर्सच्या नेटवर्कशी जोडते. PBS प्रमाणेच, बिल्डर्स हे विशेष पक्ष आहेत जे संसाधन-केंद्रित ब्लॉक-बिल्डिंगमध्ये गुंतवणूक करतात आणि MEV + प्रायोरिटी टिप्समधून मिळणारा महसूल वाढवण्यासाठी विविध धोरणे वापरतात. + +2. एक व्हॅलिडेटर (कन्सेन्सस लेयर क्लायंट चालवणारा) बिल्डर्सच्या नेटवर्ककडून बोलींसोबत एक्सिक्यूशन पेलोडची विनंती करतो. बिल्डर्सच्या बोलींमध्ये एक्सिक्यूशन पेलोड हेडर—पेलोडच्या सामग्रीसाठी एक क्रिप्टोग्राफिक कमिटमेंट—आणि व्हॅलिडेटरला देय असलेली फी असेल. + +3. व्हॅलिडेटर येणाऱ्या बोलींचे पुनरावलोकन करतो आणि सर्वाधिक फी असलेला एक्सिक्यूशन पेलोड निवडतो. बिल्डर API वापरून, व्हॅलिडेटर एक "ब्लाइंडेड" बीकन ब्लॉक प्रस्ताव तयार करतो ज्यात फक्त त्यांची स्वाक्षरी आणि एक्सिक्यूशन पेलोड हेडर समाविष्ट असतो आणि ते बिल्डरला पाठवतो. + +4. ब्लाइंडेड ब्लॉक प्रस्ताव पाहिल्यावर बिल्डर API चालवणार्‍या बिल्डरने संपूर्ण एक्सिक्यूशन पेलोडसह प्रतिसाद देणे अपेक्षित आहे. यामुळे व्हॅलिडेटरला एक "साईन्ड" बीकन ब्लॉक तयार करण्याची अनुमती मिळते, जो ते संपूर्ण नेटवर्कवर प्रसारित करतात. + +5. बिल्डर API वापरणार्‍या व्हॅलिडेटरने ब्लॉक बिल्डर वेळेवर प्रतिसाद देण्यात अयशस्वी झाल्यास स्थानिक पातळीवर ब्लॉक तयार करणे अपेक्षित आहे, जेणेकरून ते ब्लॉक प्रस्ताव रिवॉर्ड गमावणार नाहीत. तथापि, व्हॅलिडेटर आता उघड झालेल्या ट्रान्झॅक्शन्स किंवा दुसऱ्या सेटचा वापर करून दुसरा ब्लॉक तयार करू शकत नाही, कारण ते _इक्विव्होकेशन_ (एकाच स्लॉटमध्ये दोन ब्लॉक्सवर स्वाक्षरी करणे) ठरेल, जो एक स्लॅशेबल गुन्हा आहे. + +बिल्डर API चे एक उदाहरण म्हणजे [MEV बूस्ट](https://github.com/flashbots/mev-boost), जे Ethereum वर MEV च्या नकारात्मक बाह्य परिणामांवर नियंत्रण ठेवण्यासाठी डिझाइन केलेल्या [Flashbots ऑक्शन मेकॅनिझम](https://docs.flashbots.net/Flashbots-auction/overview) मधील एक सुधारणा आहे. Flashbots ऑक्शन प्रूफ-ऑफ-स्टेकमधील व्हॅलिडेटर्सना फायदेशीर ब्लॉक्स तयार करण्याचे काम **सर्चर्स** नावाच्या विशेष पक्षांना आउटसोर्स करण्याची अनुमती देते. +![MEV प्रवाहाचा तपशीलवार आकृती](./mev.png) + +सर्चर्स आकर्षक MEV संधी शोधतात आणि ब्लॉकमध्ये समाविष्ट करण्यासाठी [सील्ड-प्राइस बिड](https://en.wikipedia.org/wiki/First-price_sealed-bid_auction) सोबत ब्लॉक प्रपोजर्सना ट्रान्झॅक्शन बंडल पाठवतात. mev-geth चालवणार्‍या व्हॅलिडेटरला, जो go-ethereum (Geth) क्लायंटची एक फोर्क केलेली आवृत्ती आहे, फक्त सर्वाधिक नफा असलेला बंडल निवडावा लागतो आणि तो नवीन ब्लॉकचा भाग म्हणून समाविष्ट करावा लागतो. ब्लॉक प्रपोजर्स (व्हॅलिडेटर्स) यांना स्पॅम आणि अवैध ट्रान्झॅक्शन्सपासून संरक्षण देण्यासाठी, ट्रान्झॅक्शन बंडल प्रपोजरपर्यंत पोहोचण्यापूर्वी व्हॅलिडेशनसाठी **रिलेअर्स** मधून जातात. + +MEV बूस्ट मूळ Flashbots ऑक्शनची कार्यपद्धती कायम ठेवते, जरी Ethereum च्या प्रूफ-ऑफ-स्टेककडे स्विच करण्यासाठी डिझाइन केलेल्या नवीन वैशिष्ट्यांसह. सर्चर्स अजूनही ब्लॉक्समध्ये समाविष्ट करण्यासाठी फायदेशीर MEV ट्रान्झॅक्शन्स शोधतात, परंतु **बिल्डर्स** नावाचा एक नवीन विशेष पक्षांचा वर्ग, ट्रान्झॅक्शन्स आणि बंडल्स ब्लॉक्समध्ये एकत्रित करण्यासाठी जबाबदार आहे. एक बिल्डर सर्चर्सकडून सील्ड-प्राइस बोली स्वीकारतो आणि सर्वात फायदेशीर क्रमवारी शोधण्यासाठी ऑप्टिमायझेशन चालवतो. + +रिलेअर अजूनही ट्रान्झॅक्शन बंडल प्रपोजरकडे पाठवण्यापूर्वी ते व्हॅलिडेट करण्यासाठी जबाबदार आहे. तथापि, MEV बूस्ट **एस्क्रो** सादर करते जे बिल्डर्सद्वारे पाठवलेले ब्लॉक बॉडी आणि व्हॅलिडेटर्सद्वारे पाठवलेले ब्लॉक हेडर्स संग्रहित करून [डेटा उपलब्धता](/developers/docs/data-availability/) प्रदान करण्यासाठी जबाबदार असतात. येथे, रिलेशी कनेक्ट केलेला व्हॅलिडेटर उपलब्ध एक्सिक्यूशन पेलोड्सची मागणी करतो आणि सर्वाधिक बोली + MEV टिप्स असलेला पेलोड हेडर निवडण्यासाठी MEV बूस्टच्या ऑर्डरिंग अल्गोरिदमचा वापर करतो. + +#### बिल्डर API MEV चा प्रभाव कसा कमी करते? {#how-does-builder-api-curb-mev-impact} + +बिल्डर API चा मुख्य फायदा म्हणजे MEV संधींमध्ये प्रवेश लोकशाहीकरण करण्याची त्याची क्षमता. कमिट-रिव्हील स्कीम वापरल्याने विश्वासाची गृहीतके दूर होतात आणि MEV चा लाभ घेऊ इच्छिणाऱ्या व्हॅलिडेटर्ससाठी प्रवेशाचे अडथळे कमी होतात. यामुळे सोलो स्टेकर्सवर MEV नफा वाढवण्यासाठी मोठ्या स्टेकिंग पूल्समध्ये एकत्रित होण्याचा दबाव कमी झाला पाहिजे. + +बिल्डर API च्या व्यापक अंमलबजावणीमुळे ब्लॉक बिल्डर्समध्ये अधिक स्पर्धेला प्रोत्साहन मिळेल, ज्यामुळे सेन्सॉरशिप प्रतिरोध वाढतो. व्हॅलिडेटर्स अनेक बिल्डर्सच्या बोलींचे पुनरावलोकन करत असल्यामुळे, एक किंवा अधिक वापरकर्ता ट्रान्झॅक्शन्स सेन्सॉर करण्याचा हेतू असलेल्या बिल्डरला यशस्वी होण्यासाठी इतर सर्व नॉन-सेन्सॉरिंग बिल्डर्सपेक्षा जास्त बोली लावावी लागेल. यामुळे वापरकर्त्यांना सेन्सॉर करण्याची किंमत प्रचंड वाढते आणि या प्रथेला परावृत्त करते. + +काही प्रकल्प, जसे की MEV बूस्ट, बिल्डर API चा वापर अशा समग्र रचनेचा भाग म्हणून करतात जी फ्रंटरनिंग/सँडविचिंग हल्ले टाळण्याचा प्रयत्न करणाऱ्या ट्रेडर्ससारख्या विशिष्ट पक्षांना ट्रान्झॅक्शन गोपनीयता प्रदान करण्यासाठी डिझाइन केलेली आहे. हे वापरकर्ते आणि ब्लॉक बिल्डर्स यांच्यात एक खाजगी संवाद चॅनेल प्रदान करून साध्य केले जाते. पूर्वी वर्णन केलेल्या परमिशन असलेल्या मेमपूल्सच्या विपरीत, हा दृष्टिकोन खालील कारणांसाठी फायदेशीर आहे: + +1. बाजारात अनेक बिल्डर्सच्या अस्तित्वामुळे सेन्सॉरिंग अव्यवहार्य बनते, ज्यामुळे वापरकर्त्यांना फायदा होतो. याउलट, केंद्रीकृत आणि विश्वास-आधारित डार्क पूल्सच्या अस्तित्वामुळे काही ब्लॉक बिल्डर्सच्या हातात सत्ता केंद्रित होईल आणि सेन्सॉरिंगची शक्यता वाढेल. + +2. बिल्डर API सॉफ्टवेअर ओपन-सोर्स आहे, ज्यामुळे कोणालाही ब्लॉक-बिल्डर सेवा देऊ करण्याची अनुमती मिळते. याचा अर्थ असा की वापरकर्त्यांना कोणताही विशिष्ट ब्लॉक बिल्डर वापरण्यास भाग पाडले जात नाही आणि यामुळे Ethereum ची तटस्थता आणि परवानगी नसलेली वैशिष्ट्ये सुधारतात. शिवाय, MEV शोधणारे ट्रेडर्स खाजगी ट्रान्झॅक्शन चॅनेल वापरून अनावधानाने केंद्रीकरणाला हातभार लावणार नाहीत. + +## संबंधित संसाधने {#related-resources} + +- [Flashbots डॉक्स](https://docs.flashbots.net/) +- [Flashbots GitHub](https://github.com/flashbots/pm) +- [mevboost.org](https://www.mevboost.org/) - _MEV-बूस्ट रिले आणि ब्लॉक बिल्डर्ससाठी रिअल-टाइम आकडेवारीसह ट्रॅकर_ + +## पुढील वाचन {#further-reading} + +- [मायनर-एक्स्ट्रॅक्टेबल व्हॅल्यू (MEV) म्हणजे काय?](https://blog.chain.link/what-is-miner-extractable-value-mev/) +- [MEV आणि मी](https://www.paradigm.xyz/2021/02/mev-and-me) +- [Ethereum एक गडद जंगल आहे](https://www.paradigm.xyz/2020/08/ethereum-is-a-dark-forest/) +- [गडद जंगलातून सुटका](https://samczsun.com/escaping-the-dark-forest/) +- [Flashbots: MEV संकटाचे फ्रंटरनिंग](https://medium.com/flashbots/frontrunning-the-mev-crisis-40629a613752) +- [@bertcmiller चे MEV थ्रेड्स](https://twitter.com/bertcmiller/status/1402665992422047747) +- [MEV-बूस्ट: मर्जसाठी तयार Flashbots आर्किटेक्चर](https://ethresear.ch/t/mev-boost-merge-ready-flashbots-architecture/11177) +- [MEV बूस्ट म्हणजे काय](https://www.alchemy.com/overviews/mev-boost) +- [mev-boost का चालवावा?](https://writings.flashbots.net/writings/why-run-mevboost/) +- [द हिचहायकर्स गाइड टू Ethereum](https://members.delphidigital.io/reports/the-hitchhikers-guide-to-ethereum) diff --git a/public/content/translations/mr/developers/docs/networking-layer/index.md b/public/content/translations/mr/developers/docs/networking-layer/index.md new file mode 100644 index 00000000000..3d84f50fc4e --- /dev/null +++ b/public/content/translations/mr/developers/docs/networking-layer/index.md @@ -0,0 +1,163 @@ +--- +title: "नेटवर्किंग स्तर" +description: "Ethereum च्या नेटवर्किंग लेयरचा परिचय." +lang: mr +sidebarDepth: 2 +--- + +Ethereum हे हजारो नोड्स असलेले एक पियर-टू-पियर नेटवर्क आहे, जे प्रमाणित प्रोटोकॉल वापरून एकमेकांशी संवाद साधण्यास सक्षम असले पाहिजेत. "नेटवर्किंग लेयर" हा प्रोटोकॉलचा एक स्टॅक आहे जो त्या नोड्सना एकमेकांना शोधू देतो आणि माहितीची देवाणघेवाण करू देतो. यामध्ये नेटवर्कवर "गॉसिपिंग" माहिती (एकाकडून अनेकांपर्यंत संवाद) तसेच विशिष्ट नोड्स दरम्यान विनंत्या आणि प्रतिसादांची अदलाबदल (एकाकडून एकापर्यंत संवाद) करणे समाविष्ट आहे. प्रत्येक नोडने विशिष्ट नेटवर्किंग नियमांचे पालन केले पाहिजे, जेणेकरून ते योग्य माहिती पाठवत आणि प्राप्त करत आहेत याची खात्री होईल. + +क्लायंट सॉफ्टवेअरचे दोन भाग आहेत (एक्झिक्युशन क्लायंट आणि कन्सेन्सस क्लायंट), प्रत्येकाचा स्वतःचा वेगळा नेटवर्किंग स्टॅक आहे. इतर Ethereum नोड्सशी संवाद साधण्याव्यतिरिक्त, एक्झिक्युशन आणि कन्सेन्सस क्लायंटना एकमेकांशी संवाद साधावा लागतो. हे पृष्ठ या संवादास सक्षम करणाऱ्या प्रोटोकॉलचे प्रास्ताविक स्पष्टीकरण देते. + +एक्झिक्युशन क्लायंट एक्झिक्युशन-लेयर पियर-टू-पियर नेटवर्कवर व्यवहारांची गॉसिपिंग करतात. यासाठी प्रमाणित पियर्समध्ये एनक्रिप्टेड संवादाची आवश्यकता असते. जेव्हा ब्लॉक प्रस्तावित करण्यासाठी व्हॅलिडेटर निवडला जातो, तेव्हा नोडच्या स्थानिक ट्रान्झॅक्शन पूलमधून व्यवहार स्थानिक RPC कनेक्शनद्वारे कन्सेन्सस क्लायंटकडे पाठवले जातात, जे बीकन ब्लॉक्समध्ये पॅकेज केले जातील. त्यानंतर कन्सेन्सस क्लायंट त्यांच्या p2p नेटवर्कवर बीकन ब्लॉक्सची गॉसिपिंग करतील. यासाठी दोन स्वतंत्र p2p नेटवर्क आवश्यक आहेत: एक ट्रान्झॅक्शन गॉसिपसाठी एक्झिक्युशन क्लायंट्सना जोडणारे आणि दुसरे ब्लॉक गॉसिपसाठी कन्सेन्सस क्लायंट्सना जोडणारे. + +## पूर्वतयारी {#prerequisites} + +हे पृष्ठ समजून घेण्यासाठी Ethereum [नोड्स आणि क्लायंट](/developers/docs/nodes-and-clients/) यांचे काही ज्ञान उपयुक्त ठरेल. + +## एक्झिक्युशन लेयर {#execution-layer} + +एक्झिक्युशन लेयरचे नेटवर्किंग प्रोटोकॉल दोन स्टॅक्समध्ये विभागलेले आहेत: + +- डिस्कव्हरी स्टॅक: UDP वर तयार केलेला आहे आणि नवीन नोडला कनेक्ट करण्यासाठी पियर्स शोधण्याची परवानगी देतो + +- DevP2P स्टॅक: TCP वर आधारित आहे आणि नोड्सना माहितीची देवाणघेवाण करण्यास सक्षम करतो + +दोन्ही स्टॅक समांतरपणे कार्य करतात. डिस्कव्हरी स्टॅक नेटवर्कमध्ये नवीन नेटवर्क सहभागींना आणतो, आणि DevP2P स्टॅक त्यांच्या परस्परसंवादांना सक्षम करतो. + +### डिस्कव्हरी {#discovery} + +डिस्कव्हरी म्हणजे नेटवर्कमधील इतर नोड्स शोधण्याची प्रक्रिया. हे बूटनोड्सच्या (नोड्स ज्यांचे पत्ते क्लायंटमध्ये [हार्डकोड केलेले](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go) असतात जेणेकरून ते त्वरित शोधता येतील आणि क्लायंटला पियर्सशी कनेक्ट करता येईल) एका छोट्या सेटचा वापर करून बूटस्ट्रॅप केले जाते. हे बूटनोड्स फक्त एका नवीन नोडला पियर्सच्या सेटशी ओळख करून देण्यासाठी अस्तित्वात आहेत - हाच त्यांचा एकमेव उद्देश आहे, ते चेन सिंक करण्यासारख्या सामान्य क्लायंट कार्यांमध्ये सहभागी होत नाहीत, आणि ते फक्त क्लायंट पहिल्यांदा सुरू झाल्यावरच वापरले जातात. + +नोड-बूटनोड परस्परसंवादासाठी वापरला जाणारा प्रोटोकॉल [काडेम्लिया](https://medium.com/coinmonks/a-brief-overview-of-kademlia-and-its-use-in-various-decentralized-platforms-da08a7f72b8f) चे सुधारित रूप आहे जे नोड्सच्या याद्या शेअर करण्यासाठी [डिस्ट्रिब्युटेड हॅश टेबल](https://en.wikipedia.org/wiki/Distributed_hash_table) वापरते. प्रत्येक नोडकडे या टेबलची एक आवृत्ती असते ज्यात त्याच्या सर्वात जवळच्या पियर्सशी कनेक्ट करण्यासाठी आवश्यक माहिती असते. ही 'जवळीक' भौगोलिक नाही - अंतर नोडच्या ID च्या समानतेनुसार परिभाषित केले जाते. प्रत्येक नोडची टेबल सुरक्षा वैशिष्ट्य म्हणून नियमितपणे रिफ्रेश केली जाते. उदाहरणार्थ, [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5) डिस्कव्हरी प्रोटोकॉलमध्ये नोड्स 'जाहिराती' देखील पाठवू शकतात, जे क्लायंटद्वारे समर्थित सब-प्रोटोकॉल दर्शवतात, ज्यामुळे पियर्स संवाद साधण्यासाठी वापरल्या जाऊ शकणाऱ्या प्रोटोकॉलबद्दल वाटाघाटी करू शकतात. + +डिस्कव्हरी पिंग-पॉन्गच्या खेळाने सुरू होते. एक यशस्वी पिंग-पॉन्ग नवीन नोडला बूटनोडशी "बॉण्ड" करतो. नेटवर्कमध्ये प्रवेश करणाऱ्या नवीन नोडच्या अस्तित्वाची बूटनोडला सूचना देणारा प्रारंभिक संदेश म्हणजे `PING`. या `PING` मध्ये नवीन नोड, बूटनोड आणि एक एक्स्पायरी टाइम-स्टॅम्पबद्दल हॅश केलेली माहिती असते. बूटनोड `PING` प्राप्त करतो आणि `PING` हॅश असलेला `PONG` परत करतो. जर `PING` आणि `PONG` हॅश जुळले तर नवीन नोड आणि बूटनोडमधील कनेक्शनची पडताळणी केली जाते आणि ते "बॉन्डेड" झाले आहेत असे म्हटले जाते. + +एकदा बॉण्ड झाल्यावर, नवीन नोड बूटनोडला `FIND-NEIGHBOURS` विनंती पाठवू शकतो. बूटनोडद्वारे परत केलेल्या डेटामध्ये पियर्सची एक यादी असते ज्यांना नवीन नोड कनेक्ट करू शकतो. जर नोड्स बॉन्डेड नसतील, तर `FIND-NEIGHBOURS` विनंती अयशस्वी होईल, त्यामुळे नवीन नोड नेटवर्कमध्ये प्रवेश करू शकणार नाही. + +एकदा नवीन नोडला बूटनोडकडून शेजाऱ्यांची यादी मिळाल्यावर, तो त्या प्रत्येकाशी पिंग-पॉन्ग एक्सचेंज सुरू करतो. यशस्वी पिंग-पॉन्ग नवीन नोडला त्याच्या शेजाऱ्यांशी बॉण्ड करतात, ज्यामुळे संदेशांची देवाणघेवाण शक्य होते. + +``` +क्लायंट सुरू करा --> बूटनोडला कनेक्ट करा --> बूटनोडशी बॉण्ड करा --> शेजारी शोधा --> शेजाऱ्यांशी बॉण्ड करा +``` + +एक्झिक्युशन क्लायंट सध्या [Discv4](https://github.com/ethereum/devp2p/blob/master/discv4.md) डिस्कव्हरी प्रोटोकॉल वापरत आहेत आणि [Discv5](https://github.com/ethereum/devp2p/tree/master/discv5) प्रोटोकॉलमध्ये स्थलांतरित होण्यासाठी सक्रिय प्रयत्न सुरू आहेत. + +#### ENR: Ethereum नोड रेकॉर्ड्स {#enr} + +[Ethereum नोड रेकॉर्ड (ENR)](/developers/docs/networking-layer/network-addresses/) एक ऑब्जेक्ट आहे ज्यामध्ये तीन मूलभूत घटक आहेत: एक स्वाक्षरी (काही मान्य ओळख योजनेनुसार बनवलेल्या रेकॉर्ड सामग्रीचा हॅश), रेकॉर्डमधील बदलांचा मागोवा घेणारा एक क्रम क्रमांक, आणि की:व्हॅल्यू जोड्यांची एक अनियंत्रित यादी. हे एक भविष्यासाठी सुरक्षित स्वरूप आहे जे नवीन पियर्समध्ये ओळखणारी माहितीची सुलभ देवाणघेवाण करण्यास अनुमती देते आणि Ethereum नोड्ससाठी प्राधान्य दिलेले [नेटवर्क अॅड्रेस](/developers/docs/networking-layer/network-addresses) स्वरूप आहे. + +#### डिस्कव्हरी UDP वर का तयार केली आहे? {#why-udp} + +UDP कोणतीही त्रुटी तपासणी, अयशस्वी पॅकेट पुन्हा पाठवणे, किंवा कनेक्शन डायनॅमिकपणे उघडणे आणि बंद करणे याला समर्थन देत नाही - त्याऐवजी ते लक्ष्यावर माहितीचा सतत प्रवाह पाठवते, मग ती यशस्वीरित्या प्राप्त झाली आहे की नाही याची पर्वा न करता. ही किमान कार्यक्षमता किमान ओव्हरहेडमध्ये रूपांतरित होते, ज्यामुळे अशा प्रकारचे कनेक्शन खूप वेगवान होते. डिस्कव्हरीसाठी, जिथे नोडला फक्त त्याचे अस्तित्व ज्ञात करायचे असते जेणेकरून नंतर पियरशी औपचारिक कनेक्शन स्थापित करता येईल, तिथे UDP पुरेसे आहे. तथापि, उर्वरित नेटवर्किंग स्टॅकसाठी, UDP उद्देशासाठी योग्य नाही. नोड्समधील माहितीची देवाणघेवाण खूपच गुंतागुंतीची आहे आणि म्हणून पुन्हा पाठवणे, त्रुटी तपासणी इत्यादींना समर्थन देऊ शकणाऱ्या अधिक पूर्ण वैशिष्ट्यीकृत प्रोटोकॉलची आवश्यकता आहे. TCP शी संबंधित अतिरिक्त ओव्हरहेड अतिरिक्त कार्यक्षमतेसाठी योग्य आहे. म्हणून, P2P स्टॅकचा बहुतांश भाग TCP वर कार्य करतो. + +### DevP2P {#devp2p} + +DevP2P स्वतःच प्रोटोकॉलचा एक संपूर्ण स्टॅक आहे जो Ethereum पियर-टू-पियर नेटवर्क स्थापित करण्यासाठी आणि राखण्यासाठी लागू करतो. नवीन नोड्स नेटवर्कमध्ये प्रवेश केल्यानंतर, त्यांचे परस्परसंवाद [DevP2P](https://github.com/ethereum/devp2p) स्टॅकमधील प्रोटोकॉलद्वारे नियंत्रित केले जातात. हे सर्व TCP वर आधारित आहेत आणि त्यात RLPx ट्रान्सपोर्ट प्रोटोकॉल, वायर प्रोटोकॉल आणि अनेक सब-प्रोटोकॉल समाविष्ट आहेत. [RLPx](https://github.com/ethereum/devp2p/blob/master/rlpx.md) हा नोड्समधील सत्रे सुरू करणे, प्रमाणित करणे आणि राखणे नियंत्रित करणारा प्रोटोकॉल आहे. RLPx संदेश एन्कोड करण्यासाठी RLP (रिकर्सिव्ह लेंथ प्रीफिक्स) वापरतो जी नोड्समध्ये पाठवण्यासाठी डेटाला किमान संरचनेत एन्कोड करण्याची एक अत्यंत जागा-कार्यक्षम पद्धत आहे. + +दोन नोड्समधील RLPx सत्र प्रारंभिक क्रिप्टोग्राफिक हँडशेकने सुरू होते. यामध्ये नोड एक ऑथ मेसेज पाठवतो जो नंतर पियरद्वारे सत्यापित केला जातो. यशस्वी पडताळणीवर, पियर प्रारंभकर्ता नोडला परत करण्यासाठी एक ऑथ-अॅकनॉलेजमेंट संदेश तयार करतो. ही एक की-एक्सचेंज प्रक्रिया आहे जी नोड्सना खाजगी आणि सुरक्षितपणे संवाद साधण्यास सक्षम करते. एक यशस्वी क्रिप्टोग्राफिक हँडशेक नंतर दोन्ही नोड्सना एकमेकांना "ऑन द वायर" एक "हॅलो" संदेश पाठवण्यासाठी ट्रिगर करतो. वायर प्रोटोकॉल हॅलो संदेशांच्या यशस्वी देवाणघेवाणीने सुरू होतो. + +हॅलो संदेशांमध्ये खालील गोष्टी असतात: + +- प्रोटोकॉल आवृत्ती +- क्लायंट आयडी +- पोर्ट +- नोड आयडी +- समर्थित सब-प्रोटोकॉलची यादी + +यशस्वी परस्परसंवादासाठी ही आवश्यक माहिती आहे कारण ती दोन्ही नोड्समध्ये कोणती क्षमता सामायिक केली आहे हे परिभाषित करते आणि संवाद कॉन्फिगर करते. सब-प्रोटोकॉल वाटाघाटीची एक प्रक्रिया आहे जिथे प्रत्येक नोडद्वारे समर्थित सब-प्रोटोकॉलच्या याद्यांची तुलना केली जाते आणि जे दोन्ही नोड्ससाठी सामान्य आहेत ते सत्रात वापरले जाऊ शकतात. + +हॅलो संदेशांसह, वायर प्रोटोकॉल एक "डिस्कनेक्ट" संदेश देखील पाठवू शकतो जो पियरला कनेक्शन बंद केले जाईल अशी चेतावणी देतो. वायर प्रोटोकॉलमध्ये पिंग आणि पॉंग संदेश देखील समाविष्ट आहेत जे सत्र चालू ठेवण्यासाठी वेळोवेळी पाठवले जातात. RLPx आणि वायर प्रोटोकॉल एक्सचेंज त्यामुळे नोड्समधील संवादाचा पाया स्थापित करतात, विशिष्ट सब-प्रोटोकॉलनुसार उपयुक्त माहितीची देवाणघेवाण करण्यासाठी स्कॅफोल्डिंग प्रदान करतात. + +### सब-प्रोटोकॉल्स {#sub-protocols} + +#### वायर प्रोटोकॉल {#wire-protocol} + +एकदा पियर्स कनेक्ट झाल्यावर, आणि RLPx सत्र सुरू झाल्यावर, वायर प्रोटोकॉल पियर्स कसे संवाद साधतील हे परिभाषित करतो. सुरुवातीला, वायर प्रोटोकॉलने तीन मुख्य कार्ये परिभाषित केली: चेन सिंक्रोनाइझेशन, ब्लॉक प्रोपगेशन आणि ट्रान्झॅक्शन एक्सचेंज. तथापि, एकदा Ethereum प्रूफ-ऑफ-स्टेकवर स्विच झाल्यावर, ब्लॉक प्रोपगेशन आणि चेन सिंक्रोनाइझेशन कन्सेन्सस लेयरचा भाग बनले. ट्रान्झॅक्शन एक्सचेंज अजूनही एक्झिक्युशन क्लायंटच्या अखत्यारित आहे. ट्रान्झॅक्शन एक्सचेंज म्हणजे नोड्समध्ये प्रलंबित व्यवहारांची देवाणघेवाण करणे जेणेकरून ब्लॉक बिल्डर्स त्यापैकी काही पुढील ब्लॉकमध्ये समाविष्ट करण्यासाठी निवडू शकतील. या कार्यांविषयी तपशीलवार माहिती [येथे](https://github.com/ethereum/devp2p/blob/master/caps/eth.md) उपलब्ध आहे. या सब-प्रोटोकॉलला समर्थन देणारे क्लायंट त्यांना [JSON-RPC](/developers/docs/apis/json-rpc/) द्वारे उघड करतात. + +#### les (लाइट Ethereum सबप्रोटोकॉल) {#les} + +हा लाईट क्लायंट सिंक करण्यासाठी एक किमान प्रोटोकॉल आहे. पारंपारिकपणे हा प्रोटोकॉल क्वचितच वापरला जातो कारण पूर्ण नोड्सना लाईट क्लायंटना डेटा देण्यासाठी प्रोत्साहन न देता आवश्यक असते. एक्झिक्युशन क्लायंटचे डीफॉल्ट वर्तन हे les वर लाईट क्लायंट डेटा सर्व्ह करणे नाही. अधिक माहिती les [spec](https://github.com/ethereum/devp2p/blob/master/caps/les.md) मध्ये उपलब्ध आहे. + +#### स्नॅप {#snap} + +[स्नॅप प्रोटोकॉल](https://github.com/ethereum/devp2p/blob/master/caps/snap.md#ethereum-snapshot-protocol-snap) एक वैकल्पिक विस्तार आहे जो पियर्सना अलीकडील स्टेट्सचे स्नॅपशॉट एक्सचेंज करण्याची परवानगी देतो, ज्यामुळे पियर्सना इंटरमीडिएट मर्केल ट्राय नोड्स डाउनलोड न करता अकाउंट आणि स्टोरेज डेटाची पडताळणी करता येते. + +#### विट (विटनेस प्रोटोकॉल) {#wit} + +[विटनेस प्रोटोकॉल](https://github.com/ethereum/devp2p/blob/master/caps/wit.md#ethereum-witness-protocol-wit) एक वैकल्पिक विस्तार आहे जो पियर्समध्ये स्टेट विटनेसची देवाणघेवाण सक्षम करतो, ज्यामुळे क्लायंटला चेनच्या टोकापर्यंत सिंक करण्यास मदत होते. + +#### व्हिस्पर {#whisper} + +व्हिस्पर हा एक प्रोटोकॉल होता ज्याचा उद्देश ब्लॉकचेनवर कोणतीही माहिती न लिहिता पियर्समध्ये सुरक्षित मेसेजिंग वितरित करणे हा होता. हा DevP2P वायर प्रोटोकॉलचा भाग होता परंतु आता तो नापसंत आहे. समान उद्देशांसह इतर [संबंधित प्रकल्प](https://wakunetwork.com/) अस्तित्वात आहेत. + +## कन्सेन्सस लेयर {#consensus-layer} + +कन्सेन्सस क्लायंट एका वेगळ्या स्पेसिफिकेशनसह वेगळ्या पियर-टू-पियर नेटवर्कमध्ये सहभागी होतात. कन्सेन्सस क्लायंटला ब्लॉक गॉसिपमध्ये सहभागी होणे आवश्यक आहे जेणेकरून ते पियर्सकडून नवीन ब्लॉक प्राप्त करू शकतील आणि जेव्हा ब्लॉक प्रस्तावक होण्याची त्यांची पाळी असेल तेव्हा ते प्रसारित करू शकतील. एक्झिक्युशन लेयर प्रमाणेच, यासाठी प्रथम एक डिस्कव्हरी प्रोटोकॉल आवश्यक आहे जेणेकरून नोड पियर्स शोधू शकेल आणि ब्लॉक, अटेस्टेशन्स इत्यादींच्या देवाणघेवाणीसाठी सुरक्षित सत्रे स्थापित करू शकेल. + +### डिस्कव्हरी {#consensus-discovery} + +एक्झिक्युशन क्लायंट्सप्रमाणेच, कन्सेन्सस क्लायंट्स पियर्स शोधण्यासाठी UDP वर [discv5](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-discovery-domain-discv5) वापरतात. discv5 ची कन्सेन्सस लेयर अंमलबजावणी एक्झिक्युशन क्लायंट्सपेक्षा फक्त एवढ्याच बाबतीत वेगळी आहे की त्यात discv5 ला [libP2P](https://libp2p.io/) स्टॅकमध्ये जोडणारा अडॅप्टर समाविष्ट आहे, ज्यामुळे DevP2P नापसंत होते. एक्झिक्युशन लेयरचे RLPx सत्र libP2P च्या नॉइज सिक्युर चॅनल हँडशेकच्या बाजूने नापसंत केले आहेत. + +### ENRs {#consensus-enr} + +कन्सेन्सस नोड्ससाठी ENR मध्ये नोडची सार्वजनिक की, IP पत्ता, UDP आणि TCP पोर्ट आणि दोन कन्सेन्सस-विशिष्ट फील्ड्स समाविष्ट आहेत: अटेस्टेशन सबनेट बिटफील्ड आणि `eth2` की. पहिल्यामुळे नोड्सना विशिष्ट अटेस्टेशन गॉसिप सब-नेटवर्कमध्ये सहभागी होणारे पियर्स शोधणे सोपे होते. `eth2` की मध्ये नोड कोणत्या Ethereum फोर्क आवृत्तीचा वापर करत आहे याबद्दल माहिती असते, ज्यामुळे पियर्स योग्य Ethereum शी कनेक्ट होत आहेत याची खात्री होते. + +### libP2P {#libp2p} + +libP2P स्टॅक डिस्कव्हरीनंतरच्या सर्व संवादांना समर्थन देतो. क्लायंट त्यांच्या ENR मध्ये परिभाषित केल्यानुसार IPv4 आणि/किंवा IPv6 वर डायल आणि ऐकू शकतात. libP2P लेयरवरील प्रोटोकॉल गॉसिप आणि req/resp डोमेनमध्ये विभागले जाऊ शकतात. + +### गॉसिप {#gossip} + +गॉसिप डोमेनमध्ये अशी सर्व माहिती समाविष्ट आहे जी संपूर्ण नेटवर्कमध्ये वेगाने पसरणे आवश्यक आहे. यामध्ये बीकन ब्लॉक, प्रूफ, अटेस्टेशन्स, एक्झिट्स आणि स्लॅशिंग्स यांचा समावेश आहे. हे libP2P gossipsub v1 वापरून प्रसारित केले जाते आणि प्रत्येक नोडवर स्थानिकरित्या संग्रहित केलेल्या विविध मेटाडेटावर अवलंबून असते, ज्यात गॉसिप पेलोड प्राप्त करण्यासाठी आणि प्रसारित करण्यासाठी कमाल आकाराचा समावेश आहे. गॉसिप डोमेनबद्दल तपशीलवार माहिती [येथे](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-gossip-domain-gossipsub) उपलब्ध आहे. + +### विनंती-प्रतिसाद {#request-response} + +विनंती-प्रतिसाद डोमेनमध्ये त्यांच्या पियर्सकडून विशिष्ट माहितीची विनंती करणाऱ्या क्लायंटसाठी प्रोटोकॉल आहेत. उदाहरणांमध्ये विशिष्ट रूट हॅशशी जुळणारे किंवा स्लॉटच्या मर्यादेतील विशिष्ट बीकन ब्लॉकची विनंती करणे समाविष्ट आहे. प्रतिसाद नेहमी स्नॅपी-कॉम्प्रेस्ड SSZ एन्कोडेड बाइट्स म्हणून परत केले जातात. + +## कन्सेन्सस क्लायंट RLP पेक्षा SSZ ला प्राधान्य का देतो? {#ssz-vs-rlp} + +SSZ म्हणजे सिंपल सीरियलायझेशन. हे निश्चित ऑफसेट वापरते ज्यामुळे संपूर्ण संरचना डीकोड न करता एन्कोड केलेल्या संदेशाचे वैयक्तिक भाग डीकोड करणे सोपे होते, जे कन्सेन्सस क्लायंटसाठी खूप उपयुक्त आहे कारण ते एन्कोड केलेल्या संदेशांमधून माहितीचे विशिष्ट तुकडे कार्यक्षमतेने मिळवू शकते. हे विशेषतः मर्केल प्रोटोकॉलसह समाकलित करण्यासाठी डिझाइन केलेले आहे, मर्केलायझेशनसाठी संबंधित कार्यक्षमता वाढीसह. कन्सेन्सस लेयरमधील सर्व हॅश मर्केल रूट्स असल्याने, यामुळे लक्षणीय सुधारणा होते. SSZ मूल्यांचे अद्वितीय प्रतिनिधित्व देखील सुनिश्चित करते. + +## एक्झिक्युशन आणि कन्सेन्सस क्लायंट कनेक्ट करणे {#connecting-clients} + +कन्सेन्सस आणि एक्झिक्युशन दोन्ही क्लायंट समांतर चालतात. त्यांना कनेक्ट करणे आवश्यक आहे जेणेकरून कन्सेन्सस क्लायंट एक्झिक्युशन क्लायंटला सूचना देऊ शकेल, आणि एक्झिक्युशन क्लायंट बीकन ब्लॉक्समध्ये समाविष्ट करण्यासाठी कन्सेन्सस क्लायंटला व्यवहारांचे बंडल पाठवू शकेल. दोन क्लायंटमधील संवाद स्थानिक RPC कनेक्शन वापरून साधला जाऊ शकतो. ['इंजिन-एपीआय'](https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md) म्हणून ओळखले जाणारे API दोन क्लायंटमध्ये पाठवलेल्या सूचना परिभाषित करते. दोन्ही क्लायंट एकाच नेटवर्क ओळखीच्या मागे बसल्यामुळे, ते एक ENR (Ethereum नोड रेकॉर्ड) शेअर करतात ज्यात प्रत्येक क्लायंटसाठी एक स्वतंत्र की असते (eth1 की आणि eth2 की). + +कंट्रोल फ्लोचा सारांश खाली दर्शविला आहे, संबंधित नेटवर्किंग स्टॅक कंसात आहे. + +### जेव्हा कन्सेन्सस क्लायंट ब्लॉक निर्माता नसतो: {#when-consensus-client-is-not-block-producer} + +- कन्सेन्सस क्लायंटला ब्लॉक गॉसिप प्रोटोकॉलद्वारे एक ब्लॉक मिळतो (कन्सेन्सस p2p) +- कन्सेन्सस क्लायंट ब्लॉकची पूर्व-पडताळणी करतो, म्हणजे, तो योग्य पाठवणाऱ्याकडून योग्य मेटाडेटसह आला आहे याची खात्री करतो +- ब्लॉकमधील व्यवहार एक्झिक्युशन पेलोड म्हणून एक्झिक्युशन लेयरकडे पाठवले जातात (स्थानिक RPC कनेक्शन) +- एक्झिक्युशन लेयर व्यवहार कार्यान्वित करतो आणि ब्लॉक हेडरमधील स्टेटची पडताळणी करतो (म्हणजे, हॅश जुळतात की नाही हे तपासतो) +- एक्झिक्युशन लेयर व्हॅलिडेशन डेटा परत कन्सेन्सस लेयरकडे पाठवतो, आता ब्लॉक व्हॅलिडेटेड मानला जातो (स्थानिक RPC कनेक्शन) +- कन्सेन्सस लेयर ब्लॉकला स्वतःच्या ब्लॉकचेनच्या हेडमध्ये जोडतो आणि त्याची अटेस्टेशन करतो, नेटवर्कवर अटेस्टेशन प्रसारित करतो (कन्सेन्सस p2p) + +### जेव्हा कन्सेन्सस क्लायंट ब्लॉक निर्माता असतो: {#when-consensus-client-is-block-producer} + +- कन्सेन्सस क्लायंटला सूचना मिळते की तो पुढील ब्लॉक निर्माता आहे (कन्सेन्सस p2p) +- कन्सेन्सस लेयर एक्झिक्युशन क्लायंटमध्ये `create block` पद्धत कॉल करतो (स्थानिक RPC) +- एक्झिक्युशन लेयर ट्रान्झॅक्शन मेमपूलमध्ये प्रवेश करतो जो ट्रान्झॅक्शन गॉसिप प्रोटोकॉलद्वारे पॉप्युलेट केला गेला आहे (एक्झिक्युशन p2p) +- एक्झिक्युशन क्लायंट व्यवहारांना एका ब्लॉकमध्ये बंडल करतो, व्यवहार कार्यान्वित करतो आणि एक ब्लॉक हॅश तयार करतो +- कन्सेन्सस क्लायंट एक्झिक्युशन क्लायंटकडून व्यवहार आणि ब्लॉक हॅश घेतो आणि त्यांना बीकन ब्लॉकमध्ये जोडतो (स्थानिक RPC) +- कन्सेन्सस क्लायंट ब्लॉक गॉसिप प्रोटोकॉलवर ब्लॉक प्रसारित करतो (कन्सेन्सस p2p) +- इतर क्लायंट प्रस्तावित ब्लॉक ब्लॉक गॉसिप प्रोटोकॉलद्वारे प्राप्त करतात आणि वर वर्णन केल्याप्रमाणे व्हॅलिडेट करतात (कन्सेन्सस p2p) + +एकदा पुरेसे व्हॅलिडेटर्सद्वारे ब्लॉक अटेस्टेड झाल्यावर, तो चेनच्या हेडमध्ये जोडला जातो, जस्टिफाय केला जातो आणि शेवटी फायनलाइज केला जातो. + +![](cons_client_net_layer.png) +![](exe_client_net_layer.png) + +कन्सेन्सस आणि एक्झिक्युशन क्लायंटसाठी नेटवर्क लेयर स्किमॅटिक, [ethresear.ch](https://ethresear.ch/t/eth1-eth2-client-relationship/7248) वरून + +## अधिक वाचन {#further-reading} + +[DevP2P](https://github.com/ethereum/devp2p) +[LibP2p](https://github.com/libp2p/specs) +[कन्सेन्सस लेयर नेटवर्क स्पेक्स](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure) +[kademlia to discv5](https://vac.dev/kademlia-to-discv5) +[kademlia पेपर](https://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf) +[Ethereum p2p चा परिचय](https://p2p.paris/en/talks/intro-ethereum-networking/) +[eth1/eth2 संबंध](http://ethresear.ch/t/eth1-eth2-client-relationship/7248) +[मर्ज आणि eth2 क्लायंट तपशील व्हिडिओ](https://www.youtube.com/watch?v=zNIrIninMgg) diff --git a/public/content/translations/mr/developers/docs/networking-layer/network-addresses/index.md b/public/content/translations/mr/developers/docs/networking-layer/network-addresses/index.md new file mode 100644 index 00000000000..e1d0c72083c --- /dev/null +++ b/public/content/translations/mr/developers/docs/networking-layer/network-addresses/index.md @@ -0,0 +1,39 @@ +--- +title: "नेटवर्क अ‍ॅड्रेसेस" +description: "नेटवर्क अ‍ॅड्रेसेसची ओळख." +lang: mr +sidebarDepth: 2 +--- + +पिअर्सशी कनेक्ट होण्यासाठी इथेरियम नोड्सना काही मूलभूत माहितीसह स्वतःची ओळख पटवून द्यावी लागते. कोणताही संभाव्य पिअर या माहितीचा अर्थ लावू शकेल याची खात्री करण्यासाठी, ती तीन प्रमाणित फॉरमॅटपैकी एकात रिले केली जाते जे कोणताही इथेरियम नोड समजू शकतो: मल्टीऍडर, इनोड किंवा इथेरियम नोड रेकॉर्ड्स (ENRs). ENRs हे इथेरियम नेटवर्क अ‍ॅड्रेसेससाठी सध्याचे मानक आहेत. + +## पूर्वतयारी {#prerequisites} + +हे पृष्ठ समजण्यासाठी इथेरियमच्या [नेटवर्किंग लेयर](/developers/docs/networking-layer/) ची काही समज असणे आवश्यक आहे. + +## मल्टीऍडर {#multiaddr} + +मूळ इथेरियम नोड अ‍ॅड्रेस फॉरमॅट 'मल्टीऍडर' ('मल्टी-अ‍ॅड्रेसेस'चे संक्षिप्त रूप) होता. मल्टीऍडर हे पिअर-टू-पिअर नेटवर्कसाठी डिझाइन केलेले एक सार्वत्रिक फॉरमॅट आहे. अ‍ॅड्रेसेस की-व्हॅल्यू जोड्या म्हणून दर्शविले जातात, ज्यात की आणि व्हॅल्यूज फॉरवर्ड स्लॅशने विभक्त केलेल्या असतात. उदाहरणार्थ, IPv4 अ‍ॅड्रेस `192.168.22.27` असलेल्या आणि TCP पोर्ट `33000` ऐकणाऱ्या नोडसाठी मल्टीऍडर खालीलप्रमाणे दिसतो: + +`/ip4/192.168.22.27/tcp/33000` + +इथेरियम नोडसाठी, मल्टीऍडरमध्ये नोड-आयडी (त्यांच्या पब्लिक कीचा हॅश) असतो: + +`/ip4/192.168.22.27/tcp/33000/p2p/5t7Nv7dG2d6ffbvAiewVsEwWweU3LdebSqX2y1bPrW8br` + +## इनोड {#enode} + +इनोड हा URL अ‍ॅड्रेस फॉरमॅट वापरून इथेरियम नोड ओळखण्याचा एक मार्ग आहे. हेक्साडेसिमल नोड-आयडी URL च्या युजरनेम भागात एन्कोड केलेला असतो आणि तो @ चिन्हाचा वापर करून होस्टपासून वेगळा केला जातो. होस्टनेम फक्त आयपी अ‍ॅड्रेस म्हणून दिले जाऊ शकते; DNS नावांना परवानगी नाही. होस्टनेम विभागातील पोर्ट हा TCP लिसनिंग पोर्ट असतो. जर TCP आणि UDP (डिस्कव्हरी) पोर्ट्स वेगळे असतील, तर UDP पोर्ट \"discport\" हा क्वेरी पॅरामीटर म्हणून नमूद केला जातो. + +खालील उदाहरणात, नोड URL अशा नोडचे वर्णन करते ज्याचा आयपी अ‍ॅड्रेस `10.3.58.6`, TCP पोर्ट `30303` आणि UDP डिस्कव्हरी पोर्ट `30301` आहे. + +`enode://6f8a80d14311c39f35f516fa664deaaaa13e85b2f7493f37f6144d86991ec012937307647bd3b9a82abe2974e1407241d54947bbb39763a4cac9f77166ad92a0@10.3.58.6:30303?discport=30301` + +## इथेरियम नोड रेकॉर्ड्स (ENRs) {#enr} + +इथेरियम नोड रेकॉर्ड्स (ENRs) हे इथेरियमवरील नेटवर्क अ‍ॅड्रेसेससाठी एक प्रमाणित फॉरमॅट आहे. ते मल्टीऍडर आणि इनोड्सची जागा घेतात. हे विशेषतः उपयुक्त आहेत कारण ते नोड्स दरम्यान अधिक माहितीची देवाणघेवाण करण्यास परवानगी देतात. ENR मध्ये स्वाक्षरी, क्रम क्रमांक आणि स्वाक्षऱ्या निर्माण करण्यासाठी व प्रमाणित करण्यासाठी वापरल्या जाणाऱ्या आयडेंटिटी स्कीमचा तपशील देणारी फील्ड्स असतात. ENR मध्ये की-व्हॅल्यू जोड्या म्हणून आयोजित केलेला कोणताही डेटा देखील भरला जाऊ शकतो. या की-व्हॅल्यू जोड्यांमध्ये नोडचा आयपी अ‍ॅड्रेस आणि नोड वापरू शकणाऱ्या सब-प्रोटोकॉल्सबद्दलची माहिती असते. कन्सेन्सस क्लायंट्स बूट नोड्स ओळखण्यासाठी एक [विशिष्ट ENR रचना](https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#enr-structure) वापरतात आणि त्यात `eth2` फील्ड देखील समाविष्ट असते, ज्यात सध्याच्या इथेरियम फोर्क आणि अटेस्टेशन गॉसिप सबनेटबद्दल माहिती असते (हे नोडला पिअर्सच्या एका विशिष्ट संचाशी जोडते ज्यांचे अटेस्टेशन एकत्रित केले जातात). + +## अधिक वाचन {#further-reading} + +- [EIP-778: इथेरियम नोड रेकॉर्ड्स (ENR)](https://eips.ethereum.org/EIPS/eip-778) +- [LibP2P: Multiaddr-Enode-ENR?!](https://consensys.net/diligence/blog/2020/09/libp2p-multiaddr-enode-enr/) diff --git a/public/content/translations/mr/developers/docs/networking-layer/portal-network/index.md b/public/content/translations/mr/developers/docs/networking-layer/portal-network/index.md new file mode 100644 index 00000000000..2bf8a1a50b1 --- /dev/null +++ b/public/content/translations/mr/developers/docs/networking-layer/portal-network/index.md @@ -0,0 +1,89 @@ +--- +title: "पोर्टल नेटवर्क" +description: "पोर्टल नेटवर्कचे विहंगावलोकन - कमी-संसाधन क्लायंटना समर्थन देण्यासाठी डिझाइन केलेले एक इन-डेव्हलपमेंट नेटवर्क." +lang: mr +--- + +Ethereum हे Ethereum क्लायंट सॉफ्टवेअर चालवणार्‍या कॉम्प्युटरने बनलेले एक नेटवर्क आहे. यापैकी प्रत्येक कॉम्प्युटरला 'नोड' म्हटले जाते. क्लायंट सॉफ्टवेअर नोडला Ethereum नेटवर्कवर डेटा पाठवण्याची आणि प्राप्त करण्याची परवानगी देते आणि Ethereum प्रोटोकॉल नियमांनुसार डेटाची पडताळणी करते. नोड्स त्यांच्या डिस्क स्टोरेजमध्ये भरपूर ऐतिहासिक डेटा ठेवतात आणि जेव्हा त्यांना नेटवर्कवरील इतर नोड्सकडून माहितीचे नवीन पॅकेट, ज्यांना ब्लॉक्स म्हणून ओळखले जाते, प्राप्त होतात तेव्हा त्यात भर घालतात. नोडकडे उर्वरित नेटवर्कशी सुसंगत माहिती आहे हे नेहमी तपासण्यासाठी हे आवश्यक आहे. याचा अर्थ नोड चालवण्यासाठी भरपूर डिस्क स्पेसची आवश्यकता असू शकते. काही नोड ऑपरेशन्ससाठी भरपूर RAM ची देखील आवश्यकता असू शकते. + +या डिस्क स्टोरेज समस्येवर मात करण्यासाठी, 'लाइट' नोड्स विकसित केले गेले आहेत जे सर्व माहिती स्वतः संग्रहित करण्याऐवजी पूर्ण नोड्सकडून माहितीची विनंती करतात. तथापि, याचा अर्थ असा आहे की लाइट नोड स्वतंत्रपणे माहितीची पडताळणी करत नाही आणि त्याऐवजी दुसर्‍या नोडवर विश्वास ठेवत आहे. याचा अर्थ असाही होतो की त्या लाइट नोड्सना सेवा देण्यासाठी पूर्ण नोड्सना अतिरिक्त काम करावे लागते. + +पोर्टल नेटवर्क हे Ethereum साठी एक नवीन नेटवर्किंग डिझाइन आहे ज्याचा उद्देश "लाइट" नोड्ससाठी डेटा उपलब्धतेची समस्या पूर्ण नोड्सवर विश्वास न ठेवता किंवा अतिरिक्त ताण न टाकता सोडवणे आहे, नेटवर्कवर आवश्यक डेटा लहान भागांमध्ये शेअर करून. + +[नोड्स आणि क्लायंट्स](/developers/docs/nodes-and-clients/) वर अधिक माहिती + +## आम्हाला पोर्टल नेटवर्कची गरज का आहे {#why-do-we-need-portal-network} + +Ethereum नोड्स Ethereum ब्लॉकचेनची स्वतःची पूर्ण किंवा आंशिक प्रत संग्रहित करतात. ही स्थानिक प्रत व्यवहारांची वैधता तपासण्यासाठी आणि नोड योग्य साखळीचे अनुसरण करत असल्याची खात्री करण्यासाठी वापरली जाते. हा स्थानिकरित्या संग्रहित केलेला डेटा नोड्सना कोणत्याही इतर घटकावर विश्वास न ठेवता येणाऱ्या डेटाची वैधता आणि अचूकता स्वतंत्रपणे सत्यापित करण्यास अनुमती देतो. + +ब्लॉकचेनची ही स्थानिक प्रत आणि संबंधित स्टेट आणि पावती डेटा नोडच्या हार्ड डिस्कवर बरीच जागा घेतो. उदाहरणार्थ, एक कन्सेंसस क्लायंटला जोडलेल्या [Geth](https://geth.ethereum.org) चा वापर करून नोड चालवण्यासाठी 2TB हार्ड डिस्कची शिफारस केली जाते. स्नॅप सिंक वापरून, जे केवळ तुलनेने अलीकडील ब्लॉक्सच्या संचातून चेन डेटा संग्रहित करते, Geth साधारणपणे सुमारे 650GB डिस्क स्पेस व्यापते परंतु आठवड्यातून सुमारे 14GB ने वाढते (तुम्ही वेळोवेळी नोडची छाटणी करून 650GB पर्यंत कमी करू शकता). + +याचा अर्थ नोड्स चालवणे महाग असू शकते, कारण मोठ्या प्रमाणात डिस्क स्पेस Ethereum ला समर्पित करावी लागते. Ethereum रोडमॅपवर या समस्येवर अनेक उपाय आहेत, ज्यात [हिस्टरी एक्सपायरी](/roadmap/statelessness/#history-expiry), [स्टेट एक्सपायरी](/roadmap/statelessness/#state-expiry) आणि [स्टेटलेसनेस](/roadmap/statelessness/) यांचा समावेश आहे. तथापि, हे लागू होण्यास अनेक वर्षे लागण्याची शक्यता आहे. असे [लाइट नोड्स](/developers/docs/nodes-and-clients/light-clients/) देखील आहेत जे चेन डेटाची स्वतःची प्रत जतन करत नाहीत, ते त्यांना आवश्यक असलेला डेटा पूर्ण नोड्सकडून मागवतात. तथापि, याचा अर्थ असा आहे की लाइट नोड्सना प्रामाणिक डेटा प्रदान करण्यासाठी पूर्ण नोड्सवर विश्वास ठेवावा लागतो आणि लाइट नोड्सना आवश्यक असलेला डेटा सर्व्ह करणार्‍या पूर्ण नोड्सवर देखील ताण येतो. + +पोर्टल नेटवर्कचा उद्देश लाइट नोड्सना त्यांचा डेटा मिळविण्यासाठी एक पर्यायी मार्ग प्रदान करणे आहे ज्यासाठी पूर्ण नोड्सद्वारे कराव्या लागणाऱ्या कामावर विश्वास ठेवण्याची किंवा त्यात लक्षणीय वाढ करण्याची आवश्यकता नाही. हे करण्याचा मार्ग म्हणजे Ethereum नोड्सना नेटवर्कवर डेटा शेअर करण्यासाठी एक नवीन मार्ग सादर करणे. + +## पोर्टल नेटवर्क कसे कार्य करते? {#how-does-portal-network-work} + +Ethereum नोड्समध्ये कठोर प्रोटोकॉल असतात जे ते एकमेकांशी कसे संवाद साधतात हे परिभाषित करतात. एक्झिक्युशन क्लायंट [DevP2P](/developers/docs/networking-layer/#devp2p) म्हणून ओळखल्या जाणार्‍या सबप्रोटोकॉलच्या सेटचा वापर करून संवाद साधतात, तर कन्सेंसस क्लायंट [libP2P](/developers/docs/networking-layer/#libp2p) नावाच्या सबप्रोटोकॉलच्या वेगळ्या स्टॅकचा वापर करतात. हे नोड्स दरम्यान पास केल्या जाऊ शकणार्‍या डेटाचे प्रकार परिभाषित करतात. + +![devP2P and libP2P](portal-network-devp2p-libp2p.png) + +नोड्स [JSON-RPC API](/developers/docs/apis/json-rpc/) द्वारे विशिष्ट डेटा देखील देऊ शकतात, ज्याद्वारे ॲप्स आणि वॉलेट्स Ethereum नोड्ससह माहितीची देवाणघेवाण करतात. तथापि, यापैकी कोणताही लाइट क्लायंटना डेटा देण्यासाठी आदर्श प्रोटोकॉल नाही. + +लाइट क्लायंट सध्या DevP2P किंवा libP2p वर चेन डेटाचे विशिष्ट भाग मागू शकत नाहीत कारण ते प्रोटोकॉल केवळ चेन सिंक्रोनाइझेशन आणि ब्लॉक्स आणि व्यवहारांच्या गॉसिपिंगसाठी डिझाइन केलेले आहेत. लाइट क्लायंट ही माहिती डाउनलोड करू इच्छित नाहीत कारण त्यामुळे ते "लाइट" राहणार नाहीत. + +JSON-RPC API देखील लाइट क्लायंट डेटा विनंत्यांसाठी एक आदर्श पर्याय नाही, कारण ते एका विशिष्ट पूर्ण नोड किंवा केंद्रीकृत RPC प्रदात्याच्या कनेक्शनवर अवलंबून असते जे डेटा देऊ शकतात. याचा अर्थ असा आहे की लाइट क्लायंटला तो विशिष्ट नोड/प्रदाता प्रामाणिक असेल यावर विश्वास ठेवावा लागतो आणि पूर्ण नोडला अनेक लाइट क्लायंटकडून अनेक विनंत्या हाताळाव्या लागू शकतात, ज्यामुळे त्यांच्या बँडविड्थ आवश्यकतांमध्ये वाढ होते. + +पोर्टल नेटवर्कचा मुद्दा म्हणजे संपूर्ण डिझाइनवर पुनर्विचार करणे, विद्यमान Ethereum क्लायंटच्या डिझाइन मर्यादांच्या बाहेर, विशेषतः हलकेपणासाठी तयार करणे. + +पोर्टल नेटवर्कची मुख्य कल्पना म्हणजे सध्याच्या नेटवर्किंग स्टॅकचे सर्वोत्तम भाग घेणे, ज्यामध्ये लाइट क्लायंटना आवश्यक असलेली माहिती, जसे की ऐतिहासिक डेटा आणि चेनच्या सध्याच्या हेडची ओळख, [DHT](https://en.wikipedia.org/wiki/Distributed_hash_table) (Bittorrent सारखे) वापरून हलक्या वजनाच्या DevP2P शैलीतील पीअर-टू-पीअर विकेंद्रित नेटवर्कद्वारे दिली जाईल. + +प्रत्येक नोडमध्ये एकूण ऐतिहासिक Ethereum डेटाचे लहान भाग आणि काही विशिष्ट नोड जबाबदाऱ्या जोडण्याची कल्पना आहे. नंतर, विनंती केलेला विशिष्ट डेटा संग्रहित करणारे नोड्स शोधून आणि त्यांच्याकडून तो मिळवून विनंत्या पूर्ण केल्या जातात. + +हे लाइट नोड्सच्या सामान्य मॉडेलला उलट करते ज्यात एकच नोड शोधून मोठ्या प्रमाणात डेटा फिल्टर करण्याची आणि सर्व्ह करण्याची विनंती केली जाते; त्याऐवजी, ते नोड्सच्या मोठ्या नेटवर्कला त्वरीत फिल्टर करतात जे प्रत्येकजण कमी प्रमाणात डेटा हाताळतात. + +हलक्या वजनाच्या पोर्टल क्लायंटच्या विकेंद्रित नेटवर्कला खालील गोष्टी करण्याची परवानगी देणे हे ध्येय आहे: + +- चेनच्या हेडचा मागोवा घेणे +- अलीकडील आणि ऐतिहासिक चेन डेटा सिंक करणे +- स्टेट डेटा मिळवणे +- व्यवहार प्रसारित करणे +- [EVM](/developers/docs/evm/) वापरून व्यवहार कार्यान्वित करणे + +या नेटवर्क डिझाइनचे फायदे आहेत: + +- केंद्रीकृत प्रदात्यांवरील अवलंबित्व कमी करणे +- इंटरनेट बँडविड्थ वापर कमी करणे +- किमान किंवा शून्य सिंकिंग +- संसाधन-मर्यादित उपकरणांसाठी प्रवेशयोग्य (<1 GB RAM, <100 MB डिस्क स्पेस, 1 CPU) + +खालील तक्ता विद्यमान क्लायंटची कार्ये दर्शवितो जी पोर्टल नेटवर्कद्वारे वितरित केली जाऊ शकतात, ज्यामुळे वापरकर्त्यांना अत्यंत कमी-संसाधन उपकरणांवर या कार्यांमध्ये प्रवेश करता येतो. + +### पोर्टल नेटवर्क्स + +| बीकन लाइट क्लायंट | स्टेट नेटवर्क | व्यवहार गॉसिप | हिस्टरी नेटवर्क | +| ----------------- | --------------------- | ------------- | --------------- | +| बीकन चेन लाइट | खाते आणि करार स्टोरेज | हलके मेमपूल | हेडर्स | +| प्रोटोकॉल डेटा | | | ब्लॉक बॉडीज | +| | | | पावत्या | + +## डीफॉल्टनुसार क्लायंट विविधता {#client-diversity-as-default} + +पोर्टल नेटवर्क डेव्हलपर्सनी पहिल्या दिवसापासून चार वेगळे पोर्टल नेटवर्क क्लायंट तयार करण्याचा डिझाइन पर्याय निवडला. + +पोर्टल नेटवर्क क्लायंट आहेत: + +- [Trin](https://github.com/ethereum/trin): रस्टमध्ये लिहिलेले +- [Fluffy](https://fluffy.guide): निममध्ये लिहिलेले +- [Ultralight](https://github.com/ethereumjs/ultralight): टाइप्सक्रिप्टमध्ये लिहिलेले +- [Shisui](https://github.com/zen-eth/shisui): गो मध्ये लिहिलेले + +एकाधिक स्वतंत्र क्लायंट अंमलबजावणी असणे Ethereum नेटवर्कची लवचिकता आणि विकेंद्रीकरण वाढवते. + +एखाद्या क्लायंटला समस्या किंवा असुरक्षिततेचा सामना करावा लागल्यास, इतर क्लायंट सहजतेने कार्य करणे सुरू ठेवू शकतात, ज्यामुळे अपयशाचा एकच बिंदू टाळता येतो. याव्यतिरिक्त, विविध क्लायंट अंमलबजावणी नवकल्पना आणि स्पर्धेला प्रोत्साहन देतात, सुधारणांना चालना देतात आणि इकोसिस्टममधील मोनोकल्चरचा धोका कमी करतात. + +## पुढील वाचन {#further-reading} + +- [पोर्टल नेटवर्क (डेव्हकॉन बोगोटा येथे पायपर मेरियम)](https://www.youtube.com/watch?v=0stc9jnQLXA). +- [पोर्टल नेटवर्क डिस्कॉर्ड](https://discord.gg/CFFnmE7Hbs) +- [पोर्टल नेटवर्क वेबसाइट](https://www.ethportal.net/) diff --git a/public/content/translations/mr/developers/docs/networks/index.md b/public/content/translations/mr/developers/docs/networks/index.md new file mode 100644 index 00000000000..1d458c3b72c --- /dev/null +++ b/public/content/translations/mr/developers/docs/networks/index.md @@ -0,0 +1,216 @@ +--- +title: "नेटवर्क" +description: "Ethereum च्या नेटवर्क्सचा आढावा आणि तुमच्या ॲप्लिकेशनची चाचणी करण्यासाठी टेस्टनेट ईथर (ETH) कुठून मिळवायचे." +lang: mr +--- + +Ethereum नेटवर्क्स हे एकमेकांना जोडलेल्या संगणकांचे गट आहेत जे Ethereum प्रोटोकॉल वापरून संवाद साधतात. फक्त एकच Ethereum मेननेट आहे, परंतु चाचणी आणि विकासाच्या उद्देशांसाठी त्याच प्रोटोकॉल नियमांचे पालन करणारे स्वतंत्र नेटवर्क्स तयार केले जाऊ शकतात. असे अनेक स्वतंत्र "नेटवर्क्स" आहेत जे एकमेकांशी संवाद न साधता प्रोटोकॉलचे पालन करतात. तुम्ही तुमच्या स्मार्ट कॉन्ट्रॅक्ट्स आणि वेब3 ॲप्सची चाचणी करण्यासाठी तुमच्या स्वतःच्या संगणकावर स्थानिक पातळीवर एक सुरू करू शकता. + +तुमचे Ethereum खाते वेगवेगळ्या नेटवर्क्सवर काम करेल, परंतु तुमच्या खात्यातील शिल्लक आणि व्यवहारांचा इतिहास मुख्य Ethereum नेटवर्कवरून पुढे नेला जाणार नाही. चाचणीच्या उद्देशांसाठी, कोणते नेटवर्क्स उपलब्ध आहेत आणि प्रयोग करण्यासाठी टेस्टनेट ETH कसे मिळवायचे हे जाणून घेणे उपयुक्त आहे. सर्वसाधारणपणे, सुरक्षिततेच्या कारणास्तव, मेननेट खाती टेस्टनेट्सवर किंवा याउलट पुन्हा वापरण्याची शिफारस केली जात नाही. + +## पूर्वतयारी {#prerequisites} + +वेगवेगळ्या नेटवर्क्सबद्दल वाचण्यापूर्वी तुम्ही [Ethereum च्या मूलभूत गोष्टी](/developers/docs/intro-to-ethereum/) समजून घ्याव्यात, कारण टेस्ट नेटवर्क्स तुम्हाला प्रयोग करण्यासाठी Ethereum ची एक स्वस्त, सुरक्षित आवृत्ती देतील. + +## सार्वजनिक नेटवर्क्स {#public-networks} + +सार्वजनिक नेटवर्क्स इंटरनेट कनेक्शन असलेल्या जगातील कोणालाही उपलब्ध आहेत. कोणीही सार्वजनिक ब्लॉकचेनवर व्यवहार वाचू किंवा तयार करू शकतो आणि कार्यान्वित होत असलेल्या व्यवहारांना प्रमाणित करू शकतो. पीअर्समधील सहमती व्यवहारांच्या समावेशावर आणि नेटवर्कच्या स्थितीवर निर्णय घेते. + +### Ethereum मेननेट {#ethereum-mainnet} + +मेननेट हे प्राथमिक सार्वजनिक Ethereum प्रोडक्शन ब्लॉकचेन आहे, जिथे वितरित लेजरवर वास्तविक-मूल्याचे व्यवहार होतात. + +जेव्हा लोक आणि एक्सचेंज ETH च्या किमतींवर चर्चा करतात, तेव्हा ते मेननेट ETH बद्दल बोलत असतात. + +### Ethereum टेस्टनेट्स {#ethereum-testnets} + +मेननेट व्यतिरिक्त, सार्वजनिक टेस्टनेट्स आहेत. हे प्रोटोकॉल डेव्हलपर्स किंवा स्मार्ट कॉन्ट्रॅक्ट डेव्हलपर्सद्वारे मेननेटवर तैनात करण्यापूर्वी प्रोटोकॉल अपग्रेड्स आणि संभाव्य स्मार्ट कॉन्ट्रॅक्ट्स या दोन्हींची प्रोडक्शनसारख्या वातावरणात चाचणी घेण्यासाठी वापरले जाणारे नेटवर्क्स आहेत. याला प्रोडक्शन विरुद्ध स्टेजिंग सर्व्हर्सच्या एनालॉग म्हणून विचार करा. + +तुम्ही लिहिलेला कोणताही कॉन्ट्रॅक्ट कोड मेननेटवर तैनात करण्यापूर्वी टेस्टनेटवर तपासला पाहिजे. विद्यमान स्मार्ट कॉन्ट्रॅक्ट्ससह एकत्रित होणाऱ्या dApps पैकी, बहुतेक प्रोजेक्ट्सच्या कॉपीज टेस्टनेट्सवर तैनात केलेल्या असतात. + +बहुतेक टेस्टनेट्सनी परवानगी असलेल्या प्रूफ-ऑफ-अथॉरिटी सहमती यंत्रणेचा वापर करून सुरुवात केली. याचा अर्थ असा की व्यवहार प्रमाणित करण्यासाठी आणि नवीन ब्लॉक्स तयार करण्यासाठी काही मोजके नोड्स निवडले जातात – या प्रक्रियेत त्यांची ओळख स्टेक करून. याव्यतिरिक्त, काही टेस्टनेट्समध्ये एक खुली प्रूफ-ऑफ-स्टेक सहमती यंत्रणा असते, जिथे प्रत्येकजण Ethereum मेननेटप्रमाणेच व्हॅलिडेटर चालवण्याची चाचणी करू शकतो. + +टेस्टनेट्सवरील ETH चे कोणतेही वास्तविक मूल्य नसते असे मानले जाते; तथापि, काही प्रकारच्या टेस्टनेट ETH साठी बाजारपेठा तयार झाल्या आहेत जे दुर्मिळ किंवा मिळवण्यासाठी कठीण झाले आहे. Ethereum सोबत (अगदी टेस्टनेट्सवरही) संवाद साधण्यासाठी तुम्हाला ETH ची आवश्यकता असल्याने, बहुतेक लोक फॉसेट्समधून विनामूल्य टेस्टनेट ETH मिळवतात. बहुतेक फॉसेट्स हे वेबॲप्स आहेत जिथे तुम्ही एक पत्ता टाकू शकता ज्यावर ETH पाठवण्याची विनंती करता. + +#### मी कोणता टेस्टनेट वापरावा? + +क्लायंट डेव्हलपर्स सध्या सांभाळत असलेले दोन सार्वजनिक टेस्टनेट्स Sepolia आणि Hoodi आहेत. Sepolia हे कॉन्ट्रॅक्ट आणि ॲप्लिकेशन डेव्हलपर्ससाठी त्यांच्या ॲप्लिकेशन्सची चाचणी करण्याकरिता एक नेटवर्क आहे. Hoodi नेटवर्क प्रोटोकॉल डेव्हलपर्सना नेटवर्क अपग्रेडची चाचणी करण्याची आणि स्टेकर्सना व्हॅलिडेटर्स चालवण्याची चाचणी करण्याची परवानगी देते. + +#### Sepolia {#sepolia} + +**ॲप्लिकेशन डेव्हलपमेंटसाठी Sepolia हा शिफारस केलेला डीफॉल्ट टेस्टनेट आहे**. Sepolia नेटवर्क क्लायंट आणि टेस्टिंग टीमद्वारे नियंत्रित असलेला परवानगीप्राप्त व्हॅलिडेटर संच वापरते. + +##### संसाधने + +- [वेबसाइट](https://sepolia.dev/) +- [GitHub](https://github.com/eth-clients/sepolia) +- [Otterscan](https://sepolia.otterscan.io/) +- [Etherscan](https://sepolia.etherscan.io) +- [Blockscout](https://eth-sepolia.blockscout.com/) + +##### फॉसेट्स + +- [Alchemy Sepolia फॉसेट](https://www.alchemy.com/faucets/ethereum-sepolia) +- [Chain Platform Sepolia फॉसेट](https://faucet.chainplatform.co/faucets/ethereum-sepolia/) +- [Chainstack Sepolia फॉसेट](https://faucet.chainstack.com/sepolia-testnet-faucet) +- [Ethereum इकोसिस्टम फॉसेट](https://www.ethereum-ecosystem.com/faucets/ethereum-sepolia) +- [ethfaucet.com Sepolia फॉसेट](https://ethfaucet.com/networks/ethereum) +- [Google Cloud Web3 Sepolia फॉसेट](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) +- [Grabteeth](https://grabteeth.xyz/) +- [Infura Sepolia फॉसेट](https://www.infura.io/faucet) +- [PoW फॉसेट](https://sepolia-faucet.pk910.de/) +- [QuickNode Sepolia फॉसेट](https://faucet.quicknode.com/ethereum/sepolia) + +#### Hoodi {#hoodi} + +Hoodi हा व्हॅलिडेटिंग आणि स्टेकिंगची चाचणी करण्यासाठी एक टेस्टनेट आहे. Hoodi नेटवर्क टेस्टनेट व्हॅलिडेटर चालवू इच्छिणाऱ्या वापरकर्त्यांसाठी खुले आहे. म्हणून, मेननेटवर तैनात करण्यापूर्वी प्रोटोकॉल अपग्रेडची चाचणी करू इच्छिणाऱ्या स्टेकर्सनी Hoodi वापरावे. + +- खुला व्हॅलिडेटर सेट, स्टेकर्स नेटवर्क अपग्रेडची चाचणी करू शकतात +- मोठी स्टेट, गुंतागुंतीच्या स्मार्ट कॉन्ट्रॅक्ट इंटरॅक्शन्सची चाचणी करण्यासाठी उपयुक्त +- सिंक करण्यासाठी जास्त वेळ लागतो आणि नोड चालवण्यासाठी जास्त स्टोरेजची आवश्यकता असते + +##### संसाधने + +- [वेबसाइट](https://hoodi.ethpandaops.io/) +- [GitHub](https://github.com/eth-clients/hoodi) +- [एक्सप्लोरर](https://explorer.hoodi.ethpandaops.io/) +- [चेकपॉइंट सिंक](https://checkpoint-sync.hoodi.ethpandaops.io/) +- [Otterscan](https://hoodi.otterscan.io/) +- [Etherscan](https://hoodi.etherscan.io/) + +##### फॉसेट्स + +- [Chain Platform Hoodi फॉसेट](https://faucet.chainplatform.co/faucets/ethereum-hoodi/) +- [Hoodi फॉसेट](https://hoodi.ethpandaops.io/) +- [PoW फॉसेट](https://hoodi-faucet.pk910.de/) + +#### Ephemery {#ephemery} + +Ephemery हा एक अनोखा प्रकारचा टेस्टनेट आहे जो दर महिन्याला पूर्णपणे रीसेट होतो. अंमलबजावणी आणि सहमतीची स्थिती दर 28 दिवसांनी जेनेसिसवर परत जाते, याचा अर्थ टेस्टनेटवर घडणारी कोणतीही गोष्ट क्षणिक असते. यामुळे हे अल्प-मुदतीच्या चाचणी, जलद नोड बूटस्ट्रॅप आणि 'हॅलो वर्ल्ड' सारख्या ॲप्लिकेशन्ससाठी आदर्श आहे ज्यांना कायमस्वरूपीपणाची आवश्यकता नसते. + +- नेहमी ताजी स्थिती, व्हॅलिडेटर्स आणि ॲप्सची अल्प-मुदतीची चाचणी +- फक्त मूलभूत कॉन्ट्रॅक्ट्सचा संच समाविष्ट आहे +- खुला व्हॅलिडेटर सेट आणि मोठ्या प्रमाणात निधी मिळवणे सोपे +- सर्वात कमी नोड आवश्यकता आणि सर्वात जलद सिंक, सरासरी <5GB + +##### संसाधने + +- [वेबसाइट](https://ephemery.dev/) +- [Github](https://github.com/ephemery-testnet/ephemery-resources) +- [कम्युनिटी चॅट](https://matrix.to/#/#staker-testnet:matrix.org) +- [Blockscout](https://explorer.ephemery.dev/) +- [Otterscan](https://otter.bordel.wtf/) +- [बीकन एक्सप्लोरर](https://beaconlight.ephemery.dev/) +- [चेकपॉइंट सिंक](https://checkpoint-sync.ephemery.ethpandaops.io) +- [लाँचपॅड](https://launchpad.ephemery.dev/) + +#### फॉसेट्स + +- [Bordel फॉसेट](https://faucet.bordel.wtf/) +- [Pk910 PoW फॉसेट](https://ephemery-faucet.pk910.de/) + +#### Holesky (कालबाह्य) {#holesky} + +Holesky टेस्टनेट सप्टेंबर २०२५ पासून कालबाह्य आहे. स्टेकिंग ऑपरेटर्स आणि इन्फ्रास्ट्रक्चर प्रोव्हायडर्सनी त्याऐवजी व्हॅलिडेटर चाचणीसाठी Hoodi वापरावे. + +- [Holesky टेस्टनेट शटडाउनची घोषणा](https://blog.ethereum.org/2025/09/01/holesky-shutdown-announcement) - _EF ब्लॉग, 1-सप्टेंबर-2025_ +- [Holesky आणि Hoodi टेस्टनेट अपडेट्स](https://blog.ethereum.org/en/2025/03/18/hoodi-holesky) - _EF ब्लॉग, 18-मार्च-2025_ + +### लेयर 2 टेस्टनेट्स {#layer-2-testnets} + +[लेयर 2 (L2)](/layer-2/) ही Ethereum स्केलिंग सोल्यूशन्सच्या विशिष्ट संचाचे वर्णन करण्यासाठी वापरली जाणारी एक सामूहिक संज्ञा आहे. लेयर 2 हे एक वेगळे ब्लॉकचेन आहे जे Ethereum चा विस्तार करते आणि Ethereum च्या सुरक्षा हमी वारसा हक्काने घेते. लेयर 2 टेस्टनेट्स सामान्यतः सार्वजनिक Ethereum टेस्टनेट्सशी घट्टपणे जोडलेले असतात. + +#### Arbitrum Sepolia {#arbitrum-sepolia} + +[Arbitrum](https://arbitrum.io/) साठी एक टेस्टनेट. + +##### संसाधने + +- [Etherscan](https://sepolia.arbiscan.io/) +- [Blockscout](https://sepolia-explorer.arbitrum.io/) + +##### फॉसेट्स + +- [Alchemy Arbitrum Sepolia फॉसेट](https://www.alchemy.com/faucets/arbitrum-sepolia) +- [Chainlink Arbitrum Sepolia फॉसेट](https://faucets.chain.link/arbitrum-sepolia) +- [ethfaucet.com Arbitrum Sepolia फॉसेट](https://ethfaucet.com/networks/arbitrum) +- [QuickNode Arbitrum Sepolia फॉसेट](https://faucet.quicknode.com/arbitrum/sepolia) + +#### Optimistic Sepolia {#optimistic-sepolia} + +[Optimism](https://www.optimism.io/) साठी एक टेस्टनेट. + +##### संसाधने + +- [Etherscan](https://sepolia-optimistic.etherscan.io/) +- [Blockscout](https://optimism-sepolia.blockscout.com/) + +##### फॉसेट्स + +- [Alchemy फॉसेट](https://www.alchemy.com/faucets/optimism-sepolia) +- [Chainlink फॉसेट](https://faucets.chain.link/optimism-sepolia) +- [ethfaucet.com Optimism Sepolia फॉसेट](https://ethfaucet.com/networks/optimism) +- [टेस्टनेट फॉसेट](https://docs.optimism.io/builders/tools/build/faucets) + +#### Starknet Sepolia {#starknet-sepolia} + +[Starknet](https://www.starknet.io) साठी एक टेस्टनेट. + +##### संसाधने + +- [Starkscan](https://sepolia.starkscan.co/) + +##### फॉसेट्स + +- [Alchemy फॉसेट](https://www.alchemy.com/faucets/starknet-sepolia) +- [Blast Starknet Sepolia फॉसेट](https://blastapi.io/faucets/starknet-sepolia-eth) +- [Starknet फॉसेट](https://starknet-faucet.vercel.app/) + +## खाजगी नेटवर्क्स {#private-networks} + +एक Ethereum नेटवर्क हे खाजगी नेटवर्क असते जर त्याचे नोड्स सार्वजनिक नेटवर्कशी (म्हणजेच, मेननेट किंवा टेस्टनेट) जोडलेले नसतील. या संदर्भात, 'खाजगी' म्हणजे फक्त राखीव किंवा वेगळे, संरक्षित किंवा सुरक्षित नाही. + +### विकास नेटवर्क्स {#development-networks} + +Ethereum ॲप्लिकेशन विकसित करण्यासाठी, ते तैनात करण्यापूर्वी कसे कार्य करते हे पाहण्यासाठी तुम्हाला ते एका खाजगी नेटवर्कवर चालवायचे असेल. जसे तुम्ही वेब डेव्हलपमेंटसाठी तुमच्या संगणकावर लोकल सर्व्हर तयार करता, त्याचप्रमाणे तुम्ही तुमच्या dApp ची चाचणी करण्यासाठी लोकल ब्लॉकचेन इन्स्टन्स तयार करू शकता. हे सार्वजनिक टेस्टनेटपेक्षा खूप जलद पुनरावृत्ती करण्यास अनुमती देते. + +यासाठी मदत करण्यासाठी समर्पित प्रोजेक्ट्स आणि टूल्स आहेत. [विकास नेटवर्क्स](/developers/docs/development-networks/)बद्दल अधिक जाणून घ्या. + +### कंसोर्टियम नेटवर्क्स {#consortium-networks} + +सहमती प्रक्रिया विश्वसनीय असलेल्या नोड्सच्या पूर्व-परिभाषित संचाद्वारे नियंत्रित केली जाते. उदाहरणार्थ, ज्ञात शैक्षणिक संस्थांचे एक खाजगी नेटवर्क ज्यापैकी प्रत्येक एका नोडवर नियंत्रण ठेवते, आणि ब्लॉक्स नेटवर्कमधील स्वाक्षरीकर्त्यांच्या थ्रेशोल्डद्वारे प्रमाणित केले जातात. + +जर सार्वजनिक Ethereum नेटवर्क सार्वजनिक इंटरनेटसारखे असेल, तर कंसोर्टियम नेटवर्क खाजगी इंट्रानेटसारखे आहे. + +## Ethereum टेस्टनेट्सना मेट्रो स्टेशन्सची नावे का दिली जातात? {#why-naming} + +अनेक Ethereum टेस्टनेट्सना वास्तविक जगातील मेट्रो किंवा ट्रेन स्टेशन्सवरून नावे दिली आहेत. ही नाव देण्याची परंपरा लवकर सुरू झाली आणि ती जागतिक शहरे प्रतिबिंबित करते जिथे योगदानकर्ते राहिले किंवा काम केले आहेत. हे प्रतिकात्मक, संस्मरणीय आणि व्यावहारिक आहे. जसे टेस्टनेट्स Ethereum मेननेटपासून वेगळे आहेत, तसेच मेट्रो लाईन्स पृष्ठभागावरील रहदारीपासून वेगळ्या चालतात. + +### सामान्यतः वापरले जाणारे आणि लेगसी टेस्टनेट्स {#common-and-legacy-testnets} + +- **Sepolia** - अथेन्स, ग्रीसमधील मेट्रोने जोडलेला परिसर. सध्या स्मार्ट कॉन्ट्रॅक्ट आणि dApp चाचणीसाठी वापरले जाते. +- **Hoodi** - बंगळूर, भारतातील हुडी मेट्रो स्टेशनच्या नावावरून ठेवलेले. व्हॅलिडेटर आणि प्रोटोकॉल अपग्रेड चाचणीसाठी वापरले जाते. +- **Goerli** _(कालबाह्य)_ - बर्लिन, जर्मनीमधील Görlitzer Bahnhof च्या नावावरून ठेवलेले. +- **Rinkeby** _(कालबाह्य)_ - स्टॉकहोममधील मेट्रो स्टेशन असलेल्या उपनगराच्या नावावरून ठेवलेले. +- **Ropsten** _(कालबाह्य)_ - स्टॉकहोममधील एक परिसर आणि पूर्वीचे फेरी/मेट्रो टर्मिनल. +- **Kovan** _(कालबाह्य)_ - सिंगापूरमधील MRT स्टेशनच्या नावावरून ठेवलेले. +- **Morden** _(कालबाह्य)_ - लंडन अंडरग्राउंड स्टेशनच्या नावावरून ठेवलेले. Ethereum चा पहिला सार्वजनिक टेस्टनेट. + +### इतर विशेष टेस्टनेट्स {#other-testnets} + +काही टेस्टनेट्स अल्प-मुदतीच्या किंवा अपग्रेड-विशिष्ट चाचणीसाठी तयार केले गेले होते आणि ते आवश्यक नाही की मेट्रो-थीमवर आधारित असतील: + +- **Holesky** _(कालबाह्य)_ - प्रागमधील Holešovice स्टेशनच्या नावावरून ठेवलेले. व्हॅलिडेटर चाचणीसाठी वापरले जाते; 2025 मध्ये कालबाह्य. +- **Kiln**, **Zhejiang**, **Shandong**, **Prater**, **Pyrmont**, **Olympic** _(सर्व कालबाह्य)_ आणि **Ephemery** - द मर्ज, शांघाय, किंवा व्हॅलिडेटर प्रयोगांसारख्या अपग्रेड सिम्युलेशनसाठी उद्देश-निर्मित. काही नावे मेट्रो-आधारित नसून प्रादेशिक किंवा थीमॅटिक आहेत. + +मेट्रो स्टेशनची नावे वापरल्याने डेव्हलपर्सना अंकीय चेन आयडीवर अवलंबून न राहता टेस्टनेट्स पटकन ओळखण्यास आणि लक्षात ठेवण्यास मदत होते. हे Ethereum च्या संस्कृतीला देखील प्रतिबिंबित करते: व्यावहारिक, जागतिक आणि मानवकेंद्रित. + +## संबंधित साधने {#related-tools} + +- [Chainlist](https://chainlist.org/) _वॉलेट्स आणि प्रोव्हायडर्सना योग्य चेन आयडी आणि नेटवर्क आयडीशी जोडण्यासाठी EVM नेटवर्क्सची सूची_ +- [EVM-आधारित चेन्स](https://github.com/ethereum-lists/chains) _चेन मेटाडेटाचा GitHub रेपो जो Chainlist ला शक्ती देतो_ + +## पुढील वाचन {#further-reading} + +- [प्रस्ताव: अंदाजित Ethereum टेस्टनेट जीवनचक्र](https://ethereum-magicians.org/t/proposal-predictable-ethereum-testnet-lifecycle/11575/17) +- [Ethereum टेस्टनेट्सची उत्क्रांती](https://etherworld.co/2022/08/19/the-evolution-of-ethereum-testnet/) diff --git a/public/content/translations/mr/developers/docs/nodes-and-clients/archive-nodes/index.md b/public/content/translations/mr/developers/docs/nodes-and-clients/archive-nodes/index.md new file mode 100644 index 00000000000..094c61594a9 --- /dev/null +++ b/public/content/translations/mr/developers/docs/nodes-and-clients/archive-nodes/index.md @@ -0,0 +1,81 @@ +--- +title: "इथेरियम आर्काइव्ह नोड" +description: "आर्काइव्ह नोड्सचा आढावा" +lang: mr +sidebarDepth: 2 +--- + +आर्काइव्ह नोड हा इथेरियम क्लायंटचा एक इन्स्टन्स आहे जो सर्व ऐतिहासिक स्टेट्सचा आर्काइव्ह तयार करण्यासाठी कॉन्फिगर केलेला असतो. हे काही विशिष्ट वापरासाठी एक उपयुक्त साधन आहे परंतु पूर्ण नोडपेक्षा चालवण्यासाठी अधिक अवघड असू शकते. + +## पूर्वतयारी {#prerequisites} + +तुम्ही [इथेरियम नोडची](/developers/docs/nodes-and-clients/) संकल्पना, [त्याची रचना](/developers/docs/nodes-and-clients/node-architecture/), [सिंक करण्याची धोरणे](/developers/docs/nodes-and-clients/#sync-modes), [तो चालवण्याच्या](/developers/docs/nodes-and-clients/run-a-node/) आणि [वापरण्याच्या](/developers/docs/apis/json-rpc/) पद्धती समजून घेतल्या पाहिजेत. + +## आर्काइव्ह नोड म्हणजे काय + +आर्काइव्ह नोडचे महत्त्व समजून घेण्यासाठी, चला "स्टेट" ही संकल्पना स्पष्ट करूया. इथेरियमला _ट्रान्झॅक्शन-आधारित स्टेट मशीन_ म्हणून संबोधले जाऊ शकते. यात खाती आणि ॲप्लिकेशन्स असतात जे व्यवहार कार्यान्वित करून त्यांची स्टेट बदलतात. प्रत्येक खाते आणि कराराबद्दलच्या माहितीसह असलेला जागतिक डेटा, स्टेट नावाच्या ट्राय डेटाबेसमध्ये संग्रहित केला जातो. हे एक्झिक्युशन लेअर (EL) क्लायंटद्वारे हाताळले जाते आणि त्यात समाविष्ट आहे: + +- खात्यातील शिल्लक आणि नॉन्स +- कराराचा कोड आणि स्टोरेज +- कन्सेंसस-संबंधित डेटा, उदा., स्टेकिंग डिपॉझिट कॉन्ट्रॅक्ट + +नेटवर्कशी संवाद साधण्यासाठी, नवीन ब्लॉक्सची पडताळणी करण्यासाठी आणि तयार करण्यासाठी, इथेरियम क्लायंट्सना सर्वात अलीकडील बदलांसह (चेनचे टोक) आणि म्हणूनच वर्तमान स्टेटसह अद्ययावत रहावे लागते. पूर्ण नोड म्हणून कॉन्फिगर केलेला एक्झिक्युशन लेअर क्लायंट नेटवर्कच्या नवीनतम स्टेटची पडताळणी करतो आणि त्याचे अनुसरण करतो, पण तो फक्त मागील काही स्टेट्स कॅशे करतो, उदा., शेवटच्या 128 ब्लॉक्सशी संबंधित स्टेट, जेणेकरून तो चेन रिऑर्ग्स हाताळू शकेल आणि अलीकडील डेटामध्ये जलद प्रवेश प्रदान करू शकेल. येणारे व्यवहार सत्यापित करण्यासाठी आणि नेटवर्क वापरण्यासाठी सर्व क्लायंट्सना अलीकडील स्टेटची आवश्यकता असते. + +तुम्ही स्टेटची कल्पना एका दिलेल्या ब्लॉकवरील नेटवर्कच्या क्षणिक स्नॅपशॉट म्हणून आणि आर्काइव्हची कल्पना इतिहासाच्या रिप्ले म्हणून करू शकता. + +ऐतिहासिक स्टेट्स सुरक्षितपणे काढून टाकल्या जाऊ शकतात, कारण त्या नेटवर्क चालवण्यासाठी आवश्यक नाहीत आणि क्लायंटने सर्व कालबाह्य डेटा ठेवणे अनावश्यकपणे निरर्थक ठरेल. काही अलीकडील ब्लॉकच्या आधी अस्तित्वात असलेल्या स्टेट्स (उदा., हेडच्या 128 ब्लॉक्स आधी) प्रभावीपणे टाकून दिल्या जातात. पूर्ण नोड्स फक्त ऐतिहासिक ब्लॉकचेन डेटा (ब्लॉक्स आणि व्यवहार) आणि अधूनमधून ऐतिहासिक स्नॅपशॉट्स ठेवतात, जे ते विनंतीनुसार जुन्या स्टेट्स पुन्हा तयार करण्यासाठी वापरू शकतात. ते EVM मध्ये मागील व्यवहार पुन्हा कार्यान्वित करून हे करतात, जे संगणकीयदृष्ट्या मागणी करणारे असू शकते जेव्हा इच्छित स्टेट सर्वात जवळच्या स्नॅपशॉटपासून दूर असते. + +तथापि, याचा अर्थ असा की पूर्ण नोडवर ऐतिहासिक स्टेटमध्ये प्रवेश करण्यासाठी खूप संगणन लागते. क्लायंटला सर्व मागील व्यवहार कार्यान्वित करण्याची आणि जेनेसिसपासून एक ऐतिहासिक स्टेट संगणित करण्याची आवश्यकता भासू शकते. आर्काइव्ह नोड्स ही समस्या केवळ सर्वात अलीकडील स्टेट्सच नव्हे, तर प्रत्येक ब्लॉकनंतर तयार झालेली प्रत्येक ऐतिहासिक स्टेट संग्रहित करून सोडवतात. हे मुळात मोठ्या डिस्क स्पेसच्या आवश्यकतेसह तडजोड करते. + +हे लक्षात घेणे महत्त्वाचे आहे की सर्व ऐतिहासिक डेटा ठेवण्यासाठी आणि प्रदान करण्यासाठी नेटवर्क आर्काइव्ह नोड्सवर अवलंबून नाही. वर नमूद केल्याप्रमाणे, सर्व ऐतिहासिक अंतरिम स्टेट्स पूर्ण नोडवर मिळवता येतात. व्यवहार कोणत्याही पूर्ण नोडद्वारे संग्रहित केले जातात (सध्या 400G पेक्षा कमी) आणि संपूर्ण आर्काइव्ह तयार करण्यासाठी ते पुन्हा प्ले केले जाऊ शकतात. + +### प्रकरणे वापरा + +इथेरियमच्या नियमित वापरासाठी, जसे की व्यवहार पाठवणे, करार तैनात करणे, कन्सेंसस सत्यापित करणे इत्यादी, ऐतिहासिक स्टेट्समध्ये प्रवेशाची आवश्यकता नसते. नेटवर्कशी मानक संवादासाठी वापरकर्त्यांना आर्काइव्ह नोडची कधीही आवश्यकता नसते. + +स्टेट आर्काइव्हचा मुख्य फायदा म्हणजे ऐतिहासिक स्टेट्सबद्दलच्या क्वेरींमध्ये जलद प्रवेश मिळवणे. उदाहरणार्थ, आर्काइव्ह नोड त्वरित खालीलप्रमाणे परिणाम देईल: + +- _खाते 0x1337... ची ETH शिल्लक काय होती..._ _ब्लॉक 15537393 वर?_ +- _ब्लॉक 1920000 वर करार 0x मधील टोकन 0x ची शिल्लक काय आहे?_ + +वर स्पष्ट केल्याप्रमाणे, पूर्ण नोडला EVM एक्झिक्युशनद्वारे हा डेटा तयार करण्याची आवश्यकता असेल, जे CPU वापरते आणि वेळ घेते. आर्काइव्ह नोड्स डिस्कवर त्यात प्रवेश करतात आणि त्वरित प्रतिसाद देतात. पायाभूत सुविधांच्या काही भागांसाठी हे एक उपयुक्त वैशिष्ट्य आहे, उदाहरणार्थ: + +- ब्लॉक एक्सप्लोरर्स सारखे सेवा प्रदाते +- संशोधक +- सुरक्षा विश्लेषक +- Dapp डेव्हलपर्स +- ऑडिटिंग आणि अनुपालन + +विविध विनामूल्य [सेवा](/developers/docs/nodes-and-clients/nodes-as-a-service/) आहेत ज्या ऐतिहासिक डेटामध्ये प्रवेश करण्याची परवानगी देखील देतात. आर्काइव्ह नोड चालवणे अधिक मागणीचे असल्याने, हा प्रवेश बहुतेक मर्यादित असतो आणि फक्त अधूनमधून प्रवेशासाठी कार्य करतो. तुमच्या प्रोजेक्टला ऐतिहासिक डेटामध्ये सतत प्रवेशाची आवश्यकता असल्यास, तुम्ही स्वतः एक चालवण्याचा विचार केला पाहिजे. + +## अंमलबजावणी आणि वापर + +या संदर्भात आर्काइव्ह नोड म्हणजे वापरकर्त्यांसमोर असलेल्या एक्झिक्युशन लेअर क्लायंटद्वारे सेवा दिलेला डेटा, कारण ते स्टेट डेटाबेस हाताळतात आणि JSON-RPC एंडपॉइंट्स प्रदान करतात. कॉन्फिगरेशन पर्याय, सिंक वेळ आणि डेटाबेस आकार क्लायंटनुसार भिन्न असू शकतात. तपशिलांसाठी, कृपया तुमच्या क्लायंटने प्रदान केलेल्या डॉक्युमेंटेशनचा संदर्भ घ्या. + +तुमचा स्वतःचा आर्काइव्ह नोड सुरू करण्यापूर्वी, क्लायंटमधील फरक आणि विशेषतः विविध [हार्डवेअर आवश्यकतां](/developers/docs/nodes-and-clients/run-a-node/#requirements)बद्दल जाणून घ्या. बहुतेक क्लायंट या वैशिष्ट्यासाठी ऑप्टिमाइझ केलेले नाहीत आणि त्यांच्या आर्काइव्हसाठी 12TB पेक्षा जास्त जागेची आवश्यकता असते. याउलट, Erigon सारखी अंमलबजावणी तोच डेटा 3TB पेक्षा कमी जागेत संग्रहित करू शकते, ज्यामुळे ते आर्काइव्ह नोड चालवण्याचा सर्वात प्रभावी मार्ग ठरतात. + +## शिफारस केलेल्या पद्धती + +[नोड चालवण्यासाठीच्या](/developers/docs/nodes-and-clients/run-a-node/) सामान्य शिफारशींव्यतिरिक्त, आर्काइव्ह नोड हार्डवेअर आणि देखभालीसाठी अधिक मागणी करणारा असू शकतो. Erigon ची [मुख्य वैशिष्ट्ये](https://github.com/ledgerwatch/erigon#key-features) विचारात घेता, [Erigon](/developers/docs/nodes-and-clients/#erigon) क्लायंट अंमलबजावणी वापरणे हा सर्वात व्यावहारिक दृष्टिकोन आहे. + +### हार्डवेअर + +क्लायंटच्या डॉक्युमेंटेशनमध्ये दिलेल्या मोडसाठी हार्डवेअर आवश्यकता नेहमी सत्यापित करण्याची खात्री करा. +आर्काइव्ह नोड्ससाठी सर्वात मोठी आवश्यकता डिस्क स्पेस आहे. क्लायंटवर अवलंबून, ते 3TB ते 12TB पर्यंत बदलते. जरी मोठ्या प्रमाणात डेटासाठी HDD एक चांगला उपाय मानला जाऊ शकतो, तरीही ते सिंक करण्यासाठी आणि चेनचे हेड सतत अद्ययावत करण्यासाठी SSD ड्राइव्हची आवश्यकता असेल. [SATA](https://www.cleverfiles.com/help/sata-hard-drive.html) ड्राइव्ह पुरेसे चांगले आहेत, परंतु ते विश्वसनीय दर्जाचे असावेत, किमान [TLC](https://blog.synology.com/tlc-vs-qlc-ssds-what-are-the-differences). पुरेशा स्लॉट्स असलेल्या डेस्कटॉप संगणकात किंवा सर्व्हरमध्ये डिस्क बसवल्या जाऊ शकतात. अशी समर्पित उपकरणे उच्च अपटाइम नोड चालवण्यासाठी आदर्श आहेत. हे लॅपटॉपवर चालवणे पूर्णपणे शक्य आहे, परंतु पोर्टेबिलिटीसाठी अतिरिक्त खर्च येईल. + +सर्व डेटा एकाच व्हॉल्यूममध्ये बसवणे आवश्यक आहे, म्हणून डिस्क जोडल्या पाहिजेत, उदा., [RAID0](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_0) किंवा LVM सह. [ZFS](https://en.wikipedia.org/wiki/ZFS) वापरण्याचा विचार करणे देखील योग्य ठरू शकते, कारण ते "कॉपी-ऑन-राइट" ला सपोर्ट करते, जे हे सुनिश्चित करते की डेटा कोणत्याही निम्न-स्तरीय त्रुटींशिवाय डिस्कवर योग्यरित्या लिहिला गेला आहे. + +अपघाती डेटाबेस करप्शन टाळण्यासाठी अधिक स्थिरता आणि सुरक्षिततेसाठी, विशेषतः व्यावसायिक सेटअपमध्ये, जर तुमची सिस्टीम त्याला सपोर्ट करत असेल तर [ECC मेमरी](https://en.wikipedia.org/wiki/ECC_memory) वापरण्याचा विचार करा. RAM चा आकार साधारणपणे पूर्ण नोडसाठी सारखाच ठेवण्याचा सल्ला दिला जातो, परंतु अधिक RAM सिंकचा वेग वाढविण्यात मदत करू शकते. + +सुरुवातीच्या सिंक दरम्यान, आर्काइव्ह मोडमधील क्लायंट जेनेसिसपासून प्रत्येक व्यवहार कार्यान्वित करतील. एक्झिक्युशनचा वेग बहुतेक CPU द्वारे मर्यादित असतो, त्यामुळे वेगवान CPU सुरुवातीच्या सिंक वेळेसाठी मदत करू शकतो. सरासरी ग्राहक संगणकावर, सुरुवातीच्या सिंकसाठी एक महिन्यापर्यंतचा कालावधी लागू शकतो. + +## पुढील वाचन {#further-reading} + +- [इथेरियम फुल नोड विरुद्ध आर्काइव्ह नोड](https://www.quicknode.com/guides/infrastructure/ethereum-full-node-vs-archive-node) - _QuickNode, सप्टेंबर २०२२_ +- [तुमचा स्वतःचा इथेरियम आर्काइव्ह नोड तयार करणे](https://tjayrush.medium.com/building-your-own-ethereum-archive-node-72c014affc09) - _थॉमस जे रश, ऑगस्ट २०२१_ +- [Erigon, Erigon’s RPC आणि TrueBlocks (स्क्रॅप आणि API) सेवा म्हणून कसे सेट करावे](https://magnushansson.xyz/blog_posts/crypto_defi/2022-01-10-Erigon-Trueblocks) _– मॅग्नस हॅन्सन, सप्टेंबर २०२२ रोजी अद्यतनित_ + +## संबंधित विषय {#related-topics} + +- [नोड्स आणि क्लायंट](/developers/docs/nodes-and-clients/) +- [नोड चालवणे](/developers/docs/nodes-and-clients/run-a-node/) diff --git a/public/content/translations/mr/developers/docs/nodes-and-clients/bootnodes/index.md b/public/content/translations/mr/developers/docs/nodes-and-clients/bootnodes/index.md new file mode 100644 index 00000000000..d0f6b4739b3 --- /dev/null +++ b/public/content/translations/mr/developers/docs/nodes-and-clients/bootnodes/index.md @@ -0,0 +1,31 @@ +--- +title: "इथेरियम बूटनोड्सचा परिचय" +description: "बूटनोड्स समजण्यासाठी आवश्यक असलेली मूलभूत माहिती" +lang: mr +--- + +जेव्हा एखादा नवीन नोड इथेरियम नेटवर्कमध्ये सामील होतो, तेव्हा त्याला नवीन पीअर्स शोधण्यासाठी नेटवर्कवर आधीपासून असलेल्या नोड्सशी कनेक्ट करणे आवश्यक असते. इथेरियम नेटवर्कमधील या एन्ट्री पॉईंट्सना बूटनोड्स म्हणतात. क्लायंट्समध्ये सहसा बूटनोड्सची यादी हार्डकोड केलेली असते. हे बूटनोड्स सामान्यतः इथेरियम फाउंडेशनच्या डेव्हॉप्स टीम किंवा क्लायंट टीम्सद्वारे चालवले जातात. लक्षात घ्या की बूटनोड्स आणि स्टॅटिक नोड्स एकच नाहीत. स्टॅटिक नोड्सना वारंवार कॉल केले जाते, तर बूटनोड्सना तेव्हाच कॉल केले जाते जेव्हा कनेक्ट करण्यासाठी पुरेसे पीअर्स नसतात आणि नोडला काही नवीन कनेक्शन्स बूटस्ट्रॅप करण्याची आवश्यकता असते. + +## बूटनोडला कनेक्ट करा {#connect-to-a-bootnode} + +बहुतेक क्लायंट्समध्ये बूटनोड्सची यादी बिल्ट-इन असते, परंतु तुम्हाला तुमचा स्वतःचा बूटनोड चालवायचा असेल किंवा क्लायंटच्या हार्डकोड केलेल्या यादीत नसलेला एखादा बूटनोड वापरायचा असेल. अशा परिस्थितीत, तुम्ही तुमचा क्लायंट सुरू करताना ते खालीलप्रमाणे निर्दिष्ट करू शकता (उदाहरण Geth साठी आहे, कृपया तुमच्या क्लायंटचे डॉक्युमेंटेशन तपासा): + +``` +geth --bootnodes "enode://@:" +``` + +## बूटनोड चालवा {#run-a-bootnode} + +बूटनोड्स हे पूर्ण नोड्स आहेत जे NAT ([नेटवर्क अॅड्रेस ट्रान्सलेशन](https://www.geeksforgeeks.org/network-address-translation-nat/)) च्या मागे नसतात. प्रत्येक पूर्ण नोड जोपर्यंत सार्वजनिकरित्या उपलब्ध आहे तोपर्यंत बूटनोड म्हणून काम करू शकतो. + +तुम्ही नोड सुरू करता तेव्हा, तो तुमचा [enode](/developers/docs/networking-layer/network-addresses/#enode) लॉग करतो, जो एक सार्वजनिक ओळखकर्ता आहे ज्याचा वापर इतर तुमच्या नोडशी कनेक्ट करण्यासाठी करू शकतात. + +प्रत्येक रीस्टार्टवर enode सहसा पुन्हा जनरेट होतो, त्यामुळे तुमच्या बूटनोडसाठी एक कायमस्वरूपी enode कसा तयार करायचा याबद्दल तुमच्या क्लायंटचे डॉक्युमेंटेशन नक्की तपासा. + +एक चांगला बूटनोड होण्यासाठी, त्याच्याशी कनेक्ट होऊ शकणाऱ्या पीअर्सची कमाल संख्या वाढवणे ही एक चांगली कल्पना आहे. अनेक पीअर्ससह बूटनोड चालवल्याने बँडविड्थची आवश्यकता लक्षणीयरीत्या वाढेल. + +## उपलब्ध बूटनोड्स {#available-bootnodes} + +go-ethereum मधील बिल्ट-इन बूटनोड्सची यादी [येथे](https://github.com/ethereum/go-ethereum/blob/master/params/bootnodes.go#L23) आढळू शकते. हे बूटनोड्स इथेरियम फाउंडेशन आणि go-ethereum टीमद्वारे सांभाळले जातात. + +स्वयंसेवकांकडून सांभाळल्या जाणाऱ्या बूटनोड्सच्या इतर याद्या देखील उपलब्ध आहेत. कृपया खात्री करा की तुम्ही नेहमी किमान एक अधिकृत बूटनोड समाविष्ट करा, अन्यथा तुमच्यावर एक्लिप्स अटॅक होऊ शकतो. diff --git a/public/content/translations/mr/developers/docs/nodes-and-clients/client-diversity/index.md b/public/content/translations/mr/developers/docs/nodes-and-clients/client-diversity/index.md new file mode 100644 index 00000000000..8d8c2cd1a8d --- /dev/null +++ b/public/content/translations/mr/developers/docs/nodes-and-clients/client-diversity/index.md @@ -0,0 +1,132 @@ +--- +title: "क्लायंट विविधता" +description: "Ethereum क्लायंट विविधतेच्या महत्त्वाचे उच्च स्तरीय स्पष्टीकरण." +lang: mr +sidebarDepth: 2 +--- + +Ethereum नोडचे वर्तन ते चालवत असलेल्या क्लायंट सॉफ्टवेअरद्वारे नियंत्रित केले जाते. अनेक प्रोडक्शन-लेव्हल Ethereum क्लायंट आहेत, प्रत्येक स्वतंत्र टीमद्वारे वेगवेगळ्या भाषांमध्ये विकसित आणि देखरेख केले जाते. क्लायंट एका सामान्य स्पेसिफिकेशननुसार तयार केले आहेत, जे हे सुनिश्चित करते की क्लायंट एकमेकांशी अखंडपणे संवाद साधतात आणि समान कार्यक्षमता ठेवतात आणि समतुल्य वापरकर्ता अनुभव देतात. तथापि, सध्या नोड्सवरील क्लायंटचे वितरण या नेटवर्कच्या मजबुतीकरणाला त्याच्या पूर्ण क्षमतेपर्यंत पोहोचवण्यासाठी पुरेसे समान नाही. आदर्शपणे, वापरकर्त्यांनी नेटवर्कमध्ये शक्य तितकी क्लायंट विविधता आणण्यासाठी विविध क्लायंटमध्ये अंदाजे समान रीतीने विभागले पाहिजे. + +## पूर्वतयारी {#prerequisites} + +तुम्हाला नोड्स आणि क्लायंट काय आहेत हे आधीच माहीत नसल्यास, [नोड्स आणि क्लायंट](/developers/docs/nodes-and-clients/) तपासा. [अंमलबजावणी](/glossary/#execution-layer) आणि [सहमती](/glossary/#consensus-layer) स्तर शब्दकोशात परिभाषित केले आहेत. + +## एकापेक्षा जास्त क्लायंट का आहेत? {#why-multiple-clients} + +एकाधिक, स्वतंत्रपणे विकसित आणि देखरेख केलेले क्लायंट अस्तित्वात आहेत कारण क्लायंट विविधता नेटवर्कला हल्ले आणि बग्ससाठी अधिक लवचिक बनवते. एकाधिक क्लायंट असणे ही Ethereum साठी एक अद्वितीय ताकद आहे - इतर ब्लॉकचेन एकाच क्लायंटच्या अचूकतेवर अवलंबून असतात. तथापि, केवळ एकाधिक क्लायंट उपलब्ध असणे पुरेसे नाही, त्यांना समुदायाद्वारे स्वीकारले जाणे आवश्यक आहे आणि एकूण सक्रिय नोड्स त्यांच्यामध्ये तुलनेने समान रीतीने वितरीत केले पाहिजेत. + +## क्लायंट विविधता का महत्त्वाची आहे? {#client-diversity-importance} + +अनेक स्वतंत्रपणे विकसित आणि देखरेख केलेले क्लायंट असणे विकेंद्रित नेटवर्कच्या आरोग्यासाठी महत्त्वाचे आहे. चला त्यामागील कारणे जाणून घेऊया. + +### बग्स {#bugs} + +एखाद्या वैयक्तिक क्लायंटमधील बग, जेव्हा ते Ethereum नोड्सच्या अल्पसंख्याकांचे प्रतिनिधित्व करते, तेव्हा नेटवर्कसाठी कमी धोकादायक असते. अनेक क्लायंटमध्ये नोड्सच्या अंदाजे समान वितरणासह, बहुतेक क्लायंटना सामायिक समस्येचा सामना करण्याची शक्यता कमी असते आणि परिणामी, नेटवर्क अधिक मजबूत होते. + +### हल्ल्यांना प्रतिरोधक क्षमता {#resilience} + +क्लायंट विविधता हल्ल्यांना प्रतिरोधक क्षमता देखील प्रदान करते. उदाहरणार्थ, एखादा हल्ला जो [एखाद्या विशिष्ट क्लायंटला फसवून](https://twitter.com/vdWijden/status/1437712249926393858) चेनच्या विशिष्ट शाखेवर आणतो, तो यशस्वी होण्याची शक्यता कमी असते कारण इतर क्लायंट त्याच प्रकारे शोषण करण्यायोग्य नसतात आणि कॅनॉनिकल चेन अबाधित राहते. कमी क्लायंट विविधता प्रबळ क्लायंटवरील हॅकशी संबंधित धोका वाढवते. क्लायंट विविधता ही नेटवर्कवरील दुर्भावनापूर्ण हल्ल्यांविरूद्ध एक महत्त्वपूर्ण संरक्षण असल्याचे आधीच सिद्ध झाले आहे, उदाहरणार्थ, 2016 मधील शांघाय डिनायल-ऑफ-सर्व्हिस हल्ला शक्य झाला कारण हल्लेखोर प्रबळ क्लायंटला (Geth) प्रति ब्लॉक हजारो वेळा हळू डिस्क i/o ऑपरेशन कार्यान्वित करण्यासाठी फसवू शकले. कारण पर्यायी क्लायंट देखील ऑनलाइन होते जे असुरक्षितता सामायिक करत नव्हते, Ethereum हल्ल्याचा प्रतिकार करण्यास आणि Geth मधील असुरक्षितता दुरुस्त होईपर्यंत कार्यरत राहण्यास सक्षम होते. + +### प्रूफ-ऑफ-स्टेक अंतिमता {#finality} + +Ethereum नोड्सपैकी 33% पेक्षा जास्त असलेल्या सहमती क्लायंटमधील बग सहमती स्तराला अंतिम होण्यापासून रोखू शकतो, याचा अर्थ वापरकर्ते असा विश्वास ठेवू शकत नाहीत की व्यवहार कधीतरी परत घेतले जाणार नाहीत किंवा बदलले जाणार नाहीत. हे Ethereum वर तयार केलेल्या अनेक ॲप्ससाठी, विशेषतः DeFi साठी खूप समस्याप्रधान असेल. + + याहूनही वाईट, दोन-तृतीयांश बहुमत असलेल्या क्लायंटमधील एक गंभीर बग चेनला चुकीच्या पद्धतीने विभाजित आणि अंतिम करण्यास कारणीभूत ठरू शकतो, ज्यामुळे व्हॅलिडेटर्सचा एक मोठा संच अवैध चेनवर अडकून पडू शकतो. जर त्यांना योग्य चेनमध्ये पुन्हा सामील व्हायचे असेल, तर या व्हॅलिडेटर्सना स्लॅशिंग किंवा हळू आणि महागड्या ऐच्छिक पैसे काढणे आणि पुन्हा सक्रिय करणे याचा सामना करावा लागतो. स्लॅशिंगचे प्रमाण दोषी नोड्सच्या संख्येनुसार वाढते, ज्यात दोन-तृतीयांश बहुमताला जास्तीत जास्त (32 ETH) स्लॅश केले जाते. + +जरी हे अशक्यप्राय प्रसंग असले तरी, Ethereum इको-सिस्टम सक्रिय नोड्सवरील क्लायंटचे वितरण समान करून त्यांचा धोका कमी करू शकते. आदर्शपणे, कोणताही सहमती क्लायंट एकूण नोड्सच्या 33% वाटा कधीही गाठणार नाही. + +### सामायिक जबाबदारी {#responsibility} + +बहुसंख्य क्लायंट असण्याची मानवी किंमत देखील आहे. हे एका लहान विकास टीमवर अतिरिक्त ताण आणि जबाबदारी टाकते. क्लायंट विविधता जितकी कमी असेल, तितकीच बहुसंख्य क्लायंटची देखभाल करणाऱ्या विकासकांवर जबाबदारीचा भार जास्त असतो. ही जबाबदारी अनेक टीममध्ये विभागणे Ethereum च्या नोड्सच्या नेटवर्कच्या आणि त्याच्या लोकांच्या नेटवर्कच्या आरोग्यासाठी चांगले आहे. + +## सध्याची क्लायंट विविधता {#current-client-diversity} + +### अंमलबजावणी क्लायंट {#execution-clients-breakdown} + + + +### सहमती क्लायंट {#consensus-clients-breakdown} + + + +हा आकृती कदाचित जुना असेल — अद्ययावत माहितीसाठी [ethernodes.org](https://ethernodes.org) आणि [clientdiversity.org](https://clientdiversity.org) वर जा. + +वरील दोन पाय चार्ट अंमलबजावणी आणि सहमती स्तरांसाठी सध्याच्या क्लायंट विविधतेचे स्नॅपशॉट दर्शवतात (ऑक्टोबर 2025 मध्ये लिहिण्याच्या वेळी). गेल्या काही वर्षांत क्लायंट विविधता सुधारली आहे, आणि अंमलबजावणी स्तराने [Geth](https://geth.ethereum.org/) च्या वर्चस्वात घट पाहिली आहे, [Nethermind](https://www.nethermind.io/nethermind-client) दुसऱ्या क्रमांकावर, [Besu](https://besu.hyperledger.org/) तिसऱ्या आणि [Erigon](https://github.com/ledgerwatch/erigon) चौथ्या क्रमांकावर आहे, आणि इतर क्लायंट नेटवर्कच्या 3% पेक्षा कमी आहेत. सहमती स्तरावरील सर्वात सामान्यपणे वापरला जाणारा क्लायंट—[Lighthouse](https://lighthouse.sigmaprime.io/)—दुसऱ्या सर्वात जास्त वापरल्या जाणाऱ्या क्लायंटच्या अगदी जवळ आहे. [Prysm](https://prysmaticlabs.com/#projects) आणि [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) अनुक्रमे ~31% आणि ~14% आहेत, आणि इतर क्लायंट क्वचितच वापरले जातात. + +अंमलबजावणी स्तरावरील डेटा [supermajority.info](https://supermajority.info/) वरून 26-Oct-2025 रोजी मिळवला होता. सहमती क्लायंटसाठी डेटा [Michael Sproul](https://github.com/sigp/blockprint) यांच्याकडून मिळवला होता. सहमती क्लायंट डेटा मिळवणे अधिक कठीण आहे कारण सहमती स्तरावरील क्लायंटमध्ये नेहमीच स्पष्ट ट्रेस नसतात ज्याचा वापर त्यांना ओळखण्यासाठी केला जाऊ शकतो. हा डेटा एका वर्गीकरण अल्गोरिदमचा वापर करून तयार केला गेला आहे जो कधीकधी काही अल्पसंख्य क्लायंटमध्ये गोंधळ घालतो (अधिक माहितीसाठी [येथे](https://twitter.com/sproulM_/status/1440512518242197516) पहा). वरील आकृतीत, या संदिग्ध वर्गीकरणांना एक/किंवा लेबल (उदा. Nimbus/Teku) ने दर्शविले आहे. तरीही, हे स्पष्ट आहे की नेटवर्कचा बहुतांश भाग Prysm चालवत आहे. केवळ स्नॅपशॉट असूनही, आकृतीमधील मूल्ये क्लायंट विविधतेच्या सद्यस्थितीची एक चांगली सामान्य कल्पना देतात. + +सहमती स्तरासाठी अद्ययावत क्लायंट विविधता डेटा आता [clientdiversity.org](https://clientdiversity.org/) वर उपलब्ध आहे. + +## अंमलबजावणी स्तर {#execution-layer} + +आतापर्यंत, क्लायंट विविधतेवरील संभाषण प्रामुख्याने सहमती स्तरावर केंद्रित होते. तथापि, अंमलबजावणी क्लायंट [Geth](https://geth.ethereum.org) सध्या सर्व नोड्सपैकी सुमारे 85% आहे. ही टक्केवारी सहमती क्लायंटसाठी असलेल्या त्याच कारणांसाठी समस्याप्रधान आहे. उदाहरणार्थ, Geth मधील एक बग जो व्यवहार हाताळणी किंवा अंमलबजावणी पेलोड्स तयार करण्यावर परिणाम करतो, तो सहमती क्लायंटना समस्याप्रधान किंवा बगयुक्त व्यवहार अंतिम करण्यास प्रवृत्त करू शकतो. म्हणून, अंमलबजावणी क्लायंटच्या अधिक समान वितरणासह Ethereum अधिक निरोगी होईल, आदर्शपणे कोणताही क्लायंट नेटवर्कच्या 33% पेक्षा जास्त प्रतिनिधित्व करणार नाही. + +## अल्पसंख्य क्लायंट वापरा {#use-minority-client} + +क्लायंट विविधतेचे निराकरण करण्यासाठी केवळ वैयक्तिक वापरकर्त्यांनी अल्पसंख्य क्लायंट निवडणे पुरेसे नाही - त्यासाठी व्हॅलिडेटर पूल आणि प्रमुख dapps आणि एक्सचेंज सारख्या संस्थांना देखील क्लायंट बदलण्याची आवश्यकता आहे. तथापि, सर्व वापरकर्ते सध्याचा असमतोल दूर करण्यात आणि सर्व उपलब्ध Ethereum सॉफ्टवेअरचा वापर सामान्य करण्यात आपली भूमिका बजावू शकतात. The Merge नंतर, सर्व नोड ऑपरेटर्सना एक अंमलबजावणी क्लायंट आणि एक सहमती क्लायंट चालवणे आवश्यक असेल. खाली सुचवलेल्या क्लायंटचे संयोजन निवडल्यास क्लायंट विविधता वाढण्यास मदत होईल. + +### एक्झिक्युशन क्लायंट {#execution-clients} + +- [Besu](https://www.hyperledger.org/use/besu) +- [Nethermind](https://downloads.nethermind.io/) +- [Erigon](https://github.com/ledgerwatch/erigon) +- [Go-Ethereum](https://geth.ethereum.org/) +- [Reth](https://reth.rs/) + +### कन्सेंसस क्लायंट {#consensus-clients} + +- [Nimbus](https://nimbus.team/) +- [Lighthouse](https://github.com/sigp/lighthouse) +- [Teku](https://consensys.io/teku) +- [Lodestar](https://github.com/ChainSafe/lodestar) +- [Prysm](https://prysm.offchainlabs.com/docs/) +- [Grandine](https://docs.grandine.io/) + +तांत्रिक वापरकर्ते अल्पसंख्य क्लायंटसाठी अधिक ट्युटोरियल्स आणि डॉक्युमेंटेशन लिहून आणि त्यांच्या नोड-ऑपरेटिंग सहकाऱ्यांना प्रबळ क्लायंटपासून दूर जाण्यासाठी प्रोत्साहित करून ही प्रक्रिया वेगवान करण्यास मदत करू शकतात. अल्पसंख्य सहमती क्लायंटवर स्विच करण्यासाठी मार्गदर्शक [clientdiversity.org](https://clientdiversity.org/) वर उपलब्ध आहेत. + +## क्लायंट विविधता डॅशबोर्ड {#client-diversity-dashboards} + +अनेक डॅशबोर्ड अंमलबजावणी आणि सहमती स्तरासाठी रिअल-टाइम क्लायंट विविधता आकडेवारी देतात. + +**सहमती स्तर:** + +- [Rated.network](https://www.rated.network/) +- [clientdiversity.org](https://clientdiversity.org/) + +**अंमलबजावणी स्तर:** + +- [supermajority.info](https://supermajority.info//) +- [Ethernodes](https://ethernodes.org/) + +## पुढील वाचन {#further-reading} + +- [Ethereum च्या सहमती स्तरावरील क्लायंट विविधता](https://mirror.xyz/jmcook.eth/S7ONEka_0RgtKTZ3-dakPmAHQNPvuj15nh0YGKPFriA) +- [Ethereum Merge: बहुसंख्य क्लायंट तुमच्या स्वतःच्या जोखमीवर चालवा!](https://dankradfeist.de/ethereum/2022/03/24/run-the-majority-client-at-your-own-peril.html) – _Dankrad Fiest, 24 मार्च 2022_ +- [क्लायंट विविधतेचे महत्त्व](https://our.status.im/the-importance-of-client-diversity/) +- [Ethereum नोड सेवांची सूची](https://ethereumnodes.com/) +- [क्लायंट विविधता समस्येचे \"पाच का\"](https://notes.ethereum.org/@afhGjrKfTKmksTOtqhB9RQ/BJGj7uh08) +- [Ethereum विविधता आणि ती कशी सोडवायची (YouTube)](https://www.youtube.com/watch?v=1hZgCaiqwfU) +- [clientdiversity.org](https://clientdiversity.org/) + +## संबंधित विषय {#related-topics} + +- [एक Ethereum नोड चालवा](/run-a-node/) +- [नोड्स आणि क्लायंट](/developers/docs/nodes-and-clients/) diff --git a/public/content/translations/mr/developers/docs/nodes-and-clients/index.md b/public/content/translations/mr/developers/docs/nodes-and-clients/index.md new file mode 100644 index 00000000000..b9173b1e0c6 --- /dev/null +++ b/public/content/translations/mr/developers/docs/nodes-and-clients/index.md @@ -0,0 +1,319 @@ +--- +title: "नोड्स आणि क्लायंट" +description: "Ethereum नोड्स आणि क्लायंट सॉफ्टवेअरचा आढावा, तसेच नोड कसा सेट करायचा आणि तुम्ही ते का करावे." +lang: mr +sidebarDepth: 2 +--- + +Ethereum हे संगणकांचे (नोड्स म्हणून ओळखले जाणारे) एक वितरित नेटवर्क आहे जे सॉफ्टवेअर चालवते जे ब्लॉक्स आणि व्यवहाराच्या डेटाची पडताळणी करू शकते. तुमच्या संगणकाला Ethereum नोडमध्ये रूपांतरित करण्यासाठी हे सॉफ्टवेअर त्यावर चालवणे आवश्यक आहे. नोड तयार करण्यासाठी सॉफ्टवेअरचे दोन स्वतंत्र भाग ('क्लायंट' म्हणून ओळखले जाणारे) आवश्यक आहेत. + +## पूर्वतयारी {#prerequisites} + +Ethereum क्लायंटचे तुमचे स्वतःचे इन्स्टन्स चालवण्यापूर्वी आणि अधिक सखोल अभ्यास करण्यापूर्वी तुम्हाला पीअर-टू-पीअर नेटवर्कची संकल्पना आणि [EVM च्या मूलभूत गोष्टी](/developers/docs/evm/) समजल्या पाहिजेत. आमची [Ethereum ची ओळख](/developers/docs/intro-to-ethereum/) पहा. + +तुम्ही नोड्सच्या विषयासाठी नवीन असाल, तर आम्ही तुम्हाला शिफारस करतो की तुम्ही प्रथम [Ethereum नोड चालवण्यावर](/run-a-node) आमची वापरकर्ता-अनुकूल ओळख तपासा. + +## नोड्स आणि क्लायंट म्हणजे काय? {#what-are-nodes-and-clients} + +"नोड" हे Ethereum क्लायंट सॉफ्टवेअरचे कोणतेही उदाहरण आहे जे Ethereum सॉफ्टवेअर चालवणाऱ्या इतर संगणकांशी जोडलेले असते, ज्यामुळे एक नेटवर्क तयार होते. क्लायंट हे Ethereum चे एक अंमलबजावणी आहे जे प्रोटोकॉल नियमांनुसार डेटाची पडताळणी करते आणि नेटवर्क सुरक्षित ठेवते. एका नोडला दोन क्लायंट चालवावे लागतात: एक कन्सेंसस क्लायंट आणि एक एक्झिक्युशन क्लायंट. + +- एक्झिक्युशन क्लायंट (ज्याला एक्झिक्युशन इंजिन, EL क्लायंट किंवा पूर्वीचे Eth1 क्लायंट म्हणूनही ओळखले जाते) नेटवर्कमध्ये प्रसारित होणाऱ्या नवीन व्यवहारांवर लक्ष ठेवतो, त्यांना EVM मध्ये कार्यान्वित करतो आणि सर्व सद्य Ethereum डेटाची नवीनतम स्थिती आणि डेटाबेस ठेवतो. +- कन्सेंसस क्लायंट (ज्याला बीकन नोड, CL क्लायंट किंवा पूर्वीचा Eth2 क्लायंट असेही म्हणतात) प्रूफ-ऑफ-स्टेक कन्सेंसस अल्गोरिदमची अंमलबजावणी करतो, ज्यामुळे नेटवर्कला एक्झिक्युशन क्लायंटकडून प्रमाणित केलेल्या डेटाच्या आधारे एकमत साधता येते. एक तिसरे सॉफ्टवेअर देखील आहे, ज्याला 'व्हॅलिडेटर' म्हणून ओळखले जाते, जे कन्सेंसस क्लायंटमध्ये जोडले जाऊ शकते, ज्यामुळे नोडला नेटवर्क सुरक्षित करण्यात सहभागी होता येते. + +हे क्लायंट एकत्र काम करून Ethereum चेनच्या हेडचा मागोवा ठेवतात आणि वापरकर्त्यांना Ethereum नेटवर्कशी संवाद साधण्याची परवानगी देतात. एकत्र काम करणाऱ्या सॉफ्टवेअरच्या अनेक भागांच्या या मॉड्युलर डिझाइनला [एनकॅप्स्युलेटेड कॉम्प्लेक्सिटी](https://vitalik.eth.limo/general/2022/02/28/complexity.html) म्हटले जाते. या दृष्टिकोनामुळे [द मर्ज](/roadmap/merge) अखंडपणे कार्यान्वित करणे सोपे झाले, क्लायंट सॉफ्टवेअरची देखभाल आणि विकास सोपा होतो आणि वैयक्तिक क्लायंटचा पुनर्वापर सक्षम होतो, उदाहरणार्थ, [लेयर 2 इकोसिस्टममध्ये](/layer-2/). + +![जोडलेले एक्झिक्युशन आणि कन्सेंसस क्लायंट](./eth1eth2client.png) +जोडलेल्या एक्झिक्युशन आणि कन्सेंसस क्लायंटची सरलीकृत आकृती. + +### क्लायंट विविधता {#client-diversity} + +[एक्झिक्युशन क्लायंट](/developers/docs/nodes-and-clients/#execution-clients) आणि [कन्सेंसस क्लायंट](/developers/docs/nodes-and-clients/#consensus-clients) दोन्ही वेगवेगळ्या संघांनी विकसित केलेल्या विविध प्रोग्रामिंग भाषांमध्ये अस्तित्वात आहेत. + +एकाधिक क्लायंट अंमलबजावणीमुळे नेटवर्क एकाच कोडबेसवरील अवलंबित्व कमी करून अधिक मजबूत होऊ शकते. आदर्श ध्येय हे आहे की कोणताही एक क्लायंट नेटवर्कवर वर्चस्व गाजवणार नाही अशी विविधता प्राप्त करणे, ज्यामुळे अपयशाचा संभाव्य एकच बिंदू नाहीसा होईल. +भाषांमधील विविधता एका व्यापक विकासक समुदायाला आमंत्रित करते आणि त्यांना त्यांच्या पसंतीच्या भाषेत एकत्रीकरण तयार करण्याची परवानगी देते. + +[क्लायंट विविधतेबद्दल](/developers/docs/nodes-and-clients/client-diversity/) अधिक जाणून घ्या. + +या सर्व अंमलबजावणींमध्ये एक गोष्ट समान आहे की त्या सर्व एकाच विनिर्देशाचे पालन करतात. Ethereum नेटवर्क आणि ब्लॉकचेन कसे कार्य करतात हे विनिर्देश ठरवतात. प्रत्येक तांत्रिक तपशील परिभाषित केलेला आहे आणि विनिर्देश खालीलप्रमाणे आढळू शकतात: + +- मूळतः, [Ethereum यलो पेपर](https://ethereum.github.io/yellowpaper/paper.pdf) +- [एक्झिक्युशन स्पेसिफिकेशन्स](https://github.com/ethereum/execution-specs/) +- [कन्सेंसस स्पेसिफिकेशन्स](https://github.com/ethereum/consensus-specs) +- [EIPs](https://eips.ethereum.org/) विविध [नेटवर्क अपग्रेड्स](/ethereum-forks/) मध्ये लागू + +### नेटवर्कमधील नोड्सचा मागोवा घेणे {#network-overview} + +अनेक ट्रॅकर्स Ethereum नेटवर्कमधील नोड्सचा रिअल-टाइम आढावा देतात. लक्षात घ्या की विकेंद्रित नेटवर्कच्या स्वरूपामुळे, हे क्रॉलर्स नेटवर्कचे केवळ मर्यादित दृश्य प्रदान करू शकतात आणि भिन्न परिणाम नोंदवू शकतात. + +- Etherscan द्वारे [नोड्सचा नकाशा](https://etherscan.io/nodetracker) +- Bitfly द्वारे [Ethernodes](https://ethernodes.org/) +- Chainsafe द्वारे [Nodewatch](https://www.nodewatch.io/), कन्सेंसस नोड्स क्रॉल करत आहे +- [Monitoreth](https://monitoreth.io/) - MigaLabs द्वारे, एक वितरित नेटवर्क मॉनिटरिंग साधन +- [साप्ताहिक नेटवर्क आरोग्य अहवाल](https://probelab.io) - ProbeLab द्वारे, [Nebula crawler](https://github.com/dennis-tra/nebula) आणि इतर साधनांचा वापर करून + +## नोडचे प्रकार {#node-types} + +तुम्हाला [तुमचा स्वतःचा नोड चालवायचा असेल](/developers/docs/nodes-and-clients/run-a-node/), तर तुम्हाला हे समजले पाहिजे की नोडचे विविध प्रकार आहेत जे डेटा वेगळ्या प्रकारे वापरतात. खरं तर, क्लायंट तीन वेगवेगळ्या प्रकारचे नोड चालवू शकतात: लाइट, फुल आणि आर्काइव्ह. वेगवेगळ्या सिंक धोरणांचे पर्याय देखील आहेत जे जलद सिंक्रोनाइझेशन वेळ सक्षम करतात. सिंक्रोनाइझेशन म्हणजे Ethereum च्या स्थितीबद्दल सर्वात अद्ययावत माहिती किती लवकर मिळवता येते. + +### फुल नोड {#full-node} + +फुल नोड्स ब्लॉकचेनची ब्लॉक-दर-ब्लॉक पडताळणी करतात, ज्यात प्रत्येक ब्लॉकसाठी ब्लॉक बॉडी आणि स्टेट डेटा डाउनलोड करणे आणि सत्यापित करणे समाविष्ट आहे. फुल नोडचे वेगवेगळे वर्ग आहेत - काही जेनेसिस ब्लॉकपासून सुरुवात करतात आणि ब्लॉकचेनच्या संपूर्ण इतिहासातील प्रत्येक ब्लॉकची पडताळणी करतात. इतर त्यांची पडताळणी अधिक अलीकडील ब्लॉकपासून सुरू करतात ज्यावर ते वैध असल्याचा विश्वास ठेवतात (उदा., Geth चे 'स्नॅप सिंक'). पडताळणी कोठून सुरू होते याची पर्वा न करता, फुल नोड्स फक्त तुलनेने अलीकडील डेटाची स्थानिक प्रत ठेवतात (साधारणपणे सर्वात अलीकडील 128 ब्लॉक्स), ज्यामुळे डिस्कची जागा वाचवण्यासाठी जुना डेटा हटवता येतो. आवश्यकतेनुसार जुना डेटा पुन्हा तयार केला जाऊ शकतो. + +- संपूर्ण ब्लॉकचेन डेटा संग्रहित करतो (जरी हा डेटा वेळोवेळी छाटला जातो, त्यामुळे फुल नोड जेनेसिसपासूनचा सर्व स्टेट डेटा संग्रहित करत नाही) +- ब्लॉक पडताळणीत भाग घेतो, सर्व ब्लॉक्स आणि स्टेट्सची पडताळणी करतो. +- सर्व स्टेट्स एकतर स्थानिक स्टोरेजमधून मिळवता येतात किंवा फुल नोडद्वारे 'स्नॅपशॉट्स'मधून पुन्हा तयार करता येतात. +- नेटवर्कला सेवा देतो आणि विनंतीनुसार डेटा प्रदान करतो. + +### आर्काइव्ह नोड {#archive-node} + +आर्काइव्ह नोड्स हे फुल नोड्स आहेत जे जेनेसिसपासून प्रत्येक ब्लॉकची पडताळणी करतात आणि डाउनलोड केलेला कोणताही डेटा कधीही हटवत नाहीत. + +- फुल नोडमध्ये ठेवलेल्या सर्व गोष्टी संग्रहित करतो आणि ऐतिहासिक स्टेट्सचे आर्काइव्ह तयार करतो. जर तुम्हाला ब्लॉक #4,000,000 वरील खात्यातील शिल्लक यासारख्या गोष्टींची चौकशी करायची असेल किंवा ट्रेसिंग वापरून तुमच्या स्वतःच्या व्यवहारांच्या सेटची पडताळणी न करता फक्त आणि विश्वसनीयरित्या चाचणी करायची असेल तर याची आवश्यकता आहे. +- हा डेटा टेराबाइट्सच्या युनिट्समध्ये असतो, ज्यामुळे आर्काइव्ह नोड्स सामान्य वापरकर्त्यांसाठी कमी आकर्षक ठरतात, परंतु ब्लॉक एक्सप्लोरर्स, वॉलेट विक्रेते आणि चेन अॅनालिटिक्स यांसारख्या सेवांसाठी ते उपयुक्त ठरू शकतात. + +आर्काइव्ह व्यतिरिक्त इतर कोणत्याही मोडमध्ये क्लायंट सिंक केल्याने ब्लॉकचेन डेटा छाटला जाईल. याचा अर्थ, सर्व ऐतिहासिक स्टेट्सचे कोणतेही आर्काइव्ह नसते, परंतु फुल नोड गरजेनुसार ते तयार करू शकतो. + +[आर्काइव्ह नोड्सबद्दल](/developers/docs/nodes-and-clients/archive-nodes) अधिक जाणून घ्या. + +### लाइट नोड {#light-node} + +प्रत्येक ब्लॉक डाउनलोड करण्याऐवजी, लाइट नोड्स फक्त ब्लॉक हेडर्स डाउनलोड करतात. या हेडर्समध्ये ब्लॉक्सच्या सामग्रीबद्दल सारांश माहिती असते. लाइट नोडला आवश्यक असलेली इतर कोणतीही माहिती फुल नोडकडून मागवली जाते. लाइट नोड त्यानंतर ब्लॉक हेडर्समधील स्टेट रूट्सच्या आधारावर त्यांना मिळालेल्या डेटाची स्वतंत्रपणे पडताळणी करू शकतो. लाइट नोड्स वापरकर्त्यांना फुल नोड्स चालवण्यासाठी आवश्यक असलेल्या शक्तिशाली हार्डवेअर किंवा उच्च बँडविड्थशिवाय Ethereum नेटवर्कमध्ये सहभागी होण्यास सक्षम करतात. अखेरीस, लाइट नोड्स मोबाईल फोन किंवा एम्बेडेड उपकरणांवर चालवता येतील. लाइट नोड्स कन्सेंससमध्ये सहभागी होत नाहीत (म्हणजे, ते व्हॅलिडेटर असू शकत नाहीत), परंतु ते फुल नोड प्रमाणेच समान कार्यक्षमता आणि सुरक्षा हमीसह Ethereum ब्लॉकचेनमध्ये प्रवेश करू शकतात. + +लाइट क्लायंट हे Ethereum साठी सक्रिय विकासाचे क्षेत्र आहे आणि आम्ही लवकरच कन्सेंसस लेयर आणि एक्झिक्युशन लेयरसाठी नवीन लाइट क्लायंट पाहण्याची अपेक्षा करतो. +[गॉसिप नेटवर्क](https://www.ethportal.net/) वरून लाइट क्लायंट डेटा प्रदान करण्याचे संभाव्य मार्ग देखील आहेत. हे फायदेशीर आहे कारण गॉसिप नेटवर्क विनंत्या पूर्ण करण्यासाठी फुल नोड्सची आवश्यकता न ठेवता लाइट नोड्सच्या नेटवर्कला समर्थन देऊ शकते. + +Ethereum अद्याप मोठ्या संख्येने लाइट नोड्सना समर्थन देत नाही, परंतु लाइट नोड समर्थन हे एक क्षेत्र आहे जे नजीकच्या भविष्यात वेगाने विकसित होण्याची अपेक्षा आहे. विशेषतः, [Nimbus](https://nimbus.team/), [Helios](https://github.com/a16z/helios), आणि [LodeStar](https://lodestar.chainsafe.io/) सारखे क्लायंट सध्या लाइट नोड्सवर जास्त लक्ष केंद्रित करत आहेत. + +## मी Ethereum नोड का चालवावा? {#why-should-i-run-an-ethereum-node} + +नोड चालवण्यामुळे तुम्हाला Ethereum थेट, विश्वासहीनपणे आणि खाजगीरित्या वापरता येतो, तसेच नेटवर्कला अधिक मजबूत आणि विकेंद्रित ठेवून त्याला समर्थन देता येते. + +### तुमच्यासाठी फायदे {#benefits-to-you} + +तुमचा स्वतःचा नोड चालवल्याने तुम्हाला Ethereum खाजगी, स्वयंपूर्ण आणि विश्वासहीन पद्धतीने वापरता येते. तुम्हाला नेटवर्कवर विश्वास ठेवण्याची गरज नाही कारण तुम्ही तुमच्या क्लायंटद्वारे डेटा स्वतःच सत्यापित करू शकता. "विश्वास ठेवू नका, पडताळणी करा" हा एक लोकप्रिय ब्लॉकचेन मंत्र आहे. + +- तुमचा नोड सर्व व्यवहार आणि ब्लॉक्सची पडताळणी कन्सेंसस नियमांनुसार स्वतःच करतो. याचा अर्थ असा की तुम्हाला नेटवर्कमधील इतर कोणत्याही नोडवर अवलंबून राहण्याची किंवा त्यांच्यावर पूर्णपणे विश्वास ठेवण्याची आवश्यकता नाही. +- तुम्ही तुमच्या स्वतःच्या नोडसह Ethereum वॉलेट वापरू शकता. तुम्ही dapps अधिक सुरक्षितपणे आणि खाजगीरित्या वापरू शकता कारण तुम्हाला तुमचे पत्ते आणि शिल्लक मध्यस्थांना लीक करण्याची आवश्यकता नाही. सर्व काही तुमच्या स्वतःच्या क्लायंटने तपासले जाऊ शकते. [MetaMask](https://metamask.io), [Frame](https://frame.sh/), आणि [इतर अनेक वॉलेट्स](/wallets/find-wallet/) RPC-इम्पोर्टिंगची सुविधा देतात, ज्यामुळे त्यांना तुमचा नोड वापरता येतो. +- तुम्ही Ethereum मधील डेटावर अवलंबून असलेल्या इतर सेवा चालवू आणि स्वयं-होस्ट करू शकता. उदाहरणार्थ, हे बीकन चेन व्हॅलिडेटर, लेयर 2 सारखे सॉफ्टवेअर, पायाभूत सुविधा, ब्लॉक एक्सप्लोरर, पेमेंट प्रोसेसर इत्यादी असू शकते. +- तुम्ही तुमचे स्वतःचे सानुकूल [RPC एंडपॉइंट](/developers/docs/apis/json-rpc/) प्रदान करू शकता. तुम्ही मोठ्या केंद्रीकृत प्रदात्यांना टाळण्यास मदत करण्यासाठी समुदायाला हे एंडपॉइंट्स सार्वजनिकरित्या देऊ शकता. +- तुम्ही **इंटर-प्रोसेस कम्युनिकेशन्स (IPC)** वापरून तुमच्या नोडशी कनेक्ट होऊ शकता किंवा तुमचा प्रोग्राम प्लगइन म्हणून लोड करण्यासाठी नोड पुन्हा लिहू शकता. हे कमी विलंबता प्रदान करते, जे वेब3 लायब्ररी वापरून बरेच डेटा प्रक्रिया करताना किंवा जेव्हा आपल्याला शक्य तितक्या लवकर आपले व्यवहार पुनर्स्थित करण्याची आवश्यकता असते (उदा. फ्रंटरनिंग) तेव्हा खूप मदत करते. +- तुम्ही नेटवर्क सुरक्षित करण्यासाठी आणि बक्षिसे मिळवण्यासाठी थेट ETH स्टेक करू शकता. प्रारंभ करण्यासाठी [सोलो स्टेकिंग](/staking/solo/) पहा. + +![तुमच्या ॲप्लिकेशन आणि नोड्सद्वारे तुम्ही Ethereum मध्ये कसे प्रवेश करता](./nodes.png) + +### नेटवर्क फायदे {#network-benefits} + +Ethereum च्या आरोग्यासाठी, सुरक्षेसाठी आणि कार्यान्वयन लवचिकतेसाठी नोड्सचा एक वैविध्यपूर्ण संच महत्त्वाचा आहे. + +- फुल नोड्स कन्सेंसस नियमांची अंमलबजावणी करतात जेणेकरून त्यांना नियमांचे पालन न करणाऱ्या ब्लॉक्सना स्वीकारण्यासाठी फसवता येणार नाही. हे नेटवर्कमध्ये अतिरिक्त सुरक्षा प्रदान करते कारण जर सर्व नोड्स लाइट नोड्स असते, जे पूर्ण पडताळणी करत नाहीत, तर व्हॅलिडेटर्स नेटवर्कवर हल्ला करू शकले असते. +- [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos/#what-is-pos) च्या क्रिप्टो-इकॉनॉमिक संरक्षणावर मात करणाऱ्या हल्ल्याच्या बाबतीत, प्रामाणिक चेनचे अनुसरण करणे निवडून फुल नोड्सद्वारे सामाजिक पुनर्प्राप्ती केली जाऊ शकते. +- नेटवर्कमधील अधिक नोड्समुळे अधिक वैविध्यपूर्ण आणि मजबूत नेटवर्क तयार होते, जे विकेंद्रीकरणाचे अंतिम ध्येय आहे, जे सेन्सॉरशिप-प्रतिरोधक आणि विश्वासार्ह प्रणाली सक्षम करते. +- फुल नोड्स त्यांच्यावर अवलंबून असलेल्या हलक्या क्लायंटसाठी ब्लॉकचेन डेटामध्ये प्रवेश प्रदान करतात. लाइट नोड्स संपूर्ण ब्लॉकचेन संग्रहित करत नाहीत, त्याऐवजी ते [ब्लॉक हेडर्समधील स्टेट रूट्स](/developers/docs/blocks/#block-anatomy) द्वारे डेटाची पडताळणी करतात. त्यांना आवश्यक असल्यास ते फुल नोड्सकडून अधिक माहितीची विनंती करू शकतात. + +तुम्ही व्हॅलिडेटर चालवत नसला तरीही, तुम्ही फुल नोड चालवल्यास संपूर्ण Ethereum नेटवर्कला त्याचा फायदा होतो. + +## तुमचा स्वतःचा नोड चालवणे {#running-your-own-node} + +तुमचा स्वतःचा Ethereum क्लायंट चालविण्यात स्वारस्य आहे का? + +नवशिक्यांसाठी सोप्या परिचयासाठी, अधिक जाणून घेण्यासाठी आमच्या [नोड चालवा](/run-a-node) पृष्ठास भेट द्या. + +तुम्ही अधिक तांत्रिक वापरकर्ते असल्यास, [तुमचा स्वतःचा नोड कसा सुरू करायचा](/developers/docs/nodes-and-clients/run-a-node/) याबद्दल अधिक तपशील आणि पर्यायांमध्ये सखोल जा. + +## पर्याय {#alternatives} + +तुमचा स्वतःचा नोड सेट करण्यासाठी तुम्हाला वेळ आणि संसाधने लागू शकतात परंतु तुम्हाला नेहमीच तुमचे स्वतःचे उदाहरण चालवण्याची गरज नसते. या प्रकरणात, आपण तृतीय-पक्ष API प्रदाता वापरू शकता. या सेवा वापरण्याच्या विहंगावलोकनासाठी, [सेवा म्हणून नोड्स](/developers/docs/nodes-and-clients/nodes-as-a-service/) पहा. + +जर कोणी तुमच्या समुदायात सार्वजनिक API सह Ethereum नोड चालवत असेल, तर तुम्ही तुमच्या वॉलेट्सना कस्टम RPC द्वारे समुदाय नोडकडे निर्देशित करू शकता आणि काही यादृच्छिक विश्वासू तृतीय पक्षापेक्षा अधिक गोपनीयता मिळवू शकता. + +दुसरीकडे, जर तुम्ही क्लायंट चालवत असाल, तर तुम्ही तो तुमच्या मित्रांना शेअर करू शकता ज्यांना त्याची गरज असेल. + +## एक्झिक्युशन क्लायंट {#execution-clients} + +Ethereum समुदाय एकाधिक ओपन-सोर्स एक्झिक्युशन क्लायंट्स (पूर्वी 'Eth1 क्लायंट्स' किंवा फक्त 'Ethereum क्लायंट्स' म्हणून ओळखले जाणारे) सांभाळतो, जे वेगवेगळ्या टीम्सनी वेगवेगळ्या प्रोग्रामिंग भाषा वापरून विकसित केले आहेत. हे नेटवर्कला अधिक मजबूत आणि अधिक [विविध](/developers/docs/nodes-and-clients/client-diversity/) बनवते. आदर्श ध्येय हे आहे की अपयशाचा कोणताही एकच बिंदू कमी करण्यासाठी कोणताही क्लायंट वर्चस्व गाजवणार नाही अशी विविधता प्राप्त करणे. + +हा तक्ता वेगवेगळ्या क्लायंटचा सारांश देतो. ते सर्व [क्लायंट चाचण्या](https://github.com/ethereum/tests) पास करतात आणि नेटवर्क अपग्रेडसह अद्ययावत राहण्यासाठी सक्रियपणे देखरेख केली जाते. + +| क्लायंट | भाषा | ऑपरेटिंग सिस्टीम | नेटवर्क | सिंक स्ट्रॅटेजीज | स्टेट प्रूनिंग | +| ------------------------------------------------------------------------------------------- | ------------------------ | --------------------- | ---------------------- | ------------------------------------------------------------------------------ | ------------------ | +| [Geth](https://geth.ethereum.org/) | Go | Linux, Windows, macOS | मेननेट, सेपोलिया, हूडी | [स्नॅप](#snap-sync), [फुल](#full-sync) | आर्काइव्ह, प्रुन्ड | +| [Nethermind](https://www.nethermind.io/) | C#, .NET | Linux, Windows, macOS | मेननेट, सेपोलिया, हूडी | [स्नॅप](#snap-sync) (सेवा न देता), फास्ट, [फुल](#full-sync) | आर्काइव्ह, प्रुन्ड | +| [Besu](https://besu.hyperledger.org/en/stable/) | Java | Linux, Windows, macOS | मेननेट, सेपोलिया, हूडी | [स्नॅप](#snap-sync), [फास्ट](#fast-sync), [फुल](#full-sync) | आर्काइव्ह, प्रुन्ड | +| [Erigon](https://github.com/ledgerwatch/erigon) | Go | Linux, Windows, macOS | मेननेट, सेपोलिया, हूडी | [फुल](#full-sync) | आर्काइव्ह, प्रुन्ड | +| [Reth](https://reth.rs/) | Rust | Linux, Windows, macOS | मेननेट, सेपोलिया, हूडी | [फुल](#full-sync) | आर्काइव्ह, प्रुन्ड | +| [EthereumJS](https://github.com/ethereumjs/ethereumjs-monorepo) _(बीटा)_ | TypeScript | Linux, Windows, macOS | सेपोलिया, हूडी | [फुल](#full-sync) | प्रुन्ड | + +समर्थित नेटवर्कवर अधिक माहितीसाठी, [Ethereum नेटवर्क्स](/developers/docs/networks/) वर वाचा. + +प्रत्येक क्लायंटचे स्वतःचे अनन्य उपयोग आणि फायदे आहेत, त्यामुळे तुम्ही तुमच्या स्वतःच्या आवडीनुसार एक निवडले पाहिजे. विविधता अंमलबजावणींना वेगवेगळ्या वैशिष्ट्यांवर आणि वापरकर्त्यांच्या प्रेक्षकांवर लक्ष केंद्रित करण्यास अनुमती देते. तुम्ही वैशिष्ट्ये, समर्थन, प्रोग्रामिंग भाषा किंवा परवान्यांवर आधारित क्लायंट निवडू शकता. + +### Besu {#besu} + +हायपरलेजर Besu हा सार्वजनिक आणि परवानगी असलेल्या नेटवर्क्ससाठी एक एंटरप्राइज-ग्रेड Ethereum क्लायंट आहे. हे ट्रेसिंगपासून GraphQL पर्यंत सर्व Ethereum मेननेट वैशिष्ट्ये चालवते, त्यात विस्तृत देखरेख आहे आणि ConsenSys द्वारे, मुक्त समुदाय चॅनेलमध्ये आणि एंटरप्राइझसाठी व्यावसायिक SLA द्वारे समर्थित आहे. हे Java मध्ये लिहिलेले आहे आणि Apache 2.0 परवानाकृत आहे. + +Besu चे विस्तृत [दस्तऐवजीकरण](https://besu.hyperledger.org/en/stable/) तुम्हाला त्याच्या वैशिष्ट्यांबद्दल आणि सेटअपबद्दल सर्व तपशीलांमध्ये मार्गदर्शन करेल. + +### Erigon {#erigon} + +Erigon, पूर्वी Turbo-Geth म्हणून ओळखले जात असे, Go Ethereum च्या फोर्क म्हणून सुरू झाले जे गती आणि डिस्क-स्पेस कार्यक्षमतेवर केंद्रित होते. Erigon हे Ethereum चे पूर्णपणे पुनर्रचित केलेले अंमलबजावणी आहे, जे सध्या Go मध्ये लिहिलेले आहे परंतु इतर भाषांमध्ये अंमलबजावणी विकासाधीन आहे. Erigon चे ध्येय Ethereum ची जलद, अधिक मॉड्युलर आणि अधिक ऑप्टिमाइझ केलेली अंमलबजावणी प्रदान करणे आहे. हे सुमारे 2TB डिस्क स्पेस वापरून 3 दिवसांपेक्षा कमी वेळेत पूर्ण आर्काइव्ह नोड सिंक करू शकते. + +### Go Ethereum {#geth} + +Go Ethereum (थोडक्यात Geth) हे Ethereum प्रोटोकॉलच्या मूळ अंमलबजावणींपैकी एक आहे. सध्या, हे सर्वात व्यापक क्लायंट आहे ज्यात वापरकर्ते आणि विकासकांसाठी सर्वात मोठा वापरकर्ता आधार आणि विविध प्रकारची साधने आहेत. हे Go मध्ये लिहिलेले आहे, पूर्णपणे ओपन सोर्स आहे आणि GNU LGPL v3 अंतर्गत परवानाकृत आहे. + +Geth बद्दल त्याच्या [दस्तऐवजीकरण](https://geth.ethereum.org/docs/) मध्ये अधिक जाणून घ्या. + +### Nethermind {#nethermind} + +Nethermind हे C# .NET टेक स्टॅकसह तयार केलेले Ethereum अंमलबजावणी आहे, जे LGPL-3.0 सह परवानाकृत आहे, ARM सह सर्व प्रमुख प्लॅटफॉर्मवर चालते. हे यासह उत्कृष्ट कार्यप्रदर्शन देते: + +- एक ऑप्टिमाइझ केलेले व्हर्च्युअल मशीन +- स्टेट ऍक्सेस +- नेटवर्किंग आणि Prometheus/Grafana डॅशबोर्ड, seq एंटरप्राइझ लॉगिंग समर्थन, JSON-RPC ट्रेसिंग, आणि विश्लेषण प्लगइन यांसारख्या समृद्ध वैशिष्ट्ये. + +Nethermind कडे [तपशीलवार दस्तऐवजीकरण](https://docs.nethermind.io), मजबूत डेव्हलपर समर्थन, एक ऑनलाइन समुदाय आणि प्रीमियम वापरकर्त्यांसाठी 24/7 समर्थन देखील उपलब्ध आहे. + +### Reth {#reth} + +Reth (Rust Ethereum चे संक्षिप्त रूप) हे एक Ethereum फुल नोड अंमलबजावणी आहे जे वापरकर्ता-अनुकूल, अत्यंत मॉड्युलर, जलद आणि कार्यक्षम असण्यावर लक्ष केंद्रित करते. Reth मूळतः Paradigm द्वारे तयार केले गेले आणि पुढे नेले गेले आणि ते Apache आणि MIT परवान्यांतर्गत परवानाकृत आहे. + +Reth उत्पादनासाठी तयार आहे आणि स्टेकिंग किंवा उच्च-अपटाइम सेवांसारख्या मिशन-क्रिटिकल वातावरणात वापरासाठी योग्य आहे. RPC, MEV, इंडेक्सिंग, सिम्युलेशन आणि P2P क्रियाकलाप यांसारख्या उच्च कार्यक्षमतेची आवश्यकता असलेल्या वापराच्या प्रकरणांमध्ये चांगला परफाॅरमन्स देते. + +[Reth बुक](https://reth.rs/) किंवा [Reth GitHub repo](https://github.com/paradigmxyz/reth?tab=readme-ov-file#reth) तपासून अधिक जाणून घ्या. + +### विकासात {#execution-in-development} + +हे क्लायंट अजूनही विकासाच्या सुरुवातीच्या टप्प्यात आहेत आणि अद्याप उत्पादन वापरासाठी शिफारस केलेले नाहीत. + +#### EthereumJS {#ethereumjs} + +EthereumJS एक्झिक्युशन क्लायंट (EthereumJS) TypeScript मध्ये लिहिलेला आहे आणि अनेक पॅकेजेसनी बनलेला आहे, ज्यात ब्लॉक, व्यवहार आणि मर्क्ल-पॅट्रिशिया ट्री क्लासेसद्वारे दर्शविलेले मूळ Ethereum आदिम आणि Ethereum व्हर्च्युअल मशीन (EVM) चे अंमलबजावणी, एक ब्लॉकचेन क्लास आणि DevP2P नेटवर्किंग स्टॅकसह मूळ क्लायंट घटक समाविष्ट आहेत. + +त्याच्या [दस्तऐवजीकरण](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master) वाचून त्याबद्दल अधिक जाणून घ्या + +## कन्सेंसस क्लायंट {#consensus-clients} + +[कन्सेंसस अपग्रेड](/roadmap/beacon-chain/) ला समर्थन देण्यासाठी एकाधिक कन्सेंसस क्लायंट (पूर्वी 'Eth2' क्लायंट म्हणून ओळखले जाणारे) आहेत. ते फोर्क-चॉइस अल्गोरिदम, प्रमाणीकरणांवर प्रक्रिया करणे आणि [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos) पुरस्कार आणि दंड व्यवस्थापित करण्यासह सर्व कन्सेंसस-संबंधित तर्कासाठी जबाबदार आहेत. + +| क्लायंट | भाषा | ऑपरेटिंग सिस्टीम | नेटवर्क | +| ------------------------------------------------------------- | ---------- | --------------------- | --------------------------------------------------------- | +| [Lighthouse](https://lighthouse.sigmaprime.io/) | Rust | Linux, Windows, macOS | बीकन चेन, हूडी, पिरमाँट, सेपोलिया, आणि बरेच काही | +| [Lodestar](https://lodestar.chainsafe.io/) | TypeScript | Linux, Windows, macOS | बीकन चेन, हूडी, सेपोलिया, आणि बरेच काही | +| [Nimbus](https://nimbus.team/) | Nim | Linux, Windows, macOS | बीकन चेन, हूडी, सेपोलिया, आणि बरेच काही | +| [Prysm](https://prysm.offchainlabs.com/docs/) | Go | Linux, Windows, macOS | बीकन चेन, ग्नोसिस, हूडी, पिरमाँट, सेपोलिया, आणि बरेच काही | +| [Teku](https://consensys.net/knowledge-base/ethereum-2/teku/) | Java | Linux, Windows, macOS | बीकन चेन, ग्नोसिस, हूडी, सेपोलिया, आणि बरेच काही | +| [Grandine](https://docs.grandine.io/) | Rust | Linux, Windows, macOS | बीकन चेन, हूडी, सेपोलिया, आणि बरेच काही | + +### Lighthouse {#lighthouse} + +Lighthouse हे Rust मध्ये Apache-2.0 परवान्याअंतर्गत लिहिलेले एक कन्सेंसस क्लायंट अंमलबजावणी आहे. हे सिग्मा प्राइम द्वारे सांभाळले जाते आणि बीकन चेन जेनेसिसपासून स्थिर आणि उत्पादनासाठी तयार आहे. विविध उपक्रम, स्टेकिंग पूल आणि व्यक्ती त्यावर अवलंबून आहेत. हे डेस्कटॉप पीसीपासून ते अत्याधुनिक स्वयंचलित उपयोजनांपर्यंतच्या विस्तृत वातावरणात सुरक्षित, कार्यक्षम आणि आंतर-कार्यक्षम असण्याचे उद्दिष्ट ठेवते. + +दस्तऐवजीकरण [लाइटहाऊस बुक](https://lighthouse-book.sigmaprime.io/) मध्ये आढळू शकते + +### Lodestar {#lodestar} + +लोडस्टार हे Typescript मध्ये LGPL-3.0 परवान्याअंतर्गत लिहिलेले एक उत्पादन-तयार कन्सेंसस क्लायंट अंमलबजावणी आहे. हे चेनसेफ सिस्टीम्सद्वारे सांभाळले जाते आणि सोलो-स्टेकर्स, डेव्हलपर्स आणि संशोधकांसाठी कन्सेंसस क्लायंटमधील सर्वात नवीन आहे. लोडस्टारमध्ये बीकन नोड आणि व्हॅलिडेटर क्लायंटचा समावेश आहे जे Ethereum प्रोटोकॉलच्या JavaScript अंमलबजावणीद्वारे समर्थित आहेत. लोडस्टारचे उद्दिष्ट लाइट क्लायंटसह Ethereum उपयोगिता सुधारणे, विकसकांच्या मोठ्या गटासाठी सुलभता वाढवणे आणि इकोसिस्टम विविधतेमध्ये अधिक योगदान देणे हे आहे. + +अधिक माहिती [लोडस्टार वेबसाइट](https://lodestar.chainsafe.io/) वर आढळू शकते + +### Nimbus {#nimbus} + +निंबस हे निममध्ये Apache-2.0 परवान्याअंतर्गत लिहिलेले एक कन्सेंसस क्लायंट अंमलबजावणी आहे. हा एक उत्पादन-तयार क्लायंट आहे जो सोलो-स्टेकर्स आणि स्टेकिंग पूलद्वारे वापरला जातो. निंबस संसाधनांच्या कार्यक्षमतेसाठी डिझाइन केलेले आहे, ज्यामुळे ते संसाधन-प्रतिबंधित उपकरणांवर आणि एंटरप्राइझ इन्फ्रास्ट्रक्चरवर समान सहजतेने चालवणे सोपे होते, स्थिरता किंवा बक्षीस कार्यक्षमतेशी तडजोड न करता. हलक्या संसाधनांच्या पदचिन्हाचा अर्थ असा आहे की नेटवर्क तणावाखाली असताना क्लायंटला सुरक्षिततेचा अधिक मार्जिन असतो. + +[निंबस डॉक्स](https://nimbus.guide/) मध्ये अधिक जाणून घ्या + +### Prysm {#prysm} + +Prysm हे GPL-3.0 परवान्याअंतर्गत Go मध्ये लिहिलेले एक पूर्ण-वैशिष्ट्यीकृत, ओपन सोर्स कन्सेंसस क्लायंट आहे. यात एक पर्यायी वेबॲप UI आहे आणि घरातून स्टेक करणाऱ्या आणि संस्थात्मक वापरकर्त्यांसाठी वापरकर्ता अनुभव, दस्तऐवजीकरण आणि कॉन्फिगरिबिलिटीला प्राधान्य देते. + +अधिक जाणून घेण्यासाठी [Prysm डॉक्स](https://prysm.offchainlabs.com/docs/) ला भेट द्या. + +### Teku {#teku} + +Teku हे मूळ बीकन चेन जेनेसिस क्लायंटपैकी एक आहे. नेहमीच्या उद्दिष्टांसोबतच (सुरक्षा, मजबुती, स्थिरता, उपयोगिता, कार्यक्षमता), Teku विशेषतः सर्व विविध कन्सेंसस क्लायंट मानकांचे पूर्णपणे पालन करण्याचे उद्दिष्ट ठेवते. + +Teku खूप लवचिक उपयोजन पर्याय देते. बीकन नोड आणि व्हॅलिडेटर क्लायंट एकत्र एकाच प्रक्रियेत चालवले जाऊ शकतात, जे सोलो स्टेकर्ससाठी अत्यंत सोयीचे आहे, किंवा अत्याधुनिक स्टेकिंग ऑपरेशन्ससाठी नोड्स स्वतंत्रपणे चालवले जाऊ शकतात. याव्यतिरिक्त, Teku की सुरक्षा आणि स्लॅशिंग संरक्षणासाठी [Web3Signer](https://github.com/ConsenSys/web3signer/) सह पूर्णपणे आंतर-कार्यक्षम आहे. + +Teku Java मध्ये लिहिलेले आहे आणि Apache 2.0 परवानाकृत आहे. हे ConsenSys मधील प्रोटोकॉल टीमद्वारे विकसित केले आहे जे Besu आणि Web3Signer साठी देखील जबाबदार आहे. [Teku डॉक्स](https://docs.teku.consensys.net/en/latest/) मध्ये अधिक जाणून घ्या. + +### Grandine {#grandine} + +Grandine हे Rust मध्ये GPL-3.0 परवान्याअंतर्गत लिहिलेले एक कन्सेंसस क्लायंट अंमलबजावणी आहे. हे Grandine कोअर टीमद्वारे सांभाळले जाते आणि ते जलद, उच्च-कार्यक्षम आणि हलके आहे. हे रास्पबेरी पाय सारख्या कमी-संसाधन उपकरणांवर चालणाऱ्या सोलो स्टेकर्सपासून ते हजारो व्हॅलिडेटर्स चालवणाऱ्या मोठ्या संस्थात्मक स्टेकर्सपर्यंतच्या विस्तृत स्टेकर्ससाठी योग्य आहे. + +दस्तऐवजीकरण [Grandine Book](https://docs.grandine.io/) मध्ये आढळू शकते + +## सिंक्रोनाइझेशन मोड {#sync-modes} + +नेटवर्कमधील सद्य डेटाचे अनुसरण आणि पडताळणी करण्यासाठी, Ethereum क्लायंटला नवीनतम नेटवर्क स्थितीसह सिंक करणे आवश्यक आहे. हे पीअर्सकडून डेटा डाउनलोड करून, त्यांच्या अखंडतेची क्रिप्टोग्राफिकरित्या पडताळणी करून आणि स्थानिक ब्लॉकचेन डेटाबेस तयार करून केले जाते. + +सिंक्रोनाइझेशन मोड्स या प्रक्रियेसाठी विविध ट्रेड-ऑफसह भिन्न दृष्टिकोन दर्शवतात. क्लायंट त्यांच्या सिंक अल्गोरिदमच्या अंमलबजावणीमध्ये देखील भिन्न आहेत. अंमलबजावणीवरील तपशीलांसाठी नेहमी तुमच्या निवडलेल्या क्लायंटच्या अधिकृत दस्तऐवजीकरणाचा संदर्भ घ्या. + +### एक्झिक्युशन लेयर सिंक मोड्स {#execution-layer-sync-modes} + +एक्झिक्युशन लेयर वेगवेगळ्या वापराच्या प्रकरणांसाठी वेगवेगळ्या मोड्समध्ये चालवले जाऊ शकते, ब्लॉकचेनच्या जागतिक स्थितीची पुन्हा-अंमलबजावणी करण्यापासून ते विश्वसनीय चेकपॉइंटवरून केवळ चेनच्या टोकाशी सिंक करण्यापर्यंत. + +#### फुल सिंक {#full-sync} + +एक फुल सिंक सर्व ब्लॉक्स (हेडर्स आणि ब्लॉक बॉडीसह) डाउनलोड करतो आणि जेनेसिसपासून प्रत्येक ब्लॉक कार्यान्वित करून ब्लॉकचेनची स्थिती वाढीवपणे पुन्हा तयार करतो. + +- प्रत्येक व्यवहाराची पडताळणी करून विश्वास कमी करते आणि सर्वोच्च सुरक्षा देते. +- वाढत्या व्यवहारांच्या संख्येमुळे, सर्व व्यवहारांवर प्रक्रिया करण्यासाठी दिवस ते आठवडे लागू शकतात. + +[आर्काइव्ह नोड्स](#archive-node) प्रत्येक ब्लॉकमधील प्रत्येक व्यवहाराद्वारे केलेल्या स्थिती बदलांचा संपूर्ण इतिहास तयार करण्यासाठी (आणि टिकवून ठेवण्यासाठी) पूर्ण सिंक करतात. + +#### फास्ट सिंक {#fast-sync} + +फुल सिंकप्रमाणे, फास्ट सिंक सर्व ब्लॉक्स (हेडर्स, व्यवहार आणि पावत्यांसह) डाउनलोड करतो. तथापि, ऐतिहासिक व्यवहारांवर पुन्हा प्रक्रिया करण्याऐवजी, फास्ट सिंक अलीकडील हेडपर्यंत पोहोचेपर्यंत पावत्यांवर अवलंबून असतो, त्यानंतर तो पूर्ण नोड प्रदान करण्यासाठी ब्लॉक्स इम्पोर्ट करणे आणि प्रक्रिया करणे सुरू करतो. + +- फास्ट सिंक स्ट्रॅटेजी. +- बँडविड्थ वापराच्या बाजूने प्रक्रिया मागणी कमी करते. + +#### स्नॅप सिंक {#snap-sync} + +स्नॅप सिंक देखील चेनची ब्लॉक-दर-ब्लॉक पडताळणी करतात. तथापि, जेनेसिस ब्लॉकपासून सुरुवात करण्याऐवजी, स्नॅप सिंक अधिक अलीकडील 'विश्वसनीय' चेकपॉइंटपासून सुरू होतो जो खऱ्या ब्लॉकचेनचा भाग असल्याचे ओळखले जाते. नोड ठराविक वयापेक्षा जुना डेटा हटवताना नियतकालिक चेकपॉइंट्स सेव्ह करतो. हे स्नॅपशॉट्स कायमचे संग्रहित करण्याऐवजी आवश्यकतेनुसार स्टेट डेटा पुन्हा तयार करण्यासाठी वापरले जातात. + +- सर्वात वेगवान सिंक स्ट्रॅटेजी, सध्या Ethereum मेननेटमध्ये डीफॉल्ट आहे. +- सुरक्षिततेशी तडजोड न करता भरपूर डिस्क वापर आणि नेटवर्क बँडविड्थ वाचवते. + +[स्नॅप सिंकवर अधिक](https://github.com/ethereum/devp2p/blob/master/caps/snap.md). + +#### लाइट सिंक {#light-sync} + +लाइट क्लायंट मोड सर्व ब्लॉक हेडर्स, ब्लॉक डेटा डाउनलोड करतो आणि काहींची यादृच्छिकपणे पडताळणी करतो. केवळ विश्वसनीय चेकपॉइंटवरून चेनच्या टोकापर्यंत सिंक करते. + +- विकसक आणि कन्सेंसस यंत्रणेवरील विश्वासावर अवलंबून राहून केवळ नवीनतम स्थिती प्राप्त करते. +- क्लायंट काही मिनिटांत सध्याच्या नेटवर्क स्थितीसह वापरण्यासाठी तयार. + +**सूचना** लाइट सिंक अजूनही प्रूफ-ऑफ-स्टेक Ethereum सह कार्य करत नाही - लाइट सिंकच्या नवीन आवृत्त्या लवकरच पाठवल्या पाहिजेत! + +[लाइट क्लायंटवर अधिक](/developers/docs/nodes-and-clients/light-clients/) + +### कन्सेंसस लेयर सिंक मोड्स {#consensus-layer-sync-modes} + +#### ऑप्टिमिस्टिक सिंक {#optimistic-sync} + +ऑप्टिमिस्टिक सिंक ही एक विलीनीकरणानंतरची सिंक्रोनाइझेशन स्ट्रॅटेजी आहे जी ऑप्ट-इन आणि बॅकवर्ड्स सुसंगत असण्यासाठी डिझाइन केलेली आहे, ज्यामुळे एक्झिक्युशन नोड्सना स्थापित पद्धतींद्वारे सिंक करता येते. एक्झिक्युशन इंजिन _आशावादीपणे_ बीकन ब्लॉक्स पूर्णपणे सत्यापित न करता आयात करू शकते, नवीनतम हेड शोधू शकते आणि नंतर वरील पद्धतींसह चेन सिंक करणे सुरू करू शकते. त्यानंतर, एक्झिक्युशन क्लायंट पकडल्यानंतर, ते कन्सेंसस क्लायंटला बीकन चेनमधील व्यवहारांच्या वैधतेबद्दल सूचित करेल. + +[ऑप्टिमिस्टिक सिंकवर अधिक](https://github.com/ethereum/consensus-specs/blob/dev/sync/optimistic.md) + +#### चेकपॉइंट सिंक {#checkpoint-sync} + +चेकपॉइंट सिंक, ज्याला वीक सब्जेक्टिव्हिटी सिंक असेही म्हणतात, बीकन नोड सिंक करण्यासाठी एक उत्कृष्ट वापरकर्ता अनुभव तयार करतो. हे [कमकुवत व्यक्तिनिष्ठतेच्या](/developers/docs/consensus-mechanisms/pos/weak-subjectivity/) गृहितकांवर आधारित आहे जे जेनेसिसऐवजी अलीकडील कमकुवत व्यक्तिनिष्ठता चेकपॉइंटवरून बीकन चेन सिंक करण्यास सक्षम करते. चेकपॉइंट सिंक [जेनेसिस](/glossary/#genesis-block) पासून सिंक करण्यासारख्याच विश्वासाच्या गृहितकांसह प्रारंभिक सिंक वेळ लक्षणीयरीत्या जलद करतात. + +व्यवहारात, याचा अर्थ असा की तुमचा नोड अलीकडील अंतिम स्थिती डाउनलोड करण्यासाठी रिमोट सेवेशी कनेक्ट होतो आणि त्या बिंदूपासून डेटाची पडताळणी करणे सुरू ठेवतो. डेटा प्रदान करणारा तृतीय पक्ष विश्वासार्ह आहे आणि काळजीपूर्वक निवडला पाहिजे. + +[चेकपॉइंट सिंक](https://notes.ethereum.org/@djrtwo/ws-sync-in-practice) वर अधिक + +## पुढील वाचन {#further-reading} + +- [Ethereum 101 - भाग 2 - नोड्स समजून घेणे](https://kauri.io/ethereum-101-part-2-understanding-nodes/48d5098292fd4f11b251d1b1814f0bba/a) _- विल् बार्न्स, 13 फेब्रुवारी 2019_ +- [Ethereum फुल नोड्स चालवणे: केवळ प्रेरित लोकांसाठी एक मार्गदर्शक](https://medium.com/@JustinMLeroux/running-ethereum-full-nodes-a-guide-for-the-barely-motivated-a8a13e7a0d31) _- जस्टिन लेरॉक्स, 7 नोव्हेंबर 2019_ + +## संबंधित विषय {#related-topics} + +- [ब्लॉक्स](/developers/docs/blocks/) +- [नेटवर्क्स](/developers/docs/networks/) + +## संबंधित ट्युटोरियल्स {#related-tutorials} + +- [तुमच्या रास्पबेरी पाय 4 ला फक्त मायक्रोएसडी कार्ड फ्लॅश करून व्हॅलिडेटर नोडमध्ये बदला - इन्स्टॉलेशन मार्गदर्शक](/developers/tutorials/run-node-raspberry-pi/) _- तुमचा रास्पबेरी पाय 4 फ्लॅश करा, इथरनेट केबल लावा, एसएसडी डिस्क कनेक्ट करा आणि रास्पबेरी पाय 4 ला एक्झिक्युशन लेयर (मेननेट) आणि/किंवा कन्सेंसस लेयर (बीकन चेन/व्हॅलिडेटर) चालवणारा पूर्ण Ethereum नोड बनवण्यासाठी डिव्हाइस चालू करा._ From b4f3a8e09262a08308a88a4741995ce003e0bb17 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:13:38 +0000 Subject: [PATCH 2/9] i18n(mr): translation import part 07 of 13 (23 files) --- .../mr/developers/docs/transactions/index.md | 231 +++ .../mr/developers/docs/web2-vs-web3/index.md | 62 + .../index.md | 300 ++++ .../tutorials/all-you-can-cache/index.md | 867 ++++++++++ .../developers/tutorials/app-plasma/index.md | 1256 ++++++++++++++ .../index.md | 131 ++ .../index.md | 585 +++++++ .../index.md | 101 ++ .../index.md | 372 ++++ .../index.md | 144 ++ .../index.md | 129 ++ .../erc-721-vyper-annotated-code/index.md | 644 +++++++ .../tutorials/erc20-annotated-code/index.md | 917 ++++++++++ .../erc20-with-safety-rails/index.md | 217 +++ .../tutorials/ethereum-for-web2-auth/index.md | 886 ++++++++++ .../index.md | 156 ++ .../index.md | 102 ++ .../index.md | 1540 +++++++++++++++++ .../hello-world-smart-contract/index.md | 366 ++++ .../index.md | 151 ++ .../tutorials/how-to-mint-an-nft/index.md | 335 ++++ .../index.md | 108 ++ .../index.md | 708 ++++++++ 23 files changed, 10308 insertions(+) create mode 100644 public/content/translations/mr/developers/docs/transactions/index.md create mode 100644 public/content/translations/mr/developers/docs/web2-vs-web3/index.md create mode 100644 public/content/translations/mr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md create mode 100644 public/content/translations/mr/developers/tutorials/all-you-can-cache/index.md create mode 100644 public/content/translations/mr/developers/tutorials/app-plasma/index.md create mode 100644 public/content/translations/mr/developers/tutorials/calling-a-smart-contract-from-javascript/index.md create mode 100644 public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/deploying-your-first-smart-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/develop-and-test-dapps-with-a-multi-client-local-eth-testnet/index.md create mode 100644 public/content/translations/mr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md create mode 100644 public/content/translations/mr/developers/tutorials/eip-1271-smart-contract-signatures/index.md create mode 100644 public/content/translations/mr/developers/tutorials/erc-721-vyper-annotated-code/index.md create mode 100644 public/content/translations/mr/developers/tutorials/erc20-annotated-code/index.md create mode 100644 public/content/translations/mr/developers/tutorials/erc20-with-safety-rails/index.md create mode 100644 public/content/translations/mr/developers/tutorials/ethereum-for-web2-auth/index.md create mode 100644 public/content/translations/mr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md create mode 100644 public/content/translations/mr/developers/tutorials/guide-to-smart-contract-security-tools/index.md create mode 100644 public/content/translations/mr/developers/tutorials/hello-world-smart-contract-fullstack/index.md create mode 100644 public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md create mode 100644 public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md create mode 100644 public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md create mode 100644 public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md diff --git a/public/content/translations/mr/developers/docs/transactions/index.md b/public/content/translations/mr/developers/docs/transactions/index.md new file mode 100644 index 00000000000..7b6ab93d7d2 --- /dev/null +++ b/public/content/translations/mr/developers/docs/transactions/index.md @@ -0,0 +1,231 @@ +--- +title: "व्यवहार" +description: "Ethereum व्यवहारांचे विहंगावलोकन – ते कसे कार्य करतात, त्यांची डेटा संरचना, आणि त्यांना ॲप्लिकेशनद्वारे कसे पाठवायचे." +lang: mr +--- + +व्यवहार हे खात्यांमधून क्रिप्टोग्राफिकली स्वाक्षरी केलेल्या सूचना आहेत. एक खाते Ethereum नेटवर्कची स्थिती अद्ययावत करण्यासाठी व्यवहार सुरू करेल. सर्वात सोपा व्यवहार म्हणजे एका खात्यातून दुसऱ्या खात्यात ETH हस्तांतरित करणे. + +## पूर्वतयारी {#prerequisites} + +हे पान तुम्हाला अधिक चांगल्या प्रकारे समजण्यास मदत करण्यासाठी, आम्ही शिफारस करतो की तुम्ही प्रथम [खाती](/developers/docs/accounts/) आणि आमचा [Ethereum चा परिचय](/developers/docs/intro-to-ethereum/) वाचा. + +## व्यवहार म्हणजे काय? {#whats-a-transaction} + +Ethereum व्यवहार म्हणजे बाह्य-मालकीच्या खात्याद्वारे सुरू केलेली क्रिया, दुसऱ्या शब्दांत, मानवाद्वारे व्यवस्थापित केलेले खाते, कराराद्वारे नाही. उदाहरणार्थ, जर बॉबने ॲलिसला १ ETH पाठवले, तर बॉबच्या खात्यातून पैसे वजा केले पाहिजेत आणि ॲलिसच्या खात्यात जमा केले पाहिजेत. ही स्थिती-बदलणारी क्रिया एका व्यवहारामध्ये होते. + +![व्यवहारामुळे स्थितीतील बदल दर्शवणारे रेखाचित्र](./tx.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित रेखाचित्र_ + +व्यवहार, जे EVM ची स्थिती बदलतात, ते संपूर्ण नेटवर्कवर प्रसारित करणे आवश्यक आहे. कोणताही नोड EVM वर व्यवहार कार्यान्वित करण्याची विनंती प्रसारित करू शकतो; हे घडल्यानंतर, एक व्हॅलिडेटर तो व्यवहार कार्यान्वित करेल आणि परिणामी स्थितीतील बदल उर्वरित नेटवर्कमध्ये प्रसारित करेल. + +व्यवहारांसाठी शुल्क आवश्यक आहे आणि त्यांना प्रमाणित ब्लॉकमध्ये समाविष्ट करणे आवश्यक आहे. हे विहंगावलोकन सोपे करण्यासाठी आम्ही गॅस शुल्क आणि प्रमाणीकरण यावर इतरत्र चर्चा करू. + +सादर केलेल्या व्यवहारामध्ये खालील माहिती समाविष्ट असते: + +- `from` – प्रेषकाचा पत्ता, जो व्यवहारावर स्वाक्षरी करेल. हे बाह्य-मालकीचे खाते असेल कारण करार खाती व्यवहार पाठवू शकत नाहीत +- `to` – प्राप्तकर्त्याचा पत्ता (जर बाह्य-मालकीचे खाते असेल, तर व्यवहार मूल्य हस्तांतरित करेल. जर करार खाते असेल तर, व्यवहार करार कोड कार्यान्वित करेल) +- `signature` – प्रेषकाचा ओळखकर्ता. जेव्हा प्रेषकाची खाजगी की व्यवहारावर स्वाक्षरी करते तेव्हा हे तयार केले जाते आणि पुष्टी करते की प्रेषकाने या व्यवहारास अधिकृत केले आहे +- `nonce` - एक क्रमशः वाढणारा काउंटर जो खात्यामधील व्यवहार क्रमांक दर्शवतो +- `value` – प्रेषकाकडून प्राप्तकर्त्याकडे हस्तांतरित करायची ETH ची रक्कम (WEI मध्ये दर्शवलेले, जिथे १ ETH = १e+१८ wei) +- `input data` – ऐच्छिक डेटा समाविष्ट करण्यासाठी वैकल्पिक फील्ड +- `gasLimit` – व्यवहारामुळे वापरल्या जाऊ शकणाऱ्या गॅस युनिट्सची कमाल रक्कम. [EVM](/developers/docs/evm/opcodes) प्रत्येक संगणकीय पायरीसाठी आवश्यक असलेल्या गॅसच्या युनिट्सची माहिती देते +- `maxPriorityFeePerGas` - व्हॅलिडेटरला टीप म्हणून समाविष्ट करण्यासाठी वापरलेल्या गॅसची कमाल किंमत +- `maxFeePerGas` - व्यवहारासाठी प्रति युनिट गॅससाठी देण्यास तयार असलेले कमाल शुल्क (`baseFeePerGas` आणि `maxPriorityFeePerGas` सह) + +गॅस म्हणजे व्हॅलिडेटरद्वारे व्यवहार प्रक्रिया करण्यासाठी आवश्यक असलेल्या गणनेचा संदर्भ. वापरकर्त्यांना या गणनेसाठी शुल्क भरावे लागते. `gasLimit`, आणि `maxPriorityFeePerGas` व्हॅलिडेटरला दिले जाणारे कमाल व्यवहार शुल्क निश्चित करतात. [गॅसवर अधिक](/developers/docs/gas/). + +व्यवहार ऑब्जेक्ट काहीसा असा दिसेल: + +```js +{ + from: "0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8", + to: "0xac03bb73b6a9e108530aff4df5077c2b3d481e5a", + gasLimit: "21000", + maxFeePerGas: "300", + maxPriorityFeePerGas: "10", + nonce: "0", + value: "10000000000" +} +``` + +परंतु व्यवहार ऑब्जेक्टवर प्रेषकाच्या खाजगी की वापरून स्वाक्षरी करणे आवश्यक आहे. हे सिद्ध करते की व्यवहार केवळ प्रेषकाकडूनच आला आहे आणि तो फसवणुकीने पाठवला गेला नाही. + +Geth सारखा Ethereum क्लायंट ही स्वाक्षरी प्रक्रिया हाताळेल. + +उदाहरण [JSON-RPC](/developers/docs/apis/json-rpc) कॉल: + +```json +{ + "id": 2, + "jsonrpc": "2.0", + "method": "account_signTransaction", + "params": [ + { + "from": "0x1923f626bb8dc025849e00f99c25fe2b2f7fb0db", + "gas": "0x55555", + "maxFeePerGas": "0x1234", + "maxPriorityFeePerGas": "0x1234", + "input": "0xabcd", + "nonce": "0x0", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234" + } + ] +} +``` + +उदाहरण प्रतिसाद: + +```json +{ + "jsonrpc": "2.0", + "id": 2, + "result": { + "raw": "0xf88380018203339407a565b7ed7d7a678680a4c162885bedbb695fe080a44401a6e4000000000000000000000000000000000000000000000000000000000000001226a0223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20ea02aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "tx": { + "nonce": "0x0", + "maxFeePerGas": "0x1234", + "maxPriorityFeePerGas": "0x1234", + "gas": "0x55555", + "to": "0x07a565b7ed7d7a678680a4c162885bedbb695fe0", + "value": "0x1234", + "input": "0xabcd", + "v": "0x26", + "r": "0x223a7c9bcf5531c99be5ea7082183816eb20cfe0bbc322e97cc5c7f71ab8b20e", + "s": "0x2aadee6b34b45bb15bc42d9c09de4a6754e7000908da72d48cc7704971491663", + "hash": "0xeba2df809e7a612a0a0d444ccfa5c839624bdc00dd29e3340d46df3870f8a30e" + } + } +} +``` + +- `raw` हे स्वाक्षरी केलेला व्यवहार [रिकर्सिव्ह लेंथ प्रिफिक्स (RLP)](/developers/docs/data-structures-and-encoding/rlp) एन्कोड केलेल्या स्वरूपात आहे +- `tx` हे JSON स्वरूपात स्वाक्षरी केलेला व्यवहार आहे + +स्वाक्षरी हॅशसह, व्यवहार क्रिप्टोग्राफिकली सिद्ध केला जाऊ शकतो की तो प्रेषकाकडून आला आहे आणि नेटवर्कवर सादर केला गेला आहे. + +### डेटा फील्ड {#the-data-field} + +बहुतेक व्यवहार बाह्य-मालकीच्या खात्यातून करारावर प्रवेश करतात. +बहुतेक करार Solidity मध्ये लिहिलेले आहेत आणि ते त्यांच्या डेटा फील्डचा अर्थ [ॲप्लिकेशन बायनरी इंटरफेस (ABI)](/glossary/#abi) नुसार लावतात. + +पहिले चार बाइट्स फंक्शनच्या नावाचा आणि वितर्कांचा हॅश वापरून कोणते फंक्शन कॉल करायचे हे निर्दिष्ट करतात. +[या डेटाबेस](https://www.4byte.directory/signatures/) चा वापर करून तुम्ही सिलेक्टरमधून फंक्शन ओळखू शकता. + +उर्वरित कॉलगडाटा वितर्क आहेत, जे [ABI स्पेसिफिकेशन्समध्ये निर्दिष्ट केल्याप्रमाणे एन्कोड केलेले आहेत](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding). + +उदाहरणार्थ, [या व्यवहारावर](https://etherscan.io/tx/0xd0dcbe007569fcfa1902dae0ab8b4e078efe42e231786312289b1eee5590f6a1) एक नजर टाकूया. +कॉलडाटा पाहण्यासाठी **अधिक पाहण्यासाठी क्लिक करा** वापरा. + +फंक्शन सिलेक्टर `0xa9059cbb` आहे. [या स्वाक्षरीसह अनेक ज्ञात फंक्शन्स](https://www.4byte.directory/signatures/?bytes4_signature=0xa9059cbb) आहेत. +या प्रकरणात, [करार स्रोत कोड](https://etherscan.io/address/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#code) Etherscan वर अपलोड केला आहे, म्हणून आम्हाला माहित आहे की फंक्शन `transfer(address,uint256)` आहे. + +उर्वरित डेटा आहे: + +``` +0000000000000000000000004f6742badb049791cd9a37ea913f2bac38d01279 +000000000000000000000000000000000000000000000000000000003b0559f4 +``` + +ABI स्पेसिफिकेशन्सनुसार, पूर्णांक मूल्ये (जसे की पत्ते, जे २०-बाइट पूर्णांक आहेत) ABI मध्ये ३२-बाइट शब्दांच्या रूपात दिसतात, ज्यांच्या समोर शून्यांनी पॅडिंग केलेले असते. +म्हणून आम्हाला माहित आहे की `to` पत्ता [`4f6742badb049791cd9a37ea913f2bac38d01279`](https://etherscan.io/address/0x4f6742badb049791cd9a37ea913f2bac38d01279) आहे. +`value` 0x3b0559f4 = ९९०२०६४५२ आहे. + +## व्यवहारांचे प्रकार {#types-of-transactions} + +Ethereum वर काही वेगवेगळ्या प्रकारचे व्यवहार आहेत: + +- नियमित व्यवहार: एका खात्यातून दुसऱ्या खात्यात केलेला व्यवहार. +- करार उपयोजन व्यवहार: 'to' पत्त्याशिवाय केलेला व्यवहार, जिथे डेटा फील्ड करार कोडसाठी वापरले जाते. +- कराराची अंमलबजावणी: उपयोजित स्मार्ट कराराशी संवाद साधणारा व्यवहार. या प्रकरणात, 'to' पत्ता स्मार्ट करार पत्ता आहे. + +### गॅसवर {#on-gas} + +नमूद केल्याप्रमाणे, व्यवहार कार्यान्वित करण्यासाठी [गॅस](/developers/docs/gas/) खर्च येतो. साध्या हस्तांतरण व्यवहारांना २१००० युनिट्स गॅसची आवश्यकता असते. + +म्हणून बॉबला ॲलिसला १ ETH पाठवण्यासाठी १९० gwei च्या `baseFeePerGas` आणि १० gwei च्या `maxPriorityFeePerGas` वर, बॉबला खालील शुल्क भरावे लागेल: + +``` +(१९० + १०) * २१००० = ४,२००,००० gwei +--किंवा-- +०.००४२ ETH +``` + +बॉबच्या खात्यातून **-१.००४२ ETH** डेबिट केले जातील (ॲलिससाठी १ ETH + गॅस शुल्कात ०.००४२ ETH) + +ॲलिसच्या खात्यात **+१.० ETH** जमा केले जातील + +आधार शुल्क **-०.००३९९ ETH** बर्न केले जाईल + +व्हॅलिडेटर **+०.०००२१० ETH** टीप ठेवतो + +![न वापरलेला गॅस कसा परत केला जातो हे दर्शवणारे रेखाचित्र](./gas-tx.png) +_[Ethereum EVM illustrated](https://takenobu-hs.github.io/downloads/ethereum_evm_illustrated.pdf) वरून रुपांतरित रेखाचित्र_ + +व्यवहारात न वापरलेला कोणताही गॅस वापरकर्त्याच्या खात्यात परत केला जातो. + +### स्मार्ट करार संवाद {#smart-contract-interactions} + +स्मार्ट कराराचा समावेश असलेल्या कोणत्याही व्यवहारासाठी गॅस आवश्यक आहे. + +स्मार्ट करारांमध्ये [`view`](https://docs.soliditylang.org/en/latest/contracts.html#view-functions) किंवा [`pure`](https://docs.soliditylang.org/en/latest/contracts.html#pure-functions) म्हणून ओळखले जाणारे फंक्शन्स देखील असू शकतात, जे कराराची स्थिती बदलत नाहीत. त्यामुळे, EOA मधून या फंक्शन्सना कॉल करण्यासाठी कोणत्याही गॅसची आवश्यकता नसते. या परिस्थितीसाठी अंतर्निहित RPC कॉल [`eth_call`](/developers/docs/apis/json-rpc#eth_call) आहे. + +`eth_call` वापरून प्रवेश करण्याच्या विपरीत, हे `view` किंवा `pure` फंक्शन्स सामान्यतः अंतर्गतपणे (म्हणजे, करारातूनच किंवा दुसऱ्या करारातून) कॉल केले जातात, ज्यासाठी गॅस खर्च येतो. + +## व्यवहार जीवनचक्र {#transaction-lifecycle} + +एकदा व्यवहार सादर केल्यावर खालील गोष्टी घडतात: + +1. एक व्यवहार हॅश क्रिप्टोग्राफिकली तयार केला जातो: + `0x97d99bc7729211111a21b12c933c949d4f31684f1d6954ff477d0477538ff017` +2. त्यानंतर व्यवहार नेटवर्कवर प्रसारित केला जातो आणि इतर सर्व प्रलंबित नेटवर्क व्यवहारांचा समावेश असलेल्या व्यवहार पूलमध्ये जोडला जातो. +3. एका व्हॅलिडेटरने तुमचा व्यवहार निवडून तो ब्लॉकमध्ये समाविष्ट करणे आवश्यक आहे जेणेकरून व्यवहार सत्यापित होईल आणि तो "यशस्वी" मानला जाईल. +4. जसजसा वेळ जाईल तसतसे तुमच्या व्यवहाराचा समावेश असलेला ब्लॉक "न्याय्य" आणि नंतर "अंतिम" म्हणून अपग्रेड केला जाईल. हे अपग्रेड्स तुमचा व्यवहार यशस्वी झाल्याची आणि तो कधीही बदलला जाणार नाही याची अधिक खात्री देतात. एकदा एखादा ब्लॉक "अंतिम" झाला की तो फक्त नेटवर्क स्तरावरील हल्ल्यानेच बदलला जाऊ शकतो ज्यासाठी अब्जावधी डॉलर्स खर्च येऊ शकतो. + +## एक दृश्यात्मक डेमो {#a-visual-demo} + +ऑस्टिनला व्यवहार, गॅस आणि मायनिंगमधून तुम्हाला मार्गदर्शन करताना पहा. + + + +## टाइप्ड ट्रान्झॅक्शन एनव्हेलप {#typed-transaction-envelope} + +Ethereum मध्ये मूळतः व्यवहारांसाठी एकच स्वरूप होते. प्रत्येक व्यवहारामध्ये नॉन्स, गॅस प्राइस, गॅस लिमिट, टू ॲड्रेस, व्हॅल्यू, डेटा, v, r आणि s यांचा समावेश होता. हे फील्ड्स [RLP-एन्कोडेड](/developers/docs/data-structures-and-encoding/rlp/) आहेत, जे असे दिसतात: + +`RLP([nonce, gasPrice, gasLimit, to, value, data, v, r, s])` + +ॲक्सेस लिस्ट्स आणि [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) सारख्या नवीन वैशिष्ट्यांची अंमलबजावणी करण्यासाठी, जुन्या व्यवहार स्वरूपांवर परिणाम न करता, Ethereum आता अनेक प्रकारच्या व्यवहारांना समर्थन देण्यासाठी विकसित झाले आहे. + +[EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) हे या वर्तनास परवानगी देते. व्यवहारांचा अर्थ असा लावला जातो: + +`TransactionType || TransactionPayload` + +जिथे फील्ड्स खालीलप्रमाणे परिभाषित आहेत: + +- `TransactionType` - ० ते ०x७f मधील एक संख्या, एकूण १२८ संभाव्य व्यवहार प्रकारांसाठी. +- `TransactionPayload` - व्यवहार प्रकाराने परिभाषित केलेली एक अनियंत्रित बाइट ॲरे. + +`TransactionType` मूल्यावर आधारित, व्यवहार खालीलप्रमाणे वर्गीकृत केला जाऊ शकतो: + +1. **प्रकार ० (लेगसी) व्यवहार:** Ethereum च्या लाँचपासून वापरले जाणारे मूळ व्यवहार स्वरूप. त्यामध्ये [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) मधील वैशिष्ट्ये जसे की डायनॅमिक गॅस शुल्क गणना किंवा स्मार्ट करारांसाठी ॲक्सेस लिस्ट्स यांचा समावेश नाही. लेगसी व्यवहारांमध्ये त्यांच्या सिरियलाइज्ड स्वरूपात त्यांचा प्रकार दर्शविणारा विशिष्ट उपसर्ग नसतो, [रिकर्सिव्ह लेंथ प्रिफिक्स (RLP)](/developers/docs/data-structures-and-encoding/rlp) एन्कोडिंग वापरताना ते `0xf8` बाइटने सुरू होतात. या व्यवहारांसाठी TransactionType मूल्य `0x0` आहे. + +2. **प्रकार १ व्यवहार:** Ethereum च्या [बर्लिन अपग्रेड](/ethereum-forks/#berlin) चा भाग म्हणून [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) मध्ये सादर केलेले, या व्यवहारांमध्ये `accessList` पॅरामीटरचा समावेश आहे. ही यादी पत्ते आणि स्टोरेज की निर्दिष्ट करते ज्यावर व्यवहार प्रवेश करण्याची अपेक्षा करतो, ज्यामुळे स्मार्ट करारांचा समावेश असलेल्या जटिल व्यवहारांसाठी [गॅस](/developers/docs/gas/) खर्च कमी होण्यास मदत होते. EIP-1559 शुल्क बाजारातील बदल प्रकार १ व्यवहारांमध्ये समाविष्ट नाहीत. प्रकार १ व्यवहारांमध्ये `yParity` पॅरामीटरचा देखील समावेश असतो, जो `0x0` किंवा `0x1` असू शकतो, जो secp256k1 स्वाक्षरीच्या y-मूल्याची समानता दर्शवतो. ते `0x01` बाइटने सुरू झाल्यामुळे ओळखले जातात आणि त्यांचे TransactionType मूल्य `0x1` आहे. + +3. **प्रकार २ व्यवहार**, सामान्यतः EIP-1559 व्यवहार म्हणून ओळखले जातात, हे Ethereum च्या [लंडन अपग्रेड](/ethereum-forks/#london) मध्ये, [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) मध्ये सादर केलेले व्यवहार आहेत. ते Ethereum नेटवर्कवर मानक व्यवहार प्रकार बनले आहेत. हे व्यवहार एक नवीन शुल्क बाजार यंत्रणा सादर करतात जी व्यवहार शुल्काचे आधार शुल्क आणि प्राधान्य शुल्कामध्ये विभाजन करून अंदाजक्षमता सुधारते. ते `0x02` बाइटने सुरू होतात आणि त्यात `maxPriorityFeePerGas` आणि `maxFeePerGas` सारख्या फील्ड्सचा समावेश असतो. प्रकार २ व्यवहार आता त्यांच्या लवचिकता आणि कार्यक्षमतेमुळे डिफॉल्ट आहेत, विशेषतः उच्च नेटवर्क गर्दीच्या काळात वापरकर्त्यांना व्यवहार शुल्क अधिक अंदाजे व्यवस्थापित करण्यात मदत करण्याच्या त्यांच्या क्षमतेमुळे पसंत केले जातात. या व्यवहारांसाठी TransactionType मूल्य `0x2` आहे. + +4. **प्रकार ३ (ब्लॉब) व्यवहार** Ethereum च्या [डेनकून अपग्रेड](/ethereum-forks/#dencun) चा भाग म्हणून [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) मध्ये सादर करण्यात आले. हे व्यवहार "ब्लॉब" डेटा (बायनरी लार्ज ऑब्जेक्ट्स) अधिक कार्यक्षमतेने हाताळण्यासाठी डिझाइन केलेले आहेत, विशेषतः लेयर २ रोलअप्सना कमी खर्चात Ethereum नेटवर्कवर डेटा पोस्ट करण्याचा मार्ग प्रदान करून फायदा देतात. ब्लॉब व्यवहारांमध्ये `blobVersionedHashes`, `maxFeePerBlobGas`, आणि `blobGasPrice` सारख्या अतिरिक्त फील्ड्सचा समावेश असतो. ते `0x03` बाइटने सुरू होतात आणि त्यांचे TransactionType मूल्य `0x3` आहे. ब्लॉब व्यवहार Ethereum च्या डेटा उपलब्धता आणि स्केलिंग क्षमतांमध्ये एक महत्त्वपूर्ण सुधारणा दर्शवतात. + +5. **प्रकार ४ व्यवहार** Ethereum च्या [पेक्ट्रा अपग्रेड](/roadmap/pectra/) चा भाग म्हणून [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) मध्ये सादर करण्यात आले. हे व्यवहार खाते अमूर्ततेसह फॉरवर्ड-कंपॅटिबल होण्यासाठी डिझाइन केलेले आहेत. ते EOAs ला त्यांची मूळ कार्यक्षमता धोक्यात न घालता तात्पुरते स्मार्ट करार खात्यांसारखे वागण्याची परवानगी देतात. त्यामध्ये `authorization_list` पॅरामीटरचा समावेश आहे, जो EOA आपला अधिकार कोणत्या स्मार्ट कराराला सोपवतो हे निर्दिष्ट करतो. व्यवहारानंतर, EOA च्या कोड फील्डमध्ये सोपवलेल्या स्मार्ट कराराचा पत्ता असेल. + +## पुढील वाचन {#further-reading} + +- [EIP-2718: टाइप्ड ट्रान्झॅक्शन एनव्हेलप](https://eips.ethereum.org/EIPS/eip-2718) + +_तुम्हाला मदत केलेल्या सामुदायिक संसाधनाबद्दल माहिती आहे का?_ हे पृष्ठ संपादित करा आणि ते जोडा!_ + +## संबंधित विषय {#related-topics} + +- [खाती](/developers/docs/accounts/) +- [Ethereum व्हर्च्युअल मशीन (EVM)](/developers/docs/evm/) +- [गॅस](/developers/docs/gas/) diff --git a/public/content/translations/mr/developers/docs/web2-vs-web3/index.md b/public/content/translations/mr/developers/docs/web2-vs-web3/index.md new file mode 100644 index 00000000000..5bb571f4f9c --- /dev/null +++ b/public/content/translations/mr/developers/docs/web2-vs-web3/index.md @@ -0,0 +1,62 @@ +--- +title: "Web2 विरुद्ध Web3" +description: "इथेरियम ब्लॉकचेन तंत्रज्ञानावर तयार केलेल्या विकेंद्रित वेब3 ॲप्लिकेशन्सची केंद्रीकृत वेब2 सेवांसोबत तुलना करा." +lang: mr +--- + +वेब2 म्हणजे आज आपल्यापैकी बहुतेकांना माहीत असलेल्या इंटरनेटची आवृत्ती. तुमच्या वैयक्तिक डेटाच्या बदल्यात सेवा पुरवणाऱ्या कंपन्यांचे वर्चस्व असलेले इंटरनेट. इथेरियमच्या संदर्भात, वेब3 म्हणजे ब्लॉकचेनवर चालणारे विकेंद्रित ॲप्स. हे असे ॲप्स आहेत जे कोणालाही त्यांच्या वैयक्तिक डेटाचे मुद्रीकरण न करता सहभागी होण्याची परवानगी देतात. + +अधिक नवशिक्यांसाठी अनुकूल संसाधन शोधत आहात का? आमची [वेब3 ची ओळख](/web3/) पहा. + +## वेब3 चे फायदे {#web3-benefits} + +इथेरियमच्या मूळ विकेंद्रीकरणामुळे अनेक वेब3 डेव्हलपर्सनी dapps तयार करणे निवडले आहे: + +- नेटवर्कवर असलेल्या कोणालाही सेवा वापरण्याची परवानगी आहे – किंवा दुसऱ्या शब्दांत, परवानगीची आवश्यकता नाही. +- कोणीही तुम्हाला ब्लॉक करू शकत नाही किंवा सेवेचा ॲक्सेस नाकारू शकत नाही. +- नेटिव्ह टोकन, इथर (ETH) द्वारे पेमेंट अंतर्भूत आहेत. +- इथेरियम ट्युरिंग-कम्प्लीट आहे, म्हणजे तुम्ही जवळजवळ काहीही प्रोग्राम करू शकता. + +## व्यावहारिक तुलना {#practical-comparisons} + +| वेब2 | Web3 | +| ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | +| ट्विटर कोणतेही खाते किंवा ट्वीट सेन्सॉर करू शकते | वेब3 ट्वीट्स सेन्सॉर करता येणार नाहीत कारण नियंत्रण विकेंद्रित आहे | +| पेमेंट सेवा विशिष्ट प्रकारच्या कामासाठी पेमेंटला परवानगी न देण्याचा निर्णय घेऊ शकते | वेब3 पेमेंट ॲप्सना कोणत्याही वैयक्तिक डेटाची आवश्यकता नसते आणि ते पेमेंट रोखू शकत नाहीत | +| गिग-इकॉनॉमी ॲप्सचे सर्व्हर बंद होऊ शकतात आणि कामगारांच्या उत्पन्नावर परिणाम होऊ शकतो | वेब3 सर्व्हर बंद होऊ शकत नाहीत – ते त्यांच्या बॅकएंड म्हणून इथेरियम, हजारो संगणकांचे विकेंद्रित नेटवर्क वापरतात | + +याचा अर्थ असा नाही की सर्व सेवांचे dapp मध्ये रूपांतर करणे आवश्यक आहे. ही उदाहरणे वेब2 आणि वेब3 सेवांमधील मुख्य फरकांची निदर्शक आहेत. + +## वेब3 च्या मर्यादा {#web3-limitations} + +सध्या वेब3 मध्ये काही मर्यादा आहेत: + +- स्केलेबिलिटी – व्यवहार वेब3 वर धीमे आहेत कारण ते विकेंद्रित आहेत. पेमेंटसारख्या स्टेटमधील बदलांवर नोडद्वारे प्रक्रिया करणे आणि संपूर्ण नेटवर्कमध्ये प्रसारित करणे आवश्यक आहे. +- UX – वेब3 ॲप्लिकेशन्सशी संवाद साधण्यासाठी अतिरिक्त पायऱ्या, सॉफ्टवेअर आणि शिक्षणाची आवश्यकता असू शकते. हे अवलंबण्यात एक अडथळा असू शकतो. +- ॲक्सेसिबिलिटी – आधुनिक वेब ब्राउझरमध्ये एकत्रीकरणाच्या अभावामुळे वेब3 बहुतेक वापरकर्त्यांसाठी कमी ॲक्सेसिबल बनते. +- खर्च – बहुतेक यशस्वी dapps त्यांच्या कोडचा खूप छोटा भाग ब्लॉकचेनवर ठेवतात कारण ते महाग आहे. + +## केंद्रीकरण विरुद्ध विकेंद्रीकरण {#centralization-vs-decentralization} + +खालील तक्त्यामध्ये, आम्ही केंद्रीकृत आणि विकेंद्रित डिजिटल नेटवर्क्सचे काही ढोबळ फायदे आणि तोटे सूचीबद्ध करतो. + +| केंद्रीकृत प्रणाली | विकेंद्रित प्रणाली | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| कमी नेटवर्क व्यास (सर्व सहभागी एका केंद्रीय प्राधिकरणाशी जोडलेले असतात); माहिती त्वरीत प्रसारित होते, कारण प्रसार मोठ्या प्रमाणात संगणकीय संसाधने असलेल्या केंद्रीय प्राधिकरणाद्वारे हाताळला जातो. | नेटवर्कवरील सर्वात दूरचे सहभागी एकमेकांपासून संभाव्यतः अनेक एजेस दूर असू शकतात. नेटवर्कच्या एका बाजूने प्रसारित केलेल्या माहितीला दुसऱ्या बाजूला पोहोचायला बराच वेळ लागू शकतो. | +| सहसा उच्च कार्यक्षमता (उच्च थ्रुपुट, एकूण कमी संगणकीय संसाधने खर्च) आणि अंमलबजावणी करणे सोपे. | सहसा कमी कार्यक्षमता (कमी थ्रुपुट, अधिक एकूण संगणकीय संसाधने खर्च) आणि अंमलबजावणी करणे अधिक क्लिष्ट. | +| परस्परविरोधी डेटाच्या बाबतीत, निराकरण स्पष्ट आणि सोपे आहे: सत्याचा अंतिम स्त्रोत केंद्रीय प्राधिकरण आहे. | ज्या डेटाच्या स्टेटवर सहभागींनी सिंक केलेले असणे अपेक्षित आहे, त्याबद्दल पीअर्स परस्परविरोधी दावे करत असल्यास, विवाद निराकरणासाठी एका प्रोटोकॉलची (बहुतेकदा क्लिष्ट) आवश्यकता असते. | +| अयशस्वी होण्याचा एकच बिंदू: दुर्भावनापूर्ण घटक केंद्रीय प्राधिकरणाला लक्ष्य करून नेटवर्क बंद करू शकतात. | अयशस्वी होण्याचा एकही बिंदू नाही: सहभागींच्या मोठ्या भागावर हल्ला झाला/काढून टाकले तरीही नेटवर्क कार्य करू शकते. | +| नेटवर्क सहभागींमध्ये समन्वय खूप सोपा आहे आणि एका केंद्रीय प्राधिकरणाद्वारे हाताळला जातो. केंद्रीय प्राधिकरण नेटवर्क सहभागींना अगदी कमी घर्षणासह अपग्रेड, प्रोटोकॉल अपडेट्स इत्यादी स्वीकारण्यास भाग पाडू शकते. | समन्वय अनेकदा कठीण असतो, कारण नेटवर्क-स्तरीय निर्णय, प्रोटोकॉल अपग्रेड इत्यादींमध्ये कोणत्याही एका एजंटचा अंतिम निर्णय नसतो. सर्वात वाईट परिस्थितीत, जेव्हा प्रोटोकॉल बदलांबद्दल मतभेद असतात तेव्हा नेटवर्कमध्ये फूट पडण्याची शक्यता असते. | +| केंद्रीय प्राधिकरण डेटा सेन्सॉर करू शकते, संभाव्यतः नेटवर्कच्या काही भागांना उर्वरित नेटवर्कशी संवाद साधण्यापासून तोडू शकते. | सेन्सॉरशिप खूप कठीण आहे, कारण माहितीला नेटवर्कमध्ये प्रसारित होण्याचे अनेक मार्ग आहेत. | +| नेटवर्कमधील सहभाग केंद्रीय प्राधिकरणाद्वारे नियंत्रित केला जातो. | कोणीही नेटवर्कमध्ये सहभागी होऊ शकतो; कोणतेही “गेटकीपर” नाहीत. आदर्शपणे, सहभागाचा खर्च खूप कमी असतो. | + +लक्षात घ्या की हे सामान्य नमुने आहेत जे प्रत्येक नेटवर्कमध्ये खरे ठरतीलच असे नाही. शिवाय, प्रत्यक्षात एखादे नेटवर्क किती प्रमाणात केंद्रीकृत/विकेंद्रित आहे हे एका स्पेक्ट्रमवर अवलंबून असते; कोणतेही नेटवर्क पूर्णपणे केंद्रीकृत किंवा पूर्णपणे विकेंद्रित नसते. + +## पुढील वाचन {#further-reading} + +- [वेब3 काय आहे?](/web3/) - _ethereum.org_ +- [वेब 3.0 ॲप्लिकेशनची रचना](https://www.preethikasireddy.com/post/the-architecture-of-a-web-3-0-application) - _प्रीती कासिरेड्डी_ +- [विकेंद्रीकरणाचा अर्थ](https://medium.com/@VitalikButerin/the-meaning-of-decentralization-a0c92b76a274) _6 फेब्रुवारी, 2017 - विटालिक बुटेरिन_ +- [विकेंद्रीकरण का महत्त्वाचे आहे](https://onezero.medium.com/why-decentralization-matters-5e3f79f7638e) _18 फेब्रुवारी, 2018 - ख्रिस डिक्सन_ +- [वेब 3.0 काय आहे आणि ते का महत्त्वाचे आहे](https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b) _31 डिसेंबर, 2019 - मॅक्स मर्श आणि रिचर्ड मुइरहेड_ +- [आम्हाला वेब 3.0 ची गरज का आहे](https://gavofyork.medium.com/why-we-need-web-3-0-5da4f2bf95ab) _12 सप्टेंबर, 2018 - गॅविन वुड_ diff --git a/public/content/translations/mr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md b/public/content/translations/mr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md new file mode 100644 index 00000000000..7faec1170f9 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/a-developers-guide-to-ethereum-part-one/index.md @@ -0,0 +1,300 @@ +--- +title: "एका Python डेव्हलपरसाठी Ethereum ची ओळख, भाग 1" +description: "Ethereum डेव्हलपमेंटची ओळख, विशेषतः Python प्रोग्रामिंग भाषेचे ज्ञान असलेल्यांसाठी उपयुक्त" +author: Marc Garreau +lang: mr +tags: [ "python", "web3.py" ] +skill: beginner +published: 2020-09-08 +source: Snake charmers +sourceUrl: https://snakecharmers.ethereum.org/a-developers-guide-to-ethereum-pt-1/ +--- + +तर, तुम्ही या Ethereum नावाच्या गोष्टीबद्दल ऐकले आहे आणि या गहन जगात प्रवेश करण्यास तयार आहात का? ही पोस्ट ब्लॉकचेनच्या काही मूलभूत गोष्टींवर पटकन प्रकाश टाकेल, त्यानंतर तुम्हाला एका सिम्युलेटेड Ethereum नोडशी संवाद साधायला लावेल – ब्लॉक डेटा वाचणे, खात्यातील शिल्लक तपासणे आणि व्यवहार पाठवणे. या प्रक्रियेत, ॲप्स बनवण्याच्या पारंपरिक पद्धती आणि हे नवीन विकेंद्रित प्रतिमान (paradigm) यांमधील फरक आम्ही अधोरेखित करू. + +## (अंदाजित) पूर्वतयारी {#soft-prerequisites} + +ही पोस्ट विविध प्रकारच्या डेव्हलपर्ससाठी सोपी आणि सहज समजण्याजोगी असावी अशी आमची इच्छा आहे. [Python टूल्स](/developers/docs/programming-languages/python/) यात सामील असतील, पण ती केवळ कल्पना पोहोचवण्याचे एक माध्यम आहेत - तुम्ही Python डेव्हलपर नसाल तरी काही हरकत नाही. तथापि, तुम्हाला आधीपासून काय माहित आहे याबद्दल मी काही गृहीतके धरणार आहे, जेणेकरून आपण पटकन Ethereum-विशिष्ट भागांकडे जाऊ शकू. + +गृहीतके: + +- तुम्ही टर्मिनलमध्ये काम करू शकता, +- तुम्ही Python कोडच्या काही ओळी लिहिल्या आहेत, +- Python आवृत्ती 3.6 किंवा त्याहून अधिक तुमच्या मशीनवर इंस्टॉल केलेले आहे ([व्हर्च्युअल एन्व्हायर्नमेंट](https://realpython.com/effective-python-environment/#virtual-environments) वापरण्यास जोरदार प्रोत्साहन दिले जाते), आणि +- तुम्ही `pip`, Python चे पॅकेज इंस्टॉलर वापरले आहे. + पुन्हा एकदा, यापैकी काहीही असत्य असल्यास, किंवा तुम्ही या लेखातील कोड पुन्हा वापरण्याची योजना करत नसल्यास, तरीही तुम्ही हे सहजपणे समजून घेऊ शकता. + +## ब्लॉकचेन्स, थोडक्यात {#blockchains-briefly} + +Ethereum चे वर्णन करण्याचे अनेक मार्ग आहेत, पण त्याच्या केंद्रस्थानी एक ब्लॉकचेन आहे. ब्लॉकचेन हे ब्लॉक्सच्या मालिकेपासून बनलेले असतात, चला तर मग तिथूनच सुरुवात करूया. सोप्या भाषेत सांगायचे झाल्यास, Ethereum ब्लॉकचेनवरील प्रत्येक ब्लॉक म्हणजे काही मेटाडेटा आणि व्यवहारांची सूची. JSON फॉरमॅटमध्ये, ते असे काहीतरी दिसते: + +```json +{ + "number": 1234567, + "hash": "0xabc123...", + "parentHash": "0xdef456...", + ..., + "transactions": [...] +} +``` + +प्रत्येक [ब्लॉक](/developers/docs/blocks/) मध्ये त्याच्या आधीच्या ब्लॉकचा संदर्भ असतो; `parentHash` म्हणजे फक्त मागील ब्लॉकचा हॅश. + +टीप: Ethereum ठराविक आकाराची मूल्ये (“हॅश”) तयार करण्यासाठी हॅश फंक्शन्सचा नियमित वापर करते. हॅश Ethereum मध्ये महत्त्वाची भूमिका बजावतात, पण सध्यासाठी तुम्ही त्यांना युनिक आयडी म्हणून समजू शकता. + +![एका ब्लॉकचेनचे चित्र, ज्यात प्रत्येक ब्लॉकच्या आतील डेटा दर्शविला आहे](./blockchain-diagram.png) + +_एक ब्लॉकचेन मूलतः एक लिंक्ड लिस्ट आहे; प्रत्येक ब्लॉकला मागील ब्लॉकचा संदर्भ असतो._ + +ही डेटा स्ट्रक्चर काही नवीन नाही, परंतु नेटवर्कचे संचालन करणारे नियम (म्हणजेच, पीअर-टू-पीअर प्रोटोकॉल) नवीन आहेत. येथे कोणतेही केंद्रीय प्राधिकरण नाही; नेटवर्क टिकवून ठेवण्यासाठी पीअर्सच्या नेटवर्कला एकत्र काम करावे लागते, आणि पुढील ब्लॉकमध्ये कोणते व्यवहार समाविष्ट करायचे हे ठरवण्यासाठी स्पर्धा करावी लागते. म्हणून, जेव्हा तुम्हाला तुमच्या मित्राला काही पैसे पाठवायचे असतील, तेव्हा तुम्हाला तो व्यवहार नेटवर्कवर प्रसारित करावा लागेल, आणि नंतर तो आगामी ब्लॉकमध्ये समाविष्ट होण्याची वाट पाहावी लागेल. + +एका वापरकर्त्याकडून दुसऱ्या वापरकर्त्याकडे पैसे खरोखरच पाठवले गेले आहेत हे पडताळून पाहण्याचा ब्लॉकचेनसाठी एकमेव मार्ग म्हणजे त्या ब्लॉकचेनचे मूळ चलन (म्हणजेच, त्या ब्लॉकचेनद्वारे तयार केलेले आणि शासित) वापरणे. Ethereum मध्ये, या चलनास ईथर म्हणतात, आणि Ethereum ब्लॉकचेनमध्ये खात्यातील शिलकीची एकमेव अधिकृत नोंद असते. + +## एक नवीन प्रतिमान (paradigm) {#a-new-paradigm} + +या नवीन विकेंद्रित टेक स्टॅकने नवीन डेव्हलपर टूल्स तयार केले आहेत. अशी टूल्स अनेक प्रोग्रामिंग भाषांमध्ये अस्तित्वात आहेत, परंतु आपण Python च्या दृष्टिकोनातून पाहणार आहोत. पुन्हा सांगतो: Python तुमची पसंतीची भाषा नसली तरीही, हे समजून घेण्यासाठी जास्त अडचण येऊ नये. + +Ethereum शी संवाद साधू इच्छिणारे Python डेव्हलपर बहुधा [Web3.py](https://web3py.readthedocs.io/) चा वापर करतात. Web3.py ही एक लायब्ररी आहे जी तुम्हाला Ethereum नोडशी जोडण्याची आणि त्यातून डेटा पाठवण्याची आणि प्राप्त करण्याची पद्धत खूप सोपी करते. + +टीप: “Ethereum नोड” आणि “Ethereum क्लायंट” हे शब्द एकमेकांसाठी वापरले जातात. दोन्ही बाबतीत, याचा अर्थ Ethereum नेटवर्कमधील एक सहभागी चालवत असलेले सॉफ्टवेअर असा होतो. हे सॉफ्टवेअर ब्लॉक डेटा वाचू शकते, चेनमध्ये नवीन ब्लॉक जोडल्यावर अपडेट्स मिळवू शकते, नवीन व्यवहार प्रसारित करू शकते आणि बरेच काही. तांत्रिकदृष्ट्या, क्लायंट हे सॉफ्टवेअर आहे, तर नोड हे सॉफ्टवेअर चालवणारा संगणक आहे. + +[Ethereum क्लायंट](/developers/docs/nodes-and-clients/) [IPC](https://wikipedia.org/wiki/Inter-process_communication), HTTP, किंवा Websockets द्वारे पोहोचण्यायोग्य होण्यासाठी कॉन्फिगर केले जाऊ शकतात, म्हणून Web3.py ला हे कॉन्फिगरेशन प्रतिबिंबित करावे लागेल. Web3.py या कनेक्शन पर्यायांना **प्रोव्हायडर्स** म्हणून संबोधते. Web3.py इंस्टन्सला तुमच्या नोडशी जोडण्यासाठी तुम्हाला तीन प्रोव्हायडर्सपैकी एक निवडावा लागेल. + +![तुमचा ॲप्लिकेशन Ethereum नोडशी जोडण्यासाठी web3.py IPC चा कसा वापर करते हे दर्शवणारे एक चित्र](./web3py-and-nodes.png) + +_Ethereum नोड आणि Web3.py ला एकाच प्रोटोकॉलद्वारे संवाद साधण्यासाठी कॉन्फिगर करा, उदा., या चित्रात IPC._ + +एकदा Web3.py योग्यरित्या कॉन्फिगर झाल्यावर, तुम्ही ब्लॉकचेनशी संवाद साधण्यास सुरुवात करू शकता. पुढे काय येणार आहे याची झलक म्हणून येथे Web3.py वापराची काही उदाहरणे आहेत: + +```python +# ब्लॉक डेटा वाचा: +w3.eth.get_block('latest') + +# एक व्यवहार पाठवा: +w3.eth.send_transaction({'from': ..., 'to': ..., 'value': ...}) +``` + +## इन्स्टॉलेशन {#installation} + +या वॉकथ्रूमध्ये, आपण फक्त Python इंटरप्रिटरमध्ये काम करणार आहोत. आपण कोणत्याही डिरेक्टरीज, फाइल्स, क्लासेस किंवा फंक्शन्स तयार करणार नाही. + +टीप: खालील उदाहरणांमध्ये, `$` ने सुरू होणारे कमांड्स टर्मिनलमध्ये चालवण्यासाठी आहेत. ( `$ ` टाइप करू नका, ते फक्त ओळीची सुरुवात दर्शवते.) + +सर्वप्रथम, एक्सप्लोर करण्यासाठी वापरकर्ता-स्नेही वातावरणासाठी [IPython](https://ipython.org/) इंस्टॉल करा. IPython टॅब कंप्लिशनसारख्या इतर वैशिष्ट्यांसह, Web3.py मध्ये काय शक्य आहे हे पाहणे खूप सोपे करते. + +```bash +pip install ipython +``` + +Web3.py `web3` या नावाने प्रकाशित केले आहे. ते असे इंस्टॉल करा: + +```bash +pip install web3 +``` + +आणखी एक गोष्ट - आपण नंतर एक ब्लॉकचेन सिम्युलेट करणार आहोत, ज्यासाठी आणखी काही डिपेन्डन्सीज आवश्यक आहेत. तुम्ही त्या याप्रमाणे इंस्टॉल करू शकता: + +```bash +pip install 'web3[tester]' +``` + +तुम्ही आता पूर्णपणे तयार आहात! + +टीप: `web3[tester]` पॅकेज Python 3.10.xx पर्यंत काम करते. + +## एक सँडबॉक्स सुरू करा {#spin-up-a-sandbox} + +तुमच्या टर्मिनलमध्ये `ipython` रन करून एक नवीन Python एन्व्हायर्नमेंट उघडा. हे `python` रन करण्यासारखेच आहे, परंतु यात अधिक अतिरिक्त वैशिष्ट्ये आहेत. + +```bash +ipython +``` + +हे तुम्ही चालवत असलेल्या Python आणि IPython च्या आवृत्त्यांविषयी काही माहिती प्रिंट करेल, त्यानंतर तुम्हाला इनपुटची वाट पाहणारा एक प्रॉम्प्ट दिसेल: + +```python +In [1]: +``` + +तुम्ही आता एक इंटरॲक्टिव्ह Python शेल पाहत आहात. मूलतः, हे खेळण्यासाठी एक सँडबॉक्स आहे. जर तुम्ही इथपर्यंत पोहोचला असाल, तर आता Web3.py इम्पोर्ट करण्याची वेळ आली आहे: + +```python +In [1]: from web3 import Web3 +``` + +## Web3 मॉड्यूलची ओळख {#introducing-the-web3-module} + +Ethereum चे प्रवेशद्वार असण्याव्यतिरिक्त, [Web3](https://web3py.readthedocs.io/en/stable/overview.html#base-api) मॉड्यूल काही सोयीस्कर फंक्शन्स देखील प्रदान करते. चला काही एक्सप्लोर करूया. + +एका Ethereum ॲप्लिकेशनमध्ये, तुम्हाला सामान्यतः चलनाची परिमाणे (denominations) रूपांतरित करण्याची आवश्यकता असेल. Web3 मॉड्यूल यासाठीच काही हेल्पर मेथड्स पुरवते: [from_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.from_wei) आणि [to_wei](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.to_wei). + + +टीप: संगणक दशांश गणित हाताळण्यात कुप्रसिद्ध आहेत. यावर मात करण्यासाठी, डेव्हलपर्स अनेकदा डॉलरची रक्कम सेंटमध्ये साठवतात. उदाहरणार्थ, $5.99 किंमत असलेली वस्तू डेटाबेसमध्ये 599 म्हणून साठवली जाऊ शकते. + +ईथरमधील व्यवहार हाताळतानाही असाच पॅटर्न वापरला जातो. तथापि, दोन दशांश स्थळांऐवजी, ईथरला 18 आहेत! ईथरच्या सर्वात लहान परिमाणाला wei म्हणतात, म्हणून व्यवहार पाठवताना तेच मूल्य निर्दिष्ट केले जाते. + +1 ईथर = 1000000000000000000 wei + +1 wei = 0.000000000000000001 ईथर + + + +काही मूल्ये wei मध्ये आणि wei मधून रूपांतरित करण्याचा प्रयत्न करा. लक्षात घ्या की ईथर आणि wei मध्ये [अनेक परिमाणांसाठी नावे आहेत](https://web3py.readthedocs.io/en/stable/troubleshooting.html#how-do-i-convert-currency-denominations). त्यापैकी एक अधिक प्रसिद्ध नाव म्हणजे **gwei**, कारण व्यवहार शुल्क अनेकदा यात दर्शवले जाते. + +```python +In [2]: Web3.to_wei(1, 'ether') +Out[2]: 1000000000000000000 + +In [3]: Web3.from_wei(500000000, 'gwei') +Out[3]: Decimal('0.5') +``` + +Web3 मॉड्यूलवरील इतर युटिलिटी मेथड्समध्ये डेटा फॉरमॅट कन्व्हर्टर्स (उदा., [`toHex`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.toHex)), ॲड्रेस हेल्पर्स (उदा., [`isAddress`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.isAddress)), आणि हॅश फंक्शन्स (उदा., [`keccak`](https://web3py.readthedocs.io/en/stable/web3.main.html#web3.Web3.keccak)) यांचा समावेश आहे. यापैकी बऱ्याच गोष्टी या मालिकेत नंतर समाविष्ट केल्या जातील. सर्व उपलब्ध मेथड्स आणि प्रॉपर्टीज पाहण्यासाठी, `Web3` टाइप करून IPython च्या ऑटो-कम्प्लीटचा वापर करा. आणि पीरियडनंतर टॅब की दोनदा दाबा. + +## चेनशी बोला {#talk-to-the-chain} + +सोयीस्कर मेथड्स छान आहेत, पण चला आता ब्लॉकचेनकडे वळूया. पुढील पायरी म्हणजे Ethereum नोडशी संवाद साधण्यासाठी Web3.py कॉन्फिगर करणे. येथे आपल्याकडे IPC, HTTP किंवा Websocket प्रोव्हायडर्स वापरण्याचा पर्याय आहे. + +आपण या मार्गावर जाणार नाही, परंतु HTTP प्रोव्हायडर वापरून संपूर्ण वर्कफ्लोचे उदाहरण असे काहीतरी दिसेल: + +- एक Ethereum नोड डाउनलोड करा, उदा., [Geth](https://geth.ethereum.org/). +- एका टर्मिनल विंडोमध्ये Geth सुरू करा आणि नेटवर्क सिंक होण्याची वाट पाहा. डीफॉल्ट HTTP पोर्ट `8545` आहे, पण ते कॉन्फिगर करता येते. +- `localhost:8545` वर HTTP द्वारे नोडशी कनेक्ट करण्यासाठी Web3.py ला सांगा. + `w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545'))` +- नोडशी संवाद साधण्यासाठी `w3` इंस्टन्स वापरा. + +हे करण्याची ही एक “वास्तविक” पद्धत असली तरी, सिंक करण्याच्या प्रक्रियेला तास लागतात आणि जर तुम्हाला फक्त एक डेव्हलपमेंट एन्व्हायर्नमेंट हवे असेल तर ते अनावश्यक आहे. Web3.py या उद्देशासाठी चौथा प्रोव्हायडर उपलब्ध करतो, तो म्हणजे **EthereumTesterProvider**. हा टेस्टर प्रोव्हायडर एका सिम्युलेटेड Ethereum नोडला जोडतो, ज्यामध्ये शिथिल परवानग्या आणि खेळण्यासाठी बनावट चलन असते. + +![EthereumTesterProvider तुमच्या web3.py ॲप्लिकेशनला सिम्युलेटेड Ethereum नोडशी जोडत असल्याचे दर्शवणारे एक चित्र](./ethereumtesterprovider.png) + +_EthereumTesterProvider एका सिम्युलेटेड नोडशी कनेक्ट होतो आणि जलद डेव्हलपमेंट एन्व्हायर्नमेंटसाठी उपयुक्त आहे._ + +त्या सिम्युलेटेड नोडला [eth-tester](https://github.com/ethereum/eth-tester) म्हणतात आणि आपण तो `pip install web3[tester]` कमांडचा भाग म्हणून इंस्टॉल केला. या टेस्टर प्रोव्हायडरचा वापर करण्यासाठी Web3.py कॉन्फिगर करणे इतके सोपे आहे: + +```python +In [4]: w3 = Web3(Web3.EthereumTesterProvider()) +``` + +आता तुम्ही चेन सर्फ करण्यास तयार आहात! असं सहसा कोणी म्हणत नाही. मी हे आताच तयार केले. चला एक छोटीशी सफर करूया. + +## छोटीशी सफर {#the-quick-tour} + +सर्वात आधी, एक सॅनिटी चेक: + +```python +In [5]: w3.is_connected() +Out[5]: True +``` + +आपण टेस्टर प्रोव्हायडर वापरत असल्यामुळे, ही चाचणी खूप महत्त्वाची नाही, पण जर ती अयशस्वी झाली, तर शक्यता आहे की `w3` व्हेरिएबल इन्स्टँटिएट करताना तुम्ही काहीतरी चुकीचे टाइप केले असेल. तुम्ही आतील कंस समाविष्ट केले आहेत याची खात्री करा, म्हणजे `Web3.EthereumTesterProvider()`. + +## सफरीचा थांबा #1: [खाती](/developers/docs/accounts/) {#tour-stop-1-accounts} + +सोयीसाठी, टेस्टर प्रोव्हायडरने काही खाती तयार केली आहेत आणि त्यात आधीच चाचणीसाठी ईथर भरलेले आहेत. + +प्रथम, त्या खात्यांची यादी पाहूया: + +```python +In [6]: w3.eth.accounts +Out[6]: ['0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF', + '0x6813Eb9362372EEF6200f3b1dbC3f819671cBA69', ...] +``` + +तुम्ही हा कमांड चालवल्यास, तुम्हाला `0x` ने सुरू होणाऱ्या दहा स्ट्रिंगची यादी दिसेल. प्रत्येक एक **पब्लिक ॲड्रेस** आहे आणि काही बाबतीत, तो चेकिंग खात्यावरील खाते क्रमांकासारखा आहे. तुम्हाला ईथर पाठवू इच्छिणाऱ्या व्यक्तीला तुम्ही हा ॲड्रेस द्याल. + +सांगितल्याप्रमाणे, टेस्टर प्रोव्हायडरने या प्रत्येक खात्यात काही चाचणी ईथर आधीच भरलेले आहेत. पहिल्या खात्यात किती शिल्लक आहे ते पाहूया: + +```python +In [7]: w3.eth.get_balance(w3.eth.accounts[0]) +Out[7]: 1000000000000000000000000 +``` + +किती तरी शून्य आहेत! खोट्या बँकेत जाऊन आनंद साजरा करण्यापूर्वी, चलनांच्या परिमाणांबद्दलचा पूर्वीचा धडा आठवा. ईथर मूल्ये सर्वात लहान परिमाण, wei मध्ये दर्शविली जातात. ते ईथरमध्ये रूपांतरित करा: + +```python +In [8]: w3.from_wei(1000000000000000000000000, 'ether') +Out[8]: Decimal('1000000') +``` + +दहा लाख चाचणी ईथर - तरीही वाईट नाही. + +## सफरीचा थांबा #2: ब्लॉक डेटा {#tour-stop-2-block-data} + +या सिम्युलेटेड ब्लॉकचेनच्या स्थितीवर एक नजर टाकूया: + +```python +In [9]: w3.eth.get_block('latest') +Out[9]: AttributeDict({ + 'number': 0, + 'hash': HexBytes('0x9469878...'), + 'parentHash': HexBytes('0x0000000...'), + ... + 'transactions': [] +}) +``` + +एका ब्लॉकबद्दल बरीच माहिती परत मिळते, पण येथे फक्त काही गोष्टी नमूद करायच्या आहेत: + +- ब्लॉक क्रमांक शून्य आहे - तुम्ही टेस्टर प्रोव्हायडर कितीही वेळापूर्वी कॉन्फिगर केले असले तरीही. वास्तविक Ethereum नेटवर्कच्या विपरीत, जे दर 12 सेकंदांनी एक नवीन ब्लॉक जोडते, हे सिम्युलेशन तुम्ही त्याला काही काम देईपर्यंत थांबेल. +- `transactions` ही एक रिकामी यादी आहे, त्याच कारणासाठी: आपण अद्याप काहीही केलेले नाही. हा पहिला ब्लॉक एक **रिकामा ब्लॉक** आहे, फक्त चेन सुरू करण्यासाठी. +- लक्षात घ्या की `parentHash` फक्त रिकाम्या बाइट्सचा एक समूह आहे. हे सूचित करते की हा चेनमधील पहिला ब्लॉक आहे, ज्याला **जेनेसिस ब्लॉक** असेही म्हणतात. + +## सफरीचा थांबा #3: [व्यवहार](/developers/docs/transactions/) {#tour-stop-3-transactions} + +आपण ब्लॉक शून्यवर अडकलो आहोत जोपर्यंत प्रलंबित व्यवहार होत नाही, चला तर मग एक व्यवहार करूया. एका खात्यातून दुसऱ्या खात्यात काही चाचणी ईथर पाठवा: + +```python +In [10]: tx_hash = w3.eth.send_transaction({ + 'from': w3.eth.accounts[0], + 'to': w3.eth.accounts[1], + 'value': w3.to_wei(3, 'ether'), + 'gas': 21000 +}) +``` + +हा सहसा तो क्षण असतो जिथे तुम्ही तुमचा व्यवहार नवीन ब्लॉकमध्ये समाविष्ट होण्यासाठी काही सेकंद वाट पाहता. संपूर्ण प्रक्रिया काहीशी अशी आहे: + +1. एक व्यवहार सबमिट करा आणि व्यवहार हॅश जपून ठेवा. व्यवहार असलेला ब्लॉक तयार आणि प्रसारित होईपर्यंत, व्यवहार “प्रलंबित” असतो. + `tx_hash = w3.eth.send_transaction({ … })` +2. व्यवहार ब्लॉकमध्ये समाविष्ट होण्याची वाट पाहा: + `w3.eth.wait_for_transaction_receipt(tx_hash)` +3. ॲप्लिकेशन लॉजिक सुरू ठेवा. यशस्वी व्यवहार पाहण्यासाठी: + `w3.eth.get_transaction(tx_hash)` + +आमचे सिम्युलेटेड एन्व्हायर्नमेंट व्यवहार तात्काळ एका नवीन ब्लॉकमध्ये जोडेल, त्यामुळे आपण लगेच व्यवहार पाहू शकतो: + +```python +In [11]: w3.eth.get_transaction(tx_hash) +Out[11]: AttributeDict({ + 'hash': HexBytes('0x15e9fb95dc39...'), + 'blockNumber': 1, + 'transactionIndex': 0, + 'from': '0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf', + 'to': '0x2B5AD5c4795c026514f8317c7a215E218DcCD6cF', + 'value': 3000000000000000000, + ... +}) +``` + +तुम्हाला येथे काही ओळखीचे तपशील दिसतील: `from`, `to` आणि `value` फील्ड्स आपल्या `send_transaction` कॉलच्या इनपुटशी जुळले पाहिजेत. दुसरी दिलासादायक गोष्ट म्हणजे हा व्यवहार ब्लॉक क्रमांक 1 मध्ये पहिला व्यवहार (`'transactionIndex': 0`) म्हणून समाविष्ट केला गेला. + +या व्यवहाराची यशस्वीता आपण दोन्ही संबंधित खात्यांमधील शिल्लक तपासून सहज पडताळू शकतो. तीन ईथर एका खात्यातून दुसऱ्या खात्यात हस्तांतरित झाले पाहिजेत. + +```python +In [12]: w3.eth.get_balance(w3.eth.accounts[0]) +Out[12]: 999996999979000000000000 + +In [13]: w3.eth.get_balance(w3.eth.accounts[1]) +Out[13]: 1000003000000000000000000 +``` + +दुसरे बरोबर दिसत आहे! शिल्लक 1,000,000 वरून 1,000,003 ईथर झाली. पण पहिल्या खात्याचे काय झाले? असे दिसते की त्याने तीन ईथरपेक्षा थोडे जास्त गमावले आहेत. अरेरे, जीवनात काहीही विनामूल्य नाही, आणि Ethereum सार्वजनिक नेटवर्क वापरण्यासाठी तुम्हाला तुमच्या पीअर्सना त्यांच्या सहाय्यक भूमिकेसाठी भरपाई देणे आवश्यक आहे. व्यवहार सबमिट करणाऱ्या खात्यातून एक छोटे व्यवहार शुल्क कापले गेले - हे शुल्क म्हणजे गॅसच्या जळलेल्या प्रमाणाला (ETH हस्तांतरणासाठी 21000 गॅस युनिट्स) नेटवर्कच्या क्रियाकलापानुसार बदलणाऱ्या बेस फीने गुणले जाते, अधिक व्यवहाराला ब्लॉकमध्ये समाविष्ट करणाऱ्या व्हॅलिडेटरला जाणारी टीप. + +[गॅस](/developers/docs/gas/#post-london) बद्दल अधिक + +टीप: सार्वजनिक नेटवर्कवर, व्यवहार शुल्क नेटवर्कच्या मागणीनुसार आणि तुम्हाला व्यवहार किती लवकर प्रक्रिया करायचा आहे यावर अवलंबून बदलते. तुम्हाला शुल्क कसे मोजले जाते याच्या तपशिलात स्वारस्य असल्यास, माझी ब्लॉकमध्ये व्यवहार कसे समाविष्ट केले जातात यावरील पूर्वीची पोस्ट पाहा. + +## आणि श्वास घ्या {#and-breathe} + +आपण हे बऱ्याच वेळेपासून करत आहोत, त्यामुळे ब्रेक घेण्यासाठी हे एक चांगले ठिकाण आहे. हे गहन जग पुढेही चालू आहे, आणि आपण या मालिकेच्या दुसऱ्या भागात एक्सप्लोर करणे सुरू ठेवू. येणाऱ्या काही संकल्पना: वास्तविक नोडशी कनेक्ट करणे, स्मार्ट कॉन्ट्रॅक्ट्स आणि टोकन्स. तुमचे काही पुढील प्रश्न आहेत का? मला कळवा! तुमचा अभिप्राय आपण येथून पुढे कुठे जायचे हे ठरवेल. [Twitter](https://twitter.com/wolovim) द्वारे विनंत्यांचे स्वागत आहे. diff --git a/public/content/translations/mr/developers/tutorials/all-you-can-cache/index.md b/public/content/translations/mr/developers/tutorials/all-you-can-cache/index.md new file mode 100644 index 00000000000..74ebf5c1c7b --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/all-you-can-cache/index.md @@ -0,0 +1,867 @@ +--- +title: "तुम्ही कॅशे करू शकता ते सर्व" +description: "स्वस्त रोलअप व्यवहारांसाठी कॅशिंग करार कसा तयार करायचा आणि वापरायचा ते शिका" +author: Ori Pomerantz +tags: [ "स्तर 2", "कॅशिंग", "स्टोरेज" ] +skill: intermediate +published: 2022-09-15 +lang: mr +--- + +रोलअप वापरताना, व्यवहारातील एका बाइटची किंमत स्टोरेज स्लॉटच्या किंमतीपेक्षा खूप जास्त असते. म्हणून, शक्य तितकी माहिती ऑनचेन कॅशे करणे अर्थपूर्ण आहे. + +या लेखात, तुम्ही कॅशिंग करार कसा तयार करायचा आणि वापरायचा हे शिकाल. ज्या पॅरामीटर व्हॅल्यूचा अनेक वेळा वापर होण्याची शक्यता आहे, ती कॅशे केली जाईल आणि (पहिल्या वापरानंतर) कमी बाइट्ससह वापरासाठी उपलब्ध होईल. तसेच, हा कॅशे वापरणारा ऑफचेन कोड कसा लिहायचा हेही शिकाल. + +तुम्हाला हा लेख वगळून थेट सोर्स कोड बघायचा असेल, तर [तो इथे आहे](https://github.com/qbzzt/20220915-all-you-can-cache). डेव्हलपमेंट स्टॅक [Foundry](https://getfoundry.sh/introduction/installation/) आहे. + +## एकूण डिझाइन {#overall-design} + +सोपेपणासाठी, आपण असे गृहीत धरू की सर्व व्यवहार पॅरामीटर्स `uint256` आहेत, ज्यांची लांबी 32 बाइट्स आहे. जेव्हा आपल्याला व्यवहार प्राप्त होतो, तेव्हा आपण प्रत्येक पॅरामीटरचे अशा प्रकारे विश्लेषण करू: + +1. जर पहिला बाइट `0xFF` असेल, तर पुढील 32 बाइट्स पॅरामीटर व्हॅल्यू म्हणून घ्या आणि कॅशेमध्ये लिहा. + +2. जर पहिला बाइट `0xFE` असेल, तर पुढील 32 बाइट्स पॅरामीटर व्हॅल्यू म्हणून घ्या, परंतु कॅशेमध्ये लिहू _नका_. + +3. इतर कोणत्याही व्हॅल्यूसाठी, शीर्ष चार बिट्स अतिरिक्त बाइट्सची संख्या म्हणून घ्या आणि खालचे चार बिट्स कॅशे कीचे सर्वात महत्त्वपूर्ण बिट्स म्हणून घ्या. येथे काही उदाहरणे आहेत: + + | कॉलडेटामधील बाइट्स | कॅशे की | + | :----------------- | -------: | + | 0x0F | 0x0F | + | 0x10,0x10 | 0x10 | + | 0x12,0xAC | 0x02AC | + | 0x2D,0xEA, 0xD6 | 0x0DEAD6 | + +## कॅशे मॅनिप्युलेशन {#cache-manipulation} + +कॅशे [`Cache.sol`](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol) मध्ये इम्प्लिमेंट केले आहे. चला ओळीनुसार पाहूया. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + + +contract Cache { + + bytes1 public constant INTO_CACHE = 0xFF; + bytes1 public constant DONT_CACHE = 0xFE; +``` + +हे कॉन्स्टंट्स विशेष प्रकरणांचे अर्थ लावण्यासाठी वापरले जातात, जिथे आपण सर्व माहिती प्रदान करतो आणि ती कॅशेमध्ये लिहावी की नाही हे ठरवतो. कॅशेमध्ये लिहिण्यासाठी पूर्वी न वापरलेल्या स्टोरेज स्लॉटमध्ये प्रत्येकी 22100 गॅसच्या दराने दोन [`SSTORE`](https://www.evm.codes/#55) ऑपरेशन्सची आवश्यकता असते, म्हणून आपण ते ऐच्छिक ठेवतो. + +```solidity + + mapping(uint => uint) public val2key; +``` + +व्हॅल्यूज आणि त्यांच्या कीजमधील [मॅपिंग](https://www.geeksforgeeks.org/solidity/solidity-mappings/). तुम्ही व्यवहार पाठवण्यापूर्वी व्हॅल्यूज एन्कोड करण्यासाठी ही माहिती आवश्यक आहे. + +```solidity + // लोकेशन n मध्ये की n+1 साठी व्हॅल्यू आहे, कारण आपल्याला + // शून्य "कॅशेमध्ये नाही" म्हणून जतन करणे आवश्यक आहे. + uint[] public key2val; +``` + +आपण कीज ते व्हॅल्यूजच्या मॅपिंगसाठी ॲरे वापरू शकतो कारण आपण कीज नियुक्त करतो आणि सोपेपणासाठी आपण ते क्रमाने करतो. + +```solidity + function cacheRead(uint _key) public view returns (uint) { + require(_key <= key2val.length, "Reading uninitialize cache entry"); + return key2val[_key-1]; + } // cacheRead +``` + +कॅशेमधून व्हॅल्यू वाचा. + +```solidity + // एखादी व्हॅल्यू कॅशेमध्ये आधीच नसल्यास ती लिहा + // चाचणी काम करण्यासाठी फक्त पब्लिक + function cacheWrite(uint _value) public returns (uint) { + // जर व्हॅल्यू आधीच कॅशेमध्ये असेल, तर सध्याची की परत करा + if (val2key[_value] != 0) { + return val2key[_value]; + } +``` + +एकच व्हॅल्यू एकापेक्षा जास्त वेळा कॅशेमध्ये टाकण्यात काहीच अर्थ नाही. जर व्हॅल्यू आधीच तिथे असेल, तर फक्त अस्तित्वात असलेली की परत करा. + +```solidity + // 0xFE हा एक विशेष केस असल्यामुळे, कॅशेमध्ये ठेवता येणारी सर्वात मोठी की + // 0x0D आणि त्यानंतर 15 0xFF's आहे. जर कॅशेची लांबी आधीच इतकी + // मोठी असेल, तर फेल करा. + // 1 2 3 4 5 6 7 8 9 A B C D E F + require(key2val.length+1 < 0x0DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + "cache overflow"); +``` + +मला नाही वाटत की आपल्याला इतका मोठा कॅशे कधी मिळेल (अंदाजे 1.8\*1037 नोंदी, ज्यासाठी सुमारे 1027 टीबी स्टोरेज लागेल). तथापि, ["640kB नेहमीच पुरेसे असेल"](https://quoteinvestigator.com/2011/09/08/640k-enough/) हे आठवण्याइतका मी जुना आहे. ही चाचणी खूपच स्वस्त आहे. + +```solidity + // पुढील की वापरून व्हॅल्यू लिहा + val2key[_value] = key2val.length+1; +``` + +रिव्हर्स लुकअप (व्हॅल्यूपासून कीपर्यंत) जोडा. + +```solidity + key2val.push(_value); +``` + +फॉरवर्ड लुकअप (कीपासून व्हॅल्यूपर्यंत) जोडा. कारण आपण व्हॅल्यूज क्रमाने नियुक्त करतो, आपण ते फक्त शेवटच्या ॲरे व्हॅल्यूनंतर जोडू शकतो. + +```solidity + return key2val.length; + } // cacheWrite +``` + +`key2val` ची नवीन लांबी परत करा, जो तो सेल आहे जिथे नवीन व्हॅल्यू संग्रहित केली आहे. + +```solidity + function _calldataVal(uint startByte, uint length) + private pure returns (uint) +``` + +हे फंक्शन कॉलडेटामधून अनियंत्रित लांबीची (32 बाइट्सपर्यंत, वर्ड साइज) व्हॅल्यू वाचते. + +```solidity + { + uint _retVal; + + require(length < 0x21, + "_calldataVal length limit is 32 bytes"); + require(length + startByte <= msg.data.length, + "_calldataVal trying to read beyond calldatasize"); +``` + +हे फंक्शन इंटरनल आहे, त्यामुळे जर उर्वरित कोड योग्यरित्या लिहिला असेल, तर या चाचण्यांची आवश्यकता नाही. तथापि, त्यांची किंमत जास्त नाही म्हणून त्या असण्यात काही हरकत नाही. + +```solidity + assembly { + _retVal := calldataload(startByte) + } +``` + +हा कोड [Yul](https://docs.soliditylang.org/en/v0.8.16/yul.html) मध्ये आहे. हे कॉलडेटामधून 32 बाइट व्हॅल्यू वाचते. जर कॉलडेटा `startByte+32` च्या आधी थांबला तरीही हे कार्य करते कारण EVM मधील अनइनिशियलाइज्ड स्पेस शून्य मानली जाते. + +```solidity + _retVal = _retVal >> (256-length*8); +``` + +आम्हाला 32 बाइट व्हॅल्यूच हवी आहे असे नाही. यामुळे अतिरिक्त बाइट्स काढून टाकले जातात. + +```solidity + return _retVal; + } // _calldataVal + + + // _fromByte पासून सुरू होणाऱ्या कॉलडेटामधून एकच पॅरामीटर वाचा + function _readParam(uint _fromByte) internal + returns (uint _nextByte, uint _parameterValue) + { +``` + +कॉलडेटामधून एकच पॅरामीटर वाचा. लक्षात ठेवा की आम्हाला केवळ आपण वाचलेली व्हॅल्यूच नाही, तर पुढील बाइटचे स्थान देखील परत करणे आवश्यक आहे कारण पॅरामीटर्स 1 बाइट ते 33 बाइट्स लांब असू शकतात. + +```solidity + // पहिला बाइट आपल्याला बाकीच्यांचा अर्थ कसा लावायचा हे सांगतो + uint8 _firstByte; + + _firstByte = uint8(_calldataVal(_fromByte, 1)); +``` + +Solidity संभाव्य धोकादायक [इंप्लिसिट टाइप कन्व्हर्शन्स](https://docs.soliditylang.org/en/v0.8.16/types.html#implicit-conversions) प्रतिबंधित करून बग्सची संख्या कमी करण्याचा प्रयत्न करते. डाउनग्रेड, उदाहरणार्थ 256 बिट्सवरून 8 बिट्सपर्यंत, स्पष्टपणे नमूद करणे आवश्यक आहे. + +```solidity + + // व्हॅल्यू वाचा, पण कॅशेमध्ये लिहू नका + if (_firstByte == uint8(DONT_CACHE)) + return(_fromByte+33, _calldataVal(_fromByte+1, 32)); + + // व्हॅल्यू वाचा आणि कॅशेमध्ये लिहा + if (_firstByte == uint8(INTO_CACHE)) { + uint _param = _calldataVal(_fromByte+1, 32); + cacheWrite(_param); + return(_fromByte+33, _param); + } + + // जर आपण इथे पोहोचलो तर याचा अर्थ आपल्याला कॅशेमधून वाचण्याची गरज आहे + + // वाचण्यासाठी अतिरिक्त बाइट्सची संख्या + uint8 _extraBytes = _firstByte / 16; +``` + +खालचा [निबल](https://en.wikipedia.org/wiki/Nibble) घ्या आणि कॅशेमधून व्हॅल्यू वाचण्यासाठी इतर बाइट्ससह एकत्र करा. + +```solidity + uint _key = (uint256(_firstByte & 0x0F) << (8*_extraBytes)) + + _calldataVal(_fromByte+1, _extraBytes); + + return (_fromByte+_extraBytes+1, cacheRead(_key)); + + } // _readParam + + + // n पॅरामीटर्स वाचा (फंक्शन्सना किती पॅरामीटर्स अपेक्षित आहेत हे माहीत असते) + function _readParams(uint _paramNum) internal returns (uint[] memory) { +``` + +आपण आपल्याकडे असलेल्या पॅरामीटर्सची संख्या कॉलडेटामधूनच मिळवू शकलो असतो, परंतु आपल्याला कॉल करणार्‍या फंक्शन्सना किती पॅरामीटर्स अपेक्षित आहेत हे माहीत असते. त्यांनाच आपल्याला सांगू देणे सोपे आहे. + +```solidity + // आपण वाचलेले पॅरामीटर्स + uint[] memory params = new uint[](_paramNum); + + // पॅरामीटर्स बाइट 4 पासून सुरू होतात, त्याआधी फंक्शन सिग्नेचर असते + uint _atByte = 4; + + for(uint i=0; i<_paramNum; i++) { + (_atByte, params[i]) = _readParam(_atByte); + } +``` + +आपल्याला आवश्यक असलेली संख्या मिळेपर्यंत पॅरामीटर्स वाचा. जर आपण कॉलडेटाच्या पुढे गेलो, तर `_readParams` कॉल रिव्हर्ट करेल. + +```solidity + + return(params); + } // readParams + + // _readParams च्या चाचणीसाठी, चार पॅरामीटर्स वाचण्याची चाचणी + function fourParam() public + returns (uint256,uint256,uint256,uint256) + { + uint[] memory params; + params = _readParams(4); + return (params[0], params[1], params[2], params[3]); + } // fourParam +``` + +Foundry चा एक मोठा फायदा हा आहे की ते Solidity मध्ये चाचण्या लिहिण्याची परवानगी देते ([खालील कॅशेची चाचणी पहा](#testing-the-cache)). यामुळे युनिट टेस्ट्स खूप सोप्या होतात. हे एक फंक्शन आहे जे चार पॅरामीटर्स वाचते आणि त्यांना परत करते जेणेकरून चाचणी ते योग्य होते की नाही हे तपासू शकेल. + +```solidity + // एक व्हॅल्यू मिळवा, असे बाइट्स परत करा जे ते एन्कोड करतील (शक्य असल्यास कॅशे वापरून) + function encodeVal(uint _val) public view returns(bytes memory) { +``` + +`encodeVal` हे एक फंक्शन आहे जे ऑफचेन कोड कॅशे वापरणारा कॉलडेटा तयार करण्यात मदत करण्यासाठी कॉल करते. हे एकच व्हॅल्यू प्राप्त करते आणि ते एन्कोड करणारे बाइट्स परत करते. हे फंक्शन `view` आहे, त्यामुळे त्याला व्यवहाराची आवश्यकता नाही आणि बाहेरून कॉल केल्यावर कोणताही गॅस लागत नाही. + +```solidity + uint _key = val2key[_val]; + + // व्हॅल्यू अजून कॅशेमध्ये नाही, ती जोडा + if (_key == 0) + return bytes.concat(INTO_CACHE, bytes32(_val)); +``` + +[EVM](/developers/docs/evm/) मध्ये सर्व अनइनिशियलाइज्ड स्टोरेज शून्य मानले जाते. त्यामुळे जर आपण अशा व्हॅल्यूसाठी की शोधली जी तिथे नाही, तर आपल्याला शून्य मिळतो. त्या बाबतीत, ते एन्कोड करणारे बाइट्स `INTO_CACHE` (जेणेकरून पुढच्या वेळी ते कॅशे केले जाईल) असतात, त्यानंतर वास्तविक व्हॅल्यू असते. + +```solidity + // जर की <0x10 असेल, तर ती एकच बाइट म्हणून परत करा + if (_key < 0x10) + return bytes.concat(bytes1(uint8(_key))); +``` + +सिंगल बाइट्स सर्वात सोपे आहेत. आपण `bytes` प्रकाराला बाइट ॲरेमध्ये बदलण्यासाठी [`bytes.concat`](https://docs.soliditylang.org/en/v0.8.16/types.html#the-functions-bytes-concat-and-string-concat) वापरतो, ज्याची कोणतीही लांबी असू शकते. नाव असूनही, फक्त एक युक्तिवाद दिल्यावर ते व्यवस्थित काम करते. + +```solidity + // दोन बाइट व्हॅल्यू, 0x1vvv म्हणून एन्कोड केलेली + if (_key < 0x1000) + return bytes.concat(bytes2(uint16(_key) | 0x1000)); +``` + +जेव्हा आपल्याकडे 163 पेक्षा कमी असलेली की असते, तेव्हा आपण ती दोन बाइट्समध्ये व्यक्त करू शकतो. आपण आधी `_key`, जे 256 बिट व्हॅल्यू आहे, ते 16 बिट व्हॅल्यूमध्ये रूपांतरित करतो आणि पहिल्या बाइटमध्ये अतिरिक्त बाइट्सची संख्या जोडण्यासाठी लॉजिकल ऑर वापरतो. मग आपण ते `bytes2` व्हॅल्यूमध्ये टाकतो, जे `bytes` मध्ये रूपांतरित केले जाऊ शकते. + +```solidity + // खालील ओळी लूप म्हणून करण्याचा कदाचित एक हुशार मार्ग आहे, + // पण हे एक व्ह्यू फंक्शन आहे म्हणून मी प्रोग्रामरच्या वेळेसाठी आणि + // सोपेपणासाठी ऑप्टिमाइझ करत आहे. + + if (_key < 16*256**2) + return bytes.concat(bytes3(uint24(_key) | (0x2 * 16 * 256**2))); + if (_key < 16*256**3) + return bytes.concat(bytes4(uint32(_key) | (0x3 * 16 * 256**3))); + . + . + . + if (_key < 16*256**14) + return bytes.concat(bytes15(uint120(_key) | (0xE * 16 * 256**14))); + if (_key < 16*256**15) + return bytes.concat(bytes16(uint128(_key) | (0xF * 16 * 256**15))); +``` + +इतर व्हॅल्यूज (3 बाइट्स, 4 बाइट्स, इत्यादी) त्याच प्रकारे हाताळल्या जातात, फक्त फील्ड आकार भिन्न असतात. + +```solidity + // जर आपण इथे पोहोचलो, तर काहीतरी चुकले आहे. + revert("Error in encodeVal, should not happen"); +``` + +जर आपण इथे पोहोचलो तर याचा अर्थ आपल्याला एक की मिळाली आहे जी 16\*25615 पेक्षा कमी नाही. परंतु `cacheWrite` कीज मर्यादित करते त्यामुळे आपण 14\*25616 पर्यंत पोहोचू शकत नाही (ज्याचा पहिला बाइट 0xFE असेल, म्हणून ते `DONT_CACHE` सारखे दिसेल). परंतु भविष्यात एखादा प्रोग्रामर बग आणल्यास चाचणी जोडण्यासाठी आपल्याला जास्त खर्च येत नाही. + +```solidity + } // encodeVal + +} // Cache +``` + +### कॅशेची चाचणी {#testing-the-cache} + +Foundry चा एक फायदा हा आहे की [ते तुम्हाला Solidity मध्ये चाचण्या लिहिण्याची परवानगी देते](https://getfoundry.sh/forge/tests/overview/), ज्यामुळे युनिट चाचण्या लिहिणे सोपे होते. `Cache` क्लाससाठीच्या चाचण्या [येथे](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/Cache.t.sol) आहेत. कारण चाचणी कोड पुनरावृत्तीचा आहे, जसे चाचण्या असतात, हा लेख फक्त मनोरंजक भाग स्पष्ट करतो. + +```solidity +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; + + +// कन्सोलसाठी `forge test -vv` चालवणे आवश्यक आहे. +import "forge-std/console.sol"; +``` + +हे फक्त बॉयलरप्लेट आहे जे चाचणी पॅकेज आणि `console.log` वापरण्यासाठी आवश्यक आहे. + +```solidity +import "src/Cache.sol"; +``` + +आपण ज्या कराराची चाचणी घेत आहोत ते आपल्याला माहित असणे आवश्यक आहे. + +```solidity +contract CacheTest is Test { + Cache cache; + + function setUp() public { + cache = new Cache(); + } +``` + +`setUp` फंक्शन प्रत्येक चाचणीपूर्वी कॉल केले जाते. या प्रकरणात आपण फक्त एक नवीन कॅशे तयार करतो, जेणेकरून आपल्या चाचण्या एकमेकांवर परिणाम करणार नाहीत. + +```solidity + function testCaching() public { +``` + +चाचण्या ही अशी फंक्शन्स आहेत ज्यांची नावे `test` ने सुरू होतात. हे फंक्शन मूलभूत कॅशे कार्यक्षमता तपासते, व्हॅल्यूज लिहिणे आणि त्या पुन्हा वाचणे. + +```solidity + for(uint i=1; i<5000; i++) { + cache.cacheWrite(i*i); + } + + for(uint i=1; i<5000; i++) { + assertEq(cache.cacheRead(i), i*i); +``` + +[`assert...` फंक्शन्स](https://getfoundry.sh/reference/forge-std/std-assertions/) वापरून तुम्ही प्रत्यक्ष चाचणी कशी करता हे येथे दिले आहे. या प्रकरणात, आम्ही तपासतो की आम्ही लिहिलेली व्हॅल्यू हीच आम्ही वाचलेली व्हॅल्यू आहे. आपण `cache.cacheWrite` चा निकाल सोडून देऊ शकतो कारण आपल्याला माहित आहे की कॅशे की रेषीयपणे नियुक्त केल्या जातात. + +```solidity + } + } // testCaching + + + // एकाच व्हॅल्यूला अनेक वेळा कॅशे करा, की तीच + // राहील याची खात्री करा + function testRepeatCaching() public { + for(uint i=1; i<100; i++) { + uint _key1 = cache.cacheWrite(i); + uint _key2 = cache.cacheWrite(i); + assertEq(_key1, _key2); + } +``` + +प्रथम आम्ही प्रत्येक व्हॅल्यू कॅशेमध्ये दोनदा लिहितो आणि कीज समान असल्याची खात्री करतो (म्हणजे दुसरे लिखाण खरोखरच झाले नाही). + +```solidity + for(uint i=1; i<100; i+=3) { + uint _key = cache.cacheWrite(i); + assertEq(_key, i); + } + } // testRepeatCaching +``` + +सिद्धांतानुसार, एक बग असू शकतो जो सलग कॅशे लेखनावर परिणाम करत नाही. म्हणून येथे आम्ही काही असे लेखन करतो जे सलग नाहीत आणि पाहतो की व्हॅल्यूज अद्याप पुन्हा लिहिल्या जात नाहीत. + +```solidity + // मेमरी बफरमधून एक uint वाचा (आपण पाठवलेले पॅरामीटर्स + // परत मिळतात याची खात्री करण्यासाठी) + function toUint256(bytes memory _bytes, uint256 _start) internal pure + returns (uint256) +``` + +`bytes memory` बफरमधून 256 बिट वर्ड वाचा. हे युटिलिटी फंक्शन आम्हाला कॅशे वापरणारे फंक्शन कॉल चालवल्यावर योग्य परिणाम मिळतात की नाही हे सत्यापित करू देते. + +```solidity + { + require(_bytes.length >= _start + 32, "toUint256_outOfBounds"); + uint256 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x20), _start)) + } +``` + +Yul `uint256` च्या पलीकडे डेटा स्ट्रक्चर्सला समर्थन देत नाही, म्हणून जेव्हा तुम्ही अधिक अत्याधुनिक डेटा स्ट्रक्चरचा संदर्भ देता, जसे की मेमरी बफर `_bytes`, तेव्हा तुम्हाला त्या स्ट्रक्चरचा ॲड्रेस मिळतो. Solidity `bytes memory` व्हॅल्यूज 32 बाइट वर्ड म्हणून संग्रहित करते ज्यात लांबी असते, त्यानंतर वास्तविक बाइट्स असतात, त्यामुळे बाइट क्रमांक `_start` मिळवण्यासाठी आपल्याला `_bytes+32+_start` मोजणे आवश्यक आहे. + +```solidity + + return tempUint; + } // toUint256 + + // fourParams() साठी फंक्शन सिग्नेचर, सौजन्याने + // https://www.4byte.directory/signatures/?bytes4_signature=0x3edc1e6d + bytes4 constant FOUR_PARAMS = 0x3edc1e6d; + + // आपल्याला योग्य व्हॅल्यूज परत मिळत आहेत हे पाहण्यासाठी फक्त काही कॉन्स्टंट व्हॅल्यूज + uint256 constant VAL_A = 0xDEAD60A7; + uint256 constant VAL_B = 0xBEEF; + uint256 constant VAL_C = 0x600D; + uint256 constant VAL_D = 0x600D60A7; +``` + +चाचणीसाठी आपल्याला आवश्यक असलेले काही कॉन्स्टंट्स. + +```solidity + function testReadParam() public { +``` + +`readParams` वापरणारे फंक्शन `fourParams()` ला कॉल करा, जेणेकरून आपण पॅरामीटर्स योग्यरित्या वाचू शकतो की नाही हे तपासता येईल. + +```solidity + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; +``` + +आपण कॅशे वापरून फंक्शन कॉल करण्यासाठी सामान्य ABI यंत्रणा वापरू शकत नाही, म्हणून आपल्याला निम्न स्तरावरील [`
.call()`](https://docs.soliditylang.org/en/v0.8.16/types.html#members-of-addresses) यंत्रणा वापरण्याची आवश्यकता आहे. ती यंत्रणा इनपुट म्हणून `bytes memory` घेते आणि ते (तसेच बुलियन व्हॅल्यू) आउटपुट म्हणून परत करते. + +```solidity + // पहिला कॉल, कॅशे रिकामा आहे + _callInput = bytes.concat( + FOUR_PARAMS, +``` + +एकाच करारासाठी कॅश्ड फंक्शन्स (थेट व्यवहारांमधून कॉल करण्यासाठी) आणि नॉन-कॅश्ड फंक्शन्स (इतर स्मार्ट करारांमधून कॉल करण्यासाठी) दोन्हीला समर्थन देणे उपयुक्त आहे. हे करण्यासाठी, आपल्याला सर्व काही [एका `fallback` फंक्शनमध्ये](https://docs.soliditylang.org/en/v0.8.16/contracts.html#fallback-function) टाकण्याऐवजी, योग्य फंक्शनला कॉल करण्यासाठी Solidity यंत्रणेवर अवलंबून राहणे आवश्यक आहे. हे केल्याने कंपोझेबिलिटी खूप सोपी होते. बहुतेक प्रकरणांमध्ये फंक्शन ओळखण्यासाठी एकच बाइट पुरेसा असेल, म्हणून आपण तीन बाइट्स (16\*3=48 गॅस) वाया घालवत आहोत. तथापि, मी हे लिहित असताना त्या 48 गॅसची किंमत 0.07 सेंट आहे, जी सोप्या, कमी बग प्रोन कोडसाठी वाजवी किंमत आहे. + +```solidity + // पहिली व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), + bytes32(VAL_A), +``` + +पहिली व्हॅल्यू: एक फ्लॅग जो सांगतो की ही एक पूर्ण व्हॅल्यू आहे जी कॅशेमध्ये लिहिली पाहिजे, त्यानंतर व्हॅल्यूचे 32 बाइट्स. इतर तीन व्हॅल्यूज सारख्याच आहेत, फक्त `VAL_B` कॅशेमध्ये लिहिलेली नाही आणि `VAL_C` तिसरा आणि चौथा दोन्ही पॅरामीटर आहे. + +```solidity + . + . + . + ); + (_success, _callOutput) = _cacheAddr.call(_callInput); +``` + +येथेच आपण प्रत्यक्षात `Cache` कराराला कॉल करतो. + +```solidity + assertEq(_success, true); +``` + +आम्ही अपेक्षा करतो की कॉल यशस्वी होईल. + +```solidity + assertEq(cache.cacheRead(1), VAL_A); + assertEq(cache.cacheRead(2), VAL_C); +``` + +आपण रिकाम्या कॅशेने सुरुवात करतो आणि नंतर `VAL_A` आणि त्यानंतर `VAL_C` जोडतो. आम्ही अपेक्षा करतो की पहिल्याची की 1 असेल आणि दुसऱ्याची 2 असेल. + +``` + assertEq(toUint256(_callOutput,0), VAL_A); + assertEq(toUint256(_callOutput,32), VAL_B); + assertEq(toUint256(_callOutput,64), VAL_C); + assertEq(toUint256(_callOutput,96), VAL_C); +``` + +आउटपुट हे चार पॅरामीटर्स आहेत. येथे आम्ही ते योग्य असल्याची पडताळणी करतो. + +```solidity + // दुसरा कॉल, आपण कॅशे वापरू शकतो + _callInput = bytes.concat( + FOUR_PARAMS, + + // कॅशेमधील पहिली व्हॅल्यू + bytes1(0x01), +``` + +16 पेक्षा कमी असलेल्या कॅशे की फक्त एक बाइटच्या असतात. + +```solidity + // दुसरी व्हॅल्यू, ती कॅशेमध्ये जोडू नका + cache.DONT_CACHE(), + bytes32(VAL_B), + + // तिसरी आणि चौथी व्हॅल्यू, समान व्हॅल्यू + bytes1(0x02), + bytes1(0x02) + ); + . + . + . + } // testReadParam +``` + +कॉलनंतरच्या चाचण्या पहिल्या कॉलनंतरच्या चाचण्यांसारख्याच आहेत. + +```solidity + function testEncodeVal() public { +``` + +हे फंक्शन `testReadParam` सारखेच आहे, फक्त फरक एवढाच की पॅरामीटर्स स्पष्टपणे लिहिण्याऐवजी आपण `encodeVal()` वापरतो. + +```solidity + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(VAL_A), + cache.encodeVal(VAL_B), + cache.encodeVal(VAL_C), + cache.encodeVal(VAL_D) + ); + . + . + . + assertEq(_callInput.length, 4+1*4); + } // testEncodeVal +``` + +`testEncodeVal()` मधील एकमेव अतिरिक्त चाचणी म्हणजे `_callInput` ची लांबी योग्य आहे की नाही हे तपासणे. पहिल्या कॉलसाठी ते 4+33\*4 आहे. दुसऱ्यासाठी, जिथे प्रत्येक व्हॅल्यू आधीच कॅशेमध्ये आहे, ते 4+1\*4 आहे. + +```solidity + // जेव्हा की एका बाइटपेक्षा जास्त असेल तेव्हा encodeVal ची चाचणी घ्या + // कमाल तीन बाइट्स कारण कॅशे चार बाइट्सपर्यंत भरण्यास + // खूप वेळ लागतो. + function testEncodeValBig() public { + // कॅशेमध्ये अनेक व्हॅल्यूज ठेवा. + // गोष्टी सोप्या ठेवण्यासाठी, व्हॅल्यू n साठी की n वापरा. + for(uint i=1; i<0x1FFF; i++) { + cache.cacheWrite(i); + } +``` + +वरील `testEncodeVal` फंक्शन कॅशेमध्ये फक्त चार व्हॅल्यूज लिहिते, त्यामुळे [फंक्शनचा जो भाग मल्टी-बाइट व्हॅल्यूज हाताळतो](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/Cache.sol#L144-L171) तो तपासला जात नाही. परंतु तो कोड गुंतागुंतीचा आणि त्रुटी-प्रवण आहे. + +या फंक्शनचा पहिला भाग एक लूप आहे जो 1 ते 0x1FFF पर्यंतच्या सर्व व्हॅल्यूज क्रमाने कॅशेमध्ये लिहितो, जेणेकरून आपण त्या व्हॅल्यूज एन्कोड करू शकू आणि त्या कुठे जात आहेत हे जाणून घेऊ शकू. + +```solidity + . + . + . + + _callInput = bytes.concat( + FOUR_PARAMS, + cache.encodeVal(0x000F), // एक बाइट 0x0F + cache.encodeVal(0x0010), // दोन बाइट्स 0x1010 + cache.encodeVal(0x0100), // दोन बाइट्स 0x1100 + cache.encodeVal(0x1000) // तीन बाइट्स 0x201000 + ); +``` + +एक बाइट, दोन बाइट आणि तीन बाइट व्हॅल्यूजची चाचणी घ्या. आम्ही त्यापलीकडे चाचणी करत नाही कारण पुरेशा स्टॅक नोंदी लिहिण्यासाठी खूप वेळ लागेल (किमान 0x10000000, अंदाजे पाव अब्ज). + +```solidity + . + . + . + . + } // testEncodeValBig + + + // अत्यंत लहान बफरमुळे आपल्याला रिव्हर्ट मिळतो की नाही याची चाचणी + function testShortCalldata() public { +``` + +जेव्हा पुरेसे पॅरामीटर्स नसतात तेव्हा असामान्य परिस्थितीत काय होते याची चाचणी घ्या. + +```solidity + . + . + . + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, false); + } // testShortCalldata +``` + +ते रिव्हर्ट होत असल्याने, आपल्याला मिळणारा निकाल `false` असावा. + +``` + // अस्तित्वात नसलेल्या कॅशे कीजसह कॉल करा + function testNoCacheKey() public { + . + . + . + _callInput = bytes.concat( + FOUR_PARAMS, + + // पहिली व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), + bytes32(VAL_A), + + // दुसरी व्हॅल्यू + bytes1(0x0F), + bytes2(0x1234), + bytes11(0xA10102030405060708090A) + ); +``` + +हे फंक्शन चार पूर्णपणे कायदेशीर पॅरामीटर्स मिळवते, फक्त फरक एवढाच की कॅशे रिकामा आहे त्यामुळे वाचण्यासाठी तेथे कोणतीही व्हॅल्यूज नाहीत. + +```solidity + . + . + . + // अत्यंत लांब बफरसह सर्व काही व्यवस्थित काम करते की नाही याची चाचणी + function testLongCalldata() public { + address _cacheAddr = address(cache); + bool _success; + bytes memory _callInput; + bytes memory _callOutput; + + // पहिला कॉल, कॅशे रिकामा आहे + _callInput = bytes.concat( + FOUR_PARAMS, + + // पहिली व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), bytes32(VAL_A), + + // दुसरी व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), bytes32(VAL_B), + + // तिसरी व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), bytes32(VAL_C), + + // चौथी व्हॅल्यू, ती कॅशेमध्ये जोडा + cache.INTO_CACHE(), bytes32(VAL_D), + + // आणि "गुड लक" साठी आणखी एक व्हॅल्यू + bytes4(0x31112233) + ); +``` + +हे फंक्शन पाच व्हॅल्यूज पाठवते. आम्हाला माहित आहे की पाचवी व्हॅल्यू दुर्लक्षित केली जाते कारण ती वैध कॅशे नोंद नाही, जी समाविष्ट केली नसती तर रिव्हर्ट झाली असती. + +```solidity + (_success, _callOutput) = _cacheAddr.call(_callInput); + assertEq(_success, true); + . + . + . + } // testLongCalldata + +} // CacheTest + +``` + +## एक नमुना ॲप्लिकेशन {#a-sample-app} + +Solidity मध्ये चाचण्या लिहिणे खूप चांगले आहे, पण शेवटी, उपयुक्त होण्यासाठी dapp ला चेनच्या बाहेरून आलेल्या विनंत्यांवर प्रक्रिया करता आली पाहिजे. हा लेख `WORM` सह dapp मध्ये कॅशिंग कसे वापरावे हे दाखवतो, ज्याचा अर्थ "एकदा लिहा, अनेकदा वाचा" असा होतो. जर की अजून लिहिलेली नसेल, तर तुम्ही त्यावर एक व्हॅल्यू लिहू शकता. जर की आधीच लिहिलेली असेल, तर तुम्हाला रिव्हर्ट मिळेल. + +### करार {#the-contract} + +[हा करार आहे](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/src/WORM.sol). हे बहुतेक `Cache` आणि `CacheTest` सह आपण आधीच जे केले आहे त्याचीच पुनरावृत्ती करते, म्हणून आपण फक्त मनोरंजक भाग कव्हर करू. + +```solidity +import "./Cache.sol"; + +contract WORM is Cache { +``` + +`Cache` वापरण्याचा सर्वात सोपा मार्ग म्हणजे तो आपल्या स्वतःच्या करारामध्ये इनहेरिट करणे. + +```solidity + function writeEntryCached() external { + uint[] memory params = _readParams(2); + writeEntry(params[0], params[1]); + } // writeEntryCached +``` + +हे फंक्शन वरील `CacheTest` मधील `fourParam` सारखेच आहे. कारण आपण ABI स्पेसिफिकेशन्सचे पालन करत नाही, त्यामुळे फंक्शनमध्ये कोणतेही पॅरामीटर्स घोषित न करणे चांगले आहे. + +```solidity + // आम्हाला कॉल करणे सोपे करा + // writeEntryCached() साठी फंक्शन सिग्नेचर, सौजन्याने + // https://www.4byte.directory/signatures/?bytes4_signature=0xe4e4f2d3 + bytes4 constant public WRITE_ENTRY_CACHED = 0xe4e4f2d3; +``` + +`writeEntryCached` ला कॉल करणारा बाह्य कोडला `worm.writeEntryCached` वापरण्याऐवजी मॅन्युअली कॉलडेटा तयार करावा लागेल, कारण आम्ही ABI स्पेसिफिकेशन्सचे पालन करत नाही. हे कॉन्स्टंट व्हॅल्यू असल्याने ते लिहिणे सोपे होते. + +लक्षात ठेवा की आम्ही `WRITE_ENTRY_CACHED` ला स्टेट व्हेरिएबल म्हणून परिभाषित केले असले तरी, ते बाहेरून वाचण्यासाठी त्यासाठी गेटर फंक्शन `worm.WRITE_ENTRY_CACHED()` वापरणे आवश्यक आहे. + +```solidity + function readEntry(uint key) public view + returns (uint _value, address _writtenBy, uint _writtenAtBlock) +``` + +रीड फंक्शन `view` आहे, त्यामुळे त्याला व्यवहाराची आवश्यकता नाही आणि गॅस लागत नाही. परिणामी, पॅरामीटरसाठी कॅशे वापरण्याचा कोणताही फायदा नाही. व्ह्यू फंक्शन्ससह, सोपी असलेली मानक यंत्रणा वापरणे सर्वोत्तम आहे. + +### चाचणी कोड {#the-testing-code} + +[हा करारासाठीचा चाचणी कोड आहे](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/test/WORM.t.sol). पुन्हा, आपण फक्त मनोरंजक गोष्टी पाहू. + +```solidity + function testWReadWrite() public { + worm.writeEntry(0xDEAD, 0x60A7); + + vm.expectRevert(bytes("entry already written")); + worm.writeEntry(0xDEAD, 0xBEEF); +``` + +Foundry चाचणीमध्ये पुढील कॉल अयशस्वी व्हावा आणि अयशस्वी होण्याचे नोंदवलेले कारण कसे निर्दिष्ट करावे हे [हे (`vm.expectRevert`)](https://book.getfoundry.sh/cheatcodes/expect-revert#expectrevert) आहे. जेव्हा आपण `.` सिंटॅक्स वापरतो तेव्हा हे लागू होते()` कॉलडेटा तयार करून आणि निम्न-स्तरीय इंटरफेस (`.call()` इत्यादी) वापरून कराराला कॉल करण्याऐवजी. + +```solidity + function testReadWriteCached() public { + uint cacheGoat = worm.cacheWrite(0x60A7); +``` + +येथे आपण या वस्तुस्थितीचा वापर करतो की `cacheWrite` कॅशे की परत करते. हे असे काहीतरी नाही जे आपण उत्पादनात वापरण्याची अपेक्षा करतो, कारण `cacheWrite` स्टेट बदलते आणि म्हणून फक्त व्यवहारादरम्यानच कॉल केले जाऊ शकते. व्यवहारांना रिटर्न व्हॅल्यूज नसतात, जर त्यांचे निकाल असतील तर ते निकाल इव्हेंट म्हणून प्रसारित केले जातात. त्यामुळे `cacheWrite` रिटर्न व्हॅल्यू केवळ ऑनचेन कोडवरूनच ॲक्सेस करता येते आणि ऑनचेन कोडला पॅरामीटर कॅशिंगची आवश्यकता नसते. + +```solidity + (_success,) = address(worm).call(_callInput); +``` + +याद्वारे आपण Solidity ला सांगतो की `.call()` मध्ये दोन रिटर्न व्हॅल्यूज असल्या तरी, आपल्याला फक्त पहिल्याचीच काळजी आहे. + +```solidity + (_success,) = address(worm).call(_callInput); + assertEq(_success, false); +``` + +कारण आपण निम्न-स्तरीय `
.call()` फंक्शन वापरतो, आपण `vm.expectRevert()` वापरू शकत नाही आणि आपल्याला कॉलमधून मिळणाऱ्या बुलियन यश व्हॅल्यूकडे लक्ष द्यावे लागते. + +```solidity + event EntryWritten(uint indexed key, uint indexed value); + + . + . + . + + _callInput = bytes.concat( + worm.WRITE_ENTRY_CACHED(), worm.encodeVal(a), worm.encodeVal(b)); + vm.expectEmit(true, true, false, false); + emit EntryWritten(a, b); + (_success,) = address(worm).call(_callInput); +``` + +Foundry मध्ये कोड [योग्यरित्या इव्हेंट प्रसारित करतो](https://getfoundry.sh/reference/cheatcodes/expect-emit/) की नाही हे तपासण्याचा हा मार्ग आहे. + +### क्लायंट {#the-client} + +Solidity चाचण्यांसोबत एक गोष्ट मिळत नाही ती म्हणजे जावास्क्रिप्ट कोड जो तुम्ही तुमच्या स्वतःच्या ॲप्लिकेशनमध्ये कट आणि पेस्ट करू शकता. तो कोड लिहिण्यासाठी मी WORM ला [Optimism Goerli](https://community.optimism.io/docs/useful-tools/networks/#optimism-goerli) वर तैनात केले, जो [Optimism's](https://www.optimism.io/) नवीन टेस्टनेट आहे. ते [`0xd34335b1d818cee54e3323d3246bd31d94e6a78a`](https://goerli-optimism.etherscan.io/address/0xd34335b1d818cee54e3323d3246bd31d94e6a78a) ॲड्रेसवर आहे. + +[तुम्ही क्लायंटसाठी जावास्क्रिप्ट कोड येथे पाहू शकता](https://github.com/qbzzt/20220915-all-you-can-cache/blob/main/javascript/index.js). ते वापरण्यासाठी: + +1. गिट रिपॉझिटरी क्लोन करा: + + ```sh + git clone https://github.com/qbzzt/20220915-all-you-can-cache.git + ``` + +2. आवश्यक पॅकेजेस स्थापित करा: + + ```sh + cd javascript + yarn + ``` + +3. कॉन्फिगरेशन फाईल कॉपी करा: + + ```sh + cp .env.example .env + ``` + +4. तुमच्या कॉन्फिगरेशनसाठी `.env` संपादित करा: + + | पॅरामीटर | मूल्य | + | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | MNEMONIC | एका खात्यासाठी मेमोनिक ज्यामध्ये व्यवहारासाठी पैसे भरण्यासाठी पुरेसे ETH आहे. [तुम्ही Optimism Goerli नेटवर्कसाठी मोफत ETH येथे मिळवू शकता](https://optimismfaucet.xyz/). | + | OPTIMISM_GOERLI_URL | Optimism Goerli साठी URL. पब्लिक एंडपॉइंट, `https://goerli.optimism.io`, रेट लिमिटेड आहे पण आपल्याला येथे जे हवे आहे त्यासाठी पुरेसा आहे | + +5. `index.js` चालवा. + + ```sh + node index.js + ``` + + हे नमुना ॲप्लिकेशन प्रथम WORM मध्ये एक नोंद लिहिते, कॉलडेटा आणि Etherscan वरील व्यवहाराची लिंक दर्शवते. नंतर ते ती नोंद परत वाचते, आणि ती वापरत असलेली की आणि नोंदीमधील व्हॅल्यूज (व्हॅल्यू, ब्लॉक क्रमांक आणि लेखक) दर्शवते. + +बहुतेक क्लायंट सामान्य Dapp JavaScript आहे. त्यामुळे पुन्हा आपण फक्त मनोरंजक भागांवरच नजर टाकू. + +```javascript +. +. +. +const main = async () => { + const func = await worm.WRITE_ENTRY_CACHED() + + // प्रत्येक वेळी नवीन की आवश्यक आहे + const key = await worm.encodeVal(Number(new Date())) +``` + +दिलेल्या स्लॉटमध्ये फक्त एकदाच लिहिले जाऊ शकते, म्हणून आम्ही स्लॉट पुन्हा वापरत नाही याची खात्री करण्यासाठी टाइमस्टॅम्प वापरतो. + +```javascript +const val = await worm.encodeVal("0x600D") + +// एक नोंद लिहा +const calldata = func + key.slice(2) + val.slice(2) +``` + +Ethers ला कॉल डेटा हेक्स स्ट्रिंग असण्याची अपेक्षा आहे, `0x` नंतर सम संख्येतील हेक्साडेसिमल अंक. `key` आणि `val` दोन्ही `0x` ने सुरू होत असल्याने, आपल्याला ते हेडर काढून टाकणे आवश्यक आहे. + +```javascript +const tx = await worm.populateTransaction.writeEntryCached() +tx.data = calldata + +sentTx = await wallet.sendTransaction(tx) +``` + +Solidity चाचणी कोडप्रमाणे, आपण कॅश्ड फंक्शनला सामान्यपणे कॉल करू शकत नाही. त्याऐवजी, आपल्याला निम्न-स्तरीय यंत्रणा वापरण्याची आवश्यकता आहे. + +```javascript + . + . + . + // नुकतीच लिहिलेली नोंद वाचा + const realKey = '0x' + key.slice(4) // FF फ्लॅग काढा + const entryRead = await worm.readEntry(realKey) + . + . + . +``` + +नोंदी वाचण्यासाठी आपण सामान्य यंत्रणा वापरू शकतो. `view` फंक्शन्ससह पॅरामीटर कॅशिंग वापरण्याची आवश्यकता नाही. + +## निष्कर्ष {#conclusion} + +या लेखातील कोड एक प्रूफ ऑफ कॉन्सेप्ट आहे, उद्देश ही कल्पना समजण्यास सोपी करणे हा आहे. उत्पादनासाठी सज्ज प्रणालीसाठी तुम्ही काही अतिरिक्त कार्यक्षमता लागू करू शकता: + +- `uint256` नसलेल्या व्हॅल्यूज हाताळा. उदाहरणार्थ, स्ट्रिंग्स. +- जागतिक कॅशेऐवजी, कदाचित वापरकर्ते आणि कॅशे यांच्यात मॅपिंग ठेवा. वेगवेगळे वापरकर्ते वेगवेगळ्या व्हॅल्यूज वापरतात. +- ॲड्रेससाठी वापरल्या जाणार्‍या व्हॅल्यूज इतर उद्देशांसाठी वापरल्या जाणार्‍या व्हॅल्यूजपेक्षा वेगळ्या असतात. फक्त ॲड्रेससाठी वेगळा कॅशे असणे अर्थपूर्ण असू शकते. +- सध्या, कॅशे की "प्रथम येणाऱ्यास, सर्वात लहान की" अल्गोरिदमवर आहेत. पहिल्या सोळा व्हॅल्यूज एकाच बाइटमध्ये पाठवल्या जाऊ शकतात. पुढील 4080 व्हॅल्यूज दोन बाइट्समध्ये पाठवल्या जाऊ शकतात. पुढील अंदाजे दहा लाख व्हॅल्यूज तीन बाइट्सच्या आहेत, इत्यादी. एक उत्पादन प्रणालीने कॅशे नोंदींवर वापर काउंटर ठेवावेत आणि त्यांची पुनर्रचना करावी जेणेकरून सोळा _सर्वात सामान्य_ व्हॅल्यूज एक बाइटच्या असतील, पुढील 4080 सर्वात सामान्य व्हॅल्यूज दोन बाइट्सच्या असतील, इत्यादी. + + तथापि, ही एक संभाव्य धोकादायक क्रिया आहे. खालील घटनांचा क्रम कल्पना करा: + + 1. नोआम नेव्ह त्याला टोकन पाठवायचे असलेल्या ॲड्रेसला एन्कोड करण्यासाठी `encodeVal` ला कॉल करतो. तो ॲड्रेस ॲप्लिकेशनवर वापरल्या जाणाऱ्या पहिल्या ॲड्रेसपैकी एक आहे, त्यामुळे एन्कोड केलेली व्हॅल्यू 0x06 आहे. हे एक `view` फंक्शन आहे, व्यवहार नाही, त्यामुळे ते नोआम आणि तो वापरत असलेल्या नोडच्या दरम्यान आहे आणि इतर कोणालाही त्याबद्दल माहिती नाही + + 2. ओवेन ओनर कॅशे पुनर्रचना ऑपरेशन चालवतो. फार कमी लोक प्रत्यक्षात तो ॲड्रेस वापरतात, त्यामुळे तो आता 0x201122 म्हणून एन्कोड केला आहे. एक वेगळी व्हॅल्यू, 1018, 0x06 ला नियुक्त केली आहे. + + 3. नोआम नेव्ह त्याचे टोकन 0x06 वर पाठवतो. ते `0x0000000000000000000000000de0b6b3a7640000` ॲड्रेसवर जातात, आणि त्या ॲड्रेसची प्रायव्हेट की कोणालाच माहीत नसल्याने, ते तिथेच अडकून पडतात. नोआम _खुश नाही_. + + ही समस्या सोडवण्याचे मार्ग आहेत, आणि कॅशे पुनर्रचनेदरम्यान मेमपूलमध्ये असलेल्या व्यवहारांची संबंधित समस्या, पण तुम्हाला त्याबद्दल जागरूक असले पाहिजे. + +मी येथे Optimism सह कॅशिंगचे प्रदर्शन केले आहे, कारण मी Optimism चा कर्मचारी आहे आणि हा रोलअप मला सर्वोत्तम माहीत आहे. परंतु ते कोणत्याही रोलअपसह कार्य केले पाहिजे जे अंतर्गत प्रक्रियेसाठी किमान खर्च आकारते, जेणेकरून तुलनेत L1 वर व्यवहार डेटा लिहिणे हा मोठा खर्च असेल. + +[माझ्या कामाबद्दल अधिक माहितीसाठी येथे पहा](https://cryptodocguy.pro/). + diff --git a/public/content/translations/mr/developers/tutorials/app-plasma/index.md b/public/content/translations/mr/developers/tutorials/app-plasma/index.md new file mode 100644 index 00000000000..9a26c00004e --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/app-plasma/index.md @@ -0,0 +1,1256 @@ +--- +title: "गोपनीयतेचे संरक्षण करणारा ॲप-विशिष्ट प्लाझ्मा लिहा" +description: "या ट्युटोरिअलमध्ये, आम्ही ठेवींसाठी एक अर्ध-गुप्त बँक तयार करतो. बँक एक केंद्रीकृत घटक आहे; तिला प्रत्येक वापरकर्त्याची शिल्लक माहीत असते. तथापि, ही माहिती ऑनचेन साठवली जात नाही. त्याऐवजी, बँक स्टेटचा हॅश पोस्ट करते. प्रत्येक वेळी व्यवहार होतो तेव्हा, बँक नवीन हॅश पोस्ट करते, यासोबतच एक शून्य-ज्ञान पुरावा देखील देते की तिच्याकडे एक स्वाक्षरी केलेला व्यवहार आहे जो हॅश स्टेटला नवीन स्टेटमध्ये बदलतो. हे ट्युटोरिअल वाचल्यानंतर, तुम्हाला शून्य-ज्ञान पुरावे कसे वापरायचे हे तर समजेलच, पण ते का वापरायचे आणि सुरक्षितपणे कसे वापरायचे हे देखील समजेल." +author: Ori Pomerantz +tags: [ "शून्य-ज्ञान", "सर्व्हर", "ऑफचेन", "गोपनीयता" ] +skill: advanced +lang: mr +published: 2025-10-15 +--- + +## प्रस्तावना {#introduction} + +[रोलअप्स](/developers/docs/scaling/zk-rollups/) च्या तुलनेत, [प्लाझ्मा](/developers/docs/scaling/plasma) अखंडतेसाठी Ethereum मेननेट वापरतात, परंतु उपलब्धतेसाठी नाही. या लेखात, आम्ही एक ॲप्लिकेशन लिहितो जे प्लाझ्मासारखे वागते, ज्यात Ethereum अखंडतेची (अनधिकृत बदल नाहीत) हमी देतो परंतु उपलब्धतेची नाही (एक केंद्रीकृत घटक बंद होऊ शकतो आणि संपूर्ण प्रणाली अक्षम करू शकतो). + +आम्ही येथे जे ॲप्लिकेशन लिहित आहोत ते एक गोपनीयता-संरक्षक बँक आहे. वेगवेगळ्या ॲड्रेसवर शिल्लक असलेली खाती आहेत, आणि ते इतर खात्यांमध्ये पैसे (ETH) पाठवू शकतात. बँक स्टेट (खाती आणि त्यांची शिल्लक) आणि व्यवहारांचे हॅश पोस्ट करते, परंतु वास्तविक शिल्लक ऑफचेन ठेवते जिथे ते खाजगी राहू शकतात. + +## डिझाइन {#design} + +ही प्रोडक्शन-रेडी प्रणाली नाही, तर एक शिकवण्याचे साधन आहे. त्यामुळे, ते अनेक सरलीकरण गृहितकांसह लिहिलेले आहे. + +- निश्चित खाते पूल. खात्यांची एक विशिष्ट संख्या आहे, आणि प्रत्येक खाते एका पूर्वनिश्चित ॲड्रेसचे आहे. यामुळे एक अधिक सोपी प्रणाली तयार होते कारण शून्य-ज्ञान पुराव्यांमध्ये व्हेरिएबल-आकाराच्या डेटा स्ट्रक्चर्स हाताळणे कठीण आहे. प्रोडक्शन-रेडी प्रणालीसाठी, आपण [मर्कल रूट](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) स्टेट हॅश म्हणून वापरू शकतो आणि आवश्यक शिलकेसाठी मर्कल पुरावे देऊ शकतो. + +- मेमरी स्टोरेज. प्रोडक्शन प्रणालीवर, रीस्टार्ट झाल्यास सर्व खात्यांमधील शिल्लक जपून ठेवण्यासाठी आम्हाला त्या डिस्कवर लिहिण्याची आवश्यकता आहे. येथे, माहिती सहज गमावली तरी चालेल. + +- फक्त ट्रान्सफर. प्रोडक्शन प्रणालीला बँकेत मालमत्ता जमा करण्याचा आणि त्या काढण्याचा मार्ग आवश्यक असतो. परंतु येथे उद्देश केवळ संकल्पना स्पष्ट करणे आहे, म्हणून ही बँक केवळ ट्रान्सफरपुरती मर्यादित आहे. + +### शून्य-ज्ञान पुरावे {#zero-knowledge-proofs} + +मूलभूत स्तरावर, एक शून्य-ज्ञान पुरावा दर्शवितो की प्रोव्हरला काही डेटा, _Dataprivate_ माहित आहे, जसे की काही सार्वजनिक डेटा, _Datapublic_, आणि _Dataprivate_ यांच्यात एक संबंध _Relationship_ आहे. व्हेरिफायरला _Relationship_ आणि _Datapublic_ माहीत असते. + +गोपनीयता जपण्यासाठी, आपल्याला स्टेट्स आणि व्यवहार खाजगी ठेवण्याची गरज आहे. पण अखंडता सुनिश्चित करण्यासाठी, आम्हाला स्टेट्सचा [क्रिप्टोग्राफिक हॅश](https://en.wikipedia.org/wiki/Cryptographic_hash_function) सार्वजनिक ठेवण्याची गरज आहे. व्यवहार सबमिट करणाऱ्या लोकांना ते व्यवहार खरोखरच झाले आहेत हे सिद्ध करण्यासाठी, आम्हाला व्यवहार हॅश देखील पोस्ट करण्याची आवश्यकता आहे. + +बहुतेक प्रकरणांमध्ये, _Dataprivate_ हे शून्य-ज्ञान पुरावा प्रोग्रामसाठी इनपुट असते आणि _Datapublic_ हे आउटपुट असते. + +_Dataprivate_ मधील ही फील्ड्स: + +- _Staten_, जुनी स्टेट +- _Staten+1_, नवीन स्टेट +- _Transaction_, एक व्यवहार जो जुन्या स्टेटमधून नवीन स्टेटमध्ये बदलतो. या व्यवहारामध्ये ही फील्ड्स समाविष्ट असणे आवश्यक आहे: + - _गंतव्य ॲड्रेस_ जो ट्रान्सफर प्राप्त करतो + - ट्रान्सफर केली जाणारी _रक्कम_ + - प्रत्येक व्यवहारावर एकदाच प्रक्रिया केली जाऊ शकते हे सुनिश्चित करण्यासाठी _नॉन्स_. + स्त्रोत ॲड्रेस व्यवहारामध्ये असण्याची गरज नाही, कारण तो स्वाक्षरीतून परत मिळवता येतो. +- _स्वाक्षरी_, व्यवहार करण्यासाठी अधिकृत असलेली स्वाक्षरी. आमच्या बाबतीत, व्यवहार करण्यासाठी अधिकृत असलेला एकमेव ॲड्रेस स्त्रोत ॲड्रेस आहे. कारण आमची शून्य-ज्ञान प्रणाली ज्या प्रकारे काम करते, आम्हाला Ethereum स्वाक्षरी व्यतिरिक्त, खात्याची सार्वजनिक की देखील आवश्यक आहे. + +ही _Datapublic_ मधील फील्ड्स आहेत: + +- _Hash(Staten)_ जुन्या स्टेटचा हॅश +- _Hash(Staten+1)_ नवीन स्टेटचा हॅश +- _Hash(Transaction)_ त्या व्यवहाराचा हॅश जो स्टेटला _Staten_ मधून _Staten+1_ मध्ये बदलतो. + +संबंध अनेक अटी तपासतो: + +- सार्वजनिक हॅश खरोखरच खाजगी फील्ड्ससाठी योग्य हॅश आहेत. +- व्यवहार, जुन्या स्टेटवर लागू केल्यावर, नवीन स्टेटमध्ये परिणाम करतो. +- स्वाक्षरी व्यवहाराच्या स्त्रोत ॲड्रेसवरून येते. + +क्रिप्टोग्राफिक हॅश फंक्शन्सच्या गुणधर्मांमुळे, या अटी सिद्ध करणे अखंडता सुनिश्चित करण्यासाठी पुरेसे आहे. + +### डेटा स्ट्रक्चर्स {#data-structures} + +प्राथमिक डेटा स्ट्रक्चर सर्व्हरद्वारे धारण केलेली स्टेट आहे. प्रत्येक खात्यासाठी, सर्व्हर खात्याची शिल्लक आणि एक [नॉन्स](https://en.wikipedia.org/wiki/Cryptographic_nonce) चा मागोवा ठेवतो, जो [रिप्ले अटॅक](https://en.wikipedia.org/wiki/Replay_attack) रोखण्यासाठी वापरला जातो. + +### घटक {#components} + +या प्रणालीला दोन घटक आवश्यक आहेत: + +- _सर्व्हर_ जो व्यवहार स्वीकारतो, त्यावर प्रक्रिया करतो, आणि शून्य-ज्ञान पुराव्यांसह हॅश चेनवर पोस्ट करतो. +- एक _स्मार्ट कॉन्ट्रॅक्ट_ जो हॅश साठवतो आणि स्टेट संक्रमण वैध असल्याची खात्री करण्यासाठी शून्य-ज्ञान पुरावे सत्यापित करतो. + +### डेटा आणि नियंत्रण प्रवाह {#flows} + +एका खात्यातून दुसऱ्या खात्यात हस्तांतरण करण्यासाठी विविध घटक ज्या प्रकारे संवाद साधतात ते खालीलप्रमाणे आहेत. + +1. एक वेब ब्राउझर स्वाक्षरी केलेला व्यवहार सबमिट करतो जो स्वाक्षरीकर्त्याच्या खात्यातून वेगळ्या खात्यात हस्तांतरण करण्याची विनंती करतो. + +2. सर्व्हर सत्यापित करतो की व्यवहार वैध आहे: + + - स्वाक्षरीकर्त्याचे बँकेत पुरेशी शिल्लक असलेले खाते आहे. + - प्राप्तकर्त्याचे बँकेत एक खाते आहे. + +3. सर्व्हर स्वाक्षरीकर्त्याच्या शिलकेतून हस्तांतरित केलेली रक्कम वजा करून आणि ती प्राप्तकर्त्याच्या शिलकेत जोडून नवीन स्टेटची गणना करतो. + +4. सर्व्हर एक शून्य-ज्ञान पुरावा तयार करतो की स्टेट बदल वैध आहे. + +5. सर्व्हर Ethereum ला एक व्यवहार सबमिट करतो ज्यात समाविष्ट आहे: + + - नवीन स्टेट हॅश + - व्यवहार हॅश (जेणेकरून व्यवहार पाठवणाऱ्याला कळेल की त्यावर प्रक्रिया झाली आहे) + - शून्य-ज्ञान पुरावा जो नवीन स्टेटमध्ये संक्रमण वैध असल्याचे सिद्ध करतो + +6. स्मार्ट कॉन्ट्रॅक्ट शून्य-ज्ञान पुरावा सत्यापित करतो. + +7. जर शून्य-ज्ञान पुरावा तपासला गेला, तर स्मार्ट कॉन्ट्रॅक्ट या क्रिया करतो: + - सध्याचा स्टेट हॅश नवीन स्टेट हॅशमध्ये अपडेट करणे + - नवीन स्टेट हॅश आणि व्यवहार हॅशसह एक लॉग नोंदणी प्रसारित करणे + +### साधने {#tools} + +क्लायंट-साइड कोडसाठी, आम्ही [Vite](https://vite.dev/), [React](https://react.dev/), [Viem](https://viem.sh/), आणि [Wagmi](https://wagmi.sh/) वापरणार आहोत. ही उद्योग-मानक साधने आहेत; जर तुम्हाला त्यांच्याशी परिचय नसेल, तर तुम्ही [हे ट्यूटोरियल](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) वापरू शकता. + +सर्व्हरचा बहुतांश भाग [Node](https://nodejs.org/en) वापरून JavaScript मध्ये लिहिलेला आहे. शून्य-ज्ञान भाग [Noir](https://noir-lang.org/) मध्ये लिहिलेला आहे. आम्हाला आवृत्ती `1.0.0-beta.10` आवश्यक आहे, म्हणून तुम्ही [निर्देशानुसार Noir इन्स्टॉल](https://noir-lang.org/docs/getting_started/quick_start) केल्यानंतर, चालवा: + +``` +noirup -v 1.0.0-beta.10 +``` + +आपण जो ब्लॉकचेन वापरतो तो `anvil` आहे, एक स्थानिक चाचणी ब्लॉकचेन जो [Foundry](https://getfoundry.sh/introduction/installation) चा भाग आहे. + +## अंमलबजावणी {#implementation} + +कारण ही एक गुंतागुंतीची प्रणाली आहे, आम्ही ती टप्प्याटप्प्याने लागू करू. + +### टप्पा १ - मॅन्युअल शून्य ज्ञान {#stage-1} + +पहिल्या टप्प्यासाठी, आम्ही ब्राउझरमध्ये एका व्यवहारावर स्वाक्षरी करू आणि नंतर मॅन्युअली शून्य-ज्ञान पुराव्याला माहिती देऊ. शून्य-ज्ञान कोडला ती माहिती `server/noir/Prover.toml` मध्ये मिळण्याची अपेक्षा असते ([येथे](https://noir-lang.org/docs/getting_started/project_breakdown#provertoml-1) दस्तऐवजीकरण केलेले). + +ते कृतीत पाहण्यासाठी: + +1. तुम्ही [Node](https://nodejs.org/en/download) आणि [Noir](https://noir-lang.org/install) इन्स्टॉल केले असल्याची खात्री करा. शक्यतो, ते macOS, Linux, किंवा [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) सारख्या UNIX प्रणालीवर इन्स्टॉल करा. + +2. स्टेज 1 कोड डाउनलोड करा आणि क्लायंट कोड सर्व्ह करण्यासाठी वेब सर्व्हर सुरू करा. + + ```sh + git clone https://github.com/qbzzt/250911-zk-bank.git -b 01-manual-zk + cd 250911-zk-bank + cd client + npm install + npm run dev + ``` + + येथे वेब सर्व्हरची गरज असण्याचे कारण म्हणजे, काही प्रकारची फसवणूक टाळण्यासाठी, अनेक वॉलेट्स (जसे की MetaMask) थेट डिस्कवरून सर्व्ह केलेल्या फाइल्स स्वीकारत नाहीत + +3. वॉलेटसह ब्राउझर उघडा. + +4. वॉलेटमध्ये, एक नवीन पासफ्रेज टाका. लक्षात घ्या की यामुळे तुमचा सध्याचा पासफ्रेज हटवला जाईल, म्हणून _तुमच्याकडे बॅकअप असल्याची खात्री करा_. + + पासफ्रेज `test test test test test test test test test test test junk` आहे, जो anvil साठी डीफॉल्ट चाचणी पासफ्रेज आहे. + +5. [क्लायंट-साइड कोड](http://localhost:5173/) वर ब्राउझ करा. + +6. वॉलेटशी कनेक्ट व्हा आणि तुमचे गंतव्य खाते आणि रक्कम निवडा. + +7. **स्वाक्षरी करा** वर क्लिक करा आणि व्यवहारावर स्वाक्षरी करा. + +8. **Prover.toml** शीर्षकाखाली तुम्हाला मजकूर मिळेल. `server/noir/Prover.toml` त्या मजकूराने बदला. + +9. शून्य-ज्ञान पुरावा कार्यान्वित करा. + + ```sh + cd ../server/noir + nargo execute + ``` + + आउटपुट यासारखे असावे + + ``` + ori@CryptoDocGuy:~/noir/250911-zk-bank/server/noir$ nargo execute + + [zkBank] Circuit witness successfully solved + [zkBank] Witness saved to target/zkBank.gz + [zkBank] Circuit output: (0x199aa62af8c1d562a6ec96e66347bf3240ab2afb5d022c895e6bf6a5e617167b, 0x0cfc0a67cb7308e4e9b254026b54204e34f6c8b041be207e64c5db77d95dd82d, 0x450cf9da6e180d6159290554ae3d8787, 0x6d8bc5a15b9037e52fb59b6b98722a85) + ``` + +10. संदेश योग्यरित्या हॅश झाला आहे की नाही हे पाहण्यासाठी वेब ब्राउझरवर दिसणाऱ्या हॅशशी शेवटच्या दोन मूल्यांची तुलना करा. + +#### `server/noir/Prover.toml` {#server-noir-prover-toml} + +[ही फाइल](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/server/noir/Prover.toml) Noir द्वारे अपेक्षित माहितीचे स्वरूप दर्शवते. + +```toml +message="send 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 500 finney (milliEth) 0 " +``` + +संदेश मजकूर स्वरूपात आहे, ज्यामुळे वापरकर्त्याला समजणे सोपे होते (जे स्वाक्षरी करताना आवश्यक आहे) आणि Noir कोडला पार्स करणे सोपे होते. रक्कम फिनीमध्ये उद्धृत केली आहे जेणेकरून एकीकडे अंशात्मक हस्तांतरण सक्षम होईल आणि दुसरीकडे ते सहज वाचता येईल. शेवटची संख्या [नॉन्स](https://en.wikipedia.org/wiki/Cryptographic_nonce) आहे. + +स्ट्रिंग १०० अक्षरांची आहे. शून्य-ज्ञान पुरावे व्हेरिएबल-आकाराचा डेटा चांगल्या प्रकारे हाताळत नाहीत, त्यामुळे डेटा पॅड करणे अनेकदा आवश्यक असते. + +```toml +pubKeyX=["0x83",...,"0x75"] +pubKeyY=["0x35",...,"0xa5"] +signature=["0xb1",...,"0x0d"] +``` + +हे तीन पॅरामीटर्स निश्चित-आकाराचे बाइट ॲरे आहेत. + +```toml +[[accounts]] +address="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" +balance=100_000 +nonce=0 + +[[accounts]] +address="0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +balance=100_000 +nonce=0 +``` + +स्ट्रक्चर्सचा ॲरे निर्दिष्ट करण्याचा हा मार्ग आहे. प्रत्येक नोंदीसाठी, आम्ही ॲड्रेस, शिल्लक (milliETH उर्फ [फिनी](https://cryptovalleyjournal.com/glossary/finney/)), आणि पुढील नॉन्स मूल्य निर्दिष्ट करतो. + +#### `client/src/Transfer.tsx` {#client-src-transfer-tsx} + +[ही फाइल](https://github.com/qbzzt/250911-zk-bank/blob/01-manual-zk/client/src/Transfer.tsx) क्लायंट-साइड प्रोसेसिंग लागू करते आणि `server/noir/Prover.toml` फाइल तयार करते (ज्यामध्ये शून्य-ज्ञान पॅरामीटर्स समाविष्ट आहेत). + +येथे अधिक मनोरंजक भागांचे स्पष्टीकरण दिले आहे. + +```tsx +export default attrs => { +``` + +हे फंक्शन `Transfer` React घटक तयार करते, जे इतर फाइल्स आयात करू शकतात. + +```tsx + const accounts = [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65", + ] +``` + +हे खाते ॲड्रेस आहेत, जे `test ...` test junk` पासफ्रेजने तयार केलेले ॲड्रेस. तुम्हाला तुमचे स्वतःचे ॲड्रेस वापरायचे असल्यास, फक्त ही व्याख्या सुधारा. + +```tsx + const account = useAccount() + const wallet = createWalletClient({ + transport: custom(window.ethereum!) + }) +``` + +हे [Wagmi हुक्स](https://wagmi.sh/react/api/hooks) आम्हाला [viem](https://viem.sh/) लायब्ररी आणि वॉलेटमध्ये प्रवेश करू देतात. + +```tsx + const message = `send ${toAccount} ${ethAmount*1000} finney (milliEth) ${nonce}`.padEnd(100, " ") +``` + +हा संदेश आहे, जागांनी पॅड केलेला. प्रत्येक वेळी [`useState`](https://react.dev/reference/react/useState) व्हेरिएबल्सपैकी एक बदलतो, घटक पुन्हा काढला जातो आणि `message` अपडेट होतो. + +```tsx + const sign = async () => { +``` + +जेव्हा वापरकर्ता **स्वाक्षरी** बटणावर क्लिक करतो तेव्हा हे फंक्शन कॉल केले जाते. संदेश आपोआप अपडेट होतो, परंतु स्वाक्षरीसाठी वॉलेटमध्ये वापरकर्त्याच्या मंजुरीची आवश्यकता असते आणि गरज नसल्यास आम्ही ती विचारू इच्छित नाही. + +```tsx + const signature = await wallet.signMessage({ + account: fromAccount, + message, + }) +``` + +वॉलेटला [संदेशावर स्वाक्षरी करण्यास](https://viem.sh/docs/accounts/local/signMessage) सांगा. + +```tsx + const hash = hashMessage(message) +``` + +संदेश हॅश मिळवा. डीबगिंगसाठी (Noir कोडच्या) वापरकर्त्याला ते प्रदान करणे उपयुक्त आहे. + +```tsx + const pubKey = await recoverPublicKey({ + hash, + signature + }) +``` + +[सार्वजनिक की मिळवा](https://viem.sh/docs/utilities/recoverPublicKey). [Noir `ecrecover`](https://github.com/colinnielsen/ecrecover-noir) फंक्शनसाठी हे आवश्यक आहे. + +```tsx + setSignature(signature) + setHash(hash) + setPubKey(pubKey) +``` + +स्टेट व्हेरिएबल्स सेट करा. हे केल्याने घटक पुन्हा काढला जातो (`sign` फंक्शन बाहेर पडल्यानंतर) आणि वापरकर्त्याला अपडेट केलेली मूल्ये दर्शवितो. + +```tsx + let proverToml = ` +``` + +`Prover.toml` साठी मजकूर. + +```tsx +message="${message}" + +pubKeyX=${hexToArray(pubKey.slice(4,4+2*32))} +pubKeyY=${hexToArray(pubKey.slice(4+2*32))} +``` + +Viem आम्हाला 65-बाइट हेक्साडेसिमल स्ट्रिंग म्हणून सार्वजनिक की प्रदान करते. पहिला बाइट `0x04` आहे, एक आवृत्ती मार्कर. यानंतर सार्वजनिक कीच्या `x` साठी 32 बाइट्स आणि नंतर सार्वजनिक कीच्या `y` साठी 32 बाइट्स येतात. + +तथापि, Noir ला ही माहिती दोन-बाइट ॲरे म्हणून मिळण्याची अपेक्षा आहे, एक `x` साठी आणि एक `y` साठी. शून्य-ज्ञान पुराव्याचा भाग म्हणून पार्स करण्यापेक्षा येथे क्लायंटवर पार्स करणे सोपे आहे. + +लक्षात घ्या की ही सर्वसाधारणपणे शून्य-ज्ञानामध्ये एक चांगली प्रथा आहे. शून्य-ज्ञान पुराव्याच्या आतील कोड महाग असतो, त्यामुळे शून्य-ज्ञान पुराव्याच्या बाहेर करता येणारे कोणतेही प्रोसेसिंग शून्य-ज्ञान पुराव्याच्या बाहेरच _केले पाहिजे_. + +```tsx +signature=${hexToArray(signature.slice(2,-2))} +``` + +स्वाक्षरी देखील 65-बाइट हेक्साडेसिमल स्ट्रिंग म्हणून प्रदान केली जाते. तथापि, शेवटचा बाइट फक्त सार्वजनिक की पुनर्प्राप्त करण्यासाठी आवश्यक आहे. सार्वजनिक की आधीच Noir कोडला प्रदान केली जाईल, त्यामुळे आम्हाला स्वाक्षरी सत्यापित करण्यासाठी त्याची आवश्यकता नाही आणि Noir कोडला त्याची आवश्यकता नाही. + +```tsx +${accounts.map(accountInProverToml).reduce((a,b) => a+b, "")} +` +``` + +खाते प्रदान करा. + +```tsx + setProverToml(proverToml) + } + + return ( + <> +

Transfer

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

Greeter

+ +``` + +आम्हाला RainbowKit कडून [`ConnectButton` घटक](https://www.rainbowkit.com/docs/connect-button) मिळतो. जेव्हा आम्ही कनेक्ट नसतो, तेव्हा ते आम्हाला `Connect Wallet` बटण देते जे एक मोडल उघडते जे वॉलेट्सबद्दल स्पष्ट करते आणि तुम्हाला कोणते वापरायचे आहे ते निवडू देते. जेव्हा आम्ही कनेक्ट असतो, तेव्हा ते आम्ही वापरत असलेले ब्लॉकचेन, आमचा खाते पत्ता आणि आमची ETH शिल्लक दर्शवते. आम्ही नेटवर्क स्विच करण्यासाठी किंवा डिस्कनेक्ट करण्यासाठी हे डिस्प्ले वापरू शकतो. + +```tsx + {isConnected && ( +``` + +जेव्हा आम्हाला JSX मध्ये प्रत्यक्ष JavaScript (किंवा JavaScript मध्ये संकलित केले जाणारे TypeScript) घालण्याची आवश्यकता असते, तेव्हा आम्ही कंस (`{}`) वापरतो. + +`a && b` हे सिंटॅक्स [`a ?` साठी लहान आहे. b : a`](https://www.w3schools.com/react/react_es6_ternary.asp). म्हणजे, जर `a`सत्य असेल तर त्याचे मूल्य`b`होते आणि अन्यथा त्याचे मूल्य`a`होते (जे`false`, `0`, इत्यादी असू शकते). React ला हे सांगण्याचा हा एक सोपा मार्ग आहे की एखादा घटक केवळ तेव्हाच प्रदर्शित केला पाहिजे जेव्हा एखादी विशिष्ट अट पूर्ण होते. + +या प्रकरणात, वापरकर्ता ब्लॉकचेनशी कनेक्ट असल्यास आम्ही फक्त वापरकर्त्याला `Greeter` दाखवू इच्छितो. + +```tsx + + )} + + ) +} +``` + +#### `src/components/Greeter.tsx` {#greeter-tsx} + +या फाइलमध्ये बहुतेक UI कार्यक्षमता आहे. यात अशा व्याख्यांचा समावेश आहे ज्या सामान्यतः एकाधिक फाईल्समध्ये असतील, परंतु हे एक ट्यूटोरियल असल्याने, प्रोग्राम कामगिरी किंवा देखभालीच्या सुलभतेऐवजी पहिल्यांदा समजण्यास सोपे होण्यासाठी ऑप्टिमाइझ केला आहे. + +```tsx +import { useState, ChangeEventHandler } from 'react' +import { useNetwork, + useReadContract, + usePrepareContractWrite, + useContractWrite, + useContractEvent + } from 'wagmi' +``` + +आम्ही ही लायब्ररी फंक्शन्स वापरतो. पुन्हा, ते कुठे वापरले जातात हे खाली स्पष्ट केले आहे. + +```tsx +import { AddressType } from 'abitype' +``` + +[`abitype` लायब्ररी](https://abitype.dev/) आम्हाला विविध Ethereum डेटा प्रकारांसाठी TypeScript व्याख्या प्रदान करते, जसे की [`AddressType`](https://abitype.dev/config#addresstype). + +```tsx +let greeterABI = [ + . + . + . +] as const // greeterABI +``` + +`Greeter` करारासाठी ABI. +जर तुम्ही काँट्रॅक्ट आणि UI एकाच वेळी विकसित करत असाल तर तुम्ही सामान्यतः त्यांना एकाच रेपॉजिटरीमध्ये ठेवाल आणि तुमच्या ऍप्लिकेशनमधील फाइल म्हणून Solidity कंपाइलरद्वारे व्युत्पन्न केलेला ABI वापराल. तथापि, येथे हे आवश्यक नाही कारण करार आधीच विकसित झाला आहे आणि बदलणार नाही. + +```tsx +type AddressPerBlockchainType = { + [key: number]: AddressType +} +``` + +TypeScript स्ट्राँगली टाईप आहे. आम्ही या व्याख्येचा वापर विविध चेन्सवर `Greeter` काँट्रॅक्ट तैनात केलेला पत्ता निर्दिष्ट करण्यासाठी करतो. की ही एक संख्या आहे (chainId), आणि मूल्य एक `AddressType` (एक पत्ता) आहे. + +```tsx +const contractAddrs: AddressPerBlockchainType = { + // Holesky + 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', + + // Sepolia + 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' +} +``` + +दोन समर्थित नेटवर्क्सवर कराराचा पत्ता: [Holesky](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=contact_code) आणि [Sepolia](https://eth-sepolia.blockscout.com/address/0x7143d5c190F048C8d19fe325b748b081903E3BF0?tab=contact_code). + +टीप: प्रत्यक्षात तिसरी व्याख्या आहे, Redstone Holesky साठी, ती खाली स्पष्ट केली जाईल. + +```tsx +type ShowObjectAttrsType = { + name: string, + object: any +} +``` + +हा प्रकार `ShowObject` घटकासाठी पॅरामीटर म्हणून वापरला जातो (नंतर स्पष्ट केला आहे). यात ऑब्जेक्टचे नाव आणि त्याचे मूल्य समाविष्ट आहे, जे डीबगिंगच्या उद्देशाने प्रदर्शित केले जातात. + +```tsx +type ShowGreetingAttrsType = { + greeting: string | undefined +} +``` + +कोणत्याही क्षणी आम्हाला एकतर अभिवादन काय आहे हे माहित असू शकते (कारण आम्ही ते ब्लॉकचेनवरून वाचले आहे) किंवा माहित नाही (कारण आम्हाला ते अद्याप मिळालेले नाही). म्हणून असा प्रकार असणे उपयुक्त आहे जो एकतर स्ट्रिंग किंवा काहीही असू शकतो. + +##### `Greeter` घटक {#greeter-component} + +```tsx +const Greeter = () => { +``` + +शेवटी, आम्ही घटक परिभाषित करतो. + +```tsx + const { chain } = useNetwork() +``` + +आपण वापरत असलेल्या चेनबद्दल माहिती, [wagmi](https://wagmi.sh/react/hooks/useNetwork) च्या सौजन्याने. +कारण हा एक हुक (`use...`) आहे, प्रत्येक वेळी ही माहिती बदलल्यावर घटक पुन्हा काढला जातो. + +```tsx + const greeterAddr = chain && contractAddrs[chain.id] +``` + +Greeter काँट्रॅक्टचा पत्ता, जो चेननुसार बदलतो (आणि जर आमच्याकडे चेन माहिती नसेल किंवा आम्ही त्या काँट्रॅक्टशिवाय चेनवर असू तर तो `undefined` असतो). + +```tsx + const readResults = useReadContract({ + address: greeterAddr, + abi: greeterABI, + functionName: "greet" , // No arguments + watch: true + }) +``` + +[`useReadContract` हुक](https://wagmi.sh/react/api/hooks/useReadContract) एका काँट्रॅक्टमधून माहिती वाचतो. UI मध्ये `readResults` विस्तारून ते नक्की कोणती माहिती परत करते हे तुम्ही पाहू शकता. या प्रकरणात आम्हाला ते शोधत रहायचे आहे जेणेकरून अभिवादन बदलल्यावर आम्हाला सूचित केले जाईल. + +**टीप:** अभिवादन कधी बदलते हे जाणून घेण्यासाठी आणि त्या मार्गाने अपडेट करण्यासाठी आम्ही [`setGreeting` इव्हेंट](https://eth-holesky.blockscout.com/address/0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8?tab=logs) ऐकू शकतो. तथापि, ते अधिक कार्यक्षम असले तरी, ते सर्व बाबतीत लागू होणार नाही. जेव्हा वापरकर्ता वेगळ्या चेनवर स्विच करतो, तेव्हा अभिवादन देखील बदलते, परंतु त्या बदलासोबत इव्हेंट नसतो. आमच्याकडे कोडचा एक भाग इव्हेंट ऐकत असू शकतो आणि दुसरा चेन बदल ओळखण्यासाठी असू शकतो, परंतु ते फक्त [`watch` पॅरामीटर](https://wagmi.sh/react/api/hooks/useReadContract#watch-optional) सेट करण्यापेक्षा अधिक क्लिष्ट असेल. + +```tsx + const [ newGreeting, setNewGreeting ] = useState("") +``` + +React चा [`useState` हुक](https://www.w3schools.com/react/react_usestate.asp) आम्हाला एक स्टेट व्हेरिएबल निर्दिष्ट करू देतो, ज्याचे मूल्य घटकाच्या एका रेंडरिंगपासून दुसऱ्या रेंडरिंगपर्यंत टिकून राहते. प्रारंभिक मूल्य हे पॅरामीटर आहे, या प्रकरणात रिक्त स्ट्रिंग. + +`useState` हुक दोन मूल्यांसह एक सूची परत करतो: + +1. स्टेट व्हेरिएबलचे वर्तमान मूल्य. +2. आवश्यकतेनुसार स्टेट व्हेरिएबलमध्ये बदल करण्यासाठी एक फंक्शन. हा एक हुक असल्याने, प्रत्येक वेळी तो कॉल केल्यावर घटक पुन्हा रेंडर होतो. + +या प्रकरणात, आम्ही वापरकर्त्याने सेट करू इच्छित असलेल्या नवीन अभिवादनासाठी स्टेट व्हेरिएबल वापरत आहोत. + +```tsx + const greetingChange : ChangeEventHandler = (evt) => + setNewGreeting(evt.target.value) +``` + +नवीन अभिवादन इनपुट फील्ड बदलल्यावर हा इव्हेंट हँडलर आहे. प्रकार, [`ChangeEventHandler`](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/), निर्दिष्ट करतो की हा HTML इनपुट घटकाच्या मूल्याच्या बदलासाठी हँडलर आहे. `` भाग वापरला जातो कारण हा एक [जेनेरिक प्रकार](https://www.w3schools.com/typescript/typescript_basic_generics.php) आहे. + +```tsx + const preparedTx = usePrepareContractWrite({ + address: greeterAddr, + abi: greeterABI, + functionName: 'setGreeting', + args: [ newGreeting ] + }) + const workingTx = useContractWrite(preparedTx.config) +``` + +क्लायंटच्या दृष्टिकोनातून ब्लॉकचेन व्यवहार सबमिट करण्याची ही प्रक्रिया आहे: + +1. [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas) वापरून ब्लॉकचेनमधील नोडला व्यवहार पाठवा. +2. नोडकडून प्रतिसादाची प्रतीक्षा करा. +3. जेव्हा प्रतिसाद प्राप्त होतो, तेव्हा वापरकर्त्याला वॉलेटद्वारे व्यवहार साइन करण्यास सांगा. ही पायरी नोड प्रतिसाद मिळाल्यानंतर _घडायलाच हवी_ कारण वापरकर्त्याला साइन करण्यापूर्वी व्यवहाराची गॅस किंमत दर्शविली जाते. +4. वापरकर्त्याच्या मंजुरीची प्रतीक्षा करा. +5. यावेळी [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) वापरून व्यवहार पुन्हा पाठवा. + +पायरी 2 मध्ये लक्षात येण्याजोगा वेळ लागण्याची शक्यता आहे, ज्या दरम्यान वापरकर्त्यांना आश्चर्य वाटेल की त्यांची कमांड खरोखरच युझर इंटरफेसद्वारे प्राप्त झाली आहे की नाही आणि त्यांना आधीच व्यवहार साइन करण्यास का सांगितले जात नाही. त्यामुळे वापरकर्ता अनुभव (UX) वाईट होतो. + +यावरील उपाय म्हणजे [प्रिपेअर हुक्स](https://wagmi.sh/react/prepare-hooks) वापरणे. प्रत्येक वेळी जेव्हा पॅरामीटर बदलतो, तेव्हा लगेच नोडला `eth_estimateGas` विनंती पाठवा. मग, जेव्हा वापरकर्त्याला प्रत्यक्षात व्यवहार पाठवायचा असतो (या प्रकरणात **अपडेट ग्रीटिंग** दाबून), तेव्हा गॅसची किंमत ज्ञात असते आणि वापरकर्ता लगेच वॉलेट पृष्ठ पाहू शकतो. + +```tsx + return ( +``` + +आता आपण शेवटी परत करण्यासाठी वास्तविक HTML तयार करू शकतो. + +```tsx + <> +

Greeter

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

Hello ${loginResponse.extract.nameID}

+ + + `) + res.send(); +``` + +वापरकर्त्याला दाखवण्यासाठी की आम्हाला लॉगिन मिळाले आहे, एक HTML प्रतिसाद पाठवा. + +```typescript + } catch (err) { + console.error('Error processing SAML response:', err); + res.status(400).send('SAML authentication failed'); + } + } +) +``` + +अयशस्वी झाल्यास वापरकर्त्याला कळवा. + +```typescript +spRouter.get('/login', +``` + +जेव्हा ब्राउझर हे पृष्ठ मिळवण्याचा प्रयत्न करतो तेव्हा एक लॉगिन विनंती तयार करा. हे वरील क्रम आकृतीमधील पायरी 1 साठी हँडलर आहे. + +```typescript + async (req, res) => { + const loginRequest = await sp.createLoginRequest(idp, "post") +``` + +लॉगिन विनंती पोस्ट करण्यासाठी माहिती मिळवा. + +```typescript + res.send(` + + + +``` + +हे पृष्ठ फॉर्म (खाली पहा) आपोआप सबमिट करते. यामुळे वापरकर्त्याला पुनर्निर्देशित होण्यासाठी काहीही करण्याची गरज नाही. हे वरील क्रम आकृतीमधील पायरी 2 आहे. + +```typescript +
+``` + +`loginRequest.entityEndpoint` (आयडेंटिटी प्रोव्हायडर एंडपॉईंटची URL) वर पोस्ट करा. + +```typescript + +``` + +इनपुट नाव `loginRequest.type` (`SAMLRequest`) आहे. त्या फिल्डमधील मजकूर `loginRequest.context` आहे, जो पुन्हा base64 एन्कोड केलेला XML आहे. + +```typescript +
+ + + `) + } +) + +app.use(express.urlencoded({extended: true})) +``` + +[हे मिडलवेअर](https://expressjs.com/en/5x/api.html#express.urlencoded) [HTTP विनंती](https://www.tutorialspoint.com/http/http_requests.htm) चा मुख्य भाग वाचतो. डीफॉल्टनुसार एक्सप्रेस त्याकडे दुर्लक्ष करते, कारण बहुतेक विनंत्यांसाठी त्याची आवश्यकता नसते. आम्हाला त्याची आवश्यकता आहे कारण POST मुख्य भाग वापरतो. + +```typescript +app.use(`/${config.spDir}`, spRouter) +``` + +सर्व्हिस प्रोव्हायडर डिरेक्टरी (`/sp`) मध्ये राउटर माउंट करा. + +```typescript +app.get("/", (req, res) => { + res.send(` + + + + + + `) +}) +``` + +जर ब्राउझरला रूट डिरेक्टरी मिळवण्याचा प्रयत्न केल्यास, त्याला लॉगिन पेजची लिंक द्या. + +```typescript +app.listen(config.spPort, () => { + console.log(`service provider is running on http://${config.spHostname}:${config.spPort}`) +}) +``` + +या एक्सप्रेस ॲप्लिकेशनसह `spPort` ऐका. + +#### src/idp.mts + +हा आयडेंटिटी प्रोव्हायडर आहे. हे सर्व्हिस प्रोव्हायडरसारखेच आहे, खालील स्पष्टीकरण वेगळ्या भागांसाठी आहेत. + +```typescript +const xmlParser = new (await import("fast-xml-parser")).XMLParser( + { + ignoreAttributes: false, // Preserve attributes + attributeNamePrefix: "@_", // Prefix for attributes + } +) +``` + +आम्हाला सर्व्हिस प्रोव्हायडरकडून मिळालेली XML विनंती वाचणे आणि समजून घेणे आवश्यक आहे. + +```typescript +const getLoginPage = requestId => ` +``` + +हे फंक्शन वरील क्रम आकृतीमधील पायरी 4 मध्ये परत आलेल्या स्वयंचलित-सबमिट केलेल्या फॉर्मसह पृष्ठ तयार करते. + +```typescript + + + Login page + + +

Login page

+
+ + Email address: +
+ +``` + +आम्ही सर्व्हिस प्रोव्हायडरला दोन फिल्ड्स पाठवतो: + +1. ज्या `requestId` ला आम्ही प्रतिसाद देत आहोत. +2. वापरकर्ता ओळखकर्ता (आम्ही वापरकर्त्याने आतासाठी प्रदान केलेला ईमेल अ‍ॅड्रेस वापरतो). + +```typescript +
+ + + +const idpRouter = express.Router() + +idpRouter.post("/loginSubmitted", async (req, res) => { + const loginResponse = await idp.createLoginResponse( +``` + +हे वरील क्रम आकृतीमधील पायरी 5 साठी हँडलर आहे. [`idp.createLoginResponse`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L73-L125) लॉगिन प्रतिसाद तयार करते. + +```typescript + sp, + { + authnContextClassRef: 'urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport', + audience: sp.entityID, +``` + +श्रोता सर्व्हिस प्रोव्हायडर आहे. + +```typescript + extract: { + request: { + id: req.body.requestId + } + }, +``` + +विनंतीमधून काढलेली माहिती. विनंतीमधील आपल्याला महत्त्वाचा असलेला एक पॅरामीटर म्हणजे requestId, जो सर्व्हिस प्रोव्हायडरला विनंत्या आणि त्यांचे प्रतिसाद जुळवू देतो. + +```typescript + signingKey: { privateKey: idpPrivateKey, publicKey: config.idpCert } // Ensure signing +``` + +प्रतिसादावर स्वाक्षरी करण्यासाठी डेटा मिळवण्यासाठी आम्हाला `signingKey` ची आवश्यकता आहे. सर्व्हिस प्रोव्हायडर स्वाक्षरी नसलेल्या विनंत्यांवर विश्वास ठेवत नाही. + +```typescript + }, + "post", + { + email: req.body.email +``` + +हे फिल्ड आम्ही सर्व्हिस प्रोव्हायडरला परत पाठवत असलेल्या वापरकर्ता माहितीसह आहे. + +```typescript + } + ); + + res.send(` + + + + +
+ +
+ + + `) +}) +``` + +पुन्हा, स्वयंचलित-सबमिट केलेला फॉर्म वापरा. हे वरील क्रम आकृतीमधील पायरी 6 आहे. + +```typescript + +// IdP endpoint for login requests +idpRouter.post(`/login`, +``` + +हा एंडपॉईंट आहे जो सर्व्हिस प्रोव्हायडरकडून लॉगिन विनंती प्राप्त करतो. हे वरील क्रम आकृतीमधील पायरी 3 साठी हँडलर आहे. + +```typescript + async (req, res) => { + try { + // Workaround because I couldn't get parseLoginRequest to work. + // const loginRequest = await idp.parseLoginRequest(sp, 'post', req) + const samlRequest = xmlParser.parse(Buffer.from(req.body.SAMLRequest, 'base64').toString('utf-8')) + res.send(getLoginPage(samlRequest["samlp:AuthnRequest"]["@_ID"])) +``` + +आपण प्रमाणीकरण विनंतीचा आयडी वाचण्यासाठी [`idp.parseLoginRequest`](https://github.com/tngan/samlify/blob/master/src/entity-idp.ts#L127-L144) वापरू शकले पाहिजे. तथापि, मला ते काम करायला जमले नाही आणि त्यावर जास्त वेळ घालवणे योग्य नव्हते म्हणून मी फक्त एक [सामान्य-उद्देशीय XML पार्सर](https://www.npmjs.com/package/fast-xml-parser) वापरतो. आम्हाला आवश्यक असलेली माहिती `` टॅगमधील `ID` विशेषता आहे, जी XML च्या शीर्ष स्तरावर आहे. + +## Ethereum सिग्नेचर वापरणे + +आता आपण सर्व्हिस प्रोव्हायडरला वापरकर्त्याची ओळख पाठवू शकतो, पुढील पायरी म्हणजे विश्वसनीय पद्धतीने वापरकर्त्याची ओळख मिळवणे. Viem आपल्याला वॉलेटमधून वापरकर्त्याचा अ‍ॅड्रेस विचारण्याची परवानगी देतो, पण याचा अर्थ ब्राउझरकडून माहिती विचारणे आहे. आपण ब्राउझरवर नियंत्रण ठेवत नाही, त्यामुळे आपण त्यातून मिळणाऱ्या प्रतिसादावर आपोआप विश्वास ठेवू शकत नाही. + +त्याऐवजी, IdP ब्राउझरला स्वाक्षरी करण्यासाठी एक स्ट्रिंग पाठवेल. जर ब्राउझरमधील वॉलेट या स्ट्रिंगवर स्वाक्षरी करत असेल, तर याचा अर्थ तो खरोखरच तो अ‍ॅड्रेस आहे (म्हणजेच, त्याला अ‍ॅड्रेसशी संबंधित असलेली प्रायव्हेट की माहित आहे). + +हे कृतीत पाहण्यासाठी, विद्यमान IdP आणि SP थांबवा आणि हे कमांड चालवा: + +```sh +git checkout eth-signatures +pnpm install +pnpm start +``` + +नंतर [SP वर](http://localhost:3000) ब्राउझ करा आणि निर्देशांचे पालन करा. + +लक्षात ठेवा की या टप्प्यावर आम्हाला Ethereum अ‍ॅड्रेसवरून ईमेल अ‍ॅड्रेस कसा मिळवायचा हे माहित नाही, म्हणून त्याऐवजी आम्ही SP ला `@bad.email.address` असे रिपोर्ट करतो. + +### तपशीलवार स्पष्टीकरण + +बदल मागील आकृतीमधील पायरी 4-5 मध्ये आहेत. + +![Ethereum सिग्नेचरसह SAML](./fig-05-saml-w-signature.png) + +आम्ही बदललेली एकमेव फाईल `idp.mts` आहे. येथे बदललेले भाग आहेत. + +```typescript +import { v4 as uuidv4 } from 'uuid' +import { verifyMessage } from 'viem' +``` + +आम्हाला या दोन अतिरिक्त लायब्ररींची गरज आहे. आम्ही [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) व्हॅल्यू तयार करण्यासाठी [`uuid`](https://www.npmjs.com/package/uuid) वापरतो. मूल्य स्वतः महत्त्वाचे नाही, फक्त ते एकदाच वापरले जाते हे महत्त्वाचे आहे. + +[`viem`](https://viem.sh/) लायब्ररी आम्हाला Ethereum डेफिनेशन्स वापरण्याची परवानगी देते. येथे आम्हाला स्वाक्षरी खरोखरच वैध आहे की नाही हे तपासण्यासाठी त्याची आवश्यकता आहे. + +```typescript +const loginPrompt = "To access the service provider, sign this nonce: " +``` + +वॉलेट वापरकर्त्याला मेसेजवर स्वाक्षरी करण्याची परवानगी विचारते. फक्त एक नॉन्स असलेला संदेश वापरकर्त्यांना गोंधळात टाकू शकतो, म्हणून आम्ही हा प्रॉम्प्ट समाविष्ट करतो. + +```typescript +// Keep requestIDs here +let nonces = {} +``` + +आम्हाला त्याला प्रतिसाद देण्यासाठी विनंती माहितीची आवश्यकता आहे. आपण ते विनंतीसह पाठवू शकतो (पायरी 4), आणि ते परत मिळवू शकतो (पायरी 5). तथापि, आपण ब्राउझरकडून मिळणाऱ्या माहितीवर विश्वास ठेवू शकत नाही, जो संभाव्यतः शत्रुत्वापूर्ण वापरकर्त्याच्या नियंत्रणाखाली असतो. त्यामुळे ते येथे संग्रहित करणे चांगले आहे, नॉन्सला की म्हणून वापरून. + +लक्षात घ्या की आम्ही हे साधेपणासाठी येथे व्हेरिएबल म्हणून करत आहोत. तथापि, याचे अनेक तोटे आहेत: + +- आपण डिनायल ऑफ सर्व्हिस हल्ल्यासाठी असुरक्षित आहोत. एक दुर्भावनापूर्ण वापरकर्ता अनेक वेळा लॉग ऑन करण्याचा प्रयत्न करू शकतो, ज्यामुळे आमची मेमरी भरली जाईल. +- जर IdP प्रक्रिया पुन्हा सुरू करण्याची आवश्यकता असेल, तर आम्ही विद्यमान मूल्ये गमावतो. +- आपण अनेक प्रक्रिया ओलांडून लोड बॅलन्स करू शकत नाही, कारण प्रत्येकाचे स्वतःचे व्हेरिएबल असेल. + +उत्पादन प्रणालीवर आपण डेटाबेस वापरू आणि काही प्रकारची समाप्ती यंत्रणा लागू करू. + +```typescript +const getSignaturePage = requestId => { + const nonce = uuidv4() + nonces[nonce] = requestId +``` + +एक नॉन्स तयार करा आणि भविष्यातील वापरासाठी `requestId` संग्रहित करा. + +```typescript + return ` + + + + + +

Please sign

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

Current Message:

+

{message}

+ +

New Message:

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

{status}

+ + +
+ +
+) +``` + +तुम्ही हा कोड काळजीपूर्वक स्कॅन केल्यास, तुम्हाला दिसेल की आम्ही आमच्या UI मध्ये आमचे विविध स्टेट व्हेरिएबल्स कुठे वापरतो: + +- ओळी ६-१२ वर, जर वापरकर्त्याचे वॉलेट कनेक्ट केलेले असेल (म्हणजे, `walletAddress.length > 0`), तर आम्ही "walletButton" आयडी असलेल्या बटणामध्ये वापरकर्त्याच्या `walletAddress` ची एक संक्षिप्त आवृत्ती प्रदर्शित करतो; अन्यथा ते फक्त "वॉलेट कनेक्ट करा" असे म्हणते. +- ओळ १७ वर, आम्ही स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला सध्याचा संदेश प्रदर्शित करतो, जो `message` स्ट्रिंगमध्ये कॅप्चर केला जातो. +- ओळी २३-२६ वर, टेक्स्ट फील्डमधील इनपुट बदलल्यावर आमचे `newMessage` स्टेट व्हेरिएबल अपडेट करण्यासाठी आम्ही [नियंत्रित घटक](https://legacy.reactjs.org/docs/forms.html#controlled-components) वापरतो. + +आमच्या स्टेट व्हेरिएबल्स व्यतिरिक्त, तुम्हाला दिसेल की `publishButton` आणि `walletButton` आयडी असलेली बटणे क्लिक केल्यावर अनुक्रमे `connectWalletPressed` आणि `onUpdatePressed` फंक्शन्स कॉल केली जातात. + +शेवटी, चला पाहूया की हा `HelloWorld.js` घटक कुठे जोडला आहे. + +तुम्ही `App.js` फाइलवर गेल्यास, जी React मधील मुख्य घटक आहे जी इतर सर्व घटकांसाठी कंटेनर म्हणून काम करते, तुम्हाला दिसेल की आमचा `HelloWorld.js` घटक ओळ ७ वर इंजेक्ट केला आहे. + +शेवटचे पण महत्त्वाचे, चला तुमच्यासाठी प्रदान केलेली आणखी एक फाइल पाहूया, `interact.js` फाइल. + +#### `interact.js` फाइल {#the-interact-js-file} + +कारण आम्हाला [M-V-C](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller) पॅराडाइमचे पालन करायचे आहे, आम्हाला एक वेगळी फाइल हवी आहे ज्यात आमच्या डॅपच्या तर्कशास्त्र, डेटा आणि नियमांचे व्यवस्थापन करण्यासाठी आमची सर्व फंक्शन्स असतील, आणि नंतर ती फंक्शन्स आमच्या फ्रंटएंडवर (आमचा `HelloWorld.js` घटक) निर्यात करता येतील. + +👆🏽हाच आमच्या `interact.js` फाइलचा नेमका उद्देश आहे! + +तुमच्या `src` डिरेक्टरीमधील `util` फोल्डरवर नेव्हिगेट करा, आणि तुम्हाला दिसेल की आम्ही `interact.js` नावाची फाइल समाविष्ट केली आहे ज्यात आमची सर्व स्मार्ट कॉन्ट्रॅक्ट संवाद आणि वॉलेट फंक्शन्स आणि व्हेरिएबल्स असतील. + +```javascript +// interact.js + +//export const helloWorldContract; + +export const loadCurrentMessage = async () => {} + +export const connectWallet = async () => {} + +const getCurrentWalletConnected = async () => {} + +export const updateMessage = async (message) => {} +``` + +तुम्हाला फाइलच्या शीर्षस्थानी दिसेल की आम्ही `helloWorldContract` ऑब्जेक्टवर टिप्पणी केली आहे. नंतर या ट्युटोरियलमध्ये, आम्ही या ऑब्जेक्टवरील टिप्पणी काढून टाकू आणि या व्हेरिएबलमध्ये आमचे स्मार्ट कॉन्ट्रॅक्ट इन्स्टँटिएट करू, जे आम्ही नंतर आमच्या `HelloWorld.js` घटकामध्ये निर्यात करू. + +आमच्या `helloWorldContract` ऑब्जेक्टनंतरची चार अंमलबजावणी न केलेली फंक्शन्स खालीलप्रमाणे करतात: + +- `loadCurrentMessage` - हे फंक्शन स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला सध्याचा संदेश लोड करण्याच्या तर्कशास्त्राचे व्यवस्थापन करते. ते [Alchemy Web3 API](https://github.com/alchemyplatform/alchemy-web3) वापरून हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्टला _वाचण्याचा_ कॉल करेल. +- `connectWallet` - हे फंक्शन वापरकर्त्याचे MetaMask आमच्या डॅपशी कनेक्ट करेल. +- `getCurrentWalletConnected` - हे फंक्शन तपासेल की Ethereum खाते आधीपासूनच आमच्या डॅपशी पेज लोडवर कनेक्ट केलेले आहे की नाही आणि त्यानुसार आमचे UI अपडेट करेल. +- `updateMessage` - हे फंक्शन स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश अपडेट करेल. हे हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्टला _लिहिण्याचा_ कॉल करेल, त्यामुळे वापरकर्त्याच्या MetaMask वॉलेटला संदेश अपडेट करण्यासाठी Ethereum व्यवहारावर स्वाक्षरी करावी लागेल. + +आता आम्हाला समजले आहे की आम्ही कशावर काम करत आहोत, चला पाहूया की आमच्या स्मार्ट कॉन्ट्रॅक्टमधून कसे वाचायचे! + +### पायरी ३: तुमच्या स्मार्ट कॉन्ट्रॅक्टमधून वाचा {#step-3-read-from-your-smart-contract} + +तुमच्या स्मार्ट कॉन्ट्रॅक्टमधून वाचण्यासाठी, तुम्हाला यशस्वीरित्या सेट अप करावे लागेल: + +- Ethereum चेनशी एक API कनेक्शन +- तुमच्या स्मार्ट कॉन्ट्रॅक्टचे एक लोड केलेले उदाहरण +- तुमच्या स्मार्ट कॉन्ट्रॅक्ट फंक्शनला कॉल करण्यासाठी एक फंक्शन +- तुम्ही स्मार्ट कॉन्ट्रॅक्टमधून वाचत असलेल्या डेटामध्ये बदल झाल्यावर अपडेट्ससाठी पाहण्यासाठी एक श्रोता + +हे खूप पायऱ्या वाटू शकतात, पण काळजी करू नका! आम्ही तुम्हाला त्या प्रत्येक पायरीतून कसे जायचे हे टप्प्याटप्प्याने सांगू! :\) + +#### Ethereum चेनशी एक API कनेक्शन स्थापित करा {#establish-an-api-connection-to-the-ethereum-chain} + +तर लक्षात आहे का, या ट्युटोरियलच्या भाग २ मध्ये, आम्ही आमच्या स्मार्ट कॉन्ट्रॅक्टमधून वाचण्यासाठी आमची [Alchemy Web3 की वापरली होती](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract/interacting-with-a-smart-contract#step-1-install-web3-library)? तुमच्या डॅपमध्ये चेनवरून वाचण्यासाठी तुम्हाला Alchemy Web3 की ची देखील आवश्यकता असेल. + +तुमच्याकडे आधीपासून नसल्यास, प्रथम [Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) इन्स्टॉल करा, तुमच्या `starter-files` च्या रूट डिरेक्टरीवर नेव्हिगेट करून आणि तुमच्या टर्मिनलमध्ये खालील चालवून: + +```text +npm install @alch/alchemy-web3 +``` + +[Alchemy Web3](https://github.com/alchemyplatform/alchemy-web3) हे [Web3.js](https://docs.web3js.org/) च्या सभोवतालचे एक रॅपर आहे, जे एक वेब3 डेव्हलपर म्हणून तुमचे जीवन सोपे करण्यासाठी वर्धित API पद्धती आणि इतर महत्त्वपूर्ण फायदे प्रदान करते. हे कमीत कमी कॉन्फिगरेशन आवश्यक करण्यासाठी डिझाइन केलेले आहे जेणेकरून आपण आपल्या ॲपमध्ये लगेचच त्याचा वापर सुरू करू शकता! + +मग, तुमच्या प्रकल्प डिरेक्टरीमध्ये [dotenv](https://www.npmjs.com/package/dotenv) पॅकेज इन्स्टॉल करा, जेणेकरून आम्ही आमची API की मिळवल्यानंतर ती संग्रहित करण्यासाठी आमच्याकडे एक सुरक्षित जागा असेल. + +```text +npm install dotenv --save +``` + +आमच्या डॅपसाठी, **आम्ही आमची HTTP API की ऐवजी आमची Websockets API की वापरणार आहोत**, कारण ते आम्हाला एक श्रोता सेट करण्याची परवानगी देईल जो स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश बदलल्यावर ओळखतो. + +एकदा तुमच्याकडे तुमची API की आल्यावर, तुमच्या रूट डिरेक्टरीमध्ये `.env` फाइल तयार करा आणि त्यात तुमची Alchemy Websockets url जोडा. त्यानंतर, तुमची `.env` फाइल अशी दिसेल: + +```javascript +REACT_APP_ALCHEMY_KEY = wss://eth-goerli.ws.alchemyapi.io/v2/ +``` + +आता, आम्ही आमच्या डॅपमध्ये आमचा Alchemy Web3 एंडपॉइंट सेट करण्यासाठी तयार आहोत! चला आमच्या `util` फोल्डरमध्ये असलेल्या आमच्या `interact.js` फाइलवर परत जाऊया आणि फाइलच्या शीर्षस्थानी खालील कोड जोडूया: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +//export const helloWorldContract; +``` + +वर, आम्ही प्रथम आमच्या `.env` फाइलमधून Alchemy की आयात केली आणि नंतर आमचा Alchemy Web3 एंडपॉइंट स्थापित करण्यासाठी आमची `alchemyKey` `createAlchemyWeb3` ला पास केली. + +हा एंडपॉइंट तयार झाल्यावर, आमचे स्मार्ट कॉन्ट्रॅक्ट लोड करण्याची वेळ आली आहे! + +#### तुमचे हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्ट लोड करत आहे {#loading-your-hello-world-smart-contract} + +तुमचे हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्ट लोड करण्यासाठी, तुम्हाला त्याचा कॉन्ट्रॅक्ट पत्ता आणि ABI आवश्यक असेल, जे दोन्ही Etherscan वर आढळू शकतात जर तुम्ही [या ट्युटोरियलचा भाग ३ पूर्ण केला असेल.](/developers/tutorials/hello-world-smart-contract-fullstack/#part-3-publish-your-smart-contract-to-etherscan-part-3-publish-your-smart-contract-to-etherscan) + +#### Etherscan वरून तुमचे कॉन्ट्रॅक्ट ABI कसे मिळवायचे {#how-to-get-your-contract-abi-from-etherscan} + +तुम्ही या ट्युटोरियलचा भाग ३ वगळल्यास, तुम्ही [0x6f3f635A9762B47954229Ea479b4541eAF402A6A](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) पत्त्यासह HelloWorld कॉन्ट्रॅक्ट वापरू शकता. त्याचे ABI [येथे](https://goerli.etherscan.io/address/0x6f3f635a9762b47954229ea479b4541eaf402a6a#code) आढळू शकते. + +एक कॉन्ट्रॅक्ट ABI हे निर्दिष्ट करण्यासाठी आवश्यक आहे की कॉन्ट्रॅक्ट कोणते फंक्शन कॉल करेल तसेच फंक्शन तुमच्या अपेक्षित स्वरूपात डेटा परत करेल याची खात्री करण्यासाठी. एकदा आम्ही आमचे कॉन्ट्रॅक्ट ABI कॉपी केल्यावर, चला ते तुमच्या `src` डिरेक्टरीमध्ये `contract-abi.json` नावाची JSON फाइल म्हणून सेव्ह करूया. + +तुमची contract-abi.json तुमच्या src फोल्डरमध्ये संग्रहित केली पाहिजे. + +आमच्या कॉन्ट्रॅक्ट पत्ता, ABI, आणि Alchemy Web3 एंडपॉइंटसह सज्ज, आम्ही आमच्या स्मार्ट कॉन्ट्रॅक्टचे एक उदाहरण लोड करण्यासाठी [कॉन्ट्रॅक्ट पद्धत](https://docs.web3js.org/api/web3-eth-contract/class/Contract) वापरू शकतो. तुमचे कॉन्ट्रॅक्ट ABI `interact.js` फाइलमध्ये आयात करा आणि तुमचा कॉन्ट्रॅक्ट पत्ता जोडा. + +```javascript +// interact.js + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" +``` + +आम्ही आता अखेरीस आमच्या `helloWorldContract` व्हेरिएबलवरील टिप्पणी काढून टाकू शकतो, आणि आमचा AlchemyWeb3 एंडपॉइंट वापरून स्मार्ट कॉन्ट्रॅक्ट लोड करू शकतो: + +```javascript +// interact.js +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +रिकॅप करण्यासाठी, तुमच्या `interact.js` च्या पहिल्या १२ ओळी आता अशा दिसल्या पाहिजेत: + +```javascript +// interact.js + +require("dotenv").config() +const alchemyKey = process.env.REACT_APP_ALCHEMY_KEY +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(alchemyKey) + +const contractABI = require("../contract-abi.json") +const contractAddress = "0x6f3f635A9762B47954229Ea479b4541eAF402A6A" + +export const helloWorldContract = new web3.eth.Contract( + contractABI, + contractAddress +) +``` + +आता आमचे कॉन्ट्रॅक्ट लोड झाले आहे, आम्ही आमचे `loadCurrentMessage` फंक्शन अंमलात आणू शकतो! + +#### तुमच्या `interact.js` फाइलमध्ये `loadCurrentMessage` अंमलात आणणे {#implementing-loadCurrentMessage-in-your-interact-js-file} + +हे फंक्शन खूप सोपे आहे. आम्ही आमच्या कॉन्ट्रॅक्टमधून वाचण्यासाठी एक साधा असिंक वेब3 कॉल करणार आहोत. आमचे फंक्शन स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश परत करेल: + +तुमच्या `interact.js` फाइलमधील `loadCurrentMessage` खालीलप्रमाणे अपडेट करा: + +```javascript +// interact.js + +export const loadCurrentMessage = async () => { + const message = await helloWorldContract.methods.message().call() + return message +} +``` + +आम्हाला हा स्मार्ट कॉन्ट्रॅक्ट आमच्या UI मध्ये प्रदर्शित करायचा असल्याने, चला आमच्या `HelloWorld.js` घटकामधील `useEffect` फंक्शन खालीलप्रमाणे अपडेट करूया: + +```javascript +// HelloWorld.js + +//केवळ एकदाच कॉल केले जाते +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) +}, []) +``` + +लक्षात घ्या, आम्हाला आमचे `loadCurrentMessage` फक्त घटकाच्या पहिल्या रेंडर दरम्यान एकदाच कॉल करायचे आहे. स्मार्ट कॉन्ट्रॅक्टमधील संदेश बदलल्यानंतर UI आपोआप अपडेट करण्यासाठी आम्ही लवकरच `addSmartContractListener` अंमलात आणू. + +आमच्या श्रोत्यामध्ये जाण्यापूर्वी, चला पाहूया की आतापर्यंत आमच्याकडे काय आहे! तुमच्या `HelloWorld.js` आणि `interact.js` फायली सेव्ह करा, आणि नंतर [http://localhost:3000/](http://localhost:3000/) वर जा + +तुम्हाला दिसेल की सध्याचा संदेश आता "नेटवर्कशी कोणतेही कनेक्शन नाही" असे म्हणत नाही. त्याऐवजी ते स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश दर्शवते. छान! + +#### तुमचे UI आता स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश दर्शवला पाहिजे {#your-UI-should-now-reflect-the-message-stored-in-the-smart-contract} + +आता त्या श्रोत्याबद्दल बोलूया... + +#### `addSmartContractListener` अंमलात आणा {#implement-addsmartcontractlistener} + +जर तुम्ही या ट्युटोरियल मालिकेच्या [भाग १](https://docs.alchemy.com/alchemy/tutorials/hello-world-smart-contract#step-10-write-our-contract) मध्ये लिहिलेली `HelloWorld.sol` फाइल आठवत असाल, तर तुम्हाला आठवेल की `UpdatedMessages` नावाचा एक स्मार्ट कॉन्ट्रॅक्ट इव्हेंट आहे जो आमच्या स्मार्ट कॉन्ट्रॅक्टच्या `update` फंक्शनला कॉल केल्यानंतर उत्सर्जित होतो (ओळी ९ आणि २७ पहा): + +```javascript +// HelloWorld.sol + +// सिमेंटिक व्हर्जनिंग वापरून, Solidity ची आवृत्ती निर्दिष्ट करते. +// अधिक जाणून घ्या: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.7.3; + +// `HelloWorld` नावाचे एक कॉन्ट्रॅक्ट परिभाषित करते. +// एक कॉन्ट्रॅक्ट म्हणजे फंक्शन्स आणि डेटा (त्याची स्थिती) यांचा संग्रह. एकदा तैनात झाल्यावर, एक कॉन्ट्रॅक्ट Ethereum ब्लॉकचेनवर एका विशिष्ट पत्त्यावर राहते. अधिक जाणून घ्या: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + //जेव्हा अपडेट फंक्शन कॉल केले जाते तेव्हा उत्सर्जित होते + //स्मार्ट कॉन्ट्रॅक्ट इव्हेंट्स हे तुमच्या कॉन्ट्रॅक्टसाठी तुमच्या ॲपच्या फ्रंट-एंडला ब्लॉकचेनवर काहीतरी घडल्याचे कळवण्याचा एक मार्ग आहे, जे काही विशिष्ट इव्हेंट्ससाठी 'ऐकत' असू शकते आणि ते घडल्यावर कारवाई करू शकते. + event UpdatedMessages(string oldStr, string newStr); + + // `string` प्रकारचा `message` नावाचा एक स्टेट व्हेरिएबल घोषित करते. + // स्टेट व्हेरिएबल्स असे व्हेरिएबल्स आहेत ज्यांची मूल्ये कॉन्ट्रॅक्ट स्टोरेजमध्ये कायमस्वरूपी संग्रहित केली जातात. `public` कीवर्ड व्हेरिएबल्सला कॉन्ट्रॅक्टच्या बाहेरून प्रवेशयोग्य बनवतो आणि एक फंक्शन तयार करतो ज्याला इतर कॉन्ट्रॅक्ट्स किंवा क्लायंट मूल्यामध्ये प्रवेश करण्यासाठी कॉल करू शकतात. + string public message; + + // अनेक वर्ग-आधारित ऑब्जेक्ट-ओरिएंटेड भाषांप्रमाणे, कंस्ट्रक्टर एक विशेष फंक्शन आहे जे फक्त कॉन्ट्रॅक्ट निर्मितीवर कार्यान्वित होते. + // कंस्ट्रक्टरचा वापर कॉन्ट्रॅक्टचा डेटा सुरू करण्यासाठी केला जातो. अधिक जाणून घ्या:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // एक स्ट्रिंग युक्तिवाद `initMessage` स्वीकारते आणि कॉन्ट्रॅक्टच्या `message` स्टोरेज व्हेरिएबलमध्ये मूल्य सेट करते). + message = initMessage; + } + + // एक सार्वजनिक फंक्शन जे स्ट्रिंग युक्तिवाद स्वीकारते आणि `message` स्टोरेज व्हेरिएबल अपडेट करते. + function update(string memory newMessage) public { + string memory oldMsg = message; + message = newMessage; + emit UpdatedMessages(oldMsg, newMessage); + } +} +``` + +स्मार्ट कॉन्ट्रॅक्ट इव्हेंट्स हे तुमच्या कॉन्ट्रॅक्टसाठी तुमच्या फ्रंट-एंड ॲप्लिकेशनला ब्लॉकचेनवर काहीतरी घडल्याचे (म्हणजे, एक _इव्हेंट_ होता) कळवण्याचा एक मार्ग आहे, जे विशिष्ट इव्हेंटसाठी 'ऐकत' असू शकते आणि ते घडल्यावर कारवाई करू शकते. + +`addSmartContractListener` फंक्शन विशेषतः आमच्या हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्टच्या `UpdatedMessages` इव्हेंटसाठी ऐकेल, आणि नवीन संदेश प्रदर्शित करण्यासाठी आमचे UI अपडेट करेल. + +`addSmartContractListener` खालीलप्रमाणे सुधारित करा: + +```javascript +// HelloWorld.js + +function addSmartContractListener() { + helloWorldContract.events.UpdatedMessages({}, (error, data) => { + if (error) { + setStatus("😥 " + error.message) + } else { + setMessage(data.returnValues[1]) + setNewMessage("") + setStatus("🎉 तुमचा संदेश अपडेट झाला आहे!") + } + }) +} +``` + +चला पाहूया की श्रोता इव्हेंट ओळखल्यावर काय होते: + +- इव्हेंट उत्सर्जित झाल्यावर त्रुटी आढळल्यास, ते आमच्या `status` स्टेट व्हेरिएबलद्वारे UI मध्ये दिसेल. +- अन्यथा, आम्ही परत आलेला `data` ऑब्जेक्ट वापरू. `data.returnValues` हा एक ॲरे आहे जो शून्यावर अनुक्रमित आहे जिथे ॲरेमधील पहिला घटक मागील संदेश आणि दुसरा घटक अपडेट केलेला संदेश संग्रहित करतो. एकत्रितपणे, यशस्वी इव्हेंटवर आम्ही आमची `message` स्ट्रिंग अपडेट केलेल्या संदेशावर सेट करू, `newMessage` स्ट्रिंग साफ करू, आणि आमच्या स्मार्ट कॉन्ट्रॅक्टवर नवीन संदेश प्रकाशित झाला आहे हे दर्शविण्यासाठी आमची `status` स्टेट व्हेरिएबल अपडेट करू. + +शेवटी, चला आमच्या `useEffect` फंक्शनमध्ये आमच्या श्रोत्याला कॉल करूया जेणेकरून ते `HelloWorld.js` घटकाच्या पहिल्या रेंडरवर सुरू होईल. एकत्रितपणे, तुमचे `useEffect` फंक्शन असे दिसले पाहिजे: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() +}, []) +``` + +आता आम्ही आमच्या स्मार्ट कॉन्ट्रॅक्टमधून वाचू शकतो, त्यावर कसे लिहायचे हे शोधणे छान होईल! तथापि, आमच्या डॅपवर लिहिण्यासाठी, आमच्याकडे प्रथम एक Ethereum वॉलेट कनेक्ट केलेले असणे आवश्यक आहे. + +तर, पुढे आम्ही आमचे Ethereum वॉलेट (MetaMask) सेट अप करू आणि नंतर ते आमच्या डॅपशी कनेक्ट करू! + +### पायरी ४: तुमचे Ethereum वॉलेट सेट करा {#step-4-set-up-your-ethereum-wallet} + +Ethereum चेनवर काहीही लिहिण्यासाठी, वापरकर्त्यांना त्यांच्या व्हर्च्युअल वॉलेटच्या खाजगी की वापरून व्यवहारांवर स्वाक्षरी करावी लागेल. या ट्युटोरियलसाठी, आम्ही [MetaMask](https://metamask.io/) वापरू, जो ब्राउझरमधील एक व्हर्च्युअल वॉलेट आहे जो तुमच्या Ethereum खात्याचा पत्ता व्यवस्थापित करण्यासाठी वापरला जातो, कारण तो अंतिम-वापरकर्त्यासाठी हे व्यवहार स्वाक्षरी करणे खूप सोपे करतो. + +तुम्हाला Ethereum वरील व्यवहार कसे कार्य करतात याबद्दल अधिक समजून घ्यायचे असल्यास, Ethereum फाउंडेशनचे [हे पेज](/developers/docs/transactions/) पहा. + +#### MetaMask डाउनलोड करा {#download-metamask} + +तुम्ही [येथे](https://metamask.io/download) विनामूल्य MetaMask खाते डाउनलोड आणि तयार करू शकता. तुम्ही खाते तयार करत असताना, किंवा तुमच्याकडे आधीपासूनच खाते असल्यास, वरच्या उजवीकडील “Goerli टेस्ट नेटवर्क” वर स्विच करण्याची खात्री करा (जेणेकरून आपण खऱ्या पैशांशी व्यवहार करत नाही आहोत). + +#### फॉसेटमधून इथर जोडा {#add-ether-from-a-faucet} + +Ethereum ब्लॉकचेनवर व्यवहारावर स्वाक्षरी करण्यासाठी, आम्हाला काही बनावट Eth ची आवश्यकता असेल. Eth मिळवण्यासाठी तुम्ही [FaucETH](https://fauceth.komputing.org) वर जाऊन तुमचा Goerli खात्याचा पत्ता प्रविष्ट करू शकता, “निधीची विनंती करा” वर क्लिक करा, नंतर ड्रॉपडाउनमध्ये “Ethereum टेस्टनेट Goerli” निवडा आणि शेवटी पुन्हा “निधीची विनंती करा” बटणावर क्लिक करा. त्यानंतर लगेचच तुम्हाला तुमच्या MetaMask खात्यात Eth दिसेल! + +#### तुमची शिल्लक तपासा {#check-your-balance} + +आमची शिल्लक आहे की नाही हे पुन्हा तपासण्यासाठी, चला [Alchemy’s composer tool](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"} +``` + +**सूचना:** हा निकाल eth मध्ये नसून wei मध्ये आहे. Wei हे इथरचे सर्वात लहान एकक म्हणून वापरले जाते. wei चे eth मध्ये रूपांतर: 1 eth = 10¹⁸ wei. म्हणून जर आपण 0xde0b6b3a7640000 ला दशांश मध्ये रूपांतरित केले तर आपल्याला 1\*10¹⁸ मिळते, जे 1 eth च्या बरोबर आहे. + +हुश्श! आपले बनावट पैसे तिथेच आहेत! 🤑 + +### पायरी ५: MetaMask ला तुमच्या UI शी कनेक्ट करा {#step-5-connect-metamask-to-your-UI} + +आता आपले MetaMask वॉलेट सेट झाले आहे, चला आपला dapp त्याच्याशी कनेक्ट करूया! + +#### `connectWallet` फंक्शन {#the-connectWallet-function} + +आमच्या `interact.js` फाइलमध्ये, चला `connectWallet` फंक्शन अंमलात आणूया, जे आम्ही नंतर आमच्या `HelloWorld.js` घटकामध्ये कॉल करू शकतो. + +चला `connectWallet` खालीलप्रमाणे सुधारित करूया: + +```javascript +// interact.js + +export const connectWallet = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_requestAccounts", + }) + const obj = { + status: "👆🏽 वरील टेक्स्ट-फील्डमध्ये एक संदेश लिहा.", + address: addressArray[0], + } + return obj + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

+ {" "} + 🦊 + तुम्ही तुमच्या ब्राउझरमध्ये MetaMask, एक व्हर्च्युअल Ethereum वॉलेट, इंस्टॉल करणे आवश्यक आहे. + +

+
+ ), + } + } +} +``` + +तर या मोठ्या कोड ब्लॉकचा नेमका काय उपयोग आहे? + +बरं, प्रथम, ते तुमच्या ब्राउझरमध्ये `window.ethereum` सक्षम आहे की नाही हे तपासते. + +`window.ethereum` हे MetaMask आणि इतर वॉलेट प्रदात्यांद्वारे इंजेक्ट केलेले एक ग्लोबल API आहे जे वेबसाइट्सना वापरकर्त्यांच्या Ethereum खात्यांची विनंती करण्याची परवानगी देते. मंजूर झाल्यास, ते वापरकर्ता कनेक्ट केलेल्या ब्लॉकचेनमधून डेटा वाचू शकते, आणि वापरकर्त्याला संदेश आणि व्यवहारांवर स्वाक्षरी करण्याचे सुचवू शकते. अधिक माहितीसाठी [MetaMask डॉक्स](https://docs.metamask.io/guide/ethereum-provider.html#table-of-contents) तपासा! + +जर `window.ethereum` उपस्थित _नसेल_, तर याचा अर्थ MetaMask स्थापित नाही. यामुळे एक JSON ऑब्जेक्ट परत येतो, जिथे परत केलेला `address` एक रिकामा स्ट्रिंग असतो आणि `status` JSX ऑब्जेक्ट वापरकर्त्याला MetaMask स्थापित करणे आवश्यक असल्याचे सांगतो. + +आता जर `window.ethereum` उपस्थित _असेल_, तर गोष्टी मनोरंजक होतात. + +try/catch लूप वापरून, आम्ही [`window.ethereum.request({ method: "eth_requestAccounts" });`](https://docs.metamask.io/guide/rpc-api.html#eth-requestaccounts) कॉल करून MetaMask शी कनेक्ट करण्याचा प्रयत्न करू. हे फंक्शन कॉल केल्याने ब्राउझरमध्ये MetaMask उघडेल, जिथे वापरकर्त्याला त्यांचे वॉलेट तुमच्या dapp शी कनेक्ट करण्यास सांगितले जाईल. + +- जर वापरकर्त्याने कनेक्ट करणे निवडले, तर `method: "eth_requestAccounts"` एक ॲरे परत करेल ज्यात डॅपशी कनेक्ट केलेल्या वापरकर्त्याच्या सर्व खात्यांचे पत्ते असतील. एकूणच, आमचे `connectWallet` फंक्शन एक JSON ऑब्जेक्ट परत करेल ज्यात या ॲरेमधील _पहिला_ `address` (ओळ 9 पहा) आणि एक `status` संदेश असेल जो वापरकर्त्याला स्मार्ट कॉन्ट्रॅक्टला संदेश लिहिण्यास सांगेल. +- जर वापरकर्त्याने कनेक्शन नाकारले, तर JSON ऑब्जेक्टमध्ये परत केलेल्या `address` साठी एक रिकामा स्ट्रिंग आणि एक `status` संदेश असेल जो वापरकर्त्याने कनेक्शन नाकारले असल्याचे दर्शवेल. + +आता आम्ही हे `connectWallet` फंक्शन लिहिले आहे, पुढची पायरी म्हणजे ते आमच्या `HelloWorld.js` घटकामध्ये कॉल करणे. + +#### `connectWallet` फंक्शन तुमच्या `HelloWorld.js` UI घटकामध्ये जोडा {#add-the-connectWallet-function-to-your-HelloWorld-js-ui-component} + +`HelloWorld.js` मधील `connectWalletPressed` फंक्शनवर नेव्हिगेट करा, आणि ते खालीलप्रमाणे अपडेट करा: + +```javascript +// HelloWorld.js + +const connectWalletPressed = async () => { + const walletResponse = await connectWallet() + setStatus(walletResponse.status) + setWallet(walletResponse.address) +} +``` + +आमच्या `HelloWorld.js` घटकामधून `interact.js` फाइलमधून आमची बहुतेक कार्यक्षमता कशी दूर केली जाते हे लक्षात घ्या? हे असे आहे की आम्ही M-V-C पॅराडाइमचे पालन करतो! + +`connectWalletPressed` मध्ये, आम्ही फक्त आमच्या आयात केलेल्या `connectWallet` फंक्शनला एक await कॉल करतो आणि त्याच्या प्रतिसादाचा वापर करून, आम्ही आमचे `status` आणि `walletAddress` व्हेरिएबल्स त्यांच्या स्टेट हुक्सद्वारे अपडेट करतो. + +आता, चला दोन्ही फायली (`HelloWorld.js` आणि `interact.js`) सेव्ह करूया आणि आतापर्यंत आमच्या UI ची चाचणी घेऊया. + +तुमचा ब्राउझर [http://localhost:3000/](http://localhost:3000/) पेजवर उघडा, आणि पेजच्या वरच्या उजवीकडील "वॉलेट कनेक्ट करा" बटण दाबा. + +तुमच्याकडे MetaMask स्थापित असल्यास, तुम्हाला तुमचे वॉलेट तुमच्या dapp शी जोडण्यास सांगितले जाईल. कनेक्ट करण्याची आमंत्रणे स्वीकारा. + +तुम्हाला दिसेल की वॉलेट बटण आता तुमचा पत्ता कनेक्ट झाला आहे हे दर्शवते! व्वा 🔥 + +पुढे, पृष्ठ रिफ्रेश करण्याचा प्रयत्न करा... हे विचित्र आहे. आमचे वॉलेट बटण आम्हाला MetaMask कनेक्ट करण्यास सांगत आहे, जरी ते आधीच कनेक्ट केलेले असले तरी... + +तथापि, घाबरू नका! आम्ही ते सहजपणे सोडवू शकतो (समजले?) `getCurrentWalletConnected` अंमलात आणून, जे तपासेल की पत्ता आधीपासूनच आमच्या डॅपशी कनेक्ट केलेला आहे की नाही आणि त्यानुसार आमचे UI अपडेट करेल! + +#### `getCurrentWalletConnected` फंक्शन {#the-getcurrentwalletconnected-function} + +`interact.js` फाइलमधील तुमचे `getCurrentWalletConnected` फंक्शन खालीलप्रमाणे अपडेट करा: + +```javascript +// interact.js + +export const getCurrentWalletConnected = async () => { + if (window.ethereum) { + try { + const addressArray = await window.ethereum.request({ + method: "eth_accounts", + }) + if (addressArray.length > 0) { + return { + address: addressArray[0], + status: "👆🏽 वरील टेक्स्ट-फील्डमध्ये एक संदेश लिहा.", + } + } else { + return { + address: "", + status: "🦊 वरच्या उजव्या बटणाचा वापर करून MetaMask शी कनेक्ट करा.", + } + } + } catch (err) { + return { + address: "", + status: "😥 " + err.message, + } + } + } else { + return { + address: "", + status: ( + +

+ {" "} + 🦊 + तुम्ही तुमच्या ब्राउझरमध्ये MetaMask, एक व्हर्च्युअल Ethereum वॉलेट, इंस्टॉल करणे आवश्यक आहे. + +

+
+ ), + } + } +} +``` + +हा कोड आम्ही मागील पायरीमध्ये लिहिलेल्या `connectWallet` फंक्शनसारखाच _खूप_ आहे. + +मुख्य फरक असा आहे की `eth_requestAccounts` या पद्धतीला कॉल करण्याऐवजी, जे वापरकर्त्याला त्यांचे वॉलेट कनेक्ट करण्यासाठी MetaMask उघडते, येथे आपण `eth_accounts` ही पद्धत कॉल करतो, जी सध्या आपल्या dapp शी कनेक्ट केलेल्या MetaMask ॲड्रेसची एक ॲरे परत करते. + +हे फंक्शन कृतीत पाहण्यासाठी, चला ते आमच्या `HelloWorld.js` घटकाच्या `useEffect` फंक्शनमध्ये कॉल करूया: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) +}, []) +``` + +लक्षात घ्या, आम्ही आमच्या `getCurrentWalletConnected` च्या कॉलच्या प्रतिसादाचा वापर आमचे `walletAddress` आणि `status` स्टेट व्हेरिएबल्स अपडेट करण्यासाठी करतो. + +आता तुम्ही हा कोड जोडला आहे, चला आमचे ब्राउझर विंडो रिफ्रेश करून पाहूया. + +छान! बटण तुम्हाला कनेक्ट झाल्याचे सांगेल आणि तुमच्या कनेक्ट केलेल्या वॉलेटच्या ॲड्रेसचे पूर्वावलोकन दाखवेल - जरी तुम्ही रिफ्रेश केले तरी! + +#### `addWalletListener` अंमलात आणा {#implement-addwalletlistener} + +आमच्या dapp वॉलेट सेटअपमधील शेवटची पायरी म्हणजे वॉलेट लिसनर लागू करणे जेणेकरून आमच्या वॉलेटची स्थिती बदलल्यावर आमचे UI अपडेट होईल, जसे की वापरकर्ता डिस्कनेक्ट झाल्यावर किंवा खाती बदलल्यावर. + +तुमच्या `HelloWorld.js` फाइलमध्ये, तुमचे `addWalletListener` फंक्शन खालीलप्रमाणे सुधारित करा: + +```javascript +// HelloWorld.js + +function addWalletListener() { + if (window.ethereum) { + window.ethereum.on("accountsChanged", (accounts) => { + if (accounts.length > 0) { + setWallet(accounts[0]) + setStatus("👆🏽 वरील टेक्स्ट-फील्डमध्ये एक संदेश लिहा.") + } else { + setWallet("") + setStatus("🦊 वरच्या उजव्या बटणाचा वापर करून MetaMask शी कनेक्ट करा.") + } + }) + } else { + setStatus( +

+ {" "} + 🦊 + तुम्ही तुमच्या ब्राउझरमध्ये MetaMask, एक व्हर्च्युअल Ethereum वॉलेट, इंस्टॉल करणे आवश्यक आहे. + +

+ ) + } +} +``` + +मला खात्री आहे की तुम्हाला या टप्प्यावर काय चालले आहे हे समजून घेण्यासाठी आमच्या मदतीची गरज नाही, परंतु संपूर्णतेच्या उद्देशाने, चला ते पटकन पाहूया: + +- प्रथम, आमचे फंक्शन तपासते की `window.ethereum` सक्षम आहे का (म्हणजे MetaMask स्थापित आहे का). + - जर ते नसेल, तर आम्ही फक्त आमचे `status` स्टेट व्हेरिएबल एका JSX स्ट्रिंगवर सेट करतो जे वापरकर्त्याला MetaMask स्थापित करण्यास सांगते. + - जर ते सक्षम असेल, तर आम्ही ओळ 3 वर `window.ethereum.on("accountsChanged")` हा लिसनर सेट करतो जो MetaMask वॉलेटमधील स्टेट बदलांसाठी ऐकतो, ज्यात वापरकर्ता dapp शी अतिरिक्त खाते जोडतो, खाती बदलतो किंवा खाते डिस्कनेक्ट करतो. जर किमान एक खाते कनेक्ट केलेले असेल, तर `walletAddress` स्टेट व्हेरिएबल लिसनरद्वारे परत केलेल्या `accounts` ॲरेमधील पहिले खाते म्हणून अपडेट केले जाते. अन्यथा, `walletAddress` एक रिकामा स्ट्रिंग म्हणून सेट केला जातो. + +शेवटचे पण महत्त्वाचे, आम्ही ते आमच्या `useEffect` फंक्शनमध्ये कॉल करणे आवश्यक आहे: + +```javascript +// HelloWorld.js + +useEffect(async () => { + const message = await loadCurrentMessage() + setMessage(message) + addSmartContractListener() + + const { address, status } = await getCurrentWalletConnected() + setWallet(address) + setStatus(status) + + addWalletListener() +}, []) +``` + +आणि झाले! आम्ही आमच्या सर्व वॉलेट कार्यक्षमतेचे प्रोग्रामिंग यशस्वीरित्या पूर्ण केले आहे! आता आमच्या शेवटच्या कार्याकडे: आमच्या स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित केलेला संदेश अपडेट करणे! + +### पायरी ६: `updateMessage` फंक्शन अंमलात आणा {#step-6-implement-the-updateMessage-function} + +ठीक आहे मित्रांनो, आपण अंतिम टप्प्यात आलो आहोत! तुमच्या `interact.js` फाइलच्या `updateMessage` मध्ये, आम्ही खालील गोष्टी करणार आहोत: + +1. आम्हाला आमच्या स्मार्ट संपर्कात प्रकाशित करायचा असलेला संदेश वैध असल्याची खात्री करा +2. MetaMask वापरून आमच्या व्यवहारावर स्वाक्षरी करा +3. या फंक्शनला आमच्या `HelloWorld.js` फ्रंटएंड घटकामधून कॉल करा + +याला जास्त वेळ लागणार नाही; चला हा डॅप पूर्ण करूया! + +#### इनपुट एरर हाताळणी {#input-error-handling} + +स्वाभाविकच, फंक्शनच्या सुरुवातीला काही प्रकारचे इनपुट त्रुटी हाताळणी असणे अर्थपूर्ण आहे. + +आम्ही इच्छितो की जर MetaMask विस्तार स्थापित नसेल, कोणतेही वॉलेट कनेक्ट केलेले नसेल (म्हणजे, पास केलेला `address` एक रिकामा स्ट्रिंग आहे), किंवा `message` एक रिकामा स्ट्रिंग असेल तर आमचे फंक्शन लवकर परत यावे. चला `updateMessage` मध्ये खालील त्रुटी हाताळणी जोडूया: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + if (!window.ethereum || address === null) { + return { + status: + "💡 ब्लॉकचेनवरील संदेश अपडेट करण्यासाठी तुमचे MetaMask वॉलेट कनेक्ट करा.", + } + } + + if (message.trim() === "") { + return { + status: "❌ तुमचा संदेश रिकामा स्ट्रिंग असू शकत नाही.", + } + } +} +``` + +आता त्यात योग्य इनपुट त्रुटी हाताळणी आहे, MetaMask द्वारे व्यवहारावर स्वाक्षरी करण्याची वेळ आली आहे! + +#### आमच्या व्यवहारावर स्वाक्षरी करणे {#signing-our-transaction} + +तुम्ही आधीपासूनच पारंपरिक वेब3 Ethereum व्यवहारांशी परिचित असाल, तर आम्ही पुढे लिहिणारा कोड खूप परिचित असेल. तुमच्या इनपुट त्रुटी हाताळणी कोडच्या खाली, `updateMessage` मध्ये खालील जोडा: + +```javascript +// interact.js + +//व्यवहार पॅरामीटर्स सेट करा +const transactionParameters = { + to: contractAddress, // कॉन्ट्रॅक्ट प्रकाशनांशिवाय आवश्यक. + from: address, // वापरकर्त्याच्या सक्रिय पत्त्याशी जुळले पाहिजे. + data: helloWorldContract.methods.update(message).encodeABI(), +} + +//व्यवहारावर स्वाक्षरी करा +try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Etherscan वर तुमच्या व्यवहाराची स्थिती पहा! + +
+ ℹ️ एकदा नेटवर्कद्वारे व्यवहाराची पडताळणी झाल्यावर, संदेश आपोआप अपडेट होईल. +
+ ), + } +} catch (error) { + return { + status: "😥 " + error.message, + } +} +``` + +चला पाहूया की काय चालले आहे. प्रथम, आम्ही आमचे व्यवहार पॅरामीटर्स सेट करतो, जिथे: + +- `to` प्राप्तकर्ता ॲड्रेस (आमचा स्मार्ट कॉन्ट्रॅक्ट) निर्दिष्ट करतो +- `from` व्यवहाराच्या स्वाक्षरीकर्त्याला निर्दिष्ट करते, आम्ही आमच्या फंक्शनमध्ये पास केलेला `address` व्हेरिएबल +- `data` मध्ये आमच्या हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्टच्या `update` पद्धतीचा कॉल आहे, जो आमचा `message` स्ट्रिंग व्हेरिएबल इनपुट म्हणून घेतो + +मग, आम्ही एक await कॉल करतो, `window.ethereum.request`, जिथे आम्ही MetaMask ला व्यवहारावर स्वाक्षरी करण्यास सांगतो. लक्षात घ्या, ओळी ११ आणि १२ वर, आम्ही आमची eth पद्धत, `eth_sendTransaction` निर्दिष्ट करत आहोत आणि आमचे `transactionParameters` पास करत आहोत. + +या टप्प्यावर, MetaMask ब्राउझरमध्ये उघडेल आणि वापरकर्त्याला व्यवहारावर सही करण्यास किंवा नाकारण्यास सांगेल. + +- जर व्यवहार यशस्वी झाला, तर फंक्शन एक JSON ऑब्जेक्ट परत करेल जिथे `status` JSX स्ट्रिंग वापरकर्त्याला त्यांच्या व्यवहाराबद्दल अधिक माहितीसाठी Etherscan तपासण्यास सांगते. +- जर व्यवहार अयशस्वी झाला, तर फंक्शन एक JSON ऑब्जेक्ट परत करेल जिथे `status` स्ट्रिंग त्रुटी संदेश प्रसारित करते. + +एकत्रितपणे, आमचे `updateMessage` फंक्शन असे दिसले पाहिजे: + +```javascript +// interact.js + +export const updateMessage = async (address, message) => { + //इनपुट त्रुटी हाताळणी + if (!window.ethereum || address === null) { + return { + status: + "💡 ब्लॉकचेनवरील संदेश अपडेट करण्यासाठी तुमचे MetaMask वॉलेट कनेक्ट करा.", + } + } + + if (message.trim() === "") { + return { + status: "❌ तुमचा संदेश रिकामा स्ट्रिंग असू शकत नाही.", + } + } + + //व्यवहार पॅरामीटर्स सेट करा + const transactionParameters = { + to: contractAddress, // कॉन्ट्रॅक्ट प्रकाशनांशिवाय आवश्यक. + from: address, // वापरकर्त्याच्या सक्रिय पत्त्याशी जुळले पाहिजे. + data: helloWorldContract.methods.update(message).encodeABI(), + } + + //व्यवहारावर स्वाक्षरी करा + try { + const txHash = await window.ethereum.request({ + method: "eth_sendTransaction", + params: [transactionParameters], + }) + return { + status: ( + + ✅{" "} + + Etherscan वर तुमच्या व्यवहाराची स्थिती पहा! + +
+ ℹ️ एकदा नेटवर्कद्वारे व्यवहाराची पडताळणी झाल्यावर, संदेश आपोआप अपडेट होईल. +
+ ), + } + } catch (error) { + return { + status: "😥 " + error.message, + } + } +} +``` + +शेवटचे पण महत्त्वाचे, आम्हाला आमचे `updateMessage` फंक्शन आमच्या `HelloWorld.js` घटकाशी कनेक्ट करणे आवश्यक आहे. + +#### `updateMessage` ला `HelloWorld.js` फ्रंटएंडशी कनेक्ट करा {#connect-updatemessage-to-the-helloworld-js-frontend} + +आमच्या `onUpdatePressed` फंक्शनने आयात केलेल्या `updateMessage` फंक्शनला एक await कॉल करावा आणि आमचा व्यवहार यशस्वी झाला की अयशस्वी हे दर्शविण्यासाठी `status` स्टेट व्हेरिएबल सुधारित करावे: + +```javascript +// HelloWorld.js + +const onUpdatePressed = async () => { + const { status } = await updateMessage(walletAddress, newMessage) + setStatus(status) +} +``` + +हे खूप स्वच्छ आणि सोपे आहे. आणि अंदाज लावा... तुमचा डॅप पूर्ण झाला आहे!!! + +पुढे जा आणि **अपडेट** बटणाची चाचणी घ्या! + +### तुमचा स्वतःचा सानुकूल डॅप बनवा {#make-your-own-custom-dapp} + +व्वा, तुम्ही ट्युटोरियलच्या शेवटपर्यंत पोहोचलात! रिकॅप करण्यासाठी, तुम्ही शिकलात की कसे: + +- तुमच्या डॅप प्रकल्पाला MetaMask वॉलेट कनेक्ट करा +- [Alchemy Web3](https://docs.alchemy.com/alchemy/documentation/alchemy-web3) API वापरून तुमच्या स्मार्ट कॉन्ट्रॅक्टमधून डेटा वाचा +- MetaMask वापरून Ethereum व्यवहारांवर स्वाक्षरी करा + +आता तुम्ही तुमचा स्वतःचा सानुकूल डॅप प्रकल्प तयार करण्यासाठी या ट्युटोरियलमधील कौशल्ये लागू करण्यासाठी पूर्णपणे सुसज्ज आहात! नेहमीप्रमाणे, तुम्हाला काही प्रश्न असल्यास, [Alchemy Discord](https://discord.gg/gWuC7zB) मध्ये मदतीसाठी आमच्याशी संपर्क साधण्यास अजिबात संकोच करू नका. 🧙‍♂️ + +एकदा तुम्ही हे ट्युटोरियल पूर्ण केल्यावर, आम्हाला Twitter [@alchemyplatform](https://twitter.com/AlchemyPlatform) वर टॅग करून तुमचा अनुभव कसा होता किंवा तुमचा काही अभिप्राय असल्यास आम्हाला कळवा! diff --git a/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md new file mode 100644 index 00000000000..637ec6384c2 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md @@ -0,0 +1,366 @@ +--- +title: "नवशिक्यांसाठी हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्ट" +description: "Ethereum वर एक साधे स्मार्ट कॉन्ट्रॅक्ट लिहिण्यावर आणि उपयोजित करण्यावर एक प्रास्ताविक ट्युटोरियल." +author: "elanh" +tags: + [ + "सॉलिडिटी", + "hardhat", + "alchemy", + "स्मार्ट कॉन्ट्रॅक्ट", + "डिप्लॉयिंग" + ] +skill: beginner +lang: mr +published: 2021-03-31 +--- + +जर तुम्ही ब्लॉकचेन डेव्हलपमेंटमध्ये नवीन असाल आणि कुठून सुरुवात करावी हे माहित नसेल, किंवा जर तुम्हाला फक्त स्मार्ट कॉन्ट्रॅक्ट कसे उपयोजित करायचे आणि त्यांच्याशी संवाद कसा साधायचा हे समजून घ्यायचे असेल, तर हा मार्गदर्शक तुमच्यासाठी आहे. आपण व्हर्च्युअल वॉलेट [MetaMask](https://metamask.io/), [Solidity](https://docs.soliditylang.org/en/v0.8.0/), [Hardhat](https://hardhat.org/), आणि [Alchemy](https://www.alchemy.com/eth) वापरून सेपोलिया टेस्ट नेटवर्कवर एक साधे स्मार्ट कॉन्ट्रॅक्ट तयार करण्याची आणि उपयोजित करण्याची प्रक्रिया पाहू (यापैकी कशाचाही अर्थ तुम्हाला अजून समजत नसेल, तर काळजी करू नका, आम्ही ते स्पष्ट करू). + +या ट्युटोरियलच्या [भाग २](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) मध्ये, एकदा आपले स्मार्ट कॉन्ट्रॅक्ट येथे उपयोजित झाल्यावर आपण त्याच्याशी संवाद कसा साधू शकतो हे पाहू, आणि [भाग ३](https.www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) मध्ये आपण ते Etherscan वर कसे प्रकाशित करायचे हे पाहू. + +तुम्हाला कोणत्याही वेळी प्रश्न पडल्यास [Alchemy Discord](https://discord.gg/gWuC7zB) मध्ये मोकळेपणाने संपर्क साधा! + +## पायरी १: Ethereum नेटवर्कशी कनेक्ट करा {#step-1} + +Ethereum चेनला विनंत्या करण्याचे अनेक मार्ग आहेत. सोपेपणासाठी, आपण Alchemy वर एक विनामूल्य खाते वापरू, जो एक ब्लॉकचेन डेव्हलपर प्लॅटफॉर्म आणि API आहे, ज्यामुळे आपल्याला आपले स्वतःचे नोड्स चालवल्याशिवाय Ethereum चेनशी संवाद साधता येतो. या प्लॅटफॉर्ममध्ये मॉनिटरिंग आणि ॲनालिटिक्ससाठी डेव्हलपर साधने देखील आहेत, ज्यांचा आपण या ट्युटोरियलमध्ये फायदा घेऊ, जेणेकरून आपल्या स्मार्ट कॉन्ट्रॅक्टच्या उपयोजनात पडद्यामागे काय चालले आहे हे समजेल. जर तुमचे आधीच Alchemy खाते नसेल, तर [तुम्ही येथे विनामूल्य साइन अप करू शकता](https://dashboard.alchemy.com/signup). + +## पायरी २: तुमचे ॲप (आणि API की) तयार करा {#step-2} + +एकदा तुम्ही Alchemy खाते तयार केल्यावर, तुम्ही ॲप तयार करून API की तयार करू शकता. हे आम्हाला Sepolia चाचणी नेटवर्कवर विनंत्या करण्याची परवानगी देईल. जर तुम्ही टेस्टनेटशी परिचित नसाल, तर [हे पृष्ठ](/developers/docs/networks/) पहा. + +1. तुमच्या Alchemy डॅशबोर्डमधील "Create new app" पृष्ठावर जाण्यासाठी नेव्ह बारमध्ये "Select an app" निवडा आणि "Create new app" वर क्लिक करा. + +![हॅलो वर्ल्ड ॲप तयार करा](./hello-world-create-app.png) + +2. तुमच्या ॲपला “Hello World” असे नाव द्या, एक छोटे वर्णन द्या, आणि एक उपयोग-केस निवडा, उदा., "Infra & Tooling." पुढे, "Ethereum" साठी शोधा आणि नेटवर्क निवडा. + +![ॲप व्ह्यू हॅलो वर्ल्ड तयार करा](./create-app-view-hello-world.png) + +3. पुढे जाण्यासाठी "Next" वर क्लिक करा, नंतर “Create app” आणि बस्स! तुमचे ॲप नेव्ह बार ड्रॉपडाउन मेन्यूमध्ये दिसले पाहिजे, जिथे कॉपी करण्यासाठी API की उपलब्ध असेल. + +## पायरी ३: एक Ethereum खाते (पत्ता) तयार करा {#step-3} + +आम्हाला व्यवहार पाठवण्यासाठी आणि प्राप्त करण्यासाठी Ethereum खात्याची आवश्यकता आहे. या ट्यूटोरियलसाठी, आम्ही MetaMask वापरू, जे ब्राउझरमधील एक व्हर्च्युअल वॉलेट आहे, जे तुमचा Ethereum खाते पत्ता व्यवस्थापित करण्यासाठी वापरले जाते. [व्यवहारांविषयी](/developers/docs/transactions/) अधिक. + +तुम्ही MetaMask डाउनलोड करू शकता आणि [येथे](https://metamask.io/download) विनामूल्य Ethereum खाते तयार करू शकता. तुम्ही खाते तयार करत असताना, किंवा तुमचे खाते आधीच असल्यास, नेटवर्क ड्रॉपडाउन मेनू वापरून "Sepolia" टेस्ट नेटवर्कवर स्विच केल्याची खात्री करा (जेणेकरून आपण खऱ्या पैशांशी व्यवहार करणार नाही). + +जर तुम्हाला Sepolia सूचीबद्ध दिसत नसेल, तर मेन्यूमध्ये जा, नंतर Advanced मध्ये जाऊन खाली स्क्रोल करा आणि "Show test networks" चालू करण्यासाठी टॉगल करा. नेटवर्क निवड मेन्यूमध्ये, टेस्टनेटची सूची शोधण्यासाठी "Custom" टॅब निवडा आणि "Sepolia" निवडा. + +![metamask sepolia उदाहरण](./metamask-sepolia-example.png) + +## पायरी ४: फॉसेटमधून इथर मिळवा {#step-4} + +आपले स्मार्ट कॉन्ट्रॅक्ट टेस्ट नेटवर्कवर उपयोजित करण्यासाठी, आपल्याला काही बनावट Eth ची आवश्यकता असेल. Sepolia ETH मिळवण्यासाठी, विविध फॉसेटची सूची पाहण्यासाठी तुम्ही [Sepolia नेटवर्क तपशील](/developers/docs/networks/#sepolia) वर जाऊ शकता. एक काम करत नसल्यास, दुसरा प्रयत्न करा, कारण ते कधीकधी रिकामे होऊ शकतात. नेटवर्क ट्रॅफिकमुळे तुमचा बनावट ETH मिळण्यास थोडा वेळ लागू शकतो. त्यानंतर लवकरच तुमच्या Metamask खात्यात ETH दिसेल! + +## पायरी ५: तुमची शिल्लक तपासा {#step-5} + +आपली शिल्लक आहे की नाही, हे पुन्हा तपासण्यासाठी, चला [Alchemy च्या कंपोझर टूल](https://sandbox.alchemy.com/?network=ETH_SEPOLIA&method=eth_getBalance&body.id=1&body.jsonrpc=2.0&body.method=eth_getBalance&body.params%5B0%5D=&body.params%5B1%5D=latest) वापरून एक [eth_getBalance](/developers/docs/apis/json-rpc/#eth_getbalance) विनंती करूया. हे आमच्या वॉलेटमधील ETH ची रक्कम परत करेल. तुम्ही तुमच्या MetaMask खात्याचा पत्ता इनपुट केल्यानंतर आणि “Send Request” वर क्लिक केल्यानंतर, तुम्हाला असा प्रतिसाद दिसेल: + +```json +{ "jsonrpc": "2.0", "id": 0, "result": "0x2B5E3AF16B1880000" } +``` + +> **टीप:** हा निकाल ETH मध्ये नसून wei मध्ये आहे. Wei हे इथरचे सर्वात लहान एकक म्हणून वापरले जाते. wei चे ETH मध्ये रूपांतर असे आहे: 1 eth = 1018 wei. म्हणून जर आपण 0x2B5E3AF16B1880000 चे दशांश मध्ये रूपांतर केले, तर आपल्याला 5\*10¹⁸ मिळतात जे 5 ETH च्या बरोबर आहे. +> +> हुश्श! आपले बनावट पैसे पूर्णपणे तिथे आहेत . + +## पायरी ६: आपला प्रकल्प सुरू करा {#step-6} + +प्रथम, आपल्याला आपल्या प्रोजेक्टसाठी एक फोल्डर तयार करण्याची आवश्यकता असेल. तुमच्या कमांड लाइनवर नेव्हिगेट करा आणि टाइप करा: + +``` +mkdir hello-world +cd hello-world +``` + +आता आपण आपल्या प्रोजेक्ट फोल्डरमध्ये आहोत, आपण प्रोजेक्ट सुरू करण्यासाठी `npm init` वापरू. जर तुमच्याकडे आधीपासून npm इंस्टॉल केलेले नसेल, तर [या सूचनांचे](https://docs.alchemyapi.io/alchemy/guides/alchemy-for-macs#1-install-nodejs-and-npm) पालन करा (आपल्याला Node.js ची देखील आवश्यकता असेल, म्हणून ते देखील डाउनलोड करा!). + +``` +npm init +``` + +तुम्ही इन्स्टॉलेशनच्या प्रश्नांची उत्तरे कशी देता हे खरोखर महत्त्वाचे नाही, संदर्भासाठी आम्ही ते कसे केले ते येथे आहे: + +``` +package name: (hello-world) +version: (1.0.0) +description: hello world smart contract +entry point: (index.js) +test command: +git repository: +keywords: +author: +license: (ISC) +About to write to /Users/.../.../.../hello-world/package.json: + +{ + "name": "hello-world", + "version": "1.0.0", + "description": "hello world smart contract", + "main": "index.js", + "scripts": { + "test": "echo \\"Error: no test specified\\" && exit 1" + }, + "author": "", + "license": "ISC" +} +``` + +package.json ला मंजूर करा आणि आपण पुढे जाण्यास तयार आहोत! + +## पायरी ७: [Hardhat](https://hardhat.org/getting-started/#overview) डाउनलोड करा {#step-7} + +Hardhat हे तुमचे Ethereum सॉफ्टवेअर संकलित (compile), उपयोजित (deploy), चाचणी (test) आणि डीबग (debug) करण्यासाठी एक विकास वातावरण आहे. हे डेव्हलपर्सना थेट चेनवर उपयोजित करण्यापूर्वी स्थानिक पातळीवर स्मार्ट कॉन्ट्रॅक्ट्स आणि dApps तयार करताना मदत करते. + +आपल्या `hello-world` प्रोजेक्टमध्ये चालवा: + +``` +npm install --save-dev hardhat +``` + +[इन्स्टॉलेशन सूचनांविषयी](https://hardhat.org/getting-started/#overview) अधिक तपशीलांसाठी हे पेज पहा. + +## पायरी ८: Hardhat प्रोजेक्ट तयार करा {#step-8} + +आपल्या प्रोजेक्ट फोल्डरमध्ये चालवा: + +``` +npx hardhat +``` + +त्यानंतर तुम्हाला एक स्वागत संदेश आणि तुम्हाला काय करायचे आहे यासाठी पर्याय दिसेल. “create an empty hardhat.config.js” निवडा: + +``` +888 888 888 888 888 +888 888 888 888 888 +888 888 888 888 888 +8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 +888 888 "88b 888P" d88" 888 888 "88b "88b 888 +888 888 .d888888 888 888 888 888 888 .d888888 888 +888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. +888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 + +👷 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` फाईल तयार होईल, जिथे आपण आपल्या प्रोजेक्टसाठी सर्व सेटअप निर्दिष्ट करू (पायरी १३ वर). + +## पायरी ९: प्रोजेक्ट फोल्डर्स जोडा {#step-9} + +आपला प्रोजेक्ट सुव्यवस्थित ठेवण्यासाठी आपण दोन नवीन फोल्डर्स तयार करू. तुमच्या कमांड लाइनमधील प्रोजेक्टच्या मूळ डिरेक्टरीवर नेव्हिगेट करा आणि टाइप करा: + +``` +mkdir contracts +mkdir scripts +``` + +- `contracts/` मध्ये आपण आपली हॅलो वर्ल्ड स्मार्ट कॉन्ट्रॅक्ट कोड फाईल ठेवू +- `scripts/` मध्ये आपण आपले कॉन्ट्रॅक्ट उपयोजित करण्यासाठी आणि त्याच्याशी संवाद साधण्यासाठी स्क्रिप्ट्स ठेवू + +## पायरी १०: आपले कॉन्ट्रॅक्ट लिहा {#step-10} + +तुम्ही स्वतःला विचारत असाल, की आपण कोड कधी लिहिणार आहोत?? तर, आपण पायरी १० वर आलो आहोत. + +hello-world प्रोजेक्ट तुमच्या आवडत्या एडिटरमध्ये उघडा (आम्हाला [VSCode](https://code.visualstudio.com/) आवडते). स्मार्ट कॉन्ट्रॅक्ट्स Solidity नावाच्या भाषेत लिहिले जातात, जी आपण आपले HelloWorld.sol स्मार्ट कॉन्ट्रॅक्ट लिहिण्यासाठी वापरू.‌ + +1. "contracts" फोल्डरमध्ये नेव्हिगेट करा आणि HelloWorld.sol नावाची नवीन फाईल तयार करा +2. खाली Ethereum फाउंडेशनकडून एक नमुना Hello World स्मार्ट कॉन्ट्रॅक्ट आहे, जो आपण या ट्युटोरियलसाठी वापरणार आहोत. खालील मजकूर तुमच्या HelloWorld.sol फाईलमध्ये कॉपी आणि पेस्ट करा, आणि हे कॉन्ट्रॅक्ट काय करते हे समजून घेण्यासाठी कमेंट्स नक्की वाचा: + +```solidity +// सिमेंटिक व्हर्जनिंग वापरून सॉलिडिटीची आवृत्ती निर्दिष्ट करते. +// अधिक जाणून घ्या: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.7.0; + +// `HelloWorld` नावाचे एक कॉन्ट्रॅक्ट परिभाषित करते. +// कॉन्ट्रॅक्ट हे फंक्शन्स आणि डेटा (त्याची स्थिती) यांचा संग्रह आहे. एकदा उपयोजित झाल्यावर, कॉन्ट्रॅक्ट Ethereum ब्लॉकचेनवर एका विशिष्ट पत्त्यावर राहते. अधिक जाणून घ्या: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + // `string` प्रकाराचे एक स्टेट व्हेरिएबल `message` घोषित करते. + // स्टेट व्हेरिएबल्स असे व्हेरिएबल्स आहेत ज्यांची मूल्ये कॉन्ट्रॅक्ट स्टोरेजमध्ये कायमची संग्रहित केली जातात. `public` कीवर्ड व्हेरिएबल्सना कॉन्ट्रॅक्टच्या बाहेरून ॲक्सेस करण्यायोग्य बनवतो आणि एक फंक्शन तयार करतो ज्याला इतर कॉन्ट्रॅक्ट्स किंवा क्लायंट्स मूल्य ॲक्सेस करण्यासाठी कॉल करू शकतात. + string public message; + + // अनेक क्लास-आधारित ऑब्जेक्ट-ओरिएंटेड भाषांप्रमाणे, कन्स्ट्रक्टर हे एक विशेष फंक्शन आहे जे फक्त कॉन्ट्रॅक्ट तयार झाल्यावर कार्यान्वित होते. + // कन्स्ट्रक्टरचा वापर कॉन्ट्रॅक्टचा डेटा सुरू करण्यासाठी केला जातो. अधिक जाणून घ्या:https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) { + + // एक स्ट्रिंग युक्तिवाद `initMessage` स्वीकारतो आणि कॉन्ट्रॅक्टच्या `message` स्टोरेज व्हेरिएबलमध्ये मूल्य सेट करतो). + message = initMessage; + } + + // एक पब्लिक फंक्शन जे एक स्ट्रिंग युक्तिवाद स्वीकारते आणि `message` स्टोरेज व्हेरिएबल अपडेट करते. + function update(string memory newMessage) public { + message = newMessage; + } +} +``` + +हे एक अत्यंत सोपे स्मार्ट कॉन्ट्रॅक्ट आहे जे तयार झाल्यावर एक संदेश संग्रहित करते आणि `update` फंक्शनला कॉल करून अपडेट केले जाऊ शकते. + +## पायरी ११: तुमच्या प्रोजेक्टला MetaMask आणि Alchemy कनेक्ट करा {#step-11} + +आपण MetaMask वॉलेट, Alchemy खाते तयार केले आहे आणि आपले स्मार्ट कॉन्ट्रॅक्ट लिहिले आहे, आता या तिन्हीना जोडण्याची वेळ आली आहे. + +तुमच्या व्हर्च्युअल वॉलेटमधून पाठवलेल्या प्रत्येक व्यवहारासाठी तुमच्या युनिक प्रायव्हेट की वापरून स्वाक्षरी आवश्यक आहे. आमच्या प्रोग्रामला ही परवानगी देण्यासाठी, आम्ही आमची प्रायव्हेट की (आणि Alchemy API की) एका एन्व्हायर्नमेंट फाइलमध्ये सुरक्षितपणे संग्रहित करू शकतो. + +> व्यवहार पाठवण्याबद्दल अधिक जाणून घेण्यासाठी, वेब3 वापरून व्यवहार पाठवण्यावरील [हे ट्यूटोरियल](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) पहा. + +प्रथम, तुमच्या प्रोजेक्ट डिरेक्टरीमध्ये dotenv पॅकेज इंस्टॉल करा: + +``` +npm install dotenv --save +``` + +त्यानंतर, आमच्या प्रोजेक्टच्या रूट डिरेक्टरीमध्ये एक `.env` फाइल तयार करा आणि त्यात तुमची MetaMask प्रायव्हेट की आणि HTTP Alchemy API URL जोडा. + +- तुमची प्रायव्हेट की एक्सपोर्ट करण्यासाठी [या सूचनांचे](https://support.metamask.io/configure/accounts/how-to-export-an-accounts-private-key/) पालन करा +- HTTP Alchemy API URL मिळवण्यासाठी खाली पहा + +![अल्केमी एपीआय की मिळवा](./get-alchemy-api-key.png) + +Alchemy API URL कॉपी करा + +तुमचे `.env` असे दिसले पाहिजे: + +``` +API_URL = "https://eth-sepolia.g.alchemy.com/v2/your-api-key" +PRIVATE_KEY = "your-metamask-private-key" +``` + +हे प्रत्यक्षात आपल्या कोडशी जोडण्यासाठी, आपण या व्हेरिएबल्सचा संदर्भ आपल्या `hardhat.config.js` फाईलमध्ये पायरी १३ वर देऊ. + + + + +.env कमिट करू नका! कृपया तुमची .env फाईल कोणासोबतही शेअर किंवा उघड करू नका, कारण असे केल्याने तुम्ही तुमची गुपिते धोक्यात आणत आहात याची खात्री करा. जर तुम्ही व्हर्जन कंट्रोल वापरत असाल, तर तुमची .env फाईल gitignore फाईलमध्ये जोडा. + + + + +## पायरी १२: Ethers.js इंस्टॉल करा {#step-12-install-ethersjs} + +Ethers.js ही एक लायब्ररी आहे जी अधिक वापरकर्ता-अनुकूल पद्धतींसह [प्रमाणित JSON-RPC पद्धती](/developers/docs/apis/json-rpc/) गुंडाळून Ethereum शी संवाद साधणे आणि विनंत्या करणे सोपे करते. + +Hardhat अतिरिक्त टूलिंग आणि विस्तारित कार्यक्षमतेसाठी [प्लगइन्स](https://hardhat.org/plugins/) समाकलित करणे खूप सोपे करते. आम्ही कॉन्ट्रॅक्ट डिप्लॉयमेंटसाठी [Ethers प्लगइन](https://hardhat.org/docs/plugins/official-plugins#hardhat-ethers) चा फायदा घेणार आहोत ([Ethers.js](https://github.com/ethers-io/ethers.js/) मध्ये काही अत्यंत स्वच्छ कॉन्ट्रॅक्ट डिप्लॉयमेंट पद्धती आहेत). + +आपल्या प्रोजेक्ट डिरेक्टरीमध्ये टाइप करा: + +``` +npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0" +``` + +आपण पुढील पायरीमध्ये आपल्या `hardhat.config.js` मध्ये ethers ची आवश्यकता देखील दर्शवू. + +## पायरी १३: hardhat.config.js अद्ययावत करा {#step-13-update-hardhatconfigjs} + +आतापर्यंत आपण अनेक डिपेंडेंसी आणि प्लगइन जोडले आहेत, आता आपल्याला `hardhat.config.js` अद्यतनित करण्याची आवश्यकता आहे जेणेकरून आपल्या प्रोजेक्टला त्या सर्वांबद्दल माहिती मिळेल. + +तुमचे `hardhat.config.js` याप्रमाणे दिसण्यासाठी अद्यतनित करा: + +``` +require('dotenv').config(); + +require("@nomiclabs/hardhat-ethers"); +const { API_URL, PRIVATE_KEY } = process.env; + +/** +* @type import('hardhat/config').HardhatUserConfig +*/ +module.exports = { + solidity: "0.7.3", + defaultNetwork: "sepolia", + networks: { + hardhat: {}, + sepolia: { + url: API_URL, + accounts: [`0x${PRIVATE_KEY}`] + } + }, +} +``` + +## पायरी १४: आपले कॉन्ट्रॅक्ट कंपाईल करा {#step-14-compile-our-contracts} + +आतापर्यंत सर्व काही कार्यरत आहे याची खात्री करण्यासाठी, चला आमचा कॉन्ट्रॅक्ट संकलित करूया. `compile` कार्य हे बिल्ट-इन हार्डहॅट कार्यांपैकी एक आहे. + +कमांड लाइनमधून चालवा: + +``` +npx hardhat compile +``` + +तुम्हाला `SPDX license identifier not provided in source file` बद्दल एक चेतावणी मिळू शकते, परंतु त्याबद्दल काळजी करण्याची गरज नाही — आशा आहे की इतर सर्व काही ठीक दिसेल! नसल्यास, तुम्ही नेहमी [Alchemy discord](https://discord.gg/u72VCg3) मध्ये संदेश पाठवू शकता. + +## पायरी १५: आमची डिप्लॉय स्क्रिप्ट लिहा {#step-15-write-our-deploy-scripts} + +आता आमचा कॉन्ट्रॅक्ट लिहिला आहे आणि आमची कॉन्फिगरेशन फाइल तयार आहे, आता आमच्या कॉन्ट्रॅक्टची उपयोजन स्क्रिप्ट लिहिण्याची वेळ आली आहे. + +`scripts/` फोल्डरवर नेव्हिगेट करा आणि `deploy.js` नावाची एक नवीन फाइल तयार करा, त्यात खालील सामग्री जोडा: + +``` +async function main() { + const HelloWorld = await ethers.getContractFactory("HelloWorld"); + + // उपयोजन सुरू करा, जे एक प्रॉमिस परत करते जे कॉन्ट्रॅक्ट ऑब्जेक्टमध्ये रूपांतरित होते + const hello_world = await HelloWorld.deploy("Hello World!"); + console.log("Contract deployed to address:", hello_world.address);} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); +``` + +Hardhat त्यांच्या [कॉन्ट्रॅक्ट्स ट्यूटोरियल](https://hardhat.org/tutorial/testing-contracts.html#writing-tests) मध्ये या प्रत्येक कोड ओळी काय करते हे आश्चर्यकारकपणे स्पष्ट करते, आम्ही त्यांचे स्पष्टीकरण येथे स्वीकारले आहे. + +``` +const HelloWorld = await ethers.getContractFactory("HelloWorld"); +``` + +ethers.js मधील `ContractFactory` हे नवीन स्मार्ट कॉन्ट्रॅक्ट उपयोजित करण्यासाठी वापरले जाणारे एक ॲब्स्ट्रॅक्शन आहे, म्हणून येथे `HelloWorld` हे आपल्या हॅलो वर्ल्ड कॉन्ट्रॅक्टच्या इन्स्टन्ससाठी एक फॅक्टरी आहे. `hardhat-ethers` प्लगइन वापरताना `ContractFactory` आणि `Contract` इन्स्टन्स डीफॉल्टनुसार पहिल्या स्वाक्षरीकर्त्याशी जोडलेले असतात. + +``` +const hello_world = await HelloWorld.deploy(); +``` + +`ContractFactory` वर `deploy()` कॉल केल्याने उपयोजन सुरू होईल, आणि एक `Promise` परत येईल जो `Contract` मध्ये रिझॉल्व्ह होईल. हे ते ऑब्जेक्ट आहे ज्यामध्ये आमच्या प्रत्येक स्मार्ट कॉन्ट्रॅक्ट फंक्शनसाठी एक पद्धत आहे. + +## पायरी १६: आपले कॉन्ट्रॅक्ट उपयोजित करा {#step-16-deploy-our-contract} + +आम्ही अखेरीस आमचा स्मार्ट कॉन्ट्रॅक्ट उपयोजित करण्यास तयार आहोत! कमांड लाइनवर नेव्हिगेट करा आणि चालवा: + +``` +npx hardhat run scripts/deploy.js --network sepolia +``` + +तुम्हाला त्यानंतर असे काहीतरी दिसेल: + +``` +Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 +``` + +जर आपण [Sepolia etherscan](https://sepolia.etherscan.io/) वर गेलो आणि आपल्या कॉन्ट्रॅक्ट पत्त्यासाठी शोधले तर ते यशस्वीरित्या उपयोजित झाले आहे हे आपण पाहू शकू. व्यवहार असा काहीतरी दिसेल: + +![etherscan कॉन्ट्रॅक्ट](./etherscan-contract.png) + +`From` पत्ता तुमच्या MetaMask खात्याच्या पत्त्याशी जुळला पाहिजे आणि To पत्त्यावर “Contract Creation” असे दिसेल, परंतु जर आपण व्यवहारात क्लिक केले तर आपल्याला `To` फील्डमध्ये आपला कॉन्ट्रॅक्ट पत्ता दिसेल: + +![एथरस्कॅन व्यवहार](./etherscan-transaction.png) + +अभिनंदन! तुम्ही नुकतेच Ethereum चेनवर एक स्मार्ट कॉन्ट्रॅक्ट उपयोजित केले आहे 🎉 + +पडद्यामागे काय चालले आहे हे समजून घेण्यासाठी, चला आमच्या [Alchemy dashboard](https://dashboard.alchemyapi.io/explorer) मधील Explorer टॅबवर नेव्हिगेट करूया. तुमच्याकडे अनेक Alchemy ॲप्स असल्यास, ॲपनुसार फिल्टर केल्याची खात्री करा आणि “Hello World” निवडा. +![हॅलो वर्ल्ड एक्सप्लोरर](./hello-world-explorer.png) + +येथे तुम्हाला मुठभर JSON-RPC कॉल्स दिसतील जे Hardhat/Ethers ने `.deploy()` फंक्शन कॉल केल्यावर पडद्याआड आपल्यासाठी केले. येथे दोन महत्त्वाचे मुद्दे म्हणजे [`eth_sendRawTransaction`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-send-raw-transaction), जे प्रत्यक्षात सेपोलिया चेनवर आपले कॉन्ट्रॅक्ट लिहिण्याची विनंती आहे, आणि [`eth_getTransactionByHash`](https://www.alchemy.com/docs/node/abstract/abstract-api-endpoints/eth-get-transaction-by-hash) जे हॅश दिल्यावर आपल्या व्यवहाराबद्दल माहिती वाचण्याची विनंती आहे (व्यवहार करताना एक सामान्य नमुना). व्यवहार पाठविण्याबद्दल अधिक जाणून घेण्यासाठी, [Web3 आणि Alchemy वापरून व्यवहार पाठविण्यावरील](/developers/tutorials/sending-transactions-using-web3-and-alchemy/) हे ट्युटोरियल पहा. + +या ट्युटोरियलच्या भाग १ साठी एवढेच, भाग २ मध्ये आपण आपला सुरुवातीचा संदेश अपडेट करून [आपल्या स्मार्ट कॉन्ट्रॅक्टशी संवाद साधू](https://www.alchemy.com/docs/interacting-with-a-smart-contract) आणि भाग ३ मध्ये आपण [आपले स्मार्ट कॉन्ट्रॅक्ट Etherscan वर प्रकाशित करू](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) जेणेकरून प्रत्येकाला त्याच्याशी संवाद कसा साधायचा हे कळेल. + +\*\*Alchemy बद्दल अधिक जाणून घ्यायचे आहे? आमची [वेबसाइट](https://www.alchemy.com/eth) तपासा. एकही अपडेट चुकवायचे नाही? [येथे](https://www.alchemy.com/newsletter) आमच्या वृत्तपत्राची सदस्यता घ्या! आमच्या [Discord](https://discord.gg/u72VCg3) मध्ये सामील होण्याची खात्री करा. \*\* diff --git a/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md new file mode 100644 index 00000000000..8997ff14d37 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -0,0 +1,151 @@ +--- +title: "ERC-721 मार्केट कसे लागू करावे" +description: "विकेंद्रीकृत क्लासिफाइड्स बोर्डवर टोकनाइज्ड वस्तू विक्रीसाठी कशा ठेवायच्या" +author: "Alberto Cuesta Cañada" +tags: + [ + "स्मार्ट कॉन्ट्रॅक्ट", + "erc-721", + "सॉलिडिटी", + "tokens" + ] +skill: intermediate +lang: mr +published: 2020-03-19 +source: Hackernoon +sourceUrl: https://hackernoon.com/how-to-implement-an-erc721-market-1e1a32j9 +--- + +या लेखात, मी तुम्हाला Ethereum blockchain साठी Craigslist कसे कोड करायचे हे दाखवणार आहे. + +Gumtree, Ebay आणि Craigslist पूर्वी, क्लासिफाइड्स बोर्ड बहुतेक कॉर्क किंवा कागदाचे बनलेले होते. शाळेच्या कॉरिडॉरमध्ये, वर्तमानपत्रांमध्ये, रस्त्यावरील दिव्यांवर, दुकानांच्या दर्शनी भागात क्लासिफाइड्स बोर्ड होते. + +इंटरनेटमुळे हे सर्व बदलले. एखादा विशिष्ट क्लासिफाइड्स बोर्ड पाहू शकणाऱ्या लोकांची संख्या अनेक पटींनी वाढली. त्यामुळे, ते ज्या बाजारांचे प्रतिनिधित्व करतात ते अधिक कार्यक्षम बनले आणि जागतिक स्तरावर विस्तारले. Ebay हा एक मोठा व्यवसाय आहे ज्याची मुळे या भौतिक क्लासिफाइड्स बोर्डांमध्ये आहेत. + +Blockchain मुळे हे बाजार पुन्हा एकदा बदलणार आहेत, मी तुम्हाला दाखवतो कसे. + +## कमाई {#monetization} + +सार्वजनिक blockchain क्लासिफाइड्स बोर्डचे व्यवसाय मॉडेल Ebay आणि कंपनीच्या मॉडेलपेक्षा वेगळे असणे आवश्यक आहे. + +प्रथम, [विकेंद्रीकरणाचा दृष्टिकोन](/developers/docs/web2-vs-web3/) आहे. विद्यमान प्लॅटफॉर्मला त्यांचे स्वतःचे सर्व्हर सांभाळावे लागतात. एक विकेंद्रित प्लॅटफॉर्म त्याच्या वापरकर्त्यांद्वारे सांभाळला जातो, त्यामुळे प्लॅटफॉर्म मालकासाठी मूळ प्लॅटफॉर्म चालवण्याचा खर्च शून्यावर येतो. + +त्यानंतर फ्रंट एंड आहे, म्हणजेच वेबसाइट किंवा इंटरफेस जो प्लॅटफॉर्मवर प्रवेश देतो. येथे अनेक पर्याय आहेत. प्लॅटफॉर्मचे मालक प्रवेश प्रतिबंधित करू शकतात आणि प्रत्येकाला त्यांचा इंटरफेस वापरण्यास भाग पाडू शकतात, त्यासाठी शुल्क आकारू शकतात. प्लॅटफॉर्मचे मालक प्रवेश खुला करण्याचा निर्णय घेऊ शकतात (पॉवर टू द पीपल!) आणि कोणालाही प्लॅटफॉर्मसाठी इंटरफेस तयार करण्याची परवानगी देऊ शकतात. किंवा मालक या दोन टोकांच्या मधला कोणताही दृष्टिकोन ठरवू शकतात. + +_माझ्यापेक्षा अधिक दूरदृष्टी असलेले व्यावसायिक नेते यातून कमाई कशी करायची हे जाणतील._ _मला फक्त एवढेच दिसते की हे सध्याच्या स्थितीपेक्षा वेगळे आहे आणि कदाचित फायदेशीर आहे._ + +शिवाय, ऑटोमेशन आणि पेमेंट्सचा दृष्टिकोन आहे. काही गोष्टी खूप [प्रभावीपणे टोकनाइज्ड](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com) केल्या जाऊ शकतात आणि क्लासिफाइड्स बोर्डमध्ये त्यांचा व्यापार केला जाऊ शकतो. टोकनाइज्ड मालमत्ता blockchain मध्ये सहजपणे हस्तांतरित केल्या जातात. अत्यंत गुंतागुंतीच्या पेमेंट पद्धती blockchain मध्ये सहजपणे लागू केल्या जाऊ शकतात. + +मला येथे फक्त व्यवसायाच्या संधीचा वास येत आहे. कोणत्याही चालू खर्चाशिवाय क्लासिफाइड्स बोर्ड सहजपणे लागू केला जाऊ शकतो, ज्यामध्ये प्रत्येक व्यवहारात गुंतागुंतीचे पेमेंट मार्ग समाविष्ट असतील. मला खात्री आहे की याचा उपयोग कशासाठी करायचा याबद्दल कोणालातरी कल्पना सुचेल. + +मी फक्त ते तयार करण्यात आनंदी आहे. चला कोडवर एक नजर टाकूया. + +## अंमलबजावणी {#implementation} + +काही काळापूर्वी आम्ही बिझनेस केसच्या उदाहरणांच्या अंमलबजावणी आणि इतर चांगल्या गोष्टींसह एक [ओपन सोर्स रिपॉझिटरी](https://github.com/HQ20/contracts?ref=hackernoon.com) सुरू केली आहे, कृपया एक नजर टाका. + +या [Ethereum Classifieds Board](https://github.com/HQ20/contracts/tree/master/contracts/classifieds?ref=hackernoon.com) साठीचा कोड तिथे आहे, कृपया त्याचा वापर करा आणि त्याचा भरपूर वापर करा. फक्त हे लक्षात ठेवा की कोडचे ऑडिट केलेले नाही आणि त्यात पैसे गुंतवण्यापूर्वी तुम्हाला स्वतःची योग्य तपासणी करणे आवश्यक आहे. + +बोर्डच्या मूलभूत गोष्टी गुंतागुंतीच्या नाहीत. बोर्डमधील सर्व जाहिराती फक्त काही फील्ड्ससह एक struct असतील: + +```solidity +struct Trade { + address poster; + uint256 item; + uint256 price; + bytes32 status; // उघडा, कार्यान्वित, रद्द +} +``` + +म्हणजे जाहिरात पोस्ट करणारी कोणीतरी व्यक्ती आहे. विक्रीसाठी एक वस्तू. वस्तूसाठी एक किंमत. व्यापाराची स्थिती जी उघडी, कार्यान्वित किंवा रद्द केली जाऊ शकते. + +हे सर्व व्यवहार एका मॅपिंगमध्ये ठेवले जातील. कारण Solidity मध्ये सर्व काही मॅपिंगच असल्याचे दिसते. तसेच ते सोयीचे असल्यामुळे. + +```solidity +mapping(uint256 => Trade) public trades; +``` + +मॅपिंग वापरण्याचा अर्थ असा आहे की प्रत्येक जाहिरात पोस्ट करण्यापूर्वी आपल्याला त्यासाठी एक आयडी तयार करावा लागेल, आणि त्यावर प्रक्रिया करण्यापूर्वी आपल्याला त्या जाहिरातीचा आयडी माहित असणे आवश्यक असेल. स्मार्ट कॉन्ट्रॅक्टमध्ये किंवा फ्रंट-एंडमध्ये यावर काम करण्याचे अनेक मार्ग आहेत. तुम्हाला काही सूचना हव्या असल्यास कृपया विचारा. + +पुढे प्रश्न येतो की आपण ज्या वस्तूंचा व्यवहार करतो त्या कोणत्या आहेत आणि व्यवहारासाठी पैसे देण्यासाठी वापरले जाणारे चलन कोणते आहे. + +वस्तूंसाठी, आम्ही फक्त त्यांना [ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721.sol?ref=hackernoon.com) इंटरफेस लागू करण्यास सांगणार आहोत, जो वास्तविक जगातील वस्तू blockchain मध्ये दर्शविण्याचा एक मार्ग आहे, जरी ते [डिजिटल मालमत्तेसह सर्वोत्तम कार्य करते](https://hackernoon.com/tokenization-of-digital-assets-g0ffk3v8s?ref=hackernoon.com). आम्ही कन्स्ट्रक्टरमध्ये आमचा स्वतःचा ERC721 कॉन्ट्रॅक्ट निर्दिष्ट करणार आहोत, याचा अर्थ आमच्या क्लासिफाइड्स बोर्डमधील कोणत्याही मालमत्तेचे आधीच टोकनायझेशन करणे आवश्यक आहे. + +पेमेंट्ससाठी, आम्ही असेच काहीतरी करणार आहोत. बहुतेक blockchain प्रकल्प स्वतःची [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol?ref=hackernoon.com) क्रिप्टोकरन्सी परिभाषित करतात. काहीजण DAI सारखे मुख्य प्रवाहातील चलन वापरण्यास प्राधान्य देतात. या क्लासिफाइड्स बोर्डमध्ये, तुम्हाला फक्त निर्मितीच्या वेळी ठरवायचे आहे की तुमचे चलन कोणते असेल. सोपे. + +```solidity +constructor ( + address _currencyTokenAddress, address _itemTokenAddress +) public { + currencyToken = IERC20(_currencyTokenAddress); + itemToken = IERC721(_itemTokenAddress); + tradeCounter = 0; +} +``` + +आपण तिथे पोहोचत आहोत. आपल्याकडे जाहिराती, व्यापारासाठी वस्तू आणि पेमेंटसाठी चलन आहे. जाहिरात तयार करणे म्हणजे तुमच्याकडे ती वस्तू आहे आणि तुम्ही ती दोनदा पोस्ट केलेली नाही, शक्यतो वेगळ्या बोर्डवर, हे दाखवण्यासाठी ती वस्तू एस्क्रोमध्ये ठेवणे. + +खालील कोड नेमके तेच करतो. वस्तू एस्क्रोमध्ये ठेवतो, जाहिरात तयार करतो, काही हाउसकीपिंगची कामे करतो. + +```solidity +function openTrade(uint256 _item, uint256 _price) + public +{ + itemToken.transferFrom(msg.sender, address(this), _item); + trades[tradeCounter] = Trade({ + poster: msg.sender, + item: _item, + price: _price, + status: "Open" + }); + tradeCounter += 1; + emit TradeStatusChange(tradeCounter - 1, "Open"); +} +``` + +व्यापार स्वीकारणे म्हणजे एक जाहिरात (व्यापार) निवडणे, किंमत भरणे, वस्तू मिळवणे. खालील कोड एक व्यापार पुनर्प्राप्त करतो. तो उपलब्ध आहे का ते तपासतो. वस्तूसाठी पैसे देतो. वस्तू परत मिळवतो. जाहिरात अपडेट करतो. + +```solidity +function executeTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require(trade.status == "Open", "व्यापार खुला नाही."); + currencyToken.transferFrom(msg.sender, trade.poster, trade.price); + itemToken.transferFrom(address(this), msg.sender, trade.item); + trades[_trade].status = "Executed"; + emit TradeStatusChange(_trade, "Executed"); +} +``` + +शेवटी, विक्रेत्यांसाठी खरेदीदाराने व्यापार स्वीकारण्यापूर्वी त्यातून बाहेर पडण्याचा पर्याय आहे. काही मॉडेल्समध्ये, जाहिराती कालबाह्य होण्यापूर्वी काही कालावधीसाठी थेट (live) राहतील. तुमच्या बाजाराच्या डिझाइनवर अवलंबून, ही तुमची निवड आहे. + +हा कोड व्यापार कार्यान्वित करण्यासाठी वापरलेल्या कोडसारखाच आहे, फक्त यात चलनाची देवाणघेवाण होत नाही आणि वस्तू जाहिरात पोस्ट करणाऱ्याकडे परत जाते. + +```solidity +function cancelTrade(uint256 _trade) + public +{ + Trade memory trade = trades[_trade]; + require( + msg.sender == trade.poster, + "व्यापार फक्त पोस्ट करणाऱ्याद्वारे रद्द केला जाऊ शकतो." + ); + require(trade.status == "Open", "व्यापार खुला नाही."); + itemToken.transferFrom(address(this), trade.poster, trade.item); + trades[_trade].status = "Cancelled"; + emit TradeStatusChange(_trade, "Cancelled"); +} +``` + +बस इतकेच. तुम्ही अंमलबजावणीच्या शेवटपर्यंत पोहोचला आहात. काही व्यावसायिक संकल्पना कोडमध्ये व्यक्त केल्यावर किती संक्षिप्त असतात हे आश्चर्यकारक आहे, आणि हे त्यापैकीच एक उदाहरण आहे. संपूर्ण कॉन्ट्रॅक्ट [आमच्या रेपॉजिटरीमध्ये](https://github.com/HQ20/contracts/blob/master/contracts/classifieds/Classifieds.sol) तपासा. + +## निष्कर्ष {#conclusion} + +क्लासिफाइड्स बोर्ड हे एक सामान्य बाजारपेठेचे स्वरूप आहे जे इंटरनेटमुळे मोठ्या प्रमाणावर विस्तारले, आणि काही मक्तेदारी विजेत्यांसह एक प्रचंड लोकप्रिय व्यवसाय मॉडेल बनले. + +क्लासिफाइड्स बोर्ड हे blockchain वातावरणात प्रतिकृती बनवण्यासाठी एक सोपे साधन आहे, ज्यात खूप विशिष्ट वैशिष्ट्ये आहेत जी विद्यमान दिग्गजांना आव्हान देणे शक्य करतील. + +या लेखात, मी क्लासिफाइड्स बोर्ड व्यवसायाच्या व्यावसायिक वास्तवाला तांत्रिक अंमलबजावणीशी जोडण्याचा प्रयत्न केला आहे. जर तुमच्याकडे योग्य कौशल्ये असतील तर हे ज्ञान तुम्हाला अंमलबजावणीसाठी एक दूरदृष्टी आणि रोडमॅप तयार करण्यास मदत करेल. + +नेहमीप्रमाणे, जर तुम्ही काहीतरी मजेदार तयार करत असाल आणि तुम्हाला काही सल्ला हवा असेल, तर कृपया [मला संपर्क साधा](https://albertocuesta.es/)! मला मदत करायला नेहमीच आनंद होतो. diff --git a/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md new file mode 100644 index 00000000000..62ec6d3a132 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md @@ -0,0 +1,335 @@ +--- +title: "NFT कसे मिंट करावे (NFT ट्युटोरियल मालिकेचा भाग 2/3)" +description: "हे ट्युटोरियल आमचा स्मार्ट कॉन्ट्रॅक्ट आणि Web3 वापरून Ethereum ब्लॉकचेनवर NFT कसे मिंट करायचे याचे वर्णन करते." +author: "Sumi Mudgil" +tags: + [ + "ERC-721", + "alchemy", + "सॉलिडिटी", + "स्मार्ट कॉन्ट्रॅक्ट" + ] +skill: beginner +lang: mr +published: 2021-04-22 +--- + +[बीपल](https://www.nytimes.com/2021/03/11/arts/design/nft-auction-christies-beeple.html): $69 दशलक्ष +[3LAU](https://www.forbes.com/sites/abrambrown/2021/03/03/3lau-nft-nonfungible-tokens-justin-blau/?sh=5f72ef64643b): $11 दशलक्ष +[ग्राइम्स](https://www.theguardian.com/music/2021/mar/02/grimes-sells-digital-art-collection-non-fungible-tokens): $6 दशलक्ष + +त्या सर्वांनी Alchemy च्या शक्तिशाली API चा वापर करून त्यांचे NFTs मिंट केले. या ट्युटोरियलमध्ये, आम्ही तुम्हाला \<10 मिनिटांत तेच कसे करायचे हे शिकवू. + +"NFT मिंट करणे" म्हणजे ब्लॉकचेनवर तुमच्या ERC-721 टोकनची एक अद्वितीय प्रत प्रकाशित करण्याची क्रिया. [या NFT ट्युटोरियल मालिकेच्या भाग १](/developers/tutorials/how-to-write-and-deploy-an-nft/) मधील आमचा स्मार्ट कॉन्ट्रॅक्ट वापरून, चला आपले Web3 कौशल्य दाखवूया आणि एक NFT मिंट करूया. या ट्युटोरियलच्या शेवटी, तुम्ही तुमच्या मनाला (आणि वॉलेटला) हवे तितके NFTs मिंट करू शकाल! + +चला सुरू करूया! + +## पायरी १: Web3 इंस्टॉल करा {#install-web3} + +जर तुम्ही तुमचा NFT स्मार्ट कॉन्ट्रॅक्ट तयार करण्यावरील पहिले ट्युटोरियल फॉलो केले असेल, तर तुम्हाला Ethers.js वापरण्याचा अनुभव आधीच आहे. Web3 हे Ethers सारखेच आहे, कारण ही एक लायब्ररी आहे जी Ethereum ब्लॉकचेनला विनंत्या करणे सोपे करण्यासाठी वापरली जाते. या ट्युटोरियलमध्ये आपण [Alchemy Web3](https://docs.alchemyapi.io/alchemy/documentation/alchemy-web3) वापरणार आहोत, जी एक वर्धित Web3 लायब्ररी आहे जी स्वयंचलित पुनर्प्रयत्न आणि मजबूत WebSocket सपोर्ट देते. + +तुमच्या प्रोजेक्ट होम डिरेक्टरीमध्ये चालवा: + +``` +npm install @alch/alchemy-web3 +``` + +## पायरी २: `mint-nft.js` फाईल तयार करा {#create-mintnftjs} + +तुमच्या स्क्रिप्ट्स डिरेक्टरीमध्ये, `mint-nft.js` फाईल तयार करा आणि कोडच्या खालील ओळी जोडा: + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) +``` + +## पायरी ३: तुमचा कॉन्ट्रॅक्ट ABI मिळवा {#contract-abi} + +आमचा कॉन्ट्रॅक्ट ABI (ऍप्लिकेशन बायनरी इंटरफेस) हा आमच्या स्मार्ट कॉन्ट्रॅक्टशी संवाद साधण्यासाठी इंटरफेस आहे. तुम्ही कॉन्ट्रॅक्ट ABI बद्दल अधिक माहिती [येथे](https://docs.alchemyapi.io/alchemy/guides/eth_getlogs#what-are-ab-is) मिळवू शकता. Hardhat आमच्यासाठी आपोआप एक ABI तयार करते आणि ते `MyNFT.json` फाईलमध्ये सेव्ह करते. हे वापरण्यासाठी, आपल्याला आपल्या `mint-nft.js` फाईलमध्ये कोडच्या खालील ओळी जोडून मजकूर पार्स करणे आवश्यक आहे: + +```js +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +``` + +जर तुम्हाला ABI पाहायचा असेल तर तुम्ही ते तुमच्या कन्सोलवर प्रिंट करू शकता: + +```js +console.log(JSON.stringify(contract.abi)) +``` + +`mint-nft.js` चालवण्यासाठी आणि तुमचा ABI कन्सोलवर प्रिंट झालेला पाहण्यासाठी तुमच्या टर्मिनलवर नेव्हिगेट करा आणि चालवा: + +```js +node scripts/mint-nft.js +``` + +## पायरी ४: IPFS वापरून तुमच्या NFT साठी मेटाडेटा कॉन्फिगर करा {#config-meta} + +तुम्हाला भाग 1 मधील आमच्या ट्युटोरियलमधून आठवत असेल तर, आमचे `mintNFT` स्मार्ट कॉन्ट्रॅक्ट फंक्शन एक tokenURI पॅरामीटर घेते जे NFT च्या मेटाडेटाचे वर्णन करणाऱ्या JSON डॉक्युमेंटमध्ये रिझॉल्व्ह झाले पाहिजे — जे खरोखर NFT ला जिवंत करते, त्याला नाव, वर्णन, प्रतिमा आणि इतर गुणधर्मांसारखे कॉन्फिगर करण्यायोग्य गुणधर्म ठेवण्याची परवानगी देते. + +> _इंटरप्लॅनेटरी फाईल सिस्टम (IPFS) हा एक विकेंद्रित प्रोटोकॉल आणि पीअर-टू-पीअर नेटवर्क आहे, जो वितरित फाईल सिस्टममध्ये डेटा संग्रहित आणि शेअर करण्यासाठी आहे._ + +आपला NFT खरोखर विकेंद्रित आहे याची खात्री करण्यासाठी, आपण आपली NFT मालमत्ता आणि मेटाडेटा संग्रहित करण्यासाठी Pinata, एक सोयीस्कर IPFS API आणि टूलकिट वापरणार आहोत. तुमचे Pinata खाते नसल्यास, [येथे](https://app.pinata.cloud) विनामूल्य खात्यासाठी साइन अप करा आणि तुमचा ईमेल सत्यापित करण्यासाठी पायऱ्या पूर्ण करा. + +एकदा तुम्ही खाते तयार केल्यानंतर: + +- "फाईल्स" पेजवर नेव्हिगेट करा आणि पेजच्या वरच्या-डाव्या कोपऱ्यात असलेल्या निळ्या "अपलोड" बटणावर क्लिक करा. + +- Pinata वर एक प्रतिमा अपलोड करा — ही तुमच्या NFT साठी प्रतिमा मालमत्ता असेल. मालमत्तेला तुम्हाला हवे ते नाव देण्यास मोकळे आहात + +- तुम्ही अपलोड केल्यानंतर, तुम्हाला "फाईल्स" पेजवरील टेबलमध्ये फाईलची माहिती दिसेल. तुम्हाला एक CID स्तंभ देखील दिसेल. तुम्ही त्याच्या पुढील कॉपी बटणावर क्लिक करून CID कॉपी करू शकता. तुम्ही तुमचे अपलोड येथे पाहू शकता: `https://gateway.pinata.cloud/ipfs/`. उदाहरणार्थ, आम्ही IPFS वर वापरलेली प्रतिमा तुम्ही [येथे](https://gateway.pinata.cloud/ipfs/QmZdd5KYdCFApWn7eTZJ1qgJu18urJrP9Yh1TZcZrZxxB5) शोधू शकता. + +अधिक दृष्य शिकणाऱ्यांसाठी, वरील पायऱ्या येथे सारांशित केल्या आहेत: + +![तुमची प्रतिमा Pinata वर कशी अपलोड करावी](./instructionsPinata.gif) + +आता, आम्हाला Pinata वर आणखी एक दस्तऐवज अपलोड करायचा आहे. पण ते करण्यापूर्वी, आपल्याला ते तयार करणे आवश्यक आहे! + +तुमच्या रूट डिरेक्टरीमध्ये, `nft-metadata.json` नावाची एक नवीन फाईल बनवा आणि खालील json कोड जोडा: + +```json +{ + "attributes": [ + { + "trait_type": "जात", + "value": "Maltipoo" + }, + { + "trait_type": "डोळ्यांचा रंग", + "value": "Mocha" + } + ], + "description": "जगातील सर्वात मोहक आणि संवेदनशील पिल्लू.", + "image": "ipfs://QmWmvTJmJU3pozR9ZHFmQC2DNDwi2XJtf3QGyYiiagFSWb", + "name": "Ramses" +} +``` + +json मधील डेटा बदलण्यास मोकळे आहात. तुम्ही ऍट्रिब्युट्स विभागातून काढू किंवा त्यात भर घालू शकता. सर्वात महत्त्वाचे म्हणजे, इमेज फील्ड तुमच्या IPFS प्रतिमेच्या स्थानाकडे निर्देश करते याची खात्री करा — अन्यथा, तुमच्या NFT मध्ये एका (खूप गोंडस!) कुत्र्याचा फोटो समाविष्ट असेल. + +एकदा तुम्ही JSON फाईल संपादित करणे पूर्ण केले की, ती सेव्ह करा आणि प्रतिमा अपलोड करण्यासाठी आम्ही केलेल्या त्याच पायऱ्यांचे अनुसरण करून Pinata वर अपलोड करा. + +![तुमचे nft-metadata.json Pinata वर कसे अपलोड करायचे](./uploadPinata.gif) + +## पायरी ५: तुमच्या कॉन्ट्रॅक्टची एक प्रत तयार करा {#instance-contract} + +आता, आमच्या कॉन्ट्रॅक्टशी संवाद साधण्यासाठी, आपल्याला आमच्या कोडमध्ये त्याची एक प्रत तयार करणे आवश्यक आहे. असे करण्यासाठी आम्हाला आमच्या कॉन्ट्रॅक्ट ॲड्रेसची आवश्यकता असेल, जो आपण डिप्लॉयमेंटमधून किंवा [Blockscout](https://eth-sepolia.blockscout.com/) वरून तुम्ही कॉन्ट्रॅक्ट डिप्लॉय करण्यासाठी वापरलेला ॲड्रेस शोधून मिळवू शकतो. + +![Etherscan वर तुमचा कॉन्ट्रॅक्ट ॲड्रेस पहा](./view-contract-etherscan.png) + +वरील उदाहरणात, आमचा कॉन्ट्रॅक्ट ॲड्रेस 0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778 आहे. + +पुढे आपण ABI आणि ॲड्रेस वापरून आपला कॉन्ट्रॅक्ट तयार करण्यासाठी Web3 [कॉन्ट्रॅक्ट पद्धत](https://docs.web3js.org/api/web3-eth-contract/class/Contract) वापरू. तुमच्या `mint-nft.js` फाईलमध्ये, खालील गोष्टी जोडा: + +```js +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" + +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) +``` + +## पायरी ६: `.env` फाईल अपडेट करा {#update-env} + +आता, Ethereum चेनवर व्यवहार तयार करण्यासाठी आणि पाठवण्यासाठी, आम्ही खाते नॉन्स (खाली स्पष्ट करू) मिळवण्यासाठी तुमचा सार्वजनिक Ethereum खाते ॲड्रेस वापरू. + +तुमची सार्वजनिक की तुमच्या `.env` फाईलमध्ये जोडा — जर तुम्ही ट्युटोरियलचा भाग १ पूर्ण केला असेल, तर आमची `.env` फाईल आता अशी दिसेल: + +```js +API_URL = "https://eth-sepolia.g.alchemy.com/v2/तुमची-api-की" +PRIVATE_KEY = "तुमचा-खाजगी-खाते-ॲड्रेस" +PUBLIC_KEY = "तुमचा-सार्वजनिक-खाते-ॲड्रेस" +``` + +## पायरी ७: तुमचा व्यवहार तयार करा {#create-txn} + +प्रथम, `mintNFT(tokenData)` नावाचे एक फंक्शन परिभाषित करूया आणि खालील गोष्टी करून आपला व्यवहार तयार करूया: + +1. `.env` फाईलमधून तुमची _PRIVATE_KEY_ आणि _PUBLIC_KEY_ मिळवा. + +2. पुढे, आपल्याला खाते नॉन्स शोधण्याची आवश्यकता असेल. नॉन्स स्पेसिफिकेशनचा वापर तुमच्या ॲड्रेसवरून पाठवलेल्या व्यवहारांच्या संख्येचा मागोवा ठेवण्यासाठी केला जातो — ज्याची आम्हाला सुरक्षिततेच्या उद्देशाने आणि [रिप्ले हल्ले](https://docs.alchemyapi.io/resources/blockchain-glossary#account-nonce) टाळण्यासाठी आवश्यकता आहे. तुमच्या ॲड्रेसवरून पाठवलेल्या व्यवहारांची संख्या मिळवण्यासाठी, आम्ही [getTransactionCount](https://docs.alchemyapi.io/documentation/alchemy-api-reference/json-rpc#eth_gettransactioncount) वापरतो. + +3. शेवटी आम्ही खालील माहितीसह आमचा व्यवहार सेट करू: + +- `'from': PUBLIC_KEY` — आमच्या व्यवहाराचा उगम आमचा सार्वजनिक ॲड्रेस आहे + +- `'to': contractAddress` — ज्या कॉन्ट्रॅक्टशी आम्ही संवाद साधू आणि व्यवहार पाठवू इच्छितो + +- `'nonce': nonce` — आमच्या ॲड्रेसवरून पाठवलेल्या व्यवहारांच्या संख्येसह खाते नॉन्स + +- `'gas': estimatedGas` — व्यवहार पूर्ण करण्यासाठी लागणारा अंदाजित गॅस + +- `'data': nftContract.methods.mintNFT(PUBLIC_KEY, md).encodeABI()` — या व्यवहारामध्ये आपण जी गणना करू इच्छितो — जी या प्रकरणात NFT मिंट करणे आहे + +तुमची `mint-nft.js` फाईल आता अशी दिसेल: + +```js + require('dotenv').config(); + const API_URL = process.env.API_URL; + const PUBLIC_KEY = process.env.PUBLIC_KEY; + const PRIVATE_KEY = process.env.PRIVATE_KEY; + + const { createAlchemyWeb3 } = require("@alch/alchemy-web3"); + const web3 = createAlchemyWeb3(API_URL); + + const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json"); + const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778"; + const nftContract = new web3.eth.Contract(contract.abi, contractAddress); + + async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //नवीनतम नॉन्स मिळवा + + //व्यवहार + const tx = { + 'from': PUBLIC_KEY, + 'to': contractAddress, + 'nonce': nonce, + 'gas': 500000, + 'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI() + }; + }​ +``` + +## पायरी ८: व्यवहारावर सही करा {#sign-txn} + +आता आपण आपला व्यवहार तयार केला आहे, तो पाठवण्यासाठी आपल्याला त्यावर सही करणे आवश्यक आहे. येथे आपण आपली खाजगी की वापरू. + +`web3.eth.sendSignedTransaction` आपल्याला व्यवहाराचा हॅश देईल, ज्याचा वापर आपण आपला व्यवहार माइन झाला आहे आणि नेटवर्कद्वारे तो ड्रॉप झाला नाही याची खात्री करण्यासाठी करू शकतो. तुमच्या लक्षात येईल की व्यवहार स्वाक्षरी विभागात, आम्ही काही त्रुटी तपासणी जोडली आहे जेणेकरून आपला व्यवहार यशस्वीरित्या पार पडला की नाही हे आपल्याला कळेल. + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const PUBLIC_KEY = process.env.PUBLIC_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY + +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) + +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) + +async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //नवीनतम नॉन्स मिळवा + + //व्यवहार + const tx = { + from: PUBLIC_KEY, + to: contractAddress, + nonce: nonce, + gas: 500000, + data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(), + } + + const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY) + signPromise + .then((signedTx) => { + web3.eth.sendSignedTransaction( + signedTx.rawTransaction, + function (err, hash) { + if (!err) { + console.log( + "तुमच्या व्यवहाराचा हॅश आहे: ", + hash, + "\nतुमच्या व्यवहाराची स्थिती पाहण्यासाठी Alchemy's Mempool तपासा!" + ) + } else { + console.log( + "तुमचा व्यवहार सबमिट करताना काहीतरी चूक झाली:", + err + ) + } + } + ) + }) + .catch((err) => { + console.log(" Promise अयशस्वी झाले:", err) + }) +} +``` + +## पायरी ९: `mintNFT` ला कॉल करा आणि नोड `mint-nft.js` चालवा {#call-mintnft-fn} + +तुम्ही Pinata वर अपलोड केलेली `metadata.json` आठवते का? Pinata वरून त्याचा हॅशकोड मिळवा आणि `mintNFT` फंक्शनला पॅरामीटर म्हणून `https://gateway.pinata.cloud/ipfs/<मेटाडेटा-हॅश-कोड>` पास करा + +हॅशकोड कसा मिळवायचा ते येथे आहे: + +![Pinata वर तुमच्या nft मेटाडेटाचा हॅशकोड कसा मिळवायचा](./metadataPinata.gif)_Pinata वर तुमच्या nft मेटाडेटाचा हॅशकोड कसा मिळवायचा_ + +> स्वतंत्र विंडोमध्ये `https://gateway.pinata.cloud/ipfs/<मेटाडेटा-हॅश-कोड>` लोड करून तुम्ही कॉपी केलेला हॅशकोड तुमच्या **metadata.json** शी लिंक आहे का हे पुन्हा तपासा. हे पेज खालील स्क्रीनशॉटसारखे दिसावे: + +![तुमच्या पेजवर json मेटाडेटा प्रदर्शित झाला पाहिजे](./metadataJSON.png)_तुमच्या पेजवर json मेटाडेटा प्रदर्शित झाला पाहिजे_ + +एकूण, तुमचा कोड काहीसा असा दिसेल: + +```js +require("dotenv").config() +const API_URL = process.env.API_URL +const PUBLIC_KEY = process.env.PUBLIC_KEY +const PRIVATE_KEY = process.env.PRIVATE_KEY + +const { createAlchemyWeb3 } = require("@alch/alchemy-web3") +const web3 = createAlchemyWeb3(API_URL) + +const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json") +const contractAddress = "0x5a738a5c5fe46a1fd5ee7dd7e38f722e2aef7778" +const nftContract = new web3.eth.Contract(contract.abi, contractAddress) + +async function mintNFT(tokenURI) { + const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, "latest") //नवीनतम नॉन्स मिळवा + + //व्यवहार + const tx = { + from: PUBLIC_KEY, + to: contractAddress, + nonce: nonce, + gas: 500000, + data: nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(), + } + + const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY) + signPromise + .then((signedTx) => { + web3.eth.sendSignedTransaction( + signedTx.rawTransaction, + function (err, hash) { + if (!err) { + console.log( + "तुमच्या व्यवहाराचा हॅश आहे: ", + hash, + "\nतुमच्या व्यवहाराची स्थिती पाहण्यासाठी Alchemy's Mempool तपासा!" + ) + } else { + console.log( + "तुमचा व्यवहार सबमिट करताना काहीतरी चूक झाली:", + err + ) + } + } + ) + }) + .catch((err) => { + console.log("Promise अयशस्वी झाले:", err) + }) +} + +mintNFT("ipfs://QmYueiuRNmL4MiA2GwtVMm6ZagknXnSpQnB3z2gWbz36hP") +``` + +आता, तुमचा NFT डिप्लॉय करण्यासाठी `node scripts/mint-nft.js` चालवा. काही सेकंदांनंतर, तुम्हाला तुमच्या टर्मिनलमध्ये असा प्रतिसाद दिसेल: + + ``` + तुमच्या व्यवहाराचा हॅश आहे: 0x301791fdf492001fcd9d5e5b12f3aa1bbbea9a88ed24993a8ab2cdae2d06e1e8 + + तुमच्या व्यवहाराची स्थिती पाहण्यासाठी Alchemy's Mempool तपासा! + ``` + +पुढे, तुमच्या व्यवहाराची स्थिती (तो प्रलंबित आहे, माइन झाला आहे, किंवा नेटवर्कद्वारे ड्रॉप झाला आहे) पाहण्यासाठी तुमच्या [Alchemy mempool](https://dashboard.alchemyapi.io/mempool) ला भेट द्या. तुमचा व्यवहार ड्रॉप झाला असल्यास, [Blockscout](https://eth-sepolia.blockscout.com/) तपासणे आणि तुमच्या व्यवहाराचा हॅश शोधणे देखील उपयुक्त आहे. + +![Etherscan वर तुमचा NFT व्यवहाराचा हॅश पहा](./view-nft-etherscan.png)_Etherscan वर तुमचा NFT व्यवहाराचा हॅश पहा_ + +आणि बस्स! तुम्ही आता Ethereum ब्लॉकचेनवर एक NFT डिप्लॉय आणि मिंट केला आहे + +`mint-nft.js` वापरून तुम्ही तुमच्या मनाला (आणि वॉलेटला) हवे तितके NFTs मिंट करू शकता! फक्त NFT च्या मेटाडेटाचे वर्णन करणारा एक नवीन tokenURI पास करण्याची खात्री करा (अन्यथा, तुम्ही फक्त वेगवेगळ्या आयडीसह सारख्याच अनेक प्रती तयार कराल). + +साहजिकच, तुम्हाला तुमच्या वॉलेटमध्ये तुमचा NFT दाखवायला आवडेल — म्हणून [भाग ३: तुमच्या वॉलेटमध्ये तुमचा NFT कसा पाहावा](/developers/tutorials/how-to-view-nft-in-metamask/) नक्की पहा! diff --git a/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md new file mode 100644 index 00000000000..5faf8882a82 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -0,0 +1,108 @@ +--- +title: "चाचणीसाठी Solidity स्मार्ट कॉन्ट्रॅक्ट्सना मॉक कसे करावे" +description: "चाचणी करताना तुम्ही तुमच्या कॉन्ट्रॅक्ट्सची गंमत का करावी" +author: Markus Waas +lang: mr +tags: + [ + "सॉलिडिटी", + "स्मार्ट कॉन्ट्रॅक्ट", + "चाचणी", + "मॉक करणे" + ] +skill: intermediate +published: 2020-05-02 +source: soliditydeveloper.com +sourceUrl: https://soliditydeveloper.com/mocking-contracts +--- + +[मॉक ऑब्जेक्ट्स](https://wikipedia.org/wiki/Mock_object) हे ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंगमधील एक सामान्य डिझाइन पॅटर्न आहे. जुन्या फ्रेंच शब्द 'mocquer' ज्याचा अर्थ 'गमतीचा विषय बनवणे' आहे, त्यापासून विकसित होऊन त्याचा अर्थ 'खऱ्या गोष्टीची नक्कल करणे' असा झाला, जे आपण प्रोग्रामिंगमध्ये प्रत्यक्षात करत आहोत. तुम्हाला हवे असल्यास कृपया तुमच्या स्मार्ट कॉन्ट्रॅक्ट्सची गंमत करा, परंतु जेव्हा शक्य असेल तेव्हा त्यांना मॉक करा. हे तुमचे जीवन सोपे करते. + +## मॉकसह कॉन्ट्रॅक्ट्सची युनिट-चाचणी {#unit-testing-contracts-with-mocks} + +कॉन्ट्रॅक्ट मॉक करणे म्हणजे मूलतः त्या कॉन्ट्रॅक्टची दुसरी आवृत्ती तयार करणे जी मूळ आवृत्तीसारखीच वागते, परंतु अशा प्रकारे की डेव्हलपरद्वारे ती सहजपणे नियंत्रित केली जाऊ शकते. तुमच्याकडे अनेकदा गुंतागुंतीचे कॉन्ट्रॅक्ट्स असतात जिथे तुम्हाला फक्त [कॉन्ट्रॅक्टच्या छोट्या भागांची युनिट-चाचणी](/developers/docs/smart-contracts/testing/) करायची असते. समस्या ही आहे की, जर या छोट्या भागाची चाचणी करण्यासाठी एका विशिष्ट कॉन्ट्रॅक्ट स्थितीची आवश्यकता असेल ज्यात पोहोचणे कठीण आहे, तर काय? + +तुम्ही प्रत्येक वेळी गुंतागुंतीचे चाचणी सेटअप लॉजिक लिहू शकता जे कॉन्ट्रॅक्टला आवश्यक स्थितीत आणेल किंवा तुम्ही मॉक लिहू शकता. इनहेरिटन्ससह कॉन्ट्रॅक्ट मॉक करणे सोपे आहे. फक्त एक दुसरा मॉक कॉन्ट्रॅक्ट तयार करा जो मूळ कॉन्ट्रॅक्टमधून इनहेरिट करतो. आता तुम्ही तुमच्या मॉकसाठी फंक्शन्स ओव्हरराइड करू शकता. चला एका उदाहरणासह पाहूया. + +## उदाहरण: प्रायव्हेट ERC20 {#example-private-erc20} + +आपण एका उदाहरणादाखल ERC-20 कॉन्ट्रॅक्टचा वापर करतो ज्यामध्ये सुरुवातीला एक खाजगी वेळ असतो. मालक खाजगी वापरकर्त्यांना व्यवस्थापित करू शकतो आणि सुरुवातीला फक्त त्यांनाच टोकन मिळवण्याची परवानगी असेल. एकदा ठराविक वेळ निघून गेल्यावर, प्रत्येकाला टोकन वापरण्याची परवानगी दिली जाईल. तुम्हाला उत्सुकता असल्यास, आम्ही नवीन OpenZeppelin contracts v3 मधून [`_beforeTokenTransfer`](https://docs.openzeppelin.com/contracts/5.x/extending-contracts#using-hooks) हुक वापरत आहोत. + +```solidity +pragma solidity ^0.6.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/access/Ownable.sol"; + +contract PrivateERC20 is ERC20, Ownable { + mapping (address => bool) public isPrivateUser; + uint256 private publicAfterTime; + + constructor(uint256 privateERC20timeInSec) ERC20("PrivateERC20", "PRIV") public { + publicAfterTime = now + privateERC20timeInSec; + } + + function addUser(address user) external onlyOwner { + isPrivateUser[user] = true; + } + + function isPublic() public view returns (bool) { + return now >= publicAfterTime; + } + + function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override { + super._beforeTokenTransfer(from, to, amount); + + require(_validRecipient(to), "PrivateERC20: invalid recipient"); + } + + function _validRecipient(address to) private view returns (bool) { + if (isPublic()) { + return true; + } + + return isPrivateUser[to]; + } +} +``` + +आणि आता आपण ते मॉक करूया. + +```solidity +pragma solidity ^0.6.0; +import "../PrivateERC20.sol"; + +contract PrivateERC20Mock is PrivateERC20 { + bool isPublicConfig; + + constructor() public PrivateERC20(0) {} + + function setIsPublic(bool isPublic) external { + isPublicConfig = isPublic; + } + + function isPublic() public view returns (bool) { + return isPublicConfig; + } +} +``` + +तुम्हाला खालीलपैकी एक त्रुटी संदेश मिळेल: + +- `PrivateERC20Mock.sol: TypeError: Overriding function is missing "override" specifier.` +- `PrivateERC20.sol: TypeError: Trying to override non-virtual function. Did you forget to add "virtual"?.` + +आपण नवीन Solidity आवृत्ती 0.6 वापरत असल्यामुळे, ओव्हरराइड केल्या जाऊ शकणार्‍या फंक्शन्ससाठी `virtual` कीवर्ड आणि ओव्हरराइडिंग फंक्शनसाठी `override` कीवर्ड जोडावा लागेल. तर चला, हे दोन्ही `isPublic` फंक्शन्समध्ये जोडूया. + +आता तुमच्या युनिट चाचण्यांमध्ये, तुम्ही त्याऐवजी `PrivateERC20Mock` वापरू शकता. जेव्हा तुम्हाला खाजगी वापराच्या वेळेतील वर्तनाची चाचणी करायची असेल, तेव्हा `setIsPublic(false)` वापरा आणि त्याचप्रमाणे सार्वजनिक वापराच्या वेळेची चाचणी करण्यासाठी `setIsPublic(true)` वापरा. अर्थातच आपल्या उदाहरणात, आपण वेळ बदलण्यासाठी [टाइम हेल्पर्स](https://docs.openzeppelin.com/test-helpers/0.5/api#increase) देखील वापरू शकलो असतो. पण आता मॉक करण्याची कल्पना स्पष्ट झाली असेल आणि तुम्ही अशा परिस्थितीची कल्पना करू शकता जिथे फक्त वेळ पुढे नेण्याइतके सोपे नसते. + +## अनेक कॉन्ट्रॅक्ट्सना मॉक करणे {#mocking-many-contracts} + +प्रत्येक मॉकसाठी तुम्हाला दुसरा कॉन्ट्रॅक्ट तयार करावा लागल्यास ते गोंधळात टाकणारे असू शकते. जर तुम्हाला याचा त्रास होत असेल, तर तुम्ही [MockContract](https://github.com/gnosis/mock-contract) लायब्ररी पाहू शकता. हे तुम्हाला कॉन्ट्रॅक्ट्सचे वर्तन त्वरित ओव्हरराइड आणि बदलण्याची परवानगी देते. तथापि, हे फक्त दुसऱ्या कॉन्ट्रॅक्टला कॉल मॉक करण्यासाठी कार्य करते, त्यामुळे ते आपल्या उदाहरणासाठी कार्य करणार नाही. + +## मॉक करणे आणखी शक्तिशाली असू शकते {#mocking-can-be-even-more-powerful} + +मॉक करण्याची शक्ती इथेच संपत नाही. + +- फंक्शन्स जोडणे: केवळ एखादे विशिष्ट फंक्शन ओव्हरराइड करणेच उपयुक्त नाही, तर अतिरिक्त फंक्शन्स जोडणे देखील उपयुक्त आहे. टोकन्ससाठी एक चांगले उदाहरण म्हणजे फक्त एक अतिरिक्त `mint` फंक्शन असणे जे कोणत्याही वापरकर्त्याला विनामूल्य नवीन टोकन मिळविण्याची परवानगी देते. +- टेस्टनेटमध्ये वापर: जेव्हा तुम्ही तुमच्या dApp सह टेस्टनेटवर तुमचे कॉन्ट्रॅक्ट्स तैनात आणि चाचणी करता, तेव्हा मॉक केलेली आवृत्ती वापरण्याचा विचार करा. खरोखरच गरज असल्याशिवाय फंक्शन्स ओव्हरराइड करणे टाळा. शेवटी, तुम्हाला खऱ्या लॉजिकची चाचणी करायची आहे. परंतु उदाहरणार्थ, रीसेट फंक्शन जोडणे उपयुक्त ठरू शकते जे फक्त कॉन्ट्रॅक्टची स्थिती सुरुवातीला रीसेट करते, नवीन तैनातीची आवश्यकता नाही. अर्थातच तुम्हाला Mainnet कॉन्ट्रॅक्टमध्ये ते नको असेल. diff --git a/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md new file mode 100644 index 00000000000..c8ed9c7deff --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -0,0 +1,708 @@ +--- +title: "स्मार्ट कॉन्ट्रॅक्ट्सची चाचणी घेण्यासाठी Echidna चा वापर कसा करावा" +description: "स्मार्ट कॉन्ट्रॅक्ट्सची आपोआप चाचणी घेण्यासाठी Echidna चा वापर कसा करावा" +author: "Trailofbits" +lang: mr +tags: + [ + "सॉलिडिटी", + "स्मार्ट कॉन्ट्रॅक्ट", + "सुरक्षा", + "चाचणी", + "fuzzing" + ] +skill: advanced +published: 2020-04-10 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna +--- + +## इन्स्टॉलेशन {#installation} + +Echidna डॉकरद्वारे किंवा प्री-कंपाइल बायनरी वापरून इन्स्टॉल केले जाऊ शकते. + +### डॉकरद्वारे Echidna {#echidna-through-docker} + +```bash +docker pull trailofbits/eth-security-toolbox +docker run -it -v "$PWD":/home/training trailofbits/eth-security-toolbox +``` + +_शेवटचा कमांड तुमच्या सध्याच्या डिरेक्टरीमध्ये ऍक्सेस असलेल्या docker मध्ये eth-security-toolbox चालवतो. तुम्ही तुमच्या होस्टमधून फाइल्स बदलू शकता, आणि docker मधून फाइल्सवर टूल्स चालवू शकता_ + +डॉकरमध्ये, चालवा : + +```bash +solc-select 0.5.11 +cd /home/training +``` + +### बायनरी {#binary} + +[https://github.com/crytic/echidna/releases/tag/v1.4.0.0](https://github.com/crytic/echidna/releases/tag/v1.4.0.0) + +## प्रॉपर्टी-आधारित फझिंगची ओळख {#introduction-to-property-based-fuzzing} + +Echidna एक प्रॉपर्टी-आधारित फझर आहे, ज्याचे वर्णन आम्ही आमच्या मागील ब्लॉगपोस्टमध्ये केले आहे ([1](https://blog.trailofbits.com/2018/03/09/echidna-a-smart-fuzzer-for-ethereum/), [2](https://blog.trailofbits.com/2018/05/03/state-machine-testing-with-echidna/), [3](https://blog.trailofbits.com/2020/03/30/an-echidna-for-all-seasons/)). + +### फझिंग {#fuzzing} + +[Fuzzing](https://wikipedia.org/wiki/Fuzzing) हे सुरक्षा समुदायामध्ये एक सुप्रसिद्ध तंत्र आहे. यात प्रोग्राममधील बग शोधण्यासाठी कमी-अधिक प्रमाणात यादृच्छिक इनपुट तयार करणे समाविष्ट आहे. पारंपारिक सॉफ्टवेअरसाठी फझर्स (जसे की [AFL](http://lcamtuf.coredump.cx/afl/) किंवा [LibFuzzer](https://llvm.org/docs/LibFuzzer.html)) बग शोधण्यासाठी कार्यक्षम साधने म्हणून ओळखले जातात. + +केवळ यादृच्छिक इनपुट तयार करण्यापलीकडे, चांगले इनपुट तयार करण्यासाठी अनेक तंत्रे आणि धोरणे आहेत, ज्यात खालील गोष्टींचा समावेश आहे: + +- प्रत्येक अंमलबजावणीतून अभिप्राय मिळवा आणि त्याचा वापर करून पिढीला मार्गदर्शन करा. उदाहरणार्थ, जर नवीन तयार केलेल्या इनपुटमुळे नवीन मार्ग सापडला, तर त्याच्या जवळ नवीन इनपुट तयार करणे अर्थपूर्ण ठरू शकते. +- रचनात्मक मर्यादांचा आदर करून इनपुट तयार करणे. उदाहरणार्थ, जर तुमच्या इनपुटमध्ये चेकसमसह हेडर असेल, तर फझरला चेकसम प्रमाणित करणारे इनपुट तयार करू देणे अर्थपूर्ण ठरेल. +- नवीन इनपुट तयार करण्यासाठी ज्ञात इनपुट वापरणे: जर तुमच्याकडे वैध इनपुटच्या मोठ्या डेटासेटमध्ये प्रवेश असेल, तर तुमचा फझर सुरवातीपासून त्याची निर्मिती सुरू करण्याऐवजी त्यातून नवीन इनपुट तयार करू शकतो. यांना सहसा _seeds_ म्हटले जाते. + +### प्रॉपर्टी-आधारित फझिंग {#property-based-fuzzing} + +Echidna फझरच्या एका विशिष्ट कुटुंबाशी संबंधित आहे: [QuickCheck](https://wikipedia.org/wiki/QuickCheck) द्वारे मोठ्या प्रमाणावर प्रेरित प्रॉपर्टी-आधारित फझिंग. क्रॅश शोधण्याचा प्रयत्न करणाऱ्या क्लासिक फझरच्या विपरीत, Echidna वापरकर्ता-परिभाषित इनव्हेरियंट्स तोडण्याचा प्रयत्न करेल. + +स्मार्ट कॉन्ट्रॅक्ट्समध्ये, इनव्हेरियंट्स हे Solidity फंक्शन्स असतात, जे कॉन्ट्रॅक्ट पोहोचू शकणाऱ्या कोणत्याही चुकीच्या किंवा अवैध स्थितीचे प्रतिनिधित्व करू शकतात, ज्यात खालील गोष्टींचा समावेश आहे: + +- चुकीचे प्रवेश नियंत्रण: आक्रमणकर्ता कॉन्ट्रॅक्टचा मालक बनला. +- चुकीचे स्टेट मशीन: कॉन्ट्रॅक्ट थांबवलेले असताना टोकन हस्तांतरित केले जाऊ शकतात. +- चुकीचे अंकगणित: वापरकर्ता त्याचे शिल्लक कमी करू शकतो आणि अमर्यादित विनामूल्य टोकन मिळवू शकतो. + +### Echidna सह प्रॉपर्टीची चाचणी करणे {#testing-a-property-with-echidna} + +आम्ही Echidna सह स्मार्ट कॉन्ट्रॅक्टची चाचणी कशी करायची ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे [`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol): + +```solidity +contract Token{ + mapping(address => uint) public balances; + function airdrop() public{ + balances[msg.sender] = 1000; + } + function consume() public{ + require(balances[msg.sender]>0); + balances[msg.sender] -= 1; + } + function backdoor() public{ + balances[msg.sender] += 1; + } +} +``` + +आम्ही असे गृहीत धरू की या टोकनमध्ये खालील गुणधर्म असणे आवश्यक आहे: + +- कोणाकडेही जास्तीत जास्त 1000 टोकन असू शकतात +- टोकन हस्तांतरित केले जाऊ शकत नाही (ते ERC20 टोकन नाही) + +### एक प्रॉपर्टी लिहा {#write-a-property} + +Echidna प्रॉपर्टीज या Solidity फंक्शन्स आहेत. एका प्रॉपर्टीमध्ये हे असणे आवश्यक आहे: + +- कोणतेही आर्ग्युमेंट नसावे +- यशस्वी झाल्यास `true` परत करा +- त्याचे नाव `echidna` ने सुरू झाले पाहिजे + +Echidna हे करेल: + +- प्रॉपर्टीची चाचणी घेण्यासाठी आपोआप अनियंत्रित व्यवहार तयार करा. +- एखाद्या प्रॉपर्टीला `false` परत करण्यास किंवा त्रुटी निर्माण करण्यास कारणीभूत ठरलेल्या कोणत्याही व्यवहारांची तक्रार करा. +- प्रॉपर्टी कॉल करताना साईड-इफेक्ट टाळा (म्हणजे, जर प्रॉपर्टी स्टेट व्हेरिएबल बदलत असेल, तर चाचणीनंतर ते टाकून दिले जाते) + +खालील प्रॉपर्टी तपासते की कॉलरकडे 1000 पेक्षा जास्त टोकन नाहीत: + +```solidity +function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; +} +``` + +तुमच्या कॉन्ट्रॅक्टला तुमच्या प्रॉपर्टीजपासून वेगळे करण्यासाठी इनहेरिटन्स वापरा: + +```solidity +contract TestToken is Token{ + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +[`token.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/token.sol) प्रॉपर्टी लागू करते आणि टोकनमधून इनहेरिट करते. + +### एक कॉन्ट्रॅक्ट सुरू करा {#initiate-a-contract} + +Echidna ला आर्ग्युमेंटशिवाय [constructor](/developers/docs/smart-contracts/anatomy/#constructor-functions) ची आवश्यकता आहे. जर तुमच्या कॉन्ट्रॅक्टला विशिष्ट इनिशिएलायझेशनची आवश्यकता असेल, तर तुम्हाला ते कन्स्ट्रक्टरमध्ये करावे लागेल. + +Echidna मध्ये काही विशिष्ट ॲड्रेसेस आहेत: + +- `0x00a329c0648769A73afAc7F9381E08FB43dBEA72` जे कन्स्ट्रक्टरला कॉल करते. +- `0x10000`, `0x20000`, आणि `0x00a329C0648769a73afAC7F9381e08fb43DBEA70` जे यादृच्छिकपणे इतर फंक्शन्सना कॉल करतात. + +आमच्या सध्याच्या उदाहरणात आम्हाला कोणत्याही विशिष्ट इनिशिएलायझेशनची आवश्यकता नाही, परिणामी आमचा कन्स्ट्रक्टर रिकामा आहे. + +### Echidna चालवा {#run-echidna} + +Echidna यासह लॉन्च केले जाते: + +```bash +echidna-test contract.sol +``` + +जर contract.sol मध्ये अनेक कॉन्ट्रॅक्ट्स असतील, तर तुम्ही लक्ष्य निर्दिष्ट करू शकता: + +```bash +echidna-test contract.sol --contract MyContract +``` + +### सारांश: एका प्रॉपर्टीची चाचणी करणे {#summary-testing-a-property} + +खालील आमच्या उदाहरणावरील Echidna च्या रनचा सारांश देते: + +```solidity +contract TestToken is Token{ + constructor() public {} + function echidna_balance_under_1000() public view returns(bool){ + return balances[msg.sender] <= 1000; + } + } +``` + +```bash +echidna-test testtoken.sol --contract TestToken +... + +echidna_balance_under_1000: failed!💥 + Call sequence, shrinking (1205/5000): + airdrop() + backdoor() + +... +``` + +Echidna ला आढळले की जर `backdoor` कॉल केला तर प्रॉपर्टीचे उल्लंघन होते. + +## फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स फिल्टर करणे {#filtering-functions-to-call-during-a-fuzzing-campaign} + +आम्ही फझ करण्यासाठी फंक्शन्स कसे फिल्टर करायचे ते पाहू. +लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे: + +```solidity +contract C { + bool state1 = false; + bool state2 = false; + bool state3 = false; + bool state4 = false; + + function f(uint x) public { + require(x == 12); + state1 = true; + } + + function g(uint x) public { + require(state1); + require(x == 8); + state2 = true; + } + + function h(uint x) public { + require(state2); + require(x == 42); + state3 = true; + } + + function i() public { + require(state3); + state4 = true; + } + + function reset1() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function reset2() public { + state1 = false; + state2 = false; + state3 = false; + return; + } + + function echidna_state4() public returns (bool) { + return (!state4); + } +} +``` + +हे लहान उदाहरण Echidna ला स्टेट व्हेरिएबल बदलण्यासाठी व्यवहारांचा एक विशिष्ट क्रम शोधण्यास भाग पाडते. +हे फझरसाठी कठीण आहे (यासाठी [Manticore](https://github.com/trailofbits/manticore) सारखे सिम्बॉलिक एक्झिक्युशन टूल वापरण्याची शिफारस केली जाते). +हे तपासण्यासाठी आपण Echidna चालवू शकतो: + +```bash +echidna-test multi.sol +... +echidna_state4: passed! 🎉 +Seed: -3684648582249875403 +``` + +### फिल्टरिंग फंक्शन्स {#filtering-functions} + +Echidna ला या कॉन्ट्रॅक्टची चाचणी घेण्यासाठी योग्य क्रम शोधण्यात अडचण येत आहे कारण दोन रीसेट फंक्शन्स (`reset1` आणि `reset2`) सर्व स्टेट व्हेरिएबल्स `false` वर सेट करतील. +तथापि, आपण एक विशेष Echidna वैशिष्ट्य वापरू शकतो, एकतर रीसेट फंक्शनला ब्लॅकलिस्ट करण्यासाठी किंवा फक्त `f`, `g`, +`h` आणि `i` फंक्शन्सना व्हाइटलिस्ट करण्यासाठी. + +फंक्शन्स ब्लॅकलिस्ट करण्यासाठी, आम्ही ही कॉन्फिगरेशन फाइल वापरू शकतो: + +```yaml +filterBlacklist: true +filterFunctions: ["reset1", "reset2"] +``` + +फंक्शन्स फिल्टर करण्याचा दुसरा दृष्टिकोन म्हणजे व्हाइटलिस्ट केलेल्या फंक्शन्सची यादी करणे. ते करण्यासाठी, आम्ही ही कॉन्फिगरेशन फाइल वापरू शकतो: + +```yaml +filterBlacklist: false +filterFunctions: ["f", "g", "h", "i"] +``` + +- `filterBlacklist` हे डीफॉल्टनुसार `true` असते. +- फिल्टरिंग केवळ नावाने केले जाईल (पॅरामीटर्सशिवाय). जर तुमच्याकडे `f()` आणि `f(uint256)` असेल, तर `"f"` फिल्टर दोन्ही फंक्शन्सना जुळेल. + +### Echidna चालवा {#run-echidna-1} + +`blacklist.yaml` कॉन्फिगरेशन फाइलसह Echidna चालवण्यासाठी: + +```bash +echidna-test multi.sol --config blacklist.yaml +... +echidna_state4: failed!💥 + Call sequence: + f(12) + g(8) + h(42) + i() +``` + +Echidna जवळजवळ त्वरित प्रॉपर्टीला खोटे ठरवण्यासाठी व्यवहारांचा क्रम शोधेल. + +### सारांश: फिल्टरिंग फंक्शन्स {#summary-filtering-functions} + +Echidna फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स ब्लॅकलिस्ट किंवा व्हाइटलिस्ट करू शकते: + +```yaml +filterBlacklist: true +filterFunctions: ["f1", "f2", "f3"] +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +`filterBlacklist` बुलियनच्या मूल्यांनुसार Echidna `f1`, `f2` आणि `f3` ला ब्लॅकलिस्ट करून किंवा फक्त त्यांना कॉल करून फझिंग मोहीम सुरू करते. + +## Echidna सह Solidity's assert ची चाचणी कशी करावी {#how-to-test-soliditys-assert-with-echidna} + +या लहान ट्युटोरियलमध्ये, आम्ही कॉन्ट्रॅक्ट्समध्ये अॅसर्शन चेकिंगची चाचणी घेण्यासाठी Echidna चा वापर कसा करायचा हे दाखवणार आहोत. समजा आपल्याकडे यासारखा एक कॉन्ट्रॅक्ट आहे: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + // tmp <= counter + return (counter - tmp); + } +} +``` + +### एक अॅसर्शन लिहा {#write-an-assertion} + +त्यातील फरक परत केल्यानंतर `tmp` हे `counter` पेक्षा कमी किंवा समान आहे याची आम्ही खात्री करू इच्छितो. आपण Echidna +प्रॉपर्टी लिहू शकतो, पण आपल्याला `tmp` मूल्य कुठेतरी साठवावे लागेल. त्याऐवजी, आपण यासारखे अॅसर्शन वापरू शकतो: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +### Echidna चालवा {#run-echidna-2} + +अॅसर्शन अयशस्वी चाचणी सक्षम करण्यासाठी, एक [Echidna कॉन्फिगरेशन फाइल](https://github.com/crytic/echidna/wiki/Config) `config.yaml` तयार करा: + +```yaml +checkAsserts: true +``` + +जेव्हा आपण Echidna मध्ये हा कॉन्ट्रॅक्ट चालवतो, तेव्हा आपल्याला अपेक्षित परिणाम मिळतात: + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +तुम्ही बघू शकता, Echidna `inc` फंक्शनमध्ये काही अॅसर्शन अयशस्वी झाल्याची तक्रार करते. प्रत्येक फंक्शनमध्ये एकापेक्षा जास्त अॅसर्शन जोडणे शक्य आहे, परंतु कोणते अॅसर्शन अयशस्वी झाले हे Echidna सांगू शकत नाही. + +### अॅसर्शन्स केव्हा आणि कसे वापरावे {#when-and-how-use-assertions} + +अॅसर्शन्स स्पष्ट प्रॉपर्टीजसाठी पर्याय म्हणून वापरले जाऊ शकतात, विशेषतः जर तपासण्याची परिस्थिती थेट काही ऑपरेशन `f` च्या योग्य वापराशी संबंधित असेल. काही कोडनंतर अॅसर्शन्स जोडल्याने हे सुनिश्चित होईल की तपासणी त्याच्या अंमलबजावणीनंतर लगेच होईल: + +```solidity +function f(..) public { + // काही जटिल कोड + ... + assert (condition); + ... +} + +``` + +याउलट, स्पष्ट Echidna प्रॉपर्टी वापरल्याने व्यवहार यादृच्छिकपणे अंमलात येतील आणि ते केव्हा तपासले जाईल हे लागू करण्याचा कोणताही सोपा मार्ग नाही. हा वर्कअराउंड करणे अजूनही शक्य आहे: + +```solidity +function echidna_assert_after_f() public returns (bool) { + f(..); + return(condition); +} +``` + +तथापि, काही समस्या आहेत: + +- जर `f` हे `internal` किंवा `external` म्हणून घोषित केले असेल तर ते अयशस्वी होते. +- `f` ला कॉल करण्यासाठी कोणते आर्ग्युमेंट्स वापरावे हे अस्पष्ट आहे. +- जर `f` रिव्हर्ट झाले, तर प्रॉपर्टी अयशस्वी होईल. + +सर्वसाधारणपणे, आम्ही अॅसर्शन्स कसे वापरावे यावर [जॉन रेगेहर यांच्या शिफारसीचे](https://blog.regehr.org/archives/1091) पालन करण्याची शिफारस करतो: + +- अॅसर्शन तपासणी दरम्यान कोणताही साईड इफेक्ट जबरदस्तीने करू नका. उदाहरणार्थ: `assert(ChangeStateAndReturn() == 1)` +- स्पष्ट विधाने निश्चित करू नका. उदाहरणार्थ, `assert(var >= 0)` जेथे `var` हे `uint` म्हणून घोषित केले आहे. + +शेवटी, कृपया `assert` ऐवजी `require` **वापरू नका**, कारण Echidna ते शोधू शकणार नाही (परंतु कॉन्ट्रॅक्ट तरीही रिव्हर्ट होईल). + +### सारांश: अॅसर्शन चेकिंग {#summary-assertion-checking} + +खालील आमच्या उदाहरणावरील Echidna च्या रनचा सारांश देते: + +```solidity +contract Incrementor { + uint private counter = 2**200; + + function inc(uint val) public returns (uint){ + uint tmp = counter; + counter += val; + assert (tmp <= counter); + return (counter - tmp); + } +} +``` + +```bash +echidna-test assert.sol --config config.yaml +Analyzing contract: assert.sol:Incrementor +assertion in inc: failed!💥 + Call sequence, shrinking (2596/5000): + inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) + inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) + inc(86844066927987146567678238756515930889952488499230423029593188005934847229952) + +Seed: 1806480648350826486 +``` + +Echidna ला आढळले की `inc` मधील अॅसर्शन अयशस्वी होऊ शकते जर हे फंक्शन मोठ्या आर्ग्युमेंट्ससह अनेक वेळा कॉल केले गेले. + +## Echidna कॉर्पस गोळा करणे आणि त्यात बदल करणे {#collecting-and-modifying-an-echidna-corpus} + +आम्ही Echidna सह व्यवहारांचा कॉर्पस कसा गोळा करायचा आणि वापरायचा ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे [`magic.sol`](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/example/magic.sol): + +```solidity +contract C { + bool value_found = false; + function magic(uint magic_1, uint magic_2, uint magic_3, uint magic_4) public { + require(magic_1 == 42); + require(magic_2 == 129); + require(magic_3 == magic_4+333); + value_found = true; + return; + } + + function echidna_magic_values() public returns (bool) { + return !value_found; + } + +} +``` + +हे लहान उदाहरण Echidna ला स्टेट व्हेरिएबल बदलण्यासाठी काही विशिष्ट मूल्ये शोधण्यास भाग पाडते. हे फझरसाठी कठीण आहे +(यासाठी [Manticore](https://github.com/trailofbits/manticore) सारखे सिम्बॉलिक एक्झिक्युशन टूल वापरण्याची शिफारस केली जाते). +हे तपासण्यासाठी आपण Echidna चालवू शकतो: + +```bash +echidna-test magic.sol +... + +echidna_magic_values: passed! 🎉 + +Seed: 2221503356319272685 +``` + +तथापि, ही फझिंग मोहीम चालवताना कॉर्पस गोळा करण्यासाठी आम्ही अजूनही Echidna वापरू शकतो. + +### कॉर्पस गोळा करणे {#collecting-a-corpus} + +कॉर्पस संकलन सक्षम करण्यासाठी, एक कॉर्पस डिरेक्टरी तयार करा: + +```bash +mkdir corpus-magic +``` + +आणि एक [Echidna कॉन्फिगरेशन फाइल](https://github.com/crytic/echidna/wiki/Config) `config.yaml`: + +```yaml +coverage: true +corpusDir: "corpus-magic" +``` + +आता आपण आपले टूल चालवू शकतो आणि गोळा केलेला कॉर्पस तपासू शकतो: + +```bash +echidna-test magic.sol --config config.yaml +``` + +Echidna अजूनही योग्य मॅजिक व्हॅल्यूज शोधू शकत नाही, परंतु आपण त्याने गोळा केलेल्या कॉर्पसवर एक नजर टाकू शकतो. +उदाहरणार्थ, यापैकी एक फाइल होती: + +```json +[ + { + "_gas'": "0xffffffff", + "_delay": ["0x13647", "0xccf6"], + "_src": "00a329c0648769a73afac7f9381e08fb43dbea70", + "_dst": "00a329c0648769a73afac7f9381e08fb43dbea72", + "_value": "0x0", + "_call": { + "tag": "SolCall", + "contents": [ + "magic", + [ + { + "contents": [ + 256, + "93723985220345906694500679277863898678726808528711107336895287282192244575836" + ], + "tag": "AbiUInt" + }, + { + "contents": [256, "334"], + "tag": "AbiUInt" + }, + { + "contents": [ + 256, + "68093943901352437066264791224433559271778087297543421781073458233697135179558" + ], + "tag": "AbiUInt" + }, + { + "tag": "AbiUInt", + "contents": [256, "332"] + } + ] + ] + }, + "_gasprice'": "0xa904461f1" + } +] +``` + +स्पष्टपणे, हे इनपुट आमच्या प्रॉपर्टीमध्ये अपयश आणणार नाही. तथापि, पुढील चरणात, आम्ही त्यासाठी त्यात कसे बदल करायचे ते पाहू. + +### कॉर्पस सीडिंग करणे {#seeding-a-corpus} + +`magic` फंक्शन हाताळण्यासाठी Echidna ला काही मदतीची गरज आहे. आम्ही इनपुट कॉपी करणार आहोत आणि त्यासाठी योग्य +पॅरामीटर्स वापरण्यासाठी त्यात बदल करणार आहोत: + +```bash +cp corpus/2712688662897926208.txt corpus/new.txt +``` + +आम्ही `magic(42,129,333,0)` ला कॉल करण्यासाठी `new.txt` मध्ये बदल करू. आता, आपण Echidna पुन्हा चालवू शकतो: + +```bash +echidna-test magic.sol --config config.yaml +... +echidna_magic_values: failed!💥 + Call sequence: + magic(42,129,333,0) + + +Unique instructions: 142 +Unique codehashes: 1 +Seed: -7293830866560616537 + +``` + +यावेळी, त्याला आढळले की प्रॉपर्टीचे त्वरित उल्लंघन झाले आहे. + +## उच्च गॅस वापरासह व्यवहार शोधणे {#finding-transactions-with-high-gas-consumption} + +आम्ही Echidna सह उच्च गॅस वापरासह व्यवहार कसे शोधायचे ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे: + +```solidity +contract C { + uint state; + + function expensive(uint8 times) internal { + for(uint8 i=0; i < times; i++) + state = state + i; + } + + function f(uint x, uint y, uint8 times) public { + if (x == 42 && y == 123) + expensive(times); + else + state = 0; + } + + function echidna_test() public returns (bool) { + return true; + } + +} +``` + +येथे `expensive` मध्ये मोठा गॅस वापर असू शकतो. + +सध्या, Echidna ला नेहमी चाचणीसाठी एक प्रॉपर्टीची आवश्यकता असते: येथे `echidna_test` नेहमी `true` परत करते. +हे तपासण्यासाठी आपण Echidna चालवू शकतो: + +``` +echidna-test gas.sol +... +echidna_test: passed! 🎉 + +Seed: 2320549945714142710 +``` + +### गॅस वापर मोजणे {#measuring-gas-consumption} + +Echidna सह गॅस वापर सक्षम करण्यासाठी, एक कॉन्फिगरेशन फाइल `config.yaml` तयार करा: + +```yaml +estimateGas: true +``` + +या उदाहरणात, आम्ही परिणाम समजण्यास सोपे करण्यासाठी व्यवहार क्रमाचा आकार देखील कमी करू: + +```yaml +seqLen: 2 +estimateGas: true +``` + +### Echidna चालवा {#run-echidna-3} + +एकदा आम्ही कॉन्फिगरेशन फाइल तयार केल्यावर, आम्ही Echidna याप्रमाणे चालवू शकतो: + +```bash +echidna-test gas.sol --config config.yaml +... +echidna_test: passed! 🎉 + +f used a maximum of 1333608 gas + Call sequence: + f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2 + +Unique instructions: 157 +Unique codehashes: 1 +Seed: -325611019680165325 + +``` + +- दाखवलेला गॅस हा [HEVM](https://github.com/dapphub/dapptools/tree/master/src/hevm#hevm-) द्वारे प्रदान केलेला एक अंदाज आहे. + +### गॅस-कमी करणारे कॉल्स फिल्टर करणे {#filtering-out-gas-reducing-calls} + +वरील **फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स फिल्टर करणे** यावरील ट्युटोरियल तुमच्या चाचणीमधून काही फंक्शन्स कसे काढायचे हे दाखवते. +अचूक गॅस अंदाज मिळवण्यासाठी हे महत्त्वपूर्ण असू शकते. +खालील उदाहरण विचारात घ्या: + +```solidity +contract C { + address [] addrs; + function push(address a) public { + addrs.push(a); + } + function pop() public { + addrs.pop(); + } + function clear() public{ + addrs.length = 0; + } + function check() public{ + for(uint256 i = 0; i < addrs.length; i++) + for(uint256 j = i+1; j < addrs.length; j++) + if (addrs[i] == addrs[j]) + addrs[j] = address(0x0); + } + function echidna_test() public returns (bool) { + return true; + } +} +``` + +जर Echidna सर्व फंक्शन्सना कॉल करू शकत असेल, तर त्याला उच्च गॅस खर्चासह व्यवहार सहज सापडणार नाहीत: + +``` +echidna-test pushpop.sol --config config.yaml +... +pop used a maximum of 10746 gas +... +check used a maximum of 23730 gas +... +clear used a maximum of 35916 gas +... +push used a maximum of 40839 gas +``` + +कारण खर्च `addrs` च्या आकारावर अवलंबून असतो आणि यादृच्छिक कॉल्समुळे ॲरे जवळजवळ रिकामा राहतो. +तथापि, `pop` आणि `clear` ला ब्लॅकलिस्ट केल्याने आम्हाला बरेच चांगले परिणाम मिळतात: + +```yaml +filterBlacklist: true +filterFunctions: ["pop", "clear"] +``` + +``` +echidna-test pushpop.sol --config config.yaml +... +push used a maximum of 40839 gas +... +check used a maximum of 1484472 gas +``` + +### सारांश: उच्च गॅस वापरासह व्यवहार शोधणे {#summary-finding-transactions-with-high-gas-consumption} + +`estimateGas` कॉन्फिगरेशन पर्याय वापरून Echidna उच्च गॅस वापरासह व्यवहार शोधू शकते: + +```yaml +estimateGas: true +``` + +```bash +echidna-test contract.sol --config config.yaml +... +``` + +एकदा फझिंग मोहीम संपली की, Echidna प्रत्येक फंक्शनसाठी कमाल गॅस वापरासह एक क्रम नोंदवेल. From 4dd7f6f89c4b47e278626f2b0934ab5cdb0c1502 Mon Sep 17 00:00:00 2001 From: Joshua <62268199+minimalsm@users.noreply.github.com> Date: Sat, 14 Feb 2026 00:13:42 +0000 Subject: [PATCH 3/9] i18n(mr): translation import part 09 of 13 (23 files) --- .../developers/tutorials/short-abi/index.md | 585 +++++ .../index.md | 91 + .../tutorials/stealth-addr/index.md | 436 ++++ .../index.md | 314 +++ .../token-integration-checklist/index.md | 86 + .../index.md | 314 +++ .../index.md | 177 ++ .../uniswap-v2-annotated-code/index.md | 1898 +++++++++++++++++ .../tutorials/using-websockets/index.md | 245 +++ .../index.md | 300 +++ .../index.md | 204 ++ .../index.md | 199 ++ .../tutorials/yellow-paper-evm/index.md | 278 +++ public/content/translations/mr/eips/index.md | 78 + .../mr/energy-consumption/index.md | 86 + .../translations/mr/eth/supply/index.md | 80 + .../translations/mr/ethereum-forks/index.md | 663 ++++++ .../translations/mr/foundation/index.md | 33 + .../content/translations/mr/gaming/index.md | 70 + .../content/translations/mr/glossary/index.md | 505 +++++ .../translations/mr/governance/index.md | 184 ++ .../index.md | 75 + .../mr/guides/how-to-id-scam-tokens/index.md | 94 + 23 files changed, 6995 insertions(+) create mode 100644 public/content/translations/mr/developers/tutorials/short-abi/index.md create mode 100644 public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md create mode 100644 public/content/translations/mr/developers/tutorials/stealth-addr/index.md create mode 100644 public/content/translations/mr/developers/tutorials/the-graph-fixing-web3-data-querying/index.md create mode 100644 public/content/translations/mr/developers/tutorials/token-integration-checklist/index.md create mode 100644 public/content/translations/mr/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md create mode 100644 public/content/translations/mr/developers/tutorials/using-websockets/index.md create mode 100644 public/content/translations/mr/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md create mode 100644 public/content/translations/mr/developers/tutorials/waffle-say-hello-world-with-hardhat-and-ethers/index.md create mode 100644 public/content/translations/mr/developers/tutorials/waffle-test-simple-smart-contract/index.md create mode 100644 public/content/translations/mr/developers/tutorials/yellow-paper-evm/index.md create mode 100644 public/content/translations/mr/eips/index.md create mode 100644 public/content/translations/mr/energy-consumption/index.md create mode 100644 public/content/translations/mr/eth/supply/index.md create mode 100644 public/content/translations/mr/ethereum-forks/index.md create mode 100644 public/content/translations/mr/foundation/index.md create mode 100644 public/content/translations/mr/gaming/index.md create mode 100644 public/content/translations/mr/glossary/index.md create mode 100644 public/content/translations/mr/governance/index.md create mode 100644 public/content/translations/mr/guides/how-to-create-an-ethereum-account/index.md create mode 100644 public/content/translations/mr/guides/how-to-id-scam-tokens/index.md diff --git a/public/content/translations/mr/developers/tutorials/short-abi/index.md b/public/content/translations/mr/developers/tutorials/short-abi/index.md new file mode 100644 index 00000000000..5c32c7c8482 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/short-abi/index.md @@ -0,0 +1,585 @@ +--- +title: "कॉलडेटा ऑप्टिमायझेशनसाठी लहान ABI" +description: "ऑप्टिमिस्टिक रोलअपसाठी स्मार्ट कॉन्ट्रॅक्ट्स ऑप्टिमाइझ करणे" +author: Ori Pomerantz +lang: mr +tags: [ "स्तर 2" ] +skill: intermediate +published: 2022-04-01 +--- + +## प्रस्तावना {#introduction} + +या लेखात, आपण [optimistic rollups](/developers/docs/scaling/optimistic-rollups) बद्दल शिकाल, त्यावरील व्यवहारांची किंमत, आणि ती वेगळी किंमत संरचना Ethereum मेननेटपेक्षा आपल्याला वेगवेगळ्या गोष्टींसाठी ऑप्टिमाइझ करण्याची आवश्यकता कशी निर्माण करते. +हे ऑप्टिमायझेशन कसे लागू करायचे हे देखील आपण शिकाल. + +### संपूर्ण प्रकटीकरण {#full-disclosure} + +मी एक पूर्णवेळ [Optimism](https://www.optimism.io/) कर्मचारी आहे, त्यामुळे या लेखातील उदाहरणे Optimism वर चालतील. +तथापि, येथे स्पष्ट केलेले तंत्र इतर रोलअपसाठी देखील तितकेच चांगले कार्य करेल. + +### परिभाषा {#terminology} + +रोलअपवर चर्चा करताना, 'स्तर 1' (L1) ही संज्ञा मेननेटसाठी वापरली जाते, जे उत्पादन Ethereum नेटवर्क आहे. +'स्तर 2' (L2) ही संज्ञा रोलअप किंवा इतर कोणत्याही प्रणालीसाठी वापरली जाते जी सुरक्षिततेसाठी L1 वर अवलंबून असते परंतु तिची बहुतेक प्रक्रिया ऑफचेन करते. + +## आपण L2 व्यवहारांची किंमत आणखी कशी कमी करू शकतो? {#how-can-we-further-reduce-the-cost-of-L2-transactions} + +[ऑप्टिमिस्टिक रोलअप्सना](/developers/docs/scaling/optimistic-rollups) प्रत्येक ऐतिहासिक व्यवहाराचा रेकॉर्ड जतन करावा लागतो जेणेकरून कोणीही त्यातून जाऊन सध्याची स्थिती योग्य आहे हे सत्यापित करू शकेल. +Ethereum मेननेटमध्ये डेटा मिळवण्याचा सर्वात स्वस्त मार्ग म्हणजे तो कॅलडेटा म्हणून लिहिणे. +हे समाधान [Optimism](https://help.optimism.io/hc/en-us/articles/4413163242779-What-is-a-rollup-) आणि [Arbitrum](https://developer.offchainlabs.com/docs/rollup_basics#intro-to-rollups) या दोघांनी निवडले होते. + +### L2 व्यवहारांची किंमत {#cost-of-l2-transactions} + +L2 व्यवहारांच्या किंमतीत दोन घटक असतात: + +1. L2 प्रक्रिया, जी सहसा अत्यंत स्वस्त असते +2. L1 स्टोरेज, जे मेननेट गॅस खर्चाशी जोडलेले आहे + +मी हे लिहित असताना, Optimism वर L2 गॅसची किंमत 0.001 [Gwei](/developers/docs/gas/#pre-london) आहे. +दुसरीकडे, L1 गॅसची किंमत अंदाजे 40 gwei आहे. +[आपण सध्याच्या किमती येथे पाहू शकता](https://public-grafana.optimism.io/d/9hkhMxn7z/public-dashboard?orgId=1&refresh=5m). + +कॅलडेटाच्या एका बाइटला एकतर 4 गॅस (जर तो शून्य असेल तर) किंवा 16 गॅस (जर ते इतर कोणतेही मूल्य असेल तर) लागतात. +EVM वरील सर्वात महागड्या क्रियांपैकी एक म्हणजे स्टोरेजमध्ये लिहिणे. +L2 वर स्टोरेजमध्ये 32-बाइट शब्द लिहिण्याची कमाल किंमत 22100 गॅस आहे. सध्या, हे 22.1 gwei आहे. +म्हणून जर आपण कॅलडेटाचा एक शून्य बाइट वाचवू शकलो, तर आपण स्टोरेजमध्ये सुमारे 200 बाइट्स लिहू शकू आणि तरीही फायद्यात राहू. + +### ABI {#the-abi} + +बहुतेक व्यवहार बाह्य-मालकीच्या खात्यातून करारावर प्रवेश करतात. +बहुतेक कॉन्ट्रॅक्ट्स Solidity मध्ये लिहिलेले आहेत आणि [ऍप्लिकेशन बायनरी इंटरफेस (ABI)](https://docs.soliditylang.org/en/latest/abi-spec.html#formal-specification-of-the-encoding) नुसार त्यांचे डेटा फील्ड इंटरप्रिट करतात. + +तथापि, ABI हे L1 साठी डिझाइन केले होते, जिथे कॅलडेटाच्या एका बाइटची किंमत अंदाजे चार अंकगणितीय क्रियांइतकी असते, L2 साठी नाही, जिथे कॅलडेटाच्या एका बाइटची किंमत हजारहून अधिक अंकगणितीय क्रियांइतकी असते. +कॅलडेटा खालीलप्रमाणे विभागलेला आहे: + +| विभाग | लांबी | बाइट्स | वाया गेलेले बाइट्स | वाया गेलेला गॅस | आवश्यक बाइट्स | आवश्यक गॅस | +| --------------- | ----: | -----: | -----------------: | --------------: | ------------: | ---------: | +| फंक्शन सिलेक्टर | 4 | 0-3 | 3 | 48 | 1 | 16 | +| शून्य | 12 | 4-15 | 12 | 48 | 0 | 0 | +| गंतव्य पत्ता | 20 | 16-35 | 0 | 0 | 20 | 320 | +| रक्कम | 32 | 36-67 | 17 | 64 | 15 | 240 | +| एकूण | 68 | | | 160 | | 576 | + +स्पष्टीकरण: + +- **फंक्शन सिलेक्टर**: कॉन्ट्रॅक्टमध्ये 256 पेक्षा कमी फंक्शन्स आहेत, त्यामुळे आपण त्यांना एका बाइटने वेगळे करू शकतो. + हे बाइट्स सहसा गैर-शून्य असतात आणि त्यामुळे [सोळा गॅस खर्च येतो](https://eips.ethereum.org/EIPS/eip-2028). +- **शून्य**: हे बाइट्स नेहमी शून्य असतात कारण वीस-बाइट पत्त्याला ठेवण्यासाठी बत्तीस-बाइट शब्दाची आवश्यकता नसते. + शून्य धारण करणार्‍या बाइट्सना चार गॅस खर्च येतो ([पिवळे पेपर पहा](https://ethereum.github.io/yellowpaper/paper.pdf), परिशिष्ट G, + पृ. 27, `G``txdatazero` चे मूल्य). +- **रक्कम**: जर आपण असे गृहीत धरले की या कॉन्ट्रॅक्टमध्ये `decimals` अठरा आहे (सामान्य मूल्य) आणि आपण हस्तांतरित करत असलेल्या टोकन्सची कमाल रक्कम 1018 असेल, तर आपल्याला 1036 ची कमाल रक्कम मिळते. + 25615 > 1036, म्हणून पंधरा बाइट्स पुरेसे आहेत. + +L1 वर 160 गॅसचा अपव्यय सहसा नगण्य असतो. एका व्यवहाराला किमान [21,000 गॅस](https://yakkomajuri.medium.com/blockchain-definition-of-the-week-ethereum-gas-2f976af774ed) खर्च येतो, त्यामुळे अतिरिक्त 0.8% ने काही फरक पडत नाही. +तथापि, L2 वर, गोष्टी वेगळ्या आहेत. व्यवहाराचा जवळजवळ संपूर्ण खर्च तो L1 वर लिहिण्याचा असतो. +व्यवहार कॅलडेटा व्यतिरिक्त, 109 बाइट्सचे व्यवहार हेडर (गंतव्य पत्ता, स्वाक्षरी, इ.) आहे. +म्हणून एकूण खर्च `109*16+576+160=2480` आहे, आणि आपण त्यापैकी सुमारे 6.5% वाया घालवत आहोत. + +## जेव्हा आपण गंतव्यस्थानावर नियंत्रण ठेवत नाही तेव्हा खर्च कमी करणे {#reducing-costs-when-you-dont-control-the-destination} + +आपले गंतव्य कॉन्ट्रॅक्टवर नियंत्रण नाही असे गृहीत धरून, आपण तरीही [यासारखा](https://github.com/qbzzt/ethereum.org-20220330-shortABI) उपाय वापरू शकता. +चला संबंधित फाइल्स पाहूया. + +### Token.sol {#token-sol} + +[हे गंतव्य कॉन्ट्रॅक्ट आहे](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/Token.sol). +हे एक मानक ERC-20 कॉन्ट्रॅक्ट आहे, ज्यात एक अतिरिक्त वैशिष्ट्य आहे. +हे `faucet` फंक्शन कोणत्याही वापरकर्त्याला वापरण्यासाठी काही टोकन मिळवू देते. +हे एका उत्पादन ERC-20 कॉन्ट्रॅक्टला निरुपयोगी बनवेल, परंतु जेव्हा एखादे ERC-20 केवळ चाचणी सुलभ करण्यासाठी अस्तित्वात असते तेव्हा ते जीवन सोपे करते. + +```solidity + /** + * @dev कॉलरला खेळण्यासाठी 1000 टोकन देते + */ + function faucet() external { + _mint(msg.sender, 1000); + } // फंक्शन फॉसेट +``` + +### CalldataInterpreter.sol {#calldatainterpreter-sol} + +[हे ते कॉन्ट्रॅक्ट आहे ज्याला व्यवहारांनी लहान कॅलडेटासह कॉल करणे अपेक्षित आहे](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/contracts/CalldataInterpreter.sol). +चला ओळीनुसार पाहूया. + +```solidity +//SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.0; + + +import { OrisUselessToken } from "./Token.sol"; +``` + +त्याला कसे कॉल करायचे हे जाणून घेण्यासाठी आम्हाला टोकन फंक्शनची आवश्यकता आहे. + +```solidity +contract CalldataInterpreter { + + OrisUselessToken public immutable token; +``` + +ज्या टोकनसाठी आम्ही प्रॉक्सी आहोत त्याचा पत्ता. + +```solidity + + /** + * @dev टोकनचा पत्ता निर्दिष्ट करा + * @param tokenAddr_ ERC-20 कॉन्ट्रॅक्टचा पत्ता + */ + constructor( + address tokenAddr_ + ) { + token = OrisUselessToken(tokenAddr_); + } // कन्स्ट्रक्टर +``` + +आम्हाला निर्दिष्ट करण्याची आवश्यकता असलेला टोकन पत्ता हा एकमेव पॅरामीटर आहे. + +```solidity + function calldataVal(uint startByte, uint length) + private pure returns (uint) { +``` + +कॅलडेटा मधून मूल्य वाचा. + +```solidity + uint _retVal; + + require(length < 0x21, + "calldataVal लांबीची मर्यादा 32 बाइट्स आहे"); + + require(length + startByte <= msg.data.length, + "calldataVal calldatasize च्या पलीकडे वाचण्याचा प्रयत्न करत आहे"); +``` + +आपण मेमरीमध्ये एकच 32-बाइट (256-बिट) शब्द लोड करणार आहोत आणि जे बाइट्स आपल्याला हव्या असलेल्या फील्डचा भाग नाहीत ते काढून टाकणार आहोत. +हे अल्गोरिदम 32 बाइटपेक्षा जास्त लांबीच्या मूल्यांसाठी कार्य करत नाही, आणि अर्थातच आपण कॅलडेटाच्या शेवटाच्या पुढे वाचू शकत नाही. +L1 वर गॅस वाचवण्यासाठी या चाचण्या वगळणे आवश्यक असू शकते, परंतु L2 वर गॅस अत्यंत स्वस्त आहे, ज्यामुळे आपण विचार करू शकणाऱ्या कोणत्याही सॅनिटी तपासण्या शक्य होतात. + +```solidity + assembly { + _retVal := calldataload(startByte) + } +``` + +आपण `fallback()` (खाली पहा) च्या कॉलमधून डेटा कॉपी करू शकलो असतो, परंतु EVM ची असेंब्ली भाषा [Yul](https://docs.soliditylang.org/en/v0.8.12/yul.html) वापरणे सोपे आहे. + +येथे आपण स्टॅकमध्ये `startByte` ते `startByte+31` बाइट्स वाचण्यासाठी [CALLDATALOAD ऑपकोड](https://www.evm.codes/#35) वापरतो. +सर्वसाधारणपणे, Yul मधील ऑपकोडचे सिंटॅक्स `(,...)` असे आहे. + +```solidity + + _retVal = _retVal >> (256-length*8); +``` + +केवळ सर्वात लक्षणीय `length` बाइट्स फील्डचा भाग आहेत, म्हणून आपण इतर मूल्ये काढून टाकण्यासाठी [राइट-शिफ्ट](https://en.wikipedia.org/wiki/Logical_shift) करतो. +याचा अतिरिक्त फायदा असा आहे की ते मूल्य फील्डच्या उजवीकडे हलवते, त्यामुळे ते मूल्य स्वतःच आहे, 256something पट मूल्य नाही. + +```solidity + + return _retVal; + } + + + fallback() external { +``` + +जेव्हा Solidity कॉन्ट्रॅक्टला केलेला कॉल कोणत्याही फंक्शन सिग्नेचरशी जुळत नाही, तेव्हा ते (एक आहे असे गृहीत धरून) [`fallback()` फंक्शन](https://docs.soliditylang.org/en/v0.8.12/contracts.html#fallback-function) कॉल करते. +`CalldataInterpreter` च्या बाबतीत, _कोणताही_ कॉल येथे येतो कारण इतर कोणतेही `external` किंवा `public` फंक्शन्स नाहीत. + +```solidity + uint _func; + + _func = calldataVal(0, 1); +``` + +कॅलडेटाचा पहिला बाइट वाचा, जो आपल्याला फंक्शन सांगतो. +येथे एखादे फंक्शन उपलब्ध नसण्याची दोन कारणे आहेत: + +1. `pure` किंवा `view` असणारी फंक्शन्स स्थिती बदलत नाहीत आणि त्यांना गॅस लागत नाही (जेव्हा ऑफचेन कॉल केले जाते). + त्यांचा गॅस खर्च कमी करण्याचा प्रयत्न करण्यात काही अर्थ नाही. +2. [`msg.sender`](https://docs.soliditylang.org/en/v0.8.12/units-and-global-variables.html#block-and-transaction-properties) वर अवलंबून असलेली फंक्शन्स. + `msg.sender` चे मूल्य `CalldataInterpreter` चा पत्ता असेल, कॉलरचा नाही. + +दुर्दैवाने, [ERC-20 स्पेसिफिकेशन्स पाहिल्यास](https://eips.ethereum.org/EIPS/eip-20), फक्त एकच फंक्शन उरते, `transfer`. +यामुळे आपल्याकडे फक्त दोन फंक्शन्स उरतात: `transfer` (कारण आपण `transferFrom` कॉल करू शकतो) आणि `faucet` (कारण आपण ज्याने आपल्याला कॉल केला आहे त्याला टोकन परत हस्तांतरित करू शकतो). + +```solidity + + // कॅलडेटामधील माहिती वापरून टोकनच्या स्थिती बदलणाऱ्या पद्धतींना कॉल करा + // + + // फॉसेट + if (_func == 1) { +``` + +`faucet()` ला कॉल, ज्यामध्ये पॅरामीटर्स नाहीत. + +```solidity + token.faucet(); + token.transfer(msg.sender, + token.balanceOf(address(this))); + } +``` + +आपण `token.faucet()` कॉल केल्यावर आपल्याला टोकन्स मिळतात. तथापि, प्रॉक्सी कॉन्ट्रॅक्ट म्हणून, आम्हाला टोकनची **गरज** नाही. +आपल्याला कॉल करणार्‍या EOA (बाह्य मालकीच्या खात्याला) किंवा कॉन्ट्रॅक्टला गरज आहे. +म्हणून आम्ही आमचे सर्व टोकन ज्याने आम्हाला कॉल केला आहे त्याला हस्तांतरित करतो. + +```solidity + // हस्तांतरण (आपल्याकडे त्यासाठी भत्ता आहे असे गृहीत धरा) + if (_func == 2) { +``` + +टोकन हस्तांतरित करण्यासाठी दोन पॅरामीटर्स आवश्यक आहेत: गंतव्य पत्ता आणि रक्कम. + +```solidity + token.transferFrom( + msg.sender, +``` + +आम्ही फक्त कॉल करणाऱ्यांना त्यांच्या मालकीचे टोकन हस्तांतरित करण्याची परवानगी देतो + +```solidity + address(uint160(calldataVal(1, 20))), +``` + +गंतव्य पत्ता बाइट #1 पासून सुरू होतो (बाइट #0 हे फंक्शन आहे). +एक पत्ता म्हणून, तो 20-बाइट लांब आहे. + +```solidity + calldataVal(21, 2) +``` + +या विशिष्ट कॉन्ट्रॅक्टसाठी आपण असे गृहीत धरतो की कोणीही हस्तांतरित करू इच्छित असलेल्या टोकनची कमाल संख्या दोन बाइटमध्ये (65536 पेक्षा कमी) बसते. + +```solidity + ); + } +``` + +एकंदरीत, हस्तांतरणासाठी 35 बाइट्सचा कॅलडेटा लागतो: + +| विभाग | लांबी | बाइट्स | +| --------------- | ----: | -----: | +| फंक्शन सिलेक्टर | 1 | 0 | +| गंतव्य पत्ता | 32 | 1-32 | +| रक्कम | 2 | 33-34 | + +```solidity + } // फॉलबॅक + +} // कॉन्ट्रॅक्ट CalldataInterpreter +``` + +### test.js {#test-js} + +[हे JavaScript युनिट टेस्ट](https://github.com/qbzzt/ethereum.org-20220330-shortABI/blob/master/test/test.js) आपल्याला हे तंत्र कसे वापरावे (आणि ते योग्यरित्या कार्य करते की नाही हे कसे सत्यापित करावे) हे दाखवते. +मी असे गृहीत धरणार आहे की तुम्हाला [chai](https://www.chaijs.com/) आणि [ethers](https://docs.ethers.io/v5/) समजतात आणि केवळ कॉन्ट्रॅक्टवर विशेषतः लागू होणारे भाग स्पष्ट करणार आहे. + +```js +const { expect } = require("chai"); + +describe("CalldataInterpreter", function () { + it("Should let us use tokens", async function () { + const Token = await ethers.getContractFactory("OrisUselessToken") + const token = await Token.deploy() + await token.deployed() + console.log("Token addr:", token.address) + + const Cdi = await ethers.getContractFactory("CalldataInterpreter") + const cdi = await Cdi.deploy(token.address) + await cdi.deployed() + console.log("CalldataInterpreter addr:", cdi.address) + + const signer = await ethers.getSigner() +``` + +आपण दोन्ही कॉन्ट्रॅक्ट्स तैनात करून सुरुवात करतो. + +```javascript + // खेळण्यासाठी टोकन मिळवा + const faucetTx = { +``` + +आम्ही व्यवहार तयार करण्यासाठी सामान्यतः वापरत असलेली उच्च-स्तरीय फंक्शन्स (जसे की `token.faucet()`) वापरू शकत नाही, कारण आम्ही ABI चे पालन करत नाही. +त्याऐवजी, आपल्याला स्वतः व्यवहार तयार करून तो पाठवावा लागेल. + +```javascript + to: cdi.address, + data: "0x01" +``` + +व्यवहारासाठी आपल्याला दोन पॅरामीटर्स द्यावे लागतील: + +1. `to`, गंतव्य पत्ता. + हा कॅलडेटा इंटरप्रिटर कॉन्ट्रॅक्ट आहे. +2. `data`, पाठवण्यासाठी कॅलडेटा. + फॉसेट कॉलच्या बाबतीत, डेटा एकच बाइट आहे, `0x01`. + +```javascript + + } + await (await signer.sendTransaction(faucetTx)).wait() +``` + +आम्ही [साईनरच्या `sendTransaction` पद्धतीला](https://docs.ethers.io/v5/api/signer/#Signer-sendTransaction) कॉल करतो कारण आम्ही आधीच गंतव्य (`faucetTx.to`) निर्दिष्ट केले आहे आणि आम्हाला व्यवहार स्वाक्षरी केलेला हवा आहे. + +```javascript +// फॉसेट टोकन योग्यरित्या पुरवतो का ते तपासा +expect(await token.balanceOf(signer.address)).to.equal(1000) +``` + +येथे आपण शिल्लक तपासतो. +`view` फंक्शन्सवर गॅस वाचवण्याची गरज नाही, म्हणून आपण त्यांना सामान्यपणे चालवतो. + +```javascript +// CDI ला भत्ता द्या (मंजुरी प्रॉक्सी केली जाऊ शकत नाही) +const approveTX = await token.approve(cdi.address, 10000) +await approveTX.wait() +expect(await token.allowance(signer.address, cdi.address)).to.equal(10000) +``` + +हस्तांतरण करण्यासाठी कॅलडेटा इंटरप्रिटरला भत्ता द्या. + +```javascript +// टोकन हस्तांतरित करा +const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d" +const transferTx = { + to: cdi.address, + data: "0x02" + destAddr.slice(2, 42) + "0100", +} +``` + +एक हस्तांतरण व्यवहार तयार करा. पहिला बाइट "0x02" आहे, त्यानंतर गंतव्य पत्ता आणि शेवटी रक्कम (0x0100, जे दशांश मध्ये 256 आहे). + +```javascript + await (await signer.sendTransaction(transferTx)).wait() + + // तपासा की आपल्याकडे 256 टोकन कमी आहेत + expect (await token.balanceOf(signer.address)).to.equal(1000-256) + + // आणि ते आपल्या गंतव्यस्थानाला मिळाले आहेत + expect (await token.balanceOf(destAddr)).to.equal(256) + }) // ते +}) // वर्णन करा +``` + +## जेव्हा तुम्ही गंतव्य कॉन्ट्रॅक्टवर नियंत्रण ठेवता तेव्हा खर्च कमी करणे {#reducing-the-cost-when-you-do-control-the-destination-contract} + +जर तुमचे गंतव्य कॉन्ट्रॅक्टवर नियंत्रण असेल तर तुम्ही अशी फंक्शन्स तयार करू शकता जी `msg.sender` तपासण्यांना बायपास करतात कारण ते कॅलडेटा इंटरप्रिटरवर विश्वास ठेवतात. +[हे कसे कार्य करते याचे उदाहरण तुम्ही येथे पाहू शकता, `control-contract` शाखेत](https://github.com/qbzzt/ethereum.org-20220330-shortABI/tree/control-contract). + +जर कॉन्ट्रॅक्ट केवळ बाह्य व्यवहारांना प्रतिसाद देत असेल, तर आपण फक्त एका कॉन्ट्रॅक्टने काम चालवू शकलो असतो. +तथापि, ते [कंपोझिबिलिटी](/developers/docs/smart-contracts/composability/) खंडित करेल. +सामान्य ERC-20 कॉल्सला प्रतिसाद देणारा एक कॉन्ट्रॅक्ट आणि लहान कॉल डेटासह व्यवहारांना प्रतिसाद देणारा दुसरा कॉन्ट्रॅक्ट असणे खूप चांगले आहे. + +### Token.sol {#token-sol-2} + +या उदाहरणात आपण `Token.sol` मध्ये बदल करू शकतो. +हे आपल्याला अनेक फंक्शन्स ठेवण्याची परवानगी देते जे फक्त प्रॉक्सी कॉल करू शकते. +हे नवीन भाग आहेत: + +```solidity + // CalldataInterpreter पत्ता निर्दिष्ट करण्याची परवानगी असलेला एकमेव पत्ता + address owner; + + // CalldataInterpreter पत्ता + address proxy = address(0); +``` + +ERC-20 कॉन्ट्रॅक्टला अधिकृत प्रॉक्सीची ओळख माहित असणे आवश्यक आहे. +तथापि, आपण हे व्हेरिएबल कन्स्ट्रक्टरमध्ये सेट करू शकत नाही, कारण आपल्याला अद्याप मूल्य माहित नाही. +हा कॉन्ट्रॅक्ट प्रथम इन्स्टंटिएट केला जातो कारण प्रॉक्सीला त्याच्या कन्स्ट्रक्टरमध्ये टोकनच्या पत्त्याची अपेक्षा असते. + +```solidity + /** + * @dev ERC20 कन्स्ट्रक्टरला कॉल करते. + */ + constructor( + ) ERC20("Oris useless token-2", "OUT-2") { + owner = msg.sender; + } +``` + +निर्मात्याचा पत्ता (ज्याला `owner` म्हणतात) येथे संग्रहित केला जातो कारण प्रॉक्सी सेट करण्याची परवानगी असलेला तो एकमेव पत्ता आहे. + +```solidity + /** + * @dev प्रॉक्सीसाठी (CalldataInterpreter) पत्ता सेट करा. + * मालकाद्वारे फक्त एकदाच कॉल केले जाऊ शकते + */ + function setProxy(address _proxy) external { + require(msg.sender == owner, "फक्त मालकाद्वारे कॉल केले जाऊ शकते"); + require(proxy == address(0), "प्रॉक्सी आधीच सेट आहे"); + + proxy = _proxy; + } // फंक्शन setProxy +``` + +प्रॉक्सीला विशेषाधिकारित प्रवेश आहे, कारण ते सुरक्षा तपासण्या बायपास करू शकते. +आपण प्रॉक्सीवर विश्वास ठेवू शकतो याची खात्री करण्यासाठी, आम्ही फक्त `owner` ला हे फंक्शन कॉल करू देतो, आणि फक्त एकदाच. +एकदा `proxy` चे वास्तविक मूल्य (शून्य नाही) आले की, ते मूल्य बदलू शकत नाही, त्यामुळे मालकाने बदमाश होण्याचा निर्णय घेतला तरी, किंवा त्यासाठीचा मेमोनिक उघड झाला तरी, आपण तरीही सुरक्षित आहोत. + +```solidity + /** + * @dev काही फंक्शन्स फक्त प्रॉक्सीद्वारे कॉल केली जाऊ शकतात. + */ + modifier onlyProxy { +``` + +हे एक [`modifier` फंक्शन](https://www.tutorialspoint.com/solidity/solidity_function_modifiers.htm) आहे, ते इतर फंक्शन्सच्या कार्यपद्धतीत बदल करते. + +```solidity + require(msg.sender == proxy); +``` + +प्रथम, सत्यापित करा की आपल्याला प्रॉक्सीने आणि इतर कोणीही कॉल केलेला नाही. +नसल्यास, `revert` करा. + +```solidity + _; + } +``` + +तसे असल्यास, आपण सुधारित करत असलेले फंक्शन चालवा. + +```solidity + /* फंक्शन्स जे प्रॉक्सीला खात्यांसाठी प्रत्यक्षात प्रॉक्सी करण्याची परवानगी देतात */ + + function transferProxy(address from, address to, uint256 amount) + public virtual onlyProxy() returns (bool) + { + _transfer(from, to, amount); + return true; + } + + function approveProxy(address from, address spender, uint256 amount) + public virtual onlyProxy() returns (bool) + { + _approve(from, spender, amount); + return true; + } + + function transferFromProxy( + address spender, + address from, + address to, + uint256 amount + ) public virtual onlyProxy() returns (bool) + { + _spendAllowance(from, spender, amount); + _transfer(from, to, amount); + return true; + } +``` + +या तीन क्रिया आहेत ज्यांना सामान्यतः टोकन हस्तांतरित करणाऱ्या किंवा भत्ता मंजूर करणाऱ्या घटकाकडून थेट संदेश येण्याची आवश्यकता असते. +येथे आमच्याकडे या ऑपरेशन्सची प्रॉक्सी आवृत्ती आहे जी: + +1. `onlyProxy()` द्वारे सुधारित केले आहे जेणेकरून इतर कोणालाही त्यांना नियंत्रित करण्याची परवानगी नाही. +2. जो पत्ता सामान्यतः `msg.sender` असतो तो अतिरिक्त पॅरामीटर म्हणून मिळवतो. + +### CalldataInterpreter.sol {#calldatainterpreter-sol-2} + +कॅलडेटा इंटरप्रिटर वरील इंटरप्रिटरसारखाच आहे, फक्त प्रॉक्सी केलेल्या फंक्शन्सना `msg.sender` पॅरामीटर मिळतो आणि `transfer` साठी भत्त्याची गरज नसते. + +```solidity + // हस्तांतरण (भत्त्याची गरज नाही) + if (_func == 2) { + token.transferProxy( + msg.sender, + address(uint160(calldataVal(1, 20))), + calldataVal(21, 2) + ); + } + + // मंजूर करा + if (_func == 3) { + token.approveProxy( + msg.sender, + address(uint160(calldataVal(1, 20))), + calldataVal(21, 2) + ); + } + + // transferFrom + if (_func == 4) { + token.transferFromProxy( + msg.sender, + address(uint160(calldataVal( 1, 20))), + address(uint160(calldataVal(21, 20))), + calldataVal(41, 2) + ); + } +``` + +### Test.js {#test-js-2} + +मागील टेस्टिंग कोड आणि या कोडमध्ये काही बदल आहेत. + +```js +const Cdi = await ethers.getContractFactory("CalldataInterpreter") +const cdi = await Cdi.deploy(token.address) +await cdi.deployed() +await token.setProxy(cdi.address) +``` + +आम्हाला ERC-20 कॉन्ट्रॅक्टला कोणत्या प्रॉक्सीवर विश्वास ठेवावा हे सांगावे लागेल + +```js +console.log("CalldataInterpreter addr:", cdi.address) + +// भत्ते तपासण्यासाठी दोन स्वाक्षरीकर्त्यांची आवश्यकता आहे +const signers = await ethers.getSigners() +const signer = signers[0] +const poorSigner = signers[1] +``` + +`approve()` आणि `transferFrom()` तपासण्यासाठी आम्हाला दुसऱ्या स्वाक्षरीकर्त्याची आवश्यकता आहे. +आम्ही त्याला `poorSigner` म्हणतो कारण त्याला आमचे कोणतेही टोकन मिळत नाहीत (अर्थात, त्याच्याकडे ETH असणे आवश्यक आहे). + +```js +// टोकन हस्तांतरित करा +const destAddr = "0xf5a6ead936fb47f342bb63e676479bddf26ebe1d" +const transferTx = { + to: cdi.address, + data: "0x02" + destAddr.slice(2, 42) + "0100", +} +await (await signer.sendTransaction(transferTx)).wait() +``` + +कारण ERC-20 कॉन्ट्रॅक्ट प्रॉक्सी (`cdi`) वर विश्वास ठेवतो, आम्हाला हस्तांतरण रिले करण्यासाठी भत्त्याची गरज नाही. + +```js +// मंजूरी आणि transferFrom +const approveTx = { + to: cdi.address, + data: "0x03" + poorSigner.address.slice(2, 42) + "00FF", +} +await (await signer.sendTransaction(approveTx)).wait() + +const destAddr2 = "0xE1165C689C0c3e9642cA7606F5287e708d846206" + +const transferFromTx = { + to: cdi.address, + data: "0x04" + signer.address.slice(2, 42) + destAddr2.slice(2, 42) + "00FF", +} +await (await poorSigner.sendTransaction(transferFromTx)).wait() + +// approve / transferFrom कॉम्बो योग्यरित्या केले होते की नाही हे तपासा +expect(await token.balanceOf(destAddr2)).to.equal(255) +``` + +दोन नवीन फंक्शन्सची चाचणी घ्या. +लक्षात घ्या की `transferFromTx` ला दोन पत्ता पॅरामीटर्स आवश्यक आहेत: भत्त्याचा दाता आणि स्वीकारकर्ता. + +## निष्कर्ष {#conclusion} + +दोन्ही [Optimism](https://medium.com/ethereum-optimism/the-road-to-sub-dollar-transactions-part-2-compression-edition-6bb2890e3e92) आणि [Arbitrum](https://developer.offchainlabs.com/docs/special_features) L1 वर लिहिलेल्या कॅलडेटाचा आकार आणि त्यामुळे व्यवहारांची किंमत कमी करण्याचे मार्ग शोधत आहेत. +तथापि, सामान्य उपायांचा शोध घेणारे पायाभूत सुविधा प्रदाते म्हणून, आमच्या क्षमता मर्यादित आहेत. +dapp डेव्हलपर म्हणून, आपल्याकडे अनुप्रयोगा-विशिष्ट ज्ञान आहे, जे आपल्याला सामान्य समाधानापेक्षा आपले कॅलडेटा अधिक चांगल्या प्रकारे ऑप्टिमाइझ करू देते. +आशा आहे की, हा लेख आपल्याला आपल्या गरजांसाठी आदर्श समाधान शोधण्यात मदत करेल. + +[माझ्या कामाबद्दल अधिक माहितीसाठी येथे पहा](https://cryptodocguy.pro/). + diff --git a/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md b/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md new file mode 100644 index 00000000000..4a0a076996e --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md @@ -0,0 +1,91 @@ +--- +title: "स्मार्ट कॉन्ट्रॅक्ट सुरक्षा मार्गदर्शक तत्त्वे" +description: "तुमचे डॅप तयार करताना विचारात घेण्यासाठी सुरक्षा मार्गदर्शक तत्त्वांची तपासणी सूची" +author: "Trailofbits" +tags: [ "सॉलिडिटी", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा" ] +skill: intermediate +lang: mr +published: 2020-09-06 +source: Building secure contracts +sourceUrl: https://github.com/crytic/building-secure-contracts/blob/master/development-guidelines/guidelines.md +--- + +अधिक सुरक्षित स्मार्ट कॉन्ट्रॅक्ट तयार करण्यासाठी या उच्च-स्तरीय शिफारशींचे अनुसरण करा. + +## डिझाइन मार्गदर्शक तत्त्वे {#design-guidelines} + +कोडची कोणतीही ओळ लिहिण्यापूर्वी कॉन्ट्रॅक्टच्या डिझाइनवर वेळेपूर्वी चर्चा केली पाहिजे. + +### दस्तऐवजीकरण आणि विशिष्टता {#documentation-and-specifications} + +दस्तऐवजीकरण वेगवेगळ्या स्तरांवर लिहिले जाऊ शकते आणि कॉन्ट्रॅक्ट्सची अंमलबजावणी करताना ते अपडेट केले पाहिजे: + +- **सिस्टमचे सोपे इंग्रजी वर्णन**, जे कॉन्ट्रॅक्ट्स काय करतात आणि कोडबेसवरील कोणतीही गृहितके यांचे वर्णन करते. +- **स्कीमा आणि आर्किटेक्चरल डायग्राम**, ज्यात कॉन्ट्रॅक्टमधील परस्परसंवाद आणि सिस्टमचे स्टेट मशीन समाविष्ट आहे. [स्लिदर प्रिंटर्स](https://github.com/crytic/slither/wiki/Printer-documentation) हे स्कीमा तयार करण्यासाठी मदत करू शकतात. +- **संपूर्ण कोड दस्तऐवजीकरण**, सॉलिडिटीसाठी [Natspec फॉरमॅट](https://docs.soliditylang.org/en/develop/natspec-format.html) वापरला जाऊ शकतो. + +### ऑनचेन विरुद्ध ऑफचेन गणना {#onchain-vs-offchain-computation} + +- **तुम्ही शक्य तितका कोड ऑफचेन ठेवा.** ऑनचेन लेयर लहान ठेवा. ऑफचेन कोडसह डेटावर अशा प्रकारे पूर्व-प्रक्रिया करा की ऑनचेन पडताळणी सोपी होईल. तुम्हाला क्रमबद्ध यादीची आवश्यकता आहे का? यादी ऑफचेन लावा, मग फक्त तिचा क्रम ऑनचेन तपासा. + +### अपग्रेडेबिलिटी {#upgradeability} + +आम्ही [आमच्या ब्लॉगपोस्टमध्ये](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/) वेगवेगळ्या अपग्रेडेबिलिटी सोल्यूशन्सवर चर्चा केली आहे. कोणताही कोड लिहिण्यापूर्वी अपग्रेडेबिलिटीला सपोर्ट करायचा की नाही, याची हेतुपुरस्सर निवड करा. तुम्ही तुमचा कोड कसा संरचित करता यावर हा निर्णय प्रभाव टाकेल. सर्वसाधारणपणे, आम्ही शिफारस करतो: + +- **अपग्रेडेबिलिटीपेक्षा [कॉन्ट्रॅक्ट मायग्रेशनला](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) प्राधान्य द्या.** मायग्रेशन सिस्टम्समध्ये अपग्रेड करण्यायोग्य सिस्टमसारखेच अनेक फायदे आहेत, पण त्यांचे तोटे नाहीत. +- **डेलिगेट कॉल प्रॉक्सी पॅटर्नपेक्षा डेटा सेपरेशन पॅटर्न वापरा.** जर तुमच्या प्रोजेक्टमध्ये स्पष्ट ॲब्स्ट्रॅक्शन सेपरेशन असेल, तर डेटा सेपरेशन वापरून अपग्रेडेबिलिटीसाठी फक्त काही समायोजन आवश्यक असतील. डेलिगेट कॉल प्रॉक्सीसाठी EVM तज्ञतेची आवश्यकता असते आणि ते खूप त्रुटी-प्रवण आहे. +- **डिप्लॉयमेंट करण्यापूर्वी मायग्रेशन/अपग्रेड प्रक्रिया डॉक्युमेंट करा.** जर तुम्हाला कोणत्याही मार्गदर्शक तत्त्वांशिवाय तणावाखाली प्रतिक्रिया द्यावी लागली, तर तुम्ही चुका कराल. अनुसरण्याची प्रक्रिया वेळेपूर्वीच लिहा. त्यात समाविष्ट असावे: + - नवीन कॉन्ट्रॅक्ट्स सुरू करणारे कॉल्स + - कीज कुठे साठवल्या आहेत आणि त्या कशा ऍक्सेस करायच्या + - डिप्लॉयमेंट कशी तपासावी! डिप्लॉयमेंट-नंतरची स्क्रिप्ट विकसित करा आणि तपासा. + +## अंमलबजावणीची मार्गदर्शक तत्त्वे {#implementation-guidelines} + +**साधेपणासाठी प्रयत्न करा.** नेहमी सर्वात सोपा उपाय वापरा जो तुमच्या उद्देशाला अनुकूल असेल. तुमच्या टीममधील कोणत्याही सदस्याला तुमचा उपाय समजू शकला पाहिजे. + +### फंक्शन कंपोझिशन {#function-composition} + +तुमच्या कोडबेसचे आर्किटेक्चर असे असावे की ज्यामुळे तुमचा कोड तपासणे सोपे होईल. असे आर्किटेक्चरल पर्याय टाळा जे त्याच्या अचूकतेबद्दल तर्क करण्याची क्षमता कमी करतात. + +- **तुमच्या सिस्टमच्या लॉजिकचे विभाजन करा**, एकतर अनेक कॉन्ट्रॅक्ट्सद्वारे किंवा समान फंक्शन्स एकत्र गटबद्ध करून (उदाहरणार्थ, ऑथेंटिकेशन, अंकगणित, ...). +- **स्पष्ट उद्देशाने लहान फंक्शन्स लिहा.** यामुळे पुनरावलोकन सोपे होईल आणि वैयक्तिक घटकांची चाचणी घेता येईल. + +### इनहेरिटन्स {#inheritance} + +- **इनहेरिटन्स व्यवस्थापनीय ठेवा.** लॉजिकचे विभाजन करण्यासाठी इनहेरिटन्सचा वापर केला पाहिजे, तथापि, तुमच्या प्रोजेक्टने इनहेरिटन्स ट्रीची खोली आणि रुंदी कमी करण्याचे ध्येय ठेवले पाहिजे. +- **कॉन्ट्रॅक्ट्सची हायरार्की तपासण्यासाठी स्लिदरचा [इनहेरिटन्स प्रिंटर](https://github.com/crytic/slither/wiki/Printer-documentation#inheritance-graph) वापरा.** इनहेरिटन्स प्रिंटर तुम्हाला हायरार्कीचा आकार तपासण्यात मदत करेल. + +### इव्हेंट्स {#events} + +- **सर्व महत्त्वाच्या ऑपरेशन्स लॉग करा.** इव्हेंट्स डेव्हलपमेंट दरम्यान कॉन्ट्रॅक्ट डीबग करण्यास आणि डिप्लॉयमेंटनंतर त्यावर लक्ष ठेवण्यास मदत करतील. + +### ज्ञात धोके टाळा {#avoid-known-pitfalls} + +- **सर्वात सामान्य सुरक्षा समस्यांबद्दल जागरूक रहा.** सामान्य समस्यांबद्दल जाणून घेण्यासाठी अनेक ऑनलाइन संसाधने आहेत, जसे की [Ethernaut CTF](https://ethernaut.openzeppelin.com/), [कॅप्चर द इथर](https://capturetheether.com/), किंवा [नॉट सो स्मार्ट कॉन्ट्रॅक्ट्स](https://github.com/crytic/not-so-smart-contracts/). +- **[Solidity दस्तऐवजीकरणामधील](https://docs.soliditylang.org/en/latest/) चेतावणी विभागांबद्दल जागरूक रहा.** चेतावणी विभाग तुम्हाला भाषेच्या अस्पष्ट वर्तनाबद्दल माहिती देतील. + +### डिपेंडन्सीज {#dependencies} + +- **चांगल्या प्रकारे तपासलेल्या लायब्ररी वापरा.** चांगल्या प्रकारे तपासलेल्या लायब्ररीमधून कोड इम्पोर्ट केल्याने तुम्ही सदोष कोड लिहिण्याची शक्यता कमी होईल. जर तुम्हाला ERC20 कॉन्ट्रॅक्ट लिहायचा असेल, तर [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/contracts/token/ERC20) वापरा. +- **डिपेंडन्सी मॅनेजर वापरा; कोड कॉपी-पेस्ट करणे टाळा.** जर तुम्ही बाह्य स्त्रोतावर अवलंबून असाल, तर तुम्ही ते मूळ स्त्रोतासह अद्ययावत ठेवले पाहिजे. + +### चाचणी आणि पडताळणी {#testing-and-verification} + +- **संपूर्ण युनिट-टेस्ट्स लिहा.** उच्च-गुणवत्तेचे सॉफ्टवेअर तयार करण्यासाठी एक विस्तृत टेस्ट सूट महत्त्वपूर्ण आहे. +- **[स्लिदर](https://github.com/crytic/slither), [एकिडना](https://github.com/crytic/echidna) आणि [मॅन्टिकोर](https://github.com/trailofbits/manticore) कस्टम चेक्स आणि प्रॉपर्टीज लिहा.** स्वयंचलित टूल्स तुमचा कॉन्ट्रॅक्ट सुरक्षित असल्याची खात्री करण्यास मदत करतील. कार्यक्षम चेक्स आणि प्रॉपर्टीज कसे लिहायचे हे जाणून घेण्यासाठी या मार्गदर्शकाचा उर्वरित भाग तपासा. +- **[crytic.io](https://crytic.io/) वापरा.** क्रिटिक GitHub सह समाकलित होते, खाजगी स्लिदर डिटेक्टरना ऍक्सेस प्रदान करते, आणि एकिडनामधून कस्टम प्रॉपर्टी चेक्स चालवते. + +### Solidity {#solidity} + +- **0.4 आणि 0.6 पेक्षा सॉलिडिटी 0.5 ला प्राधान्य द्या.** आमच्या मते, सॉलिडिटी 0.5 अधिक सुरक्षित आहे आणि 0.4 पेक्षा त्यात अधिक चांगल्या बिल्ट-इन पद्धती आहेत. सॉलिडिटी 0.6 उत्पादनासाठी खूपच अस्थिर सिद्ध झाले आहे आणि त्याला परिपक्व होण्यासाठी वेळ लागेल. +- **कंपाइल करण्यासाठी स्थिर रिलीझ वापरा; चेतावणी तपासण्यासाठी नवीनतम रिलीझ वापरा.** नवीनतम कंपाइलर आवृत्तीसह तुमच्या कोडमध्ये कोणतीही नोंदवलेली समस्या नाही याची खात्री करा. तथापि, सॉलिडिटीचे रिलीझ चक्र वेगवान आहे आणि त्यात कंपाइलर बग्सचा इतिहास आहे, म्हणून आम्ही डिप्लॉयमेंटसाठी नवीनतम आवृत्तीची शिफारस करत नाही (स्लिदरची [solc आवृत्ती शिफारस](https://github.com/crytic/slither/wiki/Detector-Documentation#recommendation-33) पहा). +- **इनलाइन असेंब्ली वापरू नका.** असेंब्लीसाठी EVM तज्ञतेची आवश्यकता असते. जर तुम्ही यलो पेपरवर _प्रभुत्व_ मिळवले नसेल तर EVM कोड लिहू नका. + +## डिप्लॉयमेंट मार्गदर्शक तत्त्वे {#deployment-guidelines} + +एकदा कॉन्ट्रॅक्ट विकसित आणि डिप्लॉय झाल्यानंतर: + +- **तुमच्या कॉन्ट्रॅक्ट्सवर लक्ष ठेवा.** लॉग्स पहा आणि कॉन्ट्रॅक्ट किंवा वॉलेटशी तडजोड झाल्यास प्रतिक्रिया देण्यासाठी तयार रहा. +- **तुमची संपर्क माहिती [ब्लॉकचेन-सुरक्षा-संपर्क](https://github.com/crytic/blockchain-security-contacts) मध्ये जोडा.** जर एखादी सुरक्षा त्रुटी आढळल्यास ही यादी तृतीय-पक्षांना तुमच्याशी संपर्क साधण्यास मदत करते. +- **विशेषाधिकार असलेल्या वापरकर्त्यांचे वॉलेट्स सुरक्षित करा.** जर तुम्ही हार्डवेअर वॉलेट्समध्ये कीज साठवत असाल तर आमच्या [सर्वोत्तम पद्धतींचे](https://blog.trailofbits.com/2018/11/27/10-rules-for-the-secure-use-of-cryptocurrency-hardware-wallets/) अनुसरण करा. +- **घटनेला प्रतिसाद देण्यासाठी एक योजना तयार ठेवा.** तुमचे स्मार्ट कॉन्ट्रॅक्ट्स धोक्यात येऊ शकतात याचा विचार करा. जरी तुमचे कॉन्ट्रॅक्ट्स बग-मुक्त असले तरी, एक हल्लेखोर कॉन्ट्रॅक्ट मालकाच्या कीजचा ताबा घेऊ शकतो. diff --git a/public/content/translations/mr/developers/tutorials/stealth-addr/index.md b/public/content/translations/mr/developers/tutorials/stealth-addr/index.md new file mode 100644 index 00000000000..1c3b5e5ff16 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/stealth-addr/index.md @@ -0,0 +1,436 @@ +--- +title: "गुप्त पत्त्यांचा वापर" +description: "गुप्त पत्ते वापरकर्त्यांना अज्ञातपणे मालमत्ता हस्तांतरित करण्याची परवानगी देतात. हा लेख वाचल्यानंतर, तुम्ही हे करू शकाल: गुप्त पत्ते काय आहेत आणि ते कसे कार्य करतात हे स्पष्ट करू शकाल, अनामिकता जपणाऱ्या पद्धतीने गुप्त पत्त्यांचा वापर कसा करायचा हे समजू शकाल, आणि गुप्त पत्त्यांचा वापर करणारे वेब-आधारित ॲप्लिकेशन लिहू शकाल." +author: Ori Pomerantz +tags: [ "गुप्त पत्ता", "गोपनीयता", "कूटलेखन", "rust", "wasm" ] +skill: intermediate +published: 2025-11-30 +lang: mr +sidebarDepth: 3 +--- + +तुम्ही बिल आहात. ज्या कारणांमध्ये आपण जाणार नाही, त्या कारणास्तव, तुम्हाला "Alice for Queen of the World" मोहिमेसाठी देणगी द्यायची आहे आणि तुम्ही देणगी दिली आहे हे ॲलिसला कळावे असे तुम्हाला वाटते, जेणेकरून ती जिंकल्यास तुम्हाला बक्षीस देईल. दुर्दैवाने, तिचा विजय निश्चित नाही. एक प्रतिस्पर्धी मोहीम आहे, "Carol for Empress of the Solar System". जर कॅरोल जिंकली आणि तिला कळले की तुम्ही ॲलिसला देणगी दिली आहे, तर तुम्ही अडचणीत याल. म्हणून तुम्ही तुमच्या खात्यातून ॲलिसच्या खात्यात फक्त 200 ETH हस्तांतरित करू शकत नाही. + +[ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) मध्ये याचे समाधान आहे. हे ERC अज्ञात हस्तांतरणासाठी [गुप्त पत्त्यांचा](https://nerolation.github.io/stealth-utils) वापर कसा करायचा हे स्पष्ट करते. + +**चेतावणी**: गुप्त पत्त्यांमागील कूटलेखन, आमच्या माहितीनुसार, सुरक्षित आहे. तथापि, संभाव्य साइड-चॅनल हल्ले होऊ शकतात. [खाली](#go-wrong), हा धोका कमी करण्यासाठी तुम्ही काय करू शकता ते तुम्हाला दिसेल. + +## गुप्त पत्ते कसे कार्य करतात {#how} + +हा लेख गुप्त पत्ते दोन प्रकारे स्पष्ट करण्याचा प्रयत्न करेल. पहिले म्हणजे [त्यांचा वापर कसा करायचा](#how-use). लेखाचा उर्वरित भाग समजून घेण्यासाठी हा भाग पुरेसा आहे. त्यानंतर, [त्यामागील गणिताचे स्पष्टीकरण](#how-math) आहे. जर तुम्हाला कूटलेखनात रस असेल, तर हा भाग देखील वाचा. + +### साधी आवृत्ती (गुप्त पत्त्यांचा वापर कसा करायचा) {#how-use} + +ॲलिस दोन खाजगी की तयार करते आणि संबंधित सार्वजनिक की प्रकाशित करते (ज्या एकाच दुप्पट-लांबीच्या मेटा-पत्त्यामध्ये एकत्र केल्या जाऊ शकतात). बिल देखील एक खाजगी की तयार करतो आणि संबंधित सार्वजनिक की प्रकाशित करतो. + +एका पक्षाची सार्वजनिक की आणि दुसऱ्याची खाजगी की वापरून, तुम्ही एक सामायिक गुप्त (shared secret) मिळवू शकता जे केवळ ॲलिस आणि बिल यांनाच माहीत आहे (ते केवळ सार्वजनिक कीमधून मिळवता येत नाही). हे सामायिक गुप्त वापरून, बिलला गुप्त पत्ता मिळतो आणि तो त्यावर मालमत्ता पाठवू शकतो. + +ॲलिसला सामायिक गुप्तानंतर पत्ता मिळतो, परंतु तिने प्रकाशित केलेल्या सार्वजनिक कींच्या खाजगी की तिला माहीत असल्यामुळे, तिला त्या पत्त्यावरून पैसे काढण्यासाठी खाजगी की देखील मिळू शकते. + +### गणित (गुप्त पत्ते असे का कार्य करतात) {#how-math} + +मानक गुप्त पत्ते [एलिप्टिक-कर्व्ह क्रिप्टोग्राफी (ECC)](https://blog.cloudflare.com/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography/#elliptic-curves-building-blocks-of-a-better-trapdoor) वापरतात ज्यामुळे कमी की बिट्ससह चांगली कामगिरी मिळते, आणि त्याच वेळी सुरक्षेची पातळी कायम राहते. परंतु बहुतेक वेळा आपण त्याकडे दुर्लक्ष करू शकतो आणि आपण नियमित अंकगणित वापरत आहोत असे भासवू शकतो. + +एक संख्या आहे जी प्रत्येकाला माहीत आहे, _G_. तुम्ही _G_ ने गुणू शकता. परंतु ECC च्या स्वरूपामुळे, _G_ ने भागणे व्यावहारिकदृष्ट्या अशक्य आहे. Ethereum मध्ये सार्वजनिक की कूटलेखन सामान्यतः ज्या प्रकारे कार्य करते ते म्हणजे, तुम्ही व्यवहार स्वाक्षरी करण्यासाठी एक खाजगी की, _Ppriv_ वापरू शकता, जे नंतर सार्वजनिक की, _Ppub = GPpriv_ द्वारे सत्यापित केले जातात. + +ॲलिस दोन खाजगी की तयार करते, _Kpriv_ आणि _Vpriv_. _Kpriv_ चा वापर गुप्त पत्त्यामधून पैसे खर्च करण्यासाठी केला जाईल, आणि _Vpriv_ चा वापर ॲलिसच्या मालकीचे पत्ते पाहण्यासाठी केला जाईल. त्यानंतर ॲलिस सार्वजनिक की प्रकाशित करते: _Kpub = GKpriv_ आणि _Vpub = GVpriv_ + +बिल तिसरी खाजगी की, _Rpriv_ तयार करतो, आणि _Rpub = GRpriv_ एका केंद्रीय नोंदणीमध्ये प्रकाशित करतो (बिलने ते ॲलिसला देखील पाठवले असते, परंतु आम्ही असे गृहीत धरतो की कॅरोल ऐकत आहे). + +बिल _RprivVpub = GRprivVpriv_ ची गणना करतो, जे ॲलिसला देखील माहीत असेल अशी त्याला अपेक्षा आहे (खाली स्पष्ट केले आहे). या मूल्याला _S_, म्हणजेच सामायिक गुप्त (shared secret) म्हणतात. यामुळे बिलला एक सार्वजनिक की मिळते, _Ppub = Kpub+G\*hash(S)_. या सार्वजनिक कीमधून, तो एक पत्ता मोजू शकतो आणि त्याला हवी असलेली कोणतीही संसाधने त्यावर पाठवू शकतो. भविष्यात, जर ॲलिस जिंकली, तर बिल तिला _Rpriv_ सांगून संसाधने त्याच्याकडून आली आहेत हे सिद्ध करू शकतो. + +ॲलिस _RpubVpriv = GRprivVpriv_ ची गणना करते. यामुळे तिला तेच सामायिक गुप्त, _S_ मिळते. तिला खाजगी की, _Kpriv_ माहीत असल्यामुळे, ती _Ppriv = Kpriv+hash(S)_ ची गणना करू शकते. ही की तिला _Ppub = GPpriv = GKpriv+G\*hash(S) = Kpub+G\*hash(S)_ मधून मिळणाऱ्या पत्त्यातील मालमत्तांमध्ये प्रवेश करू देते. + +आमच्याकडे एक वेगळी व्ह्यूइंग की (viewing key) आहे, जी ॲलिसला डेव्हच्या वर्ल्ड डॉमिनेशन कॅम्पेन सर्व्हिसेसला उपकंत्राट देण्यास अनुमती देते. ॲलिस डेव्हला सार्वजनिक पत्ते कळवण्यास आणि अधिक पैसे उपलब्ध झाल्यावर तिला माहिती देण्यास तयार आहे, परंतु तिने तिच्या मोहिमेचे पैसे खर्च करावेत असे तिला वाटत नाही. + +पाहणे आणि खर्च करणे यासाठी स्वतंत्र की वापरल्या जातात, त्यामुळे ॲलिस डेव्हला _Vpriv_ देऊ शकते. त्यानंतर डेव्ह _S = RpubVpriv = GRprivVpriv_ ची गणना करू शकतो आणि त्याद्वारे सार्वजनिक की (_Ppub = Kpub+G\*hash(S)_) मिळवू शकतो. परंतु _Kpriv_ शिवाय डेव्ह खाजगी की मिळवू शकत नाही. + +सारांश, ही मूल्ये विविध सहभागींना ज्ञात आहेत. + +| ॲलिस | प्रकाशित | बिल | डेव्ह | | +| ------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------- | +| G | G | G | G | | +| _Kpriv_ | - | - | - | | +| _Vpriv_ | - | - | _Vpriv_ | | +| _Kpub = GKpriv_ | _Kpub_ | _Kpub_ | _Kpub_ | | +| _Vpub = GVpriv_ | _Vpub_ | _Vpub_ | _Vpub_ | | +| - | - | _Rpriv_ | - | | +| _Rpub_ | _Rpub_ | _Rpub = GRpriv_ | _Rpub_ | | +| _S = RpubVpriv = GRprivVpriv_ | - | _S = RprivVpub = GRprivVpriv_ | _S = _RpubVpriv_ = GRprivVpriv_ | | +| _Ppub = Kpub+G\*hash(S)_ | - | _Ppub = Kpub+G\*hash(S)_ | _Ppub = Kpub+G\*hash(S)_ | | +| _पत्ता=f(Ppub)_ | - | _पत्ता=f(Ppub)_ | _पत्ता=f(Ppub)_ | _पत्ता=f(Ppub)_ | +| _Ppriv = Kpriv+hash(S)_ | - | - | - | | + +## जेव्हा गुप्त पत्ते चुकीचे ठरतात {#go-wrong} + +_ब्लॉकचेनवर कोणतीही रहस्ये नसतात_. जरी गुप्त पत्ते तुम्हाला गोपनीयता देऊ शकतात, तरीही ती गोपनीयता ट्रॅफिक विश्लेषणासाठी असुरक्षित असते. एक सोपे उदाहरण घ्यायचे झाल्यास, कल्पना करा की बिल एका पत्त्याला निधी देतो आणि लगेच _Rpub_ मूल्य प्रकाशित करण्यासाठी एक व्यवहार पाठवतो. ॲलिसच्या _Vpriv_ शिवाय, हा एक गुप्त पत्ता आहे याची खात्री आपण करू शकत नाही, परंतु तसा अंदाज लावता येतो. त्यानंतर, आम्हाला आणखी एक व्यवहार दिसतो जो त्या पत्त्यावरून सर्व ETH ॲलिसच्या मोहीम निधी पत्त्यावर हस्तांतरित करतो. आम्ही ते सिद्ध करू शकत नाही, परंतु बहुधा बिलने नुकतीच ॲलिसच्या मोहिमेला देणगी दिली आहे. कॅरोलला नक्कीच असे वाटेल. + +बिलसाठी _Rpub_ चे प्रकाशन आणि गुप्त पत्त्यासाठी निधी देणे हे वेगळे करणे सोपे आहे (हे वेगवेगळ्या वेळी, वेगवेगळ्या पत्त्यांवरून करा). तथापि, ते पुरेसे नाही. कॅरोल जो पॅटर्न शोधते तो असा आहे की बिल एका पत्त्याला निधी देतो, आणि नंतर ॲलिसचा मोहीम निधी त्यातून पैसे काढतो. + +एक उपाय म्हणजे ॲलिसच्या मोहिमेने थेट पैसे काढू नये, तर ते तिसऱ्या पक्षाला पैसे देण्यासाठी वापरावे. जर ॲलिसची मोहीम डेव्हच्या वर्ल्ड डॉमिनेशन कॅम्पेन सर्व्हिसेसला 10 ETH पाठवते, तर कॅरोलला फक्त एवढेच कळते की बिलने डेव्हच्या एका ग्राहकाला देणगी दिली आहे. जर डेव्हकडे पुरेसे ग्राहक असतील, तर कॅरोलला हे कळू शकणार नाही की बिलने तिच्याशी स्पर्धा करणाऱ्या ॲलिसला देणगी दिली की ॲडम, अल्बर्ट किंवा ॲबिगेल यांना, ज्यांची कॅरोलला पर्वा नाही. ॲलिस पेमेंटसोबत एक हॅश केलेले मूल्य समाविष्ट करू शकते, आणि नंतर डेव्हला प्रीइमेज देऊ शकते, हे सिद्ध करण्यासाठी की ती तिची देणगी होती. वैकल्पिकरित्या, वर नमूद केल्याप्रमाणे, जर ॲलिसने डेव्हला तिची _Vpriv_ दिली, तर त्याला आधीच कळते की पेमेंट कोणाकडून आले आहे. + +या उपायातील मुख्य समस्या अशी आहे की, जेव्हा ती गुप्तता बिलच्या फायद्याची असते तेव्हा ॲलिसने गुप्ततेची काळजी घेणे आवश्यक असते. ॲलिसला तिची प्रतिष्ठा टिकवून ठेवायची असेल, जेणेकरून बिलचा मित्र बॉब देखील तिला देणगी देईल. परंतु हे देखील शक्य आहे की तिला बिलला उघड करण्यास हरकत नसेल, कारण मग कॅरोल जिंकल्यास काय होईल याची त्याला भीती वाटेल. बिल कदाचित ॲलिसला आणखी जास्त पाठिंबा देऊ शकेल. + +### अनेक गुप्त स्तरांचा वापर करणे {#multi-layer} + +बिलची गोपनीयता जपण्यासाठी ॲलिसवर अवलंबून राहण्याऐवजी, बिल ते स्वतः करू शकतो. तो बॉब आणि बेला या काल्पनिक लोकांसाठी अनेक मेटा-पत्ते तयार करू शकतो. बिल नंतर बॉबला ETH पाठवतो, आणि "बॉब" (जो खरं तर बिल आहे) ते बेलाला पाठवतो. "बेला" (जो बिलच आहे) ते ॲलिसला पाठवते. + +कॅरोल तरीही ट्रॅफिक विश्लेषण करू शकते आणि बिल-ते-बॉब-ते-बेला-ते-ॲलिस पाइपलाइन पाहू शकते. तथापि, जर "बॉब" आणि "बेला" देखील इतर कारणांसाठी ETH वापरत असतील, तर असे दिसणार नाही की बिलने ॲलिसला काही हस्तांतरित केले आहे, जरी ॲलिसने गुप्त पत्त्यावरून तिच्या ज्ञात मोहीम पत्त्यावर त्वरित पैसे काढले तरीही. + +## एक गुप्त-पत्ता ॲप्लिकेशन लिहिणे {#write-app} + +हा लेख [GitHub वर उपलब्ध](https://github.com/qbzzt/251022-stealth-addresses.git) असलेल्या गुप्त-पत्ता ॲप्लिकेशनबद्दल स्पष्ट करतो. + +### साधने {#tools} + +एक [टाइपस्क्रिप्ट गुप्त पत्ता लायब्ररी](https://github.com/ScopeLift/stealth-address-sdk) आहे जी आपण वापरू शकतो. तथापि, कूटलेखन ऑपरेशन्स CPU-केंद्रित असू शकतात. मी त्यांना [Rust](https://rust-lang.org/) सारख्या संकलित भाषेत कार्यान्वित करण्यास प्राधान्य देतो, आणि ब्राउझरमध्ये कोड चालवण्यासाठी [WASM](https://webassembly.org/) वापरतो. + +आम्ही [Vite](https://vite.dev/) आणि [React](https://react.dev/) वापरणार आहोत. ही उद्योग-मानक साधने आहेत; जर तुम्हाला त्यांच्याशी परिचय नसेल, तर तुम्ही [हे ट्यूटोरियल](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) वापरू शकता. Vite वापरण्यासाठी, आम्हाला Node ची आवश्यकता आहे. + +### गुप्त पत्ते प्रत्यक्षात पहा {#in-action} + +1. आवश्यक साधने स्थापित करा: [Rust](https://rust-lang.org/tools/install/) आणि [Node](https://nodejs.org/en/download). + +2. GitHub रिपॉझिटरी क्लोन करा. + + ```sh + git clone https://github.com/qbzzt/251022-stealth-addresses.git + cd 251022-stealth-addresses + ``` + +3. पूर्वापेक्षित गोष्टी स्थापित करा आणि Rust कोड संकलित करा. + + ```sh + cd src/rust-wasm + rustup target add wasm32-unknown-unknown + cargo install wasm-pack + wasm-pack build --target web + ``` + +4. वेब सर्व्हर सुरू करा. + + ```sh + cd ../.. + npm install + npm run dev + ``` + +5. [ॲप्लिकेशन](http://localhost:5173/) वर ब्राउझ करा. या ॲप्लिकेशन पृष्ठावर दोन फ्रेम आहेत: एक ॲलिसच्या वापरकर्ता इंटरफेससाठी आणि दुसरी बिलच्या. दोन फ्रेम संवाद साधत नाहीत; त्या फक्त सोयीसाठी एकाच पृष्ठावर आहेत. + +6. ॲलिस म्हणून, **एक गुप्त मेटा-पत्ता तयार करा** वर क्लिक करा. हे नवीन गुप्त पत्ता आणि संबंधित खाजगी की प्रदर्शित करेल. गुप्त मेटा-पत्ता क्लिपबोर्डवर कॉपी करा. + +7. बिल म्हणून, नवीन गुप्त मेटा-पत्ता पेस्ट करा आणि **एक पत्ता तयार करा** वर क्लिक करा. हे तुम्हाला ॲलिससाठी निधी देण्यासाठी पत्ता देते. + +8. पत्ता आणि बिलची सार्वजनिक की कॉपी करा आणि त्यांना ॲलिसच्या वापरकर्ता इंटरफेसच्या "बिलद्वारे तयार केलेल्या पत्त्यासाठी खाजगी की" क्षेत्रात पेस्ट करा. एकदा ती क्षेत्रे भरली की, तुम्हाला त्या पत्त्यावरील मालमत्तांमध्ये प्रवेश करण्यासाठी खाजगी की दिसेल. + +9. खाजगी की पत्त्याशी जुळते याची खात्री करण्यासाठी तुम्ही [एक ऑनलाइन कॅल्क्युलेटर](https://iancoleman.net/ethereum-private-key-to-address/) वापरू शकता. + +### प्रोग्राम कसा कार्य करतो {#how-the-program-works} + +#### WASM घटक {#wasm} + +WASM मध्ये संकलित होणारा स्त्रोत कोड [Rust](https://rust-lang.org/) मध्ये लिहिलेला आहे. तुम्ही ते [`src/rust_wasm/src/lib.rs`](https://github.com/qbzzt/251022-stealth-addresses/blob/main/src/rust-wasm/src/lib.rs) मध्ये पाहू शकता. हा कोड प्रामुख्याने JavaScript कोड आणि [`eth-stealth-addresses` लायब्ररी](https://github.com/kassandraoftroy/eth-stealth-addresses) यांच्यातील इंटरफेस आहे. + +**`Cargo.toml`** + +Rust मधील [`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html) हे JavaScript मधील [`package.json`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) प्रमाणेच आहे. यात पॅकेज माहिती, अवलंबित्व घोषणा इत्यादींचा समावेश आहे. + +```toml +[package] +name = "rust-wasm" +version = "0.1.0" +edition = "2024" + +[dependencies] +eth-stealth-addresses = "0.1.0" +hex = "0.4.3" +wasm-bindgen = "0.2.104" +getrandom = { version = "0.2", features = ["js"] } +``` + +[`getrandom`](https://docs.rs/getrandom/latest/getrandom/) पॅकेजला यादृच्छिक मूल्ये तयार करण्याची आवश्यकता आहे. हे केवळ अल्गोरिदमिक माध्यमांनी केले जाऊ शकत नाही; त्याला एंट्रॉपीचा स्त्रोत म्हणून भौतिक प्रक्रियेत प्रवेश आवश्यक आहे. ही व्याख्या निर्दिष्ट करते की आम्ही ज्या ब्राउझरमध्ये चालवत आहोत त्याला विचारून आम्ही ती एंट्रॉपी मिळवू. + +```toml +console_error_panic_hook = "0.1.7" +``` + +[ही लायब्ररी](https://docs.rs/console_error_panic_hook/latest/console_error_panic_hook/) आम्हाला अधिक अर्थपूर्ण त्रुटी संदेश देते जेव्हा WASM कोड पॅनिक होतो आणि पुढे चालू शकत नाही. + +```toml +[lib] +crate-type = ["cdylib", "rlib"] +``` + +WASM कोड तयार करण्यासाठी आवश्यक असलेला आउटपुट प्रकार. + +**`lib.rs`** + +हा खरा Rust कोड आहे. + +```rust +use wasm_bindgen::prelude::*; +``` + +Rust मधून WASM पॅकेज तयार करण्याच्या व्याख्या. ते [येथे](https://wasm-bindgen.github.io/wasm-bindgen/reference/attributes/index.html) दस्तऐवजीकरण केलेले आहेत. + +```rust +use eth_stealth_addresses::{ + generate_stealth_meta_address, + generate_stealth_address, + compute_stealth_key +}; +``` + +आम्हाला [`eth-stealth-addresses` लायब्ररी](https://github.com/kassandraoftroy/eth-stealth-addresses) मधून आवश्यक असलेली फंक्शन्स. + +```rust +use hex::{decode,encode}; +``` + +Rust सामान्यतः मूल्यांसाठी बाइट [अॅरे](https://doc.rust-lang.org/std/primitive.array.html) (`[u8; ]`) वापरते. परंतु JavaScript मध्ये, आम्ही सामान्यतः हेक्साडेसिमल स्ट्रिंग वापरतो. [`hex` लायब्ररी](https://docs.rs/hex/latest/hex/) आमच्यासाठी एका प्रतिनिधित्वातून दुसऱ्यामध्ये भाषांतर करते. + +```rust +#[wasm_bindgen] +``` + +JavaScript मधून हे फंक्शन कॉल करण्यासाठी WASM बाइंडिंग तयार करा. + +```rust +pub fn wasm_generate_stealth_meta_address() -> String { +``` + +अनेक फील्ड असलेले ऑब्जेक्ट परत करण्याचा सर्वात सोपा मार्ग म्हणजे JSON स्ट्रिंग परत करणे. + +```rust + let (address, spend_private_key, view_private_key) = + generate_stealth_meta_address(); +``` + +[`generate_stealth_meta_address`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.generate_stealth_meta_address.html) तीन फील्ड परत करते: + +- मेटा-पत्ता (_Kpub_ आणि _Vpub_) +- पाहण्याची खाजगी की (_Vpriv_) +- खर्च करण्याची खाजगी की (_Kpriv_) + +[टपल](https://doc.rust-lang.org/std/primitive.tuple.html) सिंटॅक्स आम्हाला ती मूल्ये पुन्हा वेगळी करू देतो. + +```rust + format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}", + encode(address), + encode(view_private_key), + encode(spend_private_key) + ) +} +``` + +JSON-एनकोडेड स्ट्रिंग तयार करण्यासाठी [`format!`](https://doc.rust-lang.org/std/fmt/index.html) मॅक्रो वापरा. अॅरेला हेक्स स्ट्रिंगमध्ये बदलण्यासाठी [`hex::encode`](https://docs.rs/hex/latest/hex/fn.encode.html) वापरा. + +```rust +fn str_to_array(s: &str) -> Option<[u8; N]> { +``` + +हे फंक्शन हेक्स स्ट्रिंगला (JavaScript द्वारे प्रदान केलेले) बाइट अॅरेमध्ये बदलते. आम्ही JavaScript कोडद्वारे प्रदान केलेली मूल्ये पार्स करण्यासाठी याचा वापर करतो. Rust अॅरे आणि व्हेक्टर कसे हाताळते त्यामुळे हे फंक्शन क्लिष्ट आहे. + +`` अभिव्यक्तीला [जेनेरिक](https://doc.rust-lang.org/book/ch10-01-syntax.html) म्हणतात. `N` हे एक पॅरामीटर आहे जे परत केलेल्या अॅरेच्या लांबीवर नियंत्रण ठेवते. फंक्शनला प्रत्यक्षात `str_to_array::` असे म्हणतात, जिथे `n` ही अॅरेची लांबी आहे. + +परत केलेले मूल्य `Option<[u8; N]>` आहे, याचा अर्थ परत केलेला अॅरे [पर्यायी](https://doc.rust-lang.org/std/option/) आहे. Rust मध्ये अयशस्वी होऊ शकणाऱ्या फंक्शन्ससाठी हा एक सामान्य नमुना आहे. + +उदाहरणार्थ, जर आपण `str_to_array::10("bad060a7")` कॉल केले, तर फंक्शनने दहा-मूल्यांची अॅरे परत करणे अपेक्षित आहे, परंतु इनपुट फक्त चार बाइट्सचे आहे. फंक्शन अयशस्वी होणे आवश्यक आहे, आणि ते `None` परत करून तसे करते. `str_to_array::4("bad060a7")` साठी परत केलेले मूल्य `Some<[0xba, 0xd0, 0x60, 0xa7]>` असेल. + +```rust + // decode returns Result, _> + let vec = decode(s).ok()?; +``` + +[`hex::decode`](https://docs.rs/hex/latest/hex/fn.decode.html) फंक्शन `Result, FromHexError>` परत करते. [`Result`](https://doc.rust-lang.org/std/result/) प्रकारात एकतर यशस्वी परिणाम (`Ok(value)`) किंवा एक त्रुटी (`Err(error)`) असू शकते. + +`.ok()` पद्धत `Result` ला `Option` मध्ये रूपांतरित करते, ज्याचे मूल्य यशस्वी झाल्यास `Ok()` मूल्य किंवा अयशस्वी झाल्यास `None` असते. शेवटी, [प्रश्नचिन्ह ऑपरेटर](https://doc.rust-lang.org/std/option/#the-question-mark-operator-) `Option` रिक्त असल्यास वर्तमान फंक्शन रद्द करतो आणि `None` परत करतो. अन्यथा, ते मूल्य अनरॅप करते आणि ते परत करते (या प्रकरणात, `vec` ला मूल्य नियुक्त करण्यासाठी). + +त्रुटी हाताळण्याची ही एक विचित्र गुंतागुंतीची पद्धत वाटते, परंतु `Result` आणि `Option` हे सुनिश्चित करतात की सर्व त्रुटी, एका ना कोणत्या मार्गाने हाताळल्या जातात. + +```rust + if vec.len() != N { return None; } +``` + +जर बाइट्सची संख्या चुकीची असेल, तर ते अपयश आहे, आणि आम्ही `None` परत करतो. + +```rust + // try_into consumes vec and attempts to make [u8; N] + let array: [u8; N] = vec.try_into().ok()?; +``` + +Rust मध्ये दोन अॅरे प्रकार आहेत. [अॅरे](https://doc.rust-lang.org/std/primitive.array.html) चा आकार निश्चित असतो. [व्हेक्टर](https://doc.rust-lang.org/std/vec/index.html) वाढू आणि लहान होऊ शकतात. `hex::decode` एक व्हेक्टर परत करतो, परंतु `eth_stealth_addresses` लायब्ररीला अॅरे प्राप्त करायचे आहेत. [`.try_into()`](https://doc.rust-lang.org/std/convert/trait.TryInto.html#required-methods) एका मूल्याला दुसऱ्या प्रकारात रूपांतरित करते, उदाहरणार्थ, व्हेक्टरला अॅरेमध्ये. + +```rust + Some(array) +} +``` + +Rust तुम्हाला फंक्शनच्या शेवटी मूल्य परत करताना [`return`](https://doc.rust-lang.org/std/keyword.return.html) कीवर्ड वापरण्याची आवश्यकता नाही. + +```rust +#[wasm_bindgen] +pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option { +``` + +हे फंक्शन एक सार्वजनिक मेटा-पत्ता प्राप्त करते, ज्यात _Vpub_ आणि _Kpub_ दोन्ही समाविष्ट आहेत. ते गुप्त पत्ता, प्रकाशित करण्यासाठी सार्वजनिक की (_Rpub_), आणि एक-बाइट स्कॅन मूल्य परत करते जे ॲलिसच्या मालकीचे कोणते प्रकाशित पत्ते असू शकतात हे ओळखण्यास गती देते. + +स्कॅन मूल्य सामायिक गुप्त (_S = GRprivVpriv_) चा भाग आहे. हे मूल्य ॲलिससाठी उपलब्ध आहे, आणि ते तपासणे _f(Kpub+G\*hash(S))_ प्रकाशित पत्त्याच्या बरोबर आहे की नाही हे तपासण्यापेक्षा खूप वेगवान आहे. + +```rust + let (address, r_pub, scan) = + generate_stealth_address(&str_to_array::<66>(stealth_address)?); +``` + +आम्ही लायब्ररीचे [`generate_stealth_address`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.generate_stealth_address.html) वापरतो. + +```rust + format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}", + encode(address), + encode(r_pub), + encode(&[scan]) + ).into() +} +``` + +JSON-एनकोडेड आउटपुट स्ट्रिंग तयार करा. + +```rust +#[wasm_bindgen] +pub fn wasm_compute_stealth_key( + address: &str, + bill_pub_key: &str, + view_private_key: &str, + spend_private_key: &str +) -> Option { + . + . + . +} +``` + +हे फंक्शन पत्त्यावरून (_Rpriv_) पैसे काढण्यासाठी खाजगी की मोजण्यासाठी लायब्ररीच्या [`compute_stealth_key`](https://docs.rs/eth-stealth-addresses/latest/eth_stealth_addresses/fn.compute_stealth_key.html) चा वापर करते. या गणनेसाठी ही मूल्ये आवश्यक आहेत: + +- पत्ता (_पत्ता=f(Ppub)_) +- बिलद्वारे तयार केलेली सार्वजनिक की (_Rpub_) +- पाहण्याची खाजगी की (_Vpriv_) +- खर्च करण्याची खाजगी की (_Kpriv_) + +```rust +#[wasm_bindgen(start)] +``` + +[`#[wasm_bindgen(start)]`](https://wasm-bindgen.github.io/wasm-bindgen/reference/attributes/on-rust-exports/start.html) निर्दिष्ट करते की WASM कोड सुरू झाल्यावर फंक्शन कार्यान्वित केले जाते. + +```rust +pub fn main() { + console_error_panic_hook::set_once(); +} +``` + +हा कोड निर्दिष्ट करतो की पॅनिक आउटपुट JavaScript कन्सोलवर पाठवले जावे. ते प्रत्यक्षात पाहण्यासाठी, ॲप्लिकेशन वापरा आणि बिलला एक अवैध मेटा-पत्ता द्या (फक्त एक हेक्साडेसिमल अंक बदला). तुम्हाला JavaScript कन्सोलमध्ये ही त्रुटी दिसेल: + +``` +rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs:701:9: +assertion `left == right` failed + left: 0 + right: 1 +``` + +त्यानंतर स्टॅक ट्रेस येईल. नंतर बिलला वैध मेटा-पत्ता द्या, आणि ॲलिसला एकतर अवैध पत्ता किंवा अवैध सार्वजनिक की द्या. तुम्हाला ही त्रुटी दिसेल: + +``` +rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/eth-stealth-addresses-0.1.0/src/lib.rs:78:9: +keys do not generate stealth address +``` + +पुन्हा, त्यानंतर स्टॅक ट्रेस येईल. + +#### वापरकर्ता इंटरफेस {#ui} + +वापरकर्ता इंटरफेस [React](https://react.dev/) वापरून लिहिलेला आहे आणि [Vite](https://vite.dev/) द्वारे सर्व्ह केला जातो. तुम्ही [या ट्यूटोरियल](/developers/tutorials/creating-a-wagmi-ui-for-your-contract/) चा वापर करून त्यांच्याबद्दल शिकू शकता. येथे [WAGMI](https://wagmi.sh/) ची गरज नाही कारण आम्ही थेट ब्लॉकचेन किंवा वॉलेटशी संवाद साधत नाही. + +वापरकर्ता इंटरफेसचा एकमेव अस्पष्ट भाग म्हणजे WASM कनेक्टिव्हिटी. हे कसे कार्य करते ते येथे आहे. + +**`vite.config.js`** + +या फाइलमध्ये [Vite कॉन्फिगरेशन](https://vite.dev/config/) आहे. + +```js +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import wasm from "vite-plugin-wasm"; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react(), wasm()], +}) +``` + +आम्हाला दोन Vite प्लगइनची आवश्यकता आहे: [react](https://www.npmjs.com/package/@vitejs/plugin-react) आणि [wasm](https://github.com/Menci/vite-plugin-wasm#readme). + +**`App.jsx`** + +ही फाइल ॲप्लिकेशनचा मुख्य घटक आहे. हे एक कंटेनर आहे ज्यात दोन घटक आहेत: `Alice` आणि `Bill`, त्या वापरकर्त्यांसाठी वापरकर्ता इंटरफेस. WASM साठी संबंधित भाग म्हणजे इनिशियलायझेशन कोड. + +```jsx +import init from './rust-wasm/pkg/rust_wasm.js' +``` + +जेव्हा आपण [`wasm-pack`](https://rustwasm.github.io/docs/wasm-pack/) वापरतो, तेव्हा ते दोन फाइल्स तयार करते ज्या आपण येथे वापरतो: प्रत्यक्ष कोड असलेली एक wasm फाइल (येथे, `src/rust-wasm/pkg/rust_wasm_bg.wasm`) आणि ते वापरण्यासाठी व्याख्या असलेली एक JavaScript फाइल (येथे, `src/rust_wasm/pkg/rust_wasm.js`). त्या JavaScript फाइलचा डीफॉल्ट एक्सपोर्ट हा कोड आहे जो WASM सुरू करण्यासाठी चालवणे आवश्यक आहे. + +```jsx +function App() { + . + . + . + useEffect(() => { + const loadWasm = async () => { + try { + await init(); + setWasmReady(true) + } catch (err) { + console.error('Error loading wasm:', err) + alert("Wasm error: " + err) + } + } + + loadWasm() + }, [] + ) +``` + +[`useEffect` हुक](https://react.dev/reference/react/useEffect) तुम्हाला एक फंक्शन निर्दिष्ट करू देतो जे स्टेट व्हेरिएबल्स बदलल्यावर कार्यान्वित होते. येथे, स्टेट व्हेरिएबल्सची सूची रिकामी (`[]`) आहे, त्यामुळे हे फंक्शन पृष्ठ लोड झाल्यावर फक्त एकदाच कार्यान्वित होते. + +इफेक्ट फंक्शन त्वरित परत आले पाहिजे. असिंक्रोनस कोड वापरण्यासाठी, जसे की WASM `init` (ज्याला `.wasm` फाइल लोड करावी लागते आणि त्यामुळे वेळ लागतो) आम्ही एक अंतर्गत [`async`](https://en.wikipedia.org/wiki/Async/await) फंक्शन परिभाषित करतो आणि ते `await` शिवाय चालवतो. + +**`Bill.jsx`** + +हा बिलसाठी वापरकर्ता इंटरफेस आहे. त्यात एकच क्रिया आहे, ॲलिसने प्रदान केलेल्या गुप्त मेटा-पत्त्यावर आधारित पत्ता तयार करणे. + +```jsx +import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js' +``` + +डीफॉल्ट एक्सपोर्ट व्यतिरिक्त, `wasm-pack` द्वारे तयार केलेला JavaScript कोड WASM कोडमधील प्रत्येक फंक्शनसाठी एक फंक्शन एक्सपोर्ट करतो. + +```jsx + -``` - -जर `workingTx.write` नसेल तर आम्ही अद्याप अभिवादन अपडेट पाठवण्यासाठी आवश्यक असलेल्या माहितीची वाट पाहत आहोत, म्हणून बटण अक्षम आहे. जर `workingTx.write` मूल्य असेल तर ते व्यवहार पाठवण्यासाठी कॉल करण्याचे फंक्शन आहे. - -```tsx -
- - - - - ) -} -``` - -शेवटी, आम्ही काय करत आहोत हे पाहण्यात तुम्हाला मदत करण्यासाठी, आम्ही वापरत असलेल्या तीन वस्तू दाखवा: - -- `readResults` -- `preparedTx` -- `workingTx` - -##### `ShowGreeting` घटक {#showgreeting-component} - -हा घटक दाखवतो - -```tsx -const ShowGreeting = (attrs : ShowGreetingAttrsType) => { -``` - -घटक फंक्शनला घटकाच्या सर्व गुणधर्मांसह एक पॅरामीटर मिळतो. - -```tsx - return {attrs.greeting} -} -``` - -##### `ShowObject` घटक {#showobject-component} - -माहितीच्या उद्देशांसाठी, आम्ही महत्त्वाच्या वस्तू (`readResults` अभिवादन वाचण्यासाठी आणि `preparedTx` आणि `workingTx` आपण तयार केलेल्या व्यवहारांसाठी) दाखवण्यासाठी `ShowObject` घटक वापरतो. - -```tsx -const ShowObject = (attrs: ShowObjectAttrsType ) => { - const keys = Object.keys(attrs.object) - const funs = keys.filter(k => typeof attrs.object[k] == "function") - return <> -
-``` - -आम्हाला सर्व माहितीने UI ला अव्यवस्थित करायचे नाही, म्हणून त्यांना पाहणे किंवा बंद करणे शक्य करण्यासाठी, आम्ही [`details`](https://www.w3schools.com/tags/tag_details.asp) टॅग वापरतो. - -```tsx - {attrs.name} -
-        {JSON.stringify(attrs.object, null, 2)}
-```
-
-बहुतेक फील्ड [`JSON.stringify`](https://www.w3schools.com/js/js_json_stringify.asp) वापरून प्रदर्शित केले जातात.
-
-```tsx
-      
- { funs.length > 0 && - <> - Functions: -
    -``` - -अपवाद फंक्शन्स आहेत, जे [JSON मानकाचा](https://www.json.org/json-en.html) भाग नाहीत, म्हणून ते स्वतंत्रपणे प्रदर्शित करावे लागतील. - -```tsx - {funs.map((f, i) => -``` - -JSX मध्ये, `{` कर्ली ब्रॅकेट्स `}` मधील कोड JavaScript म्हणून अर्थ लावला जातो. मग, `(` रेग्युलर ब्रॅकेट्स `)` मधील कोडचा पुन्हा JSX म्हणून अर्थ लावला जातो. - -```tsx - (
  • {f}
  • ) - )} -``` - -React ला [DOM ट्री](https://www.w3schools.com/js/js_htmldom.asp) मधील टॅगसाठी वेगळे आयडेंटिफायर असणे आवश्यक आहे. याचा अर्थ असा की एकाच टॅगच्या चाइल्ड्सना (या प्रकरणात, [अनऑर्डर्ड लिस्ट](https://www.w3schools.com/tags/tag_ul.asp)), वेगळ्या `key` अॅट्रिब्युट्सची आवश्यकता असते. - -```tsx -
- - } -
- -} -``` - -विविध HTML टॅग्ज संपवा. - -##### अंतिम `export` {#the-final-export} - -```tsx -export { Greeter } -``` - -`Greeter` घटक हा आहे जो आम्हाला ऍप्लिकेशनसाठी निर्यात करणे आवश्यक आहे. - -#### `src/wagmi.ts` {#wagmi-ts} - -शेवटी, WAGMI शी संबंधित विविध व्याख्या `src/wagmi.ts` मध्ये आहेत. मी येथे सर्व काही स्पष्ट करणार नाही, कारण त्यातील बहुतेक बॉयलरप्लेट आहे जी तुम्हाला बदलण्याची शक्यता नाही. - -येथील कोड [github](https://github.com/qbzzt/20230801-modern-ui/blob/main/src/wagmi.ts) वरील कोड सारखाच नाही कारण नंतर लेखात आम्ही आणखी एक चेन ([Redstone Holesky](https://redstone.xyz/docs/network-info)) जोडतो. - -```ts -import { getDefaultWallets } from '@rainbow-me/rainbowkit' -import { configureChains, createConfig } from 'wagmi' -import { holesky, sepolia } from 'wagmi/chains' -``` - -ऍप्लिकेशनला समर्थन देणारे ब्लॉकचेन आयात करा. तुम्ही [viem github](https://github.com/wagmi-dev/viem/tree/main/src/chains/definitions) मध्ये समर्थित चेन्सची सूची पाहू शकता. - -```ts -import { publicProvider } from 'wagmi/providers/public' - -const walletConnectProjectId = 'c96e690bb92b6311e8e9b2a6a22df575' -``` - -[WalletConnect](https://walletconnect.com/) वापरण्यास सक्षम होण्यासाठी तुम्हाला तुमच्या ऍप्लिकेशनसाठी प्रोजेक्ट आयडी आवश्यक आहे. तुम्ही ते [cloud.walletconnect.com](https://cloud.walletconnect.com/sign-in) वर मिळवू शकता. - -```ts -const { chains, publicClient, webSocketPublicClient } = configureChains( - [ holesky, sepolia ], - [ - publicProvider(), - ], -) - -const { connectors } = getDefaultWallets({ - appName: 'My wagmi + RainbowKit App', - chains, - projectId: walletConnectProjectId, -}) - -export const config = createConfig({ - autoConnect: true, - connectors, - publicClient, - webSocketPublicClient, -}) - -export { chains } -``` - -### दुसरे ब्लॉकचेन जोडणे {#add-blockchain} - -आजकाल बरेच [L2 स्केलिंग सोल्यूशन](/layer-2/) आहेत, आणि तुम्ही काहींना समर्थन देऊ इच्छित असाल जे viem अद्याप समर्थन देत नाही. ते करण्यासाठी, तुम्ही `src/wagmi.ts` मध्ये बदल करा. या सूचना [Redstone Holesky](https://redstone.xyz/docs/network-info) कसे जोडायचे हे स्पष्ट करतात. - -1. viem वरून `defineChain` प्रकार आयात करा. - - ```ts - import { defineChain } from 'viem' - ``` - -2. नेटवर्क व्याख्या जोडा. - - ```ts - const redstoneHolesky = defineChain({ - id: 17_001, - name: 'Redstone Holesky', - network: 'redstone-holesky', - nativeCurrency: { - decimals: 18, - name: 'Ether', - symbol: 'ETH', - }, - rpcUrls: { - default: { - http: ['https://rpc.holesky.redstone.xyz'], - webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], - }, - public: { - http: ['https://rpc.holesky.redstone.xyz'], - webSocket: ['wss://rpc.holesky.redstone.xyz/ws'], - }, - }, - blockExplorers: { - default: { name: 'Explorer', url: 'https://explorer.holesky.redstone.xyz' }, - }, - }) - ``` - -3. `configureChains` कॉलमध्ये नवीन चेन जोडा. - - ```ts - const { chains, publicClient, webSocketPublicClient } = configureChains( - [ holesky, sepolia, redstoneHolesky ], - [ publicProvider(), ], - ) - ``` - -4. ऍप्लिकेशनला नवीन नेटवर्कवर तुमच्या काँट्रॅक्ट्सचा पत्ता माहित असल्याची खात्री करा. या प्रकरणात, आम्ही `src/components/Greeter.tsx` मध्ये बदल करतो: - - ```ts - const contractAddrs : AddressPerBlockchainType = { - // Holesky - 17000: '0x432d810484AdD7454ddb3b5311f0Ac2E95CeceA8', - - // Redstone Holesky - 17001: '0x4919517f82a1B89a32392E1BF72ec827ba9986D3', - - // Sepolia - 11155111: '0x7143d5c190F048C8d19fe325b748b081903E3BF0' - } - ``` - -## निष्कर्ष {#conclusion} - -अर्थात, तुम्हाला `Greeter` साठी युझर इंटरफेस प्रदान करण्याची खरोखर काळजी नाही. तुम्हाला तुमच्या स्वतःच्या काँट्रॅक्ट्ससाठी युझर इंटरफेस तयार करायचा आहे. तुमचे स्वतःचे ऍप्लिकेशन तयार करण्यासाठी, या पायऱ्या चालवा: - -1. wagmi ऍप्लिकेशन तयार करण्यासाठी निर्दिष्ट करा. - - ```sh copy - pnpm create wagmi - ``` - -2. ऍप्लिकेशनला नाव द्या. - -3. **React** फ्रेमवर्क निवडा. - -4. **Vite** व्हेरिएंट निवडा. - -5. तुम्ही [Rainbow kit जोडू शकता](https://www.rainbowkit.com/docs/installation#manual-setup). - -आता जा आणि तुमचे काँट्रॅक्ट्स व्यापक जगासाठी वापरण्यायोग्य बनवा. - -[माझ्या कामाबद्दल अधिक माहितीसाठी येथे पहा](https://cryptodocguy.pro/). - diff --git a/public/content/translations/mr/developers/tutorials/deploying-your-first-smart-contract/index.md b/public/content/translations/mr/developers/tutorials/deploying-your-first-smart-contract/index.md index 56f0da82b3b..f4f89244e10 100644 --- a/public/content/translations/mr/developers/tutorials/deploying-your-first-smart-contract/index.md +++ b/public/content/translations/mr/developers/tutorials/deploying-your-first-smart-contract/index.md @@ -5,8 +5,8 @@ author: "jdourlens" tags: [ "स्मार्ट कॉन्ट्रॅक्ट", - "रीमिक्स", - "सॉलिडिटी", + "Remix", + "Solidity", "डिप्लॉयिंग" ] skill: beginner diff --git a/public/content/translations/mr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md b/public/content/translations/mr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md index b45c9e7f91e..69705980c89 100644 --- a/public/content/translations/mr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md +++ b/public/content/translations/mr/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/index.md @@ -3,7 +3,7 @@ title: "कंत्राटाच्या आकाराच्या मर description: "तुमचे स्मार्ट कंत्राट खूप मोठे होण्यापासून रोखण्यासाठी तुम्ही काय करू शकता?" author: Markus Waas lang: mr -tags: [ "सॉलिडिटी", "स्मार्ट कॉन्ट्रॅक्ट", "स्टोरेज" ] +tags: [ "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "स्टोरेज" ] skill: intermediate published: 2020-06-26 source: soliditydeveloper.com diff --git a/public/content/translations/mr/developers/tutorials/erc-721-vyper-annotated-code/index.md b/public/content/translations/mr/developers/tutorials/erc-721-vyper-annotated-code/index.md index e765c3bb84f..9eb20977eaa 100644 --- a/public/content/translations/mr/developers/tutorials/erc-721-vyper-annotated-code/index.md +++ b/public/content/translations/mr/developers/tutorials/erc-721-vyper-annotated-code/index.md @@ -3,7 +3,7 @@ title: "Vyper ERC-721 कॉन्ट्रॅक्ट वॉकथ्रू" description: "Ryuya Nakamura चे ERC-721 कॉन्ट्रॅक्ट आणि ते कसे कार्य करते" author: Ori Pomerantz lang: mr -tags: [ "vyper", "erc-721", "python" ] +tags: [ "Vyper", "erc-721", "Python" ] skill: beginner published: 2021-04-01 --- @@ -214,7 +214,7 @@ Python मध्ये, आणि Vyper मध्ये, तुम्ही ए self.minter = msg.sender ``` -स्टेट व्हेरिएबल्स ऍक्सेस करण्यासाठी तुम्ही `self.` वापरता` (पुन्हा, Python प्रमाणेच). +स्टेट व्हेरिएबल्स ऍक्सेस करण्यासाठी तुम्ही `self.` वापरता (पुन्हा, Python प्रमाणेच). #### व्ह्यू फंक्शन्स {#views} diff --git a/public/content/translations/mr/developers/tutorials/erc20-annotated-code/index.md b/public/content/translations/mr/developers/tutorials/erc20-annotated-code/index.md index 77ded2dfd5c..8bc2229a3b5 100644 --- a/public/content/translations/mr/developers/tutorials/erc20-annotated-code/index.md +++ b/public/content/translations/mr/developers/tutorials/erc20-annotated-code/index.md @@ -3,7 +3,7 @@ title: "ERC-20 कॉन्ट्रॅक्ट वॉक-थ्रू" description: "OpenZeppelin ERC-20 कॉन्ट्रॅक्टमध्ये काय आहे आणि ते तिथे का आहे?" author: Ori Pomerantz lang: mr -tags: [ "सॉलिडिटी", "erc-20" ] +tags: [ "Solidity", "erc-20" ] skill: beginner published: 2021-03-09 --- diff --git a/public/content/translations/mr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md b/public/content/translations/mr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md index 30aa0f8a9a5..a629dfac846 100644 --- a/public/content/translations/mr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md +++ b/public/content/translations/mr/developers/tutorials/getting-started-with-ethereum-development-using-alchemy/index.md @@ -4,11 +4,11 @@ description: "हे Ethereum डेव्हलपमेंटची सुर author: "Elan Halpern" tags: [ - "javascript", + "JavaScript", "ethers.js", "नोड्स", "querying", - "alchemy" + "Alchemy" ] skill: beginner lang: mr diff --git a/public/content/translations/mr/developers/tutorials/guide-to-smart-contract-security-tools/index.md b/public/content/translations/mr/developers/tutorials/guide-to-smart-contract-security-tools/index.md index 075df7fff4b..33343bd33cb 100644 --- a/public/content/translations/mr/developers/tutorials/guide-to-smart-contract-security-tools/index.md +++ b/public/content/translations/mr/developers/tutorials/guide-to-smart-contract-security-tools/index.md @@ -3,7 +3,7 @@ title: "स्मार्ट कॉन्ट्रॅक्ट सुरक् description: "तीन वेगवेगळ्या चाचणी आणि प्रोग्राम विश्लेषण तंत्रांचे अवलोकन" author: "Trailofbits" lang: mr -tags: [ "सॉलिडिटी", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा" ] +tags: [ "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा" ] skill: intermediate published: 2020-09-07 source: Building secure contracts diff --git a/public/content/translations/mr/developers/tutorials/hello-world-smart-contract-fullstack/index.md b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract-fullstack/index.md index 70432814ee9..ea79244115b 100644 --- a/public/content/translations/mr/developers/tutorials/hello-world-smart-contract-fullstack/index.md +++ b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract-fullstack/index.md @@ -4,9 +4,9 @@ description: "Ethereum वर एक साधे स्मार्ट कॉ author: "nstrike2" tags: [ - "सॉलिडिटी", - "hardhat", - "alchemy", + "Solidity", + "Hardhat", + "Alchemy", "स्मार्ट कॉन्ट्रॅक्ट", "डिप्लॉयिंग", "ब्लॉक एक्सप्लोरर", diff --git a/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md index 637ec6384c2..7b5fc7f46bf 100644 --- a/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md +++ b/public/content/translations/mr/developers/tutorials/hello-world-smart-contract/index.md @@ -4,9 +4,9 @@ description: "Ethereum वर एक साधे स्मार्ट कॉ author: "elanh" tags: [ - "सॉलिडिटी", - "hardhat", - "alchemy", + "Solidity", + "Hardhat", + "Alchemy", "स्मार्ट कॉन्ट्रॅक्ट", "डिप्लॉयिंग" ] @@ -51,7 +51,7 @@ Ethereum चेनला विनंत्या करण्याचे अ ## पायरी ४: फॉसेटमधून इथर मिळवा {#step-4} -आपले स्मार्ट कॉन्ट्रॅक्ट टेस्ट नेटवर्कवर उपयोजित करण्यासाठी, आपल्याला काही बनावट Eth ची आवश्यकता असेल. Sepolia ETH मिळवण्यासाठी, विविध फॉसेटची सूची पाहण्यासाठी तुम्ही [Sepolia नेटवर्क तपशील](/developers/docs/networks/#sepolia) वर जाऊ शकता. एक काम करत नसल्यास, दुसरा प्रयत्न करा, कारण ते कधीकधी रिकामे होऊ शकतात. नेटवर्क ट्रॅफिकमुळे तुमचा बनावट ETH मिळण्यास थोडा वेळ लागू शकतो. त्यानंतर लवकरच तुमच्या Metamask खात्यात ETH दिसेल! +आपले स्मार्ट कॉन्ट्रॅक्ट टेस्ट नेटवर्कवर उपयोजित करण्यासाठी, आपल्याला काही बनावट Eth ची आवश्यकता असेल. Sepolia ETH मिळवण्यासाठी, विविध फॉसेटची सूची पाहण्यासाठी तुम्ही [Sepolia नेटवर्क तपशील](/developers/docs/networks/#sepolia) वर जाऊ शकता. एक काम करत नसल्यास, दुसरा प्रयत्न करा, कारण ते कधीकधी रिकामे होऊ शकतात. नेटवर्क ट्रॅफिकमुळे तुमचा बनावट ETH मिळण्यास थोडा वेळ लागू शकतो. त्यानंतर लवकरच तुमच्या MetaMask खात्यात ETH दिसेल! ## पायरी ५: तुमची शिल्लक तपासा {#step-5} @@ -363,4 +363,4 @@ Contract deployed to address: 0x6cd7d44516a20882cEa2DE9f205bF401c0d23570 या ट्युटोरियलच्या भाग १ साठी एवढेच, भाग २ मध्ये आपण आपला सुरुवातीचा संदेश अपडेट करून [आपल्या स्मार्ट कॉन्ट्रॅक्टशी संवाद साधू](https://www.alchemy.com/docs/interacting-with-a-smart-contract) आणि भाग ३ मध्ये आपण [आपले स्मार्ट कॉन्ट्रॅक्ट Etherscan वर प्रकाशित करू](https://www.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) जेणेकरून प्रत्येकाला त्याच्याशी संवाद कसा साधायचा हे कळेल. -\*\*Alchemy बद्दल अधिक जाणून घ्यायचे आहे? आमची [वेबसाइट](https://www.alchemy.com/eth) तपासा. एकही अपडेट चुकवायचे नाही? [येथे](https://www.alchemy.com/newsletter) आमच्या वृत्तपत्राची सदस्यता घ्या! आमच्या [Discord](https://discord.gg/u72VCg3) मध्ये सामील होण्याची खात्री करा. \*\* +**Alchemy बद्दल अधिक जाणून घ्यायचे आहे? आमची [वेबसाइट](https://www.alchemy.com/eth) तपासा. एकही अपडेट चुकवायचे नाही? [येथे](https://www.alchemy.com/newsletter) आमच्या वृत्तपत्राची सदस्यता घ्या! आमच्या [Discord](https://discord.gg/u72VCg3) मध्ये सामील होण्याची खात्री करा. ** diff --git a/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md b/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md index 8997ff14d37..9551cb7167a 100644 --- a/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md +++ b/public/content/translations/mr/developers/tutorials/how-to-implement-an-erc721-market/index.md @@ -6,7 +6,7 @@ tags: [ "स्मार्ट कॉन्ट्रॅक्ट", "erc-721", - "सॉलिडिटी", + "Solidity", "tokens" ] skill: intermediate diff --git a/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md b/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md index 62ec6d3a132..3d4fa601695 100644 --- a/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md +++ b/public/content/translations/mr/developers/tutorials/how-to-mint-an-nft/index.md @@ -5,8 +5,8 @@ author: "Sumi Mudgil" tags: [ "ERC-721", - "alchemy", - "सॉलिडिटी", + "Alchemy", + "Solidity", "स्मार्ट कॉन्ट्रॅक्ट" ] skill: beginner diff --git a/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md b/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md index 5faf8882a82..83e1155b5c4 100644 --- a/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md +++ b/public/content/translations/mr/developers/tutorials/how-to-mock-solidity-contracts-for-testing/index.md @@ -5,7 +5,7 @@ author: Markus Waas lang: mr tags: [ - "सॉलिडिटी", + "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "चाचणी", "मॉक करणे" diff --git a/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md b/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md index c8ed9c7deff..fb13f726c4c 100644 --- a/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md +++ b/public/content/translations/mr/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/index.md @@ -5,7 +5,7 @@ author: "Trailofbits" lang: mr tags: [ - "सॉलिडिटी", + "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा", "चाचणी", diff --git a/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md b/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md index 4a0a076996e..e3675d6c4b0 100644 --- a/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md +++ b/public/content/translations/mr/developers/tutorials/smart-contract-security-guidelines/index.md @@ -2,7 +2,7 @@ title: "स्मार्ट कॉन्ट्रॅक्ट सुरक्षा मार्गदर्शक तत्त्वे" description: "तुमचे डॅप तयार करताना विचारात घेण्यासाठी सुरक्षा मार्गदर्शक तत्त्वांची तपासणी सूची" author: "Trailofbits" -tags: [ "सॉलिडिटी", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा" ] +tags: [ "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा" ] skill: intermediate lang: mr published: 2020-09-06 diff --git a/public/content/translations/mr/developers/tutorials/stealth-addr/index.md b/public/content/translations/mr/developers/tutorials/stealth-addr/index.md index 1c3b5e5ff16..76e8571c36d 100644 --- a/public/content/translations/mr/developers/tutorials/stealth-addr/index.md +++ b/public/content/translations/mr/developers/tutorials/stealth-addr/index.md @@ -2,7 +2,7 @@ title: "गुप्त पत्त्यांचा वापर" description: "गुप्त पत्ते वापरकर्त्यांना अज्ञातपणे मालमत्ता हस्तांतरित करण्याची परवानगी देतात. हा लेख वाचल्यानंतर, तुम्ही हे करू शकाल: गुप्त पत्ते काय आहेत आणि ते कसे कार्य करतात हे स्पष्ट करू शकाल, अनामिकता जपणाऱ्या पद्धतीने गुप्त पत्त्यांचा वापर कसा करायचा हे समजू शकाल, आणि गुप्त पत्त्यांचा वापर करणारे वेब-आधारित ॲप्लिकेशन लिहू शकाल." author: Ori Pomerantz -tags: [ "गुप्त पत्ता", "गोपनीयता", "कूटलेखन", "rust", "wasm" ] +tags: [ "गुप्त पत्ता", "गोपनीयता", "कूटलेखन", "Rust", "wasm" ] skill: intermediate published: 2025-11-30 lang: mr diff --git a/public/content/translations/mr/developers/tutorials/the-graph-fixing-web3-data-querying/index.md b/public/content/translations/mr/developers/tutorials/the-graph-fixing-web3-data-querying/index.md index 8bbb8535dbb..1e554254f8b 100644 --- a/public/content/translations/mr/developers/tutorials/the-graph-fixing-web3-data-querying/index.md +++ b/public/content/translations/mr/developers/tutorials/the-graph-fixing-web3-data-querying/index.md @@ -5,11 +5,11 @@ author: Markus Waas lang: mr tags: [ - "सॉलिडिटी", + "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "querying", "द ग्राफ", - "react" + "React" ] skill: intermediate published: 2020-09-06 diff --git a/public/content/translations/mr/developers/tutorials/token-integration-checklist/index.md b/public/content/translations/mr/developers/tutorials/token-integration-checklist/index.md index 9955b7a9383..510be7ff52b 100644 --- a/public/content/translations/mr/developers/tutorials/token-integration-checklist/index.md +++ b/public/content/translations/mr/developers/tutorials/token-integration-checklist/index.md @@ -5,7 +5,7 @@ author: "Trailofbits" lang: mr tags: [ - "सॉलिडिटी", + "Solidity", "स्मार्ट कॉन्ट्रॅक्ट", "सुरक्षा", "tokens" diff --git a/public/content/translations/mr/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md b/public/content/translations/mr/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md index e3a993289e4..f1c94a9327b 100644 --- a/public/content/translations/mr/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md +++ b/public/content/translations/mr/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/index.md @@ -2,7 +2,7 @@ title: "Solidity स्मार्ट कॉन्ट्रॅक्टमधून ERC-20 टोकनचे हस्तांतरण आणि मंजूरी" description: "Solidity वापरून एक DEX स्मार्ट कॉन्ट्रॅक्ट तयार करा जो ERC-20 टोकन हस्तांतरण आणि मंजुरी हाताळतो." author: "jdourlens" -tags: [ "स्मार्ट कॉन्ट्रॅक्ट", "tokens", "सॉलिडिटी", "erc-20" ] +tags: [ "स्मार्ट कॉन्ट्रॅक्ट", "tokens", "Solidity", "erc-20" ] skill: intermediate lang: mr published: 2020-04-07 diff --git a/public/content/translations/mr/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md b/public/content/translations/mr/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md index aef47ef34ae..e36db0e2715 100644 --- a/public/content/translations/mr/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md +++ b/public/content/translations/mr/developers/tutorials/understand-the-erc-20-token-smart-contract/index.md @@ -2,7 +2,7 @@ title: "ERC-20 टोकन स्मार्ट कॉन्ट्रॅक्ट समजून घ्या" description: "संपूर्ण सॉलिडिटी स्मार्ट कॉन्ट्रॅक्ट उदाहरण आणि स्पष्टीकरणासह ERC-20 टोकन स्टँडर्ड कसे अंमलात आणायचे ते शिका." author: "jdourlens" -tags: [ "स्मार्ट कॉन्ट्रॅक्ट", "tokens", "सॉलिडिटी", "erc-20" ] +tags: [ "स्मार्ट कॉन्ट्रॅक्ट", "tokens", "Solidity", "erc-20" ] skill: beginner lang: mr published: 2020-04-05 diff --git a/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md b/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md deleted file mode 100644 index 51bc913db16..00000000000 --- a/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md +++ /dev/null @@ -1,1898 +0,0 @@ ---- -title: "Uniswap-v2 कराराचे अवलोकन" -description: "Uniswap-v2 करार कसा काम करतो? ते त्या प्रकारे का लिहिले आहे?" -author: Ori Pomerantz -tags: [ "सॉलिडिटी" ] -skill: intermediate -published: 2021-05-01 -lang: mr ---- - -## प्रस्तावना {#introduction} - -[Uniswap v2](https://app.uniswap.org/whitepaper.pdf) कोणत्याही दोन ERC-20 टोकन्समध्ये विनिमय बाजार तयार करू शकते. या लेखात आपण या प्रोटोकॉलची अंमलबजावणी करणाऱ्या करारांसाठी स्रोत कोड पाहू आणि ते या प्रकारे का लिहिले आहेत हे पाहू. - -### Uniswap काय करते? {#what-does-uniswap-do} - -मूलतः, वापरकर्त्यांचे दोन प्रकार आहेत: लिक्विडिटी प्रोव्हायडर आणि व्यापारी. - -_लिक्विडिटी प्रोव्हायडर_ पूलला दोन टोकन्स प्रदान करतात ज्यांचा विनिमय केला जाऊ शकतो (आपण त्यांना **टोकन0** आणि **टोकन1** म्हणू). त्या बदल्यात, त्यांना तिसरे टोकन मिळते जे पूलच्या आंशिक मालकीचे प्रतिनिधित्व करते, ज्याला _लिक्विडिटी टोकन_ म्हणतात. - -_व्यापारी_ पूलमध्ये एका प्रकारचे टोकन पाठवतात आणि दुसरे टोकन (उदाहरणार्थ, **टोकन0** पाठवून **टोकन1** प्राप्त करणे) लिक्विडिटी प्रोव्हायडरद्वारे प्रदान केलेल्या पूलमधून प्राप्त करतात. पूलमध्ये असलेल्या **टोकन0** आणि **टोकन1** च्या सापेक्ष संख्येनुसार विनिमय दर निर्धारित केला जातो. याव्यतिरिक्त, पूल लिक्विडिटी पूलसाठी बक्षीस म्हणून लहान टक्केवारी घेते. - -जेव्हा लिक्विडिटी प्रोव्हायडरना त्यांची मालमत्ता परत हवी असते, तेव्हा ते पूल टोकन्स बर्न करू शकतात आणि बक्षिसांमधील त्यांच्या वाट्यासह त्यांचे टोकन्स परत मिळवू शकतात. - -[अधिक वर्णनासाठी येथे क्लिक करा](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/swaps/). - -### v2 का? v3 का नाही? {#why-v2} - -[Uniswap v3](https://app.uniswap.org/whitepaper-v3.pdf) हे एक अपग्रेड आहे जे v2 पेक्षा खूपच गुंतागुंतीचे आहे. आधी v2 शिकणे आणि नंतर v3 कडे जाणे सोपे आहे. - -### मुख्य करार विरुद्ध परिघ करार {#contract-types} - -Uniswap v2 दोन घटकांमध्ये विभागलेले आहे, एक मुख्य आणि एक परिघ. हे विभाजन मुख्य करारांना, जे मालमत्ता ठेवतात आणि त्यामुळे _सुरक्षित_ असणे आवश्यक आहे, सोपे आणि ऑडिट करण्यास सोपे बनवते. व्यापाऱ्यांसाठी आवश्यक असलेली सर्व अतिरिक्त कार्यक्षमता नंतर परिघ करारांद्वारे प्रदान केली जाऊ शकते. - -## डेटा आणि नियंत्रण प्रवाह {#flows} - -जेव्हा तुम्ही Uniswap च्या तीन मुख्य क्रिया करता तेव्हा हा डेटा आणि नियंत्रणाचा प्रवाह आहे: - -1. वेगवेगळ्या टोकन्समध्ये स्वॅप करा -2. मार्केटमध्ये लिक्विडिटी जोडा आणि पेअर एक्सचेंज ERC-20 लिक्विडिटी टोकन्ससह बक्षीस मिळवा -3. ERC-20 लिक्विडिटी टोकन्स बर्न करा आणि पेअर एक्सचेंज व्यापाऱ्यांना विनिमय करण्याची परवानगी देणारे ERC-20 टोकन्स परत मिळवा - -### स्वॅप {#swap-flow} - -हा सर्वात सामान्य प्रवाह आहे, जो व्यापाऱ्यांद्वारे वापरला जातो: - -#### कॉलर {#caller} - -1. स्वॅप करायच्या रकमेसाठी परिघ खात्याला अनुमती द्या. -2. परिघ कराराच्या अनेक स्वॅप फंक्शन्सपैकी एक कॉल करा (कोणते फंक्शन वापरायचे हे ETH सामील आहे की नाही, व्यापारी जमा करायच्या टोकन्सची रक्कम किंवा परत मिळवायच्या टोकन्सची रक्कम निर्दिष्ट करतो का, इत्यादीवर अवलंबून असते). - प्रत्येक स्वॅप फंक्शन एक `path` स्वीकारतो, जो एक एक्सचेंजेसचा अॅरे आहे ज्यातून जायचे आहे. - -#### परिघ करारामध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02-sol} - -3. मार्गावरील प्रत्येक एक्सचेंजवर व्यापार करण्याची आवश्यकता असलेल्या रकमेची ओळख करा. -4. मार्गावर पुनरावृत्ती करते. मार्गावरील प्रत्येक एक्सचेंजसाठी ते इनपुट टोकन पाठवते आणि नंतर एक्सचेंजच्या `swap` फंक्शनला कॉल करते. - बहुतेक प्रकरणांमध्ये टोकन्ससाठी गंतव्य पत्ता मार्गावरील पुढील पेअर एक्सचेंज असतो. अंतिम एक्सचेंजमध्ये तो व्यापाऱ्याने प्रदान केलेला पत्ता असतो. - -#### मुख्य करारामध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2} - -5. मुख्य कराराची फसवणूक होत नाही आणि स्वॅपनंतर पुरेशी लिक्विडिटी राखू शकते याची पडताळणी करा. -6. ज्ञात रिझर्व्ह्स व्यतिरिक्त आमच्याकडे किती अतिरिक्त टोकन्स आहेत ते पहा. ती रक्कम म्हणजे आम्हाला विनिमय करण्यासाठी मिळालेल्या इनपुट टोकन्सची संख्या. -7. आउटपुट टोकन्स गंतव्यस्थानावर पाठवा. -8. रिझर्व्ह रक्कम अपडेट करण्यासाठी `_update` ला कॉल करा - -#### परिघ करारामध्ये परत (UniswapV2Router02.sol) {#back-in-the-periphery-contract-uniswapv2router02-sol} - -9. आवश्यक स्वच्छता करा (उदाहरणार्थ, व्यापाऱ्याला पाठवण्यासाठी ETH परत मिळवण्यासाठी WETH टोकन्स बर्न करा) - -### लिक्विडिटी जोडा {#add-liquidity-flow} - -#### कॉलर {#caller-2} - -1. लिक्विडिटी पूलमध्ये जोडल्या जाणाऱ्या रकमेसाठी परिघ खात्याला अनुमती द्या. -2. परिघ कराराच्या `addLiquidity` फंक्शन्सपैकी एक कॉल करा. - -#### परिघ करारामध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02sol-2} - -3. आवश्यक असल्यास नवीन पेअर एक्सचेंज तयार करा -4. जर अस्तित्वात असलेला पेअर एक्सचेंज असेल, तर जोडण्यासाठी टोकन्सची रक्कम मोजा. हे दोन्ही टोकन्ससाठी समान मूल्य मानले जाते, म्हणून नवीन टोकन्स आणि अस्तित्वातील टोकन्सचे प्रमाण समान असते. -5. रक्कम स्वीकारार्ह आहे की नाही ते तपासा (कॉलर किमान रक्कम निर्दिष्ट करू शकतात ज्याच्या खाली ते लिक्विडिटी जोडू इच्छित नाहीत) -6. मुख्य कराराला कॉल करा. - -#### मुख्य करारामध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2} - -7. लिक्विडिटी टोकन्स मिंट करा आणि ते कॉलरला पाठवा -8. रिझर्व्ह रक्कम अपडेट करण्यासाठी `_update` ला कॉल करा - -### लिक्विडिटी काढा {#remove-liquidity-flow} - -#### कॉलर {#caller-3} - -1. अंतर्निहित टोकन्सच्या बदल्यात बर्न करण्यासाठी लिक्विडिटी टोकन्सची अनुमती परिघ खात्याला द्या. -2. परिघ कराराच्या `removeLiquidity` फंक्शन्सपैकी एक कॉल करा. - -#### परिघ करारामध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02sol-3} - -3. लिक्विडिटी टोकन्स पेअर एक्सचेंजला पाठवा - -#### मुख्य करारामध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-3} - -4. बर्न केलेल्या टोकन्सच्या प्रमाणात गंतव्य पत्त्यावर अंतर्निहित टोकन्स पाठवा. उदाहरणार्थ, जर पूलमध्ये 1000 A टोकन्स, 500 B टोकन्स, आणि 90 लिक्विडिटी टोकन्स असतील, आणि आम्हाला बर्न करण्यासाठी 9 टोकन्स मिळाले, तर आम्ही 10% लिक्विडिटी टोकन्स बर्न करत आहोत, म्हणून आम्ही वापरकर्त्याला 100 A टोकन्स आणि 50 B टोकन्स परत पाठवतो. -5. लिक्विडिटी टोकन्स बर्न करा -6. रिझर्व्ह रक्कम अपडेट करण्यासाठी `_update` ला कॉल करा - -## मुख्य करार {#core-contracts} - -हे सुरक्षित करार आहेत जे लिक्विडिटी ठेवतात. - -### UniswapV2Pair.sol {#UniswapV2Pair} - -[हा करार](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol) प्रत्यक्ष पूलची अंमलबजावणी करतो जो टोकन्सचा विनिमय करतो. ही मुख्य Uniswap कार्यक्षमता आहे. - -```solidity -pragma solidity =0.5.16; - -import './interfaces/IUniswapV2Pair.sol'; -import './UniswapV2ERC20.sol'; -import './libraries/Math.sol'; -import './libraries/UQ112x112.sol'; -import './interfaces/IERC20.sol'; -import './interfaces/IUniswapV2Factory.sol'; -import './interfaces/IUniswapV2Callee.sol'; -``` - -हे सर्व इंटरफेस आहेत ज्यांबद्दल कराराला माहित असणे आवश्यक आहे, एकतर कारण करार त्यांची अंमलबजावणी करतो (`IUniswapV2Pair` आणि `UniswapV2ERC20`) किंवा कारण तो त्यांची अंमलबजावणी करणाऱ्या करारांना कॉल करतो. - -```solidity -contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 { -``` - -हा करार `UniswapV2ERC20` पासून वारसा घेतो, जो लिक्विडिटी टोकन्ससाठी ERC-20 फंक्शन्स प्रदान करतो. - -```solidity - using SafeMath for uint; -``` - -[SafeMath लायब्ररी](https://docs.openzeppelin.com/contracts/2.x/api/math) ओव्हरफ्लो आणि अंडरफ्लो टाळण्यासाठी वापरली जाते. हे महत्त्वाचे आहे कारण अन्यथा आपण अशा परिस्थितीत येऊ शकतो जिथे मूल्य `-1` असले पाहिजे, परंतु त्याऐवजी `2^256-1` असेल. - -```solidity - using UQ112x112 for uint224; -``` - -पूल करारामध्ये अनेक गणितांसाठी अपूर्णांकांची आवश्यकता असते. तथापि, EVM द्वारे अपूर्णांक समर्थित नाहीत. -Uniswap ने शोधलेला उपाय म्हणजे 224 बिट मूल्यांचा वापर करणे, ज्यामध्ये पूर्णांक भागासाठी 112 बिट्स आणि अपूर्णांकासाठी 112 बिट्स असतात. म्हणून `1.0` हे `2^112` म्हणून दर्शविले जाते, `1.5` हे `2^112 + 2^111` म्हणून दर्शविले जाते, इत्यादी. - -या लायब्ररीबद्दल अधिक तपशील [दस्तऐवजात नंतर](#FixedPoint) उपलब्ध आहेत. - -#### व्हेरिअबल्स {#pair-vars} - -```solidity - uint public constant MINIMUM_LIQUIDITY = 10**3; -``` - -शून्याने भागाकार टाळण्यासाठी, लिक्विडिटी टोकन्सची किमान संख्या नेहमी अस्तित्वात असते (परंतु ती शून्य खात्याच्या मालकीची असते). ती संख्या **MINIMUM_LIQUIDITY** आहे, एक हजार. - -```solidity - bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); -``` - -हा ERC-20 ट्रान्सफर फंक्शनसाठी ABI सिलेक्टर आहे. हे दोन टोकन खात्यांमध्ये ERC-20 टोकन्स हस्तांतरित करण्यासाठी वापरले जाते. - -```solidity - address public factory; -``` - -हा फॅक्टरी करार आहे ज्याने हा पूल तयार केला. प्रत्येक पूल दोन ERC-20 टोकन्समध्ये एक एक्सचेंज आहे, फॅक्टरी एक केंद्रीय बिंदू आहे जो या सर्व पूलांना जोडतो. - -```solidity - address public token0; - address public token1; -``` - -हे त्या दोन प्रकारच्या ERC-20 टोकन्सच्या करारांचे पत्ते आहेत ज्यांचा या पूलमार्फत विनिमय केला जाऊ शकतो. - -```solidity - uint112 private reserve0; // uses single storage slot, accessible via getReserves - uint112 private reserve1; // uses single storage slot, accessible via getReserves -``` - -प्रत्येक टोकन प्रकारासाठी पूलमध्ये असलेला राखीव साठा. आपण असे गृहीत धरतो की दोन्ही समान मूल्याचे प्रतिनिधित्व करतात, आणि म्हणून प्रत्येक token0 चे मूल्य reserve1/reserve0 token1 इतके आहे. - -```solidity - uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves -``` - -शेवटच्या ब्लॉकसाठी टाइमस्टॅम्प ज्यामध्ये विनिमय झाला होता, जो वेळेनुसार विनिमय दरांचा मागोवा घेण्यासाठी वापरला जातो. - -Ethereum करारांचा सर्वात मोठा गॅस खर्च म्हणजे स्टोरेज, जो कराराच्या एका कॉलपासून दुसऱ्या कॉलपर्यंत कायम राहतो. प्रत्येक स्टोरेज सेल 256 बिट्स लांब असतो. म्हणून तीन व्हेरिएबल्स, `reserve0`, `reserve1`, आणि `blockTimestampLast`, अशा प्रकारे वाटप केले जातात की एकाच स्टोरेज मूल्यामध्ये हे तिन्ही समाविष्ट होऊ शकतात (112+112+32=256). - -```solidity - uint public price0CumulativeLast; - uint public price1CumulativeLast; -``` - -हे व्हेरिएबल्स प्रत्येक टोकनसाठी (प्रत्येकी दुसऱ्याच्या संदर्भात) एकत्रित खर्च ठेवतात. ते एका विशिष्ट कालावधीसाठी सरासरी विनिमय दर मोजण्यासाठी वापरले जाऊ शकतात. - -```solidity - uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event -``` - -पेअर एक्सचेंज token0 आणि token1 मधील विनिमय दराचा निर्णय घेण्याचा मार्ग म्हणजे व्यापारादरम्यान दोन राखीव साठ्यांचा गुणाकार स्थिर ठेवणे. `kLast` हे हे मूल्य आहे. जेव्हा एखादा लिक्विडिटी प्रोव्हायडर टोकन्स जमा करतो किंवा काढतो तेव्हा ते बदलते आणि 0.3% बाजार शुल्कामुळे ते किंचित वाढते. - -येथे एक सोपे उदाहरण आहे. लक्षात घ्या की साधेपणासाठी सारणीमध्ये दशांश बिंदूनंतर फक्त तीन अंक आहेत आणि आम्ही 0.3% व्यापार शुल्क दुर्लक्षित करतो त्यामुळे संख्या अचूक नाहीत. - -| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | सरासरी विनिमय दर (टोकन1 / टोकन0) | -| ---------------------------------------------------------------------- | ------------------------: | ------------------------: | -------------------: | --------------------------------------------------- | -| प्राथमिक सेटअप | 1,000.000 | 1,000.000 | 1,000,000 | | -| व्यापारी A ने 50 token0 साठी 47.619 token1 स्वॅप केले | 1,050.000 | 952.381 | 1,000,000 | 0.952 | -| व्यापारी B ने 10 token0 साठी 8.984 token1 स्वॅप केले | 1,060.000 | 943.396 | 1,000,000 | 0.898 | -| व्यापारी C ने 40 token0 साठी 34.305 token1 स्वॅप केले | 1,100.000 | 909.090 | 1,000,000 | 0.858 | -| व्यापारी D ने 100 token1 साठी 109.01 token0 स्वॅप केले | 990.990 | 1,009.090 | 1,000,000 | 0.917 | -| व्यापारी E ने 10 token0 साठी 10.079 token1 स्वॅप केले | 1,000.990 | 999.010 | 1,000,000 | 1.008 | - -व्यापारी जसजसे अधिक token0 प्रदान करतात, तसतसे token1 चे सापेक्ष मूल्य वाढते आणि उलट, पुरवठा आणि मागणीवर आधारित. - -#### लॉक {#pair-lock} - -```solidity - uint private unlocked = 1; -``` - -सुरक्षा भेद्यतांचा एक वर्ग आहे जो [पुनर्प्रवेश गैरवापरा](https://medium.com/coinmonks/ethernaut-lvl-10-re-entrancy-walkthrough-how-to-abuse-execution-ordering-and-reproduce-the-dao-7ec88b912c14) वर आधारित आहे. Uniswap ला अनियंत्रित ERC-20 टोकन हस्तांतरित करणे आवश्यक आहे, याचा अर्थ ERC-20 करारांना कॉल करणे जे त्यांना कॉल करणाऱ्या Uniswap बाजाराचा गैरवापर करण्याचा प्रयत्न करू शकतात. -कराराचा भाग म्हणून `unlocked` व्हेरिएबल असल्यामुळे, आपण फंक्शन्स चालू असताना (एकाच व्यवहारात) त्यांना कॉल करण्यापासून रोखू शकतो. - -```solidity - modifier lock() { -``` - -हे फंक्शन एक [मॉडिफायर](https://docs.soliditylang.org/en/v0.8.3/contracts.html#function-modifiers) आहे, एक फंक्शन जे सामान्य फंक्शनभोवती गुंडाळते आणि त्याचे वर्तन काही प्रकारे बदलते. - -```solidity - require(unlocked == 1, 'UniswapV2: LOCKED'); - unlocked = 0; -``` - -जर `unlocked` एकच्या बरोबर असेल, तर ते शून्यावर सेट करा. जर ते आधीच शून्य असेल तर कॉल रिव्हर्ट करा, ते अयशस्वी करा. - -```solidity - _; -``` - -एका मॉडिफायरमध्ये `_;` हे मूळ फंक्शन कॉल आहे (सर्व पॅरामीटर्ससह). येथे याचा अर्थ असा आहे की फंक्शन कॉल तेव्हाच होतो जेव्हा `unlocked` चे मूल्य एक होते, आणि ते चालू असताना `unlocked` चे मूल्य शून्य असते. - -```solidity - unlocked = 1; - } -``` - -मुख्य फंक्शन परत आल्यानंतर, लॉक सोडा. - -#### विविध फंक्शन्स {#pair-misc} - -```solidity - function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { - _reserve0 = reserve0; - _reserve1 = reserve1; - _blockTimestampLast = blockTimestampLast; - } -``` - -हे फंक्शन कॉल करणाऱ्यांना एक्सचेंजच्या सध्याच्या स्थितीबद्दल माहिती देते. लक्षात घ्या की सॉलिडिटी फंक्शन्स [एकाधिक मूल्ये परत करू शकतात](https://docs.soliditylang.org/en/v0.8.3/contracts.html#returning-multiple-values). - -```solidity - function _safeTransfer(address token, address to, uint value) private { - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); -``` - -हे इंटर्नल फंक्शन एक्सचेंजमधून ERC20 टोकन्सची ठराविक रक्कम दुसऱ्या कोणालातरी हस्तांतरित करते. `SELECTOR` हे निर्दिष्ट करते की आपण ज्या फंक्शनला कॉल करत आहोत ते `transfer(address,uint)` आहे (वरील व्याख्या पहा). - -टोकन फंक्शनसाठी इंटरफेस इम्पोर्ट करणे टाळण्यासाठी, आम्ही [ABI फंक्शन्स](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html#abi-encoding-and-decoding-functions) पैकी एक वापरून "मॅन्युअली" कॉल तयार करतो. - -```solidity - require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED'); - } -``` - -ERC-20 ट्रान्सफर कॉल अयशस्वी झाल्याची तक्रार करण्याचे दोन मार्ग आहेत: - -1. रिव्हर्ट. जर बाह्य कॉन्ट्रॅक्टचा कॉल रिव्हर्ट झाल्यास, तर बुलियन रिटर्न व्हॅल्यू `false` असते -2. सामान्यपणे समाप्त होते परंतु अपयशाची तक्रार करते. त्या बाबतीत रिटर्न व्हॅल्यू बफरची लांबी शून्य नसते, आणि जेव्हा बुलियन व्हॅल्यू म्हणून डीकोड केले जाते, तेव्हा ते `false` असते - -यापैकी कोणतीही अट घडल्यास, रिव्हर्ट करा. - -#### इव्हेंट्स {#pair-events} - -```solidity - event Mint(address indexed sender, uint amount0, uint amount1); - event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); -``` - -हे दोन इव्हेंट्स तेव्हा उत्सर्जित होतात जेव्हा लिक्विडिटी प्रोव्हायडर एकतर लिक्विडिटी जमा करतो (`Mint`) किंवा काढतो (`Burn`). दोन्ही बाबतीत, जमा केलेल्या किंवा काढलेल्या token0 आणि token1 ची रक्कम इव्हेंटचा भाग आहे, तसेच आम्हाला कॉल करणाऱ्या खात्याची ओळख (`sender`) देखील आहे. विथड्रॉवलच्या बाबतीत, इव्हेंटमध्ये टोकन प्राप्त करणारे लक्ष्य (`to`) देखील समाविष्ट असते, जे प्रेषकासारखे (`sender`) नसू शकते. - -```solidity - event Swap( - address indexed sender, - uint amount0In, - uint amount1In, - uint amount0Out, - uint amount1Out, - address indexed to - ); -``` - -जेव्हा एखादा व्यापारी एका टोकनसाठी दुसऱ्या टोकनची देवाणघेवाण करतो तेव्हा हा इव्हेंट उत्सर्जित होतो. पुन्हा, प्रेषक आणि गंतव्यस्थान समान नसू शकतात. -प्रत्येक टोकन एकतर एक्सचेंजला पाठवला जाऊ शकतो, किंवा तिथून प्राप्त केला जाऊ शकतो. - -```solidity - event Sync(uint112 reserve0, uint112 reserve1); -``` - -शेवटी, `Sync` प्रत्येक वेळी टोकन्स जोडले किंवा काढले जातात, कारणाकडे दुर्लक्ष करून, नवीनतम राखीव माहिती (आणि म्हणून विनिमय दर) प्रदान करण्यासाठी उत्सर्जित होतो. - -#### सेटअप फंक्शन्स {#pair-setup} - -नवीन पेअर एक्सचेंज सेट अप केल्यावर हे फंक्शन्स एकदा कॉल केले जाणे अपेक्षित आहे. - -```solidity - constructor() public { - factory = msg.sender; - } -``` - -कन्स्ट्रक्टर हे सुनिश्चित करतो की आम्ही पेअर तयार करणाऱ्या फॅक्टरीच्या ॲड्रेसचा मागोवा ठेवू. ही माहिती `initialize` साठी आणि फॅक्टरी फीसाठी (असल्यास) आवश्यक आहे. - -```solidity - // डिप्लॉयमेंटच्या वेळी फॅक्टरीद्वारे एकदा कॉल केले जाते - function initialize(address _token0, address _token1) external { - require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // पुरेसे तपासणी - token0 = _token0; - token1 = _token1; - } -``` - -हे फंक्शन फॅक्टरीला (आणि फक्त फॅक्टरीला) दोन ERC-20 टोकन्स निर्दिष्ट करण्याची परवानगी देते ज्यांची हे पेअर देवाणघेवाण करेल. - -#### इंटर्नल अपडेट फंक्शन्स {#pair-update-internal} - -##### \_update - -```solidity - // रिझर्व्हस् अपडेट करा आणि, प्रति ब्लॉक पहिल्या कॉलवर, किंमत संचयक (price accumulators) अपडेट करा - function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { -``` - -प्रत्येक वेळी टोकन्स जमा केले किंवा काढले जातात तेव्हा हे फंक्शन कॉल केले जाते. - -```solidity - require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW'); -``` - -जर balance0 किंवा balance1 (uint256) हे uint112(-1) (=2^112-1) पेक्षा जास्त असेल (म्हणजे uint112 मध्ये रूपांतरित केल्यावर ते ओव्हरफ्लो होते आणि 0 वर परत येते) तर ओव्हरफ्लो टाळण्यासाठी \_update पुढे चालू ठेवण्यास नकार द्या. एका सामान्य टोकनसह ज्याला 10^18 युनिट्समध्ये उपविभाजित केले जाऊ शकते, याचा अर्थ प्रत्येक एक्सचेंज प्रत्येक टोकनच्या सुमारे 5.1\*10^15 पर्यंत मर्यादित आहे. आतापर्यंत ही समस्या आलेली नाही. - -```solidity - uint32 blockTimestamp = uint32(block.timestamp % 2**32); - uint32 timeElapsed = blockTimestamp - blockTimestampLast; // ओव्हरफ्लो अपेक्षित आहे - if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { -``` - -जर गेलेला वेळ शून्य नसेल, तर याचा अर्थ आम्ही या ब्लॉकवरील पहिले एक्सचेंज व्यवहार आहोत. त्या बाबतीत, आम्हाला कॉस्ट अ‍ॅक्युम्युलेटर (cost accumulators) अपडेट करणे आवश्यक आहे. - -```solidity - // * कधीही ओव्हरफ्लो होत नाही, आणि + ओव्हरफ्लो अपेक्षित आहे - price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; - price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; - } -``` - -प्रत्येक कॉस्ट अ‍ॅक्युम्युलेटरला नवीनतम कॉस्ट (दुसऱ्या टोकनचा रिझर्व्ह/या टोकनचा रिझर्व्ह) गुणिले सेकंदात गेलेला वेळ यानुसार अपडेट केले जाते. सरासरी किंमत मिळवण्यासाठी, तुम्ही वेळेच्या दोन बिंदूंमधील एकत्रित किंमत वाचता आणि त्यांच्यातील वेळेच्या फरकाने भागता. उदाहरणार्थ, घटनांचा हा क्रम गृहीत धरा: - -| इव्हेंट | reserve0 | reserve1 | टाइमस्टॅम्प | सीमान्त विनिमय दर (reserve1 / reserve0) | price0CumulativeLast | -| --------------------------------------------------------------------------- | ------------------------: | ------------------------: | ----------- | ---------------------------------------------------------: | -------------------------------------------------------------------------: | -| प्राथमिक सेटअप | 1,000.000 | 1,000.000 | 5,000 | 1.000 | 0 | -| व्यापारी A 50 token0 जमा करतो आणि 47.619 token1 परत मिळवतो | 1,050.000 | 952.381 | 5,020 | 0.907 | 20 | -| व्यापारी B 10 token0 जमा करतो आणि 8.984 token1 परत मिळवतो | 1,060.000 | 943.396 | 5,030 | 0.890 | 20+10\*0.907 = 29.07 | -| व्यापारी C 40 token0 जमा करतो आणि 34.305 token1 परत मिळवतो | 1,100.000 | 909.090 | 5,100 | 0.826 | 29.07+70\*0.890 = 91.37 | -| व्यापारी D 100 token1 जमा करतो आणि 109.01 token0 परत मिळवतो | 990.990 | 1,009.090 | 5,110 | 1.018 | 91.37+10\*0.826 = 99.63 | -| व्यापारी E 10 token0 जमा करतो आणि 10.079 token1 परत मिळवतो | 1,000.990 | 999.010 | 5,150 | 0.998 | 99.63+40\*1.1018 = 143.702 | - -समजा आपल्याला 5,030 आणि 5,150 टाइमस्टॅम्प दरम्यान **Token0** ची सरासरी किंमत काढायची आहे. `price0Cumulative` च्या मूल्यातील फरक 143.702-29.07=114.632 आहे. ही दोन मिनिटांची (120 सेकंद) सरासरी आहे. म्हणून सरासरी किंमत 114.632/120 = 0.955 आहे. - -या किंमतीच्या गणनेमुळेच आपल्याला जुन्या रिझर्व्ह आकारांची माहिती असणे आवश्यक आहे. - -```solidity -एका मॉडिफायरमध्ये `_;` मूळ फंक्शन कॉल (सर्व पॅरामीटर्ससह) असतो. -``` - -येथे याचा अर्थ असा आहे की फंक्शन कॉल तेव्हाच होतो जेव्हा `unlocked` कॉल केल्यावर एक होते आणि ते चालू असताना `unlocked` चे मूल्य शून्य असते. - -##### ``` - - unlocked = 1; -} -``` - -```solidity -मुख्य फंक्शन परत आल्यानंतर, लॉक सोडा. -``` - -विविध फंक्शन्स {#pair-misc} function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { -_reserve0 = reserve0; -_reserve1 = reserve1; -_blockTimestampLast = blockTimestampLast; -} - -हे फंक्शन कॉलरला एक्सचेंजच्या सध्याच्या स्थितीबद्दल माहिती देते. - -```solidity -लक्षात घ्या की Solidity फंक्शन्स [एकापेक्षा जास्त मूल्ये परत करू शकतात](https://docs.soliditylang.org/en/v0.8.3/contracts.html#returning-multiple-values). -``` - -``` -function _safeTransfer(address token, address to, uint value) private { - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); हे अंतर्गत फंक्शन एक्सचेंजमधून ERC20 टोकनची रक्कम दुसऱ्या कोणालातरी हस्तांतरित करते. -``` - -```solidity -`SELECTOR` निर्दिष्ट करते की आपण ज्या फंक्शनला कॉल करत आहोत ते `transfer(address,uint)` आहे (वर व्याख्या पहा). -``` - -टोकन फंक्शनसाठी इंटरफेस आयात करणे टाळण्यासाठी, आम्ही [ABI फंक्शन्स](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html#abi-encoding-and-decoding-functions) पैकी एक वापरून "मॅन्युअली" कॉल तयार करतो. -require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED'); -} - -```solidity -ERC-20 ट्रान्सफर कॉल अयशस्वी झाल्याची तक्रार करण्याचे दोन मार्ग आहेत: -``` - -रिव्हर्ट. जर बाह्य कराराचा कॉल रिव्हर्ट झाला, तर बूलियन रिटर्न व्हॅल्यू `false` असते - -```solidity -सामान्यपणे समाप्त होते परंतु अपयशाची तक्रार करते. -``` - -त्या बाबतीत रिटर्न व्हॅल्यू बफरची लांबी शून्य नसते आणि बूलियन व्हॅल्यू म्हणून डीकोड केल्यावर ते `false` असते यापैकी कोणतीही एक अट घडल्यास, रिव्हर्ट करा. - -```solidity -इव्हेंट्स {#pair-events} -``` - -``` -event Mint(address indexed sender, uint amount0, uint amount1); -event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); जेव्हा लिक्विडिटी प्रोव्हायडर एकतर लिक्विडिटी जमा करतो (`Mint`) किंवा काढतो (`Burn`) तेव्हा हे दोन इव्हेंट उत्सर्जित होतात. -``` - -```solidity -दोन्ही बाबतीत, जमा किंवा काढलेल्या token0 आणि token1 ची रक्कम इव्हेंटचा भाग असते, तसेच आम्हाला कॉल करणाऱ्या खात्याची ओळख (`sender`). -``` - -पैसे काढण्याच्या बाबतीत, इव्हेंटमध्ये टोकन प्राप्त करणाऱ्या लक्ष्याचा (`to`) देखील समावेश असतो, जो प्रेषकसारखाच असेल असे नाही. - -```solidity - event Swap( - address indexed sender, - uint amount0In, - uint amount1In, - uint amount0Out, - uint amount1Out, - address indexed to - ); -``` - -जेव्हा व्यापारी एका टोकनसाठी दुसरा टोकन स्वॅप करतो तेव्हा हा इव्हेंट उत्सर्जित होतो. पुन्हा, प्रेषक आणि गंतव्यस्थान समान असू शकत नाहीत. -प्रत्येक टोकन एकतर एक्सचेंजला पाठवला जाऊ शकतो, किंवा त्यातून प्राप्त केला जाऊ शकतो. - -#### ``` - -event Sync(uint112 reserve0, uint112 reserve1); -``` - -शेवटी, `Sync` प्रत्येक वेळी टोकन जोडले किंवा काढले जातात, कारणास्तव काहीही असो, नवीनतम राखीव माहिती (आणि म्हणून विनिमय दर) प्रदान करण्यासाठी उत्सर्जित होते. सेटअप फंक्शन्स {#pair-setup} - -##### नवीन पेअर एक्सचेंज सेट केल्यावर ही फंक्शन्स एकदा कॉल केली जावीत. - -```solidity - constructor() public { - factory = msg.sender; - } -``` - -कन्स्ट्रक्टर हे सुनिश्चित करतो की आम्ही पेअर तयार करणाऱ्या फॅक्टरीच्या पत्त्याचा मागोवा ठेवू. ही माहिती `initialize` आणि फॅक्टरी शुल्कासाठी (जर असेल तर) आवश्यक आहे // called once by the factory at time of deployment -function initialize(address _token0, address _token1) external { -require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // sufficient check -token0 = _token0; -token1 = _token1; -} - -```solidity -हे फंक्शन फॅक्टरीला (आणि फक्त फॅक्टरीला) दोन ERC-20 टोकन निर्दिष्ट करण्याची परवानगी देते ज्यांचा हा पेअर एक्सचेंज करेल. -``` - -अंतर्गत अपडेट फंक्शन्स {#pair-update-internal} \_update - -```solidity - // update reserves and, on the first call per block, price accumulators - function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { -``` - -जेव्हाही टोकन्स जमा किंवा काढले जातात तेव्हा हे फंक्शन कॉल केले जाते. - -```solidity - require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW'); -``` - -जर balance0 किंवा balance1 (uint256) uint112(-1) (=2^112-1) पेक्षा जास्त असेल (म्हणजे ते ओव्हरफ्लो होते आणि uint112 मध्ये रूपांतरित झाल्यावर 0 वर परत येते), तर ओव्हरफ्लो टाळण्यासाठी \_update पुढे चालू ठेवण्यास नकार द्या. सामान्य टोकनसह जे 10^18 युनिट्समध्ये विभागले जाऊ शकते, याचा अर्थ प्रत्येक एक्सचेंज सुमारे 5.1\*10^15 प्रत्येक टोकनपर्यंत मर्यादित आहे. - -```solidity -आतापर्यंत ती समस्या नाही. -``` - -``` - uint32 blockTimestamp = uint32(block.timestamp % 2**32); - uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired - if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { जर गेलेला वेळ शून्य नसेल, तर याचा अर्थ आम्ही या ब्लॉकवरील पहिला एक्सचेंज व्यवहार आहोत. त्या बाबतीत, आम्हाला खर्च संचयक अद्यतनित करणे आवश्यक आहे. // * never overflows, and + overflow is desired - price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; - price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; - } -``` - -प्रत्येक खर्च संचयक नवीनतम खर्चासह (दुसऱ्या टोकनचा राखीव साठा/या टोकनचा राखीव साठा) सेकंदात गेलेल्या वेळेने गुणून अद्यतनित केला जातो. - -सरासरी किंमत मिळविण्यासाठी, आपण दोन वेळेच्या बिंदूंवर एकत्रित किंमत वाचता आणि त्यांच्यातील वेळेच्या फरकाने भागता. -उदाहरणार्थ, घटनांचा हा क्रम गृहीत धरा: एक व्यापारी या वस्तुस्थितीचा वापर करू शकतो की पेअर एक्सचेंजला वाटते की **Token0** अधिक मौल्यवान आहे, त्यातून मूल्य काढण्यासाठी. - -| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | price0CumulativeLast | -| --------------------------------------------------------------- | -------: | -------: | -------------------: | -------------------: | -| प्राथमिक सेटअप | 8 | 32 | 5,000 | 40 | -| व्यापारी 8 **Token0** टोकन्स जमा करतो, 16 **Token1** परत मिळवतो | 16 | 16 | 5,000 | 32 | - -0.907 - -```solidity - } else { - liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); -``` - -व्यापारी B ने 10 token0 जमा केले आणि 8.984 token1 परत मिळवले जर ते तसे करत नाहीत, तर आम्ही त्यांना शिक्षा म्हणून त्यांनी प्रदान केलेल्या कमी मूल्याच्या आधारावर लिक्विडिटी टोकन देतो. - -ती सुरुवातीची ठेव असो किंवा नंतरची, आम्ही प्रदान केलेल्या लिक्विडिटी टोकन्सची संख्या `reserve0*reserve1` मधील बदलाच्या वर्गमूळाएवढी असते आणि लिक्विडिटी टोकनचे मूल्य बदलत नाही (जोपर्यंत आम्हाला दोन्ही प्रकारांचे समान मूल्य नसलेली ठेव मिळत नाही, ज्या प्रकरणात "दंड" वितरित केला जातो). 5,030 - -| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | पूल मूल्य (reserve0 + reserve1) | 5,100 | 0.826 | 29.07+70\*0.890 = 91.37 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ----: | --------------------: | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| प्राथमिक सेटअप | 8.000 | 8.000 | 64 | 1.018 | 8 | 8 | 2.000 | -| प्रत्येक प्रकारातील चार जमा करा | 5,150 | 5,150 | 99.63+40\*1.1018 = 143.702 | समजा आपल्याला 5,030 आणि 5,150 टाइमस्टॅम्प दरम्यान **टोकन0** ची सरासरी किंमत मोजायची आहे. | 4 | 12 | 2.000 | -| या किंमतीच्या गणनेमुळेच आपल्याला जुन्या राखीव आकारांची माहिती असणे आवश्यक आहे. | ``` - reserve0 = uint112(balance0); - reserve1 = uint112(balance1); - blockTimestampLast = blockTimestamp; - emit Sync(reserve0, reserve1); -} -``` | ``` - reserve0 = uint112(balance0); - reserve1 = uint112(balance1); - blockTimestampLast = blockTimestamp; - emit Sync(reserve0, reserve1); -} -``` | \_mintFee | ``` -// if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k) -function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) { -``` | 2 | 14 | 2.000 | -| गणना कमी करण्यासाठी (आणि त्यामुळे गॅस खर्च), हे शुल्क प्रत्येक व्यवहाराऐवजी केवळ लिक्विडिटी जोडताना किंवा पूलमधून काढतानाच मोजले जाते. | ``` - address feeTo = IUniswapV2Factory(factory).feeTo(); - feeOn = feeTo != address(0); -``` | ``` - reserve0 = uint112(balance0); - reserve1 = uint112(balance1); - blockTimestampLast = blockTimestamp; - emit Sync(reserve0, reserve1); -} -``` | जर ते शून्य असेल तर कोणतेही प्रोटोकॉल शुल्क नाही आणि ते शुल्क मोजण्याची गरज नाही. | ``` - uint _kLast = kLast; // gas savings -``` | 0 | 14 | ``` - if (feeOn) { - if (_kLast != 0) { -``` | -| लिक्विडिटी प्रोव्हायडरला त्यांच्या लिक्विडिटी टोकनच्या मूल्यांकनातून त्यांचा वाटा मिळतो. | परंतु प्रोटोकॉल शुल्कासाठी नवीन लिक्विडिटी टोकन्स मिंट करणे आणि `feeTo` पत्त्यावर प्रदान करणे आवश्यक आहे. | परंतु प्रोटोकॉल शुल्कासाठी नवीन लिक्विडिटी टोकन्स मिंट करणे आणि `feeTo` पत्त्यावर प्रदान करणे आवश्यक आहे. | जर ते शून्य असेल तर कोणतेही प्रोटोकॉल शुल्क नाही आणि ते शुल्क मोजण्याची गरज नाही. | आपण वर्गमूळ फंक्शन [या लेखात नंतर](#Math) पाहू शकता. | 0 | 14 | आम्हाला माहित आहे की `kLast` ची गणना केल्यापासून आणि वर्तमानापर्यंत कोणतीही लिक्विडिटी जोडली किंवा काढली गेली नाही (कारण आम्ही प्रत्येक वेळी लिक्विडिटी जोडली किंवा काढली जाते तेव्हा ही गणना करतो, ती प्रत्यक्षात बदलण्यापूर्वी), त्यामुळे `reserve0 * reserve1` मधील कोणताही बदल व्यवहार शुल्कातून आला पाहिजे (त्यांच्याशिवाय आम्ही `reserve0 * reserve1` स्थिर ठेवू). | - -```solidity - if (liquidity > 0) _mint(feeTo, liquidity); - } - } -``` - -अतिरिक्त लिक्विडिटी टोकन तयार करण्यासाठी आणि त्यांना `feeTo` ला नियुक्त करण्यासाठी `UniswapV2ERC20._mint` फंक्शन वापरा. - -```solidity - } else if (_kLast != 0) { - kLast = 0; - } - } -``` - -जर कोणतेही शुल्क नसेल तर `kLast` शून्यावर सेट करा (जर ते आधीच नसेल तर). - -##### जेव्हा हा करार लिहिला गेला होता तेव्हा एक [गॅस परतावा वैशिष्ट्य](https://eips.ethereum.org/EIPS/eip-3298) होते जे करारांना Ethereum राज्याचा एकूण आकार कमी करण्यासाठी प्रोत्साहन देत होते, ज्यासाठी त्यांना आवश्यक नसलेले स्टोरेज शून्यावर आणावे लागत होते. - -```solidity -हा कोड शक्य असेल तेव्हा तो परतावा मिळवतो. -``` - -बाह्यरित्या प्रवेश करण्यायोग्य फंक्शन्स {#pair-external} -लक्षात घ्या की कोणताही व्यवहार किंवा करार ही फंक्शन्स _कॉल_ करू शकतो, तरीही ते परिघ करारातून कॉल करण्यासाठी डिझाइन केलेले आहेत. - -```solidity -जर तुम्ही त्यांना थेट कॉल केले तर तुम्ही पेअर एक्सचेंजला फसवू शकणार नाही, परंतु चुकीमुळे तुमचे मूल्य कमी होऊ शकते. -``` - -मिंट // this low-level function should be called from a contract which performs important safety checks -function mint(address to) external lock returns (uint liquidity) { - -```solidity -जेव्हा लिक्विडिटी प्रोव्हायडर पूलमध्ये लिक्विडिटी जोडतो तेव्हा हे फंक्शन कॉल केले जाते. -``` - -ते बक्षीस म्हणून अतिरिक्त लिक्विडिटी टोकन मिंट करते. हे [परिघ करार](#UniswapV2Router02) मधून कॉल केले पाहिजे जे त्याच व्यवहारात लिक्विडिटी जोडल्यानंतर त्याला कॉल करते (जेणेकरून इतर कोणीही कायदेशीर मालकापूर्वी नवीन लिक्विडिटीचा दावा करणारा व्यवहार सबमिट करू शकणार नाही). - -```solidity - (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings -``` - -अनेक मूल्ये परत करणाऱ्या Solidity फंक्शनचे परिणाम वाचण्याचा हा मार्ग आहे. - -##### आम्ही शेवटची परत केलेली मूल्ये, ब्लॉक टाइमस्टॅम्प, टाकून देतो कारण आम्हाला त्याची गरज नाही. - -```solidity - uint balance0 = IERC20(token0).balanceOf(address(this)); - uint balance1 = IERC20(token1).balanceOf(address(this)); - uint amount0 = balance0.sub(_reserve0); - uint amount1 = balance1.sub(_reserve1); -``` - -सध्याची शिल्लक मिळवा आणि प्रत्येक टोकन प्रकारात किती जोडले गेले ते पहा. - -```solidity - bool feeOn = _mintFee(_reserve0, _reserve1); -``` - -गोळा करायचे प्रोटोकॉल शुल्क, जर असेल तर, मोजा आणि त्यानुसार लिक्विडिटी टोकन मिंट करा. -कारण `_mintFee` चे पॅरामीटर्स जुने राखीव मूल्ये आहेत, शुल्क केवळ शुल्कामुळे होणाऱ्या पूल बदलांवर आधारित अचूकपणे मोजले जाते. uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee -if (_totalSupply == 0) { -liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); -_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens - -```solidity -जर ही पहिली ठेव असेल, तर `MINIMUM_LIQUIDITY` टोकन तयार करा आणि त्यांना लॉक करण्यासाठी शून्य पत्त्यावर पाठवा. -``` - -ते कधीही रिडीम केले जाऊ शकत नाहीत, याचा अर्थ पूल कधीही पूर्णपणे रिकामा होणार नाही (हे आपल्याला काही ठिकाणी शून्याने भागाकार करण्यापासून वाचवते). `MINIMUM_LIQUIDITY` चे मूल्य एक हजार आहे, जे बहुतेक ERC-20 हे 10^-18 व्या टोकनच्या युनिट्समध्ये विभागलेले आहेत हे लक्षात घेता, जसे ETH वेईमध्ये विभागलेले आहे, ते एकाच टोकनच्या मूल्याच्या 10^-15 आहे. - -```solidity -जास्त खर्च नाही. -``` - -पहिल्या ठेवीच्या वेळी आम्हाला दोन टोकनचे सापेक्ष मूल्य माहित नसते, म्हणून आम्ही फक्त रक्कम गुणतो आणि वर्गमूळ घेतो, असे गृहीत धरून की ठेव आम्हाला दोन्ही टोकनमध्ये समान मूल्य प्रदान करते. - -```solidity -आपण यावर विश्वास ठेवू शकतो कारण समान मूल्य प्रदान करणे ठेवकर्त्याच्या हिताचे आहे, जेणेकरून आर्बिट्रेजमुळे मूल्य गमावू नये. -``` - -समजा दोन टोकनचे मूल्य समान आहे, परंतु आमच्या ठेवकर्त्याने **टोकन0** पेक्षा चार पट जास्त **टोकन1** जमा केले. एक व्यापारी या वस्तुस्थितीचा वापर करू शकतो की पेअर एक्सचेंजला वाटते की **टोकन0** अधिक मौल्यवान आहे, त्यातून मूल्य काढण्यासाठी. यामुळे कॉन्ट्रॅक्टला फसवणूक होत नाही हे तपासणे सोपे होते, ही तपासणी कोअर कॉन्ट्रॅक्टमध्येच _व्हावी_ लागते (कारण आम्हाला आमच्या पेरिफेरी कॉन्ट्रॅक्टव्यतिरिक्त इतर घटकांद्वारे कॉल केले जाऊ शकते). - -```solidity - uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; - uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; - require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); - { // reserve{0,1}Adjusted साठी स्कोप, स्टॅक खूप खोल त्रुटी टाळतो - uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); - uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); - require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K'); -``` - -स्वॅपमधून आपले नुकसान होणार नाही याची खात्री करण्यासाठी ही एक सॅनिटी चेक आहे. अशी कोणतीही परिस्थिती नाही ज्यात स्वॅपमुळे `reserve0*reserve1` कमी व्हावे. पूलचे मूल्य (reserve0 + reserve1) - -```solidity - } - - _update(balance0, balance1, _reserve0, _reserve1); - emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); - } -``` - -`reserve0` आणि `reserve1` अपडेट करा, आणि आवश्यक असल्यास प्राइस अ‍ॅक्युम्युलेटर (price accumulators) आणि टाइमस्टॅम्प अपडेट करा आणि एक इव्हेंट उत्सर्जित करा. - -##### सिंक किंवा स्किम - -256 -कॉन्ट्रॅक्टच्या संमतीशिवाय टोकन काढण्याचा कोणताही मार्ग नाही, परंतु डिपॉझिट ही एक वेगळी बाब आहे. व्यापारी 8 **टोकन0** टोकन्स जमा करतो, 16 **टोकन1** परत मिळवतो - -त्या बाबतीत दोन उपाय आहेत: - -- `sync`, रिझर्व्हस्ना सध्याच्या बॅलन्सवर अपडेट करा -- `skim`, अतिरिक्त रक्कम काढा. लक्षात घ्या की कोणत्याही खात्याला `skim` कॉल करण्याची परवानगी आहे कारण आम्हाला माहित नाही की टोकन कोणी जमा केले. जसे आपण पाहू शकता, व्यापाऱ्याने अतिरिक्त 8 टोकन कमावले, जे पूलच्या मूल्यात घट झाल्यामुळे येतात, ज्यामुळे त्याच्या मालकीच्या ठेवकर्त्याला दुखापत होते. - -```solidity - } else { - liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); -``` - -### प्रत्येक त्यानंतरच्या ठेवीसह आम्हाला दोन मालमत्तांमधील विनिमय दर आधीच माहित आहे, आणि आम्ही अपेक्षा करतो की लिक्विडिटी प्रदाता दोन्हीमध्ये समान मूल्य प्रदान करतील. - -जर ते तसे करत नाहीत, तर आम्ही त्यांना शिक्षा म्हणून त्यांनी प्रदान केलेल्या कमी मूल्यावर आधारित लिक्विडिटी टोकन देतो. - -```solidity -ती प्रारंभिक ठेव असो किंवा त्यानंतरची, आम्ही प्रदान करत असलेल्या लिक्विडिटी टोकनची संख्या `reserve0*reserve1` मधील बदलाच्या वर्गमूळाच्या बरोबरीची असते आणि लिक्विडिटी टोकनचे मूल्य बदलत नाही (जोपर्यंत आम्हाला अशी ठेव मिळत नाही ज्यात दोन्ही प्रकारांची समान मूल्ये नसतात, अशावेळी "दंड" वितरीत केला जातो). -``` - -येथे समान मूल्याच्या दोन टोकनसह दुसरे उदाहरण आहे, ज्यात तीन चांगल्या ठेवी आणि एक वाईट ठेव आहे (फक्त एका टोकन प्रकाराची ठेव, त्यामुळे ते कोणतेही लिक्विडिटी टोकन तयार करत नाही). -`feeTo` ॲड्रेस प्रोटोकॉल फीसाठी लिक्विडिटी टोकन जमा करतो, आणि `feeToSetter` हा `feeTo` ला वेगळ्या ॲड्रेसवर बदलण्याची परवानगी असलेला ॲड्रेस आहे. - -```solidity - mapping(address => mapping(address => address)) public getPair; - address[] public allPairs; -``` - -हे व्हेरिएबल्स पेअर्सचा, म्हणजेच दोन टोकन प्रकारांमधील एक्सचेंजचा मागोवा ठेवतात. - -पहिले, `getPair`, हे एक मॅपिंग आहे जे दोन ERC-20 टोकन्सच्या आधारे पेअर एक्सचेंज कॉन्ट्रॅक्ट ओळखते ज्यांची ते देवाणघेवाण करते. पूल मूल्य (reserve0 + reserve1) या ठेवीसाठी तयार केलेले लिक्विडिटी टोकन - -एकूण लिक्विडिटी टोकन्स प्रत्येक लिक्विडिटी टोकनचे मूल्य - -टीप: मॅपिंगच्या सर्व कीज (keys) वर पुनरावृत्ती (iterate) न करू शकण्याचे कारण म्हणजे कॉन्ट्रॅक्ट डेटा स्टोरेज _महाग_ आहे, म्हणून आपण जितके कमी वापरू तितके चांगले आणि जितके कमी वेळा बदलू तितके चांगले. 8.000 बहुतेक ऍप्लिकेशन्समध्ये तुम्हाला त्याची गरज नसते. - -```solidity - event PairCreated(address indexed token0, address indexed token1, address pair, uint); -``` - -16.000 यात टोकन्सचे ॲड्रेस, पेअर एक्सचेंजचा ॲड्रेस आणि फॅक्टरीद्वारे व्यवस्थापित केलेल्या एकूण एक्सचेंजची संख्या समाविष्ट आहे. - -```solidity - constructor(address _feeToSetter) public { - feeToSetter = _feeToSetter; - } -``` - -2.000 प्रत्येक प्रकारचे चार जमा करा - -```solidity -12.000 -``` - -हे फंक्शन एक्सचेंज पेअर्सची संख्या परत करते. - -```solidity -144 -``` - -24.000 लक्षात घ्या की कोणीही हे फंक्शन कॉल करू शकतो. नवीन पेअर एक्सचेंज तयार करण्यासाठी तुम्हाला Uniswap कडून परवानगीची आवश्यकता नाही. - -```solidity - require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); - (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); -``` - -प्रत्येक प्रकारचे दोन जमा करा -14.000 - -```solidity - require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); - require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // एकच तपासणी पुरेशी आहे -``` - -196 28.000 जर आधीपासूनच एक्सचेंज अस्तित्वात असेल, तर त्याच पेअरसाठी दुसरे तयार करण्याची गरज नाही. - -```solidity - bytes memory bytecode = type(UniswapV2Pair).creationCode; -``` - -नवीन कॉन्ट्रॅक्ट तयार करण्यासाठी आम्हाला तो तयार करणारा कोड आवश्यक आहे (कन्स्ट्रक्टर फंक्शन आणि प्रत्यक्ष कॉन्ट्रॅक्टचा EVM बायकोड मेमरीमध्ये लिहिणारा कोड दोन्ही). असमान मूल्य ठेव -18.000 ही आता समस्या नाही, कारण [Solidity आता CREATE2 ला सपोर्ट करते](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#salted-contract-creations-create2). - -```solidity -252 -``` - -32.000 - -```solidity - IUniswapV2Pair(pair).initialize(token0, token1); -``` - -नवीन एक्सचेंजला ते कोणते दोन टोकन एक्सचेंज करते हे सांगण्यासाठी `initialize` फंक्शनला कॉल करा. - -```solidity -~2.286 -``` - -आर्बिट्रेजनंतर - -```solidity -~15.874 -``` - -हे दोन फंक्शन्स `feeSetter` ला फी प्राप्तकर्त्यावर (असल्यास) नियंत्रण ठेवण्याची आणि `feeSetter` ला नवीन ॲड्रेसवर बदलण्याची परवानगी देतात. - -### UniswapV2ERC20.sol {#UniswapV2ERC20} - -~31.748 हे [OpenZeppelin ERC-20 कॉन्ट्रॅक्ट](/developers/tutorials/erc20-annotated-code) सारखेच आहे, म्हणून मी फक्त वेगळा असलेला भाग, `permit` फंक्शनॅलिटी समजावून सांगेन. - -Ethereum वरील व्यवहारांसाठी इथर (ETH) खर्च होतो, जो खऱ्या पैशाच्या समतुल्य आहे. ~2.267 } -require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED'); -_mint(to, liquidity); -अतिरिक्त लिक्विडिटी टोकन तयार करण्यासाठी आणि त्यांना योग्य खात्यात देण्यासाठी `UniswapV2ERC20._mint` फंक्शन वापरा. -_update(balance0, balance1, _reserve0, _reserve1); -if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date -emit Mint(msg.sender, amount0, amount1); -} - -```solidity -स्टेट व्हेरिएबल्स (`reserve0`, `reserve1`, आणि आवश्यक असल्यास `kLast`) अद्यतनित करा आणि योग्य इव्हेंट उत्सर्जित करा. -``` - -बर्न // this low-level function should be called from a contract which performs important safety checks -function burn(address to) external lock returns (uint amount0, uint amount1) { - -```solidity -जेव्हा लिक्विडिटी काढली जाते आणि योग्य लिक्विडिटी टोकन बर्न करणे आवश्यक असते तेव्हा हे फंक्शन कॉल केले जाते. -``` - -हे [परिघ खात्या](#UniswapV2Router02) मधून देखील कॉल केले पाहिजे. (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings -address _token0 = token0; // gas savings -address _token1 = token1; // gas savings -uint balance0 = IERC20(_token0).balanceOf(address(this)); -uint balance1 = IERC20(_token1).balanceOf(address(this)); -uint liquidity = balanceOf[address(this)]; परिघ कराराने कॉल करण्यापूर्वी बर्न करण्यासाठी लिक्विडिटी या करारात हस्तांतरित केली. त्यामुळे आम्हाला माहित आहे की किती लिक्विडिटी बर्न करायची आहे आणि आम्ही खात्री करू शकतो की ती बर्न होईल. - -```solidity - bool feeOn = _mintFee(_reserve0, _reserve1); - uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee - amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution - amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution - require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED'); -``` - -लिक्विडिटी प्रोव्हायडरला दोन्ही टोकनचे समान मूल्य मिळते. यामुळे आपण विनिमय दर बदलत नाही. _burn(address(this), liquidity); -_safeTransfer(_token0, to, amount0); -_safeTransfer(_token1, to, amount1); -balance0 = IERC20(_token0).balanceOf(address(this)); -balance1 = IERC20(_token1).balanceOf(address(this));``` - _update(balance0, balance1, _reserve0, _reserve1); - if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date - emit Burn(msg.sender, amount0, amount1, to); -} -``` - -```solidity -`burn` फंक्शनचा उर्वरित भाग वरील `mint` फंक्शनचा आरसा प्रतिमा आहे. -``` - -स्वॅप - -```solidity - // this low-level function should be called from a contract which performs important safety checks - function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { -``` - -हे फंक्शन [परिघ करार](#UniswapV2Router02) मधून कॉल केले जाणे अपेक्षित आहे. require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT'); -(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings -require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY');``` - uint balance0; - uint balance1; - { // scope for _token{0,1}, avoids stack too deep errors -``` - -```solidity -स्थानिक व्हेरिएबल्स एकतर मेमरीमध्ये किंवा, जर ते जास्त नसतील तर, थेट स्टॅकवर संग्रहित केले जाऊ शकतात. -``` - -जर आपण संख्या मर्यादित करू शकलो तर आपण स्टॅक वापरू ज्यामुळे कमी गॅस वापरला जाईल. - -```solidity -अधिक माहितीसाठी [पिवळे कागदपत्र, अधिकृत Ethereum तपशील](https://ethereum.github.io/yellowpaper/paper.pdf), पृष्ठ २६, समीकरण २९८ पहा. -``` - -``` - address _token0 = token0; - address _token1 = token1; - require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO'); - if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens - if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens हे हस्तांतरण आशावादी आहे, कारण सर्व अटी पूर्ण झाल्या आहेत याची खात्री करण्यापूर्वी आम्ही हस्तांतरण करतो. -``` - -Ethereum मध्ये हे ठीक आहे कारण जर कॉलमध्ये नंतर अटी पूर्ण झाल्या नाहीत तर आम्ही त्यातून आणि त्याने तयार केलेल्या कोणत्याही बदलांमधून रिव्हर्ट करतो. - -```solidity - if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); -``` - -मागणी केल्यास प्राप्तकर्त्याला स्वॅपबद्दल माहिती द्या. - -```solidity - balance0 = IERC20(_token0).balanceOf(address(this)); - balance1 = IERC20(_token1).balanceOf(address(this)); - } -``` - -सध्याची शिल्लक मिळवा. - -## परिघ करार आम्हाला स्वॅपसाठी कॉल करण्यापूर्वी टोकन्स पाठवतो. - -यामुळे कराराला त्याची फसवणूक होत नाही हे तपासणे सोपे होते, ही तपासणी _मुख्य करारामध्ये_ होणे आवश्यक आहे (कारण आम्हाला आमच्या परिघ कराराव्यतिरिक्त इतर घटकांकडून कॉल केला जाऊ शकतो). uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; -uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; -require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); -{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors -uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); -uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); -require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000\*\*2), 'UniswapV2: K'); स्वॅपमधून आम्हाला नुकसान होत नाही याची खात्री करण्यासाठी ही एक sanity check आहे. कोणत्याही परिस्थितीत स्वॅपने `reserve0*reserve1` कमी करू नये. येथेच आम्ही खात्री करतो की स्वॅपवर 0.3% शुल्क पाठवले जात आहे; K चे मूल्य तपासण्यापूर्वी, आम्ही दोन्ही शिल्लक 1000 ने गुणतो आणि रकमेला 3 ने गुणून वजा करतो, याचा अर्थ 0.3% (3/1000 = 0.003 = 0.3%) शिल्लक मधून वजा केले जात आहे, त्याच्या K मूल्याची सध्याच्या राखीव K मूल्याशी तुलना करण्यापूर्वी. - -### ``` - - } - - _update(balance0, balance1, _reserve0, _reserve1); - emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); -} -``` - -`reserve0` आणि `reserve1` अद्यतनित करा, आणि आवश्यक असल्यास किंमत संचयक आणि टाइमस्टॅम्प आणि एक इव्हेंट उत्सर्जित करा. सिंक किंवा स्किम - -### पेअर एक्सचेंजला वाटणाऱ्या राखीव साठ्याशी वास्तविक शिल्लक सिंकच्या बाहेर जाणे शक्य आहे. - -कराराच्या संमतीशिवाय टोकन काढण्याचा कोणताही मार्ग नाही, परंतु ठेवी वेगळी बाब आहे. -एक खाते `mint` किंवा `swap` कॉल न करता एक्सचेंजला टोकन हस्तांतरित करू शकते. - -```solidity -त्या बाबतीत दोन उपाय आहेत: -``` - -`sync`, राखीव साठा सध्याच्या शिल्लकनुसार अद्यतनित करा `skim`, अतिरिक्त रक्कम काढा. लक्षात घ्या की कोणत्याही खात्याला `skim` कॉल करण्याची परवानगी आहे कारण आम्हाला माहित नाही की टोकन कोणी जमा केले. ही माहिती एका इव्हेंटमध्ये उत्सर्जित केली जाते, परंतु इव्हेंट ब्लॉकचेनमधून प्रवेश करण्यायोग्य नाहीत. // force balances to match reserves -function skim(address to) external lock { -address _token0 = token0; // gas savings -address _token1 = token1; // gas savings -_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0)); -_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1)); -}``` -// force reserves to match balances -function sync() external lock { - _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1); -} -```} UniswapV2Factory.sol {#UniswapV2Factory} [हा करार](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol) पेअर एक्सचेंजेस तयार करतो. - -```solidity -pragma solidity =0.5.16; - -import './interfaces/IUniswapV2Factory.sol'; -import './UniswapV2Pair.sol'; - -contract UniswapV2Factory is IUniswapV2Factory { - address public feeTo; - address public feeToSetter; -``` - -प्रोटोकॉल शुल्क लागू करण्यासाठी हे स्टेट व्हेरिएबल्स आवश्यक आहेत ([व्हाइटपेपर](https://app.uniswap.org/whitepaper.pdf), पृष्ठ 5 पहा). `feeTo` पत्ता प्रोटोकॉल शुल्कासाठी लिक्विडिटी टोकन जमा करतो, आणि `feeToSetter` हा `feeTo` वेगळ्या पत्त्यावर बदलण्यास परवानगी असलेला पत्ता आहे. mapping(address => mapping(address => address)) public getPair; -address[] public allPairs; - -```solidity -हे व्हेरिएबल्स पेअर्सचा, दोन टोकन प्रकारांमधील एक्सचेंजेसचा मागोवा ठेवतात. -``` - -पहिले, `getPair`, एक मॅपिंग आहे जे दोन ERC-20 टोकनच्या आधारावर पेअर एक्सचेंज करार ओळखते. - -```solidity -ERC-20 टोकन्स त्यांच्या अंमलबजावणी करणाऱ्या करारांच्या पत्त्यांवरून ओळखले जातात, त्यामुळे की आणि मूल्य सर्व पत्ते आहेत. -``` - -`tokenA` वरून `tokenB` मध्ये रूपांतरित करणाऱ्या पेअर एक्सचेंजचा पत्ता मिळवण्यासाठी, तुम्ही `getPair[][]` (किंवा उलट) वापरता. - -```solidity -दुसरे व्हेरिएबल, `allPairs`, एक अॅरे आहे ज्यात या फॅक्टरीद्वारे तयार केलेल्या पेअर एक्सचेंजेसचे सर्व पत्ते समाविष्ट आहेत. -``` - -Ethereum मध्ये तुम्ही मॅपिंगच्या सामग्रीवर पुनरावृत्ती करू शकत नाही, किंवा सर्व कीची सूची मिळवू शकत नाही, म्हणून हे व्हेरिएबलच या फॅक्टरीद्वारे व्यवस्थापित केलेल्या एक्सचेंजेसची माहिती मिळवण्याचा एकमेव मार्ग आहे. टीप: तुम्ही मॅपिंगच्या सर्व कीवर पुनरावृत्ती करू शकत नाही याचे कारण असे की करार डेटा स्टोरेज _महाग_ आहे, त्यामुळे आपण जितके कमी वापरू तितके चांगले, आणि आपण ते जितके कमी बदलू तितके चांगले. - -#### तुम्ही [पुनरावृत्तीला समर्थन देणारे मॅपिंग](https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol) तयार करू शकता, परंतु त्यांना कीच्या सूचीसाठी अतिरिक्त स्टोरेजची आवश्यकता असते. - -बहुतेक ॲप्लिकेशन्समध्ये तुम्हाला त्याची गरज नसते. - -```solidity - event PairCreated(address indexed token0, address indexed token1, address pair, uint); -``` - -जेव्हा नवीन पेअर एक्सचेंज तयार केले जाते तेव्हा हा इव्हेंट उत्सर्जित होतो. - -```solidity -यात टोकनचे पत्ते, पेअर एक्सचेंजचा पत्ता आणि फॅक्टरीद्वारे व्यवस्थापित केलेल्या एकूण एक्सचेंजेसची संख्या समाविष्ट आहे. -``` - -``` -constructor(address _feeToSetter) public { - feeToSetter = _feeToSetter; -} -``` - -```solidity -कन्स्ट्रक्टर फक्त `feeToSetter` निर्दिष्ट करतो. -``` - -फॅक्टरीज शुल्काशिवाय सुरू होतात, आणि फक्त `feeSetter` ते बदलू शकतो. function allPairsLength() external view returns (uint) { -return allPairs.length; -} - -```solidity -हे फंक्शन एक्सचेंज पेअर्सची संख्या परत करते. -``` - -``` -function createPair(address tokenA, address tokenB) external returns (address pair) { फॅक्टरीचे मुख्य कार्य म्हणजे दोन ERC-20 टोकनमध्ये पेअर एक्सचेंज तयार करणे. लक्षात घ्या की कोणीही हे फंक्शन कॉल करू शकते. -``` - -नवीन पेअर एक्सचेंज तयार करण्यासाठी तुम्हाला Uniswap कडून परवानगीची गरज नाही. require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); -(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); - -आम्हाला नवीन एक्सचेंजचा पत्ता निश्चित हवा आहे, जेणेकरून तो ऑफचेन आगाऊ मोजला जाऊ शकेल (हे [लेयर 2 व्यवहारांसाठी](/developers/docs/scaling/) उपयुक्त ठरू शकते). - -| पॅरामीटर | मूल्य | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| मोठे लिक्विडिटी पूल लहान पूलांपेक्षा चांगले असतात, कारण त्यांच्या किंमती अधिक स्थिर असतात. | आम्हाला प्रति टोकन जोडीसाठी एकापेक्षा जास्त लिक्विडिटी पूल नको आहे. | -| जर आधीच एक एक्सचेंज असेल, तर त्याच जोडीसाठी दुसरा तयार करण्याची गरज नाही. | आम्हाला प्रति टोकन जोडीसाठी एकापेक्षा जास्त लिक्विडिटी पूल नको आहे. | -| नवीन करार तयार करण्यासाठी आम्हाला तो तयार करणारा कोड आवश्यक आहे (कन्स्ट्रक्टर फंक्शन आणि वास्तविक कराराचा EVM बायटकोड मेमरीमध्ये लिहिणारा कोड दोन्ही). | सामान्यतः Solidity मध्ये आपण फक्त `addr = new ()` वापरतो आणि कंपायलर आमच्यासाठी सर्व काही हाताळतो, परंतु एक निश्चित करार पत्ता मिळवण्यासाठी आम्हाला [CREATE2 ऑपकोड](https://eips.ethereum.org/EIPS/eip-1014) वापरण्याची गरज आहे. | -| जेव्हा हा कोड लिहिला गेला होता तेव्हा तो ऑपकोड अजूनही Solidity द्वारे समर्थित नव्हता, म्हणून कोड मॅन्युअली मिळवणे आवश्यक होते. | ही आता समस्या नाही, कारण [Solidity आता CREATE2 ला समर्थन देते](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#salted-contract-creations-create2). | - -``` - bytes32 salt = keccak256(abi.encodePacked(token0, token1)); - assembly { - pair := create2(0, add(bytecode, 32), mload(bytecode), salt) - } जेव्हा एखादा ऑपकोड Solidity द्वारे अजून समर्थित नसतो तेव्हा आपण त्याला [इनलाइन असेंब्ली](https://docs.soliditylang.org/en/v0.8.3/assembly.html) वापरून कॉल करू शकतो. -``` - -``` - IUniswapV2Pair(pair).initialize(token0, token1); नवीन एक्सचेंजला कोणते दोन टोकन एक्सचेंज करायचे आहेत हे सांगण्यासाठी `initialize` फंक्शनला कॉल करा. -``` - -```solidity - getPair[token0][token1] = pair; - getPair[token1][token0] = pair; // populate mapping in the reverse direction - allPairs.push(pair); - emit PairCreated(token0, token1, pair, allPairs.length); - } -``` - -नवीन जोडीची माहिती स्टेट व्हेरिएबल्समध्ये सेव्ह करा आणि नवीन जोडी एक्सचेंजची माहिती जगाला देण्यासाठी एक इव्हेंट उत्सर्जित करा. - -```solidity - function setFeeTo(address _feeTo) external { - require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); - feeTo = _feeTo; - } - - function setFeeToSetter(address _feeToSetter) external { - require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); - feeToSetter = _feeToSetter; - } -} -``` - -ही दोन फंक्शन्स `feeSetter` ला शुल्क प्राप्तकर्ता (जर असेल तर) नियंत्रित करण्यास आणि `feeSetter` ला नवीन पत्त्यावर बदलण्यास परवानगी देतात. - -```solidity -UniswapV2ERC20.sol {#UniswapV2ERC20} -``` - -[हा करार](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) ERC-20 लिक्विडिटी टोकन लागू करतो. - -```solidity -हे [OpenZeppelin ERC-20 करार](/developers/tutorials/erc20-annotated-code) सारखेच आहे, म्हणून मी फक्त वेगळा भाग, `permit` कार्यक्षमता स्पष्ट करेन. -``` - -Ethereum वरील व्यवहारांसाठी इथर (ETH) लागते, जे खऱ्या पैशाच्या समतुल्य आहे. तुमच्याकडे ERC-20 टोकन्स असतील पण ETH नसेल, तर तुम्ही व्यवहार पाठवू शकत नाही, त्यामुळे तुम्ही त्यांच्यासोबत काहीही करू शकत नाही. - -```solidity -ही समस्या टाळण्यासाठी एक उपाय म्हणजे [मेटा-ट्रान्झॅक्शन्स](https://docs.uniswap.org/contracts/v2/guides/smart-contract-integration/supporting-meta-transactions). -``` - -टोकनचा मालक एका व्यवहारावर स्वाक्षरी करतो ज्यामुळे दुसऱ्या कोणालातरी ऑफचेन टोकन काढण्याची परवानगी मिळते आणि ते इंटरनेटद्वारे प्राप्तकर्त्याला पाठवतो. प्राप्तकर्ता, ज्याच्याकडे ETH आहे, तो मालकाच्या वतीने परवानगी सादर करतो. - -```solidity - bytes32 public DOMAIN_SEPARATOR; - // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; -``` - -हा हॅश [व्यवहार प्रकारासाठी ओळखकर्ता](https://eips.ethereum.org/EIPS/eip-712#rationale-for-typehash) आहे. - -```solidity -आम्ही येथे फक्त या पॅरामीटर्ससह `Permit` ला समर्थन देतो. -``` - -``` -mapping(address => uint) public nonces; प्राप्तकर्त्यासाठी डिजिटल स्वाक्षरी बनावट करणे शक्य नाही. तथापि, समान व्यवहार दोनदा पाठवणे क्षुल्लक आहे (हा [रिप्ले हल्ला](https://wikipedia.org/wiki/Replay_attack) चा एक प्रकार आहे). -``` - -हे टाळण्यासाठी, आम्ही [नॉन्स](https://wikipedia.org/wiki/Cryptographic_nonce) वापरतो. जर नवीन `Permit` चा नॉन्स शेवटच्या वापरलेल्या नॉन्सपेक्षा एक जास्त नसेल, तर आम्ही ते अवैध मानतो. constructor() public { -uint chainId; -assembly { -chainId := chainid -} हा [चेन आयडेंटिफायर](https://chainid.network/) मिळवण्यासाठी कोड आहे. हे [Yul](https://docs.soliditylang.org/en/v0.8.4/yul.html) नावाच्या EVM असेंब्ली बोलीचा वापर करते. लक्षात घ्या की Yul च्या सध्याच्या आवृत्तीमध्ये तुम्हाला `chainid()` वापरावे लागेल, `chainid` नाही. - -``` - DOMAIN_SEPARATOR = keccak256( - abi.encode( - keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), - keccak256(bytes(name)), - keccak256(bytes('1')), - chainId, - address(this) - ) - ); -``` - -EIP-712 साठी [डोमेन विभाजक](https://eips.ethereum.org/EIPS/eip-712#rationale-for-domainseparator) मोजा. function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { - -```solidity -हे फंक्शन परवानगी लागू करते. -``` - -ते पॅरामीटर्स म्हणून संबंधित फील्ड्स आणि [स्वाक्षरीसाठी](https://yos.io/2018/11/16/ethereum-signatures/) तीन स्केलर मूल्ये (v, r, आणि s) प्राप्त करते. require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); - -. bytes32 digest = keccak256( -abi.encodePacked( -'\x19\x01', -DOMAIN_SEPARATOR, -keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) -) -); `abi.encodePacked(...)` हा संदेश आहे जो आम्हाला मिळण्याची अपेक्षा आहे. - -```solidity -आम्हाला माहित आहे की नॉन्स काय असावे, म्हणून आम्हाला ते पॅरामीटर म्हणून मिळवण्याची गरज नाही. -``` - -Ethereum स्वाक्षरी अल्गोरिदमला स्वाक्षरी करण्यासाठी 256 बिट्सची अपेक्षा असते, म्हणून आम्ही `keccak256` हॅश फंक्शन वापरतो. address recoveredAddress = ecrecover(digest, v, r, s); - -```solidity -डायजेस्ट आणि स्वाक्षरीवरून आपण [ecrecover](https://coders-errand.com/ecrecover-signature-verification-ethereum/) वापरून स्वाक्षरी करणारा पत्ता मिळवू शकतो. -``` - -``` - require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); - _approve(owner, spender, value); -} -``` - -```solidity -जर सर्व काही ठीक असेल, तर याला [ERC-20 approve](https://eips.ethereum.org/EIPS/eip-20#approve) म्हणून समजा. -``` - -परिघ करार {#periphery-contracts} परिघ करार Uniswap साठी API (ॲप्लिकेशन प्रोग्राम इंटरफेस) आहेत. - -```solidity -ते बाह्य कॉल्ससाठी उपलब्ध आहेत, एकतर इतर करारांमधून किंवा विकेंद्रीकृत ॲप्लिकेशन्समधून. -``` - -तुम्ही मुख्य करारांना थेट कॉल करू शकता, परंतु ते अधिक गुंतागुंतीचे आहे आणि तुम्ही चूक केल्यास मूल्य गमावू शकता. मुख्य करारांमध्ये फक्त ते फसवले जात नाहीत याची खात्री करण्यासाठी चाचण्या असतात, इतर कोणासाठीही sanity checks नाहीत. ते परिघामध्ये आहेत जेणेकरून आवश्यकतेनुसार ते अद्यतनित केले जाऊ शकतात. - -```solidity -UniswapV2Router01.sol {#UniswapV2Router01} -``` - -[या करारामध्ये](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router01.sol) समस्या आहेत, आणि [तो आता वापरला जाऊ नये](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-01). सुदैवाने, परिघ करार स्टेटलेस आहेत आणि कोणतीही मालमत्ता ठेवत नाहीत, त्यामुळे त्याला नाकारणे आणि लोकांना त्याऐवजी बदल, `UniswapV2Router02`, वापरण्यास सुचवणे सोपे आहे. UniswapV2Router02.sol {#UniswapV2Router02} - -```solidity -बहुतेक प्रकरणांमध्ये तुम्ही [या कराराद्वारे](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router02.sol) Uniswap वापराल. -``` - -तुम्ही ते कसे वापरायचे ते [येथे](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02) पाहू शकता. - -#### pragma solidity =0.6.6;import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; import '@uniswap/lib/contracts/libraries/TransferHelper.sol';import './interfaces/IUniswapV2Router02.sol'; import './libraries/UniswapV2Library.sol'; import './libraries/SafeMath.sol'; import './interfaces/IERC20.sol'; import './interfaces/IWETH.sol'; - -यापैकी बहुतेक आपण यापूर्वी पाहिले आहेत, किंवा ते बरेच स्पष्ट आहेत. - -```solidity -एक अपवाद `IWETH.sol` आहे. -``` - -Uniswap v2 कोणत्याही ERC-20 टोकनच्या जोडीसाठी एक्सचेंजला परवानगी देतो, परंतु इथर (ETH) स्वतः ERC-20 टोकन नाही. ते मानकापूर्वीचे आहे आणि अद्वितीय यंत्रणेद्वारे हस्तांतरित केले जाते. - -```solidity -ERC-20 टोकनवर लागू होणाऱ्या करारांमध्ये ETH चा वापर सक्षम करण्यासाठी लोकांनी [रॅप्ड इथर (WETH)](https://weth.tkn.eth.limo/) करार आणला. -``` - -तुम्ही या कराराला ETH पाठवता, आणि ते तुम्हाला WETH ची समतुल्य रक्कम मिंट करते. - -```solidity -किंवा तुम्ही WETH बर्न करू शकता, आणि ETH परत मिळवू शकता. -``` - -contract UniswapV2Router02 is IUniswapV2Router02 { -using SafeMath for uint;``` -address public immutable override factory; -address public immutable override WETH; राउटरला माहित असणे आवश्यक आहे की कोणती फॅक्टरी वापरायची, आणि WETH आवश्यक असलेल्या व्यवहारांसाठी कोणता WETH करार वापरायचा. -``` - -```solidity -ही मूल्ये [अपरिवर्तनीय](https://docs.soliditylang.org/en/v0.8.3/contracts.html#constant-and-immutable-state-variables) आहेत, म्हणजे ती फक्त कन्स्ट्रक्टरमध्ये सेट केली जाऊ शकतात. -``` - -यामुळे वापरकर्त्यांना विश्वास मिळतो की कोणीही त्यांना कमी प्रामाणिक करारांकडे निर्देशित करण्यासाठी बदलू शकणार नाही. - -```solidity - modifier ensure(uint deadline) { - require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED'); - _; - } -``` - -हा मॉडिफायर खात्री करतो की वेळेनुसार मर्यादित व्यवहार ("वेळेच्या आत Y करा जर तुम्ही करू शकत असाल तर") त्यांच्या वेळेच्या मर्यादेनंतर होत नाहीत. - -```solidity - constructor(address _factory, address _WETH) public { - factory = _factory; - WETH = _WETH; - } -``` - -कन्स्ट्रक्टर फक्त अपरिवर्तनीय स्टेट व्हेरिएबल्स सेट करतो. - -```solidity - receive() external payable { - assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract - } -``` - -जेव्हा आम्ही WETH करारातून टोकन परत ETH मध्ये रिडीम करतो तेव्हा हे फंक्शन कॉल केले जाते. - -```solidity -फक्त आम्ही वापरत असलेला WETH करारच ते करण्यास अधिकृत आहे. -``` - -लिक्विडिटी जोडा {#add-liquidity} ही फंक्शन्स पेअर एक्सचेंजमध्ये टोकन जोडतात, ज्यामुळे लिक्विडिटी पूल वाढतो. - -```solidity - - // **** ADD LIQUIDITY **** - function _addLiquidity( -``` - -अंतिम कार्य स्टोरेज फी आणि मेटा-ट्रान्झॅक्शन्स एकत्र करते. - -#### ट्रेड {#trade} - -```solidity - // **** स्वॅप **** - // प्रारंभिक रक्कम आधीच पहिल्या जोडीला पाठवली गेली असणे आवश्यक आहे - function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual { -``` - -हे कार्य अंतर्गत प्रक्रिया करते जे ट्रेडर्ससाठी उपलब्ध असलेल्या कार्यांसाठी आवश्यक आहे. - -```solidity - for (uint i; i < path.length - 1; i++) { -``` - -मी हे लिहित असताना [388,160 ERC-20 टोकन्स](https://eth.blockscout.com/tokens) आहेत. प्रत्येक टोकन जोडीसाठी एक पेअर एक्सचेंज असते, तर ते 150 अब्ज पेक्षा जास्त पेअर एक्सचेंज झाले असते. संपूर्ण चेनमध्ये, सध्या, [त्या संख्येच्या केवळ 0.1% खाती आहेत](https://eth.blockscout.com/stats/accountsGrowth). त्याऐवजी, स्वॅप फंक्शन्स पाथच्या संकल्पनेला समर्थन देतात. एक ट्रेडर A ला B साठी, B ला C साठी, आणि C ला D साठी एक्सचेंज करू शकतो, त्यामुळे थेट A-D पेअर एक्सचेंजची गरज नाही. - -या बाजारांमधील किमती सिंक्रोनाइझ (समक्रमित) केल्या जातात, कारण जेव्हा त्या सिंकमध्ये नसतात तेव्हा आर्बिट्रेजसाठी संधी निर्माण होते. उदाहरणार्थ, A, B आणि C या तीन टोकन्सची कल्पना करा. प्रत्येक जोडीसाठी एक, असे तीन पेअर एक्सचेंज आहेत. - -1. सुरुवातीची परिस्थिती -2. एक ट्रेडर 24.695 A टोकन्स विकतो आणि 25.305 B टोकन्स मिळवतो. -3. ट्रेडर 24.695 B टोकन्स 25.305 C टोकन्ससाठी विकतो, आणि अंदाजे 0.61 B टोकन्स नफा म्हणून ठेवतो. -4. मग ट्रेडर 24.695 C टोकन्स 25.305 A टोकन्ससाठी विकतो, आणि अंदाजे 0.61 C टोकन्स नफा म्हणून ठेवतो. ट्रेडरकडे 0.61 अतिरिक्त A टोकन्स देखील आहेत (ट्रेडरला शेवटी मिळालेले 25.305, वजा 24.695 ची मूळ गुंतवणूक). - -| टप्पा | A-B एक्सचेंज | B-C एक्सचेंज | A-C एक्सचेंज | -| ----- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| 1 | A:1000 B:1050 A/B=1.05 | B:1000 C:1050 B/C=1.05 | A:1050 C:1000 C/A=1.05 | -| 2 | A:1024.695 B:1024.695 A/B=1 | B:1000 C:1050 B/C=1.05 | A:1050 C:1000 C/A=1.05 | -| 3 | A:1024.695 B:1024.695 A/B=1 | B:1024.695 C:1024.695 B/C=1 | A:1050 C:1000 C/A=1.05 | -| 4 | A:1024.695 B:1024.695 A/B=1 | B:1024.695 C:1024.695 B/C=1 | A:1024.695 C:1024.695 C/A=1 | - -```solidity - (address input, address output) = (path[i], path[i + 1]); - (address token0,) = UniswapV2Library.sortTokens(input, output); - uint amountOut = amounts[i + 1]; -``` - -आपण सध्या हाताळत असलेली जोडी मिळवा, ती क्रमवारी लावा (जोडीसोबत वापरण्यासाठी) आणि अपेक्षित आउटपुट रक्कम मिळवा. - -```solidity - (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); -``` - -अपेक्षित आउटपुट रक्कम मिळवा, पेअर एक्सचेंजला अपेक्षित असलेल्या पद्धतीने क्रमवारी लावा. - -```solidity - address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; -``` - -हे शेवटचे एक्सचेंज आहे का? तसे असल्यास, ट्रेडसाठी मिळालेले टोकन्स गंतव्यस्थानावर पाठवा. तसे नसल्यास, ते पुढील पेअर एक्सचेंजवर पाठवा. - -```solidity - - IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap( - amount0Out, amount1Out, to, new bytes(0) - ); - } - } -``` - -टोकन्स स्वॅप करण्यासाठी प्रत्यक्षात पेअर एक्सचेंजला कॉल करा. आम्हाला एक्सचेंजबद्दल कळवण्यासाठी कॉलबॅकची आवश्यकता नाही, म्हणून आम्ही त्या फील्डमध्ये कोणतेही बाइट्स पाठवत नाही. - -```solidity - function swapExactTokensForTokens( -``` - -हे कार्य ट्रेडर्सद्वारे थेट एका टोकनला दुसऱ्या टोकनसाठी स्वॅप करण्याकरिता वापरले जाते. - -```solidity - uint amountIn, - uint amountOutMin, - address[] calldata path, -``` - -या पॅरामीटरमध्ये ERC-20 कॉन्ट्रॅक्ट्सचे ॲड्रेस आहेत. वर स्पष्ट केल्याप्रमाणे, ही एक ॲरे आहे कारण तुमच्याकडे असलेल्या मालमत्तेपासून तुम्हाला हव्या असलेल्या मालमत्तेपर्यंत पोहोचण्यासाठी तुम्हाला अनेक पेअर एक्सचेंजेसमधून जावे लागू शकते. - -सॉलिडिटीमधील फंक्शन पॅरामीटर `memory` किंवा `calldata` मध्ये संग्रहित केले जाऊ शकते. जर कार्य कॉन्ट्रॅक्टसाठी एक प्रवेश बिंदू असेल, वापरकर्त्याकडून थेट (ट्रान्झॅक्शन वापरून) किंवा वेगळ्या कॉन्ट्रॅक्टवरून कॉल केले असेल, तर पॅरामीटरचे मूल्य थेट कॉल डेटामधून घेतले जाऊ शकते. जर कार्य अंतर्गतपणे कॉल केले असेल, जसे वरील `_swap`, तर पॅरामीटर्स `memory` मध्ये संग्रहित करणे आवश्यक आहे. कॉल केलेल्या कॉन्ट्रॅक्टच्या दृष्टिकोनातून `calldata` फक्त वाचनीय आहे. - -`uint` किंवा `address` सारख्या स्केलर प्रकारांसह कंपाइलर आमच्यासाठी स्टोरेजची निवड हाताळतो, परंतु ॲरेंसाठी, जे लांब आणि अधिक महाग आहेत, आम्ही वापरल्या जाणाऱ्या स्टोरेजचा प्रकार निर्दिष्ट करतो. - -```solidity - address to, - uint deadline - ) external virtual override ensure(deadline) returns (uint[] memory amounts) { -``` - -परत येणारी मूल्ये नेहमी मेमरीमध्ये परत केली जातात. - -```solidity - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); -``` - -प्रत्येक स्वॅपमध्ये खरेदी करायच्या रकमेची गणना करा. जर परिणाम ट्रेडरने स्वीकारण्यास तयार असलेल्या किमान रकमेपेक्षा कमी असेल, तर ट्रान्झॅक्शनमधून परत या. - -```solidity - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] - ); - _swap(amounts, path, to); - } -``` - -शेवटी, प्रारंभिक ERC-20 टोकन पहिल्या पेअर एक्सचेंजच्या खात्यावर हस्तांतरित करा आणि `_swap` कॉल करा. हे सर्व एकाच ट्रान्झॅक्शनमध्ये घडत आहे, त्यामुळे पेअर एक्सचेंजला माहित आहे की कोणतेही अनपेक्षित टोकन या हस्तांतरणाचा भाग आहेत. - -```solidity - function swapTokensForExactTokens( - uint amountOut, - uint amountInMax, - address[] calldata path, - address to, - uint deadline - ) external virtual override ensure(deadline) returns (uint[] memory amounts) { - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] - ); - _swap(amounts, path, to); - } -``` - -मागील कार्य, `swapTokensForTokens`, एका ट्रेडरला तो देण्यास तयार असलेल्या इनपुट टोकन्सची नेमकी संख्या आणि त्या बदल्यात तो स्वीकारण्यास तयार असलेल्या आउटपुट टोकन्सची किमान संख्या निर्दिष्ट करण्याची परवानगी देते. हे कार्य उलट स्वॅप करते, हे एका ट्रेडरला त्याला हव्या असलेल्या आउटपुट टोकन्सची संख्या आणि त्यासाठी तो देण्यास तयार असलेल्या इनपुट टोकन्सची कमाल संख्या निर्दिष्ट करू देते. - -दोन्ही प्रकरणांमध्ये, ट्रेडरला प्रथम या पेरिफेरी कॉन्ट्रॅक्टला एक भत्ता द्यावा लागतो जेणेकरून ते त्यांना हस्तांतरित करू शकेल. - -```solidity - function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) - external - virtual - override - payable - ensure(deadline) - returns (uint[] memory amounts) - { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); - IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); - _swap(amounts, path, to); - } - - - function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) - external - virtual - override - ensure(deadline) - returns (uint[] memory amounts) - { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] - ); - _swap(amounts, path, address(this)); - IWETH(WETH).withdraw(amounts[amounts.length - 1]); - TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); - } - - - - function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) - external - virtual - override - ensure(deadline) - returns (uint[] memory amounts) - { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); - require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] - ); - _swap(amounts, path, address(this)); - IWETH(WETH).withdraw(amounts[amounts.length - 1]); - TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); - } - - - function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) - external - virtual - override - payable - ensure(deadline) - returns (uint[] memory amounts) - { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); - require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); - IWETH(WETH).deposit{value: amounts[0]}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); - _swap(amounts, path, to); - // डस्ट eth परत करा, जर असेल तर - if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); - } -``` - -हे चार प्रकार ETH आणि टोकन्समध्ये ट्रेड करण्याशी संबंधित आहेत. फरक फक्त एवढाच आहे की आम्ही एकतर ट्रेडरकडून ETH घेतो आणि WETH तयार करण्यासाठी त्याचा वापर करतो, किंवा आम्ही पाथमधील शेवटच्या एक्सचेंजमधून WETH घेतो आणि ते बर्न करतो, आणि ट्रेडरला परिणामी ETH परत पाठवतो. - -```solidity - // **** स्वॅप (फी-ऑन-ट्रान्सफर टोकन्सना समर्थन देणारे) **** - // प्रारंभिक रक्कम आधीच पहिल्या जोडीला पाठवली गेली असणे आवश्यक आहे - function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual { -``` - -हे ट्रान्सफर किंवा स्टोरेज फी असलेल्या टोकन्सना स्वॅप करण्यासाठीचे अंतर्गत कार्य आहे ([ही समस्या](https://github.com/Uniswap/uniswap-interface/issues/835) सोडवण्यासाठी). - -```solidity - for (uint i; i < path.length - 1; i++) { - (address input, address output) = (path[i], path[i + 1]); - (address token0,) = UniswapV2Library.sortTokens(input, output); - IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)); - uint amountInput; - uint amountOutput; - { // स्टॅक खूप खोल त्रुटी टाळण्यासाठी स्कोप - (uint reserve0, uint reserve1,) = pair.getReserves(); - (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); - amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput); - amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); -``` - -ट्रान्सफर फीमुळे प्रत्येक ट्रान्सफरमधून आम्हाला किती मिळेल हे सांगण्यासाठी आम्ही `getAmountsOut` फंक्शनवर अवलंबून राहू शकत नाही (ज्याप्रमाणे आम्ही मूळ `_swap` कॉल करण्यापूर्वी करतो). त्याऐवजी आम्हाला आधी हस्तांतरण करावे लागेल आणि मग आम्हाला किती टोकन्स परत मिळाले हे पाहावे लागेल. - -टीप: सैद्धांतिकदृष्ट्या आपण `_swap` ऐवजी फक्त हे फंक्शन वापरू शकतो, परंतु काही विशिष्ट प्रकरणांमध्ये (उदाहरणार्थ, जर आवश्यक किमान रक्कम पूर्ण करण्यासाठी शेवटी पुरेसे नसल्यामुळे हस्तांतरण परत केले गेले) त्यासाठी जास्त गॅस खर्च येईल. ट्रान्सफर फी टोकन्स खूप दुर्मिळ आहेत, त्यामुळे जरी आपल्याला त्यांना सामावून घेण्याची आवश्यकता असली तरी, सर्व स्वॅप्सना त्यांच्यापैकी किमान एकातून जावे लागेल असे गृहीत धरण्याची गरज नाही. - -```solidity - } - (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); - address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; - pair.swap(amount0Out, amount1Out, to, new bytes(0)); - } - } - - - function swapExactTokensForTokensSupportingFeeOnTransferTokens( - uint amountIn, - uint amountOutMin, - address[] calldata path, - address to, - uint deadline - ) external virtual override ensure(deadline) { - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn - ); - uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); - _swapSupportingFeeOnTransferTokens(path, to); - require( - IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, - 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' - ); - } - - - function swapExactETHForTokensSupportingFeeOnTransferTokens( - uint amountOutMin, - address[] calldata path, - address to, - uint deadline - ) - external - virtual - override - payable - ensure(deadline) - { - require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); - uint amountIn = msg.value; - IWETH(WETH).deposit{value: amountIn}(); - assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn)); - uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); - _swapSupportingFeeOnTransferTokens(path, to); - require( - IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, - 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' - ); - } - - - function swapExactTokensForETHSupportingFeeOnTransferTokens( - uint amountIn, - uint amountOutMin, - address[] calldata path, - address to, - uint deadline - ) - external - virtual - override - ensure(deadline) - { - require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); - TransferHelper.safeTransferFrom( - path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn - ); - _swapSupportingFeeOnTransferTokens(path, address(this)); - uint amountOut = IERC20(WETH).balanceOf(address(this)); - require(amountOut >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); - IWETH(WETH).withdraw(amountOut); - TransferHelper.safeTransferETH(to, amountOut); - } -``` - -हे सामान्य टोकन्ससाठी वापरले जाणारे तेच प्रकार आहेत, परंतु ते त्याऐवजी `_swapSupportingFeeOnTransferTokens` कॉल करतात. - -```solidity - // **** लायब्ररी फंक्शन्स **** - function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) { - return UniswapV2Library.quote(amountA, reserveA, reserveB); - } - - function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) - public - pure - virtual - override - returns (uint amountOut) - { - return UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut); - } - - function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) - public - pure - virtual - override - returns (uint amountIn) - { - return UniswapV2Library.getAmountIn(amountOut, reserveIn, reserveOut); - } - - function getAmountsOut(uint amountIn, address[] memory path) - public - view - virtual - override - returns (uint[] memory amounts) - { - return UniswapV2Library.getAmountsOut(factory, amountIn, path); - } - - function getAmountsIn(uint amountOut, address[] memory path) - public - view - virtual - override - returns (uint[] memory amounts) - { - return UniswapV2Library.getAmountsIn(factory, amountOut, path); - } -} -``` - -ही फंक्शन्स फक्त प्रॉक्सी आहेत जी [UniswapV2Library फंक्शन्स](#uniswapV2library) ला कॉल करतात. - -### UniswapV2Migrator.sol {#UniswapV2Migrator} - -हा कॉन्ट्रॅक्ट जुन्या v1 मधून v2 मध्ये एक्सचेंज स्थलांतरित करण्यासाठी वापरला गेला होता. आता ते स्थलांतरित झाले असल्याने, ते आता संबंधित नाही. - -## लायब्ररी {#libraries} - -[SafeMath लायब्ररी](https://docs.openzeppelin.com/contracts/2.x/api/math) चांगल्या प्रकारे दस्तऐवजीकृत आहे, म्हणून येथे त्याचे दस्तऐवजीकरण करण्याची गरज नाही. - -### गणित {#Math} - -या लायब्ररीमध्ये काही गणिती फंक्शन्स आहेत ज्यांची सामान्यतः Solidity कोडमध्ये आवश्यकता नसते, म्हणून ते भाषेचा भाग नाहीत. - -```solidity -pragma solidity =0.5.16; - -// विविध गणिती क्रिया करण्यासाठी एक लायब्ररी - -library Math { - function min(uint x, uint y) internal pure returns (uint z) { - z = x < y ? x : y; - } - - // बॅबिलोनियन पद्धत (https://wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) - function sqrt(uint y) internal pure returns (uint z) { - if (y > 3) { - z = y; - uint x = y / 2 + 1; -``` - -वर्गमूळापेक्षा जास्त असलेल्या अंदाजाने x सह प्रारंभ करा (हेच कारण आहे की आम्हाला 1-3 ला विशेष प्रकरणे म्हणून हाताळण्याची आवश्यकता आहे). - -```solidity - while (x < z) { - z = x; - x = (y / x + x) / 2; -``` - -एक जवळचा अंदाज मिळवा, मागील अंदाज आणि ज्या संख्येचे वर्गमूळ आपण शोधण्याचा प्रयत्न करत आहोत ती संख्या, मागील अंदाजाने भागून मिळणारी सरासरी. नवीन अंदाज विद्यमान अंदाजापेक्षा कमी होईपर्यंत पुनरावृत्ती करा. अधिक माहितीसाठी, [येथे पहा](https://wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method). - -```solidity - } - } else if (y != 0) { - z = 1; -``` - -आपल्याला शून्याच्या वर्गमूळाची कधीही गरज भासू नये. एक, दोन आणि तीन यांचे वर्गमूळ अंदाजे एक आहे (आपण पूर्णांक वापरतो, म्हणून आपण अपूर्णांकाकडे दुर्लक्ष करतो). - -```solidity - } - } -} -``` - -### फिक्स्ड पॉईंट फ्रॅक्शन्स (UQ112x112) {#FixedPoint} - -ही लायब्ररी अपूर्णांक हाताळते, जे सामान्यतः Ethereum अंकगणिताचा भाग नाहीत. हे _x_ या संख्येला _x\*2^112_ म्हणून एन्कोड करून करते. हे आपल्याला मूळ बेरीज आणि वजाबाकी ऑपकोड्समध्ये बदल न करता वापरण्याची परवानगी देते. - -```solidity -pragma solidity =0.5.16; - -// बायनरी फिक्स्ड पॉईंट संख्या हाताळण्यासाठी एक लायब्ररी (https://wikipedia.org/wiki/Q_(number_format)) - -// श्रेणी: [0, 2**112 - 1] -// रिझोल्यूशन: 1 / 2**112 - -library UQ112x112 { - uint224 constant Q112 = 2**112; -``` - -`Q112` हे एक साठी एन्कोडिंग आहे. - -```solidity - // uint112 ला UQ112x112 म्हणून एन्कोड करा - function encode(uint112 y) internal pure returns (uint224 z) { - z = uint224(y) * Q112; // कधीही ओव्हरफ्लो होत नाही - } -``` - -कारण y हे `uint112` आहे, ते जास्तीत जास्त 2^112-1 असू शकते. ती संख्या अजूनही `UQ112x112` म्हणून एन्कोड केली जाऊ शकते. - -```solidity - // UQ112x112 ला uint112 ने भागा, UQ112x112 परत करा - function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { - z = x / uint224(y); - } -} -``` - -जर आपण दोन `UQ112x112` मूल्यांना भागले, तर परिणाम 2^112 ने गुणला जात नाही. म्हणून त्याऐवजी आपण भाजकासाठी एक पूर्णांक घेतो. गुणाकार करण्यासाठी आम्हाला अशीच युक्ती वापरावी लागली असती, परंतु आम्हाला `UQ112x112` मूल्यांचा गुणाकार करण्याची आवश्यकता नाही. - -### UniswapV2Library {#uniswapV2library} - -ही लायब्ररी केवळ पेरिफेरी कॉन्ट्रॅक्ट्सद्वारे वापरली जाते. - -```solidity -pragma solidity >=0.5.0; - -import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; - -import "./SafeMath.sol"; - -library UniswapV2Library { - using SafeMath for uint; - - // क्रमवारी लावलेले टोकन पत्ते परत करते, या क्रमाने क्रमवारी लावलेल्या जोड्यांमधून परत येणारी मूल्ये हाताळण्यासाठी वापरले जाते - function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { - require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); - (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); - require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); - } -``` - -दोन टोकन्सना ॲड्रेसनुसार क्रमवारी लावा, म्हणजे आपल्याला त्यांच्यासाठी पेअर एक्सचेंजचा ॲड्रेस मिळू शकेल. हे आवश्यक आहे कारण अन्यथा आमच्याकडे दोन शक्यता असतील, एक A,B पॅरामीटर्ससाठी आणि दुसरी B,A पॅरामीटर्ससाठी, ज्यामुळे एकाऐवजी दोन एक्सचेंज होतील. - -```solidity - // कोणत्याही बाह्य कॉल न करता जोडीसाठी CREATE2 ॲड्रेसची गणना करते - function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { - (address token0, address token1) = sortTokens(tokenA, tokenB); - pair = address(uint(keccak256(abi.encodePacked( - hex'ff', - factory, - keccak256(abi.encodePacked(token0, token1)), - hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init कोड हॅश - )))); - } -``` - -हे फंक्शन दोन टोकन्ससाठी पेअर एक्सचेंजच्या ॲड्रेसची गणना करते. हा कॉन्ट्रॅक्ट [CREATE2 ऑपकोड](https://eips.ethereum.org/EIPS/eip-1014) वापरून तयार केला आहे, त्यामुळे जर आम्हाला ते वापरत असलेले पॅरामीटर्स माहित असतील तर आम्ही त्याच अल्गोरिदमचा वापर करून ॲड्रेसची गणना करू शकतो. हे फॅक्टरीला विचारण्यापेक्षा खूपच स्वस्त आहे, आणि - -```solidity - // एका जोडीसाठी राखीव निधी मिळवते आणि क्रमवारी लावते - function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { - (address token0,) = sortTokens(tokenA, tokenB); - (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves(); - (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); - } -``` - -हे फंक्शन पेअर एक्सचेंजकडे असलेल्या दोन टोकन्सचा राखीव निधी परत करते. लक्षात घ्या की ते टोकन्स कोणत्याही क्रमाने प्राप्त करू शकते, आणि अंतर्गत वापरासाठी त्यांची क्रमवारी लावते. - -```solidity - // मालमत्तेची काही रक्कम आणि जोडीचा राखीव निधी दिल्यास, दुसऱ्या मालमत्तेची समतुल्य रक्कम परत करते - function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { - require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); - require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); - amountB = amountA.mul(reserveB) / reserveA; - } -``` - -हे फंक्शन तुम्हाला टोकन A च्या बदल्यात मिळणाऱ्या टोकन B ची रक्कम देते, जर त्यात कोणतेही शुल्क सामील नसेल. ही गणना विचारात घेते की हस्तांतरणामुळे विनिमय दर बदलतो. - -```solidity - // मालमत्तेची इनपुट रक्कम आणि जोडीचा राखीव निधी दिल्यास, दुसऱ्या मालमत्तेची कमाल आउटपुट रक्कम परत करते - function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { -``` - -वरील `quote` फंक्शन उत्तम काम करते, जर पेअर एक्सचेंज वापरण्यासाठी कोणतेही शुल्क नसेल. तथापि, जर 0.3% एक्सचेंज शुल्क असेल तर तुम्हाला मिळणारी रक्कम कमी असते. हे फंक्शन एक्सचेंज फी नंतरच्या रकमेची गणना करते. - -```solidity - - require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); - require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); - uint amountInWithFee = amountIn.mul(997); - uint numerator = amountInWithFee.mul(reserveOut); - uint denominator = reserveIn.mul(1000).add(amountInWithFee); - amountOut = numerator / denominator; - } -``` - -Solidity मूळतः अपूर्णांक हाताळत नाही, म्हणून आपण फक्त रकमेला 0.997 ने गुणू शकत नाही. त्याऐवजी, आम्ही अंशाला 997 ने आणि भाजकाला 1000 ने गुणतो, ज्यामुळे तोच परिणाम साधला जातो. - -```solidity - // मालमत्तेची आउटपुट रक्कम आणि जोडीचा राखीव निधी दिल्यास, दुसऱ्या मालमत्तेची आवश्यक इनपुट रक्कम परत करते - function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { - require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); - require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); - uint numerator = reserveIn.mul(amountOut).mul(1000); - uint denominator = reserveOut.sub(amountOut).mul(997); - amountIn = (numerator / denominator).add(1); - } -``` - -हे फंक्शन अंदाजे तेच काम करते, परंतु ते आउटपुट रक्कम मिळवते आणि इनपुट प्रदान करते. - -```solidity - - // कोणत्याही संख्येच्या जोड्यांवर साखळी getAmountOut गणना करते - function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { - require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); - amounts = new uint[](path.length); - amounts[0] = amountIn; - for (uint i; i < path.length - 1; i++) { - (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); - amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); - } - } - - // कोणत्याही संख्येच्या जोड्यांवर साखळी getAmountIn गणना करते - function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { - require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); - amounts = new uint[](path.length); - amounts[amounts.length - 1] = amountOut; - for (uint i = path.length - 1; i > 0; i--) { - (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); - amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); - } - } -} -``` - -ही दोन फंक्शन्स मूल्ये ओळखण्याचे काम करतात, जेव्हा अनेक पेअर एक्सचेंजेसमधून जाणे आवश्यक असते. - -### ट्रान्सफर हेल्पर {#transfer-helper} - -[ही लायब्ररी](https://github.com/Uniswap/uniswap-lib/blob/master/contracts/libraries/TransferHelper.sol) ERC-20 आणि Ethereum ट्रान्सफरभोवती यशस्वी तपासणी जोडते, जेणेकरून रिव्हर्ट आणि `false` मूल्य परत येण्यास एकाच प्रकारे हाताळता येईल. - -```solidity -// SPDX-License-Identifier: GPL-3.0-or-later - -pragma solidity >=0.6.0; - -// ERC20 टोकन्सशी संवाद साधण्यासाठी आणि ETH पाठवण्यासाठी मदतनीस पद्धती जे सातत्याने खरे/खोटे परत करत नाहीत -library TransferHelper { - function safeApprove( - address token, - address to, - uint256 value - ) internal { - // bytes4(keccak256(bytes('approve(address,uint256)'))); - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); - -``` - -आपण वेगळ्या कॉन्ट्रॅक्टला दोनपैकी एका प्रकारे कॉल करू शकतो: - -- फंक्शन कॉल तयार करण्यासाठी इंटरफेस व्याख्या वापरा -- कॉल तयार करण्यासाठी [ऍप्लिकेशन बायनरी इंटरफेस (ABI)](https://docs.soliditylang.org/en/v0.8.3/abi-spec.html) "मॅन्युअली" वापरा. कोडच्या लेखकाने हेच करण्याचे ठरवले. - -```solidity - require( - success && (data.length == 0 || abi.decode(data, (bool))), - 'TransferHelper::safeApprove: approve failed' - ); - } -``` - -ERC-20 मानकापूर्वी तयार केलेल्या टोकनसह बॅकवर्ड सुसंगततेसाठी, ERC-20 कॉल एकतर रिव्हर्ट होऊन अयशस्वी होऊ शकतो (या प्रकरणात `success` `false` असते) किंवा यशस्वी होऊन `false` मूल्य परत करून (या प्रकरणात आउटपुट डेटा असतो, आणि जर तुम्ही ते बुलियन म्हणून डीकोड केले तर तुम्हाला `false` मिळते). - -```solidity - - - function safeTransfer( - address token, - address to, - uint256 value - ) internal { - // bytes4(keccak256(bytes('transfer(address,uint256)'))); - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); - require( - success && (data.length == 0 || abi.decode(data, (bool))), - 'TransferHelper::safeTransfer: transfer failed' - ); - } -``` - -हे फंक्शन [ERC-20 ची ट्रान्सफर कार्यक्षमता](https://eips.ethereum.org/EIPS/eip-20#transfer) लागू करते, जे एका खात्याला दुसऱ्या खात्याने प्रदान केलेला भत्ता खर्च करण्याची परवानगी देते. - -```solidity - - function safeTransferFrom( - address token, - address from, - address to, - uint256 value - ) internal { - // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); - (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); - require( - success && (data.length == 0 || abi.decode(data, (bool))), - 'TransferHelper::transferFrom: transferFrom failed' - ); - } -``` - -हे फंक्शन [ERC-20 ची transferFrom कार्यक्षमता](https://eips.ethereum.org/EIPS/eip-20#transferfrom) लागू करते, जे एका खात्याला दुसऱ्या खात्याने प्रदान केलेला भत्ता खर्च करण्याची परवानगी देते. - -```solidity - - function safeTransferETH(address to, uint256 value) internal { - (bool success, ) = to.call{value: value}(new bytes(0)); - require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); - } -} -``` - -हे फंक्शन एका खात्यात ईथर हस्तांतरित करते. वेगळ्या कॉन्ट्रॅक्टला केलेला कोणताही कॉल ईथर पाठवण्याचा प्रयत्न करू शकतो. कारण आम्हाला प्रत्यक्षात कोणतेही फंक्शन कॉल करण्याची गरज नाही, आम्ही कॉलसोबत कोणताही डेटा पाठवत नाही. - -## निष्कर्ष {#conclusion} - -हा सुमारे 50 पानांचा एक लांब लेख आहे. तुम्ही इथपर्यंत पोहोचलात तर, अभिनंदन! आशा आहे की आतापर्यंत तुम्हाला वास्तविक जीवनातील ॲप्लिकेशन लिहिण्यातील विचार (लहान नमुना कार्यक्रमांच्या विपरीत) समजले असतील आणि तुमच्या स्वतःच्या वापराच्या प्रकरणांसाठी कॉन्ट्रॅक्ट लिहिण्यास अधिक सक्षम आहात. - -आता जा आणि काहीतरी उपयुक्त लिहा आणि आम्हाला चकित करा. - -[माझ्या कामाबद्दल अधिक माहितीसाठी येथे पहा](https://cryptodocguy.pro/). diff --git a/public/content/translations/mr/developers/tutorials/using-websockets/index.md b/public/content/translations/mr/developers/tutorials/using-websockets/index.md index 04ae738b218..85213ca869e 100644 --- a/public/content/translations/mr/developers/tutorials/using-websockets/index.md +++ b/public/content/translations/mr/developers/tutorials/using-websockets/index.md @@ -3,7 +3,7 @@ title: "WebSockets वापरणे" description: "JSON-RPC विनंत्या करण्यासाठी आणि इव्हेंटसाठी सदस्यत्व घेण्यासाठी WebSockets आणि Alchemy वापरण्याकरिता मार्गदर्शक." author: "Elan Halpern" lang: mr -tags: [ "alchemy", "websockets", "querying", "javascript" ] +tags: [ "Alchemy", "websockets", "querying", "JavaScript" ] skill: beginner source: Alchemy docs sourceUrl: https://www.alchemy.com/docs/reference/best-practices-for-using-websockets-in-web3 diff --git a/public/content/translations/mr/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md b/public/content/translations/mr/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md index b64d523f92b..162274b1a7d 100644 --- a/public/content/translations/mr/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md +++ b/public/content/translations/mr/developers/tutorials/waffle-dynamic-mocking-and-testing-calls/index.md @@ -32,7 +32,7 @@ published: 2020-11-14 डायनॅमिक मॉकिंग उपयुक्त का आहे? बरं, ते आपल्याला इंटिग्रेशन टेस्ट्सऐवजी युनिट टेस्ट्स लिहिण्याची परवानगी देते. याचा अर्थ काय? याचा अर्थ असा आहे की आपल्याला स्मार्ट कॉन्ट्रॅक्टच्या अवलंबनांबद्दल (dependencies) काळजी करण्याची गरज नाही, त्यामुळे आपण त्या सर्वांची पूर्णपणे वेगळे ठेवून चाचणी घेऊ शकतो. तुम्ही हे नक्की कसे करू शकता, हे मी तुम्हाला दाखवतो. -### **१.** प्रोजेक्ट\*\* {#1-project} +### **१. प्रोजेक्ट** {#1-project} सुरू करण्यापूर्वी, आपल्याला एक साधा node.js प्रोजेक्ट तयार करणे आवश्यक आहे: @@ -71,7 +71,7 @@ npm install ethereum-waffle ethers --save-dev └── test ``` -### **२.** स्मार्ट कॉन्ट्रॅक्ट\*\* {#2-smart-contract} +### **२. स्मार्ट कॉन्ट्रॅक्ट** {#2-smart-contract} डायनॅमिक मॉकिंग सुरू करण्यासाठी, आपल्याला अवलंबित्व (dependencies) असलेल्या स्मार्ट कॉन्ट्रॅक्टची आवश्यकता आहे. काळजी करू नका, मी सर्व तयारी केली आहे! @@ -120,7 +120,7 @@ npx waffle सोपे आहे, नाही का? `build/` फोल्डरमध्ये कॉन्ट्रॅक्ट आणि इंटरफेसशी संबंधित दोन फाइल्स दिसू लागल्या. चाचणीसाठी आपण त्यांचा वापर नंतर करणार आहोत. -### **३.** चाचणी\*\* {#3-testing} +### **३. चाचणी** {#3-testing} प्रत्यक्ष चाचणीसाठी `AmIRichAlready.test.ts` नावाची फाइल तयार करूया. सर्वप्रथम, आपल्याला इम्पोर्ट्स हाताळावे लागतील. आपल्याला नंतर त्यांची आवश्यकता असेल: diff --git a/public/content/translations/mr/energy-consumption/index.md b/public/content/translations/mr/energy-consumption/index.md index 2fdc698e59b..08d92f0d826 100644 --- a/public/content/translations/mr/energy-consumption/index.md +++ b/public/content/translations/mr/energy-consumption/index.md @@ -6,7 +6,7 @@ lang: mr # Ethereum चा ऊर्जा खर्च {#proof-of-stake-energy} -इथरियम एक हिरवा ब्लॉकचेन आहे. Ethereum ची [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos) सहमती यंत्रणा [नेटवर्क सुरक्षित करण्यासाठी ऊर्जेऐवजी](/developers/docs/consensus-mechanisms/pow) ETH वापरते. संपूर्ण जागतिक नेटवर्कवर Ethereum चा ऊर्जेचा वापर अंदाजे [~0.0026 TWh/yr](https://carbon-ratings.com/eth-report-2022) आहे. +इथरियम एक हिरवा ब्लॉकचेन आहे. Ethereum ची [प्रूफ-ऑफ-स्टेक](/developers/docs/consensus-mechanisms/pos) सहमती यंत्रणा [नेटवर्क सुरक्षित करण्यासाठी ऊर्जेऐवजी](/developers/docs/consensus-mechanisms/pow) ETH वापरते. संपूर्ण जागतिक नेटवर्कवर Ethereum चा ऊर्जेचा वापर अंदाजे [\~0.0026 TWh/yr](https://carbon-ratings.com/eth-report-2022) आहे. Ethereum साठी ऊर्जेच्या वापराचा अंदाज [CCRI (Crypto Carbon Ratings Institute)](https://carbon-ratings.com) च्या अभ्यासातून आला आहे. त्यांनी Ethereum नेटवर्कच्या विजेच्या वापराचे आणि कार्बन फूटप्रिंटचे बॉटम-अप अंदाज तयार केले ([अहवाल पहा](https://carbon-ratings.com/eth-report-2022)). त्यांनी विविध हार्डवेअर आणि क्लायंट सॉफ्टवेअर कॉन्फिगरेशनसह वेगवेगळ्या नोड्सचा वीज वापर मोजला. नेटवर्कच्या वार्षिक वीज वापरासाठी अंदाजित **2,601 MWh** (0.0026 TWh) हे प्रादेशिक-विशिष्ट कार्बन तीव्रता घटक लागू केल्यावर **870 टन CO2e** च्या वार्षिक कार्बन उत्सर्जनाशी संबंधित आहे. जेव्हा नोड्स नेटवर्कमध्ये प्रवेश करतात आणि बाहेर पडतात तेव्हा हे मूल्य बदलते - आपण [Cambridge Blockchain network Sustainability Index](https://ccaf.io/cbnsi/ethereum) द्वारे 7-दिवसांच्या सरासरी अंदाजाचा वापर करून याचा मागोवा ठेवू शकता (लक्षात घ्या की ते त्यांच्या अंदाजांसाठी थोडी वेगळी पद्धत वापरतात - तपशील त्यांच्या साइटवर उपलब्ध आहेत). diff --git a/public/content/translations/mr/nft/index.md b/public/content/translations/mr/nft/index.md index edb1ce858ce..ae62c092618 100644 --- a/public/content/translations/mr/nft/index.md +++ b/public/content/translations/mr/nft/index.md @@ -46,7 +46,7 @@ NFT चा वापर अनेक गोष्टींसाठी केल - तुम्ही कोर्स पूर्ण केल्याचे प्रमाणित करा - खेळांसाठी मालकीच्या वस्तू - डिजिटल कला -- वास्तविक-जगातील मालमत्ता टोकन करणे +- [वास्तविक-जगातील मालमत्ता](/real-world-assets/) टोकन करणे - आपली ऑनलाइन ओळख सिद्ध करणे - सामग्रीमध्ये प्रवेश करणे - तिकीट @@ -67,7 +67,7 @@ NFT चा वापर अनेक गोष्टींसाठी केल किंवा एखाद्या क्रीडा स्पर्धेसाठी तिकीट विचारात घ्या. ज्याप्रमाणे एखाद्या **कार्यक्रमाचा आयोजक किती तिकिटे विकायची हे निवडू शकतो**, त्याचप्रमाणे NFT चा निर्माता किती प्रतिकृती अस्तित्वात असतील हे ठरवू शकतो. काहीवेळा या अचूक प्रतिकृती असतात, जसे की 5000 सामान्य प्रवेश तिकिटे. काहीवेळा पुष्कळ टकसाळ असतात जे अगदी सारखे असतात, परंतु प्रत्येक थोडे वेगळे असते, जसे की नियुक्त केलेल्या सीटसह तिकीट. हे तिकिट हाताळणाऱ्यांना पैसे न देता पीअर-टू-पीअर खरेदी आणि विक्री करता येतात आणि खरेदीदार नेहमी कराराचा पत्ता तपासून तिकिटाच्या सत्यतेची खात्री देतो. -ethereum.org वर, **लोकांनी आमच्या Github रेपॉजिटरीमध्ये अर्थपूर्ण योगदान दिले आहे हे दाखवण्यासाठी NFT वापरले जातात** (वेबसाइट प्रोग्रॅम केली, एखादा लेख लिहिला किंवा सुधारित केला...), आमच्या कंटेंटचे भाषांतर केले, किंवा आमच्या कम्युनिटी कॉल्समध्ये उपस्थित राहिले, आणि आमच्याकडे आमचे स्वतःचे NFT डोमेन नाव देखील आहे. तुम्ही ethereum.org मध्ये योगदान दिल्यास, तुम्ही [POAP](/glossary/#poap) NFT चा दावा करू शकता. काही क्रिप्टो मीटअप्सनी POAP चा तिकीट म्हणून वापर केला आहे. [योगदानाबद्दल अधिक](/contributing/#poap). +ethereum.org वर, **लोकांनी आमच्या GitHub रेपॉजिटरीमध्ये अर्थपूर्ण योगदान दिले आहे हे दाखवण्यासाठी NFT वापरले जातात** (वेबसाइट प्रोग्रॅम केली, एखादा लेख लिहिला किंवा सुधारित केला...), आमच्या कंटेंटचे भाषांतर केले, किंवा आमच्या कम्युनिटी कॉल्समध्ये उपस्थित राहिले, आणि आमच्याकडे आमचे स्वतःचे NFT डोमेन नाव देखील आहे. तुम्ही ethereum.org मध्ये योगदान दिल्यास, तुम्ही [POAP](/glossary/#poap) NFT चा दावा करू शकता. काही क्रिप्टो मीटअप्सनी POAP चा तिकीट म्हणून वापर केला आहे. [योगदानाबद्दल अधिक](/contributing/#poap). तुम्ही कम्युनिटी अचीव्हमेंट NFT पाहण्यासाठी आमचे [ethereum.org कलेक्टिबल्स](/collectibles/) पृष्ठ देखील एक्सप्लोर करू शकता. ![ethereum.org POAP](./poap.png) diff --git a/public/content/translations/mr/payments/index.md b/public/content/translations/mr/payments/index.md index d93cf08d140..4995d872394 100644 --- a/public/content/translations/mr/payments/index.md +++ b/public/content/translations/mr/payments/index.md @@ -27,7 +27,7 @@ summaryPoint3: "एका मिनिटात देयके प्राप परदेशात काम करणाऱ्या लाखो लोकांसाठी, घरी पैसे पाठवणे ही एक नियमित गरज आहे. पारंपारिक रेमिटन्स सेवांमध्ये अनेकदा जास्त शुल्क आणि हळू प्रक्रिया वेळ असतो. इथेरियम एक आकर्षक पर्याय सादर करते. - + diff --git a/public/content/translations/mr/restaking/index.md b/public/content/translations/mr/restaking/index.md index 6f4eec8bfa1..7b67f61e66c 100644 --- a/public/content/translations/mr/restaking/index.md +++ b/public/content/translations/mr/restaking/index.md @@ -19,7 +19,7 @@ buttons: Ethereum नेटवर्क 24/7, 365 अब्जावधी डॉलर्सच्या मूल्याला सुरक्षित करते. कसे? -जगभरातील लोक Ethereum व्यवहार प्रक्रिया करणारे आणि Ethereum नेटवर्क सुरक्षित करणारे सॉफ्टवेअर चालवण्यासाठी स्मार्ट कॉन्ट्रॅक्टमध्ये [ईथर (ETH)](/eth/) लॉक करतात (किंवा 'स्टेक' करतात). त्या बदल्यात, त्यांना अधिक ETH चे रिवॉर्ड्स मिळतात. +जगभरातील लोक Ethereum व्यवहार प्रक्रिया करणारे आणि Ethereum नेटवर्क सुरक्षित करणारे सॉफ्टवेअर चालवण्यासाठी स्मार्ट कॉन्ट्रॅक्टमध्ये [ईथर (ETH)](/what-is-ether/) लॉक करतात (किंवा 'स्टेक' करतात). त्या बदल्यात, त्यांना अधिक ETH चे रिवॉर्ड्स मिळतात. रिस्टेकिंग हे [स्टेकर्स](/staking/) साठी तयार केलेले एक तंत्रज्ञान आहे जे ही सुरक्षा इतर सेवा, ॲप्लिकेशन्स किंवा नेटवर्कपर्यंत विस्तारित करते. त्या बदल्यात, ते अतिरिक्त रिस्टेकिंग रिवॉर्ड्स मिळवतात. तथापि, ते त्यांच्या स्टेक केलेल्या ETH ला अधिक धोक्यात टाकतात. diff --git a/public/content/translations/mr/roadmap/fusaka/index.md b/public/content/translations/mr/roadmap/fusaka/index.md index 1de259ea4cb..2d3464d6513 100644 --- a/public/content/translations/mr/roadmap/fusaka/index.md +++ b/public/content/translations/mr/roadmap/fusaka/index.md @@ -26,7 +26,7 @@ lang: mr हा फुसाका फोर्कचा _हेडलाइनर_ आहे, या अपग्रेडमध्ये जोडलेले मुख्य वैशिष्ट्य. लेअर 2s सध्या त्यांचा डेटा इथेरियमवर ब्लॉब्समध्ये पोस्ट करतात, हा एक अल्पायुषी डेटा प्रकार आहे जो विशेषतः लेअर 2s साठी तयार केला आहे. फुसाका-पूर्वी, डेटा अस्तित्वात असल्याची खात्री करण्यासाठी प्रत्येक पूर्ण नोडला प्रत्येक ब्लॉब साठवून ठेवावा लागतो. जसजसा ब्लॉब थ्रूपुट वाढतो, तसतसा हा सर्व डेटा डाउनलोड करणे असह्यपणे संसाधन-केंद्रित बनते. -[डेटा उपलब्धता सॅम्पलिंग](https://notes.ethereum.org/@fradamt/das-fork-choice) सह, सर्व ब्लॉब डेटा साठवण्याऐवजी, प्रत्येक नोड ब्लॉब डेटाच्या उपसंचासाठी जबाबदार असेल. ब्लॉब्स नेटवर्कमधील नोड्सवर समान रीतीने यादृच्छिकपणे वितरित केले जातात, प्रत्येक पूर्ण नोड फक्त 1/8 डेटा धारण करतो, त्यामुळे सैद्धांतिकरित्या 8x पर्यंत स्केल करणे शक्य होते. डेटाची उपलब्धता सुनिश्चित करण्यासाठी, डेटाचा कोणताही भाग संपूर्ण डेटाच्या विद्यमान 50% भागातून अशा पद्धतींनी पुनर्रचित केला जाऊ शकतो ज्यामुळे चुकीच्या किंवा गहाळ डेटाची संभाव्यता क्रिप्टोग्राफिकदृष्ट्या नगण्य पातळीवर (~1020 मध्ये एक ते 1024 मध्ये एक) कमी होते. +[डेटा उपलब्धता सॅम्पलिंग](https://notes.ethereum.org/@fradamt/das-fork-choice) सह, सर्व ब्लॉब डेटा साठवण्याऐवजी, प्रत्येक नोड ब्लॉब डेटाच्या उपसंचासाठी जबाबदार असेल. ब्लॉब्स नेटवर्कमधील नोड्सवर समान रीतीने यादृच्छिकपणे वितरित केले जातात, प्रत्येक पूर्ण नोड फक्त 1/8 डेटा धारण करतो, त्यामुळे सैद्धांतिकरित्या 8x पर्यंत स्केल करणे शक्य होते. डेटाची उपलब्धता सुनिश्चित करण्यासाठी, डेटाचा कोणताही भाग संपूर्ण डेटाच्या विद्यमान 50% भागातून अशा पद्धतींनी पुनर्रचित केला जाऊ शकतो ज्यामुळे चुकीच्या किंवा गहाळ डेटाची संभाव्यता क्रिप्टोग्राफिकदृष्ट्या नगण्य पातळीवर (\~1020 मध्ये एक ते 1024 मध्ये एक) कमी होते. हे नोड्ससाठी हार्डवेअर आणि बँडविड्थ आवश्यकता टिकवून ठेवते, तसेच ब्लॉब स्केलिंग सक्षम करते, ज्यामुळे लेअर 2s साठी कमी शुल्कासह अधिक स्केल मिळतो. @@ -187,7 +187,7 @@ UX अपग्रेड! वापरकर्त्यांसाठी, ह ### हे अपग्रेड सर्व इथेरियम नोड्स आणि व्हॅलिडेटर्सवर परिणाम करते का? {#does-this-upgrade-affect-all-ethereum-nodes-and-validators} -होय, फुसाका अपग्रेडसाठी [एक्झिक्यूशन क्लायंट आणि कन्सेन्सस क्लायंट](/developers/docs/nodes-and-clients/) दोन्हीमध्ये अपडेट्स आवश्यक आहेत. सर्व प्रमुख इथेरियम क्लायंट उच्च प्राधान्य म्हणून चिन्हांकित हार्ड फोर्कला समर्थन देणाऱ्या आवृत्त्या रिलीज करतील. हे प्रकाशन क्लायंट Github रेपॉजिटरीज, त्यांचे [डिस्कॉर्ड चॅनेल्स](https://ethstaker.org/support), [EthStaker डिस्कॉर्ड](https://dsc.gg/ethstaker) मध्ये कधी उपलब्ध होतील याची माहिती तुम्ही ठेवू शकता, किंवा प्रोटोकॉल अपडेट्ससाठी इथेरियम ब्लॉगची सदस्यता घेऊ शकता. अपग्रेडनंतर इथेरियम नेटवर्कसोबत सिंक्रोनाइझेशन राखण्यासाठी, नोड ऑपरेटरने ते समर्थित क्लायंट आवृत्ती चालवत असल्याची खात्री करणे आवश्यक आहे. लक्षात घ्या की क्लायंट रिलीजची माहिती वेळेनुसार बदलणारी आहे आणि वापरकर्त्यांनी सर्वात सध्याच्या तपशिलांसाठी नवीनतम अपडेट्सचा संदर्भ घ्यावा. +होय, फुसाका अपग्रेडसाठी [एक्झिक्यूशन क्लायंट आणि कन्सेन्सस क्लायंट](/developers/docs/nodes-and-clients/) दोन्हीमध्ये अपडेट्स आवश्यक आहेत. सर्व प्रमुख इथेरियम क्लायंट उच्च प्राधान्य म्हणून चिन्हांकित हार्ड फोर्कला समर्थन देणाऱ्या आवृत्त्या रिलीज करतील. हे प्रकाशन क्लायंट GitHub रेपॉजिटरीज, त्यांचे [डिस्कॉर्ड चॅनेल्स](https://ethstaker.org/support), [EthStaker डिस्कॉर्ड](https://dsc.gg/ethstaker) मध्ये कधी उपलब्ध होतील याची माहिती तुम्ही ठेवू शकता, किंवा प्रोटोकॉल अपडेट्ससाठी इथेरियम ब्लॉगची सदस्यता घेऊ शकता. अपग्रेडनंतर इथेरियम नेटवर्कसोबत सिंक्रोनाइझेशन राखण्यासाठी, नोड ऑपरेटरने ते समर्थित क्लायंट आवृत्ती चालवत असल्याची खात्री करणे आवश्यक आहे. लक्षात घ्या की क्लायंट रिलीजची माहिती वेळेनुसार बदलणारी आहे आणि वापरकर्त्यांनी सर्वात सध्याच्या तपशिलांसाठी नवीनतम अपडेट्सचा संदर्भ घ्यावा. ### हार्ड फोर्कनंतर ETH चे रूपांतर कसे केले जाऊ शकते? {#how-can-eth-be-converted-after-the-hardfork} diff --git a/public/content/translations/mr/roadmap/fusaka/peerdas/index.md b/public/content/translations/mr/roadmap/fusaka/peerdas/index.md index 9ada5141728..59efa78aff5 100644 --- a/public/content/translations/mr/roadmap/fusaka/peerdas/index.md +++ b/public/content/translations/mr/roadmap/fusaka/peerdas/index.md @@ -12,7 +12,7 @@ lang: mr ## स्केलेबिलिटी {#scalability} -इथेरियमचे ध्येय एक तटस्थ, सुरक्षित आणि विकेंद्रित प्लॅटफॉर्म बनणे आहे जो जगातील प्रत्येकासाठी उपलब्ध असेल. नेटवर्कचा वापर जसजसा वाढत जातो, तसतसे नेटवर्कच्या स्केल, सुरक्षा आणि विकेंद्रीकरण या त्रिसंकटात संतुलन साधणे आवश्यक असते. जर इथेरियमने आपल्या सध्याच्या डिझाइनमध्ये नेटवर्कद्वारे हाताळला जाणारा डेटा वाढवला, तर ते [/developers/docs/nodes-and-clients/ इथेरियम ज्या नोड्सवर विकेंद्रीकरणासाठी अवलंबून आहे] त्यांना ओव्हरलोड करण्याचा धोका पत्करेल. स्केलेबिलिटीसाठी कठोर यंत्रणा डिझाइन आवश्यक आहे जे तडजोडी कमी करते. +[इथेरियमचे ध्येय एक तटस्थ, सुरक्षित आणि विकेंद्रित प्लॅटफॉर्म बनणे आहे जो जगातील प्रत्येकासाठी उपलब्ध असेल. नेटवर्कचा वापर जसजसा वाढत जातो, तसतसे नेटवर्कच्या स्केल, सुरक्षा आणि विकेंद्रीकरण या त्रिसंकटात संतुलन साधणे आवश्यक असते. जर इथेरियमने आपल्या सध्याच्या डिझाइनमध्ये नेटवर्कद्वारे हाताळला जाणारा डेटा वाढवला, तर ते [इथेरियम ज्या नोड्सवर विकेंद्रीकरणासाठी अवलंबून आहे](/developers/docs/nodes-and-clients/) त्यांना ओव्हरलोड करण्याचा धोका पत्करेल. स्केलेबिलिटीसाठी कठोर यंत्रणा डिझाइन आवश्यक आहे जे तडजोडी कमी करते. हे ध्येय साध्य करण्याच्या धोरणांपैकी एक म्हणजे [लेयर 1 (L1)](/glossary/#layer-1) मेननेटवर सर्व व्यवहारांवर प्रक्रिया करण्याऐवजी लेयर 2 स्केलिंग सोल्यूशन्सच्या विविध इकोसिस्टमला परवानगी देणे. [लेयर 2s (L2s)](/glossary/#layer-2) किंवा [रोलअप्स](/glossary#rollups) त्यांच्या स्वतःच्या स्वतंत्र चेन्सवर व्यवहार प्रक्रिया करतात आणि पडताळणी व सुरक्षिततेसाठी इथेरियमचा वापर करतात. केवळ सुरक्षेसाठी-महत्वपूर्ण कमिटमेंट्स प्रकाशित करणे आणि पेलोड्स संकुचित केल्याने L2s इथेरियमची DA क्षमता अधिक कार्यक्षमतेने वापरू शकतात. या बदल्यात, L1 सुरक्षेच्या हमीशी तडजोड न करता कमी डेटा वाहून नेतो, तर L2s कमी गॅस खर्चात अधिक वापरकर्त्यांना ऑनबोर्ड करतात. सुरुवातीला, L2s सामान्य व्यवहारांमध्ये `calldata` म्हणून डेटा प्रकाशित करत होते, जे गॅससाठी L1 व्यवहारांशी स्पर्धा करत असे आणि मोठ्या प्रमाणात डेटा उपलब्धतेसाठी अव्यवहार्य होते. diff --git a/public/content/translations/mr/roadmap/merge/index.md b/public/content/translations/mr/roadmap/merge/index.md index f010abcef26..83261c27569 100644 --- a/public/content/translations/mr/roadmap/merge/index.md +++ b/public/content/translations/mr/roadmap/merge/index.md @@ -119,7 +119,7 @@ id="developers"> ## द मर्ज बद्दलचे गैरसमज {#misconceptions} Ethereum नोड्सचे दोन प्रकार आहेत: ब्लॉक प्रस्तावित करू शकणारे नोड्स आणि जे करू शकत नाहीत. @@ -136,7 +136,7 @@ Ethereum नोड्सचे दोन प्रकार आहेत: ब् गॅस फी नेटवर्कच्या क्षमतेच्या तुलनेत नेटवर्कच्या मागणीचे उत्पादन आहे. द मर्जने प्रूफ-ऑफ-वर्कचा वापर बंद केला, कन्सेन्सससाठी प्रूफ-ऑफ-स्टेकवर संक्रमण केले, परंतु नेटवर्क क्षमता किंवा थ्रूपुटवर थेट परिणाम करणारे कोणतेही पॅरामीटर्स लक्षणीयरीत्या बदलले नाहीत. @@ -145,7 +145,7 @@ contentPreview="खोटे. द मर्ज हे कन्सेन्स व्यवहाराचा "वेग" काही मार्गांनी मोजला जाऊ शकतो, ज्यात ब्लॉकमध्ये समाविष्ट होण्यासाठी लागणारा वेळ आणि अंतिम होण्यासाठी लागणारा वेळ यांचा समावेश आहे. हे दोन्ही बदल थोडेसे आहेत, पण वापरकर्त्यांच्या लक्षात येण्यासारखे नाहीत. @@ -155,7 +155,7 @@ contentPreview="खोटे. जरी काही किरकोळ बद द मर्ज नंतर सुरुवातीला, स्टेकर्स फक्त ब्लॉक प्रस्तावांच्या परिणामी मिळालेले फी टिप्स आणि MEV ऍक्सेस करू शकत होते. हे रिवॉर्ड्स व्हॅलिडेटरद्वारे नियंत्रित नॉन-स्टेकिंग खात्यात (फी रेसिपिएंट म्हणून ओळखले जाते) जमा केले जातात, आणि ते त्वरित उपलब्ध असतात. हे रिवॉर्ड्स व्हॅलिडेटर कर्तव्ये पार पाडण्यासाठी मिळणाऱ्या प्रोटोकॉल रिवॉर्ड्सपेक्षा वेगळे आहेत. @@ -166,7 +166,7 @@ contentPreview="खोटे, परंतु स्टेकिंग विथ शांघाय/कॅपेलला अपग्रेडने विथड्रॉव्हल्स सक्षम केल्यामुळे, व्हॅलिडेटर्सना ३२ ETH पेक्षा जास्त असलेली त्यांची स्टेकिंग बॅलन्स काढण्यासाठी प्रोत्साहन दिले जाते, कारण हे फंड उत्पन्नात भर घालत नाहीत आणि अन्यथा लॉक केलेले असतात. APR वर अवलंबून (एकूण स्टेक केलेल्या ETH द्वारे निर्धारित), त्यांना त्यांची संपूर्ण शिल्लक परत मिळवण्यासाठी त्यांच्या व्हॅलिडेटरमधून बाहेर पडण्यासाठी किंवा अधिक उत्पन्न मिळवण्यासाठी त्यांच्या रिवॉर्ड्सचा वापर करून आणखी जास्त स्टेक करण्यासाठी प्रोत्साहन दिले जाऊ शकते. diff --git a/public/content/translations/mr/roadmap/merge/issuance/index.md b/public/content/translations/mr/roadmap/merge/issuance/index.md index a388ae0afb8..b7c7a278240 100644 --- a/public/content/translations/mr/roadmap/merge/issuance/index.md +++ b/public/content/translations/mr/roadmap/merge/issuance/index.md @@ -39,18 +39,18 @@ title="ETH जारी करण्याचा सारांश"> ### मर्ज-पूर्वी जारी करण्याचे विश्लेषण {#pre-merge-issuance-breakdown} -एकूण ETH पुरवठा: **~120,520,000 ETH** (सप्टेंबर 2022 मध्ये द मर्जच्या वेळी) +एकूण ETH पुरवठा: **\~120,520,000 ETH** (सप्टेंबर 2022 मध्ये द मर्जच्या वेळी) **एक्झिक्युशन लेयर जारी करणे:** -- अंदाजे 13.3 सेकंदाला 2.08 ETH\*: एका वर्षात **~4,930,000** ETH जारी केले. +- अंदाजे 13.3 सेकंदाला 2.08 ETH\*: एका वर्षात **\~4,930,000** ETH जारी केले. - यामुळे चलनवाढीचा दर **अंदाजे 4.09%** होता (प्रति वर्ष 4.93M / एकूण 120.5M) - \*यात प्रति कॅनोनिकल ब्लॉक 2 ETH, तसेच ओमर ब्लॉक्समधून कालांतराने सरासरी 0.08 ETH समाविष्ट आहे. यामध्ये 13.3 सेकंदांचा वापर केला आहे, जो [डिफिकल्टी बॉम्ब](/glossary/#difficulty-bomb) च्या कोणत्याही प्रभावाशिवाय बेसलाइन ब्लॉक टाइमचे लक्ष्य आहे. ([स्रोत पहा](https://bitinfocharts.com/ethereum/)) **कन्सेंसस लेयर जारी करणे:** - एकूण 14,000,000 ETH स्टेक केल्यावर, ETH जारी करण्याचा दर अंदाजे 1700 ETH/दिवस आहे ([स्रोत पहा](https://ultrasound.money/)) -- यामुळे एका वर्षात **~620,500** ETH जारी होतात +- यामुळे एका वर्षात **\~620,500** ETH जारी होतात - यामुळे चलनवाढीचा दर **अंदाजे 0.52%** होता (प्रति वर्ष 620.5K / एकूण 119.3M) @@ -58,9 +58,9 @@ title="ETH जारी करण्याचा सारांश"> **एकूण वार्षिक जारी करण्याचा दर (मर्ज-पूर्वी): ~4.61%** (4.09% + 0.52%) -जारी केलेल्या रकमेपैकी **~88.7%** एक्झिक्युशन लेयरवरील मायनर्सना जात होते (4.09 / 4.61 \* 100) +जारी केलेल्या रकमेपैकी **\~88.7%** एक्झिक्युशन लेयरवरील मायनर्सना जात होते (4.09 / 4.61 \* 100) -**~11.3%** कन्सेंसस लेयरवरील स्टेकर्सना जारी केले जात होते (0.52 / 4.61 \* 100) +**\~11.3%** कन्सेंसस लेयरवरील स्टेकर्सना जारी केले जात होते (0.52 / 4.61 \* 100) @@ -87,16 +87,16 @@ title="ETH जारी करण्याचा सारांश"> ### मर्ज-नंतर चलनवाढीचे विश्लेषण {#post-merge-inflation-breakdown} -- एकूण ETH पुरवठा: **~120,520,000 ETH** (सप्टेंबर 2022 मध्ये द मर्जच्या वेळी) +- [एकूण ETH पुरवठा](/eth/supply/): **\~120,520,000 ETH** (सप्टेंबर 2022 मध्ये द मर्जच्या वेळी) - एक्झिक्युशन लेयर जारी करणे: **0** -- कन्सेंसस लेयर जारी करणे: वरीलप्रमाणेच, **~0.52%** वार्षिक जारी करण्याचा दर (14 दशलक्ष एकूण ETH स्टेक केल्यावर) +- कन्सेंसस लेयर जारी करणे: वरीलप्रमाणेच, **\~0.52%** वार्षिक जारी करण्याचा दर (14 दशलक्ष एकूण ETH स्टेक केल्यावर) -एकूण वार्षिक जारी करण्याचा दर: **~0.52%** +एकूण वार्षिक जारी करण्याचा दर: **\~0.52%** -वार्षिक ETH जारी करण्यात निव्वळ घट: **~88.7%** ((4.61% - 0.52%) / 4.61% \* 100) +वार्षिक ETH जारी करण्यात निव्वळ घट: **\~88.7%** ((4.61% - 0.52%) / 4.61% \* 100) From 33377c108fcc132a5a8f3bdfb796c2f8c82c6cc2 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:37:10 -0700 Subject: [PATCH 6/9] i18n(mr): Gemini translation --- .../index.md | 771 ++++++++++++++++++ 1 file changed, 771 insertions(+) create mode 100644 public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md diff --git a/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md new file mode 100644 index 00000000000..977a57b148b --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md @@ -0,0 +1,771 @@ +--- +title: "Building a user interface for your contract" +description: Using modern components such as TypeScript, React, Vite, and Wagmi, we will go over a modern, but minimal, user interface and learn how to connect a wallet to the user interface, call a smart contract to read information, send a transaction to a smart contract, and monitor events from a smart contract to identify changes. +author: Ori Pomerantz +tags: ["typescript", "react", "vite", "wagmi", "फ्रंटएंड"] +skill: beginner +breadcrumb: UI with WAGMI +published: 2023-11-01 +lang: mr +sidebarDepth: 3 +--- + +तुम्हाला इथरियम इकोसिस्टममध्ये आवश्यक असलेले एक वैशिष्ट्य सापडले आहे. त्याची अंमलबजावणी करण्यासाठी तुम्ही स्मार्ट कॉन्ट्रॅक्ट्स लिहिले आहेत आणि कदाचित ऑफचेन चालणारा काही संबंधित कोडही लिहिला असेल. हे उत्तम आहे! दुर्दैवाने, युजर इंटरफेसशिवाय तुम्हाला कोणतेही युजर्स मिळणार नाहीत आणि तुम्ही शेवटची वेबसाईट बनवली तेव्हा लोक डायल-अप मॉडेम वापरत होते आणि JavaScript नवीन होते. + +हा लेख तुमच्यासाठी आहे. मी असे गृहीत धरतो की तुम्हाला प्रोग्रामिंग येते आणि कदाचित थोडे JavaScript आणि HTML देखील येते, परंतु तुमचे युजर इंटरफेस कौशल्य जुने आणि कालबाह्य झाले आहे. आपण एकत्र एका साध्या आधुनिक ॲप्लिकेशनवर नजर टाकू जेणेकरून आजकाल हे कसे केले जाते हे तुम्हाला समजेल. + +## हे महत्त्वाचे का आहे {#why-important} + +सैद्धांतिकदृष्ट्या, तुम्ही लोकांना तुमच्या कॉन्ट्रॅक्ट्सशी संवाद साधण्यासाठी फक्त [Etherscan](https://sepolia.etherscan.io/address/0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA#readContract) किंवा [Blockscout](https://eth-sepolia.blockscout.com/address/0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA?tab=read_write_contract) वापरण्यास सांगू शकता. अनुभवी इथरियन्ससाठी हे उत्तम आहे. परंतु आम्ही [आणखी एक अब्ज लोकांना](https://blog.ethereum.org/2021/05/07/ethereum-for-the-next-billion) सेवा देण्याचा प्रयत्न करत आहोत. एका उत्तम युजर एक्सपिरियन्सशिवाय हे शक्य होणार नाही आणि एक अनुकूल युजर इंटरफेस हा त्याचा एक मोठा भाग आहे. + +## Greeter ॲप्लिकेशन {#greeter-app} + +आधुनिक UI कसे कार्य करते यामागे बरेच सिद्धांत आहेत आणि [अनेक चांगल्या साईट्स](https://react.dev/learn/thinking-in-react) [ते स्पष्ट करतात](https://wagmi.sh/core/getting-started). त्या साईट्सनी केलेल्या उत्तम कामाची पुनरावृत्ती करण्याऐवजी, मी असे गृहीत धरणार आहे की तुम्हाला प्रत्यक्ष कृतीतून शिकायला आवडते आणि आपण एका ॲप्लिकेशनपासून सुरुवात करू ज्यासोबत तुम्ही प्रयोग करू शकता. गोष्टी पूर्ण करण्यासाठी तुम्हाला अजूनही सिद्धांताची आवश्यकता आहे आणि आपण त्याकडे वळू - आपण फक्त सोर्स फाईलनुसार पुढे जाऊ आणि जसे आपण त्यांच्यापर्यंत पोहोचू तशी गोष्टींवर चर्चा करू. + +### इन्स्टॉलेशन {#installation} + +1. हे ॲप्लिकेशन [Sepolia](https://sepolia.dev/) टेस्ट नेटवर्क वापरते. आवश्यक असल्यास, [Sepolia टेस्ट ETH मिळवा](/developers/docs/networks/#sepolia) आणि [तुमच्या वॉलेटमध्ये Sepolia जोडा](https://chainlist.org/chain/11155111). + +2. GitHub रिपॉझिटरी क्लोन करा आणि आवश्यक पॅकेजेस इन्स्टॉल करा. + + ```sh + git clone https://github.com/qbzzt/260301-modern-ui-web3.git + cd 260301-modern-ui-web3 + npm install +``` + +3. हे ॲप्लिकेशन मोफत ॲक्सेस पॉईंट्स वापरते, ज्यांच्या परफॉर्मन्सवर मर्यादा आहेत. जर तुम्हाला [नोड ॲज अ सर्व्हिस](/developers/docs/nodes-and-clients/nodes-as-a-service/) प्रोव्हायडर वापरायचा असेल, तर [`src/wagmi.ts`](#wagmi-ts) मधील URLs बदला. + +4. ॲप्लिकेशन सुरू करा. + + ```sh + npm run dev +``` + +5. ॲप्लिकेशनद्वारे दर्शविलेल्या URL वर जा. बहुतांश प्रकरणांमध्ये, ते [http://localhost:5173/](http://localhost:5173/) असते. + +6. तुम्ही कॉन्ट्रॅक्टचा सोर्स कोड, जो Hardhat च्या Greeter ची सुधारित आवृत्ती आहे, [ब्लॉकचेन एक्सप्लोररवर](https://eth-sepolia.blockscout.com/address/0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA?tab=contract_code) पाहू शकता. + +### फाईल वॉक थ्रू {#file-walk-through} + +#### `index.html` {#index-html} + +ही फाईल एक स्टँडर्ड HTML बॉयलरप्लेट आहे, फक्त या ओळीचा अपवाद वगळता, जी स्क्रिप्ट फाईल इम्पोर्ट करते. + +```html + +``` + +#### `src/main.tsx` {#main-tsx} + +फाईल एक्स्टेंशन दर्शविते की हा एक [React कंपोनंट](https://www.w3schools.com/react/react_components.asp) आहे जो [TypeScript](https://www.typescriptlang.org/) मध्ये लिहिला आहे, जे JavaScript चे एक एक्स्टेंशन आहे आणि [टाईप चेकिंगला](https://en.wikipedia.org/wiki/Type_system#Type_checking) सपोर्ट करते. TypeScript हे JavaScript मध्ये कंपाईल केले जाते, त्यामुळे आपण ते क्लायंट साईडवर वापरू शकतो. + +जर तुम्हाला स्वारस्य असेल तरच ही फाईल प्रामुख्याने स्पष्ट केली आहे. सहसा तुम्ही ही फाईल बदलत नाही, तर [`src/App.tsx`](#app-tsx) आणि ती इम्पोर्ट करत असलेल्या फाईल्स बदलता. + +```tsx +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import React from 'react' +import ReactDOM from 'react-dom/client' +import { WagmiProvider } from 'wagmi' +``` + +आपल्याला आवश्यक असलेला लायब्ररी कोड इम्पोर्ट करा. + +```tsx +import App from './App.tsx' +``` + +ॲप्लिकेशनची अंमलबजावणी करणारा React कंपोनंट इम्पोर्ट करा (खाली पहा). + +```tsx +import { config } from './wagmi.ts' +``` + +[wagmi](https://wagmi.sh/) कॉन्फिगरेशन इम्पोर्ट करा, ज्यामध्ये ब्लॉकचेन कॉन्फिगरेशन समाविष्ट आहे. + +```tsx +const queryClient = new QueryClient() +``` + +[React Query च्या](https://tanstack.com/query/latest/docs/framework/react/overview) कॅशे मॅनेजरचा एक नवीन इन्स्टन्स तयार करते. हा ऑब्जेक्ट खालील गोष्टी स्टोअर करेल: + +- कॅशे केलेले RPC कॉल्स +- कॉन्ट्रॅक्ट रीड्स +- बॅकग्राउंड रिफेचिंग स्टेट + +आपल्याला कॅशे मॅनेजरची आवश्यकता आहे कारण wagmi v3 अंतर्गतपणे React Query वापरते. + +```tsx +ReactDOM.createRoot(document.getElementById('root')!).render( +``` + +रूट React कंपोनंट तयार करा. `render` चा पॅरामीटर [JSX](https://www.w3schools.com/react/react_jsx.asp) आहे, जी एक एक्स्टेंशन लँग्वेज आहे आणि HTML आणि JavaScript/TypeScript दोन्ही वापरते. येथील उद्गारवाचक चिन्ह TypeScript कंपोनंटला सांगते: "तुम्हाला माहित नाही की `document.getElementById('root')` हे `ReactDOM.createRoot` साठी एक वैध पॅरामीटर असेल, पण काळजी करू नका - मी डेव्हलपर आहे आणि मी तुम्हाला सांगत आहे की ते असेल". + +```tsx + +``` + +हे ॲप्लिकेशन [एका `React.StrictMode` कंपोनंटच्या](https://react.dev/reference/react/StrictMode) आत जात आहे. हा कंपोनंट React लायब्ररीला अतिरिक्त डीबगिंग चेक्स समाविष्ट करण्यास सांगतो, जे डेव्हलपमेंट दरम्यान उपयुक्त ठरते. + +```tsx + +``` + +हे ॲप्लिकेशन [एका `WagmiProvider` कंपोनंटच्या](https://wagmi.sh/react/api/WagmiProvider) आत देखील आहे. [wagmi (we are going to make it) लायब्ररी](https://wagmi.sh/) इथरियम डिसेंट्रलाईज्ड ॲप्लिकेशन लिहिण्यासाठी React UI डेफिनेशन्सना [viem लायब्ररीशी](https://viem.sh/) जोडते. + +```tsx + +``` + +आणि शेवटी, एक React Query प्रोव्हायडर जोडा जेणेकरून कोणताही ॲप्लिकेशन कंपोनंट कॅशे केलेल्या क्वेरीज वापरू शकेल. + +```tsx + +``` + +आता आपण ॲप्लिकेशनसाठी कंपोनंट घेऊ शकतो, जो प्रत्यक्षात UI ची अंमलबजावणी करतो. कंपोनंटच्या शेवटी असलेले `/>` React ला सांगते की XML स्टँडर्डनुसार या कंपोनंटच्या आत कोणत्याही डेफिनेशन्स नाहीत. + +```tsx + + + , +) +``` + +अर्थात, आपल्याला इतर कंपोनंट्स बंद करावे लागतील. + +#### `src/App.tsx` {#app-tsx} + +```tsx +import { + useConnect, + useConnection, + useDisconnect, + useSwitchChain +} from 'wagmi' + +import { useEffect } from 'react' +import { Greeter } from './Greeter' +``` + +आपल्याला आवश्यक असलेल्या लायब्ररीज, तसेच [`Greeter` कंपोनंट](#greeter-tsx) इम्पोर्ट करा. + +```tsx +const SEPOLIA_CHAIN_ID = 11155111 +``` + +Sepolia चेन ID. + +``` +function App() { +``` + +React कंपोनंट तयार करण्याचा हा स्टँडर्ड मार्ग आहे: एक फंक्शन डिफाईन करा जे जेव्हा रेंडर करण्याची आवश्यकता असते तेव्हा कॉल केले जाते. या फंक्शनमध्ये सामान्यतः TypeScript किंवा JavaScript कोड असतो, त्यानंतर एक `return` स्टेटमेंट असते जे JSX कोड रिटर्न करते. + +```tsx + const connection = useConnection() +``` + +सध्याच्या कनेक्शनशी संबंधित माहिती मिळवण्यासाठी [`useConnection`](https://wagmi.sh/react/api/hooks/useConnection) वापरा, जसे की ॲड्रेस आणि `chainId`. + +प्रथेनुसार, React मध्ये `use...` नावाच्या फंक्शन्सना [हुक्स (hooks)](https://www.w3schools.com/react/react_hooks.asp) म्हणतात. ही फंक्शन्स केवळ कंपोनंटला डेटा रिटर्न करत नाहीत; तर जेव्हा तो डेटा बदलतो तेव्हा ते पुन्हा रेंडर केले जाईल (कंपोनंट फंक्शन पुन्हा एक्झिक्युट केले जाते आणि त्याचे आऊटपुट HTML मधील मागील आऊटपुटची जागा घेते) याची देखील खात्री करतात. + +```tsx + const { connectors, connect, status, error } = useConnect() +``` + +वॉलेट कनेक्शनबद्दल माहिती मिळवण्यासाठी [`useConnect`](https://wagmi.sh/react/api/hooks/useConnect) वापरा. + +```tsx + const { disconnect } = useDisconnect() +``` + +[हा हुक](https://wagmi.sh/react/api/hooks/useDisconnect) आपल्याला वॉलेटमधून डिस्कनेक्ट करण्यासाठी फंक्शन देतो. + +```tsx + const { switchChain } = useSwitchChain() +``` + +[हा हुक](https://wagmi.sh/react/api/hooks/useSwitchChain) आपल्याला चेन्स स्विच करू देतो. + +```tsx + useEffect(() => { +``` + +React हुक [`useEffect`](https://react.dev/reference/react/useEffect) तुम्हाला बाह्य सिस्टीम सिंक्रोनाईज करण्यासाठी जेव्हा एखाद्या व्हेरिएबलचे मूल्य बदलते तेव्हा फंक्शन रन करू देतो. + +```tsx + if (connection.status === 'connected' && + connection.chainId !== SEPOLIA_CHAIN_ID + ) { + switchChain({ chainId: SEPOLIA_CHAIN_ID }) + } +``` + +जर आपण कनेक्टेड असू, पण Sepolia ब्लॉकचेनशी नसू, तर Sepolia वर स्विच करा. + +```tsx + }, [connection.status, connection.chainId]) +``` + +प्रत्येक वेळी जेव्हा कनेक्शन स्टेटस किंवा कनेक्शन chainId बदलतो तेव्हा फंक्शन पुन्हा रन करा. + +```tsx + return ( + <> +``` + +React कंपोनंटच्या JSX ने एकच HTML कंपोनंट रिटर्न करणे _आवश्यक_ आहे. जेव्हा आपल्याकडे अनेक कंपोनंट्स असतात आणि त्या सर्वांना रॅप करण्यासाठी कंटेनरची आवश्यकता नसते, तेव्हा आपण त्यांना एकाच कंपोनंटमध्ये एकत्र करण्यासाठी एक रिकामा कंपोनंट (`<> ... `) वापरतो. + +```tsx +

Connection

+
+ status: {connection.status} +
+ addresses: {JSON.stringify(connection.addresses)} +
+ chainId: {connection.chainId} +
+``` + +सध्याच्या कनेक्शनबद्दल माहिती द्या. JSX मध्ये, `{}` म्हणजे एक्स्प्रेशनचे JavaScript म्हणून मूल्यमापन करणे. + +```tsx + {connection.status === 'connected' && ( +``` + +`{ && }` या सिंटॅक्सचा अर्थ असा आहे की "जर कंडिशन `true` असेल, तर व्हॅल्यूचे मूल्यमापन करा; जर नसेल, तर `false` चे मूल्यमापन करा". + +JSX मध्ये if स्टेटमेंट्स टाकण्याचा हा स्टँडर्ड मार्ग आहे. + +```tsx +
+ +
+``` + +JSX हे XML स्टँडर्ड फॉलो करते, जे HTML पेक्षा अधिक कडक आहे. जर एखाद्या टॅगला संबंधित एंड टॅग नसेल, तर तो टर्मिनेट करण्यासाठी त्याच्या शेवटी स्लॅश (`/`) असणे _आवश्यक_ आहे. + +येथे आपल्याकडे असे दोन टॅग्स आहेत, `` (ज्यामध्ये प्रत्यक्षात कॉन्ट्रॅक्टशी संवाद साधणारा HTML कोड असतो) आणि [आडव्या रेषेसाठी `
`](https://www.w3schools.com/tags/tag_hr.asp). + +```tsx + +
+ )} +``` + +जर युजरने या बटणावर क्लिक केले, तर `disconnect` फंक्शन कॉल करा. + +```tsx + {connection.status !== 'connected' && ( +``` + +जर आपण कनेक्टेड _नसू_, तर वॉलेटशी कनेक्ट करण्यासाठी आवश्यक पर्याय दाखवा. + +```tsx +
+

Connect

+ {connectors.map((connector) => ( +``` + +`connectors` मध्ये आपल्याकडे कनेक्टर्सची यादी आहे. आपण ती प्रदर्शित करण्यासाठी JSX बटणांच्या यादीत बदलण्यासाठी [`map`](https://www.w3schools.com/jsref/jsref_map.asp) वापरतो. + +```tsx + + ))} +``` + +कनेक्टर बटणे. + +```tsx +
{status}
+
{error?.message}
+
+ )} +``` + +अतिरिक्त माहिती द्या. `?.` हा एक्स्प्रेशन सिंटॅक्स JavaScript ला सांगतो की जर व्हेरिएबल डिफाईन केले असेल, तर त्या फील्डचे मूल्यमापन करा. जर व्हेरिएबल डिफाईन केले नसेल, तर हे एक्स्प्रेशन `undefined` चे मूल्यमापन करते. + +जेव्हा कोणतीही एरर नसते, तेव्हा `error.message` हे एक्स्प्रेशन एक्सेप्शन निर्माण करेल. `error?.message` वापरल्याने आपल्याला ही समस्या टाळता येते. + +#### `src/Greeter.tsx` {#greeter-tsx} + +या फाईलमध्ये बहुतांश UI कार्यक्षमता आहे. यात अशा डेफिनेशन्स समाविष्ट आहेत ज्या सामान्यतः अनेक फाईल्समध्ये असतात, परंतु हे एक ट्युटोरिअल असल्याने, प्रोग्राम परफॉर्मन्स किंवा देखभालीच्या सुलभतेपेक्षा पहिल्यांदा समजण्यास सोपा असावा यासाठी ऑप्टिमाईज केला आहे. + +```tsx +import { + useState, + useEffect, + } from 'react' +import { useChainId, + useAccount, + useReadContract, + useWriteContract, + useWatchContractEvent, + useSimulateContract + } from 'wagmi' +``` + +आपण ही लायब्ररी फंक्शन्स वापरतो. पुन्हा, ती जिथे वापरली आहेत तिथे खाली स्पष्ट केली आहेत. + +```tsx +import { AddressType } from 'abitype' +``` + +[`abitype` लायब्ररी](https://abitype.dev/) आपल्याला विविध इथरियम डेटा टाईप्ससाठी TypeScript डेफिनेशन्स प्रदान करते, जसे की [`AddressType`](https://abitype.dev/config#addresstype). + +```tsx +let greeterABI = [ + { "type": "function", "name": "greet", ... }, + { "type": "function", "name": "setGreeting", ... }, + { "type": "event", "name": "SetGreeting", ... }, +] as const // greeterABI +``` + +`Greeter` कॉन्ट्रॅक्टसाठी ABI. +जर तुम्ही कॉन्ट्रॅक्ट्स आणि UI एकाच वेळी डेव्हलप करत असाल, तर तुम्ही सामान्यतः त्यांना एकाच रिपॉझिटरीमध्ये ठेवाल आणि Solidity कंपायलरद्वारे जनरेट केलेला ABI तुमच्या ॲप्लिकेशनमध्ये फाईल म्हणून वापराल. तथापि, येथे हे आवश्यक नाही कारण कॉन्ट्रॅक्ट आधीच डेव्हलप केले आहे आणि ते बदलणार नाही. + +आपण TypeScript ला हे सांगण्यासाठी [`as const`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) वापरतो की हा एक _खरा_ कॉन्स्टंट आहे. सामान्यतः, जेव्हा तुम्ही JavaScript मध्ये `const x = {"a": 1}` निर्दिष्ट करता, तेव्हा तुम्ही `x` मधील व्हॅल्यू बदलू शकता, तुम्ही फक्त त्याला असाईन करू शकत नाही. + +```tsx +type AddressPerBlockchainType = { + [key: number]: AddressType +} +``` + +TypeScript हे स्ट्रॉंगली टाईप्ड आहे. आपण या डेफिनेशनचा वापर वेगवेगळ्या चेन्सवर `Greeter` कॉन्ट्रॅक्ट जिथे डिप्लॉय केले आहे तो ॲड्रेस निर्दिष्ट करण्यासाठी करतो. की (key) हा एक नंबर (chainId) आहे आणि व्हॅल्यू ही एक `AddressType` (एक ॲड्रेस) आहे. + +```tsx +const contractAddrs : AddressPerBlockchainType = { + // सेपोलिया + 11155111: '0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA' +} +``` + +[Sepolia](https://eth-sepolia.blockscout.com/address/0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA?tab=contract) वरील कॉन्ट्रॅक्टचा ॲड्रेस. + +##### `Timer` कंपोनंट {#timer-component} + +`Timer` कंपोनंट दिलेल्या वेळेपासून किती सेकंद झाले हे दर्शवितो. युझेबिलिटीच्या उद्देशाने हे महत्त्वाचे आहे. जेव्हा युजर्स काहीतरी करतात, तेव्हा त्यांना त्वरित प्रतिक्रियेची अपेक्षा असते. ब्लॉकचेन्समध्ये, हे अनेकदा अशक्य असते कारण जोपर्यंत ट्रान्झॅक्शन ब्लॉकमध्ये ठेवले जात नाही तोपर्यंत काहीही होत नाही. यावर एक उपाय म्हणजे युजरने कृती केल्यापासून किती वेळ झाला आहे हे दाखवणे, जेणेकरून लागणारा वेळ योग्य आहे की नाही हे युजर ठरवू शकेल. + +```tsx +type TimerProps = { + lastUpdate: Date +} +``` + +`Timer` कंपोनंट एक पॅरामीटर घेतो, `lastUpdate`, जी शेवटच्या कृतीची वेळ असते. + +```tsx +const Timer = ({ lastUpdate }: TimerProps) => { + const [_, setNow] = useState(new Date()) +``` + +कंपोनंट योग्यरित्या कार्य करण्यासाठी आपल्याकडे स्टेट (कंपोनंटशी जोडलेले व्हेरिएबल) असणे आणि ते अपडेट करणे आवश्यक आहे. परंतु आपल्याला ते कधीही वाचण्याची आवश्यकता नसते, त्यामुळे व्हेरिएबल तयार करण्याची तसदी घेऊ नका. + +```tsx + useEffect(() => { + const id = setInterval(() => setNow(new Date()), 1000) + return () => clearInterval(id) + }, []) +``` + +[`setInterval`](https://www.w3schools.com/jsref/met_win_setinterval.asp) फंक्शन आपल्याला वेळोवेळी रन करण्यासाठी फंक्शन शेड्युल करू देते. या प्रकरणात, दर सेकंदाला. हे फंक्शन स्टेट अपडेट करण्यासाठी `setNow` ला कॉल करते, त्यामुळे `Timer` कंपोनंट पुन्हा रेंडर होईल. आपण याला एका रिकाम्या डिपेंडन्सी लिस्टसह [`useEffect`](https://react.dev/reference/react/useEffect) च्या आत रॅप करतो जेणेकरून ते प्रत्येक वेळी कंपोनंट रेंडर झाल्यावर होण्याऐवजी फक्त एकदाच होईल. + +```tsx + const secondsSinceUpdate = Math.floor( + (Date.now() - lastUpdate.getTime()) / 1000 + ) + + return ( + {secondsSinceUpdate} seconds ago + ) +} +``` + +शेवटच्या अपडेटपासून किती सेकंद झाले याची गणना करा आणि ते रिटर्न करा. + +##### `Greeter` कंपोनंट {#greeter-component} + +```tsx +const Greeter = () => { +``` + +शेवटी, आपण कंपोनंट डिफाईन करतो. + +```tsx + const chainId = useChainId() + const account = useAccount() +``` + +आपण वापरत असलेल्या चेन आणि अकाउंटबद्दलची माहिती, [wagmi](https://wagmi.sh/) च्या सौजन्याने. कारण हा एक हुक (`use...`) आहे, जेव्हा ही माहिती बदलते तेव्हा कंपोनंट पुन्हा रेंडर केला जातो. + +```tsx + const greeterAddr = chainId && contractAddrs[chainId] +``` + +Greeter कॉन्ट्रॅक्टचा ॲड्रेस, जो `undefined` असतो जर आपल्याकडे चेनची माहिती नसेल, किंवा आपण त्या कॉन्ट्रॅक्टशिवाय असलेल्या चेनवर असू. + +```tsx + const readResults = useReadContract({ + address: greeterAddr, + abi: greeterABI, + functionName: "greet", // कोणतेही आर्ग्युमेंट्स नाहीत + }) +``` + +[`useReadContract` हुक](https://wagmi.sh/react/api/hooks/useReadContract) [कॉन्ट्रॅक्टच्या](https://eth-sepolia.blockscout.com/address/0xC87506C66c7896366b9E988FE0aA5B6dDE77CFfA?tab=contract) `greet` फंक्शनला कॉल करतो. + +```tsx + const [ currentGreeting, setCurrentGreeting ] = + useState("Please wait while we fetch the greeting from the blockchain...") + const [ newGreeting, setNewGreeting ] = useState("") +``` + +React चा [`useState` हुक](https://www.w3schools.com/react/react_usestate.asp) आपल्याला एक स्टेट व्हेरिएबल निर्दिष्ट करू देतो, ज्याची व्हॅल्यू कंपोनंटच्या एका रेंडरिंगपासून दुसऱ्या रेंडरिंगपर्यंत टिकून राहते. प्रारंभिक व्हॅल्यू हे पॅरामीटर असते, या प्रकरणात रिकामी स्ट्रिंग. + +`useState` हुक दोन व्हॅल्यूज असलेली यादी रिटर्न करतो: + +1. स्टेट व्हेरिएबलची सध्याची व्हॅल्यू. +2. आवश्यकतेनुसार स्टेट व्हेरिएबलमध्ये बदल करण्यासाठी एक फंक्शन. हा एक हुक असल्याने, प्रत्येक वेळी जेव्हा त्याला कॉल केले जाते तेव्हा कंपोनंट पुन्हा रेंडर केला जातो. + +या प्रकरणात, युजरला जे नवीन ग्रीटिंग सेट करायचे आहे त्यासाठी आपण स्टेट व्हेरिएबल वापरत आहोत. + +```tsx + const [ lastSetterAddress, setLastSetterAddress ] = useState("") +``` + +जर अनेक युजर्स एकाच वेळी एकच कॉन्ट्रॅक्ट वापरत असतील, तर ते एकमेकांचे ग्रीटिंग्ज ओव्हरराईट करू शकतात. यामुळे युजर्सना असे वाटेल की ॲप्लिकेशन खराब झाले आहे. जर ॲप्लिकेशनने दाखवले की शेवटचे ग्रीटिंग कोणी सेट केले आहे, तर युजरला समजेल की ते दुसरे कोणीतरी होते आणि ॲप्लिकेशन योग्यरित्या काम करत आहे. + +```tsx + const [ status, setStatus ] = useState("") + const [ statusTime, setStatusTime ] = useState(new Date()) +``` + +युजर्सना त्यांच्या कृतींचा त्वरित परिणाम झालेला पाहायला आवडते. तथापि, ब्लॉकचेनवर असे होत नाही. हे स्टेट व्हेरिएबल्स आपल्याला युजर्सना किमान काहीतरी प्रदर्शित करू देतात जेणेकरून त्यांना समजेल की त्यांची कृती प्रगतीपथावर आहे. + +```tsx + useEffect(() => { + if (readResults.data) { + setCurrentGreeting(readResults.data) + setStatus("Greeting fetched from blockchain") + } + }, [readResults.data]) +``` + +जर वरील `readResults` ने डेटा बदलला आणि तो फॉल्स व्हॅल्यूवर (`undefined`, उदाहरणार्थ) सेट केलेला नसेल, तर सध्याचे ग्रीटिंग ब्लॉकचेनवरून वाचलेल्या ग्रीटिंगवर अपडेट करा. तसेच, स्टेटस अपडेट करा. + +```tsx + useWatchContractEvent({ + address: greeterAddr, + abi: greeterABI, + eventName: 'SetGreeting', + chainId, +``` + +`SetGreeting` इव्हेंट्स ऐका. + +```tsx + enabled: !!greeterAddr, +``` + +`!!` चा अर्थ असा आहे की जर व्हॅल्यू `false` असेल, किंवा अशी व्हॅल्यू जिचे मूल्यमापन फॉल्स म्हणून होते, जसे की `undefined`, `0`, किंवा रिकामी स्ट्रिंग, तर एकूण एक्स्प्रेशन `false` असते. इतर कोणत्याही व्हॅल्यूसाठी, ते `true` असते. व्हॅल्यूजना बुलियन्समध्ये रूपांतरित करण्याचा हा एक मार्ग आहे, कारण जर `greeterAddr` नसेल, तर आपल्याला इव्हेंट्स ऐकायचे नाहीत. + +```tsx + onLogs: logs => { + const greetingFromContract = logs[0].args.greeting + setCurrentGreeting(greetingFromContract) + setLastSetterAddress(logs[0].args.sender) + updateStatus("Greeting updated by event") + }, + }) +``` + +जेव्हा आपण लॉग्स पाहतो (जे नवीन इव्हेंट पाहिल्यावर घडते), तेव्हा त्याचा अर्थ असा होतो की ग्रीटिंग सुधारित केले गेले आहे. त्या प्रकरणात, आपण `currentGreeting` आणि `lastSetterAddress` नवीन व्हॅल्यूजवर अपडेट करू शकतो. तसेच, आपल्याला स्टेटस डिस्प्ले अपडेट करायचा आहे. + +```tsx + const updateStatus = (newStatus: string) => { + setStatus(newStatus) + setStatusTime(new Date()) + } +``` + +जेव्हा आपण स्टेटस अपडेट करतो तेव्हा आपल्याला दोन गोष्टी करायच्या असतात: + +1. स्टेटस स्ट्रिंग अपडेट करणे (`status`) +2. शेवटच्या स्टेटस अपडेटची वेळ (`statusTime`) आताच्या वेळेवर अपडेट करणे. + +```tsx + const greetingChange = (evt) => + setNewGreeting(evt.target.value) +``` + +नवीन ग्रीटिंग इनपुट फील्डमधील बदलांसाठी हा इव्हेंट हँडलर आहे. आपण `evt` पॅरामीटरचा प्रकार निर्दिष्ट करू शकलो असतो, परंतु TypeScript ही एक टाईप ऑप्शनल लँग्वेज आहे. हे फंक्शन HTML इव्हेंट हँडलरमध्ये फक्त एकदाच कॉल केले जात असल्याने, मला वाटत नाही की ते आवश्यक आहे. + +```tsx + const { writeContractAsync } = useWriteContract() +``` + +कॉन्ट्रॅक्टवर राईट करण्यासाठी फंक्शन. हे [`writeContracts`](https://wagmi.sh/core/api/actions/writeContracts#writecontracts) सारखेच आहे, परंतु अधिक चांगले स्टेटस अपडेट्स सक्षम करते. + +```tsx + const simulation = useSimulateContract({ + address: greeterAddr, + abi: greeterABI, + functionName: 'setGreeting', + args: [newGreeting], + account: account.address + }) +``` + +क्लायंटच्या दृष्टिकोनातून ब्लॉकचेन ट्रान्झॅक्शन सबमिट करण्याची ही प्रक्रिया आहे: + +1. [`eth_estimateGas`](https://docs.alchemy.com/reference/eth-estimategas) वापरून ब्लॉकचेनमधील नोडला ट्रान्झॅक्शन पाठवा. +2. नोडकडून प्रतिसादाची प्रतीक्षा करा. +3. जेव्हा प्रतिसाद प्राप्त होतो, तेव्हा युजरला वॉलेटद्वारे ट्रान्झॅक्शन साईन करण्यास सांगा. ही पायरी नोडचा प्रतिसाद मिळाल्यानंतरच होणे _आवश्यक_ आहे कारण साईन करण्यापूर्वी युजरला ट्रान्झॅक्शनचा गॅस खर्च दाखवला जातो. +4. युजरच्या मंजुरीची प्रतीक्षा करा. +5. ट्रान्झॅक्शन पुन्हा पाठवा, यावेळी [`eth_sendRawTransaction`](https://docs.alchemy.com/reference/eth-sendrawtransaction) वापरून. + +पायरी 2 ला लक्षणीय वेळ लागण्याची शक्यता आहे, ज्या दरम्यान युजर्सना प्रश्न पडू शकतो की त्यांची कमांड युजर इंटरफेसद्वारे प्राप्त झाली आहे की नाही आणि त्यांना अद्याप ट्रान्झॅक्शन साईन करण्यास का विचारले जात नाही. यामुळे एक खराब युजर एक्सपिरियन्स (UX) तयार होतो. + +यावर एक उपाय म्हणजे प्रत्येक वेळी पॅरामीटर बदलल्यावर `eth_estimateGas` पाठवणे. त्यानंतर, जेव्हा युजरला प्रत्यक्षात ट्रान्झॅक्शन पाठवायचे असते (या प्रकरणात **Update greeting** दाबून), तेव्हा गॅस खर्च माहित असतो आणि युजर लगेच वॉलेट पेज पाहू शकतो. + +```tsx + return ( +``` + +आता आपण शेवटी रिटर्न करण्यासाठी प्रत्यक्ष HTML तयार करू शकतो. + +```tsx + <> +

Greeter

+ {currentGreeting} +``` + +सध्याचे ग्रीटिंग दाखवा. + +```tsx + {lastSetterAddress && ( +

Last updated by { + lastSetterAddress === account.address ? "you" : lastSetterAddress + }

+ )} +``` + +जर आपल्याला माहित असेल की शेवटचे ग्रीटिंग कोणी सेट केले आहे, तर ती माहिती प्रदर्शित करा. `Greeter` या माहितीचा मागोवा ठेवत नाही, आणि आपल्याला `SetGreeting` इव्हेंट्ससाठी मागे वळून पाहायचे नाही, त्यामुळे आपण रन करत असताना ग्रीटिंग बदलल्यावरच आपल्याला ते मिळते. + +```tsx +
+ +
+``` + +हे इनपुट टेक्स्ट फील्ड आहे जिथे युजर नवीन ग्रीटिंग सेट करू शकतो. प्रत्येक वेळी जेव्हा युजर की दाबतो, तेव्हा आपण `greetingChange` ला कॉल करतो, जे `setNewGreeting` ला कॉल करते. `setNewGreeting` हे `useState` मधून येत असल्याने, यामुळे `Greeter` कंपोनंट पुन्हा रेंडर होतो. याचा अर्थ असा की: + +- नवीन ग्रीटिंगची व्हॅल्यू ठेवण्यासाठी आपल्याला `value` निर्दिष्ट करणे आवश्यक आहे, कारण अन्यथा ते परत डीफॉल्टमध्ये, म्हणजे रिकाम्या स्ट्रिंगमध्ये बदलेल. +- प्रत्येक वेळी `newGreeting` बदलल्यावर `simulation` देखील अपडेट केले जाते, याचा अर्थ असा की आपल्याला योग्य ग्रीटिंगसह सिम्युलेशन मिळेल. हे प्रासंगिक असू शकते कारण गॅस खर्च कॉल डेटाच्या आकारावर अवलंबून असतो, जो स्ट्रिंगच्या लांबीवर अवलंबून असतो. + +```tsx + + +``` + +ट्रान्झॅक्शन प्रत्यक्षात पाठवल्यानंतरच `writeContractAsync` रिटर्न करते. यामुळे आपण युजरला दाखवू शकतो की ट्रान्झॅक्शन ब्लॉकचेनमध्ये समाविष्ट होण्यासाठी किती वेळ वाट पाहत आहे. + +```tsx +

Status: {status}

+

Updated

+ + ) +} +``` + +स्टेटस आणि ते अपडेट केल्यापासून किती वेळ झाला आहे हे दाखवा. + +``` +export {Greeter} +``` + +कंपोनंट एक्सपोर्ट करा. + +#### `src/wagmi.ts` {#wagmi-ts} + +शेवटी, wagmi शी संबंधित विविध डेफिनेशन्स `src/wagmi.ts` मध्ये आहेत. मी येथे सर्वकाही स्पष्ट करणार नाही, कारण त्यातील बहुतांश बॉयलरप्लेट आहे जे तुम्हाला बदलण्याची शक्यता कमी आहे. + +```ts +import { http, webSocket, createConfig, fallback } from 'wagmi' +import { sepolia } from 'wagmi/chains' +import { injected } from 'wagmi/connectors' + +export const config = createConfig({ + chains: [sepolia], +``` + +wagmi कॉन्फिगरेशनमध्ये या ॲप्लिकेशनद्वारे समर्थित चेन्स समाविष्ट आहेत. तुम्ही [उपलब्ध चेन्सची यादी](https://wagmi.sh/core/api/chains) पाहू शकता. + +```ts + connectors: [ + injected(), + ], +``` + +[हा कनेक्टर](https://wagmi.sh/core/api/connectors/injected) आपल्याला ब्राउझरमध्ये इन्स्टॉल केलेल्या वॉलेटशी संवाद साधू देतो. + +```ts + transports: { + [sepolia.id]: http() +``` + +Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉईंट पुरेसा चांगला आहे. जर आपल्याला वेगळी URL हवी असेल, तर आपण `http("https:// hostname ")` किंवा `webSocket("wss:// hostname ")` वापरू शकतो. + +```ts + }, + multiInjectedProviderDiscovery: false, +}) +``` + +## दुसरी ब्लॉकचेन जोडणे {#add-blockchain} + +आजकाल अनेक [L2 स्केलिंग सोल्युशन्स](https://ethereum.org/layer-2/) आहेत, आणि तुम्हाला अशा काहींना सपोर्ट करायचा असेल ज्यांना viem अद्याप सपोर्ट करत नाही. हे करण्यासाठी, तुम्ही `src/wagmi.ts` मध्ये बदल करता. या सूचना [Optimism Sepolia](https://chainlist.org/chain/11155420) कसे जोडायचे हे स्पष्ट करतात. + +1. `src/wagmi.ts` एडिट करा + + A. viem मधून `defineChain` टाईप इम्पोर्ट करा. + + ```ts + import { defineChain } from 'viem' +``` + + B. नेटवर्क डेफिनेशन जोडा. तुम्हाला Optimism Sepolia साठी हे करण्याची खरोखर गरज नाही, [ते आधीपासूनच `viem` मध्ये आहे](https://github.com/wevm/viem/blob/main/src/chains/definitions/optimismSepolia.ts), परंतु या मार्गाने तुम्ही `viem` मध्ये नसलेली ब्लॉकचेन कशी जोडायची हे शिकता. + + ```ts + const optimismSepolia = defineChain({ + id: 11_155_420, + name: 'OP Sepolia', + nativeCurrency: { name: 'Sepolia Ether', symbol: 'ETH', decimals: 18 }, + rpcUrls: { + default: { + http: ['https://sepolia.optimism.io'], + webSocket: ['wss://optimism-sepolia.drpc.org'], + }, + }, + blockExplorers: { + default: { + name: 'Blockscout', + url: 'https://optimism-sepolia.blockscout.com', + apiUrl: 'https://optimism-sepolia.blockscout.com/api', + } + }, + }) +``` + + C. `createConfig` कॉलमध्ये नवीन चेन जोडा. + + ```ts + export const config = createConfig({ + chains: [sepolia, optimismSepolia], + connectors: [ + injected(), + ], + transports: { + [optimismSepolia.id]: http(), + [sepolia.id]: http() + }, + multiInjectedProviderDiscovery: false, + }) +``` + +2. Sepolia वरील स्वयंचलित स्विच कमेंट आऊट करण्यासाठी `src/App.tsx` एडिट करा. प्रोडक्शन सिस्टीमवर, तुम्ही कदाचित तुम्ही सपोर्ट करत असलेल्या प्रत्येक ब्लॉकचेनच्या लिंक्ससह बटणे दाखवाल. + + ```ts + /* useEffect(() => { + if (connection.status === 'connected' && + connection.chainId !== SEPOLIA_CHAIN_ID + ) { + switchChain({ chainId: SEPOLIA_CHAIN_ID }) + } + }, [connection.status, connection.chainId]) */ + + + + + + + + + +``` + +3. ॲप्लिकेशनला नवीन नेटवर्कवरील तुमच्या कॉन्ट्रॅक्ट्सचा ॲड्रेस माहित आहे याची खात्री करण्यासाठी `src/Greeter.tsx` एडिट करा. + + ```ts + const contractAddrs: AddressPerBlockchainType = { + // ऑप्टिमिझम सेपोलिया + 11155420: "0x4dd85791923E9294E934271522f63875EAe5806f", + + // सेपोलिया + 11155111: "0x7143d5c190F048C8d19fe325b748b081903E3BF0", + } +``` + +4. तुमच्या ब्राउझरमध्ये. + + A. [ChainList](https://chainlist.org/chain/11155420?testnets=true) वर जा आणि तुमच्या वॉलेटमध्ये चेन जोडण्यासाठी टेबलच्या उजव्या बाजूला असलेल्या बटणांपैकी एकावर क्लिक करा. + + B. ॲप्लिकेशनमध्ये, ब्लॉकचेन बदलण्यासाठी **Disconnect** करा आणि नंतर पुन्हा कनेक्ट करा. हे हाताळण्याचे अधिक चांगले मार्ग आहेत, परंतु त्यासाठी ॲप्लिकेशनमध्ये बदल करावे लागतील. + +## निष्कर्ष {#conclusion} + +अर्थात, तुम्हाला `Greeter` साठी युजर इंटरफेस प्रदान करण्याची खरोखर काळजी नाही. तुम्हाला तुमच्या स्वतःच्या कॉन्ट्रॅक्ट्ससाठी युजर इंटरफेस तयार करायचा आहे. तुमचे स्वतःचे ॲप्लिकेशन तयार करण्यासाठी, या पायऱ्या रन करा: + +1. wagmi ॲप्लिकेशन तयार करण्यासाठी निर्दिष्ट करा. + + ```sh copy + npm create wagmi +``` + +2. पुढे जाण्यासाठी `y` टाईप करा. + +3. ॲप्लिकेशनला नाव द्या. + +4. **React** फ्रेमवर्क निवडा. + +5. **Vite** व्हेरिएंट निवडा. + +आता जा आणि तुमचे कॉन्ट्रॅक्ट्स संपूर्ण जगासाठी वापरण्यायोग्य बनवा. + +[माझ्या अधिक कामासाठी येथे पहा](https://cryptodocguy.pro/). \ No newline at end of file From b6aa73a89be96c462dd3da669a8188fd143e0f91 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:39:57 -0700 Subject: [PATCH 7/9] i18n(mr): Gemini translation --- .../uniswap-v2-annotated-code/index.md | 1972 +++++++++++++++++ 1 file changed, 1972 insertions(+) create mode 100644 public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md diff --git a/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md b/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md new file mode 100644 index 00000000000..20aac56cd02 --- /dev/null +++ b/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md @@ -0,0 +1,1972 @@ +--- +title: "Uniswap-v2 कॉन्ट्रॅक्ट वॉक-थ्रू" +description: Uniswap-v2 कॉन्ट्रॅक्ट कसे काम करते? ते तसे का लिहिले आहे? +author: Ori Pomerantz +tags: ["solidity", "डॅप्स"] +skill: intermediate +breadcrumb: Uniswap v2 वॉक-थ्रू +published: 2021-05-01 +lang: mr +--- +## परिचय {#introduction} + +[Uniswap v2](https://app.uniswap.org/whitepaper.pdf) कोणत्याही दोन ERC-20 टोकन्स दरम्यान एक्सचेंज मार्केट तयार करू शकते. या लेखामध्ये आपण या प्रोटोकॉलची अंमलबजावणी करणाऱ्या कॉन्ट्रॅक्ट्सच्या सोर्स कोडवर नजर टाकू आणि ते अशा प्रकारे का लिहिले आहेत ते पाहू. + +### Uniswap काय करते? {#what-does-uniswap-do} + +मूलतः, वापरकर्त्यांचे दोन प्रकार आहेत: लिक्विडिटी प्रोव्हायडर्स (तरलता पुरवठादार) आणि ट्रेडर्स (व्यापारी). + +_लिक्विडिटी प्रोव्हायडर्स_ पूलला दोन टोकन्स पुरवतात ज्यांची देवाणघेवाण केली जाऊ शकते (आपण त्यांना **Token0** आणि **Token1** म्हणू). या बदल्यात, त्यांना एक तिसरे टोकन मिळते जे पूलच्या आंशिक मालकीचे प्रतिनिधित्व करते, ज्याला _लिक्विडिटी टोकन_ म्हणतात. + +_ट्रेडर्स_ पूलमध्ये एका प्रकारचे टोकन पाठवतात आणि लिक्विडिटी प्रोव्हायडर्सनी पुरवलेल्या पूलमधून दुसरे टोकन प्राप्त करतात (उदाहरणार्थ, **Token0** पाठवा आणि **Token1** प्राप्त करा). विनिमय दर (एक्सचेंज रेट) पूलकडे असलेल्या **Token0** आणि **Token1** च्या सापेक्ष संख्येनुसार ठरवला जातो. याव्यतिरिक्त, पूल लिक्विडिटी पूलसाठी बक्षीस म्हणून काही टक्केवारी घेतो. + +जेव्हा लिक्विडिटी प्रोव्हायडर्सना त्यांची मालमत्ता परत हवी असते, तेव्हा ते पूल टोकन्स बर्न करू शकतात आणि बक्षिसांमधील त्यांच्या वाट्यासह त्यांचे टोकन्स परत मिळवू शकतात. + +[अधिक सविस्तर माहितीसाठी येथे क्लिक करा](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/swaps/). + +### v2 का? v3 का नाही? {#why-v2} + +[Uniswap v3](https://app.uniswap.org/whitepaper-v3.pdf) हे एक अपग्रेड आहे जे v2 पेक्षा खूपच गुंतागुंतीचे आहे. आधी v2 शिकणे आणि नंतर v3 कडे जाणे सोपे आहे. + +### कोअर कॉन्ट्रॅक्ट्स विरूद्ध पेरिफेरी कॉन्ट्रॅक्ट्स {#contract-types} + +Uniswap v2 दोन घटकांमध्ये विभागलेले आहे, एक कोअर (मुख्य) आणि एक पेरिफेरी (बाह्य). या विभागणीमुळे कोअर कॉन्ट्रॅक्ट्स, ज्यांच्याकडे मालमत्ता असते आणि त्यामुळे ते सुरक्षित _असायलाच_ हवेत, अधिक सोपे आणि ऑडिट करण्यासाठी सोयीस्कर बनतात. ट्रेडर्सना आवश्यक असलेली सर्व अतिरिक्त कार्यक्षमता नंतर पेरिफेरी कॉन्ट्रॅक्ट्सद्वारे प्रदान केली जाऊ शकते. + +## डेटा आणि कंट्रोल फ्लो {#flows} + +जेव्हा तुम्ही Uniswap च्या तीन मुख्य क्रिया करता तेव्हा डेटा आणि कंट्रोलचा फ्लो असा असतो: + +1. वेगवेगळ्या टोकन्समध्ये स्वॅप करणे +2. मार्केटमध्ये लिक्विडिटी जोडणे आणि पेअर एक्सचेंज ERC-20 लिक्विडिटी टोकन्सच्या स्वरूपात रिवॉर्ड मिळवणे +3. ERC-20 लिक्विडिटी टोकन्स बर्न करणे आणि पेअर एक्सचेंज ट्रेडर्सना एक्सचेंज करण्याची परवानगी देणारे ERC-20 टोकन्स परत मिळवणे + +### स्वॅप {#swap-flow} + +हा सर्वात सामान्य फ्लो आहे, जो ट्रेडर्सद्वारे वापरला जातो: + +#### कॉलर {#caller} + +1. स्वॅप करायच्या रकमेसाठी पेरिफेरी अकाउंटला अलाउन्स (allowance) प्रदान करा. +2. पेरिफेरी कॉन्ट्रॅक्टच्या अनेक स्वॅप फंक्शन्सपैकी एकाला कॉल करा (कोणते फंक्शन कॉल करायचे हे ETH समाविष्ट आहे की नाही, ट्रेडरने जमा करायच्या टोकन्सची रक्कम किंवा परत मिळवायच्या टोकन्सची रक्कम निर्दिष्ट केली आहे की नाही, इत्यादींवर अवलंबून असते). + प्रत्येक स्वॅप फंक्शन `path` स्वीकारते, जो पार करायच्या एक्सचेंजेसचा एक अ‍ॅरे (array) असतो. + +#### पेरिफेरी कॉन्ट्रॅक्टमध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02-sol} + +3. पाथवरील प्रत्येक एक्सचेंजवर ट्रेड केल्या जाणाऱ्या रकमा ओळखा. +4. पाथवर इटरेट (Iterate) करते. वाटेतील प्रत्येक एक्सचेंजसाठी ते इनपुट टोकन पाठवते आणि नंतर एक्सचेंजच्या `swap` फंक्शनला कॉल करते. + बहुतेक प्रकरणांमध्ये टोकन्सचा डेस्टिनेशन अ‍ॅड्रेस हा पाथवरील पुढील पेअर एक्सचेंज असतो. अंतिम एक्सचेंजमध्ये तो ट्रेडरने दिलेला अ‍ॅड्रेस असतो. + +#### कोअर कॉन्ट्रॅक्टमध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2} + +5. कोअर कॉन्ट्रॅक्टची फसवणूक होत नाहीये आणि स्वॅपनंतर पुरेशी लिक्विडिटी राखली जाऊ शकते याची पडताळणी करा. +6. ज्ञात रिझर्व्ह व्यतिरिक्त आपल्याकडे किती अतिरिक्त टोकन्स आहेत ते पहा. ती रक्कम म्हणजे एक्सचेंज करण्यासाठी आपल्याला मिळालेल्या इनपुट टोकन्सची संख्या आहे. +7. आउटपुट टोकन्स डेस्टिनेशनवर पाठवा. +8. रिझर्व्ह रकमा अपडेट करण्यासाठी `_update` ला कॉल करा + +#### परत पेरिफेरी कॉन्ट्रॅक्टमध्ये (UniswapV2Router02.sol) {#back-in-the-periphery-contract-uniswapv2router02-sol} + +9. कोणतीही आवश्यक साफसफाई करा (उदाहरणार्थ, ट्रेडरला पाठवण्यासाठी ETH परत मिळवण्यासाठी WETH टोकन्स बर्न करा) + +### लिक्विडिटी जोडणे {#add-liquidity-flow} + +#### कॉलर {#caller-2} + +1. लिक्विडिटी पूलमध्ये जोडल्या जाणाऱ्या रकमांसाठी पेरिफेरी अकाउंटला अलाउन्स प्रदान करा. +2. पेरिफेरी कॉन्ट्रॅक्टच्या `addLiquidity` फंक्शन्सपैकी एकाला कॉल करा. + +#### पेरिफेरी कॉन्ट्रॅक्टमध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02sol-2} + +3. आवश्यक असल्यास नवीन पेअर एक्सचेंज तयार करा +4. जर आधीपासूनच पेअर एक्सचेंज अस्तित्वात असेल, तर जोडायच्या टोकन्सच्या रकमेची गणना करा. हे दोन्ही टोकन्ससाठी समान मूल्य असणे अपेक्षित आहे, त्यामुळे नवीन टोकन्सचे विद्यमान टोकन्सशी समान गुणोत्तर असावे. +5. रकमा स्वीकार्य आहेत का ते तपासा (कॉलर्स किमान रक्कम निर्दिष्ट करू शकतात ज्याच्या खाली ते लिक्विडिटी जोडणे पसंत करणार नाहीत) +6. कोअर कॉन्ट्रॅक्टला कॉल करा. + +#### कोअर कॉन्ट्रॅक्टमध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-2} + +7. लिक्विडिटी टोकन्स मिंट करा आणि ते कॉलरला पाठवा +8. रिझर्व्ह रकमा अपडेट करण्यासाठी `_update` ला कॉल करा + +### लिक्विडिटी काढून टाकणे {#remove-liquidity-flow} + +#### कॉलर {#caller-3} + +1. अंडरलाइंग टोकन्सच्या बदल्यात बर्न करण्यासाठी पेरिफेरी अकाउंटला लिक्विडिटी टोकन्सचा अलाउन्स प्रदान करा. +2. पेरिफेरी कॉन्ट्रॅक्टच्या `removeLiquidity` फंक्शन्सपैकी एकाला कॉल करा. + +#### पेरिफेरी कॉन्ट्रॅक्टमध्ये (UniswapV2Router02.sol) {#in-the-periphery-contract-uniswapv2router02sol-3} + +3. पेअर एक्सचेंजला लिक्विडिटी टोकन्स पाठवा + +#### कोअर कॉन्ट्रॅक्टमध्ये (UniswapV2Pair.sol) {#in-the-core-contract-uniswapv2pairsol-3} + +4. बर्न केलेल्या टोकन्सच्या प्रमाणात डेस्टिनेशन अ‍ॅड्रेसवर अंडरलाइंग टोकन्स पाठवा. उदाहरणार्थ, जर पूलमध्ये 1000 A टोकन्स, 500 B टोकन्स आणि 90 लिक्विडिटी टोकन्स असतील आणि आपल्याला बर्न करण्यासाठी 9 टोकन्स मिळाले, तर आपण 10% लिक्विडिटी टोकन्स बर्न करत आहोत, त्यामुळे आपण वापरकर्त्याला 100 A टोकन्स आणि 50 B टोकन्स परत पाठवतो. +5. लिक्विडिटी टोकन्स बर्न करा +6. रिझर्व्ह रकमा अपडेट करण्यासाठी `_update` ला कॉल करा + +## मुख्य कॉन्ट्रॅक्ट्स {#core-contracts} + +हे सुरक्षित कॉन्ट्रॅक्ट्स आहेत जे लिक्विडिटी (तरलता) धारण करतात. + +### UniswapV2Pair.sol {#UniswapV2Pair} + +[हे कॉन्ट्रॅक्ट](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol) प्रत्यक्ष पूल लागू करते जे टोकन्सची देवाणघेवाण करते. ही मुख्य Uniswap कार्यक्षमता आहे. + +```solidity +pragma solidity =0.5.16; + +import './interfaces/IUniswapV2Pair.sol'; +import './UniswapV2ERC20.sol'; +import './libraries/Math.sol'; +import './libraries/UQ112x112.sol'; +import './interfaces/IERC20.sol'; +import './interfaces/IUniswapV2Factory.sol'; +import './interfaces/IUniswapV2Callee.sol'; +``` + +हे सर्व इंटरफेसेस आहेत ज्यांच्याबद्दल कॉन्ट्रॅक्टला माहिती असणे आवश्यक आहे, एकतर कारण कॉन्ट्रॅक्ट त्यांची अंमलबजावणी करते (`IUniswapV2Pair` आणि `UniswapV2ERC20`) किंवा कारण ते त्यांची अंमलबजावणी करणाऱ्या कॉन्ट्रॅक्ट्सना कॉल करते. + +```solidity +contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20 { +``` + +हे कॉन्ट्रॅक्ट `UniswapV2ERC20` कडून इनहेरिट करते, जे लिक्विडिटी टोकन्ससाठी ERC-20 फंक्शन्स प्रदान करते. + +```solidity + using SafeMath for uint; +``` + +ओव्हरफ्लो आणि अंडरफ्लो टाळण्यासाठी [SafeMath लायब्ररी](https://docs.openzeppelin.com/contracts/2.x/api/math) वापरली जाते. हे महत्त्वाचे आहे कारण अन्यथा आपण अशा परिस्थितीत अडकू शकतो जिथे मूल्य `-1` असावे, परंतु त्याऐवजी ते `2^256-1` असते. + +```solidity + using UQ112x112 for uint224; +``` + +पूल कॉन्ट्रॅक्टमधील अनेक गणनेसाठी अपूर्णांकांची आवश्यकता असते. तथापि, EVM द्वारे अपूर्णांकांना सपोर्ट नाही. +Uniswap ने शोधलेला उपाय म्हणजे 224 बिट व्हॅल्यूज वापरणे, ज्यामध्ये पूर्णांक भागासाठी 112 बिट्स आणि अपूर्णांकासाठी 112 बिट्स असतात. त्यामुळे `1.0` हे `2^112` म्हणून दर्शविले जाते, `1.5` हे `2^112 + 2^111` म्हणून दर्शविले जाते, इ. + +या लायब्ररीबद्दल अधिक तपशील [डॉक्युमेंटमध्ये पुढे](#FixedPoint) उपलब्ध आहेत. + +#### व्हेरिएबल्स {#pair-vars} + +```solidity + uint public constant MINIMUM_LIQUIDITY = 10**3; +``` + +शून्याने भाग जाण्याची प्रकरणे टाळण्यासाठी, लिक्विडिटी टोकन्सची किमान संख्या असते जी नेहमी अस्तित्वात असते (परंतु ती अकाउंट झिरोच्या मालकीची असते). ती संख्या **MINIMUM_LIQUIDITY** आहे, एक हजार. + +```solidity + bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)'))); +``` + +हा ERC-20 ट्रान्सफर फंक्शनसाठी ABI सिलेक्टर आहे. याचा वापर दोन टोकन अकाउंट्समध्ये ERC-20 टोकन्स ट्रान्सफर करण्यासाठी केला जातो. + +```solidity + address public factory; +``` + +हे फॅक्टरी कॉन्ट्रॅक्ट आहे ज्याने हा पूल तयार केला आहे. प्रत्येक पूल हा दोन ERC-20 टोकन्समधील एक्सचेंज आहे, फॅक्टरी हा एक मध्यवर्ती बिंदू आहे जो या सर्व पूल्सना जोडतो. + +```solidity + address public token0; + address public token1; +``` + +या पूलद्वारे एक्सचेंज केल्या जाऊ शकणाऱ्या दोन प्रकारच्या ERC-20 टोकन्ससाठी कॉन्ट्रॅक्ट्सचे पत्ते येथे आहेत. + +```solidity + uint112 private reserve0; // एकाच स्टोरेज स्लॉटचा वापर करते, getReserves द्वारे प्रवेश करण्यायोग्य + uint112 private reserve1; // एकाच स्टोरेज स्लॉटचा वापर करते, getReserves द्वारे प्रवेश करण्यायोग्य +``` + +प्रत्येक टोकन प्रकारासाठी पूलकडे असलेले रिझर्व्ह्स. आम्ही असे गृहीत धरतो की दोन्ही समान मूल्याचे प्रतिनिधित्व करतात आणि म्हणून प्रत्येक token0 ची किंमत reserve1/reserve0 token1 इतकी असते. + +```solidity + uint32 private blockTimestampLast; // एकाच स्टोरेज स्लॉटचा वापर करते, getReserves द्वारे प्रवेश करण्यायोग्य +``` + +ज्या शेवटच्या ब्लॉकमध्ये एक्सचेंज झाले त्याचा टाइमस्टॅम्प, जो वेळेनुसार एक्सचेंज रेट्स ट्रॅक करण्यासाठी वापरला जातो. + +Ethereum कॉन्ट्रॅक्ट्सच्या सर्वात मोठ्या गॅस खर्चांपैकी एक म्हणजे स्टोरेज, जे कॉन्ट्रॅक्टच्या एका कॉलपासून दुसऱ्या कॉलपर्यंत टिकून राहते. प्रत्येक स्टोरेज सेल 256 बिट्स लांब असतो. त्यामुळे तीन व्हेरिएबल्स, `reserve0`, `reserve1`, आणि `blockTimestampLast`, अशा प्रकारे वाटप केले जातात की एकाच स्टोरेज व्हॅल्यूमध्ये त्या तिन्हींचा समावेश होऊ शकतो (112+112+32=256). + +```solidity + uint public price0CumulativeLast; + uint public price1CumulativeLast; +``` + +हे व्हेरिएबल्स प्रत्येक टोकनसाठी (प्रत्येक दुसऱ्याच्या संदर्भात) एकत्रित खर्च धारण करतात. त्यांचा वापर ठराविक कालावधीत सरासरी एक्सचेंज रेट मोजण्यासाठी केला जाऊ शकतो. + +```solidity + uint public kLast; // reserve0 * reserve1, सर्वात अलीकडील लिक्विडिटी इव्हेंटच्या लगेच नंतर +``` + +पेअर एक्सचेंज ज्या प्रकारे token0 आणि token1 मधील एक्सचेंज रेट ठरवते ते म्हणजे ट्रेड्स दरम्यान दोन रिझर्व्ह्सचा गुणाकार स्थिर ठेवणे. `kLast` हे ते मूल्य आहे. जेव्हा लिक्विडिटी प्रोव्हायडर टोकन्स जमा करतो किंवा काढतो तेव्हा ते बदलते आणि 0.3% मार्केट फीमुळे ते थोडे वाढते. + +येथे एक साधे उदाहरण आहे. लक्षात घ्या की साधेपणासाठी टेबलमध्ये दशांश चिन्हानंतर फक्त तीन अंक आहेत आणि आम्ही 0.3% ट्रेडिंग फीकडे दुर्लक्ष करतो त्यामुळे आकडे अचूक नाहीत. + +| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | सरासरी एक्सचेंज रेट (token1 / token0) | +| ------------------------------------------- | --------: | --------: | -------------------: | --------------------------------------- | +| प्रारंभिक सेटअप | 1,000.000 | 1,000.000 | 1,000,000 | | +| ट्रेडर A 47.619 token1 साठी 50 token0 स्वॅप करतो | 1,050.000 | 952.381 | 1,000,000 | 0.952 | +| ट्रेडर B 8.984 token1 साठी 10 token0 स्वॅप करतो | 1,060.000 | 943.396 | 1,000,000 | 0.898 | +| ट्रेडर C 34.305 token1 साठी 40 token0 स्वॅप करतो | 1,100.000 | 909.090 | 1,000,000 | 0.858 | +| ट्रेडर D 109.01 token0 साठी 100 token1 स्वॅप करतो | 990.990 | 1,009.090 | 1,000,000 | 0.917 | +| ट्रेडर E 10.079 token1 साठी 10 token0 स्वॅप करतो | 1,000.990 | 999.010 | 1,000,000 | 1.008 | + +जसे ट्रेडर्स अधिक token0 प्रदान करतात, तसे पुरवठा आणि मागणीच्या आधारावर token1 चे सापेक्ष मूल्य वाढते आणि याउलट. + +#### लॉक {#pair-lock} + +```solidity + uint private unlocked = 1; +``` + +सुरक्षा भेद्यतेचा एक वर्ग आहे जो [रीएन्ट्रन्सी गैरवापरावर](https://medium.com/coinmonks/ethernaut-lvl-10-re-entrancy-walkthrough-how-to-abuse-execution-ordering-and-reproduce-the-dao-7ec88b912c14) आधारित आहे. Uniswap ला अनियंत्रित ERC-20 टोकन्स ट्रान्सफर करणे आवश्यक आहे, ज्याचा अर्थ अशा ERC-20 कॉन्ट्रॅक्ट्सना कॉल करणे जे त्यांना कॉल करणाऱ्या Uniswap मार्केटचा गैरवापर करण्याचा प्रयत्न करू शकतात. +कॉन्ट्रॅक्टचा भाग म्हणून `unlocked` व्हेरिएबल ठेवून, आपण फंक्शन्स चालू असताना (एकाच ट्रान्झॅक्शनमध्ये) त्यांना कॉल करण्यापासून रोखू शकतो. + +```solidity + modifier lock() { +``` + +हे फंक्शन एक [मॉडिफायर](https://docs.soliditylang.org/en/v0.8.3/contracts.html#function-modifiers) आहे, एक फंक्शन जे सामान्य फंक्शनच्या भोवती गुंडाळले जाते जेणेकरून त्याचे वर्तन काही प्रकारे बदलता येईल. + +```solidity + require(unlocked == 1, 'UniswapV2: LOCKED'); + unlocked = 0; +``` + +जर `unlocked` एक च्या बरोबरीचे असेल, तर ते शून्य वर सेट करा. जर ते आधीच शून्य असेल तर कॉल रिव्हर्ट करा, तो अयशस्वी करा. + +```solidity + _; +``` + +मॉडिफायरमध्ये `_;` हा मूळ फंक्शन कॉल असतो (सर्व पॅरामीटर्ससह). येथे याचा अर्थ असा आहे की फंक्शन कॉल तेव्हाच होतो जेव्हा कॉल केला गेला तेव्हा `unlocked` एक होता आणि ते चालू असताना `unlocked` चे मूल्य शून्य असते. + +```solidity + unlocked = 1; + } +``` + +मुख्य फंक्शन परत आल्यानंतर, लॉक रिलीज करा. + +#### संकीर्ण फंक्शन्स {#pair-misc} + +```solidity + function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { + _reserve0 = reserve0; + _reserve1 = reserve1; + _blockTimestampLast = blockTimestampLast; + } +``` + +हे फंक्शन कॉलर्सना एक्सचेंजची सद्यस्थिती प्रदान करते. लक्षात घ्या की Solidity फंक्शन्स [एकाधिक मूल्ये परत करू शकतात](https://docs.soliditylang.org/en/v0.8.3/contracts.html#returning-multiple-values). + +```solidity + function _safeTransfer(address token, address to, uint value) private { + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value)); +``` + +हे अंतर्गत फंक्शन एक्सचेंजमधून दुसऱ्या कोणालातरी ERC20 टोकन्सची रक्कम ट्रान्सफर करते. `SELECTOR` हे निर्दिष्ट करते की आपण कॉल करत असलेले फंक्शन `transfer(address,uint)` आहे (वरील व्याख्या पहा). + +टोकन फंक्शनसाठी इंटरफेस इम्पोर्ट करणे टाळण्यासाठी, आम्ही [ABI फंक्शन्सपैकी](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html#abi-encoding-and-decoding-functions) एकाचा वापर करून "मॅन्युअली" कॉल तयार करतो. + +```solidity + require(success && (data.length == 0 || abi.decode(data, (bool))), 'UniswapV2: TRANSFER_FAILED'); + } +``` + +ERC-20 ट्रान्सफर कॉल अपयश नोंदवू शकण्याचे दोन मार्ग आहेत: + +1. रिव्हर्ट. जर बाह्य कॉन्ट्रॅक्टचा कॉल रिव्हर्ट झाला, तर बुलियन रिटर्न व्हॅल्यू `false` असते +2. सामान्यपणे समाप्त करा परंतु अपयश नोंदवा. त्या बाबतीत रिटर्न व्हॅल्यू बफरची लांबी नॉन-झिरो असते आणि जेव्हा बुलियन व्हॅल्यू म्हणून डीकोड केले जाते तेव्हा ते `false` असते + +यापैकी कोणतीही परिस्थिती उद्भवल्यास, रिव्हर्ट करा. + +#### इव्हेंट्स {#pair-events} + +```solidity + event Mint(address indexed sender, uint amount0, uint amount1); + event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); +``` + +जेव्हा लिक्विडिटी प्रोव्हायडर एकतर लिक्विडिटी जमा करतो (`Mint`) किंवा ती काढतो (`Burn`) तेव्हा हे दोन इव्हेंट्स एमिट केले जातात. दोन्ही प्रकरणांमध्ये, जमा केलेल्या किंवा काढलेल्या token0 आणि token1 ची रक्कम इव्हेंटचा भाग असते, तसेच आम्हाला कॉल करणाऱ्या अकाउंटची ओळख (`sender`). पैसे काढण्याच्या बाबतीत, इव्हेंटमध्ये टोकन्स प्राप्त करणारे लक्ष्य (`to`) देखील समाविष्ट असते, जे सेंडरसारखे नसू शकते. + +```solidity + event Swap( + address indexed sender, + uint amount0In, + uint amount1In, + uint amount0Out, + uint amount1Out, + address indexed to + ); +``` + +जेव्हा एखादा ट्रेडर एका टोकनची दुसऱ्या टोकनसाठी देवाणघेवाण करतो तेव्हा हा इव्हेंट एमिट केला जातो. पुन्हा, सेंडर आणि डेस्टिनेशन समान नसू शकतात. +प्रत्येक टोकन एकतर एक्सचेंजला पाठवले जाऊ शकते किंवा त्यातून प्राप्त केले जाऊ शकते. + +```solidity + event Sync(uint112 reserve0, uint112 reserve1); +``` + +शेवटी, नवीनतम रिझर्व्ह माहिती (आणि म्हणून एक्सचेंज रेट) प्रदान करण्यासाठी, कारण काहीही असले तरी, प्रत्येक वेळी टोकन्स जोडले किंवा काढले जातात तेव्हा `Sync` एमिट केले जाते. + +#### सेटअप फंक्शन्स {#pair-setup} + +जेव्हा नवीन पेअर एक्सचेंज सेट केले जाते तेव्हा ही फंक्शन्स एकदा कॉल केली जावीत. + +```solidity + constructor() public { + factory = msg.sender; + } +``` + +कन्स्ट्रक्टर हे सुनिश्चित करतो की आम्ही पेअर तयार करणाऱ्या फॅक्टरीच्या पत्त्याचा मागोवा ठेवू. ही माहिती `initialize` साठी आणि फॅक्टरी फीसाठी (जर अस्तित्वात असेल तर) आवश्यक आहे + +```solidity + // डिप्लॉयमेंटच्या वेळी फॅक्टरीद्वारे एकदाच कॉल केले जाते + function initialize(address _token0, address _token1) external { + require(msg.sender == factory, 'UniswapV2: FORBIDDEN'); // पुरेशी तपासणी + token0 = _token0; + token1 = _token1; + } +``` + +हे फंक्शन फॅक्टरीला (आणि फक्त फॅक्टरीला) दोन ERC-20 टोकन्स निर्दिष्ट करण्याची परवानगी देते ज्यांची ही पेअर देवाणघेवाण करेल. + +#### अंतर्गत अपडेट फंक्शन्स {#pair-update-internal} + +##### \_update + +```solidity + // रिझर्व्ह अपडेट करा आणि, प्रति ब्लॉक पहिल्या कॉलवर, प्राईस अ‍ॅक्युम्युलेटर्स अपडेट करा + function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private { +``` + +प्रत्येक वेळी टोकन्स जमा केल्यावर किंवा काढल्यावर हे फंक्शन कॉल केले जाते. + +```solidity + require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'UniswapV2: OVERFLOW'); +``` + +जर balance0 किंवा balance1 (uint256) पैकी एक uint112(-1) (=2^112-1) पेक्षा जास्त असेल (त्यामुळे ते ओव्हरफ्लो होते आणि uint112 मध्ये रूपांतरित केल्यावर 0 वर परत येते) तर ओव्हरफ्लो टाळण्यासाठी \_update सुरू ठेवण्यास नकार द्या. 10^18 युनिट्समध्ये विभागल्या जाऊ शकणाऱ्या सामान्य टोकनसह, याचा अर्थ प्रत्येक एक्सचेंज प्रत्येक टोकनच्या सुमारे 5.1\*10^15 पर्यंत मर्यादित आहे. आतापर्यंत ही समस्या उद्भवलेली नाही. + +```solidity + uint32 blockTimestamp = uint32(block.timestamp % 2**32); + uint32 timeElapsed = blockTimestamp - blockTimestampLast; // ओव्हरफ्लो अपेक्षित आहे + if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) { +``` + +जर गेलेला वेळ शून्य नसेल, तर याचा अर्थ आपण या ब्लॉकवरील पहिले एक्सचेंज ट्रान्झॅक्शन आहोत. त्या बाबतीत, आम्हाला कॉस्ट ॲक्युम्युलेटर्स अपडेट करणे आवश्यक आहे. + +```solidity + // * कधीही ओव्हरफ्लो होत नाही, आणि + ओव्हरफ्लो अपेक्षित आहे + price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; + price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed; + } +``` + +प्रत्येक कॉस्ट ॲक्युम्युलेटर नवीनतम कॉस्ट (दुसऱ्या टोकनचा रिझर्व्ह/या टोकनचा रिझर्व्ह) गुणिले सेकंदांमध्ये गेलेला वेळ यासह अपडेट केला जातो. सरासरी किंमत मिळवण्यासाठी, तुम्ही वेळेच्या दोन बिंदूंमधील एकत्रित किंमत वाचता आणि त्यांच्यातील वेळेच्या फरकाने भागता. उदाहरणार्थ, इव्हेंट्सचा हा क्रम गृहीत धरा: + +| इव्हेंट | reserve0 | reserve1 | टाइमस्टॅम्प | मार्जिनल एक्सचेंज रेट (reserve1 / reserve0) | price0CumulativeLast | +| -------------------------------------------------------- | --------: | --------: | --------- | -------------------------------------------: | -------------------------: | +| प्रारंभिक सेटअप | 1,000.000 | 1,000.000 | 5,000 | 1.000 | 0 | +| ट्रेडर A 50 token0 जमा करतो आणि 47.619 token1 परत मिळवतो | 1,050.000 | 952.381 | 5,020 | 0.907 | 20 | +| ट्रेडर B 10 token0 जमा करतो आणि 8.984 token1 परत मिळवतो | 1,060.000 | 943.396 | 5,030 | 0.890 | 20+10\*0.907 = 29.07 | +| ट्रेडर C 40 token0 जमा करतो आणि 34.305 token1 परत मिळवतो | 1,100.000 | 909.090 | 5,100 | 0.826 | 29.07+70\*0.890 = 91.37 | +| ट्रेडर D 100 token1 जमा करतो आणि 109.01 token0 परत मिळवतो | 990.990 | 1,009.090 | 5,110 | 1.018 | 91.37+10\*0.826 = 99.63 | +| ट्रेडर E 10 token0 जमा करतो आणि 10.079 token1 परत मिळवतो | 1,000.990 | 999.010 | 5,150 | 0.998 | 99.63+40\*1.1018 = 143.702 | + +समजा आपल्याला 5,030 आणि 5,150 या टाइमस्टॅम्प्स दरम्यान **Token0** ची सरासरी किंमत मोजायची आहे. `price0Cumulative` च्या मूल्यातील फरक 143.702-29.07=114.632 आहे. ही दोन मिनिटांची (120 सेकंद) सरासरी आहे. त्यामुळे सरासरी किंमत 114.632/120 = 0.955 आहे. + +या किंमतीच्या गणनेमुळेच आपल्याला जुन्या रिझर्व्ह आकारांची माहिती असणे आवश्यक आहे. + +```solidity + reserve0 = uint112(balance0); + reserve1 = uint112(balance1); + blockTimestampLast = blockTimestamp; + emit Sync(reserve0, reserve1); + } +``` + +शेवटी, ग्लोबल व्हेरिएबल्स अपडेट करा आणि `Sync` इव्हेंट एमिट करा. + +##### \_mintFee + +```solidity + // जर फी चालू असेल, तर sqrt(k) मधील वाढीच्या 1/6 च्या समतुल्य लिक्विडिटी मिंट करा + function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) { +``` + +Uniswap 2.0 मध्ये ट्रेडर्स मार्केट वापरण्यासाठी 0.30% फी भरतात. त्या फीचा बहुतांश भाग (ट्रेडचा 0.25%) नेहमी लिक्विडिटी प्रोव्हायडर्सना जातो. उर्वरित 0.05% एकतर लिक्विडिटी प्रोव्हायडर्सना किंवा फॅक्टरीद्वारे प्रोटोकॉल फी म्हणून निर्दिष्ट केलेल्या पत्त्यावर जाऊ शकतो, जो Uniswap ला त्यांच्या विकास प्रयत्नांसाठी पैसे देतो. + +गणने कमी करण्यासाठी (आणि त्यामुळे गॅस खर्च), ही फी प्रत्येक ट्रान्झॅक्शनच्या ऐवजी केवळ पूलमधून लिक्विडिटी जोडली किंवा काढली जाते तेव्हाच मोजली जाते. + +```solidity + address feeTo = IUniswapV2Factory(factory).feeTo(); + feeOn = feeTo != address(0); +``` + +फॅक्टरीचे फी डेस्टिनेशन वाचा. जर ते शून्य असेल तर कोणतीही प्रोटोकॉल फी नाही आणि ती फी मोजण्याची गरज नाही. + +```solidity + uint _kLast = kLast; // गॅसची बचत +``` + +`kLast` स्टेट व्हेरिएबल स्टोरेजमध्ये स्थित आहे, त्यामुळे कॉन्ट्रॅक्टच्या वेगवेगळ्या कॉल्स दरम्यान त्याचे मूल्य असेल. +स्टोरेजचा ॲक्सेस हा व्होलॅटाईल मेमरीच्या ॲक्सेसपेक्षा खूप महाग आहे जी कॉन्ट्रॅक्टचा फंक्शन कॉल संपल्यावर रिलीज होते, त्यामुळे गॅस वाचवण्यासाठी आम्ही अंतर्गत व्हेरिएबल वापरतो. + +```solidity + if (feeOn) { + if (_kLast != 0) { +``` + +लिक्विडिटी प्रोव्हायडर्सना त्यांचा वाटा केवळ त्यांच्या लिक्विडिटी टोकन्सच्या वाढीमुळे मिळतो. परंतु प्रोटोकॉल फीसाठी नवीन लिक्विडिटी टोकन्स मिंट करणे आणि `feeTo` पत्त्यावर प्रदान करणे आवश्यक आहे. + +```solidity + uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1)); + uint rootKLast = Math.sqrt(_kLast); + if (rootK > rootKLast) { +``` + +जर नवीन लिक्विडिटी असेल ज्यावर प्रोटोकॉल फी गोळा करायची असेल. तुम्ही स्क्वेअर रूट फंक्शन [या लेखात पुढे](#Math) पाहू शकता + +```solidity + uint numerator = totalSupply.mul(rootK.sub(rootKLast)); + uint denominator = rootK.mul(5).add(rootKLast); + uint liquidity = numerator / denominator; +``` + +फीची ही गुंतागुंतीची गणना [व्हाईटपेपरमध्ये](https://app.uniswap.org/whitepaper.pdf) पृष्ठ 5 वर स्पष्ट केली आहे. आम्हाला माहित आहे की `kLast` मोजल्या गेलेल्या वेळेपासून ते आतापर्यंत कोणतीही लिक्विडिटी जोडली किंवा काढली गेली नाही (कारण आम्ही प्रत्येक वेळी लिक्विडिटी जोडली किंवा काढली जाते तेव्हा, ती प्रत्यक्षात बदलण्यापूर्वी ही गणना चालवतो), त्यामुळे `reserve0 * reserve1` मधील कोणताही बदल ट्रान्झॅक्शन फीमधून आला पाहिजे (त्यांच्याशिवाय आम्ही `reserve0 * reserve1` स्थिर ठेवू). + +```solidity + if (liquidity > 0) _mint(feeTo, liquidity); + } + } +``` + +अतिरिक्त लिक्विडिटी टोकन्स प्रत्यक्षात तयार करण्यासाठी आणि त्यांना `feeTo` ला नियुक्त करण्यासाठी `UniswapV2ERC20._mint` फंक्शन वापरा. + +```solidity + } else if (_kLast != 0) { + kLast = 0; + } + } +``` + +जर कोणतीही फी नसेल तर `kLast` शून्य वर सेट करा (जर ते आधीच नसेल तर). जेव्हा हे कॉन्ट्रॅक्ट लिहिले गेले तेव्हा एक [गॅस रिफंड वैशिष्ट्य](https://eips.ethereum.org/EIPS/eip-3298) होते ज्याने कॉन्ट्रॅक्ट्सना त्यांना आवश्यक नसलेले स्टोरेज शून्य करून Ethereum स्टेटचा एकूण आकार कमी करण्यास प्रोत्साहित केले. +शक्य असेल तेव्हा या कोडला तो रिफंड मिळतो. + +#### बाह्यरित्या ॲक्सेसिबल फंक्शन्स {#pair-external} + +लक्षात घ्या की कोणतेही ट्रान्झॅक्शन किंवा कॉन्ट्रॅक्ट या फंक्शन्सना कॉल _करू शकते_, तरीही ते पेरिफेरी कॉन्ट्रॅक्टमधून कॉल करण्यासाठी डिझाइन केलेले आहेत. जर तुम्ही त्यांना थेट कॉल केले तर तुम्ही पेअर एक्सचेंजला फसवू शकणार नाही, परंतु तुम्ही चुकीमुळे मूल्य गमावू शकता. + +##### mint + +```solidity + // हे लो-लेव्हल फंक्शन अशा कॉन्ट्रॅक्टमधून कॉल केले जावे जे महत्त्वाच्या सुरक्षितता तपासण्या करते + function mint(address to) external lock returns (uint liquidity) { +``` + +जेव्हा लिक्विडिटी प्रोव्हायडर पूलमध्ये लिक्विडिटी जोडतो तेव्हा हे फंक्शन कॉल केले जाते. हे बक्षीस म्हणून अतिरिक्त लिक्विडिटी टोकन्स मिंट करते. हे [पेरिफेरी कॉन्ट्रॅक्टमधून](#UniswapV2Router02) कॉल केले जावे जे एकाच ट्रान्झॅक्शनमध्ये लिक्विडिटी जोडल्यानंतर त्याला कॉल करते (जेणेकरून कायदेशीर मालकापूर्वी नवीन लिक्विडिटीचा दावा करणारे ट्रान्झॅक्शन इतर कोणीही सबमिट करू शकणार नाही). + +```solidity + (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // गॅसची बचत +``` + +एकाधिक मूल्ये परत करणाऱ्या Solidity फंक्शनचे परिणाम वाचण्याचा हा मार्ग आहे. आम्ही शेवटची परत केलेली मूल्ये, ब्लॉक टाइमस्टॅम्प, टाकून देतो कारण आम्हाला त्याची आवश्यकता नाही. + +```solidity + uint balance0 = IERC20(token0).balanceOf(address(this)); + uint balance1 = IERC20(token1).balanceOf(address(this)); + uint amount0 = balance0.sub(_reserve0); + uint amount1 = balance1.sub(_reserve1); +``` + +सध्याचे बॅलन्सेस मिळवा आणि प्रत्येक टोकन प्रकाराचे किती जोडले गेले ते पहा. + +```solidity + bool feeOn = _mintFee(_reserve0, _reserve1); +``` + +गोळा करण्यासाठी प्रोटोकॉल फीची गणना करा, जर काही असेल तर, आणि त्यानुसार लिक्विडिटी टोकन्स मिंट करा. कारण `_mintFee` चे पॅरामीटर्स जुनी रिझर्व्ह मूल्ये आहेत, फीची गणना केवळ फीमुळे होणाऱ्या पूल बदलांवर आधारित अचूकपणे केली जाते. + +```solidity + uint _totalSupply = totalSupply; // गॅसची बचत, येथे परिभाषित करणे आवश्यक आहे कारण totalSupply _mintFee मध्ये अपडेट होऊ शकते + if (_totalSupply == 0) { + liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); + _mint(address(0), MINIMUM_LIQUIDITY); // पहिले MINIMUM_LIQUIDITY टोकन्स कायमचे लॉक करा +``` + +जर ही पहिली ठेव असेल, तर `MINIMUM_LIQUIDITY` टोकन्स तयार करा आणि त्यांना लॉक करण्यासाठी ॲड्रेस झिरोवर पाठवा. ते कधीही रिडीम केले जाऊ शकत नाहीत, ज्याचा अर्थ पूल कधीही पूर्णपणे रिकामा होणार नाही (हे आम्हाला काही ठिकाणी शून्याने भाग जाण्यापासून वाचवते). `MINIMUM_LIQUIDITY` चे मूल्य एक हजार आहे, जे बहुतेक ERC-20 टोकनच्या 10^-18 व्या युनिट्समध्ये विभागलेले आहेत हे लक्षात घेता, जसे ETH wei मध्ये विभागले जाते, एकाच टोकनच्या मूल्याच्या 10^-15 आहे. जास्त किंमत नाही. + +पहिल्या ठेवीच्या वेळी आम्हाला दोन टोकन्सचे सापेक्ष मूल्य माहित नसते, म्हणून आम्ही फक्त रकमांचा गुणाकार करतो आणि स्क्वेअर रूट घेतो, असे गृहीत धरून की ठेव आम्हाला दोन्ही टोकन्समध्ये समान मूल्य प्रदान करते. + +आम्ही यावर विश्वास ठेवू शकतो कारण आर्बिट्रेजमुळे मूल्य गमावणे टाळण्यासाठी समान मूल्य प्रदान करणे ठेवीदाराच्या हिताचे आहे. +समजा दोन टोकन्सचे मूल्य समान आहे, परंतु आमच्या ठेवीदाराने **Token0** च्या तुलनेत **Token1** ची चार पट जास्त ठेव ठेवली. पेअर एक्सचेंजला असे वाटते की **Token0** अधिक मौल्यवान आहे या वस्तुस्थितीचा वापर करून ट्रेडर त्यातून मूल्य काढू शकतो. + +| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | पूलचे मूल्य (reserve0 + reserve1) | +| ------------------------------------------------------------ | -------: | -------: | -------------------: | --------------------------------------: | +| प्रारंभिक सेटअप | 8 | 32 | 256 | 40 | +| ट्रेडर 8 **Token0** टोकन्स जमा करतो, 16 **Token1** परत मिळवतो | 16 | 16 | 256 | 32 | + +जसे तुम्ही पाहू शकता, ट्रेडरने अतिरिक्त 8 टोकन्स मिळवले, जे पूलच्या मूल्यातील कपातीतून येतात, ज्यामुळे त्याच्या मालक असलेल्या ठेवीदाराचे नुकसान होते. + +```solidity + } else { + liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1); +``` + +प्रत्येक त्यानंतरच्या ठेवीसह आम्हाला दोन ॲसेट्समधील एक्सचेंज रेट आधीच माहित असतो आणि आम्ही लिक्विडिटी प्रोव्हायडर्सनी दोन्हीमध्ये समान मूल्य प्रदान करण्याची अपेक्षा करतो. जर त्यांनी तसे केले नाही, तर आम्ही त्यांना शिक्षा म्हणून त्यांनी प्रदान केलेल्या कमी मूल्यावर आधारित लिक्विडिटी टोकन्स देतो. + +ती प्रारंभिक ठेव असो किंवा त्यानंतरची, आम्ही प्रदान करत असलेल्या लिक्विडिटी टोकन्सची संख्या `reserve0*reserve1` मधील बदलाच्या स्क्वेअर रूटच्या बरोबरीची असते आणि लिक्विडिटी टोकनचे मूल्य बदलत नाही (जोपर्यंत आम्हाला अशी ठेव मिळत नाही ज्यामध्ये दोन्ही प्रकारांची समान मूल्ये नाहीत, अशा परिस्थितीत "दंड" वितरित केला जातो). येथे समान मूल्य असलेल्या दोन टोकन्सचे आणखी एक उदाहरण आहे, ज्यामध्ये तीन चांगल्या ठेवी आणि एक वाईट ठेव आहे (केवळ एका टोकन प्रकाराची ठेव, त्यामुळे ती कोणतीही लिक्विडिटी टोकन्स तयार करत नाही). + +| इव्हेंट | reserve0 | reserve1 | reserve0 \* reserve1 | पूल मूल्य (reserve0 + reserve1) | या ठेवीसाठी मिंट केलेले लिक्विडिटी टोकन्स | एकूण लिक्विडिटी टोकन्स | प्रत्येक लिक्विडिटी टोकनचे मूल्य | +| ------------------------- | -------: | -------: | -------------------: | -------------------------------: | ---------------------------------------: | ---------------------: | ----------------------------: | +| प्रारंभिक सेटअप | 8.000 | 8.000 | 64 | 16.000 | 8 | 8 | 2.000 | +| प्रत्येक प्रकाराचे चार जमा करा | 12.000 | 12.000 | 144 | 24.000 | 4 | 12 | 2.000 | +| प्रत्येक प्रकाराचे दोन जमा करा | 14.000 | 14.000 | 196 | 28.000 | 2 | 14 | 2.000 | +| असमान मूल्य ठेव | 18.000 | 14.000 | 252 | 32.000 | 0 | 14 | ~2.286 | +| आर्बिट्रेजनंतर | ~15.874 | ~15.874 | 252 | ~31.748 | 0 | 14 | ~2.267 | + +```solidity + } + require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED'); + _mint(to, liquidity); +``` + +अतिरिक्त लिक्विडिटी टोकन्स प्रत्यक्षात तयार करण्यासाठी आणि त्यांना योग्य अकाउंटला देण्यासाठी `UniswapV2ERC20._mint` फंक्शन वापरा. + +```solidity + + _update(balance0, balance1, _reserve0, _reserve1); + if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 आणि reserve1 अद्ययावत आहेत + emit Mint(msg.sender, amount0, amount1); + } +``` + +स्टेट व्हेरिएबल्स (`reserve0`, `reserve1`, आणि आवश्यक असल्यास `kLast`) अपडेट करा आणि योग्य इव्हेंट एमिट करा. + +##### burn + +```solidity + // हे लो-लेव्हल फंक्शन अशा कॉन्ट्रॅक्टमधून कॉल केले जावे जे महत्त्वाच्या सुरक्षितता तपासण्या करते + function burn(address to) external lock returns (uint amount0, uint amount1) { +``` + +जेव्हा लिक्विडिटी काढली जाते आणि योग्य लिक्विडिटी टोकन्स बर्न करणे आवश्यक असते तेव्हा हे फंक्शन कॉल केले जाते. +हे [पेरिफेरी अकाउंटमधून](#UniswapV2Router02) देखील कॉल केले जावे. + +```solidity + (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // गॅसची बचत + address _token0 = token0; // गॅसची बचत + address _token1 = token1; // गॅसची बचत + uint balance0 = IERC20(_token0).balanceOf(address(this)); + uint balance1 = IERC20(_token1).balanceOf(address(this)); + uint liquidity = balanceOf[address(this)]; +``` + +पेरिफेरी कॉन्ट्रॅक्टने कॉल करण्यापूर्वी बर्न करायची लिक्विडिटी या कॉन्ट्रॅक्टमध्ये ट्रान्सफर केली. अशा प्रकारे आम्हाला माहित आहे की किती लिक्विडिटी बर्न करायची आहे आणि आम्ही खात्री करू शकतो की ती बर्न होईल. + +```solidity + bool feeOn = _mintFee(_reserve0, _reserve1); + uint _totalSupply = totalSupply; // गॅसची बचत, येथे परिभाषित करणे आवश्यक आहे कारण totalSupply _mintFee मध्ये अपडेट होऊ शकते + amount0 = liquidity.mul(balance0) / _totalSupply; // बॅलन्स वापरल्याने प्रमाणबद्ध (pro-rata) वितरण सुनिश्चित होते + amount1 = liquidity.mul(balance1) / _totalSupply; // बॅलन्स वापरल्याने प्रमाणबद्ध (pro-rata) वितरण सुनिश्चित होते + require(amount0 > 0 && amount1 > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_BURNED'); +``` + +लिक्विडिटी प्रोव्हायडरला दोन्ही टोकन्सचे समान मूल्य मिळते. अशा प्रकारे आम्ही एक्सचेंज रेट बदलत नाही. + +```solidity + _burn(address(this), liquidity); + _safeTransfer(_token0, to, amount0); + _safeTransfer(_token1, to, amount1); + balance0 = IERC20(_token0).balanceOf(address(this)); + balance1 = IERC20(_token1).balanceOf(address(this)); + + _update(balance0, balance1, _reserve0, _reserve1); + if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 आणि reserve1 अद्ययावत आहेत + emit Burn(msg.sender, amount0, amount1, to); + } + +``` + +उर्वरित `burn` फंक्शन हे वरील `mint` फंक्शनची मिरर इमेज आहे. + +##### swap + +```solidity + // हे लो-लेव्हल फंक्शन अशा कॉन्ट्रॅक्टमधून कॉल केले जावे जे महत्त्वाच्या सुरक्षितता तपासण्या करते + function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock { +``` + +हे फंक्शन देखील [पेरिफेरी कॉन्ट्रॅक्टमधून](#UniswapV2Router02) कॉल केले जावे असे अपेक्षित आहे. + +```solidity + require(amount0Out > 0 || amount1Out > 0, 'UniswapV2: INSUFFICIENT_OUTPUT_AMOUNT'); + (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // गॅसची बचत + require(amount0Out < _reserve0 && amount1Out < _reserve1, 'UniswapV2: INSUFFICIENT_LIQUIDITY'); + + uint balance0; + uint balance1; + { // _token{0,1} साठी स्कोप, 'stack too deep' एरर्स टाळतो +``` + +लोकल व्हेरिएबल्स एकतर मेमरीमध्ये किंवा, जर ते खूप जास्त नसतील तर, थेट स्टॅकवर स्टोअर केले जाऊ शकतात. +जर आपण संख्या मर्यादित करू शकलो जेणेकरून आपण स्टॅक वापरू तर आपण कमी गॅस वापरू. अधिक तपशीलांसाठी [यलो पेपर, औपचारिक Ethereum स्पेसिफिकेशन्स](https://ethereum.github.io/yellowpaper/paper.pdf), पृष्ठ 26, समीकरण 298 पहा. + +```solidity + address _token0 = token0; + address _token1 = token1; + require(to != _token0 && to != _token1, 'UniswapV2: INVALID_TO'); + if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // आशावादीपणे (optimistically) टोकन्स ट्रान्सफर करा + if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // आशावादीपणे (optimistically) टोकन्स ट्रान्सफर करा +``` + +हे ट्रान्सफर आशावादी आहे, कारण सर्व अटी पूर्ण झाल्याची खात्री होण्यापूर्वी आम्ही ट्रान्सफर करतो. Ethereum मध्ये हे ठीक आहे कारण जर कॉलमध्ये नंतर अटी पूर्ण झाल्या नाहीत तर आम्ही त्यातून आणि त्याने तयार केलेल्या कोणत्याही बदलांमधून रिव्हर्ट करतो. + +```solidity + if (data.length > 0) IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); +``` + +विनंती केल्यास प्राप्तकर्त्याला स्वॅपबद्दल माहिती द्या. + +```solidity + balance0 = IERC20(_token0).balanceOf(address(this)); + balance1 = IERC20(_token1).balanceOf(address(this)); + } +``` + +सध्याचे बॅलन्सेस मिळवा. पेरिफेरी कॉन्ट्रॅक्ट आम्हाला स्वॅपसाठी कॉल करण्यापूर्वी टोकन्स पाठवते. यामुळे कॉन्ट्रॅक्टला फसवले जात नाही हे तपासणे सोपे होते, एक तपासणी जी कोर कॉन्ट्रॅक्टमध्ये _होणे आवश्यक_ आहे (कारण आम्हाला आमच्या पेरिफेरी कॉन्ट्रॅक्ट व्यतिरिक्त इतर संस्थांद्वारे कॉल केले जाऊ शकते). + +```solidity + uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0; + uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0; + require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT'); + { // reserve{0,1}Adjusted साठी स्कोप, 'stack too deep' एरर्स टाळतो + uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); + uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); + require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K'); +``` + +स्वॅपमधून आमचे नुकसान होणार नाही याची खात्री करण्यासाठी ही एक सॅनिटी चेक आहे. अशी कोणतीही परिस्थिती नाही ज्यामध्ये स्वॅपने `reserve0*reserve1` कमी केले पाहिजे. येथेच आम्ही हे देखील सुनिश्चित करतो की स्वॅपवर 0.3% फी पाठविली जात आहे; K च्या मूल्याची सॅनिटी तपासणी करण्यापूर्वी, आम्ही दोन्ही बॅलन्सेसना 1000 ने गुणतो आणि त्यातून 3 ने गुणलेल्या रकमा वजा करतो, याचा अर्थ 0.3% (3/1000 = 0.003 = 0.3%) बॅलन्समधून वजा केले जात आहे त्याच्या K मूल्याची सध्याच्या रिझर्व्ह्सच्या K मूल्याशी तुलना करण्यापूर्वी. + +```solidity + } + + _update(balance0, balance1, _reserve0, _reserve1); + emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); + } +``` + +`reserve0` आणि `reserve1` अपडेट करा, आणि आवश्यक असल्यास प्राईस ॲक्युम्युलेटर्स आणि टाइमस्टॅम्प अपडेट करा आणि इव्हेंट एमिट करा. + +##### Sync किंवा Skim + +पेअर एक्सचेंजला वाटत असलेल्या रिझर्व्ह्सच्या तुलनेत वास्तविक बॅलन्सेस सिंकच्या बाहेर जाणे शक्य आहे. +कॉन्ट्रॅक्टच्या संमतीशिवाय टोकन्स काढण्याचा कोणताही मार्ग नाही, परंतु ठेवी ही वेगळी बाब आहे. एखादे अकाउंट `mint` किंवा `swap` ला कॉल न करता एक्सचेंजमध्ये टोकन्स ट्रान्सफर करू शकते. + +त्या बाबतीत दोन उपाय आहेत: + +- `sync`, रिझर्व्ह्सना सध्याच्या बॅलन्सेसवर अपडेट करा +- `skim`, अतिरिक्त रक्कम काढा. लक्षात घ्या की कोणत्याही अकाउंटला `skim` कॉल करण्याची परवानगी आहे कारण आम्हाला माहित नाही की टोकन्स कोणी जमा केले. ही माहिती इव्हेंटमध्ये एमिट केली जाते, परंतु इव्हेंट्स ब्लॉकचेनवरून ॲक्सेसिबल नसतात. + +```solidity + // बॅलन्सला रिझर्व्हशी जुळण्यासाठी सक्ती करा + function skim(address to) external lock { + address _token0 = token0; // गॅसची बचत + address _token1 = token1; // गॅसची बचत + _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0)); + _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1)); + } + + + + // रिझर्व्हला बॅलन्सशी जुळण्यासाठी सक्ती करा + function sync() external lock { + _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1); + } +} +``` + +### UniswapV2Factory.sol {#UniswapV2Factory} + +[हे कॉन्ट्रॅक्ट](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Factory.sol) पेअर एक्सचेंजेस तयार करते. + +```solidity +pragma solidity =0.5.16; + +import './interfaces/IUniswapV2Factory.sol'; +import './UniswapV2Pair.sol'; + +contract UniswapV2Factory is IUniswapV2Factory { + address public feeTo; + address public feeToSetter; +``` + +प्रोटोकॉल फी लागू करण्यासाठी हे स्टेट व्हेरिएबल्स आवश्यक आहेत ([व्हाईटपेपर](https://app.uniswap.org/whitepaper.pdf), पृष्ठ 5 पहा). +`feeTo` पत्ता प्रोटोकॉल फीसाठी लिक्विडिटी टोकन्स जमा करतो आणि `feeToSetter` हा असा पत्ता आहे ज्याला `feeTo` वेगळ्या पत्त्यावर बदलण्याची परवानगी आहे. + +```solidity + mapping(address => mapping(address => address)) public getPair; + address[] public allPairs; +``` + +हे व्हेरिएबल्स पेअर्सचा, दोन टोकन प्रकारांमधील एक्सचेंजेसचा मागोवा ठेवतात. + +पहिले, `getPair`, एक मॅपिंग आहे जे पेअर एक्सचेंज कॉन्ट्रॅक्ट ओळखते ते एक्सचेंज करत असलेल्या दोन ERC-20 टोकन्सच्या आधारावर. ERC-20 टोकन्स त्यांची अंमलबजावणी करणाऱ्या कॉन्ट्रॅक्ट्सच्या पत्त्यांद्वारे ओळखले जातात, त्यामुळे कीज आणि व्हॅल्यू हे सर्व पत्ते आहेत. पेअर एक्सचेंजचा पत्ता मिळवण्यासाठी जो तुम्हाला `tokenA` मधून `tokenB` मध्ये रूपांतरित करू देतो, तुम्ही `getPair[][]` (किंवा उलट) वापरता. + +दुसरे व्हेरिएबल, `allPairs`, एक ॲरे आहे ज्यामध्ये या फॅक्टरीद्वारे तयार केलेल्या पेअर एक्सचेंजेसचे सर्व पत्ते समाविष्ट आहेत. Ethereum मध्ये तुम्ही मॅपिंगच्या सामग्रीवर इटरेट करू शकत नाही किंवा सर्व कीजची सूची मिळवू शकत नाही, त्यामुळे ही फॅक्टरी कोणते एक्सचेंजेस व्यवस्थापित करते हे जाणून घेण्याचा हा व्हेरिएबल एकमेव मार्ग आहे. + +टीप: तुम्ही मॅपिंगच्या सर्व कीजवर इटरेट करू शकत नाही याचे कारण असे आहे की कॉन्ट्रॅक्ट डेटा स्टोरेज _महाग_ आहे, त्यामुळे आपण त्याचा जितका कमी वापर करू तितके चांगले आणि आपण ते जितक्या कमी वेळा बदलू तितके चांगले. तुम्ही [इटरेशनला सपोर्ट करणारी मॅपिंग्ज](https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol) तयार करू शकता, परंतु त्यांना कीजच्या सूचीसाठी अतिरिक्त स्टोरेजची आवश्यकता असते. बहुतेक ॲप्लिकेशन्समध्ये तुम्हाला त्याची आवश्यकता नसते. + +```solidity + event PairCreated(address indexed token0, address indexed token1, address pair, uint); +``` + +जेव्हा नवीन पेअर एक्सचेंज तयार केले जाते तेव्हा हा इव्हेंट एमिट केला जातो. यामध्ये टोकन्सचे पत्ते, पेअर एक्सचेंजचा पत्ता आणि फॅक्टरीद्वारे व्यवस्थापित केलेल्या एक्सचेंजेसची एकूण संख्या समाविष्ट असते. + +```solidity + constructor(address _feeToSetter) public { + feeToSetter = _feeToSetter; + } +``` + +कन्स्ट्रक्टर फक्त एकच गोष्ट करतो ती म्हणजे `feeToSetter` निर्दिष्ट करणे. फॅक्टरीज फीशिवाय सुरू होतात आणि फक्त `feeSetter` ते बदलू शकतो. + +```solidity + function allPairsLength() external view returns (uint) { + return allPairs.length; + } +``` + +हे फंक्शन एक्सचेंज पेअर्सची संख्या परत करते. + +```solidity + function createPair(address tokenA, address tokenB) external returns (address pair) { +``` + +दोन ERC-20 टोकन्समध्ये पेअर एक्सचेंज तयार करणे हे फॅक्टरीचे मुख्य फंक्शन आहे. लक्षात घ्या की कोणीही या फंक्शनला कॉल करू शकतो. नवीन पेअर एक्सचेंज तयार करण्यासाठी तुम्हाला Uniswap च्या परवानगीची आवश्यकता नाही. + +```solidity + require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES'); + (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); +``` + +आम्हाला नवीन एक्सचेंजचा पत्ता डिटरमिनिस्टिक असावा असे वाटते, जेणेकरून त्याची आगाऊ ऑफचेन गणना केली जाऊ शकेल (हे [लेयर 2 ट्रान्झॅक्शन्ससाठी](/developers/docs/scaling/) उपयुक्त ठरू शकते). +हे करण्यासाठी आम्हाला टोकन पत्त्यांचा एक सुसंगत क्रम असणे आवश्यक आहे, आम्ही ते कोणत्या क्रमाने प्राप्त केले आहेत याची पर्वा न करता, म्हणून आम्ही त्यांना येथे सॉर्ट करतो. + +```solidity + require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS'); + require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // एकच तपासणी पुरेशी आहे +``` + +मोठे लिक्विडिटी पूल्स लहान पूल्सपेक्षा चांगले असतात, कारण त्यांच्या किंमती अधिक स्थिर असतात. आम्हाला टोकन्सच्या प्रति पेअर एकापेक्षा जास्त लिक्विडिटी पूल नको आहे. जर आधीच एक्सचेंज असेल, तर त्याच पेअरसाठी दुसरे तयार करण्याची गरज नाही. + +```solidity + bytes memory bytecode = type(UniswapV2Pair).creationCode; +``` + +नवीन कॉन्ट्रॅक्ट तयार करण्यासाठी आम्हाला तो तयार करणारा कोड आवश्यक आहे (कन्स्ट्रक्टर फंक्शन आणि प्रत्यक्ष कॉन्ट्रॅक्टचा EVM बाइटकोड मेमरीमध्ये लिहिणारा कोड दोन्ही). साधारणपणे Solidity मध्ये आम्ही फक्त `addr = new ()` वापरतो आणि कंपायलर आमच्यासाठी सर्व गोष्टींची काळजी घेतो, परंतु डिटरमिनिस्टिक कॉन्ट्रॅक्ट पत्ता मिळवण्यासाठी आम्हाला [CREATE2 ऑपकोड](https://eips.ethereum.org/EIPS/eip-1014) वापरण्याची आवश्यकता आहे. +जेव्हा हा कोड लिहिला गेला तेव्हा त्या ऑपकोडला Solidity द्वारे अद्याप सपोर्ट नव्हता, त्यामुळे मॅन्युअली कोड मिळवणे आवश्यक होते. ही आता समस्या नाही, कारण [Solidity आता CREATE2 ला सपोर्ट करते](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#salted-contract-creations-create2). + +```solidity + bytes32 salt = keccak256(abi.encodePacked(token0, token1)); + assembly { + pair := create2(0, add(bytecode, 32), mload(bytecode), salt) + } +``` + +जेव्हा एखाद्या ऑपकोडला Solidity द्वारे अद्याप सपोर्ट नसतो तेव्हा आम्ही [इनलाइन असेंब्ली](https://docs.soliditylang.org/en/v0.8.3/assembly.html) वापरून त्याला कॉल करू शकतो. + +```solidity + IUniswapV2Pair(pair).initialize(token0, token1); +``` + +नवीन एक्सचेंजला ते कोणते दोन टोकन्स एक्सचेंज करते हे सांगण्यासाठी `initialize` फंक्शनला कॉल करा. + +```solidity + getPair[token0][token1] = pair; + getPair[token1][token0] = pair; // उलट्या दिशेने मॅपिंग पॉप्युलेट करा + allPairs.push(pair); + emit PairCreated(token0, token1, pair, allPairs.length); + } +``` + +नवीन पेअरची माहिती स्टेट व्हेरिएबल्समध्ये सेव्ह करा आणि जगाला नवीन पेअर एक्सचेंजची माहिती देण्यासाठी इव्हेंट एमिट करा. + +```solidity + function setFeeTo(address _feeTo) external { + require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); + feeTo = _feeTo; + } + + function setFeeToSetter(address _feeToSetter) external { + require(msg.sender == feeToSetter, 'UniswapV2: FORBIDDEN'); + feeToSetter = _feeToSetter; + } +} +``` + +ही दोन फंक्शन्स `feeSetter` ला फी प्राप्तकर्त्यावर (जर कोणी असेल तर) नियंत्रण ठेवण्याची आणि `feeSetter` ला नवीन पत्त्यावर बदलण्याची परवानगी देतात. + +### UniswapV2ERC20.sol {#UniswapV2ERC20} + +[हे कॉन्ट्रॅक्ट](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) ERC-20 लिक्विडिटी टोकन लागू करते. हे [OpenZeppelin ERC-20 कॉन्ट्रॅक्ट](/developers/tutorials/erc20-annotated-code) सारखेच आहे, त्यामुळे मी फक्त तो भाग स्पष्ट करेन जो वेगळा आहे, `permit` कार्यक्षमता. + +Ethereum वरील ट्रान्झॅक्शन्ससाठी इथर (ETH) खर्च होतो, जे खऱ्या पैशाच्या समतुल्य आहे. जर तुमच्याकडे ERC-20 टोकन्स असतील पण ETH नसेल, तर तुम्ही ट्रान्झॅक्शन्स पाठवू शकत नाही, त्यामुळे तुम्ही त्यांच्यासोबत काहीही करू शकत नाही. ही समस्या टाळण्यासाठी एक उपाय म्हणजे [मेटा-ट्रान्झॅक्शन्स](https://docs.uniswap.org/contracts/v2/guides/smart-contract-integration/supporting-meta-transactions). +टोकन्सचा मालक अशा ट्रान्झॅक्शनवर स्वाक्षरी करतो जे दुसऱ्या कोणालातरी ऑफचेन टोकन्स काढण्याची परवानगी देते आणि इंटरनेटचा वापर करून ते प्राप्तकर्त्याला पाठवते. प्राप्तकर्ता, ज्याच्याकडे ETH आहे, तो नंतर मालकाच्या वतीने परमिट सबमिट करतो. + +```solidity + bytes32 public DOMAIN_SEPARATOR; + // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; +``` + +हा हॅश [ट्रान्झॅक्शन प्रकारासाठी आयडेंटिफायर](https://eips.ethereum.org/EIPS/eip-712#rationale-for-typehash) आहे. आम्ही येथे सपोर्ट करत असलेला एकमेव प्रकार या पॅरामीटर्ससह `Permit` आहे. + +```solidity + mapping(address => uint) public nonces; +``` + +प्राप्तकर्त्यासाठी डिजिटल स्वाक्षरी बनावट करणे शक्य नाही. तथापि, तेच ट्रान्झॅक्शन दोनदा पाठवणे क्षुल्लक आहे (हा [रिप्ले अटॅकचा](https://wikipedia.org/wiki/Replay_attack) एक प्रकार आहे). हे टाळण्यासाठी, आम्ही [नॉन्स](https://wikipedia.org/wiki/Cryptographic_nonce) वापरतो. जर नवीन `Permit` चा नॉन्स वापरलेल्या शेवटच्या नॉन्सपेक्षा एकने जास्त नसेल, तर आम्ही ते अवैध असल्याचे गृहीत धरतो. + +```solidity + constructor() public { + uint chainId; + assembly { + chainId := chainid + } +``` + +हा [चेन आयडेंटिफायर](https://chainid.network/) पुनर्प्राप्त करण्यासाठीचा कोड आहे. हे [Yul](https://docs.soliditylang.org/en/v0.8.4/yul.html) नावाचा EVM असेंब्ली डायलेक्ट वापरते. लक्षात घ्या की Yul च्या सध्याच्या आवृत्तीमध्ये तुम्हाला `chainid()` वापरावे लागेल, `chainid` नाही. + +```solidity + DOMAIN_SEPARATOR = keccak256( + abi.encode( + keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'), + keccak256(bytes(name)), + keccak256(bytes('1')), + chainId, + address(this) + ) + ); + } +``` + +EIP-712 साठी [डोमेन सेपरेटरची](https://eips.ethereum.org/EIPS/eip-712#rationale-for-domainseparator) गणना करा. + +```solidity + function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { +``` + +हे ते फंक्शन आहे जे परवानग्या लागू करते. हे पॅरामीटर्स म्हणून संबंधित फील्ड्स आणि [स्वाक्षरीसाठी](https://yos.io/2018/11/16/ethereum-signatures/) तीन स्केलर व्हॅल्यूज (v, r, आणि s) प्राप्त करते. + +```solidity + require(deadline >= block.timestamp, 'UniswapV2: EXPIRED'); +``` + +डेडलाइननंतर ट्रान्झॅक्शन्स स्वीकारू नका. + +```solidity + bytes32 digest = keccak256( + abi.encodePacked( + '\x19\x01', + DOMAIN_SEPARATOR, + keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) + ) + ); +``` + +`abi.encodePacked(...)` हा आम्हाला मिळण्याची अपेक्षा असलेला मेसेज आहे. आम्हाला माहित आहे की नॉन्स काय असावा, त्यामुळे आम्हाला तो पॅरामीटर म्हणून मिळवण्याची गरज नाही. + +Ethereum स्वाक्षरी अल्गोरिदमला स्वाक्षरी करण्यासाठी 256 बिट्स मिळण्याची अपेक्षा असते, त्यामुळे आम्ही `keccak256` हॅश फंक्शन वापरतो. + +```solidity + address recoveredAddress = ecrecover(digest, v, r, s); +``` + +डायजेस्ट आणि स्वाक्षरीवरून आम्ही [ecrecover](https://coders-errand.com/ecrecover-signature-verification-ethereum/) वापरून ज्याने स्वाक्षरी केली तो पत्ता मिळवू शकतो. + +```solidity + require(recoveredAddress != address(0) && recoveredAddress == owner, 'UniswapV2: INVALID_SIGNATURE'); + _approve(owner, spender, value); + } + +``` + +जर सर्व काही ठीक असेल, तर याला [ERC-20 अप्रूव्ह](https://eips.ethereum.org/EIPS/eip-20#approve) म्हणून हाताळा. + +## पेरिफेरी कॉन्ट्रॅक्ट्स {#periphery-contracts} + +पेरिफेरी कॉन्ट्रॅक्ट्स हे Uniswap चे API (अॅप्लिकेशन प्रोग्राम इंटरफेस) आहेत. ते बाह्य कॉल्ससाठी उपलब्ध आहेत, मग ते इतर कॉन्ट्रॅक्ट्समधून असोत किंवा डिसेंट्रलाइज्ड अॅप्लिकेशन्समधून. तुम्ही कोर कॉन्ट्रॅक्ट्सना थेट कॉल करू शकता, परंतु ते अधिक गुंतागुंतीचे आहे आणि जर तुम्ही चूक केली तर तुमचे मूल्य गमावले जाऊ शकते. कोर कॉन्ट्रॅक्ट्समध्ये केवळ त्यांची फसवणूक होणार नाही याची खात्री करण्यासाठी चाचण्या असतात, इतर कोणासाठीही सॅनिटी चेक्स (sanity checks) नसतात. ते पेरिफेरीमध्ये असतात जेणेकरून आवश्यकतेनुसार ते अपडेट केले जाऊ शकतील. + +### UniswapV2Router01.sol {#UniswapV2Router01} + +[या कॉन्ट्रॅक्टमध्ये](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router01.sol) समस्या आहेत, आणि [ते यापुढे वापरले जाऊ नये](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-01). सुदैवाने, पेरिफेरी कॉन्ट्रॅक्ट्स स्टेटलेस (stateless) असतात आणि त्यांच्याकडे कोणतीही मालमत्ता नसते, त्यामुळे ते डेप्रिकेट (deprecate) करणे आणि लोकांना त्याऐवजी `UniswapV2Router02` वापरण्याचा सल्ला देणे सोपे आहे. + +### UniswapV2Router02.sol {#UniswapV2Router02} + +बहुतांश प्रकरणांमध्ये तुम्ही [या कॉन्ट्रॅक्टद्वारे](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/UniswapV2Router02.sol) Uniswap वापराल. +ते कसे वापरायचे ते तुम्ही [येथे](https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02) पाहू शकता. + +```solidity +pragma solidity =0.6.6; + +import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol'; +import '@uniswap/lib/contracts/libraries/TransferHelper.sol'; + +import './interfaces/IUniswapV2Router02.sol'; +import './libraries/UniswapV2Library.sol'; +import './libraries/SafeMath.sol'; +import './interfaces/IERC20.sol'; +import './interfaces/IWETH.sol'; +``` + +यापैकी बहुतांश गोष्टी आपण यापूर्वी पाहिल्या आहेत किंवा त्या अगदी स्पष्ट आहेत. याला एक अपवाद म्हणजे `IWETH.sol`. Uniswap v2 कोणत्याही ERC-20 टोकन्सच्या जोडीसाठी एक्सचेंजची परवानगी देते, परंतु इथर (ETH) स्वतः एक ERC-20 टोकन नाही. ते या मानकाच्या आधीचे आहे आणि अद्वितीय यंत्रणेद्वारे ट्रान्सफर केले जाते. ERC-20 टोकन्सना लागू होणाऱ्या कॉन्ट्रॅक्ट्समध्ये ETH चा वापर सक्षम करण्यासाठी लोकांनी [रॅप्ड इथर (WETH)](https://weth.tkn.eth.limo/) कॉन्ट्रॅक्ट तयार केले. तुम्ही या कॉन्ट्रॅक्टला ETH पाठवता आणि ते तुम्हाला समतुल्य प्रमाणात WETH मिंट (mint) करून देते. किंवा तुम्ही WETH बर्न (burn) करू शकता आणि परत ETH मिळवू शकता. + +```solidity +contract UniswapV2Router02 is IUniswapV2Router02 { + using SafeMath for uint; + + address public immutable override factory; + address public immutable override WETH; +``` + +राउटरला कोणती फॅक्टरी वापरायची आहे हे माहित असणे आवश्यक आहे, आणि ज्या ट्रान्झॅक्शन्ससाठी WETH आवश्यक आहे त्यांच्यासाठी कोणते WETH कॉन्ट्रॅक्ट वापरायचे हे माहित असणे आवश्यक आहे. ही मूल्ये [इम्युटेबल (immutable)](https://docs.soliditylang.org/en/v0.8.3/contracts.html#constant-and-immutable-state-variables) आहेत, याचा अर्थ ती फक्त कन्स्ट्रक्टरमध्ये (constructor) सेट केली जाऊ शकतात. यामुळे युजर्सना असा विश्वास मिळतो की कोणीही त्यांना कमी प्रामाणिक कॉन्ट्रॅक्ट्सकडे निर्देशित करण्यासाठी बदलू शकणार नाही. + +```solidity + modifier ensure(uint deadline) { + require(deadline >= block.timestamp, 'UniswapV2Router: EXPIRED'); + _; + } +``` + +हा मॉडिफायर (modifier) हे सुनिश्चित करतो की वेळेची मर्यादा असलेली ट्रान्झॅक्शन्स ("शक्य असल्यास Y वेळेपूर्वी X करा") त्यांच्या वेळेच्या मर्यादेनंतर होणार नाहीत. + +```solidity + constructor(address _factory, address _WETH) public { + factory = _factory; + WETH = _WETH; + } +``` + +कन्स्ट्रक्टर फक्त इम्युटेबल स्टेट व्हेरिएबल्स सेट करतो. + +```solidity + receive() external payable { + assert(msg.sender == WETH); // फक्त WETH कॉन्ट्रॅक्टमधून फॉलबॅकद्वारे ETH स्वीकारा + } +``` + +जेव्हा आपण WETH कॉन्ट्रॅक्टमधून टोकन्स परत ETH मध्ये रिडीम (redeem) करतो तेव्हा हे फंक्शन कॉल केले जाते. आपण वापरत असलेल्या फक्त WETH कॉन्ट्रॅक्टलाच तसे करण्याचा अधिकार आहे. + +#### लिक्विडिटी जोडा {#add-liquidity} + +ही फंक्शन्स पेअर एक्सचेंजमध्ये टोकन्स जोडतात, ज्यामुळे लिक्विडिटी पूल वाढतो. + +```solidity + + // **** लिक्विडिटी जोडा **** + function _addLiquidity( +``` + +हे फंक्शन पेअर एक्सचेंजमध्ये जमा केल्या जाणाऱ्या A आणि B टोकन्सच्या रकमेची गणना करण्यासाठी वापरले जाते. + +```solidity + address tokenA, + address tokenB, +``` + +हे ERC-20 टोकन कॉन्ट्रॅक्ट्सचे पत्ते (addresses) आहेत. + +```solidity + uint amountADesired, + uint amountBDesired, +``` + +या त्या रकमा आहेत ज्या लिक्विडिटी प्रोव्हायडरला जमा करायच्या आहेत. त्या जमा केल्या जाणाऱ्या A आणि B च्या कमाल रकमा देखील आहेत. + +```solidity + uint amountAMin, + uint amountBMin +``` + +या जमा करण्यासाठी किमान स्वीकार्य रकमा आहेत. जर ट्रान्झॅक्शन या रकमांसह किंवा त्याहून अधिक रकमेसह होऊ शकत नसेल, तर ते रिव्हर्ट (revert) करा. जर तुम्हाला हे वैशिष्ट्य नको असेल, तर फक्त शून्य (0) निर्दिष्ट करा. + +लिक्विडिटी प्रोव्हायडर्स सामान्यतः किमान रक्कम निर्दिष्ट करतात, कारण त्यांना ट्रान्झॅक्शन सध्याच्या एक्सचेंज रेटच्या जवळ असलेल्या एक्सचेंज रेटपर्यंत मर्यादित ठेवायचे असते. जर एक्सचेंज रेटमध्ये खूप चढ-उतार होत असेल तर याचा अर्थ असा असू शकतो की काही बातम्यांमुळे मूळ मूल्ये बदलत आहेत, आणि त्यांना मॅन्युअली काय करायचे ते ठरवायचे असते. + +उदाहरणार्थ, अशी कल्पना करा की एक्सचेंज रेट एकास एक (one to one) आहे आणि लिक्विडिटी प्रोव्हायडर ही मूल्ये निर्दिष्ट करतो: + +| Parameter | Value | +| -------------- | ----: | +| amountADesired | 1000 | +| amountBDesired | 1000 | +| amountAMin | 900 | +| amountBMin | 800 | + +जोपर्यंत एक्सचेंज रेट 0.9 आणि 1.25 च्या दरम्यान राहतो, तोपर्यंत ट्रान्झॅक्शन होते. जर एक्सचेंज रेट त्या कक्षेच्या बाहेर गेला, तर ट्रान्झॅक्शन रद्द होते. + +या खबरदारीचे कारण असे आहे की ट्रान्झॅक्शन्स त्वरित होत नाहीत, तुम्ही ती सबमिट करता आणि शेवटी एक व्हॅलिडेटर (validator) त्यांना ब्लॉकमध्ये समाविष्ट करणार असतो (जोपर्यंत तुमची गॅस प्राईस खूप कमी नसेल, अशा परिस्थितीत तुम्हाला ते ओव्हरराईट करण्यासाठी समान नॉन्स (nonce) आणि उच्च गॅस प्राईससह दुसरे ट्रान्झॅक्शन सबमिट करावे लागेल). सबमिशन आणि समावेशाच्या दरम्यानच्या काळात काय होते यावर तुमचे नियंत्रण नसते. + +```solidity + ) internal virtual returns (uint amountA, uint amountB) { +``` + +हे फंक्शन रिझर्व्ह्समधील सध्याच्या गुणोत्तराइतके गुणोत्तर मिळवण्यासाठी लिक्विडिटी प्रोव्हायडरने जमा करावयाच्या रकमा परत करते. + +```solidity + // जर पेअर (जोडी) अद्याप अस्तित्वात नसेल तर ती तयार करा + if (IUniswapV2Factory(factory).getPair(tokenA, tokenB) == address(0)) { + IUniswapV2Factory(factory).createPair(tokenA, tokenB); + } +``` + +जर या टोकन जोडीसाठी अद्याप कोणतेही एक्सचेंज नसेल, तर ते तयार करा. + +```solidity + (uint reserveA, uint reserveB) = UniswapV2Library.getReserves(factory, tokenA, tokenB); +``` + +जोडीमधील सध्याचे रिझर्व्ह्स मिळवा. + +```solidity + if (reserveA == 0 && reserveB == 0) { + (amountA, amountB) = (amountADesired, amountBDesired); +``` + +जर सध्याचे रिझर्व्ह्स रिकामे असतील तर हे एक नवीन पेअर एक्सचेंज आहे. जमा करावयाच्या रकमा लिक्विडिटी प्रोव्हायडरला द्यावयाच्या रकमांसारख्याच असाव्यात. + +```solidity + } else { + uint amountBOptimal = UniswapV2Library.quote(amountADesired, reserveA, reserveB); +``` + +जर आपल्याला रकमा काय असतील हे पाहायचे असेल, तर आपण [या फंक्शनचा](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol#L35) वापर करून इष्टतम (optimal) रक्कम मिळवतो. आपल्याला सध्याच्या रिझर्व्ह्ससारखेच गुणोत्तर हवे आहे. + +```solidity + if (amountBOptimal <= amountBDesired) { + require(amountBOptimal >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + (amountA, amountB) = (amountADesired, amountBOptimal); +``` + +जर `amountBOptimal` लिक्विडिटी प्रोव्हायडरला जमा करावयाच्या रकमेपेक्षा लहान असेल तर याचा अर्थ असा की टोकन B सध्या लिक्विडिटी जमा करणाऱ्याच्या विचारापेक्षा अधिक मौल्यवान आहे, त्यामुळे कमी रकमेची आवश्यकता आहे. + +```solidity + } else { + uint amountAOptimal = UniswapV2Library.quote(amountBDesired, reserveB, reserveA); + assert(amountAOptimal <= amountADesired); + require(amountAOptimal >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + (amountA, amountB) = (amountAOptimal, amountBDesired); +``` + +जर इष्टतम B रक्कम इच्छित B रकमेपेक्षा जास्त असेल तर याचा अर्थ असा की B टोकन्स सध्या लिक्विडिटी जमा करणाऱ्याच्या विचारापेक्षा कमी मौल्यवान आहेत, त्यामुळे जास्त रकमेची आवश्यकता आहे. तथापि, इच्छित रक्कम ही कमाल रक्कम आहे, त्यामुळे आपण तसे करू शकत नाही. त्याऐवजी आपण B टोकन्सच्या इच्छित रकमेसाठी A टोकन्सच्या इष्टतम संख्येची गणना करतो. + +हे सर्व एकत्र केल्यावर आपल्याला हा आलेख मिळतो. असे समजा की तुम्ही एक हजार A टोकन्स (निळी रेषा) आणि एक हजार B टोकन्स (लाल रेषा) जमा करण्याचा प्रयत्न करत आहात. x अक्ष हा एक्सचेंज रेट, A/B आहे. जर x=1 असेल, तर त्यांचे मूल्य समान आहे आणि तुम्ही प्रत्येकी एक हजार जमा करता. जर x=2 असेल, तर A चे मूल्य B च्या दुप्पट आहे (तुम्हाला प्रत्येक A टोकनसाठी दोन B टोकन्स मिळतात) त्यामुळे तुम्ही एक हजार B टोकन्स जमा करता, परंतु फक्त 500 A टोकन्स. जर x=0.5 असेल, तर परिस्थिती उलट असते, एक हजार A टोकन्स आणि पाचशे B टोकन्स. + +![Graph](liquidityProviderDeposit.png) + +तुम्ही थेट कोर कॉन्ट्रॅक्टमध्ये लिक्विडिटी जमा करू शकता ([UniswapV2Pair::mint](https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol#L110) वापरून), परंतु कोर कॉन्ट्रॅक्ट फक्त स्वतःची फसवणूक होत नाही ना हे तपासते, त्यामुळे तुम्ही तुमचे ट्रान्झॅक्शन सबमिट करता आणि ते कार्यान्वित होते या दरम्यानच्या वेळेत एक्सचेंज रेट बदलल्यास तुमचे मूल्य गमावण्याचा धोका असतो. जर तुम्ही पेरिफेरी कॉन्ट्रॅक्ट वापरत असाल, तर ते तुम्हाला किती रक्कम जमा करावी लागेल हे शोधून काढते आणि ती त्वरित जमा करते, त्यामुळे एक्सचेंज रेट बदलत नाही आणि तुमचे कोणतेही नुकसान होत नाही. + +```solidity + function addLiquidity( + address tokenA, + address tokenB, + uint amountADesired, + uint amountBDesired, + uint amountAMin, + uint amountBMin, + address to, + uint deadline +``` + +लिक्विडिटी जमा करण्यासाठी ट्रान्झॅक्शनद्वारे हे फंक्शन कॉल केले जाऊ शकते. दोन अपवाद वगळता बहुतांश पॅरामीटर्स वरील `_addLiquidity` प्रमाणेच आहेत: + +. `to` हा तो पत्ता आहे ज्याला पूलमधील लिक्विडिटी प्रोव्हायडरचा हिस्सा दर्शविण्यासाठी नवीन लिक्विडिटी टोकन्स मिंट करून मिळतात +. `deadline` ही ट्रान्झॅक्शनवरील वेळेची मर्यादा आहे + +```solidity + ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) { + (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin); + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); +``` + +आपण प्रत्यक्षात जमा करावयाच्या रकमांची गणना करतो आणि नंतर लिक्विडिटी पूलचा पत्ता शोधतो. गॅस वाचवण्यासाठी आपण हे फॅक्टरीला विचारून करत नाही, तर `pairFor` हे लायब्ररी फंक्शन वापरून करतो (खाली लायब्ररीमध्ये पहा) + +```solidity + TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA); + TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB); +``` + +युजरकडून पेअर एक्सचेंजमध्ये टोकन्सच्या योग्य रकमा ट्रान्सफर करा. + +```solidity + liquidity = IUniswapV2Pair(pair).mint(to); + } +``` + +त्या बदल्यात पूलच्या आंशिक मालकीसाठी `to` पत्त्याला लिक्विडिटी टोकन्स द्या. कोर कॉन्ट्रॅक्टचे `mint` फंक्शन पाहते की त्याच्याकडे किती अतिरिक्त टोकन्स आहेत (गेल्या वेळी लिक्विडिटी बदलली तेव्हा त्याच्याकडे जे होते त्याच्या तुलनेत) आणि त्यानुसार लिक्विडिटी मिंट करते. + +```solidity + function addLiquidityETH( + address token, + uint amountTokenDesired, +``` + +जेव्हा लिक्विडिटी प्रोव्हायडरला Token/ETH पेअर एक्सचेंजला लिक्विडिटी प्रदान करायची असते, तेव्हा काही फरक असतात. कॉन्ट्रॅक्ट लिक्विडिटी प्रोव्हायडरसाठी ETH रॅप (wrap) करण्याचे काम हाताळते. युजरला किती ETH जमा करायचे आहेत हे निर्दिष्ट करण्याची आवश्यकता नाही, कारण युजर फक्त त्यांना ट्रान्झॅक्शनसोबत पाठवतो (ही रक्कम `msg.value` मध्ये उपलब्ध असते). + +```solidity + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) { + (amountToken, amountETH) = _addLiquidity( + token, + WETH, + amountTokenDesired, + msg.value, + amountTokenMin, + amountETHMin + ); + address pair = UniswapV2Library.pairFor(factory, token, WETH); + TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken); + IWETH(WETH).deposit{value: amountETH}(); + assert(IWETH(WETH).transfer(pair, amountETH)); +``` + +ETH जमा करण्यासाठी कॉन्ट्रॅक्ट प्रथम त्याला WETH मध्ये रॅप करते आणि नंतर WETH ला जोडीमध्ये ट्रान्सफर करते. लक्षात घ्या की ट्रान्सफर एका `assert` मध्ये रॅप केलेले आहे. याचा अर्थ असा की जर ट्रान्सफर अयशस्वी झाले तर हा कॉन्ट्रॅक्ट कॉल देखील अयशस्वी होतो, आणि त्यामुळे रॅपिंग खरोखर होत नाही. + +```solidity + liquidity = IUniswapV2Pair(pair).mint(to); + // काही उरलेले (dust) eth असल्यास, रिफंड करा + if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); + } +``` + +युजरने आपल्याला आधीच ETH पाठवले आहेत, त्यामुळे जर काही अतिरिक्त शिल्लक राहिले असेल (कारण दुसरे टोकन युजरच्या विचारापेक्षा कमी मौल्यवान आहे), तर आपल्याला रिफंड (refund) जारी करणे आवश्यक आहे. + +#### लिक्विडिटी काढा {#remove-liquidity} + +ही फंक्शन्स लिक्विडिटी काढून टाकतील आणि लिक्विडिटी प्रोव्हायडरला परतफेड करतील. + +```solidity + // **** लिक्विडिटी काढा **** + function removeLiquidity( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) { +``` + +लिक्विडिटी काढण्याचे सर्वात सोपे प्रकरण. लिक्विडिटी प्रोव्हायडर स्वीकारण्यास सहमत असलेल्या प्रत्येक टोकनची किमान रक्कम असते, आणि ते डेडलाईनपूर्वी (deadline) होणे आवश्यक आहे. + +```solidity + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + IUniswapV2Pair(pair).transferFrom(msg.sender, pair, liquidity); // पेअरला लिक्विडिटी पाठवा + (uint amount0, uint amount1) = IUniswapV2Pair(pair).burn(to); +``` + +कोर कॉन्ट्रॅक्टचे `burn` फंक्शन युजरला टोकन्स परत देण्याचे काम हाताळते. + +```solidity + (address token0,) = UniswapV2Library.sortTokens(tokenA, tokenB); +``` + +जेव्हा एखादे फंक्शन अनेक मूल्ये परत करते, परंतु आपल्याला त्यापैकी काहींमध्येच स्वारस्य असते, तेव्हा आपण फक्त तीच मूल्ये अशा प्रकारे मिळवतो. एखादे मूल्य वाचणे आणि ते कधीही न वापरणे यापेक्षा गॅसच्या दृष्टीने हे काहीसे स्वस्त आहे. + +```solidity + (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); +``` + +कोर कॉन्ट्रॅक्ट ज्या प्रकारे रकमा परत करते (लोअर अॅड्रेस टोकन प्रथम) त्यावरून युजरला ज्या प्रकारे त्या अपेक्षित आहेत ( `tokenA` आणि `tokenB` शी संबंधित) त्यामध्ये रकमांचे भाषांतर करा. + +```solidity + require(amountA >= amountAMin, 'UniswapV2Router: INSUFFICIENT_A_AMOUNT'); + require(amountB >= amountBMin, 'UniswapV2Router: INSUFFICIENT_B_AMOUNT'); + } +``` + +प्रथम ट्रान्सफर करणे आणि नंतर ते कायदेशीर आहे की नाही हे पडताळून पाहणे ठीक आहे, कारण जर ते नसेल तर आपण सर्व स्टेट बदलांमधून रिव्हर्ट करू. + +```solidity + function removeLiquidityETH( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) { + (amountToken, amountETH) = removeLiquidity( + token, + WETH, + liquidity, + amountTokenMin, + amountETHMin, + address(this), + deadline + ); + TransferHelper.safeTransfer(token, to, amountToken); + IWETH(WETH).withdraw(amountETH); + TransferHelper.safeTransferETH(to, amountETH); + } +``` + +ETH साठी लिक्विडिटी काढणे जवळजवळ सारखेच आहे, फक्त एवढाच फरक आहे की आपल्याला WETH टोकन्स मिळतात आणि नंतर लिक्विडिटी प्रोव्हायडरला परत देण्यासाठी आपण त्यांना ETH साठी रिडीम करतो. + +```solidity + function removeLiquidityWithPermit( + address tokenA, + address tokenB, + uint liquidity, + uint amountAMin, + uint amountBMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountA, uint amountB) { + address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline); + } + + + function removeLiquidityETHWithPermit( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountToken, uint amountETH) { + address pair = UniswapV2Library.pairFor(factory, token, WETH); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline); + } +``` + +ही फंक्शन्स इथर नसलेल्या युजर्सना पूलमधून पैसे काढण्याची परवानगी देण्यासाठी मेटा-ट्रान्झॅक्शन्स रिले (relay) करतात, यासाठी [परमिट मेकॅनिझम (permit mechanism)](#UniswapV2ERC20) वापरले जाते. + +```solidity + + // **** लिक्विडिटी काढा (फी-ऑन-ट्रान्सफर टोकन्सना सपोर्ट करणारे) **** + function removeLiquidityETHSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline + ) public virtual override ensure(deadline) returns (uint amountETH) { + (, amountETH) = removeLiquidity( + token, + WETH, + liquidity, + amountTokenMin, + amountETHMin, + address(this), + deadline + ); + TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this))); + IWETH(WETH).withdraw(amountETH); + TransferHelper.safeTransferETH(to, amountETH); + } + +``` + +हे फंक्शन ट्रान्सफर किंवा स्टोरेज फी असलेल्या टोकन्ससाठी वापरले जाऊ शकते. जेव्हा एखाद्या टोकनला अशी फी असते तेव्हा आपल्याला किती टोकन परत मिळतील हे सांगण्यासाठी आपण `removeLiquidity` फंक्शनवर अवलंबून राहू शकत नाही, त्यामुळे आपल्याला प्रथम पैसे काढावे लागतील आणि नंतर बॅलन्स मिळवावा लागेल. + +```solidity + + + function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( + address token, + uint liquidity, + uint amountTokenMin, + uint amountETHMin, + address to, + uint deadline, + bool approveMax, uint8 v, bytes32 r, bytes32 s + ) external virtual override returns (uint amountETH) { + address pair = UniswapV2Library.pairFor(factory, token, WETH); + uint value = approveMax ? uint(-1) : liquidity; + IUniswapV2Pair(pair).permit(msg.sender, address(this), value, deadline, v, r, s); + amountETH = removeLiquidityETHSupportingFeeOnTransferTokens( + token, liquidity, amountTokenMin, amountETHMin, to, deadline + ); + } +``` + +अंतिम फंक्शन स्टोरेज फीला मेटा-ट्रान्झॅक्शन्ससोबत जोडते. + +#### ट्रेड {#trade} + +```solidity + // **** स्वॅप (SWAP) **** + // सुरुवातीची रक्कम पहिल्या पेअरला आधीच पाठवली असणे आवश्यक आहे + function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual { +``` + +हे फंक्शन ट्रेडर्ससाठी उघड केलेल्या फंक्शन्ससाठी आवश्यक असलेली अंतर्गत प्रक्रिया करते. + +```solidity + for (uint i; i < path.length - 1; i++) { +``` + +मी हे लिहित असताना [388,160 ERC-20 टोकन्स](https://eth.blockscout.com/tokens) आहेत. जर प्रत्येक टोकन जोडीसाठी एक पेअर एक्सचेंज असते, तर ते 150 अब्जांहून अधिक पेअर एक्सचेंजेस झाले असते. सध्या संपूर्ण चेनवर, [त्या संख्येच्या फक्त 0.1% खाती आहेत](https://eth.blockscout.com/stats/accountsGrowth). त्याऐवजी, स्वॅप (swap) फंक्शन्स पाथच्या (path) संकल्पनेला समर्थन देतात. एक ट्रेडर A ला B साठी, B ला C साठी, आणि C ला D साठी एक्सचेंज करू शकतो, त्यामुळे थेट A-D पेअर एक्सचेंजची आवश्यकता नाही. + +या मार्केट्सवरील किमती सिंक्रोनाइझ (synchronized) असतात, कारण जेव्हा त्या सिंकच्या बाहेर असतात तेव्हा ते आर्बिट्रेजसाठी (arbitrage) संधी निर्माण करते. उदाहरणार्थ, A, B, आणि C या तीन टोकन्सची कल्पना करा. तीन पेअर एक्सचेंजेस आहेत, प्रत्येक जोडीसाठी एक. + +1. सुरुवातीची परिस्थिती +2. एक ट्रेडर 24.695 A टोकन्स विकतो आणि 25.305 B टोकन्स मिळवतो. +3. ट्रेडर 25.305 C टोकन्ससाठी 24.695 B टोकन्स विकतो, आणि अंदाजे 0.61 B टोकन्स नफा म्हणून ठेवतो. +4. त्यानंतर ट्रेडर 25.305 A टोकन्ससाठी 24.695 C टोकन्स विकतो, आणि अंदाजे 0.61 C टोकन्स नफा म्हणून ठेवतो. ट्रेडरकडे 0.61 अतिरिक्त A टोकन्स देखील आहेत (ट्रेडरकडे शेवटी असलेले 25.305, वजा 24.695 ची मूळ गुंतवणूक). + +| Step | A-B Exchange | B-C Exchange | A-C Exchange | +| ---- | --------------------------- | --------------------------- | --------------------------- | +| 1 | A:1000 B:1050 A/B=1.05 | B:1000 C:1050 B/C=1.05 | A:1050 C:1000 C/A=1.05 | +| 2 | A:1024.695 B:1024.695 A/B=1 | B:1000 C:1050 B/C=1.05 | A:1050 C:1000 C/A=1.05 | +| 3 | A:1024.695 B:1024.695 A/B=1 | B:1024.695 C:1024.695 B/C=1 | A:1050 C:1000 C/A=1.05 | +| 4 | A:1024.695 B:1024.695 A/B=1 | B:1024.695 C:1024.695 B/C=1 | A:1024.695 C:1024.695 C/A=1 | + +```solidity + (address input, address output) = (path[i], path[i + 1]); + (address token0,) = UniswapV2Library.sortTokens(input, output); + uint amountOut = amounts[i + 1]; +``` + +आपण सध्या हाताळत असलेली जोडी मिळवा, ती सॉर्ट (sort) करा (जोडीसोबत वापरण्यासाठी) आणि अपेक्षित आउटपुट रक्कम मिळवा. + +```solidity + (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); +``` + +पेअर एक्सचेंजला ज्या प्रकारे अपेक्षित आहे त्या प्रकारे सॉर्ट केलेल्या अपेक्षित आउट रकमा मिळवा. + +```solidity + address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; +``` + +हे शेवटचे एक्सचेंज आहे का? तसे असल्यास, ट्रेडसाठी मिळालेले टोकन्स डेस्टिनेशनला (destination) पाठवा. नसल्यास, ते पुढील पेअर एक्सचेंजला पाठवा. + +```solidity + + IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)).swap( + amount0Out, amount1Out, to, new bytes(0) + ); + } + } +``` + +टोकन्स स्वॅप करण्यासाठी प्रत्यक्षात पेअर एक्सचेंजला कॉल करा. एक्सचेंजविषयी सांगण्यासाठी आपल्याला कॉलबॅकची (callback) आवश्यकता नाही, त्यामुळे आपण त्या फील्डमध्ये कोणतेही बाइट्स (bytes) पाठवत नाही. + +```solidity + function swapExactTokensForTokens( +``` + +हे फंक्शन ट्रेडर्सद्वारे एका टोकनला दुसऱ्या टोकनसाठी स्वॅप करण्यासाठी थेट वापरले जाते. + +```solidity + uint amountIn, + uint amountOutMin, + address[] calldata path, +``` + +या पॅरामीटरमध्ये ERC-20 कॉन्ट्रॅक्ट्सचे पत्ते असतात. वर स्पष्ट केल्याप्रमाणे, हा एक अॅरे (array) आहे कारण तुमच्याकडे असलेल्या मालमत्तेवरून तुम्हाला हव्या असलेल्या मालमत्तेपर्यंत पोहोचण्यासाठी तुम्हाला अनेक पेअर एक्सचेंजेसमधून जावे लागू शकते. + +Solidity मधील फंक्शन पॅरामीटर एकतर `memory` किंवा `calldata` मध्ये स्टोअर केले जाऊ शकते. जर फंक्शन कॉन्ट्रॅक्टचा एंट्री पॉईंट असेल, जे थेट युजरकडून (ट्रान्झॅक्शन वापरून) किंवा वेगळ्या कॉन्ट्रॅक्टमधून कॉल केले गेले असेल, तर पॅरामीटरचे मूल्य थेट कॉल डेटामधून घेतले जाऊ शकते. जर फंक्शन अंतर्गत कॉल केले गेले असेल, जसे की वरील `_swap`, तर पॅरामीटर्स `memory` मध्ये स्टोअर करावे लागतात. कॉल केलेल्या कॉन्ट्रॅक्टच्या दृष्टिकोनातून `calldata` हे रीड ओन्ली (read only) असते. + +`uint` किंवा `address` सारख्या स्केलर (scalar) प्रकारांसह कंपायलर (compiler) आपल्यासाठी स्टोरेजची निवड हाताळतो, परंतु अॅरेसह, जे मोठे आणि अधिक महाग असतात, आपण वापरल्या जाणाऱ्या स्टोरेजचा प्रकार निर्दिष्ट करतो. + +```solidity + address to, + uint deadline + ) external virtual override ensure(deadline) returns (uint[] memory amounts) { +``` + +रिटर्न व्हॅल्यूज (Return values) नेहमी मेमरीमध्ये परत केल्या जातात. + +```solidity + amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); +``` + +प्रत्येक स्वॅपमध्ये खरेदी करावयाच्या रकमेची गणना करा. जर परिणाम ट्रेडर स्वीकारण्यास तयार असलेल्या किमान रकमेपेक्षा कमी असेल, तर ट्रान्झॅक्शनमधून रिव्हर्ट करा. + +```solidity + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, to); + } +``` + +शेवटी, सुरुवातीचे ERC-20 टोकन पहिल्या पेअर एक्सचेंजसाठी खात्यात ट्रान्सफर करा आणि `_swap` ला कॉल करा. हे सर्व एकाच ट्रान्झॅक्शनमध्ये होत आहे, त्यामुळे पेअर एक्सचेंजला माहित असते की कोणतेही अनपेक्षित टोकन्स या ट्रान्सफरचा भाग आहेत. + +```solidity + function swapTokensForExactTokens( + uint amountOut, + uint amountInMax, + address[] calldata path, + address to, + uint deadline + ) external virtual override ensure(deadline) returns (uint[] memory amounts) { + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, to); + } +``` + +मागील फंक्शन, `swapTokensForTokens`, ट्रेडरला तो देऊ इच्छित असलेल्या इनपुट टोकन्सची अचूक संख्या आणि त्या बदल्यात तो प्राप्त करू इच्छित असलेल्या आउटपुट टोकन्सची किमान संख्या निर्दिष्ट करण्याची परवानगी देते. हे फंक्शन रिव्हर्स स्वॅप (reverse swap) करते, ते ट्रेडरला त्याला हव्या असलेल्या आउटपुट टोकन्सची संख्या आणि त्यासाठी तो देऊ इच्छित असलेल्या इनपुट टोकन्सची कमाल संख्या निर्दिष्ट करू देते. + +दोन्ही प्रकरणांमध्ये, ट्रेडरला प्रथम या पेरिफेरी कॉन्ट्रॅक्टला त्यांना ट्रान्सफर करण्याची परवानगी देण्यासाठी अलाउन्स (allowance) द्यावा लागतो. + +```solidity + function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) + external + virtual + override + payable + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsOut(factory, msg.value, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + IWETH(WETH).deposit{value: amounts[0]}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + _swap(amounts, path, to); + } + + + function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) + external + virtual + override + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= amountInMax, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, address(this)); + IWETH(WETH).withdraw(amounts[amounts.length - 1]); + TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); + } + + + + function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) + external + virtual + override + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); + require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0] + ); + _swap(amounts, path, address(this)); + IWETH(WETH).withdraw(amounts[amounts.length - 1]); + TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]); + } + + + function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) + external + virtual + override + payable + ensure(deadline) + returns (uint[] memory amounts) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); + require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); + IWETH(WETH).deposit{value: amounts[0]}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0])); + _swap(amounts, path, to); + // काही उरलेले (dust) eth असल्यास, रिफंड करा + if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); + } +``` + +या चारही व्हेरिएंट्समध्ये (variants) ETH आणि टोकन्स दरम्यान ट्रेडिंगचा समावेश आहे. फरक एवढाच आहे की आपण एकतर ट्रेडरकडून ETH प्राप्त करतो आणि WETH मिंट करण्यासाठी त्याचा वापर करतो, किंवा आपण पाथमधील शेवटच्या एक्सचेंजकडून WETH प्राप्त करतो आणि ते बर्न करतो, आणि परिणामी मिळणारे ETH ट्रेडरला परत पाठवतो. + +```solidity + // **** स्वॅप (फी-ऑन-ट्रान्सफर टोकन्सना सपोर्ट करणारे) **** + // सुरुवातीची रक्कम पहिल्या पेअरला आधीच पाठवली असणे आवश्यक आहे + function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual { +``` + +ट्रान्सफर किंवा स्टोरेज फी असलेल्या टोकन्सना स्वॅप करण्यासाठी हे अंतर्गत फंक्शन आहे जेणेकरून ([ही समस्या](https://github.com/Uniswap/uniswap-interface/issues/835)) सोडवता येईल. + +```solidity + for (uint i; i < path.length - 1; i++) { + (address input, address output) = (path[i], path[i + 1]); + (address token0,) = UniswapV2Library.sortTokens(input, output); + IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, input, output)); + uint amountInput; + uint amountOutput; + { // 'stack too deep' एरर्स टाळण्यासाठी स्कोप + (uint reserve0, uint reserve1,) = pair.getReserves(); + (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput); + amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); +``` + +ट्रान्सफर फीमुळे आपण प्रत्येक ट्रान्सफरमधून आपल्याला किती मिळते हे सांगण्यासाठी `getAmountsOut` फंक्शनवर अवलंबून राहू शकत नाही (जसे आपण मूळ `_swap` ला कॉल करण्यापूर्वी करतो). त्याऐवजी आपल्याला प्रथम ट्रान्सफर करावे लागेल आणि नंतर आपल्याला किती टोकन्स परत मिळाले हे पहावे लागेल. + +टीप: सिद्धांतानुसार आपण `_swap` ऐवजी फक्त हे फंक्शन वापरू शकतो, परंतु काही प्रकरणांमध्ये (उदाहरणार्थ, जर आवश्यक किमान रक्कम पूर्ण करण्यासाठी शेवटी पुरेशी रक्कम नसल्यामुळे ट्रान्सफर रिव्हर्ट झाले) तर त्यासाठी अधिक गॅस खर्च होईल. ट्रान्सफर फी टोकन्स खूप दुर्मिळ आहेत, त्यामुळे आपल्याला त्यांना सामावून घेण्याची आवश्यकता असली तरी, सर्व स्वॅप्स किमान त्यापैकी एकामधून जातात असे गृहीत धरण्याची आवश्यकता नाही. + +```solidity + } + (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); + address to = i < path.length - 2 ? UniswapV2Library.pairFor(factory, output, path[i + 2]) : _to; + pair.swap(amount0Out, amount1Out, to, new bytes(0)); + } + } + + + function swapExactTokensForTokensSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) external virtual override ensure(deadline) { + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + ); + uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); + _swapSupportingFeeOnTransferTokens(path, to); + require( + IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, + 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + + + function swapExactETHForTokensSupportingFeeOnTransferTokens( + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) + external + virtual + override + payable + ensure(deadline) + { + require(path[0] == WETH, 'UniswapV2Router: INVALID_PATH'); + uint amountIn = msg.value; + IWETH(WETH).deposit{value: amountIn}(); + assert(IWETH(WETH).transfer(UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn)); + uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); + _swapSupportingFeeOnTransferTokens(path, to); + require( + IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin, + 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT' + ); + } + + + function swapExactTokensForETHSupportingFeeOnTransferTokens( + uint amountIn, + uint amountOutMin, + address[] calldata path, + address to, + uint deadline + ) + external + virtual + override + ensure(deadline) + { + require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH'); + TransferHelper.safeTransferFrom( + path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amountIn + ); + _swapSupportingFeeOnTransferTokens(path, address(this)); + uint amountOut = IERC20(WETH).balanceOf(address(this)); + require(amountOut >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT'); + IWETH(WETH).withdraw(amountOut); + TransferHelper.safeTransferETH(to, amountOut); + } +``` + +हे सामान्य टोकन्ससाठी वापरले जाणारे तेच व्हेरिएंट्स आहेत, परंतु ते त्याऐवजी `_swapSupportingFeeOnTransferTokens` ला कॉल करतात. + +```solidity + // **** लायब्ररी फंक्शन्स **** + function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) { + return UniswapV2Library.quote(amountA, reserveA, reserveB); + } + + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) + public + pure + virtual + override + returns (uint amountOut) + { + return UniswapV2Library.getAmountOut(amountIn, reserveIn, reserveOut); + } + + function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) + public + pure + virtual + override + returns (uint amountIn) + { + return UniswapV2Library.getAmountIn(amountOut, reserveIn, reserveOut); + } + + function getAmountsOut(uint amountIn, address[] memory path) + public + view + virtual + override + returns (uint[] memory amounts) + { + return UniswapV2Library.getAmountsOut(factory, amountIn, path); + } + + function getAmountsIn(uint amountOut, address[] memory path) + public + view + virtual + override + returns (uint[] memory amounts) + { + return UniswapV2Library.getAmountsIn(factory, amountOut, path); + } +} +``` + +ही फंक्शन्स फक्त प्रॉक्सी (proxies) आहेत जी [UniswapV2Library फंक्शन्सना](#uniswapV2library) कॉल करतात. + +### UniswapV2Migrator.sol {#UniswapV2Migrator} + +हे कॉन्ट्रॅक्ट जुन्या v1 वरून v2 वर एक्सचेंजेस मायग्रेट (migrate) करण्यासाठी वापरले गेले होते. आता ते मायग्रेट झाले असल्याने, ते यापुढे संबंधित नाही. + +## लायब्ररीज {#libraries} + +[SafeMath library](https://docs.openzeppelin.com/contracts/2.x/api/math) चे दस्तऐवजीकरण चांगले केले आहे, त्यामुळे येथे त्याचे दस्तऐवजीकरण करण्याची आवश्यकता नाही. + +### Math {#Math} + +या लायब्ररीमध्ये काही गणितीय फंक्शन्स आहेत ज्यांची सामान्यतः Solidity कोडमध्ये आवश्यकता नसते, त्यामुळे ते भाषेचा भाग नाहीत. + +```solidity +pragma solidity =0.5.16; + +// विविध गणितीय ऑपरेशन्स करण्यासाठी एक लायब्ररी + +library Math { + function min(uint x, uint y) internal pure returns (uint z) { + z = x < y ? x : y; + } + + // बॅबिलोनियन पद्धत (https://wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) + function sqrt(uint y) internal pure returns (uint z) { + if (y > 3) { + z = y; + uint x = y / 2 + 1; +``` + +x ने सुरुवात करा जो वर्गमुळापेक्षा जास्त असलेला अंदाज आहे (याच कारणामुळे आपल्याला 1-3 ला विशेष प्रकरणे म्हणून हाताळण्याची आवश्यकता आहे). + +```solidity + while (x < z) { + z = x; + x = (y / x + x) / 2; +``` + +अधिक जवळचा अंदाज मिळवा, मागील अंदाजाची सरासरी आणि ज्या संख्येचे वर्गमूळ आपण शोधण्याचा प्रयत्न करत आहोत तिला मागील अंदाजाने भागून मिळणारी संख्या. जोपर्यंत नवीन अंदाज विद्यमान अंदाजापेक्षा कमी होत नाही तोपर्यंत पुनरावृत्ती करा. अधिक तपशीलांसाठी, [येथे पहा](https://wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method). + +```solidity + } + } else if (y != 0) { + z = 1; +``` + +आपल्याला शून्याच्या वर्गमुळाची कधीही आवश्यकता भासू नये. एक, दोन आणि तीनचे वर्गमूळ साधारणपणे एक असते (आपण पूर्णांक वापरतो, त्यामुळे आपण अपूर्णांकाकडे दुर्लक्ष करतो). + +```solidity + } + } +} +``` + +### फिक्स्ड पॉइंट फ्रॅक्शन्स (UQ112x112) {#FixedPoint} + +ही लायब्ररी अपूर्णांक हाताळते, जे सामान्यतः Ethereum अंकगणिताचा भाग नसतात. हे _x_ या संख्येला _x\*2^112_ म्हणून एन्कोड करून असे करते. यामुळे आपल्याला मूळ बेरीज आणि वजाबाकी opcodes मध्ये कोणताही बदल न करता वापरता येतात. + +```solidity +pragma solidity =0.5.16; + +// बायनरी फिक्स्ड पॉईंट नंबर्स हाताळण्यासाठी एक लायब्ररी (https://wikipedia.org/wiki/Q_(number_format)) + +// रेंज: [0, 2**112 - 1] +// रिझोल्यूशन: 1 / 2**112 + +library UQ112x112 { + uint224 constant Q112 = 2**112; +``` + +`Q112` हे एकासाठी एन्कोडिंग आहे. + +```solidity + // uint112 ला UQ112x112 म्हणून एन्कोड करा + function encode(uint112 y) internal pure returns (uint224 z) { + z = uint224(y) * Q112; // कधीही ओव्हरफ्लो होत नाही + } +``` + +कारण y हे `uint112` आहे, ते जास्तीत जास्त 2^112-1 असू शकते. ती संख्या अजूनही `UQ112x112` म्हणून एन्कोड केली जाऊ शकते. + +```solidity + // UQ112x112 ला uint112 ने भागा, आणि UQ112x112 रिटर्न करा + function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { + z = x / uint224(y); + } +} +``` + +जर आपण दोन `UQ112x112` मूल्यांना भागले, तर परिणामाला यापुढे 2^112 ने गुणले जात नाही. त्यामुळे त्याऐवजी आपण छेदासाठी एक पूर्णांक घेतो. गुणाकार करण्यासाठी आपल्याला अशीच युक्ती वापरावी लागली असती, परंतु आपल्याला `UQ112x112` मूल्यांचा गुणाकार करण्याची आवश्यकता नाही. + +### UniswapV2Library {#uniswapV2library} + +ही लायब्ररी फक्त पेरिफेरी कॉन्ट्रॅक्ट्सद्वारे वापरली जाते + +```solidity +pragma solidity >=0.5.0; + +import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; + +import "./SafeMath.sol"; + +library UniswapV2Library { + using SafeMath for uint; + + // सॉर्ट केलेले टोकन अ‍ॅड्रेसेस रिटर्न करते, या क्रमाने सॉर्ट केलेल्या पेअर्समधून रिटर्न व्हॅल्यूज हाताळण्यासाठी वापरले जाते + function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { + require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); + (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); + require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); + } +``` + +दोन टोकन्सना पत्त्यानुसार क्रमवारी लावा, जेणेकरून आपल्याला त्यांच्यासाठी पेअर एक्सचेंजचा पत्ता मिळू शकेल. हे आवश्यक आहे कारण अन्यथा आपल्याकडे दोन शक्यता असतील, एक A,B पॅरामीटर्ससाठी आणि दुसरी B,A पॅरामीटर्ससाठी, ज्यामुळे एकाऐवजी दोन एक्सचेंजेस तयार होतील. + +```solidity + // कोणतेही बाह्य कॉल्स न करता पेअरसाठी CREATE2 अ‍ॅड्रेस कॅल्क्युलेट करते + function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { + (address token0, address token1) = sortTokens(tokenA, tokenB); + pair = address(uint(keccak256(abi.encodePacked( + hex'ff', + factory, + keccak256(abi.encodePacked(token0, token1)), + hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init कोड हॅश + )))); + } +``` + +हे फंक्शन दोन टोकन्ससाठी पेअर एक्सचेंजच्या पत्त्याची गणना करते. हे कॉन्ट्रॅक्ट [CREATE2 opcode](https://eips.ethereum.org/EIPS/eip-1014) वापरून तयार केले आहे, त्यामुळे जर आपल्याला ते वापरत असलेले पॅरामीटर्स माहित असतील तर आपण त्याच अल्गोरिदमचा वापर करून पत्त्याची गणना करू शकतो. फॅक्टरीला विचारण्यापेक्षा हे खूप स्वस्त आहे, आणि + +```solidity + // पेअरसाठी रिझर्व्ह फेच करते आणि सॉर्ट करते + function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { + (address token0,) = sortTokens(tokenA, tokenB); + (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves(); + (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + } +``` + +हे फंक्शन पेअर एक्सचेंजकडे असलेल्या दोन टोकन्सचे रिझर्व्ह परत करते. लक्षात घ्या की ते कोणत्याही क्रमाने टोकन्स प्राप्त करू शकते आणि अंतर्गत वापरासाठी त्यांची क्रमवारी लावते. + +```solidity + // एखाद्या अ‍ॅसेटची काही रक्कम आणि पेअर रिझर्व्ह दिले असता, दुसऱ्या अ‍ॅसेटची समतुल्य रक्कम रिटर्न करते + function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { + require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); + require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); + amountB = amountA.mul(reserveB) / reserveA; + } +``` + +जर कोणतीही फी समाविष्ट नसेल तर हे फंक्शन तुम्हाला टोकन A च्या बदल्यात मिळणाऱ्या टोकन B ची रक्कम देते. ही गणना हे लक्षात घेते की ट्रान्सफरमुळे विनिमय दर बदलतो. + +```solidity + // एखाद्या अ‍ॅसेटची इनपुट रक्कम आणि पेअर रिझर्व्ह दिले असता, दुसऱ्या अ‍ॅसेटची कमाल आउटपुट रक्कम रिटर्न करते + function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { +``` + +जर पेअर एक्सचेंज वापरण्यासाठी कोणतीही फी नसेल तर वरील `quote` फंक्शन उत्तम काम करते. तथापि, जर 0.3% एक्सचेंज फी असेल तर तुम्हाला प्रत्यक्षात मिळणारी रक्कम कमी असते. हे फंक्शन एक्सचेंज फी नंतरच्या रकमेची गणना करते. + +```solidity + + require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); + require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); + uint amountInWithFee = amountIn.mul(997); + uint numerator = amountInWithFee.mul(reserveOut); + uint denominator = reserveIn.mul(1000).add(amountInWithFee); + amountOut = numerator / denominator; + } +``` + +Solidity मूळतः अपूर्णांक हाताळत नाही, त्यामुळे आपण रकमेला फक्त 0.997 ने गुणू शकत नाही. त्याऐवजी, आपण अंशाला 997 ने आणि छेदाला 1000 ने गुणतो, ज्यामुळे तोच परिणाम साध्य होतो. + +```solidity + // एखाद्या अ‍ॅसेटची आउटपुट रक्कम आणि पेअर रिझर्व्ह दिले असता, दुसऱ्या अ‍ॅसेटची आवश्यक इनपुट रक्कम रिटर्न करते + function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { + require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); + require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); + uint numerator = reserveIn.mul(amountOut).mul(1000); + uint denominator = reserveOut.sub(amountOut).mul(997); + amountIn = (numerator / denominator).add(1); + } +``` + +हे फंक्शन साधारणपणे तेच काम करते, परंतु ते आउटपुट रक्कम मिळवते आणि इनपुट प्रदान करते. + +```solidity + + // कोणत्याही संख्येच्या पेअर्सवर चेन्ड (chained) getAmountOut कॅल्क्युलेशन्स करते + function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { + require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); + amounts = new uint[](path.length); + amounts[0] = amountIn; + for (uint i; i < path.length - 1; i++) { + (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); + amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); + } + } + + // कोणत्याही संख्येच्या पेअर्सवर चेन्ड (chained) getAmountIn कॅल्क्युलेशन्स करते + function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { + require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); + amounts = new uint[](path.length); + amounts[amounts.length - 1] = amountOut; + for (uint i = path.length - 1; i > 0; i--) { + (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); + amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); + } + } +} +``` + +जेव्हा अनेक पेअर एक्सचेंजेसमधून जाणे आवश्यक असते तेव्हा ही दोन फंक्शन्स मूल्ये ओळखण्याचे काम हाताळतात. + +### ट्रान्सफर हेल्पर {#transfer-helper} + +[ही लायब्ररी](https://github.com/Uniswap/uniswap-lib/blob/master/contracts/libraries/TransferHelper.sol) ERC-20 आणि Ethereum ट्रान्सफर्सच्या आसपास यश तपासणी जोडते जेणेकरून रिव्हर्ट आणि `false` मूल्य परतावा एकाच प्रकारे हाताळला जाईल. + +```solidity +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity >=0.6.0; + +// ERC20 टोकन्सशी संवाद साधण्यासाठी आणि ETH पाठवण्यासाठी हेल्पर मेथड्स जे सातत्याने true/false रिटर्न करत नाहीत +library TransferHelper { + function safeApprove( + address token, + address to, + uint256 value + ) internal { + // bytes4(keccak256(bytes('approve(address,uint256)'))); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); + +``` + +आपण दोनपैकी एका मार्गाने वेगळ्या कॉन्ट्रॅक्टला कॉल करू शकतो: + +- फंक्शन कॉल तयार करण्यासाठी इंटरफेस व्याख्येचा वापर करा +- कॉल तयार करण्यासाठी "मॅन्युअली" [अॅप्लिकेशन बायनरी इंटरफेस (ABI)](https://docs.soliditylang.org/en/v0.8.3/abi-spec.html) चा वापर करा. कोडच्या लेखकाने हेच करण्याचे ठरवले आहे. + +```solidity + require( + success && (data.length == 0 || abi.decode(data, (bool))), + 'TransferHelper::safeApprove: approve failed' + ); + } +``` + +ERC-20 मानकापूर्वी तयार केलेल्या टोकनसह बॅकवर्ड्स कंपॅटिबिलिटीसाठी, ERC-20 कॉल एकतर रिव्हर्ट करून (ज्या प्रकरणात `success` हे `false` असते) किंवा यशस्वी होऊन आणि `false` मूल्य परत करून (ज्या प्रकरणात आउटपुट डेटा असतो, आणि जर तुम्ही त्याला बुलियन म्हणून डीकोड केले तर तुम्हाला `false` मिळते) अयशस्वी होऊ शकतो. + +```solidity + + + function safeTransfer( + address token, + address to, + uint256 value + ) internal { + // bytes4(keccak256(bytes('transfer(address,uint256)'))); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); + require( + success && (data.length == 0 || abi.decode(data, (bool))), + 'TransferHelper::safeTransfer: transfer failed' + ); + } +``` + +हे फंक्शन [ERC-20 ची ट्रान्सफर कार्यक्षमता](https://eips.ethereum.org/EIPS/eip-20#transfer) लागू करते, जे एका खात्याला वेगळ्या खात्याद्वारे प्रदान केलेला भत्ता खर्च करण्याची परवानगी देते. + +```solidity + + function safeTransferFrom( + address token, + address from, + address to, + uint256 value + ) internal { + // bytes4(keccak256(bytes('transferFrom(address,address,uint256)'))); + (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value)); + require( + success && (data.length == 0 || abi.decode(data, (bool))), + 'TransferHelper::transferFrom: transferFrom failed' + ); + } +``` + +हे फंक्शन [ERC-20 ची transferFrom कार्यक्षमता](https://eips.ethereum.org/EIPS/eip-20#transferfrom) लागू करते, जे एका खात्याला वेगळ्या खात्याद्वारे प्रदान केलेला भत्ता खर्च करण्याची परवानगी देते. + +```solidity + + function safeTransferETH(address to, uint256 value) internal { + (bool success, ) = to.call{value: value}(new bytes(0)); + require(success, 'TransferHelper::safeTransferETH: ETH transfer failed'); + } +} +``` + +हे फंक्शन खात्यात इथर ट्रान्सफर करते. वेगळ्या कॉन्ट्रॅक्टला केलेला कोणताही कॉल इथर पाठवण्याचा प्रयत्न करू शकतो. कारण आपल्याला प्रत्यक्षात कोणत्याही फंक्शनला कॉल करण्याची आवश्यकता नाही, आपण कॉलसह कोणताही डेटा पाठवत नाही. + +## निष्कर्ष {#conclusion} + +हा सुमारे 50 पानांचा एक मोठा लेख आहे. जर तुम्ही इथपर्यंत पोहोचला असाल, तर तुमचे अभिनंदन! आशा आहे की आतापर्यंत तुम्हाला (लहान नमुना प्रोग्राम्सच्या तुलनेत) वास्तविक जीवनातील ॲप्लिकेशन लिहिताना कोणत्या गोष्टी विचारात घ्याव्या लागतात हे समजले असेल आणि तुम्ही तुमच्या स्वतःच्या युज केसेससाठी कॉन्ट्रॅक्ट्स अधिक चांगल्या प्रकारे लिहू शकाल. + +आता जा आणि काहीतरी उपयुक्त लिहा आणि आम्हाला थक्क करा. + +[माझ्या अधिक कामासाठी येथे पहा](https://cryptodocguy.pro/). \ No newline at end of file From ff5883631bb7e5dc799eac5332d7053e5b2052c8 Mon Sep 17 00:00:00 2001 From: wackerow <54227730+wackerow@users.noreply.github.com> Date: Tue, 24 Mar 2026 20:50:26 -0700 Subject: [PATCH 8/9] revert: tag transliteration --- .../mr/developers/tutorials/uniswap-v2-annotated-code/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md b/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md index 20aac56cd02..0071aa47a90 100644 --- a/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md +++ b/public/content/translations/mr/developers/tutorials/uniswap-v2-annotated-code/index.md @@ -2,7 +2,7 @@ title: "Uniswap-v2 कॉन्ट्रॅक्ट वॉक-थ्रू" description: Uniswap-v2 कॉन्ट्रॅक्ट कसे काम करते? ते तसे का लिहिले आहे? author: Ori Pomerantz -tags: ["solidity", "डॅप्स"] +tags: ["solidity", "dapps"] skill: intermediate breadcrumb: Uniswap v2 वॉक-थ्रू published: 2021-05-01 From 91a808f8bf5486eb48fe1a0f3612d7f5aebe5279 Mon Sep 17 00:00:00 2001 From: myelinated-wackerow <263208946+myelinated-wackerow@users.noreply.github.com> Date: Wed, 25 Mar 2026 04:17:43 +0000 Subject: [PATCH 9/9] fix(i18n): translate frontmatter, fix fences Translate title, description, and breadcrumb to Marathi. Fix 8 code block closing fences misaligned at column 0 inside list items. Remove extra blank lines in commented-out useEffect block. Co-Authored-By: Claude Opus 4.6 Co-Authored-By: wackerow <54227730+wackerow@users.noreply.github.com> --- .../index.md | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md b/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md index 977a57b148b..ffe22adcb43 100644 --- a/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md +++ b/public/content/translations/mr/developers/tutorials/creating-a-wagmi-ui-for-your-contract/index.md @@ -1,10 +1,10 @@ --- -title: "Building a user interface for your contract" -description: Using modern components such as TypeScript, React, Vite, and Wagmi, we will go over a modern, but minimal, user interface and learn how to connect a wallet to the user interface, call a smart contract to read information, send a transaction to a smart contract, and monitor events from a smart contract to identify changes. +title: "तुमच्या कॉन्ट्रॅक्टसाठी युजर इंटरफेस तयार करणे" +description: "TypeScript, React, Vite आणि Wagmi सारख्या आधुनिक कॉम्पोनेंट्स वापरून, आम्ही एक आधुनिक परंतु किमान युजर इंटरफेस पाहू आणि वॉलेट युजर इंटरफेसशी कसे कनेक्ट करायचे, माहिती वाचण्यासाठी स्मार्ट कॉन्ट्रॅक्टला कसे कॉल करायचे, स्मार्ट कॉन्ट्रॅक्टवर ट्रॅन्सॅक्शन कसे पाठवायचे आणि बदल ओळखण्यासाठी स्मार्ट कॉन्ट्रॅक्टमधील इव्हेंट्स कसे मॉनिटर करायचे हे शिकू." author: Ori Pomerantz tags: ["typescript", "react", "vite", "wagmi", "फ्रंटएंड"] skill: beginner -breadcrumb: UI with WAGMI +breadcrumb: "WAGMI सोबत UI" published: 2023-11-01 lang: mr sidebarDepth: 3 @@ -32,7 +32,7 @@ sidebarDepth: 3 git clone https://github.com/qbzzt/260301-modern-ui-web3.git cd 260301-modern-ui-web3 npm install -``` + ``` 3. हे ॲप्लिकेशन मोफत ॲक्सेस पॉईंट्स वापरते, ज्यांच्या परफॉर्मन्सवर मर्यादा आहेत. जर तुम्हाला [नोड ॲज अ सर्व्हिस](/developers/docs/nodes-and-clients/nodes-as-a-service/) प्रोव्हायडर वापरायचा असेल, तर [`src/wagmi.ts`](#wagmi-ts) मधील URLs बदला. @@ -40,7 +40,7 @@ sidebarDepth: 3 ```sh npm run dev -``` + ``` 5. ॲप्लिकेशनद्वारे दर्शविलेल्या URL वर जा. बहुतांश प्रकरणांमध्ये, ते [http://localhost:5173/](http://localhost:5173/) असते. @@ -668,7 +668,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ ```ts import { defineChain } from 'viem' -``` + ``` B. नेटवर्क डेफिनेशन जोडा. तुम्हाला Optimism Sepolia साठी हे करण्याची खरोखर गरज नाही, [ते आधीपासूनच `viem` मध्ये आहे](https://github.com/wevm/viem/blob/main/src/chains/definitions/optimismSepolia.ts), परंतु या मार्गाने तुम्ही `viem` मध्ये नसलेली ब्लॉकचेन कशी जोडायची हे शिकता. @@ -691,7 +691,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ } }, }) -``` + ``` C. `createConfig` कॉलमध्ये नवीन चेन जोडा. @@ -707,7 +707,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ }, multiInjectedProviderDiscovery: false, }) -``` + ``` 2. Sepolia वरील स्वयंचलित स्विच कमेंट आऊट करण्यासाठी `src/App.tsx` एडिट करा. प्रोडक्शन सिस्टीमवर, तुम्ही कदाचित तुम्ही सपोर्ट करत असलेल्या प्रत्येक ब्लॉकचेनच्या लिंक्ससह बटणे दाखवाल. @@ -719,16 +719,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ switchChain({ chainId: SEPOLIA_CHAIN_ID }) } }, [connection.status, connection.chainId]) */ - - - - - - - - - -``` + ``` 3. ॲप्लिकेशनला नवीन नेटवर्कवरील तुमच्या कॉन्ट्रॅक्ट्सचा ॲड्रेस माहित आहे याची खात्री करण्यासाठी `src/Greeter.tsx` एडिट करा. @@ -740,7 +731,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ // सेपोलिया 11155111: "0x7143d5c190F048C8d19fe325b748b081903E3BF0", } -``` + ``` 4. तुमच्या ब्राउझरमध्ये. @@ -756,7 +747,7 @@ Viem सोबत येणारा डीफॉल्ट HTTP एंडपॉ ```sh copy npm create wagmi -``` + ``` 2. पुढे जाण्यासाठी `y` टाईप करा.