ZYCORD दस्तावेज़
हिन्दी
Zycordदस्तावेज़नोड चलाना

नोड चलाना

zycordd के लिए ऑपरेटर की मार्गदर्शिका। वह जो प्रोटोकॉल बोलता है वह वायर विशिष्टि है; यह पृष्ठ उसे चलाने के बारे में है।

एक पंक्ति में#

zycordd --devnet --dir ./devnet

यह एक पूर्ण नोड है: वह genesis से हर ब्लॉक का सत्यापन करता है, पीयर्स को सेवा देता है, और 127.0.0.1:9420 पर केवल-पठन RPC का उत्तर देता है। सार्वजनिक नेटवर्कों के लिए -randomx बाइनरी चाहिए: zycordd-randomx --dir ./data अपने अंतर्निहित seeds से mainnet से जुड़ता है, जो 2026-10-07 से चल रहा है, और सार्वजनिक testnet दूसरे नेटवर्क के बारे में बताता है।

नोड के पास क्या नहीं है#

नोड प्रक्रिया में कभी कोई कुंजी सामग्री नहीं होती। वह न कोई seed लेता है, न कोई passphrase, न कोई कुंजी फ़ाइल। हस्ताक्षर zcd में होते हैं, और नोड के लेखन एंडपॉइंट कोई अधिकार नहीं देते: /submit एक हस्ताक्षरित सर्टिफिकेट लेता है, /openintent forced path के लिए एक हस्ताक्षरित open intent और /servicecard एक हस्ताक्षरित सेवा घोषणा, और हर एक की जाँच ठीक वैसे ही होती है जैसे किसी अजनबी से आए हुए की होती, फिर उसे gossip किया जाता है। RPC डिफ़ॉल्ट रूप से 127.0.0.1:9420 से बँधता है।

यहाँ कोई विशेषाधिकार-प्राप्त एंडपॉइंट भी नहीं है, क्योंकि विशेषाधिकार देने को कुछ है ही नहीं। कोई कुंजी न रोक सकती है, न अपग्रेड कर सकती है, न सेंसर, न नई मुद्रा गढ़ सकती है, इसलिए उजागर करने को कोई कॉल नहीं है।

अगर आप RPC को किसी प्रॉक्सी के पीछे रखें, तो दर-सीमा प्रॉक्सी पर लगाएँ

सीमक transport पीयर के आधार पर चलता है, कभी X-Forwarded-For के आधार पर नहीं: जो सीमक क्लाइंट के सेट किए हेडर पर भरोसा करता है वह ऐसा सीमक है जिसे क्लाइंट बंद कर देता है। इसलिए प्रॉक्सी के पीछे हर अनुरोध प्रॉक्सी के पते के साथ आता है, जिससे प्रति-क्लाइंट सीमा प्रति-क्लाइंट रहना बंद कर देती है और सबके लिए एक साथ प्रति मिनट 600 की एक साझा बाल्टी बन जाती है — और एक अकेला कॉल करने वाला उसे सबके लिए ख़ाली कर सकता है। यह दलील से कोई सीमा न होने से भी बुरा है, और प्रतिक्रिया में कुछ भी यह नहीं बताता: कॉल करने वालों को सादा 429 मिलता है, चाहे वजह वे ख़ुद हों या कोई और।

केवल-पठन सतह#

जो कुछ भी चेन को बाहर से देखता है — कोई explorer, कोई मॉनिटर, कोई indexer — वह उसे यहीं से पढ़ता है। नोड बाइट्स सौंपता है, व्याख्या कभी नहीं।

हर रूट, उसके पैरामीटर और लौटाए जाने वाले फ़ील्ड, RPC API संदर्भ में हैं।

एंडपॉइंटक्या बताता है
/status, /headशीर्ष की पहचान, ऊँचाई, state root
/block?height=N या ?id=0x…एक ब्लॉक JSON के रूप में, canonical, orphaned और confirmations सहित
/block?…&format=sszवही ब्लॉक कैनोनिकल SSZ बाइट्स के रूप में, application/octet-stream
/paramsसक्रिय पैरामीटर सेट और उसका consensus root
/cell, /balanceशीर्ष की स्टेट
/feesआधार शुल्क, और लागू लोचदार सीमाएँ
/mempoolपूल के गणक; ?limit=N से 1000 तक लंबित id जुड़ती हैं, सबसे कम पहले
/certकिसी एक सर्टिफिकेट का क्या हुआ: लंबित, drop हुआ, शामिल हुआ या अज्ञात
/sequencer, /directoryहर कॉन्ट्रैक्ट ने किस कुंजी को अपने sequencer के रूप में पंजीकृत किया, और हर कुंजी ने directory में किस URL की घोषणा की — अपनी ही स्टेट के बारे में इस नोड का कथन, बिना प्रमाणीकरण के
/code, /storage, /callकिसी कॉन्ट्रैक्ट का कोड और storage, और किसी कॉल का dry run (POST, कुछ नहीं बदलता)
/network, /metricsकनेक्शन का आकार और गणक
/submit, /openintent, /servicecardलेखन: एक सर्टिफिकेट, एक open intent, एक service card। कोई भी कुछ अधिकार नहीं देता
ये सीमाएँ पैरामीटर नहीं हैं

श्वेतपत्र §9 ब्लॉक की बाइट, gas और सर्टिफिकेट सीमाओं को T का फलन बनाता है, यानी अनुक्रमिक लक्ष्य का, और T वह consensus स्टेट है जिसे epoch नियंत्रक हिलाता है। इसलिए /params केवल genesis के मान ढोता है — block_byte_limit_genesis और उसके साथी — जो बताते हैं कि T कहाँ से शुरू होता है और घटकर किस फ़र्श तक लौट सकता है, कभी वह सीमा नहीं जो लागू है। वे अंक हमेशा असली बने रहते हैं, इसलिए उनमें से किसी को "ब्लॉक आकार सीमा" मानकर पढ़ना चुपचाप ग़लत होता है, और 2.5 MB के genesis मान तथा 8 MB की क्षमता-दीवार के बीच की पूरी दूरी तक ग़लत हो सकता है। /fees जीवित T और उससे निकली चार सीमाएँ परोसता है, ताकि व्युत्पत्ति पर भरोसा करने के बजाय उसे जाँचा जा सके।

बाइट्स क्यों मायने रखते हैं#

blake3("zcd/block/v1" ‖ header_bytes) ही ब्लॉक id है, इसलिए जो प्रेक्षक अपने को परोसी गई चीज़ से id दोबारा निकालता है वह या तो नेटवर्क से सहमत होता है या तुरंत पता लगा लेता है। प्रति-सर्टिफिकेट परिणाम भी इसी तरह मिलते हैं: कोई सर्टिफिकेट लागू हुआ, skip होकर बिल हुआ, या drop हुआ, यह fold के भीतर गणना होती है और कभी संग्रहीत नहीं होती, क्योंकि मेमोरी में रहने वाले भंडार में प्रति सर्टिफिकेट एक पंक्ति, हमेशा के लिए, ऐसी चीज़ नहीं जिसे ढोने को नोड से कहा जा सके। जो प्रेक्षक परिणाम चाहता है वह ब्लॉक को ख़ुद fold कर लेता है।

यहाँ क्या नहीं है, और न होगा#

  • स्टेट पर कोई मनमाना पुनरावर्तन नहीं। न कोई पता सूची, न उपसर्ग स्कैन, न कोई rich list।
  • कोई ऐतिहासिक स्टेट नहीं। /cell और /balance शीर्ष पढ़ते हैं; "ऊँचाई H पर शेष" का मतलब है सुरक्षित रखा गया इतिहास, जो नोड रखता ही नहीं।
  • कोई admin, reindex या debug कॉल नहीं, क्योंकि विशेषाधिकार देने को कुछ है ही नहीं।

समुच्चयन उसका काम है जो देख रहा है, जो उसे अपने डेटाबेस में लेते समय एक ही बार गणना कर ले।

स्थिति कोड#

पठन GET और HEAD का उत्तर देते हैं और बाक़ी हर क्रिया को 405 से मना कर देते हैं। सुगठित प्रश्न जिसका उत्तर नकारात्मक हो — ऐसी ऊँचाई जहाँ चेन नहीं पहुँची, कोई अज्ञात id, किसी reorg में हारे ब्लॉक की बॉडी — वह 404 है; केवल ख़राब गठन वाला अनुरोध 400 है। जो रिकॉर्ड नोड ने लिखा और अब वापस नहीं पढ़ सकता वह 500 है, 400 नहीं: दोष नोड की डिस्क का है, और कॉल करने वाले को यह बताना कि उसका अनुरोध ख़राब था उसे ऐसा अनुरोध दोबारा भेजना छोड़ने पर उकसाता है जो हमेशा सुगठित था। किसी poller को अनुपस्थिति और त्रुटि में, या अपने बग और नोड के बग में, फ़र्क़ करने के लिए कभी गद्य नहीं पढ़ना चाहिए।

Reorg#

ऊँचाई से खोज केवल canonical चेन के लिए उत्तर देती है। जो ब्लॉक किसी reorg में हारता है वह अपना हेडर रखता है और अपनी बॉडी खो देता है, इसलिए उसकी id अब भी हल होती है, orphaned चिह्नित होकर लौटती है, और fork बिंदु तक की parent कड़ी भी ढोती है — और यही id से खोज को इकलौता reorg-सुरक्षित रास्ता बनाता है।

पहुँच-योग्यता, और यह दिखने से ज़्यादा क्यों मायने रखती है#

Zycord NAT traversal नहीं करता। जिस नोड पर --listen किसी पहुँच-योग्य पोर्ट पर हो वह ऐसी जगह है जहाँ से दूसरे बूटस्ट्रैप कर सकें, और ऐसे नोड का अनुपात ही वह मिथ्याकरणीय शर्त है जिस पर traversal न करने का पूरा निर्णय टिका है।

# periphery: nothing to configure
zycordd --testnet --dir ./testnet

# core: bind a port, and make sure it is actually reachable
zycordd --testnet --dir ./testnet \
  --listen 0.0.0.0:9421 --advertise <public-address>:9421
ऐसा पता प्रचारित करें जो उत्तर दे, या कोई नहीं

--listen 0.0.0.0:9421 पीछे हटकर --listen पर चला जाता है, इसलिए बिना --advertise के --advertise 0.0.0.0:9421 प्रकाशित करता है, जिसे कोई डायल नहीं कर सकता। ग़लत पता पीयर आदान-प्रदान से फैलता है और उसे आज़माने वाले हर नोड को एक डायल की पड़ता है। अगर आप कोई पोर्ट फ़ॉरवर्ड नहीं कर सकते, तो --listen बंद रहने दें और परिधि पर रहें।

यह जाँचना कि काम हुआ या नहीं#

curl -s localhost:9420/network
{"enabled":true,"peers":8,"listening":true,"inbound":5,"outbound":3,"reachable":true}

नोड के कुछ मिनट चलते रहने के बाद listening: true के साथ inbound: 0 का मतलब है कि पोर्ट वास्तव में पहुँच-योग्य नहीं है: प्रक्रिया बँधी हुई है और इंतज़ार कर रही है, और कुछ आ नहीं रहा। बाक़ी हर दृश्य में यह स्वस्थ दिखता है, और इसीलिए यह एंडपॉइंट मौजूद है।

फ़ाइल से बूटस्ट्रैप पते#

zycordd --testnet --dir ./testnet --peers-file peers.txt

प्रति पंक्ति एक पता; # टिप्पणियाँ और ख़ाली पंक्तियाँ अनदेखी की जाती हैं, और सूची नेटवर्क के अंतर्निहित seeds के साथ मिला दी जाती है। --peers वही चीज़ अल्पविराम से अलग किए तर्क के रूप में लेता है, और --no-seeds अंतर्निहित seeds हटा देता है और बाक़ी दोनों रखता है।

वॉलेट इंटरफ़ेस, ssh टनल पर#

नोड कोई कुंजी नहीं रखता और कभी नहीं रखेगा। वॉलेट एक अलग प्रक्रिया है, और सर्वर पर वह है zcd ui:

zcd ui --key wallet.json --no-open

वह एक URL छापता है और उसे 127.0.0.1:9430 पर परोसता है। वह loopback से बँधता है और बाक़ी सब मना कर देता है, और इसे बदलने के लिए कोई फ़्लैग नहीं है। उस listener के पीछे की प्रक्रिया एक अनलॉक निजी कुंजी रखती है और URL में मौजूद bearer टोकन से प्रमाणीकरण करती है, जो ऐसे सॉकेट के लिए पर्याप्त है जिसे केवल स्थानीय मशीन खोल सकती है और किसी और चीज़ के लिए पर्याप्त नहीं। कहीं और से उस तक पहुँचना ssh का काम है, और ssh इसमें इससे बेहतर है:

# on your own machine
ssh -L 9430:127.0.0.1:9430 <host>

फिर सर्वर द्वारा छापा गया URL खोलें। टोकन URL के fragment में सवार होता है, इसलिए वह न सर्वर तक पहुँचता है, न किसी लॉग तक, न किसी Referer हेडर तक — URL को वही रहस्य मानें जो वह है। हर बार चलाने पर वह नया होता है, और Ctrl-C कुंजी मिटा देता है और सेवा रोक देता है।

फ़ॉरवर्ड का स्थानीय सिरा पोर्ट 9430 ही हो, यह ज़रूरी नहीं: इंटरफ़ेस Host हेडर में होस्टनाम जाँचता है और जानबूझकर पोर्ट नहीं। होस्टनाम ही मायने रखता है — वही DNS rebinding रोकता है, जो loopback पर चल रहे सर्वर के विरुद्ध असली हमला है, क्योंकि आपके ब्राउज़र का कोई भी पृष्ठ 127.0.0.1 पर अनुरोध भेज सकता है और इकलौती चीज़ जो वह गढ़ नहीं सकता वह है वह नाम जिस पर वह पहुँचा।

zcd ui के आगे कोई रिवर्स प्रॉक्सी न लगाएँ

ऊपर नोड की RPC के बारे में दी गई सलाह ऐसी सतह के बारे में है जो कोई कुंजी नहीं रखती और कोई अधिकार नहीं देती। यह वाली एक कुंजी रखती है। इसे उजागर करने का कोई भी रूप अच्छा विचार नहीं है, और टनल की क़ीमत बस एक फ़्लैग है।

दो और रूप जानने लायक हैं:

  • zcd ui --locked टर्मिनल में passphrase पूछे बिना शुरू होता है; उसके बजाय ब्राउज़र पूछता है। जब टर्मिनल साझा हो या उसका लॉग रखा जाता हो तब उपयोगी।
  • zcd ui --lock-after 5m निष्क्रियता पर लगने वाला लॉक छोटा कर देता है, जो कुंजी को उसकी जगह पर ही मिटा देता है — seed पर ऊपर से लिखा जाता है, उसे केवल छोड़ा नहीं जाता।

forced path, और sequencer चलाना#

Era 1 से एक माइनिंग नोड forced path का निष्पादक भी है। वह प्राप्त होने वाले open intents को एकत्र करता है और, अपने बनाए ब्लॉकों में, उनमें से जिन्हें वह चुने उन्हें ब्लॉक-के-अंत की स्टेट पर निष्पादित करके forced सर्टिफिकेट के रूप में जोड़ देता है, प्रति ब्लॉक अधिकतम 16। यह डिफ़ॉल्ट रूप से चालू है और इसका भुगतान होता है: हर open intent का भुगतान उसके शुल्क को ढकता है, आधार शुल्क जला दिया जाता है और शेष producer को जाता है।

zycordd ... --mine --forced-min-margin DROPS   # execute only open intents that pay this much beyond their fees
zycordd ... --mine --no-forced                 # execute none

इसे बंद करने से इस नोड को भुगतानों का नुक़सान होता है और उपयोगकर्ताओं का ऐसा कुछ नहीं जाता जो उन्हें कहीं और न मिल सके: कोई भी दूसरा producer वही open intents ले जा सकता है।

कोई नोड उन कॉन्ट्रैक्ट के लिए sequencer के रूप में भी काम कर सकता है जिन्होंने उसकी कुंजी पंजीकृत की है: वह उनके intents को उस कुंजी के persistent पते से fill करता है और sequencer इंटरफ़ेस पर वॉलेटों को उत्तर देता है, अपने अलग listener पर जो RPC नहीं है।

zcd wallet new --out seq.key        # its first persistent key is the sequencer key
zycordd --dir ./data --sequencer --sequencer-key seq.key \
  --sequencer-listen 0.0.0.0:PORT \
  --sequencer-tls-cert cert.pem --sequencer-tls-key key.pem \
  --sequencer-endpoint https://HOST:PORT --sequencer-announce

--sequencer-announce एंडपॉइंट को on-chain directory में बनाए रखता है और उसकी अवधि समाप्त होने से पहले उसका नवीनीकरण करता है; वॉलेट loopback और .onion को छोड़कर https की माँग करते हैं। मूल्य फ़्लैग (--sequencer-flat, --sequencer-seq-rate, --sequencer-par-rate) तय करते हैं कि किसी intent को कितना भुगतान करना होगा। कुंजी फ़ाइल एन्क्रिप्टेड रहती है और उसका passphrase मानक इनपुट या environment से आता है, कमांड लाइन पर कभी नहीं। fill का deposit और उसके skips उसी persistent पते से निकलते हैं, इसलिए उसमें धन बनाए रखें: जो sequencer पुरानी स्टेट पर fill प्रकाशित करता है वह skip शुल्क चुकाता है, और उसके उपयोगकर्ता कुछ नहीं चुकाते। किसी कॉन्ट्रैक्ट की सेवा तब होती है जब उसका रिकॉर्ड इस कुंजी का नाम दे, जिसे उसका admin zcd wallet register-sequencer से या उसका अपना कोड सेट करता है। पूरी प्रक्रिया docs/OPERATING.md में है।

पीयर पहचान और गुमनामी#

नोड हर बार शुरू होने पर एक नई Ed25519 पीयर कुंजी बनाता है और उसे कभी डिस्क पर नहीं लिखता। वह किसी चीज़ से व्युत्पन्न नहीं होती — न आपके वॉलेट से, न किसी seed से, न मशीन की किसी और चीज़ से। दोबारा शुरू करने पर वह बदल जाती है।

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

डेटा डायरेक्टरी#

data/
  chain/       blocks, state, and the write-ahead log
  peers.json   the persisted peer store

पीयर स्टोर जानबूझकर स्थायी रखा जाता है: जो नोड हर बार पुनः शुरू होने पर कोरी स्लेट से शुरू होता है वह हमलावर को उसे भरने का नया मौक़ा देता है। उसे हटाना सुरक्षित है पर उससे यह लाभ चला जाता है।

नोड किसी भी क्षण मार दिए जाने से बच जाता है — write-ahead लॉग इसी के लिए है, और इसे नेटवर्क अफ़रा-तफ़री के बीच नोड को बेतरतीब मारकर परखा जाता है। वह अपनी डेटा डायरेक्टरी को नीचे से बदल दिए जाने से नहीं बचता: शुरू होने पर वह state root दोबारा गणना करता है और संग्रहीत मान से असहमति होने पर चलने से मना कर देता है।

नेटवर्क चुनना#

फ़्लैगनेटवर्कChain idइंजन
(कोई नहीं)mainnet1randomx-v2
--testnetसार्वजनिक testnet2randomx-v2
--devnetस्थानीय devnet1337विकास इंजन

पैरामीटर बाइनरी में जड़े होते हैं, किसी पथ से पढ़े नहीं जाते। किसी सार्वजनिक नेटवर्क के हर सहभागी को वही बाइट ढोने होते हैं वरना वे एक नेटवर्क पर हैं ही नहीं, और --params से दी गई फ़ाइल ऐसी फ़ाइल है जो खिसकती है। अलग नेटवर्क अलग नेटवर्क होता है: दोनों हैंडशेक पर ही अलग हो जाते हैं, और ग़लत चेन रखने वाली डेटा डायरेक्टरी को चुपचाप मिलाने के बजाय शुरुआत में ही अस्वीकार कर दिया जाता है।

क्षतिग्रस्त डेटा डायरेक्टरी की मरम्मत#

zycordd में ऐसी डेटा डायरेक्टरी के लिए एक मरम्मत मार्ग है जिसके विरुद्ध नोड शुरू होने से इनकार कर देता है। पहले नोड रोकें — zycordd repair --dir ./data डायरेक्टरी लॉक लेता है और जब तक कोई नोड उसे पकड़े हो तब तक चलने से इनकार करता है — और फिर कुछ भी बदलने से पहले --dry-run से पूछें कि हुआ क्या। केवल एक क्षति-श्रेणी वहीं ठीक होती है; बाक़ी का उपाय फिर से sync करना है, और आपके पास कौन-सी है यह यही ड्राई रन बताता है।