Rand Protocol
لاسوندونه
RISC-V پروګرامونه

د RISC-V ISA

په Rand کې د RV32IM مانا څه ده - هغه لارښوونې چې zkVM یې ثابتوي، هغه څه چې چکوونکی یې ردوي، اته syscalls، حافظه، د انځور کانټینر چې پروګرام پکې وړاندې کېږي، او د پروګرام سقف.

مخکې له دې چې د Rand لپاره پروګرام ولیکئ، دا پاڼه ولولئ. دا وايي چې ستاسو کوډ پر کوم ماشین چلېږي، د وسیلو لړۍ څه ردوي، پروګرام له بهرنۍ نړۍ سره څنګه اړیکه نیسي، او کومه دوتنه پلي کوئ. راتلونکې پاڼې پر همدې ولاړې دي: د Rust پروګرام پلي کول، د RISC-V پروګرام پلي کول، او دواړه ژباړونکي.

ماشین

د Rand پروګرامونه RV32IM دي: د RISC-V د بشپړو عددونو 32-بټي بنسټیزه ټولګه، جمع د ضرب او وېش توسیع. دوی د 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 د خپل هدف صفرم بټ پاکوي، لکه څنګه چې RV32I وايي، او کوډبندي یې باید funct3 = 0 ولري. دواړه قاعدې د محدودیتونو له ټولګې 7 (ځنځیر 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 او د 9 شمېرې ecall لري، لکه څنګه چې 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 ptrپر 50 کلمو په خپل ځای کې یوه Keccak-f[1600] جابه‌جایي192keccak(state), keccak256(msg)rand_keccak
5SHA256 ptrپر 24 کلمو په خپل ځای کې یو 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، له ځنځیر 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] اخلي.

د وسیلو په لړۍ کې یوه تشه. د circuits په aeacf31 کې ماشین، ایمولېټر او Rust SDK سیستمي بلنه 7 پلي کوي، خو rand-guest check یې نه پلي کوي: د سیستمي بلنو لړ لیست یې په 6 پای ته رسېږي، نو هغه ecall چې a7 = 7 ولري، د Syscall موندنې په توګه راپور کوي، او rand-guest build د هغه مېلمه پروګرام لپاره چې poseidon2_len بولي، له غیرصفري کوډ سره وځي (د circuits ستونزه #1). guest.h هم ورته هېڅ پوښ نه لري. تر هغه چې دا سمه شوې نه وي، هغه مېلمه پروګرام چې په معیاري وسیله جوړ شوی وي، پر ثابت‌اوږدوالو پیغامونو POSEIDON2 کاروي.

ثبوت یوازې همدا خپروي: hc، H_IN، H_PUB، کچه، د ګاز اعلان شوې پوله، او اته د وتنې کلمې. نن پر ځنځیر دوه پولې پلي کېږي:

  • عامه برخه د پلي کولو پر مهال ثابتېږي. پر ځنځیر 20 باندې، rand program deploy --public د پروګرام عامې کلمې ټاکي (تر ټولو ډېر max_program_public_words، یعنې 32,768)، او هره بلنه د هغوی پر وړاندې ازمویل کېږي. د هرې بلنې لپاره د پروګرام خپلې عامې کلمې نشته. ځنځیر 20، د ځنځیر 19 په څېر، له هغوی وروسته د هرې بلنې برخې ته اته کلمې زیاتوي، چې د بلنې تړنه ده او ثبوت له خپلې معاملې سره تړي (پر ځنځیر 20 کې د پیدایښت هش هم پکې شامل دی)؛ مېلمه پروګرام خپلې کلمې د پخوا په څېر په همغو شاخصونو کې لولي. د RPL-2 یو Invoke اعلان شوی لېږد له تړنې وروسته زیاتوي، چې پروګرام یې له public_len + 8 څخه وروسته لولي (پروګرامونه). پر هغه ځنځیر چې د پولې ساحې نه لري، لکه ځنځیر 12، عامه برخه تشه ده او READ_PUBLIC د لوستلو لپاره څه نه لري.
  • د یوې بلنې د خصوصي ننوتې کلمې د مهر شوې پاکټ له لوري محدودې دي. د ځنځیر 20 max_call_envelope_bytes، چې 65,536 دی، 16,071 کلمې اجازه کوي؛ هغه ځنځیر چې دا ساحه نه لري، 4,295 کلمې اجازه کوي.

د KECCAK یا SHA256 بلنه ثبوت ته یو جدول زیاتوي، او بیا د ثبوت سرلیک ښيي چې بلنې هش کړی دی. هغه ثبوت چې keccak لري، شاوخوا 3.3 MB دی: د ثبوت له 2 MiB ډیفالټ پولې پورته، د ځنځیر 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 او د پروګرام پېژندنه د ټولو words پر سر، د سریزې په ګډون، محاسبه کېږي. نو hc د کوډ ترڅنګ معلومات هم تړي.

هغه کانټینر چې معلومات نه لري، سریزه نه ورکوي، او همغه پروګرام او hc ورکوي چې په همغه بنسټ کې یو بې‌سرلیکه هوار باینري یې ورکوي.

د fullnode په v0.3 او وروستیو نسخو کې rand program deploy کانټینر د هغه په لومړۍ کلمه پېژني. 0x444e4152 هېڅکله د لارښوونې په توګه کوډلوستل کېږي نه، نو خام .bin د کانټینر سره نه شي ګډوډېدای. هغه دوتنه چې په جادويي کلمې پیلېږي خو بڼه یې ناسمه وي، تېروتنه ده، نه بدیل ته ستنېدل.

دوه هویتونه

نومڅه دیڅوک یې کاروي
hcد (base_pc, len, words) د سرکټ Poseidon2 ډایجسټد یوې غوښتنې هر ثبوت د هغه پر وړاندې تاییدیږي؛ rand_getProgram یې د code_hash په توګه ښيي
د پروګرام پېژندونکیblake3("rand-program" ‖ base_pc ‖ words)؛ هغه ځای پر ځای کول چې --public ولري، عامې کلمې هم د rand-program-2 ټګ لاندې تړيهغه کلي چې ځای پر ځای شوی پروګرام پرې ساتل کیږي او غوښتل کیږي

rand-guest build او rand-guest info دواړه چاپوي. hc تړونکی دی خو پټوونکی نه دی: هر څوک چې یو نوماند پروګرام ولري، کولی شي هغه تایید کړي.

د پروګرام سقف

یو ځای پر ځای کول تر ټولو زیات د زنځیر د پروګرام سقف په اندازه کلمې لېږدولی شي.

زنځیرسقف
هغه پیدایښت چې 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 کې، د کلمو سقف ټاکونکی حد نه دی. د هغه پیدایښت hardening_v6 ټاکي، چې له مخې یې ځای پر ځای کول (ProgramUncallable) هغه وخت ردیږي کله چې هېڅ غوښتنه هېڅکله د پروګرام ثبوت جوړ نه کړای شي. یوه غوښتنه تر پوړ 14 پورې محدوده ده، چې د Poseidon2 جدول یې 2,048 پرمیوټیشنونه لري. د پروګرام ډایجسټ د هرو څلورو کلمو لپاره یو پرمیوټیشن لګوي، د ورودي د مالګې قطار یو او د غوښتنې اته تړونکې کلمې دوه، چې 2,045 پاتې کیږي: د عامې ورودي پرته پروګرام لپاره 8,180 کلمې، او د عامې ورودي سره لږ (د نهو عامو کلمو سره 8,168). د هر نوډ حوض په هر زنځیر کې داسې ځای پر ځای کول ردوي.

په زنځیر 20 کې د بلاکونو راټولول بند دي: د هغه پیدایښت د aggregation برخه نه لري. زنځیر 20 له 2026-10-01 06:17 UTC راهیسې د fullnode v0.6.8 پر سر ژوندی دی، یو سخت فورک چې د زنځیر 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
ایمېجکلمېپه 4,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 قطارونو پورې محدودوي: سایکلونه جمع د ډایجسټ قطارونه (د هرو څلورو پروګرام کلمو لپاره یو، د هرو څلورو ورودي کلمو لپاره یو، او د عامې ورودي ډایجسټ). پوړ د 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⌉، د زنځیر په اوسنیو بیو، چې له 100 او 800 واحدونو د 10⁻⁹ RAND څخه پیلیږي، د بلاک له ډکوالي سره بدلیږي او په زنځیر 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 پرمیوټیشنونه ده، او د پروګرام خپل ډایجسټ د هرو څلورو کلمو لپاره نږدې یو پرمیوټیشن لګوي، نو له 8,180 کلمو څخه لوی پروګرام نشي غوښتل کېدای، او زنځیر 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. چېرې چې کوډ او دا پاڼه سره توپیر ولري، کوډ سم دی؛ موږ ته خبر راکړئ.