Rand Protocol
दस्तावेज़ीकरण
RISC-V प्रोग्राम

RISC-V ISA

Rand पर RV32IM का अर्थ - वे निर्देश जिन्हें zkVM सिद्ध करता है, वे जिन्हें चेकर अस्वीकार करता है, आठ syscall, मेमोरी, वह इमेज कंटेनर जिसमें प्रोग्राम वितरित होता है, और प्रोग्राम की सीमा।

इस पेज को Rand के लिए प्रोग्राम लिखने से पहले पढ़ें। यह बताता है कि आपका कोड किस मशीन पर चलता है, टूलचेन क्या अस्वीकार करता है, प्रोग्राम बाहरी दुनिया से कैसे संवाद करता है, और आप कौन-सी फ़ाइल डिप्लॉय करते हैं। आगे के पेज इसी पर आधारित हैं: Rust प्रोग्राम डिप्लॉय करें, RISC-V प्रोग्राम डिप्लॉय करें, और दोनों ट्रांसपाइलर।

मशीन

Rand प्रोग्राम RV32IM हैं: 32-बिट RISC-V बेस इंटीजर सेट और साथ में गुणा तथा भाग एक्सटेंशन। ये Rand zkVM के भीतर चलते हैं, जो हर रन को Plonky3 बैच STARK से प्रमाणित करता है। सत्यापनकर्ता कभी कोई निर्देश नहीं देखता। वह प्रूफ को hc के विरुद्ध जाँचता है, जो प्रोग्राम का इन-सर्किट Poseidon2 डाइजेस्ट है।

समूहनिर्देश
अपर / जंपLUI AUIPC JAL JALR
ब्रांचBEQ BNE BLT BGE BLTU BGEU
लोड / स्टोरLW SW LB LH LBU LHU SB SH
ALUADDI SLTI SLTIU XORI ORI ANDI SLLI SRLI SRAI ADD SUB SLL SLT SLTU XOR SRL SRA OR AND
RV32MMUL MULH MULHU MULHSU DIV DIVU REM REMU
सिस्टमकेवल ECALL

JALR अपने लक्ष्य का बिट 0 साफ़ करता है, जैसा RV32I कहता है, और इसकी एन्कोडिंग में funct3 = 0 होना अनिवार्य है। ये दोनों नियम कंस्ट्रेंट सेट 7 (chain 16) के साथ आए; उससे पहले विषम लक्ष्य को फ़ेच नहीं किया जा सकता था और रन को प्रमाणित नहीं किया जा सकता था। जो लक्ष्य सम है पर चार का गुणज नहीं है, उसे अब भी फ़ेच नहीं किया जा सकता।

इसमें फ़्लोटिंग पॉइंट नहीं है, एटॉमिक्स (A एक्सटेंशन) नहीं हैं, कंप्रेस्ड निर्देश (C एक्सटेंशन) नहीं हैं और 64-बिट रजिस्टर नहीं हैं। C में 64-बिट भाग एक सॉफ़्टवेयर हेल्पर के कॉल में बदल जाता है; देखें C पथ।

क्या अस्वीकार किया जाता है

rand-guest check हर टेक्स्ट वर्ड को मशीन के अपने डिकोडर से गुज़ारता है। जो प्रोग्राम इसमें पास हो जाता है, वह सर्किट में एन्कोडिंग, सिस्कॉल-संख्या या लेआउट के कारण विफल नहीं हो सकता। चेकर इन्हें अस्वीकार करता है:

निष्कर्षयह क्या है
Compressed16-बिट RVC एन्कोडिंग; मशीन केवल 32-बिट वर्ड डिकोड करती है
Undecodableऐसा ऑपकोड, funct या शिफ़्ट मान जिसे मशीन लागू नहीं करती
FenceFENCE या FENCE.I; मशीन में कोई मेमोरी ऑर्डरिंग नहीं है
Csrकोई भी CSR निर्देश; मशीन में CSR नहीं हैं
EbreakEBREAK; ट्रैप मॉडल नहीं किए गए हैं
Syscallऐसा ecall जिसका a7 ठीक पहले किसी li द्वारा सेट हो और किसी सिस्कॉल को इंगित न करे
Cap--max-words से अधिक वर्ड, उसी तरह गिने गए जैसे लोडर गिनता है
Layoutऐसा टेक्स्ट बेस जो वर्ड-संरेखित नहीं है

एक चार-वर्ड प्रोग्राम जिसमें एक fence, एक ebreak और ecall संख्या 9 है, जैसा rand-guest check इसे रिपोर्ट करता है (एग्ज़िट कोड 1):

$ rand-guest check bad.elf
note: the loader refuses this image (Decode { index: 0, word: 267386895, err: Opcode(15) }), so its data prologue could not be counted; the word count below is the text alone
0x00001000  0x0ff0000f  Fence: FENCE/FENCE.I: the machine has no memory ordering instructions
0x00001004  0x00100073  Ebreak: EBREAK: traps are not modelled
0x0000100c  0x00000073  Syscall: ecall with a7 = 9, which is no syscall the machine implements
4 words against a cap of 4096 (fits); 0 ecall(s) with a non-static a7
REJECTED

जिस ecall का a7 चेकर नहीं देख सकता (जो li के अलावा किसी और चीज़ से, या किसी ब्रांच के बाद सेट हो), उसे अस्वीकार नहीं किया जाता बल्कि unresolved_ecalls में गिना जाता है। रन टाइम पर ग़लत संख्या मिलने पर मशीन फिर भी ट्रैप करती है।

चेकर पॉइंटर मान, लंबाइयाँ या इनपुट इंडेक्स, RAM के सापेक्ष 64 KiB स्टैक, या रन टाइम पर गणना किए गए पतों का संरेखण नहीं जाँचता। असंरेखित एक्सेस कंस्ट्रेंट का उल्लंघन है, इसलिए टूलचेन -unaligned-scalar-mem के साथ कंपाइल करता है। rand-guest run रन टाइम के किसी भी ट्रैप की रिपोर्ट करता है।

सिस्कॉल

ECALL सिस्कॉल संख्या a7 से, पहला आर्ग्युमेंट a0 से और दूसरा a1 से पढ़ता है। लौटाया गया मान a0 में आता है।

#सिस्कॉलप्रभावगैसRust (guest-sdk)C (guest.h)
0HALTरन समाप्त करता है1halt()rand_halt()
1WRITE_OUTPUT slot wordसार्वजनिक आउटपुट slot < 8 सेट करता है, प्रति स्लॉट अधिकतम एक बार; जिन स्लॉट में नहीं लिखा गया वे शून्य रहते हैं1write_output(slot, word)rand_write_output
2READ_INPUT idxनिजी इनपुट वर्ड idx लौटाता है, जो सॉल्टेड कमिटमेंट H_IN से बँधा है1read_input(idx)rand_read_input
3POSEIDON2 ptr nवर्ड पता ptr पर n ≤ 4096 वर्ड हैश करता है और 8-वर्ड डाइजेस्ट ptr..ptr+8 पर लिखता है; कोई पैडिंग नहीं3 + 3·⌈n/4⌉unsafe poseidon2(ptr, n)rand_poseidon2
4KECCAK ptr50 वर्ड पर इन-प्लेस एक Keccak-f[1600] परम्यूटेशन192keccak(state), keccak256(msg)rand_keccak
5SHA256 ptr24 वर्ड पर इन-प्लेस एक SHA-256 कम्प्रेशन64sha256_compress(buf), sha256(msg)rand_sha256_compress
6READ_PUBLIC idxसार्वजनिक-सेगमेंट वर्ड idx लौटाता है, जो अनसॉल्टेड H_PUB से बँधा है1read_public(idx)rand_read_public
7POSEIDON2_LEN ptr nPOSEIDON2, जिसमें लंबाई n स्पंज में बँधी होती है, कम से कम एक परम्यूटेशन (कंस्ट्रेंट सेट 7)3 + 3·max(⌈n/4⌉, 1)poseidon2_len(buf, n)कोई नहीं

हर अन्य निर्देश की लागत 1 गैस है: गैस प्रति cpu पंक्ति एक है, और केवल हैश सिस्कॉल का भार अधिक है (कंस्ट्रेंट सेट 8, chain 18 से)। एक Poseidon2 कॉल में उसकी ecall पंक्ति, दो राइट-बैक पंक्तियाँ और ⌈n/4⌉ अब्ज़ॉर्ब पंक्तियाँ होती हैं, प्रत्येक 3 गैस की।

POSEIDON2 पैडिंग नहीं करता। स्पंज हर चार-वर्ड खंड से अपनी पहली लेनों को अधिलेखित कर देता है, इसलिए [a], [a, 0], [a, 0, 0] और [a, 0, 0, 0] का हैश एक ही डाइजेस्ट होता है। जो प्रोग्राम परिवर्तनशील लंबाई वाले डेटा को हैश करता है, उसे लंबाई को संदेश में शामिल करना होगा, निश्चित-लंबाई एन्कोडिंग को हैश करना होगा, या POSEIDON2_LEN को कॉल करना होगा, जो n को स्पंज की कैपेसिटी में डालता है और उन्हीं वर्ड का अलग डाइजेस्ट देता है। Rust SDK में poseidon2 एक रॉ पॉइंटर पर unsafe fn है और poseidon2_len स्लाइस पर सुरक्षित कॉल है; keccak और sha256_compress क्रमशः &mut [u32; 50] और &mut [u32; 24] लेते हैं।

टूलचेन में एक कमी। सर्किट aeacf31 पर मशीन, एमुलेटर और Rust SDK सिस्कॉल 7 को लागू करते हैं, पर rand-guest check नहीं करता: इसकी सिस्कॉल सूची 6 पर रुक जाती है, इसलिए यह a7 = 7 वाले ecall को Syscall निष्कर्ष के रूप में रिपोर्ट करता है और poseidon2_len को कॉल करने वाले गेस्ट पर rand-guest build गैर-शून्य कोड के साथ बाहर निकलता है (circuits issue #1)। guest.h में भी इसका कोई रैपर नहीं है। जब तक यह ठीक नहीं होता, मानक टूल से बना गेस्ट निश्चित-लंबाई संदेशों पर POSEIDON2 का उपयोग करता है।

एक प्रूफ ठीक यही प्रकाशित करता है: hc, H_IN, H_PUB, टियर, घोषित गैस सीमा, और आठ आउटपुट वर्ड। आज चेन पर दो सीमाएँ लागू हैं:

  • सार्वजनिक सेगमेंट डिप्लॉय के समय निश्चित हो जाता है। chain 20 पर rand program deploy --public किसी प्रोग्राम के सार्वजनिक वर्ड सेट करता है (अधिकतम max_program_public_words, 32,768), और हर कॉल उनके विरुद्ध जाँची जाती है। प्रोग्राम के अपने कोई प्रति-कॉल सार्वजनिक वर्ड नहीं होते। chain 20, chain 19 की तरह, हर कॉल के सेगमेंट में उनके बाद आठ वर्ड जोड़ता है, जो कॉल बाइंडिंग है और प्रूफ को उसके ट्रांज़ैक्शन से जोड़ती है (chain 20 पर इसमें जेनेसिस हैश भी शामिल है); गेस्ट अपने वर्ड पहले जैसे ही इंडेक्स पर पढ़ता है। RPL-2 Invoke बाइंडिंग के बाद घोषित ट्रांज़िशन जोड़ता है, जिसे प्रोग्राम public_len + 8 से आगे पढ़ता है (प्रोग्राम)। जिस चेन में सीमा फ़ील्ड नहीं हैं, जैसे chain 12, वहाँ सार्वजनिक सेगमेंट ख़ाली होता है और READ_PUBLIC के पास पढ़ने को कुछ नहीं होता।
  • किसी कॉल के निजी इनपुट वर्ड सील किए गए एन्वेलप से सीमित होते हैं। chain 20 का max_call_envelope_bytes, जो 65,536 है, 16,071 वर्ड की अनुमति देता है; जिस चेन में यह फ़ील्ड नहीं है, वह 4,295 की अनुमति देती है।

KECCAK या SHA256 कॉल प्रूफ में एक टेबल जोड़ती है, और तब प्रूफ का हेडर दिखाता है कि कॉल ने हैश किया। keccak वाला प्रूफ लगभग 3.3 MB का होता है: डिफ़ॉल्ट 2 MiB प्रूफ सीमा से अधिक, chain 20 की 4 MiB से कम, और एक कॉल अधिकतम 128 Keccak-f परम्यूटेशन और 128 SHA-256 कम्प्रेशन का उपयोग कर सकती है (प्रोग्राम)।

मेमोरी

  • 32 रजिस्टर; x0 शून्य है।
  • RAM शून्य से शुरू होती है। हर पता 2³⁰ से नीचे है।
  • डिफ़ॉल्ट लिंकर स्क्रिप्ट, guest-sdk/guest.ld, प्रोग्राम को 0x1000 पर रखती है, फिर .rodata, .data और .bss, फिर __stack_top पर 64 KiB स्टैक।
  • डेटा सेगमेंट वाले प्रोग्राम को अपने टेक्स्ट के नीचे लोडर के प्रोलॉग (अगला खंड) के लिए जगह चाहिए। उसका अपना .ld ORIGIN को बढ़ाकर 0x10000 कर देता है, जैसा evm.ld और sbpf.ld करते हैं।

इमेज कंटेनर

rand-guest build और rand-guest pack एक ही फ़ाइल फ़ॉर्मेट लिखते हैं, इमेज कंटेनर। सभी संख्याएँ लिटिल-एंडियन 32-बिट वर्ड हैं:

[0x444e4152 ("RAND"), 1, text_base, n_text, data_base, n_data] text… data…

लोडर कंटेनर को एक प्रोग्राम { base_pc, words } में बदलता है:

  1. यह हर गैर-शून्य डेटा वर्ड के लिए एक li/sw जोड़ी लिखता है। शून्य वर्ड छोड़ दिए जाते हैं, क्योंकि RAM पहले से शून्य पढ़ती है।
  2. यह उस प्रोलॉग को सीधे text_base के नीचे रखता है, इसलिए base_pc = text_base − 4 × prologue words। प्रोलॉग से निष्पादन सीधे प्रोग्राम के अपने _start में चला जाता है।
  3. hc और प्रोग्राम id की गणना पूरे words पर होती है, प्रोलॉग सहित। इसलिए hc कोड के साथ-साथ डेटा को भी बाँधता है।

जिस कंटेनर में डेटा नहीं है, उससे कोई प्रोलॉग नहीं बनता, और उसी बेस पर हेडर-रहित फ़्लैट बाइनरी जैसा ही प्रोग्राम और hc मिलता है।

fullnode v0.3 और उसके बाद के संस्करणों में rand program deploy कंटेनर को उसके पहले वर्ड से पहचानता है। 0x444e4152 कभी किसी निर्देश के रूप में डिकोड नहीं होता, इसलिए किसी रॉ .bin को कंटेनर समझ लेने की भूल नहीं हो सकती। जो फ़ाइल मैजिक से शुरू होती है पर विकृत है, वह त्रुटि है, फ़ॉलबैक नहीं।

दो पहचानें

नामयह क्या हैइसका उपयोग कौन करता है
hc(base_pc, len, words) का सर्किट द्वारा परिकलित Poseidon2 डाइजेस्टकिसी कॉल के प्रत्येक प्रमाण का सत्यापन इसी के विरुद्ध होता है; rand_getProgram इसे code_hash के रूप में दिखाता है
प्रोग्राम idblake3("rand-program" ‖ base_pc ‖ words); --public के साथ किया गया डिप्लॉय सार्वजनिक words को भी rand-program-2 टैग के अंतर्गत बाँधता हैवह कुंजी जिसके अंतर्गत डिप्लॉय किया गया प्रोग्राम संग्रहीत होता है और कॉल किया जाता है

rand-guest build और rand-guest info दोनों को प्रिंट करते हैं। hc बाध्यकारी (binding) है, पर गोपनीय (hiding) नहीं: जिसके पास कोई संभावित प्रोग्राम है, वह इसकी पुष्टि कर सकता है।

प्रोग्राम की सीमा

एक डिप्लॉय में अधिकतम उतने words हो सकते हैं जितनी चेन की प्रोग्राम सीमा है।

चेनसीमा
max_program_words के बिना जेनेसिस (चेन 12)4,096
max_program_words वाला जेनेसिसवही मान, 1..=65535
zkVM की कठोर सीमा, कोई भी चेन65,535

यह सीमा जेनेसिस हैश का हिस्सा है, इसलिए चल रही चेन पर इसे बदला नहीं जा सकता। rand-guest इसकी जाँच --max-words (डिफ़ॉल्ट 4,096) के विरुद्ध करता है। rand program deploy नोड से rand_estimateFee द्वारा पूछता है और सीमा से बड़े प्रोग्राम को कुछ भी प्रमाणित करने से पहले ही अस्वीकार कर देता है।

चेन 20, जो लाइव चेन है, यह सीमा बढ़ाती है। इसका जेनेसिस हैश 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135 है और इसका max_program_words 65,535 है। यह चेन 13 (v0.4 चेन) द्वारा लागू की गई सीमाएँ बनाए रखती है, सिवाय प्रमाण सीमा के, जिसे चेन 17 से 20 आधा कर देती हैं। इसकी अन्य सीमाएँ:

सीमाचेन 20
max_proof_bytes4,194,304 (4 MiB); चेन 13 से 16 पर 8 MiB
max_block_bytes20,971,520 (20 MiB)
max_call_envelope_bytes65,536
max_program_public_words32,768

चेन 20 पर, चेन 19 की तरह, words की सीमा निर्णायक सीमा नहीं है। इसका जेनेसिस hardening_v6 सेट करता है, जिसके अंतर्गत किसी डिप्लॉय को (ProgramUncallable) अस्वीकार कर दिया जाता है जब कोई भी कॉल उस प्रोग्राम को कभी प्रमाणित न कर सके। एक कॉल की सीमा टियर 14 है, जिसकी Poseidon2 तालिका में 2,048 परम्यूटेशन आते हैं। प्रोग्राम डाइजेस्ट हर चार words पर एक परम्यूटेशन लेता है, इनपुट की salt पंक्ति एक और आठ कॉल-बाइंडिंग words दो, जिससे 2,045 बचते हैं: सार्वजनिक इनपुट के बिना प्रोग्राम के लिए 8,180 words, और सार्वजनिक इनपुट होने पर इससे कम (नौ सार्वजनिक words के साथ 8,168)। प्रत्येक नोड का पूल किसी भी चेन पर ऐसे डिप्लॉय को अस्वीकार कर देता है।

चेन 20 पर ब्लॉक एग्रीगेशन बंद है: इसके जेनेसिस में कोई aggregation खंड नहीं है। चेन 20 fullnode v0.6.8 पर 2026-10-01 06:17 UTC से लाइव है; यह चेन 19 की स्थिति से ऊँचाई 7,258 पर काटा गया हार्ड फ़ोर्क है (चेन 19 ऊँचाई 7,700 पर रुकी); चेन 19 (उसी दिन 03:43 UTC से लाइव) स्वयं ऊँचाई 141,935 पर चेन 18 का पुनः-जेनेसिस थी। प्रोग्राम किसी कट के पार नहीं जाते, इसलिए किसी पिछली चेन पर डिप्लॉय किया गया कोई भी प्रोग्राम चेन 20 पर मौजूद नहीं है। चेन 20 RPL-2 प्रोग्राम स्टेट वाली पहली चेन भी है (प्रोग्राम)। यह नेटवर्क पर इन बूटस्ट्रैप नोड्स के माध्यम से चलती है:

/ip4/164.90.239.200/tcp/30303/p2p/12D3KooWEQEbUwZRgqhDPXhW7vNBmcRcnhUDGUADe81VFdv3ALYe
/ip4/165.245.173.74/tcp/30303/p2p/12D3KooWJyc5oDHggAr89e9QrRFBy9Tg8TxXh18yzrb1SM6KKLYw
/ip4/188.166.235.187/tcp/30303/p2p/12D3KooWSyX84P1DAbWByLHpRBMLRWD53r3Jj4aqVt6tHoF8B2ZQ
इमेजwords4,096 में समाता है65,535 में समाता हैचेन 20 पर डिप्लॉय होता है (8,180 कॉल-योग्य)
fib (Rust)26हाँहाँहाँ
c-fib (C)25हाँहाँहाँ
ERC-20, अनूदित (चरण दो)11,686नहींहाँनहीं
evm.bin, EVM इंटरप्रेटर18,009नहींहाँनहीं
sbpf.bin, sBPF इंटरप्रेटर8,317नहींहाँनहीं
SPL Token, अनूदित65,096नहींहाँ, 439 शेष रहते हुएनहीं

टियर

किसी प्रमाण का टियर t रन को 2ᵗ − 1 पंक्तियों तक सीमित करता है: साइकिल और डाइजेस्ट पंक्तियाँ (हर चार प्रोग्राम words पर एक, हर चार इनपुट words पर एक, और सार्वजनिक-इनपुट डाइजेस्ट)। टियर एक अलग Poseidon2 बजट भी तय करता है। rand-guest run --tier t दोनों की रिपोर्ट देता है:

tier 10: fits (cycles 146 of 1023, Poseidon2 permutations 10 of 128)

टियर सार्वजनिक है, और प्रमाण द्वारा घोषित गैस सीमा भी। चेन 20 पर कॉल शुल्क टियर के बजाय उसी सीमा और प्रमाण के आकार पर निर्भर करता है: चेन की वर्तमान कीमतों पर कम से कम 0.001 RAND + gas_price × gas_limit + byte_price × ⌈bytes / 1024⌉; ये कीमतें 10⁻⁹ RAND की 100 और 800 इकाइयों से शुरू होती हैं, ब्लॉक के भराव के साथ बदलती हैं और चेन 20 पर 10,000 और 80,000 इकाइयों पर रुकती हैं (शुल्क)। कोई सीमा हेडर की अधिकतम सीमा से अधिक नहीं हो सकती, जो (2ᵗ − 1) + 2ᵗ⁻² है, साथ में प्रमाण द्वारा घोषित प्रत्येक Keccak ब्लॉक पर 191 और प्रत्येक SHA-256 ब्लॉक पर 63: हैश तालिका के बिना टियर 10 पर 1,279 और टियर 14 पर 20,479। rand-guest run साइकिल और परम्यूटेशन की रिपोर्ट देता है, गैस की नहीं। rand call प्रमाणित करने से पहले प्रोग्राम को चलाता है और उसके द्वारा खर्च की गई गैस तथा घोषित सीमा प्रिंट करता है, जो डिफ़ॉल्ट रूप से सटीक गैस को 2ᵗ⁻² के अगले गुणज तक बढ़ाकर निकाली जाती है:

gas: 5636 (declaring 6144, tier 12)

यह पंक्ति 2026-09-30 को चेन 18 पर की गई एक कॉल की है (एक अनाम मतदान)। जेनेसिस gas खंड के बिना वाली चेन पर, यानी चेन 15 और उससे पहले, शुल्क एक टियर अनुसूची थी: 0.001 + (0.001 + 0.0001 × (t − 10) / 2) RAND। किसी प्रमाण के लिए आवश्यक मेमोरी टियर के साथ तेज़ी से बढ़ती है; देखें वैलिडेटर और एग्रीगेटर हार्डवेयर।

fullnode v0.5.6 (2026-09-25) से कोई कॉल अधिकतम टियर 14 घोषित कर सकती है: नोड उच्चतर टियर वाले कॉल प्रमाण को सत्यापन कुंजी बनाने से पहले ही CallTierTooHigh के साथ अस्वीकार कर देता है, और ऐसा प्रमाण ले जाने वाला ब्लॉक अमान्य होता है। टियर-14 का बजट 16,383 पंक्तियाँ और 2,048 Poseidon2 परम्यूटेशन है, और प्रोग्राम का अपना डाइजेस्ट लगभग हर चार words पर एक परम्यूटेशन खर्च करता है, इसलिए 8,180 words से बड़े प्रोग्राम को कॉल नहीं किया जा सकता, और चेन 20, चेन 19 की तरह, उसका डिप्लॉय अस्वीकार कर देती है। Rust या C में प्रोग्राम लिखें इस बजट को विस्तार से समझाता है।

2026-10-12 को fullnode कमिट c0878c3f (चेन 21) के विरुद्ध अंतिम बार सत्यापित, और circuits `aeacf31` (`rand-guest/README.md`, `rand-guest/src/check.rs`, `research/docs/01-isa.md`, `guest-sdk/`), fullnode tag v0.6.8 `c9c9bd3c` (`docs/program-state.md`, `ledger/program_state.rs`, `deploy/cut-chain20-genesis.sh`), chain 20's genesis and `rand_getLimits`, read on 2026-10-01, fullnode tag v0.8.0 `c0878c3f` (`docs/zkvm.md` §8a, constraint set 9), `deploy/genesis-chain21.json` and `rand_getLimits` on chain 21, read on 2026-10-12। जहाँ कोड और यह पृष्ठ असहमत हों, वहाँ कोड सही है; हमें बताएँ।