मुख्य सामग्री पर जाएँ

गोपनीय पतों का उपयोग करना

गोपनीय पता
गोपनीयता
क्रिप्टोग्राफ़ी
Rust
wasm
माध्यमिक
ओरी पोमेरेंट्ज़
30 नवंबर 2025
18 मिनट का पठन

आप बिल हैं। उन कारणों से जिन पर हम चर्चा नहीं करेंगे, आप "पूरी दुनिया की रानी के लिए एलिस" अभियान को दान देना चाहते हैं और चाहते हैं कि एलिस को पता चले कि आपने दान दिया है ताकि अगर वह जीतती है तो वह आपको पुरस्कृत करेगी। दुर्भाग्य से, उसकी जीत की गारंटी नहीं है। एक प्रतिस्पर्धी अभियान है, "सौर मंडल की महारानी के लिए कैरल"। यदि कैरल जीत जाती है, और उसे पता चलता है कि आपने ऐलिस को दान दिया है, तो आप मुश्किल में पड़ जाएँगे। तो आप अपने खाते से एलिस के खाते में सिर्फ 200 ETH स्थानांतरित नहीं कर सकते।

ERC-5564 (opens in a new tab) के पास इसका समाधान है। यह ERC बताता है कि गुमनाम स्थानांतरण के लिए गोपनीय पतों (opens in a new tab) का उपयोग कैसे करें।

चेतावनी: गोपनीय पतों के पीछे की क्रिप्टोग्राफी, जहाँ तक हम जानते हैं, सुदृढ़ है। हालाँकि, इसमें संभावित साइड-चैनल हमले हो सकते हैं। नीचे, आप देखेंगे कि इस जोखिम को कम करने के लिए आप क्या कर सकते हैं।

गोपनीय पते कैसे काम करते हैं

यह लेख दो तरीकों से गोपनीय पतों को समझाने का प्रयास करेगा। पहला है उनका उपयोग कैसे करें। यह भाग लेख के बाकी हिस्सों को समझने के लिए पर्याप्त है। फिर, इसके पीछे के गणित की व्याख्या है। यदि आप क्रिप्टोग्राफी में रुचि रखते हैं, तो इस भाग को भी पढ़ें।

सरल संस्करण (गोपनीय पतों का उपयोग कैसे करें)

एलिस दो निजी कुंजियाँ बनाती है और संबंधित सार्वजनिक कुंजियाँ प्रकाशित करती है (जिन्हें एक एकल दोहरी-लंबाई वाले मेटा-पते में जोड़ा जा सकता है)। बिल भी एक निजी कुंजी बनाता है और संबंधित सार्वजनिक कुंजी प्रकाशित करता है।

एक पक्ष की सार्वजनिक कुंजी और दूसरे की निजी कुंजी का उपयोग करके, आप केवल एलिस और बिल को ज्ञात एक साझा रहस्य प्राप्त कर सकते हैं (इसे केवल सार्वजनिक कुंजियों से प्राप्त नहीं किया जा सकता है)। इस साझा रहस्य का उपयोग करके, बिल गोपनीय पता प्राप्त करता है और उसमें संपत्ति भेज सकता है।

एलिस को भी साझा रहस्य से पता मिलता है, लेकिन क्योंकि वह अपने द्वारा प्रकाशित सार्वजनिक कुंजियों की निजी कुंजियाँ जानती है, वह उस पते से निकासी करने वाली निजी कुंजी भी प्राप्त कर सकती है।

गणित (गोपनीय पते इस तरह क्यों काम करते हैं)

मानक गोपनीय पते कम कुंजी बिट्स के साथ बेहतर प्रदर्शन पाने के लिए एलिप्टिक-कर्व क्रिप्टोग्राफी (ECC) (opens in a new tab) का उपयोग करते हैं, जबकि सुरक्षा का समान स्तर बनाए रखते हैं। लेकिन ज़्यादातर हम इसे अनदेखा कर सकते हैं और मान सकते हैं कि हम नियमित अंकगणित का उपयोग कर रहे हैं।

एक संख्या है जिसे हर कोई जानता है, G। आप G से गुणा कर सकते हैं। लेकिन ECC की प्रकृति के कारण, G से विभाजित करना व्यावहारिक रूप से असंभव है। जिस तरह से एथेरियम में सार्वजनिक कुंजी क्रिप्टोग्राफी आम तौर पर काम करती है, वह यह है कि आप एक निजी कुंजी, Ppriv, का उपयोग लेनदेन पर हस्ताक्षर करने के लिए कर सकते हैं जिन्हें फिर एक सार्वजनिक कुंजी, Ppub = GPpriv द्वारा सत्यापित किया जाता है।

एलिस दो निजी कुंजियाँ, Kpriv और Vpriv बनाती है। Kpriv का उपयोग गोपनीय पते से पैसे खर्च करने के लिए किया जाएगा, और Vpriv का उपयोग एलिस से संबंधित पतों को देखने के लिए किया जाएगा। एलिस फिर सार्वजनिक कुंजियाँ प्रकाशित करती है: Kpub = GKpriv और Vpub = GVpriv

बिल एक तीसरी निजी कुंजी, Rpriv बनाता है, और Rpub = GRpriv को एक केंद्रीय रजिस्ट्री में प्रकाशित करता है (बिल इसे एलिस को भी भेज सकता था, लेकिन हम मानते हैं कि कैरल सुन रही है)।

बिल RprivVpub = GRprivVpriv की गणना करता है, जिसके बारे में वह उम्मीद करता है कि एलिस भी जानती होगी (नीचे समझाया गया है)। इस मान को S, साझा रहस्य कहा जाता है। यह बिल को एक सार्वजनिक कुंजी देता है, Ppub = Kpub+G*hash(S)। इस सार्वजनिक कुंजी से, वह एक पते की गणना कर सकता है और जो भी संसाधन वह चाहता है उसे भेज सकता है। भविष्य में, यदि एलिस जीत जाती है, तो बिल उसे Rpriv बताकर यह साबित कर सकता है कि संसाधन उसकी ओर से आए थे।

एलिस RpubVpriv = GRprivVpriv की गणना करती है। यह उसे वही साझा रहस्य, S देता है। क्योंकि वह निजी कुंजी, Kpriv जानती है, वह Ppriv = Kpriv+hash(S) की गणना कर सकती है। यह कुंजी उसे उस पते में संपत्ति तक पहुँचने देती है जो Ppub = GPpriv = GKpriv+G*hash(S) = Kpub+G*hash(S) से प्राप्त होता है।

हमारे पास एक अलग देखने वाली कुंजी है ताकि एलिस डेव की वर्ल्ड डॉमिनेशन कैंपेन सर्विसेज को सब-कॉन्ट्रैक्ट दे सके। एलिस डेव को सार्वजनिक पतों को जानने देने और अधिक पैसे उपलब्ध होने पर उसे सूचित करने के लिए तैयार है, लेकिन वह नहीं चाहती कि वह उसके अभियान का पैसा खर्च करे।

क्योंकि देखने और खर्च करने के लिए अलग-अलग कुंजियों का उपयोग होता है, एलिस डेव को Vpriv दे सकती है। तब डेव S = RpubVpriv = GRprivVpriv की गणना कर सकता है और इस तरह सार्वजनिक कुंजियाँ (Ppub = Kpub+G*hash(S)) प्राप्त कर सकता है। लेकिन Kpriv के बिना डेव निजी कुंजी प्राप्त नहीं कर सकता।

सारांश में, ये विभिन्न प्रतिभागियों द्वारा ज्ञात मान हैं।

एलिसप्रकाशितबिलडेव
GGGG
Kpriv
VprivVpriv
Kpub = GKprivKpubKpubKpub
Vpub = GVprivVpubVpubVpub
Rpriv
RpubRpubRpub = GRprivRpub
S = RpubVpriv = GRprivVprivS = RprivVpub = GRprivVprivS = 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)

जब गोपनीय पते गलत हो जाते हैं

ब्लॉकचेन पर कोई रहस्य नहीं हैं। हालांकि गोपनीय पते आपको गोपनीयता प्रदान कर सकते हैं, वह गोपनीयता ट्रैफिक विश्लेषण के प्रति संवेदनशील है। एक मामूली उदाहरण लेने के लिए, कल्पना करें कि बिल एक पते को फंड करता है और तुरंत एक Rpub मान प्रकाशित करने के लिए एक लेनदेन भेजता है। एलिस के Vpriv के बिना, हम यह सुनिश्चित नहीं कर सकते कि यह एक गोपनीय पता है, लेकिन शर्त लगाने का यही तरीका है। फिर, हम एक और लेनदेन देखते हैं जो उस पते से सभी ETH को एलिस के अभियान निधि पते पर स्थानांतरित करता है। हम इसे साबित नहीं कर सकते हैं, लेकिन यह संभावना है कि बिल ने अभी-अभी एलिस के अभियान को दान दिया है। कैरल निश्चित रूप से ऐसा ही सोचेगी।

बिल के लिए Rpub के प्रकाशन को गोपनीय पते की फंडिंग से अलग करना आसान है (उन्हें अलग-अलग समय पर, अलग-अलग पतों से करें)। हालाँकि, यह अपर्याप्त है। कैरल जिस पैटर्न की तलाश करती है वह यह है कि बिल एक पते को फंड करता है, और फिर एलिस का अभियान फंड उससे निकासी करता है।

एक समाधान यह है कि एलिस का अभियान सीधे पैसे की निकासी न करे, बल्कि इसका उपयोग किसी तीसरे पक्ष को भुगतान करने के लिए करे। यदि एलिस का अभियान डेव की वर्ल्ड डॉमिनेशन कैंपेन सर्विसेज को 10 ETH भेजता है, तो कैरल को केवल यह पता चलता है कि बिल ने डेव के ग्राहकों में से एक को दान दिया है। यदि डेव के पास पर्याप्त ग्राहक हैं, तो कैरल यह नहीं जान पाएगी कि बिल ने एलिस को दान दिया है जो उसके साथ प्रतिस्पर्धा करती है, या एडम, अल्बर्ट, या अबीगैल को, जिनकी कैरल को परवाह नहीं है। एलिस भुगतान के साथ एक हैश किया हुआ मान शामिल कर सकती है, और फिर डेव को प्रीइमेज प्रदान कर सकती है, यह साबित करने के लिए कि यह उसका दान था। वैकल्पिक रूप से, जैसा कि ऊपर उल्लेख किया गया है, यदि एलिस डेव को अपना Vpriv देती है, तो वह पहले से ही जानता है कि भुगतान किससे आया है।

इस समाधान के साथ मुख्य समस्या यह है कि इसमें एलिस को गोपनीयता की परवाह करने की आवश्यकता होती है जब उस गोपनीयता से बिल को लाभ होता है। एलिस अपनी प्रतिष्ठा बनाए रखना चाह सकती है ताकि बिल का दोस्त बॉब भी उसे दान दे। लेकिन यह भी संभव है कि उसे बिल को बेनकाब करने में कोई आपत्ति न हो, क्योंकि तब उसे डर होगा कि अगर कैरल जीत गई तो क्या होगा। बिल शायद एलिस को और भी अधिक समर्थन प्रदान करेगा।

कई गोपनीय परतों का उपयोग करना

बिल की गोपनीयता को बनाए रखने के लिए एलिस पर निर्भर रहने के बजाय, बिल इसे स्वयं कर सकता है। वह काल्पनिक लोगों, बॉब और बेला के लिए कई मेटा-पते उत्पन्न कर सकता है। बिल फिर बॉब को ETH भेजता है, और "बॉब" (जो वास्तव में बिल है) इसे बेला को भेजता है। "बेला" (जो बिल भी है) इसे एलिस को भेजती है।

कैरल अभी भी ट्रैफिक विश्लेषण कर सकती है और बिल-से-बॉब-से-बेला-से-एलिस पाइपलाइन देख सकती है। हालाँकि, यदि "बॉब" और "बेला" अन्य उद्देश्यों के लिए भी ETH का उपयोग करते हैं, तो यह प्रतीत नहीं होगा कि बिल ने एलिस को कुछ भी स्थानांतरित किया है, भले ही एलिस तुरंत गोपनीय पते से अपने ज्ञात अभियान पते पर निकासी कर ले।

एक गोपनीय-पता एप्लिकेशन लिखना

यह लेख एक गोपनीय-पता एप्लिकेशन की व्याख्या करता है जो गिटहब पर उपलब्ध है (opens in a new tab)

उपकरण

एक टाइपस्क्रिप्ट गोपनीय पता लाइब्रेरी (opens in a new tab) है जिसका हम उपयोग कर सकते हैं। हालाँकि, क्रिप्टोग्राफ़िक संचालन CPU-गहन हो सकते हैं। मैं उन्हें रस्ट (opens in a new tab) जैसी संकलित भाषा में लागू करना पसंद करता हूँ, और ब्राउज़र में कोड चलाने के लिए WASM (opens in a new tab) का उपयोग करता हूँ।

हम वीट (opens in a new tab) और रिएक्ट (opens in a new tab) का उपयोग करने जा रहे हैं। ये उद्योग-मानक उपकरण हैं; यदि आप इनसे परिचित नहीं हैं, तो आप इस ट्यूटोरियल का उपयोग कर सकते हैं। वीट का उपयोग करने के लिए, हमें Node की आवश्यकता है।

गोपनीय पतों को क्रिया में देखें

  1. आवश्यक उपकरण स्थापित करें: रस्ट (opens in a new tab) और Node (opens in a new tab)

  2. गिटहब रिपॉजिटरी को क्लोन करें।

    1git clone https://github.com/qbzzt/251022-stealth-addresses.git
    2cd 251022-stealth-addresses
  3. आवश्यक शर्तें स्थापित करें और रस्ट कोड संकलित करें।

    1cd src/rust-wasm
    2rustup target add wasm32-unknown-unknown
    3cargo install wasm-pack
    4wasm-pack build --target web
  4. वेब सर्वर शुरू करें।

    1cd ../..
    2npm install
    3npm run dev
  5. एप्लिकेशन (opens in a new tab) पर ब्राउज़ करें। इस एप्लिकेशन पेज में दो फ्रेम हैं: एक एलिस के यूज़र इंटरफेस के लिए और दूसरा बिल के लिए। दोनों फ्रेम संवाद नहीं करते हैं; वे केवल सुविधा के लिए एक ही पेज पर हैं।

  6. एलिस के रूप में, एक गोपनीय मेटा-पता उत्पन्न करें पर क्लिक करें। यह नया गोपनीय पता और संबंधित निजी कुंजियाँ प्रदर्शित करेगा। गोपनीय मेटा-पते को क्लिपबोर्ड पर कॉपी करें।

  7. बिल के रूप में, नया गोपनीय मेटा-पता पेस्ट करें और एक पता उत्पन्न करें पर क्लिक करें। यह आपको एलिस के लिए फंड करने का पता देता है।

  8. पते और बिल की सार्वजनिक कुंजी को कॉपी करें और उन्हें एलिस के यूज़र इंटरफेस के "बिल द्वारा उत्पन्न पते के लिए निजी कुंजी" क्षेत्र में पेस्ट करें। एक बार जब वे फ़ील्ड भर दिए जाते हैं, तो आप उस पते पर संपत्ति तक पहुँचने के लिए निजी कुंजी देखेंगे।

  9. आप यह सुनिश्चित करने के लिए एक ऑनलाइन कैलकुलेटर (opens in a new tab) का उपयोग कर सकते हैं कि निजी कुंजी पते से मेल खाती है।

प्रोग्राम कैसे काम करता है

WASM घटक

WASM में संकलित होने वाला स्रोत कोड रस्ट (opens in a new tab) में लिखा गया है। आप इसे src/rust_wasm/src/lib.rs (opens in a new tab) में देख सकते हैं। यह कोड मुख्य रूप से जावास्क्रिप्ट कोड और eth-stealth-addresses लाइब्रेरी (opens in a new tab) के बीच एक इंटरफ़ेस है।

Cargo.toml

रस्ट में Cargo.toml (opens in a new tab) जावास्क्रिप्ट में package.json (opens in a new tab) के अनुरूप है। इसमें पैकेज जानकारी, निर्भरता घोषणाएँ आदि शामिल हैं।

1[package]
2name = "rust-wasm"
3version = "0.1.0"
4edition = "2024"
5
6[dependencies]
7eth-stealth-addresses = "0.1.0"
8hex = "0.4.3"
9wasm-bindgen = "0.2.104"
10getrandom = { version = "0.2", features = ["js"] }
सभी दिखाएँ

getrandom (opens in a new tab) पैकेज को यादृच्छिक मान उत्पन्न करने की आवश्यकता है। यह केवल एल्गोरिथम माध्यमों से नहीं किया जा सकता है; इसके लिए एन्ट्रापी के स्रोत के रूप में एक भौतिक प्रक्रिया तक पहुंच की आवश्यकता होती है। यह परिभाषा निर्दिष्ट करती है कि हम जिस ब्राउज़र में चल रहे हैं, उससे पूछकर वह एन्ट्रापी प्राप्त करेंगे।

1console_error_panic_hook = "0.1.7"

यह लाइब्रेरी (opens in a new tab) हमें अधिक सार्थक त्रुटि संदेश देती है जब WASM कोड पैनिक करता है और जारी नहीं रह सकता है।

1[lib]
2crate-type = ["cdylib", "rlib"]

WASM कोड बनाने के लिए आवश्यक आउटपुट प्रकार।

lib.rs

यह वास्तविक रस्ट कोड है।

1use wasm_bindgen::prelude::*;

रस्ट से WASM पैकेज बनाने के लिए परिभाषाएँ। वे यहां (opens in a new tab) प्रलेखित हैं।

1use eth_stealth_addresses::{
2 generate_stealth_meta_address,
3 generate_stealth_address,
4 compute_stealth_key
5};

वे फ़ंक्शन जिनकी हमें eth-stealth-addresses लाइब्रेरी (opens in a new tab) से आवश्यकता है।

1use hex::{decode,encode};

रस्ट आमतौर पर मानों के लिए बाइट ऐरे (opens in a new tab) ([u8; <size>]) का उपयोग करता है। लेकिन जावास्क्रिप्ट में, हम आमतौर पर हेक्साडेसिमल स्ट्रिंग्स का उपयोग करते हैं। hex लाइब्रेरी (opens in a new tab) हमारे लिए एक प्रतिनिधित्व से दूसरे में अनुवाद करती है।

1#[wasm_bindgen]

जावास्क्रिप्ट से इस फ़ंक्शन को कॉल करने में सक्षम होने के लिए WASM बाइंडिंग उत्पन्न करें।

1pub fn wasm_generate_stealth_meta_address() -> String {

कई फ़ील्ड वाले ऑब्जेक्ट को वापस करने का सबसे आसान तरीका JSON स्ट्रिंग वापस करना है।

1 let (address, spend_private_key, view_private_key) =
2 generate_stealth_meta_address();

generate_stealth_meta_address (opens in a new tab) तीन फ़ील्ड लौटाता है:

  • मेटा-पता (Kpub और Vpub)
  • देखने वाली निजी कुंजी (Vpriv)
  • खर्च करने वाली निजी कुंजी (Kpriv)

टपल (opens in a new tab) सिंटैक्स हमें उन मानों को फिर से अलग करने देता है।

1 format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}",
2 encode(address),
3 encode(view_private_key),
4 encode(spend_private_key)
5 )
6}

JSON-एन्कोडेड स्ट्रिंग उत्पन्न करने के लिए format! (opens in a new tab) मैक्रो का उपयोग करें। ऐरे को हेक्स स्ट्रिंग्स में बदलने के लिए hex::encode (opens in a new tab) का उपयोग करें।

1fn str_to_array<const N: usize>(s: &str) -> Option<[u8; N]> {

यह फ़ंक्शन एक हेक्स स्ट्रिंग (जावास्क्रिप्ट द्वारा प्रदान किया गया) को बाइट ऐरे में बदलता है। हम इसका उपयोग जावास्क्रिप्ट कोड द्वारा प्रदान किए गए मानों को पार्स करने के लिए करते हैं। यह फ़ंक्शन इस वजह से जटिल है कि रस्ट ऐरे और वेक्टर को कैसे संभालता है।

<const N: usize> एक्सप्रेशन को जेनेरिक (opens in a new tab) कहा जाता है। N एक पैरामीटर है जो लौटाए गए ऐरे की लंबाई को नियंत्रित करता है। फ़ंक्शन को वास्तव में str_to_array::<n> कहा जाता है, जहाँ n ऐरे की लंबाई है।

वापसी मान Option<[u8; N]> है, जिसका अर्थ है कि लौटाया गया ऐरे वैकल्पिक (opens in a new tab) है। यह रस्ट में उन फ़ंक्शन के लिए एक विशिष्ट पैटर्न है जो विफल हो सकते हैं।

उदाहरण के लिए, यदि हम str_to_array::10("bad060a7") को कॉल करते हैं, तो फ़ंक्शन को एक दस-मान ऐरे लौटाना चाहिए, लेकिन इनपुट केवल चार बाइट्स का है। फ़ंक्शन को विफल होना चाहिए, और यह None लौटाकर ऐसा करता है। str_to_array::4("bad060a7") के लिए वापसी मान Some<[0xba, 0xd0, 0x60, 0xa7]> होगा।

1 // decode returns Result<Vec<u8>, _>
2 let vec = decode(s).ok()?;

hex::decode (opens in a new tab) फ़ंक्शन एक Result<Vec<u8>, FromHexError> लौटाता है। Result (opens in a new tab) प्रकार में या तो एक सफल परिणाम (Ok(value)) या एक त्रुटि (Err(error)) हो सकती है।

.ok() विधि Result को Option में बदल देती है, जिसका मान या तो सफल होने पर Ok() मान होता है या नहीं होने पर None होता है। अंत में, प्रश्न चिह्न ऑपरेटर (opens in a new tab) वर्तमान फ़ंक्शन को समाप्त कर देता है और यदि Option खाली है तो None लौटाता है। अन्यथा, यह मान को अनरैप करता है और उसे लौटाता है (इस मामले में, vec को एक मान निर्दिष्ट करने के लिए)।

यह त्रुटियों को संभालने के लिए एक अजीब तरह से जटिल तरीका लगता है, लेकिन Result और Option यह सुनिश्चित करते हैं कि सभी त्रुटियों को किसी न किसी तरह से संभाला जाए।

1 if vec.len() != N { return None; }

यदि बाइट्स की संख्या गलत है, तो यह एक विफलता है, और हम None लौटाते हैं।

1 // try_into consumes vec and attempts to make [u8; N]
2 let array: [u8; N] = vec.try_into().ok()?;

रस्ट में दो ऐरे प्रकार होते हैं। ऐरे (opens in a new tab) का एक निश्चित आकार होता है। वेक्टर (opens in a new tab) बढ़ और घट सकते हैं। hex::decode एक वेक्टर लौटाता है, लेकिन eth_stealth_addresses लाइब्रेरी ऐरे प्राप्त करना चाहती है। .try_into() (opens in a new tab) एक मान को दूसरे प्रकार में परिवर्तित करता है, उदाहरण के लिए, एक वेक्टर को एक ऐरे में।

1 Some(array)
2}

रस्ट को किसी फ़ंक्शन के अंत में मान लौटाते समय return (opens in a new tab) कीवर्ड का उपयोग करने की आवश्यकता नहीं होती है।

1#[wasm_bindgen]
2pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option<String> {

यह फ़ंक्शन एक सार्वजनिक मेटा-पता प्राप्त करता है, जिसमें Vpub और Kpub दोनों शामिल हैं। यह गोपनीय पता, प्रकाशित करने के लिए सार्वजनिक कुंजी (Rpub), और एक-बाइट स्कैन मान लौटाता है जो उन प्रकाशित पतों की पहचान को गति देता है जो एलिस के हो सकते हैं।

स्कैन मान साझा रहस्य (S = GRprivVpriv) का हिस्सा है। यह मान एलिस के लिए उपलब्ध है, और इसकी जाँच करना यह जाँचने की तुलना में बहुत तेज़ है कि f(Kpub+G*hash(S)) प्रकाशित पते के बराबर है या नहीं।

1 let (address, r_pub, scan) =
2 generate_stealth_address(&str_to_array::<66>(stealth_address)?);

हम लाइब्रेरी के generate_stealth_address (opens in a new tab) का उपयोग करते हैं।

1 format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}",
2 encode(address),
3 encode(r_pub),
4 encode(&[scan])
5 ).into()
6}

JSON-एन्कोडेड आउटपुट स्ट्रिंग तैयार करें।

1#[wasm_bindgen]
2pub fn wasm_compute_stealth_key(
3 address: &str,
4 bill_pub_key: &str,
5 view_private_key: &str,
6 spend_private_key: &str
7) -> Option<String> {
8 .
9 .
10 .
11}
सभी दिखाएँ

यह फ़ंक्शन लाइब्रेरी के compute_stealth_key (opens in a new tab) का उपयोग पते से निकासी के लिए निजी कुंजी (Rpriv) की गणना करने के लिए करता है। इस गणना के लिए इन मानों की आवश्यकता होती है:

  • पता (पता=f(Ppub))
  • बिल द्वारा उत्पन्न सार्वजनिक कुंजी (Rpub)
  • व्यू निजी कुंजी (Vpriv)
  • स्पेंड निजी कुंजी (Kpriv)
1#[wasm_bindgen(start)]

#[wasm_bindgen(start)] (opens in a new tab) निर्दिष्ट करता है कि फ़ंक्शन तब निष्पादित होता है जब WASM कोड प्रारंभ किया जाता है।

1pub fn main() {
2 console_error_panic_hook::set_once();
3}

यह कोड निर्दिष्ट करता है कि पैनिक आउटपुट जावास्क्रिप्ट कंसोल पर भेजा जाए। इसे क्रिया में देखने के लिए, एप्लिकेशन का उपयोग करें और बिल को एक अमान्य मेटा-पता दें (बस एक हेक्साडेसिमल अंक बदलें)। आपको जावास्क्रिप्ट कंसोल में यह त्रुटि दिखाई देगी:

1rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs:701:9:
2assertion `left == right` failed
3 left: 0
4 right: 1

इसके बाद एक स्टैक ट्रेस होता है। फिर बिल को वैध मेटा-पता दें, और एलिस को या तो एक अमान्य पता या एक अमान्य सार्वजनिक कुंजी दें। आपको यह त्रुटि दिखाई देगी:

1rust_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:
2keys do not generate stealth address

फिर से, एक स्टैक ट्रेस के बाद।

यूज़र इंटरफ़ेस

यूज़र इंटरफ़ेस रिएक्ट (opens in a new tab) का उपयोग करके लिखा गया है और वीट (opens in a new tab) द्वारा परोसा जाता है। आप इस ट्यूटोरियल का उपयोग करके उनके बारे में जान सकते हैं। यहाँ WAGMI (opens in a new tab) की कोई आवश्यकता नहीं है क्योंकि हम सीधे ब्लॉकचेन या वॉलेट के साथ इंटरैक्ट नहीं करते हैं।

यूज़र इंटरफ़ेस का एकमात्र गैर-स्पष्ट हिस्सा WASM कनेक्टिविटी है। यह कैसे काम करता है, यह यहाँ बताया गया है।

vite.config.js

इस फ़ाइल में वीट कॉन्फ़िगरेशन (opens in a new tab) है।

1import { defineConfig } from 'vite'
2import react from '@vitejs/plugin-react'
3import wasm from "vite-plugin-wasm";
4
5// https://vite.dev/config/
6export default defineConfig({
7 plugins: [react(), wasm()],
8})

हमें दो वीट प्लगइन्स की आवश्यकता है: react (opens in a new tab) और wasm (opens in a new tab)

App.jsx

यह फ़ाइल एप्लिकेशन का मुख्य घटक है। यह एक कंटेनर है जिसमें दो घटक शामिल हैं: Alice और Bill, जो उन यूज़र्स के लिए यूज़र इंटरफ़ेस हैं। WASM के लिए प्रासंगिक भाग इनिशियलाइज़ेशन कोड है।

1import init from './rust-wasm/pkg/rust_wasm.js'

जब हम wasm-pack (opens in a new tab) का उपयोग करते हैं, तो यह दो फाइलें बनाता है जिनका हम यहां उपयोग करते हैं: वास्तविक कोड वाली एक wasm फ़ाइल (यहाँ, src/rust-wasm/pkg/rust_wasm_bg.wasm) और इसका उपयोग करने के लिए परिभाषाओं वाली एक जावास्क्रिप्ट फ़ाइल (यहाँ, src/rust-wasm/pkg/rust_wasm.js)। उस जावास्क्रिप्ट फ़ाइल का डिफ़ॉल्ट एक्सपोर्ट वह कोड है जिसे WASM शुरू करने के लिए चलाने की आवश्यकता होती है।

1function App() {
2 .
3 .
4 .
5 useEffect(() => {
6 const loadWasm = async () => {
7 try {
8 await init();
9 setWasmReady(true)
10 } catch (err) {
11 console.error('Error loading wasm:', err)
12 alert("Wasm error: " + err)
13 }
14 }
15
16 loadWasm()
17 }, []
18 )
सभी दिखाएँ

useEffect हुक (opens in a new tab) आपको एक फ़ंक्शन निर्दिष्ट करने देता है जो स्टेट वैरिएबल बदलने पर निष्पादित होता है। यहाँ, स्टेट वैरिएबल की सूची खाली ([]) है, इसलिए यह फ़ंक्शन केवल एक बार निष्पादित होता है जब पेज लोड होता है।

इफेक्ट फ़ंक्शन को तुरंत लौटना होगा। असिंक्रोनस कोड का उपयोग करने के लिए, जैसे कि WASM init (जिसे .wasm फ़ाइल लोड करनी होती है और इसलिए समय लगता है) हम एक आंतरिक async (opens in a new tab) फ़ंक्शन को परिभाषित करते हैं और इसे await के बिना चलाते हैं।

Bill.jsx

यह बिल के लिए यूज़र इंटरफ़ेस है। इसमें एक ही क्रिया है, जो एलिस द्वारा प्रदान किए गए गोपनीय मेटा-पते के आधार पर एक पता बनाना है।

1import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js'

डिफ़ॉल्ट एक्सपोर्ट के अलावा, wasm-pack द्वारा उत्पन्न जावास्क्रिप्ट कोड WASM कोड में प्रत्येक फ़ंक्शन के लिए एक फ़ंक्शन एक्सपोर्ट करता है।

1 <button onClick={() => {
2 setPublicAddress(JSON.parse(wasm_generate_stealth_address(stealthMetaAddress)))
3 }}>

WASM फ़ंक्शन को कॉल करने के लिए, हम बस wasm-pack द्वारा बनाई गई जावास्क्रिप्ट फ़ाइल द्वारा एक्सपोर्ट किए गए फ़ंक्शन को कॉल करते हैं।

Alice.jsx

Alice.jsx में कोड समान है, सिवाय इसके कि एलिस के पास दो क्रियाएँ हैं:

  • एक मेटा-पता उत्पन्न करें
  • बिल द्वारा प्रकाशित एक पते के लिए निजी कुंजी प्राप्त करें

निष्कर्ष

गोपनीय पते कोई रामबाण नहीं हैं; उन्हें सही ढंग से उपयोग किया जाना चाहिए। लेकिन जब सही ढंग से उपयोग किया जाता है, तो वे एक सार्वजनिक ब्लॉकचेन पर गोपनीयता को सक्षम कर सकते हैं।

मेरे और काम के लिए यहाँ देखें (opens in a new tab)

पेज का अंतिम अपडेट: 14 नवंबर 2025

क्या यह ट्यूटोरियल सहायक था?