முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்

மறைமுக முகவரிகளைப் பயன்படுத்துதல்

மறைமுக முகவரி
தனியுரிமை
குறியாக்கவியல்
Rust
wasm
இடைநிலையாளர்
ஓரி பொமரன்ட்ஸ்
30 நவம்பர், 2025
13 நிமிட வாசிப்பு

நீங்கள் பில் (Bill). நாம் விவாதிக்க விரும்பாத சில காரணங்களுக்காக, "ஆலிஸ் ஃபார் குயின் ஆஃப் தி வேர்ல்ட்" (Alice for Queen of the World) பிரச்சாரத்திற்கு நீங்கள் நன்கொடை அளிக்க விரும்புகிறீர்கள், மேலும் நீங்கள் நன்கொடை அளித்ததை ஆலிஸ் (Alice) தெரிந்துகொள்ள வேண்டும், அப்போதுதான் அவள் வெற்றி பெற்றால் உங்களுக்கு வெகுமதி அளிப்பாள். துரதிர்ஷ்டவசமாக, அவளது வெற்றிக்கு உத்தரவாதம் இல்லை. "கரோல் ஃபார் எம்பிரஸ் ஆஃப் தி சோலார் சிஸ்டம்" (Carol for Empress of the Solar System) என்ற போட்டிப் பிரச்சாரம் உள்ளது. கரோல் (Carol) வெற்றி பெற்று, நீங்கள் ஆலிஸுக்கு நன்கொடை அளித்ததை அவள் கண்டுபிடித்தால், நீங்கள் சிக்கலில் மாட்டுவீர்கள். எனவே உங்கள் கணக்கிலிருந்து ஆலிஸின் கணக்கிற்கு 200 ETH-ஐ உங்களால் சாதாரணமாக மாற்ற முடியாது.

ERC-5564 (opens in a new tab) இதற்கு தீர்வு கொண்டுள்ளது. அநாமதேய பரிமாற்றத்திற்கு மறைமுக முகவரிகளை (opens in a new tab) எவ்வாறு பயன்படுத்துவது என்பதை இந்த ERC விளக்குகிறது.

எச்சரிக்கை: மறைமுக முகவரிகளுக்குப் பின்னால் உள்ள குறியாக்கவியல், எங்களுக்குத் தெரிந்தவரை, பாதுகாப்பானது. இருப்பினும், சாத்தியமான பக்க-சேனல் தாக்குதல்கள் (side-channel attacks) உள்ளன. இந்த அபாயத்தைக் குறைக்க நீங்கள் என்ன செய்யலாம் என்பதை கீழே காண்பீர்கள்.

மறைமுக முகவரிகள் எவ்வாறு செயல்படுகின்றன

இந்தக் கட்டுரை மறைமுக முகவரிகளை இரண்டு வழிகளில் விளக்க முயற்சிக்கும். முதலாவது அவற்றை எவ்வாறு பயன்படுத்துவது என்பது. கட்டுரையின் மீதமுள்ள பகுதியைப் புரிந்துகொள்ள இந்தப் பகுதி போதுமானது. பின்னர், இதற்குப் பின்னால் உள்ள கணிதத்தின் விளக்கம் உள்ளது. உங்களுக்கு குறியாக்கவியலில் ஆர்வம் இருந்தால், இந்தப் பகுதியையும் படிக்கவும்.

எளிய பதிப்பு (மறைமுக முகவரிகளை எவ்வாறு பயன்படுத்துவது)

ஆலிஸ் இரண்டு தனிப்பட்ட திறவுகோல்களை (private keys) உருவாக்கி, அதற்கான பொதுத் திறவுகோல்களை (public keys) வெளியிடுகிறாள் (இவற்றை ஒற்றை இரட்டை-நீள மெட்டா-முகவரியாக இணைக்கலாம்). பில்லும் ஒரு தனிப்பட்ட திறவுகோலை உருவாக்கி, அதற்கான பொதுத் திறவுகோலை வெளியிடுகிறார்.

ஒரு தரப்பினரின் பொதுத் திறவுகோலையும் மற்றவரின் தனிப்பட்ட திறவுகோலையும் பயன்படுத்தி, ஆலிஸ் மற்றும் பில்லுக்கு மட்டுமே தெரிந்த பகிரப்பட்ட ரகசியத்தை (shared secret) நீங்கள் பெறலாம் (இதை பொதுத் திறவுகோல்களிலிருந்து மட்டுமே பெற முடியாது). இந்தப் பகிரப்பட்ட ரகசியத்தைப் பயன்படுத்தி, பில் மறைமுக முகவரியைப் பெறுகிறார், மேலும் அதற்குச் சொத்துக்களை அனுப்ப முடியும்.

ஆலிஸும் பகிரப்பட்ட ரகசியத்திலிருந்து முகவரியைப் பெறுகிறாள், ஆனால் அவள் வெளியிட்ட பொதுத் திறவுகோல்களுக்கான தனிப்பட்ட திறவுகோல்கள் அவளுக்குத் தெரியும் என்பதால், அந்த முகவரியிலிருந்து பணத்தை எடுக்க அனுமதிக்கும் தனிப்பட்ட திறவுகோலையும் அவளால் பெற முடியும்.

கணிதம் (மறைமுக முகவரிகள் ஏன் இப்படிச் செயல்படுகின்றன)

நிலையான மறைமுக முகவரிகள் நீள்வட்ட-வளைவு குறியாக்கவியலை (ECC) (opens in a new tab) பயன்படுத்தி, அதே அளவிலான பாதுகாப்பைப் பராமரிக்கும் அதே வேளையில், குறைவான திறவுகோல் பிட்களுடன் சிறந்த செயல்திறனைப் பெறுகின்றன. ஆனால் பெரும்பாலும் நாம் அதைப் புறக்கணித்துவிட்டு, வழக்கமான எண்கணிதத்தைப் பயன்படுத்துவது போல் பாசாங்கு செய்யலாம்.

அனைவருக்கும் தெரிந்த ஒரு எண் உள்ளது, G. நீங்கள் G ஆல் பெருக்கலாம். ஆனால் ECC-இன் தன்மை காரணமாக, G ஆல் வகுப்பது நடைமுறையில் சாத்தியமற்றது. Ethereum-இல் பொதுத் திறவுகோல் குறியாக்கவியல் பொதுவாகச் செயல்படும் விதம் என்னவென்றால், நீங்கள் ஒரு தனிப்பட்ட திறவுகோலான 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) என்பதிலிருந்து உருவாகும் முகவரியில் உள்ள சொத்துக்களை அணுக அவளை அனுமதிக்கிறது.

ஆலிஸ் டேவின் வேர்ல்ட் டாமினேஷன் கேம்பெயின் சர்வீசஸுக்கு (Dave's World Domination Campaign Services) துணை ஒப்பந்தம் செய்ய அனுமதிக்க எங்களிடம் ஒரு தனிப் பார்வைத் திறவுகோல் (viewing key) உள்ளது. பொது முகவரிகளை டேவ் தெரிந்துகொள்ளவும், அதிகப் பணம் கிடைக்கும்போது அவளுக்குத் தெரிவிக்கவும் ஆலிஸ் தயாராக இருக்கிறாள், ஆனால் அவர் தனது பிரச்சாரப் பணத்தைச் செலவழிப்பதை அவள் விரும்பவில்லை.

பார்ப்பதற்கும் செலவழிப்பதற்கும் தனித்தனித் திறவுகோல்கள் பயன்படுத்தப்படுவதால், ஆலிஸ் டேவுக்கு Vpriv-ஐக் கொடுக்கலாம். பின்னர் டேவ் S = RpubVpriv = GRprivVpriv-ஐக் கணக்கிடலாம், அந்த வகையில் பொதுத் திறவுகோல்களைப் பெறலாம் (Ppub = Kpub+G*hash(S)). ஆனால் Kpriv இல்லாமல் டேவால் தனிப்பட்ட திறவுகோலைப் பெற முடியாது.

சுருக்கமாகக் கூறினால், வெவ்வேறு பங்கேற்பாளர்களுக்குத் தெரிந்த மதிப்புகள் இவை.

ஆலிஸ்வெளியிடப்பட்டதுபில்டேவ்
GGGG
Kpriv---
Vpriv--Vpriv
Kpub = GKprivKpubKpubKpub
Vpub = GVprivVpubVpubVpub
--Rpriv-
RpubRpubRpub = GRprivRpub
S = RpubVpriv = GRprivVpriv-S = RprivVpub = GRprivVprivS = RpubVpriv = GRprivVpriv
Ppub = Kpub+G*hash(S)-Ppub = Kpub+G*hash(S)Ppub = Kpub+G*hash(S)
Address=f(Ppub)-Address=f(Ppub)Address=f(Ppub)
Ppriv = Kpriv+hash(S)---

மறைமுக முகவரிகள் தவறாகப் போகும்போது

பிளாக்செயினில் ரகசியங்கள் எதுவும் இல்லை. மறைமுக முகவரிகள் உங்களுக்குத் தனியுரிமையை வழங்க முடியும் என்றாலும், அந்தத் தனியுரிமை போக்குவரத்துப் பகுப்பாய்விற்கு (traffic analysis) ஆளாகக்கூடியது. ஒரு சிறிய உதாரணத்தை எடுத்துக்கொண்டால், பில் ஒரு முகவரிக்கு நிதியளித்து, உடனடியாக Rpub மதிப்பை வெளியிட ஒரு பரிவர்த்தனையை அனுப்புகிறார் என்று கற்பனை செய்து பாருங்கள். ஆலிஸின் Vpriv இல்லாமல், இது ஒரு மறைமுக முகவரி என்று நாம் உறுதியாகக் கூற முடியாது, ஆனால் அதுதான் பந்தயம் கட்டும் வழி. பின்னர், அந்த முகவரியிலிருந்து அனைத்து ETH-ஐயும் ஆலிஸின் பிரச்சார நிதி முகவரிக்கு மாற்றும் மற்றொரு பரிவர்த்தனையை நாம் காண்கிறோம். எங்களால் அதை நிரூபிக்க முடியாமல் போகலாம், ஆனால் பில் ஆலிஸின் பிரச்சாரத்திற்கு நன்கொடை அளித்திருக்க வாய்ப்புள்ளது. கரோல் நிச்சயமாக அப்படித் தான் நினைப்பாள்.

பில் Rpub வெளியீட்டை மறைமுக முகவரியின் நிதியுதவியிலிருந்து பிரிப்பது எளிது (அவற்றை வெவ்வேறு நேரங்களில், வெவ்வேறு முகவரிகளிலிருந்து செய்யலாம்). இருப்பினும், அது போதாது. கரோல் தேடும் முறை என்னவென்றால், பில் ஒரு முகவரிக்கு நிதியளிக்கிறார், பின்னர் ஆலிஸின் பிரச்சார நிதி அதிலிருந்து பணத்தை எடுக்கிறது.

இதற்கு ஒரு தீர்வு, ஆலிஸின் பிரச்சாரம் பணத்தை நேரடியாக எடுக்காமல், மூன்றாம் தரப்பினருக்குச் செலுத்த அதைப் பயன்படுத்துவதாகும். ஆலிஸின் பிரச்சாரம் டேவின் வேர்ல்ட் டாமினேஷன் கேம்பெயின் சர்வீசஸுக்கு 10 ETH-ஐ அனுப்பினால், பில் டேவின் வாடிக்கையாளர்களில் ஒருவருக்கு நன்கொடை அளித்தார் என்பது மட்டுமே கரோலுக்குத் தெரியும். டேவுக்குப் போதுமான வாடிக்கையாளர்கள் இருந்தால், பில் தன்னுடன் போட்டியிடும் ஆலிஸுக்கு நன்கொடை அளித்தாரா அல்லது கரோல் கவலைப்படாத ஆடம், ஆல்பர்ட் அல்லது அபிகாயிலுக்கு நன்கொடை அளித்தாரா என்பதை கரோலால் அறிய முடியாது. ஆலிஸ் கட்டணத்துடன் ஒரு ஹாஷ் செய்யப்பட்ட மதிப்பைச் சேர்க்கலாம், பின்னர் அது தனது நன்கொடை என்பதை நிரூபிக்க டேவுக்கு ப்ரீஇமேஜை (preimage) வழங்கலாம். மாற்றாக, மேலே குறிப்பிட்டுள்ளபடி, ஆலிஸ் டேவுக்கு தனது Vpriv-ஐக் கொடுத்தால், பணம் யாரிடமிருந்து வந்தது என்பது அவருக்கு ஏற்கனவே தெரியும்.

இந்தத் தீர்வின் முக்கியப் பிரச்சனை என்னவென்றால், அந்த ரகசியம் பில்லுக்குப் பயனளிக்கும் போது ஆலிஸ் ரகசியத்தைப் பற்றி அக்கறை கொள்ள வேண்டும். ஆலிஸ் தனது நற்பெயரைப் பராமரிக்க விரும்பலாம், அதனால் பில்லின் நண்பரான பாபும் அவளுக்கு நன்கொடை அளிப்பார். ஆனால் பில்லை அம்பலப்படுத்துவதில் அவளுக்கு எந்த ஆட்சேபனையும் இருக்காது என்பதும் சாத்தியமே, ஏனென்றால் கரோல் வெற்றி பெற்றால் என்ன நடக்கும் என்று அவர் பயப்படுவார். பில் ஆலிஸுக்கு இன்னும் அதிக ஆதரவை வழங்க நேரிடலாம்.

பல மறைமுக அடுக்குகளைப் பயன்படுத்துதல்

பில்லின் தனியுரிமையைப் பாதுகாக்க ஆலிஸை நம்பியிருப்பதற்குப் பதிலாக, பில் அதைத் தானே செய்யலாம். அவர் பாப் மற்றும் பெல்லா என்ற கற்பனையான நபர்களுக்குப் பல மெட்டா-முகவரிகளை உருவாக்க முடியும். பில் பின்னர் பாப்பிற்கு ETH-ஐ அனுப்புகிறார், மேலும் "பாப்" (உண்மையில் பில்) அதை பெல்லாவுக்கு அனுப்புகிறார். "பெல்லா" (அவரும் பில் தான்) அதை ஆலிஸுக்கு அனுப்புகிறார்.

கரோல் இன்னும் போக்குவரத்துப் பகுப்பாய்வு செய்து பில்-டு-பாப்-டு-பெல்லா-டு-ஆலிஸ் (Bill-to-Bob-to-Bella-to-Alice) பைப்லைனைக் காண முடியும். இருப்பினும், "பாப்" மற்றும் "பெல்லா" மற்ற நோக்கங்களுக்காகவும் ETH-ஐப் பயன்படுத்தினால், ஆலிஸ் உடனடியாக மறைமுக முகவரியிலிருந்து தனக்குத் தெரிந்த பிரச்சார முகவரிக்கு பணத்தை எடுத்தாலும், பில் ஆலிஸுக்கு எதையும் மாற்றியதாகத் தெரியாது.

மறைமுக-முகவரி பயன்பாட்டை எழுதுதல்

இந்தக் கட்டுரை GitHub-இல் கிடைக்கும் (opens in a new tab) ஒரு மறைமுக-முகவரி பயன்பாட்டை விளக்குகிறது.

கருவிகள்

நாம் பயன்படுத்தக்கூடிய ஒரு typescript மறைமுக முகவரி நூலகம் (opens in a new tab) உள்ளது. இருப்பினும், குறியாக்கவியல் செயல்பாடுகள் CPU-ஐ அதிகம் பயன்படுத்தக்கூடியவை. அவற்றை Rust (opens in a new tab) போன்ற தொகுக்கப்பட்ட மொழியில் (compiled language) செயல்படுத்தவும், உலாவியில் குறியீட்டை இயக்க WASM (opens in a new tab)-ஐப் பயன்படுத்தவும் நான் விரும்புகிறேன்.

நாம் Vite (opens in a new tab) மற்றும் React (opens in a new tab)-ஐப் பயன்படுத்தப் போகிறோம். இவை தொழில்துறை-தரமான கருவிகள்; உங்களுக்கு அவை பரிச்சயமில்லை என்றால், நீங்கள் இந்த டுடோரியலைப் பயன்படுத்தலாம். Vite-ஐப் பயன்படுத்த, நமக்கு Node தேவை.

மறைமுக முகவரிகள் செயல்படுவதைப் பார்க்கவும்

  1. தேவையான கருவிகளை நிறுவவும்: Rust (opens in a new tab) மற்றும் Node (opens in a new tab).

  2. GitHub களஞ்சியத்தை குளோன் (Clone) செய்யவும்.

    1git clone https://github.com/qbzzt/251022-stealth-addresses.git
    2cd 251022-stealth-addresses
  3. முன்நிபந்தனைகளை நிறுவி, Rust குறியீட்டைத் தொகுக்கவும்.

    1cd src/rust-wasm
    2rustup target add wasm32-unknown-unknown
    3cargo install wasm-pack
    4wasm-pack build --target web
  4. இணையச் சேவையகத்தைத் (web server) தொடங்கவும்.

    1cd ../..
    2npm install
    3npm run dev
  5. பயன்பாட்டிற்குச் (opens in a new tab) செல்லவும். இந்தப் பயன்பாட்டுப் பக்கத்தில் இரண்டு பிரேம்கள் உள்ளன: ஒன்று ஆலிஸின் பயனர் இடைமுகத்திற்கும் மற்றொன்று பில்லிற்கும். இரண்டு பிரேம்களும் தொடர்பு கொள்ளாது; அவை வசதிக்காக மட்டுமே ஒரே பக்கத்தில் உள்ளன.

  6. ஆலிஸாக, Generate a Stealth Meta-Address என்பதைக் கிளிக் செய்யவும். இது புதிய மறைமுக முகவரியையும் அதற்கான தனிப்பட்ட திறவுகோல்களையும் காண்பிக்கும். மறைமுக மெட்டா-முகவரியை கிளிப்போர்டுக்கு நகலெடுக்கவும்.

  7. பில்லாக, புதிய மறைமுக மெட்டா-முகவரியை ஒட்டி, Generate an address என்பதைக் கிளிக் செய்யவும். இது ஆலிஸுக்கு நிதியளிப்பதற்கான முகவரியை உங்களுக்கு வழங்குகிறது.

  8. முகவரி மற்றும் பில்லின் பொதுத் திறவுகோலை நகலெடுத்து, ஆலிஸின் பயனர் இடைமுகத்தின் "Private key for address generated by Bill" பகுதியில் ஒட்டவும். அந்தப் புலங்கள் நிரப்பப்பட்டவுடன், அந்த முகவரியில் உள்ள சொத்துக்களை அணுகுவதற்கான தனிப்பட்ட திறவுகோலை நீங்கள் காண்பீர்கள்.

  9. தனிப்பட்ட திறவுகோல் முகவரிக்கு ஒத்திருப்பதை உறுதிசெய்ய நீங்கள் ஆன்லைன் கால்குலேட்டரைப் (opens in a new tab) பயன்படுத்தலாம்.

நிரல் எவ்வாறு செயல்படுகிறது

WASM கூறு

WASM-ஆகத் தொகுக்கப்படும் மூலக் குறியீடு Rust (opens in a new tab)-இல் எழுதப்பட்டுள்ளது. நீங்கள் அதை src/rust_wasm/src/lib.rs (opens in a new tab)-இல் பார்க்கலாம். இந்தக் குறியீடு முதன்மையாக JavaScript குறியீட்டிற்கும் eth-stealth-addresses நூலகத்திற்கும் (opens in a new tab) இடையிலான இடைமுகமாகும்.

Cargo.toml

Rust-இல் உள்ள Cargo.toml (opens in a new tab) என்பது JavaScript-இல் உள்ள package.json (opens in a new tab)-க்கு ஒப்பானது. இது தொகுப்புத் தகவல், சார்பு அறிவிப்புகள் (dependency declarations) போன்றவற்றைக் கொண்டுள்ளது.

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) தொகுப்பு சீரற்ற மதிப்புகளை (random values) உருவாக்க வேண்டும். அதைத் தூய அல்காரிதமிக் வழிகளில் செய்ய முடியாது; அதற்கு என்ட்ரோபியின் (entropy) ஆதாரமாக ஒரு இயற்பியல் செயல்முறைக்கான அணுகல் தேவை. நாம் இயங்கும் உலாவியைக் கேட்பதன் மூலம் அந்த என்ட்ரோபியைப் பெறுவோம் என்பதை இந்த வரையறை குறிப்பிடுகிறது.

1console_error_panic_hook = "0.1.7"

WASM குறியீடு பீதியடைந்து (panics) தொடர முடியாதபோது, இந்த நூலகம் (opens in a new tab) எங்களுக்கு மிகவும் அர்த்தமுள்ள பிழைச் செய்திகளை வழங்குகிறது.

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

WASM குறியீட்டை உருவாக்கத் தேவையான வெளியீட்டு வகை.

lib.rs

இது உண்மையான Rust குறியீடு.

1use wasm_bindgen::prelude::*;

Rust-இலிருந்து 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};

Rust பொதுவாக மதிப்புகளுக்கு பைட் அணிகளை (arrays) (opens in a new tab) ([u8; <size>]) பயன்படுத்துகிறது. ஆனால் JavaScript-இல், நாம் பொதுவாக ஹெக்ஸாடெசிமல் சரங்களைப் (hexadecimal strings) பயன்படுத்துகிறோம். hex நூலகம் (opens in a new tab) ஒரு பிரதிநிதித்துவத்திலிருந்து மற்றொன்றுக்கு நமக்காக மொழிபெயர்க்கிறது.

1#[wasm_bindgen]

JavaScript-இலிருந்து இந்தச் செயல்பாட்டை அழைக்க WASM பிணைப்புகளை (bindings) உருவாக்கவும்.

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)

டூப்பிள் (tuple) (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]> {

இந்தச் செயல்பாடு ஒரு ஹெக்ஸ் சரத்தை (JavaScript வழங்கியது) பைட் அணியாக மாற்றுகிறது. JavaScript குறியீட்டால் வழங்கப்பட்ட மதிப்புகளைப் பாகுபடுத்த (parse) இதைப் பயன்படுத்துகிறோம். Rust அணிகள் மற்றும் வெக்டர்களைக் கையாளும் விதம் காரணமாக இந்தச் செயல்பாடு சிக்கலானது.

<const N: usize> வெளிப்பாடு ஒரு ஜெனரிக் (generic) (opens in a new tab) என்று அழைக்கப்படுகிறது. N என்பது திருப்பி அனுப்பப்பட்ட அணியின் நீளத்தைக் கட்டுப்படுத்தும் ஒரு அளவுருவாகும். செயல்பாடு உண்மையில் str_to_array::<n> என்று அழைக்கப்படுகிறது, இதில் n என்பது அணியின் நீளம்.

திரும்பப் பெறும் மதிப்பு Option<[u8; N]> ஆகும், அதாவது திருப்பி அனுப்பப்பட்ட அணி விருப்பத்திற்குரியது (optional) (opens in a new tab). தோல்வியடையக்கூடிய செயல்பாடுகளுக்கான Rust-இல் இது ஒரு பொதுவான வடிவமாகும்.

எடுத்துக்காட்டாக, நாம் str_to_array::10("bad060a7")-ஐ அழைத்தால், செயல்பாடு பத்து-மதிப்பு அணியைத் திருப்பி அனுப்ப வேண்டும், ஆனால் உள்ளீடு நான்கு பைட்டுகள் மட்டுமே. செயல்பாடு தோல்வியடைய வேண்டும், மேலும் அது None-ஐத் திருப்பி அனுப்புவதன் மூலம் அவ்வாறு செய்கிறது. str_to_array::4("bad060a7")-க்கான திரும்பப் பெறும் மதிப்பு Some<[0xba, 0xd0, 0x60, 0xa7]> ஆக இருக்கும்.

1 // decode ஆனது 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-ஐத் திருப்பி அனுப்புகிறது. இல்லையெனில், அது மதிப்பை அன்ராப் (unwrap) செய்து அதைத் திருப்பி அனுப்புகிறது (இந்த நிலையில், vec-க்கு ஒரு மதிப்பை ஒதுக்க).

இது பிழைகளைக் கையாள ஒரு விசித்திரமான சிக்கலான முறை போல் தெரிகிறது, ஆனால் Result மற்றும் Option அனைத்துப் பிழைகளும் ஏதோ ஒரு வகையில் கையாளப்படுவதை உறுதி செய்கின்றன.

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

பைட்டுகளின் எண்ணிக்கை தவறாக இருந்தால், அது ஒரு தோல்வி, மேலும் நாம் None-ஐத் திருப்பி அனுப்புகிறோம்.

1 // try_into ஆனது vec ஐ உட்கொண்டு [u8; N] ஐ உருவாக்க முயற்சிக்கிறது
2 let array: [u8; N] = vec.try_into().ok()?;

Rust-இல் இரண்டு அணி வகைகள் உள்ளன. அணிகள் (Arrays) (opens in a new tab) நிலையான அளவைக் கொண்டுள்ளன. வெக்டர்கள் (Vectors) (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) முக்கிய சொல்லைப் பயன்படுத்த Rust உங்களைக் கட்டாயப்படுத்துவதில்லை.

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}
அனைத்தையும் காட்டு

இந்தச் செயல்பாடு முகவரியிலிருந்து பணத்தை எடுப்பதற்கான தனிப்பட்ட திறவுகோலைக் கணக்கிட (Rpriv) நூலகத்தின் compute_stealth_key (opens in a new tab)-ஐப் பயன்படுத்துகிறது. இந்தக் கணக்கீட்டிற்கு இந்த மதிப்புகள் தேவை:

  • முகவரி (Address=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}

இந்தக் குறியீடு பீதி வெளியீடு (panic output) JavaScript கன்சோலுக்கு அனுப்பப்பட வேண்டும் என்பதைக் குறிப்பிடுகிறது. இது செயல்படுவதைப் பார்க்க, பயன்பாட்டைப் பயன்படுத்தி பில்லுக்குத் தவறான மெட்டா-முகவரியைக் கொடுங்கள் (ஒரு ஹெக்ஸாடெசிமல் இலக்கத்தை மட்டும் மாற்றவும்). JavaScript கன்சோலில் இந்தப் பிழையை நீங்கள் காண்பீர்கள்:

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

அதைத் தொடர்ந்து ஒரு ஸ்டாக் ட்ரேஸ் (stack trace) இருக்கும். பின்னர் பில்லுக்குச் சரியான மெட்டா-முகவரியைக் கொடுங்கள், மேலும் ஆலிஸுக்குத் தவறான முகவரி அல்லது தவறான பொதுத் திறவுகோலைக் கொடுங்கள். நீங்கள் இந்தப் பிழையைக் காண்பீர்கள்:

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

மீண்டும், அதைத் தொடர்ந்து ஒரு ஸ்டாக் ட்ரேஸ் இருக்கும்.

பயனர் இடைமுகம்

பயனர் இடைமுகம் React (opens in a new tab)-ஐப் பயன்படுத்தி எழுதப்பட்டுள்ளது மற்றும் Vite (opens in a new tab) மூலம் வழங்கப்படுகிறது. இந்த டுடோரியலைப் பயன்படுத்தி நீங்கள் அவற்றைப் பற்றி அறியலாம். நாம் நேரடியாக பிளாக்செயின் அல்லது வாலட்டுடன் தொடர்பு கொள்ளாததால், இங்கே WAGMI (opens in a new tab) தேவையில்லை.

பயனர் இடைமுகத்தில் வெளிப்படையாகத் தெரியாத ஒரே பகுதி WASM இணைப்பு மட்டுமே. இது எவ்வாறு செயல்படுகிறது என்பது இங்கே.

vite.config.js

இந்தக் கோப்பு Vite உள்ளமைவைக் (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})

நமக்கு இரண்டு Vite செருகுநிரல்கள் (plugins) தேவை: react (opens in a new tab) மற்றும் wasm (opens in a new tab).

App.jsx

இந்தக் கோப்பு பயன்பாட்டின் முக்கியக் கூறாகும். இது இரண்டு கூறுகளை உள்ளடக்கிய ஒரு கொள்கலன் (container): 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) மற்றும் அதைப் பயன்படுத்துவதற்கான வரையறைகளைக் கொண்ட ஒரு JavaScript கோப்பு (இங்கே, src/rust_wasm/pkg/rust_wasm.js). அந்த JavaScript கோப்பின் இயல்புநிலை ஏற்றுமதி (default export) என்பது 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) நிலை மாறிகள் (state variables) மாறும்போது செயல்படுத்தப்படும் ஒரு செயல்பாட்டைக் குறிப்பிட உங்களை அனுமதிக்கிறது. இங்கே, நிலை மாறிகளின் பட்டியல் காலியாக உள்ளது ([]), எனவே பக்கம் ஏற்றப்படும்போது இந்தச் செயல்பாடு ஒரு முறை மட்டுமே செயல்படுத்தப்படும்.

எஃபெக்ட் (effect) செயல்பாடு உடனடியாகத் திரும்ப வேண்டும். 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 உருவாக்கிய JavaScript குறியீடு WASM குறியீட்டில் உள்ள ஒவ்வொரு செயல்பாட்டிற்கும் ஒரு செயல்பாட்டை ஏற்றுமதி செய்கிறது.

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

WASM செயல்பாடுகளை அழைக்க, wasm-pack உருவாக்கிய JavaScript கோப்பால் ஏற்றுமதி செய்யப்பட்ட செயல்பாட்டை நாம் அழைக்கிறோம்.

Alice.jsx

Alice.jsx-இல் உள்ள குறியீடு ஒத்திருக்கிறது, ஆனால் ஆலிஸுக்கு இரண்டு செயல்கள் உள்ளன:

  • ஒரு மெட்டா-முகவரியை உருவாக்குதல்
  • பில் வெளியிட்ட முகவரிக்கான தனிப்பட்ட திறவுகோலைப் பெறுதல்

முடிவுரை

மறைமுக முகவரிகள் சஞ்சீவி அல்ல; அவை சரியாகப் பயன்படுத்தப்பட வேண்டும். ஆனால் சரியாகப் பயன்படுத்தப்படும்போது, அவை பொது பிளாக்செயினில் தனியுரிமையைச் செயல்படுத்த முடியும்.

எனது மேலும் பல பணிகளுக்கு இங்கே பார்க்கவும் (opens in a new tab).

பக்கம் கடைசியாகப் புதுப்பிக்கப்பட்டது: 14 நவம்பர், 2025

இந்த வழிகாட்டி பயனுள்ளதாக இருந்ததா?