اس صفحے کی مدد سے آپ کسی پروگرام کو چین پر تعینات کر کے اسے کال کر سکتے ہیں۔ یہاں بتایا گیا ہے کہ پروگرام کیا ہے، اسے کیسے بنایا جاتا ہے، ایک کال کیا شائع کرتی ہے اور کیا پوشیدہ رکھتی ہے، رسید واپس کیسے پڑھی جاتی ہے، اور آپ کو کن حدود کا سامنا ہوگا۔ ہر پروگرام عوامی کوڈ ہے؛ ہر کال ایک ثبوت ہے۔ مثالی پروگرام میں مکمل ایپلیکیشنز موجود ہیں، اور randprotocol/example-programs میں چین 20 پر تعینات پروگراموں کا سورس کوڈ ہے، بشمول RPL-2 والے پروگرام (نیچے)۔
پروگرام کیا ہے
پروگرام Rand zkVM کے لیے RV32IM مشینی کوڈ ہے: { base_pc: u32, words: Vec<u32> }۔ اس کی زیادہ سے زیادہ لمبائی چین کی پروگرام حد ہے (چین 20 پر 65,535 ورڈ، جیسا کہ چین 13 کے بعد ہر چین پر؛ max_program_words کے بغیر جینیسس پر 4,096، جیسے چین 12)۔ base_pc کا 4 کا مضرب ہونا لازم ہے، اور ہر ورڈ کا ایک ہدایت کے طور پر ڈی کوڈ ہونا ضروری ہے (جو ورڈ ڈی کوڈ نہ ہو وہ تعیناتی کے وقت ہی رد کر دیا جاتا ہے، رن ٹائم پر کبھی نہیں)۔ چین 20، چین 19 کی طرح، ایسا پروگرام بھی تعینات کرنے سے انکار کرتی ہے جو کسی کال میں سما نہ سکے: عوامی حصے کے بغیر 8,180 سے زیادہ ورڈ، اور عوامی حصے کے ساتھ اس سے کم (نیچے)۔ پروگرام کا پتہ اس کے مواد سے متعین ہوتا ہے اور یہ ناقابلِ تغیر ہے:
program_id = blake3("rand-program" || base_pc || words) // the id, with no public input
program_id = blake3("rand-program-2", base_pc || u32_le(len(words)) || words || u32_le(len(public)) || public) // deployed with --public
code_hash = hc = Poseidon2 digest of (base_pc, len, words) // what calls are verified against
کال ایک STARK ثبوت ہے کہ ڈائجسٹ hc والا پروگرام کچھ نجی ان پٹس پر چلا، اس نے اعلان کردہ گیس حد سے زیادہ خرچ نہیں کیا، اور آٹھ آؤٹ پٹ ورڈ شائع کیے۔ نوڈ ثبوت کی تصدیق کرتا ہے اور ایک رسید درج کرتا ہے، اس کے سوا کچھ نہیں ہوتا: آؤٹ پٹ محض ڈیٹا ہیں، اثرات نہیں۔ کال RAND منتقل نہیں کر سکتی؛ کال کنندہ قدر اس بنڈل میں منتقل کرتا ہے جو کال کی ادائیگی کرتا ہے، اور پروگرام کے آؤٹ پٹ کا وہی مطلب ہوتا ہے جس پر پروگرام اور اس کا کال کنندہ متفق ہوں۔ چین 20 پر Invoke اس اصول سے مستثنیٰ ہے: اس کا ثبوت ایک اعلان کردہ اسٹیٹ کی تبدیلی کی ضمانت دیتا ہے، جسے پھر لیجر نافذ کرتا ہے (پروگرام اسٹیٹ (RPL-2))۔
گیسٹ کیا کر سکتا ہے:
| گروپ | ہدایات |
|---|---|
| بالائی / جمپ | LUI AUIPC JAL JALR |
| برانچ | BEQ BNE BLT BGE BLTU BGEU |
| لوڈ / اسٹور | LW SW LB LH LBU LHU SB SH |
| ALU | ADDI SLTI SLTIU XORI ORI ANDI SLLI SRLI SRAI ADD SUB SLL SLT SLTU XOR SRL SRA OR AND |
| RV32M | MUL MULH MULHU MULHSU DIV DIVU REM REMU |
| سسٹم | ECALL؛ FENCE، CSRs، EBREAK، اور A یا C ایکسٹینشنز کبھی نہیں |
سسٹم کالز، a7 میں ان کے نمبر کے لحاظ سے:
| # | سسٹم کال | اثر |
|---|---|---|
| 0 | HALT | رن ختم کرتا ہے |
| 1 | WRITE_OUTPUT slot word | عوامی آؤٹ پٹ slot < 8 کو مقرر کرتا ہے؛ ہر سلاٹ زیادہ سے زیادہ ایک بار، جو سلاٹ لکھے نہ جائیں وہ صفر رہتے ہیں |
| 2 | READ_INPUT idx | نجی ان پٹ ورڈ idx لوٹاتا ہے، جو نمک آمیز کمٹمنٹ H_IN سے بندھا ہوتا ہے |
| 3 | POSEIDON2 ptr n | Poseidon2 اسپنج کے ذریعے n ≤ 4096 ورڈز کو ان کی اپنی جگہ پر ہیش کرتا ہے |
| 4 | KECCAK ptr | اپنی جگہ پر ایک Keccak-f[1600] پرمیوٹیشن؛ اس سے ثبوت میں keccak ٹیبل شامل ہو جاتا ہے |
| 5 | SHA256 ptr | اپنی جگہ پر ایک SHA-256 کمپریشن؛ اس سے ثبوت میں sha256 ٹیبل شامل ہو جاتا ہے |
| 6 | READ_PUBLIC idx | عوامی حصے کا ورڈ idx لوٹاتا ہے؛ چین 20 پر عوامی حصہ تعیناتی کے وقت طے ہوتا ہے (rand program deploy --public)؛ max_program_public_words کے بغیر جینیسس پر یہ حصہ خالی ہوتا ہے اور یہ کال کچھ نہیں پڑھتی |
| 7 | POSEIDON2_LEN ptr n | ایسا POSEIDON2 جس میں پیغام کی لمبائی بھی اسپنج میں شامل کی جاتی ہے، اس لیے [a] اور [a, 0] کے ہیش مختلف ہوتے ہیں (قیود کا مجموعہ 7، چین 16 اور اس کے بعد)۔ circuits aeacf31 پر rand-guest check اسے اب بھی رد کرتا ہے (اگلا حصہ) |
میموری: 32 رجسٹر جن میں x0 صفر ہے؛ RAM جس کی ابتدائی قدر صفر ہے؛ ہر پتہ 2³⁰ سے کم؛ کمپائل شدہ گیسٹس کے لیے 64 KiB اسٹیک۔ rand-guest سے بنا پروگرام اپنا صرف پڑھنے کے قابل اور ابتدائی قدر والا ڈیٹا امیج کنٹینر میں رکھتا ہے۔ پروگرام کا حصہ ایک لوڈر پرولوگ پروگرام کا اپنا کوڈ چلنے سے پہلے یہ ڈیٹا میموری میں لکھ دیتا ہے (RISC-V ISA)۔ نوٹ کمٹمنٹس، نلیفائرز اور Merkle جانچیں سسٹم کالز نہیں بلکہ POSEIDON2 پر مبنی لائبریری روٹینز ہیں۔
چین 18 (قیود کا مجموعہ 8) سے ہر رن کی گیس میں پیمائش ہوتی ہے۔ ایک عام ہدایت اور سسٹم کالز 0، 1، 2 اور 6 میں سے ہر ایک کی لاگت 1 گیس ہے۔ n ورڈز پر POSEIDON2 کی لاگت 3 + 3 × ⌈n / 4⌉ ہے، ایک KECCAK پرمیوٹیشن کی لاگت 192 اور ایک SHA256 کمپریشن کی لاگت 64 ہے۔ مثالی پروگرام میں مکمل ٹیبل اور یہ تفصیل موجود ہے کہ ایک کال کیا اعلان کرتی ہے۔
پروگرام بنانا
اس کے تین طریقے ہیں، اور تینوں RV32IM ورڈ تیار کرتے ہیں:
بلٹ اِن اسمبلر۔ والیٹ میں ہاتھ سے اسمبل کیے گئے پانچ گیسٹ شامل ہیں، جنہیں یہ { "base_pc", "words" } JSON فائل میں اسمبل کرتا ہے:
rand program build --guest private_payment --arg 1000 --out pp.json # prints the program id
rand program build --guest balance_check --arg 1000 --out bc.json
# guests: fib, memcpy, bubble_sort, balance_check, private_payment, public_echo, rpl2_counter (v0.6.8); --arg is repeatable
rand-guest کے ذریعے کمپائل شدہ پروگرام۔ circuits ریپوزٹری کا rand-guest ایک no_std Rust کریٹ (riscv32im-unknown-none-elf، Rust 1.98.1) یا C ڈائریکٹری (clang 23.1.1) سے امیج کنٹینر بناتا ہے، ہر ورڈ کو مشین کے ڈی کوڈر سے جانچتا ہے، اور hc اور پروگرام آئی ڈی پرنٹ کرتا ہے۔ بلڈ بیرونی ماحول سے مکمل طور پر الگ تھلگ ہے، اس لیے ایک ہی سورس کسی بھی مشین پر ایک ہی hc دیتا ہے۔ چین 18 سے 20 کے لیے ٹول چین circuits کمٹ aeacf31 (برانچ feat/v067-circuits) پر بنائیں؛ fullnode v0.6.7 اور v0.6.8 دونوں اسی کمٹ کو پِن کرتے ہیں۔ اس کمٹ پر rand-guest check صرف سسٹم کالز 0 تا 6 کو تسلیم کرتا ہے، اس لیے جو گیسٹ guest_sdk::poseidon2_len (سسٹم کال 7) کو کال کرے وہ بلڈ کے وقت رد ہو جاتا ہے، حالانکہ مشین اسے چلا سکتی ہے (zkp-circuits ایشو #1)۔ مرحلہ وار رہنمائی: Rust پروگرام تعینات کریں اور RISC-V پروگرام تعینات کریں۔
ترجمہ شدہ پروگرام۔ sbpf2rv ایک Solana sBPF ELF کو، اور evm2rv EVM رن ٹائم بائٹ کوڈ کو، ایسے پروگراموں میں ترجمہ کرتے ہیں جن کے آؤٹ پٹ Rand کے انٹرپریٹر گیسٹس کے آؤٹ پٹ سے ورڈ بہ ورڈ مطابقت رکھتے ہیں: Solana ٹرانسپائلر اور Ethereum ٹرانسپائلر۔
والیٹ میں خود کوئی کمپائلر نہیں ہے۔ rand program deploy ایک .json فائل، لٹل اینڈین ورڈز پر مشتمل خام .bin فائل، یا rand-guest کا لکھا ہوا امیج کنٹینر قبول کرتا ہے (fullnode v0.3 اور اس کے بعد)۔
تعیناتی
rand program deploy pp.json # a bundle pays the floor; waits for the commit; prints the id
rand program show <id> # id, base_pc, words_len, code_hash, deployed_at, public_words_len, public_digest
testnet چین 20 ہے، اور اس پر تعیناتی، کال یا انووک کے لیے fullnode v0.6.8 یا اس کے بعد کا rand والیٹ درکار ہے۔ پرانا والیٹ وہاں کچھ بھی نہیں بھیج سکتا: چین 20 کا جینیسس binding_domain: 1 مقرر کرتا ہے، اس لیے ہر ثبوت کی بائنڈنگ اور ہر دستخط شدہ پیغام میں جینیسس ہیش شامل ہوتا ہے، جبکہ v0.6.7 والیٹ کی بائنڈنگز میں صرف چین آئی ڈی ہوتی ہے۔ عوامی اینڈپوائنٹ https://rpc.randprotocol.org والیٹ کی سنک، تعیناتی اور کالز کی خدمت فراہم کرتا ہے (سیٹ اپ)۔
والیٹ پہلے پروگرام آئی ڈی، ورڈز کی تعداد اور hc پرنٹ کرتا ہے اور rand_estimateFee کے ذریعے نوڈ سے فیس دریافت کرتا ہے۔ نوڈ چین کی حد سے بڑے پروگرام کو کسی بھی ثبوت سازی سے پہلے ہی رد کر دیتا ہے۔ پھر والیٹ صفر قدر کی خود کو منتقلی کا بنڈل بناتا ہے (یہ وہی واحد 4-ان-4-آؤٹ پوشیدہ اثاثہ بنڈل ہے جو ہر ٹرانزیکشن میں ہوتا ہے؛ فیس اس کے RAND سلاٹس سے ادا ہوتی ہے)۔ یہ بنڈل اپنے ہی نوٹس سے 0.001 RAND + 100,000 units × words ادا کرتا ہے (عوامی حصے کے ورڈ بھی کوڈ ورڈز میں شمار ہوتے ہیں)۔ اس کے بعد والیٹ Action::Deploy { base_pc, words, public } منسلک کرتا ہے، ٹرانزیکشن کی بائنڈنگ کے مطابق بنڈل کا ثبوت بناتا ہے اور اسے جمع کرا دیتا ہے۔ چین 17 سے اس میں دو ثبوت ہوتے ہیں، اور والیٹ ہر ایک کے لیے ایک سطر پرنٹ کرتا ہے: درجہ-10 خرچ کی اجازت (چند سیکنڈ، تقریباً 1.37 MB) اور درجہ-14 بنڈل (لیپ ٹاپ پر تقریباً دو منٹ، تقریباً 1.5 MB)۔ چین 17 سے پہلے صرف بنڈل کا ثبوت ہوتا تھا، جو چین 15 پر تقریباً 100 s لیتا تھا اور اس کا حجم تقریباً 1.42 MB تھا۔ تعیناتی فیس میں گیس یا بائٹس کا کوئی جزو نہیں: گیس صرف کالز کی قیمت طے کرتی ہے۔ نوڈ جانچتا ہے کہ ہر ورڈ ڈی کوڈ ہوتا ہے، hc شمار کرتا ہے، ریکارڈ محفوظ کرتا ہے، اور پس منظر میں تصدیق کنندہ کی کلید بنانا شروع کر دیتا ہے۔ کوڈ عوامی ہے؛ لیکن یہ عوامی نہیں کہ اس کی ادائیگی کس نے کی، کیونکہ rand_getProgram میں کوئی deployer فیلڈ نہیں ہے۔ ایک ہی ورڈز کو دو بار تعینات کرنے سے کوئی نیا اثر نہیں ہوتا؛ نتیجہ وہی رہتا ہے۔
→ {"method":"rand_getProgram","params":["675adeea…0065"]}
← { "id": "675adeea…0065", "base_pc": 0, "words_len": 42, "code_hash": "…", "deployed_at": 10,
"public_words_len": 0, "public_digest": null }
→ {"method":"rand_getProgramCode","params":["675adeea…0065"]}
← { "base_pc": 0, "words": [ … ] }
کال کرنا
rand call <program id> --input 400 --input 250 --input 300 --input 75
rand receipt <tx hash>
والیٹ نوڈ سے کوڈ اور عوامی حصہ حاصل کرتا ہے اور جانچتا ہے کہ ان کا ہیش آئی ڈی کے مطابق ہے۔ پھر کچھ بھی ثابت کرنے سے پہلے یہ کال کو ایمولیٹر میں چلاتا ہے اور گیس اور فیس پرنٹ کرتا ہے:
gas: 5636 (declaring 6144, tier 12)
fee 0.006191437 RAND (incl. two price steps of headroom)
اس کے بعد والیٹ ان پٹ ٹرانسکرپٹ کو سیل کرتا ہے (نیچے دیکھیں)۔ پھر یہ چین کے FRI پروفائل کے تحت، ان پٹس کو نجی ویکٹر کے طور پر لے کر، کال کا ثبوت مقامی طور پر بناتا ہے، فیس ادا کرنے والے بنڈل کا ثبوت بناتا ہے، جمع کراتا ہے، انتظار کرتا ہے اور رسید پرنٹ کرتا ہے۔ چین 20 پر کال کا ثبوت اس کی اپنی ٹرانزیکشن سے بندھا ہوتا ہے (ایسی بائنڈنگ جس میں جینیسس ہیش شامل ہے) اور بنڈل میں دو ثبوت ہوتے ہیں، اس لیے ایک کال میں کل تین ثبوت ہوتے ہیں: کال کا ثبوت، درجہ-10 خرچ کی اجازت اور درجہ-14 بنڈل۔ اوپر کی دونوں سطریں 2026-09-30 کو چین 18 پر گمنام ووٹ کی کال سے لی گئی ہیں (ایک گمنام ووٹ)۔
فیس۔ چین 20 پر کم از کم فیس BUNDLE_BASE + gas_price × declared gas limit + byte_price × ⌈bytes / 1024⌉ ہے، جہاں BUNDLE_BASE کی قدر 0.001 RAND ہے، بائٹس سے مراد کال کا ثبوت اور ان پٹ لفافہ ہیں، اور قیمتیں 100 اور 800 یونٹ سے شروع ہوئیں (ایک یونٹ 10⁻⁹ RAND ہے) اور بلاک کے بھرنے کے ساتھ بدلتی ہیں۔ چین 20 ان کی بالائی حد 10,000 اور 80,000 یونٹ مقرر کرتی ہے، اور اس کے بوجھ میں صرف وہی بائٹس شمار ہوتے ہیں جو بائٹ قیمت ادا کرتے ہیں (کالز کے ثبوت اور لفافے) (byte_load: "paying")؛ چین 18 اور 19 پر قیمتوں کی کوئی بالائی حد نہ تھی اور ہر ٹرانزیکشن کے بائٹس بائٹ قیمت کو متاثر کرتے تھے۔ لیجر کا یکساں 0.001 RAND + call_fee(tier) نظام، جو چین 15 کا قاعدہ تھا، وہاں لاگو نہیں ہوتا۔ والٹ فیس ثبوت کے وجود میں آنے سے پہلے طے کرتا ہے، اس لیے وہ ثبوت کی قیمت چین کی 4 MiB حد کے مطابق لگاتا ہے اور گنجائش کے لیے قیمت کے دو مراحل کا اضافہ کرتا ہے۔ چین 18 پر ناپی گئی چار کالز میں سے ہر ایک کی لاگت 0.0057 سے 0.0075 RAND رہی (حساب)۔ rand fee call <tier> --gas <limit> --bytes <B> کم از کم فیس براہِ راست نوڈ سے دریافت کرتا ہے۔ private_payment چار نجی بیلنس پڑھتا ہے اور اگر ان کا مجموعہ کم از کم اس کی حدِ مقررہ کے برابر ہو تو زائد رقم شائع کرتا ہے: آؤٹ پٹ [1, 0, 25, 0, 0, 0, 0, 0]۔ چین ثبوت، درجہ اور یہ آٹھ ورڈ دیکھتی ہے؛ بیلنس اسے کبھی نظر نہیں آتے۔
فلیگز: --tier T کوئی خاص درجہ لازم کرتا ہے؛ --gas-limit <N|max> طے شدہ قدر کے بجائے ایک قطعی گیس حد یا درجے کی بالائی حد کا اعلان کرتا ہے، اور قطعی گیس کو 2^(tier − 2) کے مضرب تک بڑھا دیا جاتا ہے؛ --fee <RAND> فیس مقرر کرتا ہے؛ --expect-public <FILE> ثبوت بنانے سے پہلے ہی انکار کر دیتا ہے، الا یہ کہ پروگرام کا عوامی حصہ اسی فائل کے ورڈز پر مشتمل ہو؛ --auditor <rand1…> ٹرانسکرپٹ کو ایک نامزد آڈیٹر کے لیے بھی سربمہر کرتا ہے؛ --print-call-key فی کال کلید پرنٹ کرتا ہے؛ --no-envelope کوئی ٹرانسکرپٹ شائع نہیں کرتا؛ --cuda GPU بیک اینڈ منتخب کرتا ہے (جس کی ہارڈویئر پر جانچ نہیں ہوئی، اور جو لفافہ سربمہر کرنے سے مطابقت نہیں رکھتا)۔ چین 20 کسی کال پر --cuda کو یکسر مسترد کر دیتی ہے: اپنی ٹرانزیکشن سے منسلک کال کا ثبوت CPU بیک اینڈ پر بنایا جاتا ہے۔
رسیدیں
ہر کمٹ شدہ کال کے لیے ایک رسید محفوظ کی جاتی ہے، اور جب کوئی نوڈ اپنی چین کو ہم وقت ساز کرتا یا اس کی تصدیق کرتا ہے تو یہ رسید دوبارہ شمار کی جاتی ہے:
→ {"method":"rand_getReceipt","params":["b082…09b0"]}
← { "tx": "b082…09b0", "program": "675adeea…0065", "tier": 14,
"outputs": [1, 0, 25, 0, 0, 0, 0, 0], "height": 105, "index": 0, "h_in": "9c0e…7f", "h_pub": null }
h_in نجی ان پٹس سے متعلق ثبوت کا سالٹ شدہ کمٹمنٹ ہے؛ بذاتِ خود یہ کچھ ظاہر نہیں کرتا۔ h_pub پروگرام کے ڈیپلائے کے وقت کے عوامی حصے کا ڈائجسٹ ہے، یعنی پروگرام کا public_digest، یا عوامی حصے کے بغیر ڈیپلائے ہونے والے پروگرام کے لیے null۔ رسید میں کوئی effect فیلڈ نہیں، اور اعلان شدہ گیس حد بھی رسید میں شامل نہیں۔ ایکسپلورر کسی call کے لیے یہی آبجیکٹ GET /transactions/:hash پر receipt کے طور پر دکھاتا ہے، کسی پروگرام کی کالز GET /programs/:id پر درج کرتا ہے، اور GET /transactions?kind=call&program=<id> کے ذریعے فلٹر کرتا ہے۔
ان پٹ لفافے: کال کو بعد میں ظاہر کرنا
بطورِ طے شدہ rand call کال کا (salt, inputs) ٹرانسکرپٹ ایک کال ان پٹ لفافے میں سربمہر کر کے شائع کرتا ہے، تاکہ ان پٹس کو دوسرے ثبوت کے بغیر بعد میں دکھایا جا سکے:
| حصہ | بائٹس | یہ کیا ہے |
|---|---|---|
body | 12 + 16 + 4·n + 16 | ایک نئی فی کال کلید K_call کے تحت salt ‖ inputs |
to_sender | 60 | کال کنندہ کی آؤٹ گوئنگ ویوئنگ کلید کے لیے لپیٹی گئی K_call |
kem_ct | 1,088 یا 0 | آڈیٹر کے لیے ML-KEM-768 انکیپسولیشن، آڈیٹر نہ ہو تو خالی |
to_auditor | 60 یا 0 | اسی انکیپسولیشن کے راز کے تحت لپیٹی گئی K_call |
باڈی کا منسلکہ ڈیٹا H_IN ہے، اس لیے اگر کسی لفافے کو اٹھا کر کسی دوسری کال پر رکھ دیا جائے تو وہ کسی کے لیے نہیں کھلتا۔ چین صرف اس کا سائز جانچتی ہے (زیادہ سے زیادہ max_call_envelope_bytes: چین 20 پر 65,536 بائٹس، اور اس فیلڈ کے بغیر جینیسس پر 18,432) اور اسے rand_getCallEnvelope(tx) کے ذریعے بعینہٖ فراہم کرتی ہے۔ اسے تین کلیدیں کھولتی ہیں، اس سے زیادہ کوئی نہیں: کال کنندہ کی ویوئنگ کلید (اس والٹ کی ہر کال)، فی کال کلید (صرف وہی ایک کال)، اور آڈیٹر کی ویوئنگ کلید (صرف وہی ایک کال)۔
rand open-call <txhash> # as the caller
rand open-call <txhash> --as-auditor # as the auditor
rand open-call <txhash> --call-key <hex> # with the per-call key alone
open-call ٹرانسکرپٹ کھولتا ہے، input_digest(salt, inputs) == H_IN کی جانچ کرتا ہے، بازیافت شدہ ان پٹس پر ایمولیٹر کے ذریعے پروگرام دوبارہ چلاتا ہے، آؤٹ پٹس کا رسید کے آؤٹ پٹس سے موازنہ کرتا ہے — اور اگر دونوں میں سے کوئی جانچ ناکام ہو تو غیر صفر کوڈ کے ساتھ ختم ہوتا ہے، تاکہ کوئی اسکرپٹ انتباہ کو اثبات نہ سمجھ بیٹھے۔ --no-envelope ناقابلِ واپسی ہے: سالٹ ضائع ہو جانے کے بعد کوئی بھی، بشمول کال کنندہ، اس کال کو نہیں کھول سکتا۔
v0.6.8 سے پروگرام کو دوبارہ اسی عوامی حصے پر چلایا جاتا ہے جس پر ثبوت بنایا گیا تھا: پروگرام کے ڈیپلائے کے وقت کے عوامی ورڈز اور، hardening_v6 کے تحت، ان کے بعد آٹھ ورڈ کا کال بائنڈنگ (fullnode issue #116)۔ v0.6.7 میں open-call صرف عوامی حصے کے بغیر ڈیپلائے ہونے والے پروگرام کے لیے کام کرتا تھا؛ عوامی حصے والے پروگرام کے لیے یہ ان پٹس پرنٹ کرتا اور پھر re-running the program on these inputs failed: PublicIndex(0) کے ساتھ رک جاتا، اور کوئی بھی جانچ کیے بغیر غیر صفر کوڈ کے ساتھ ختم ہو جاتا۔
پروگرام اسٹیٹ (RPL-2)
چین 20 پہلی چین ہے جس میں RPL-2 موجود ہے، جسے اس کے جینیسس کا program_state حصہ فعال کرتا ہے۔ پروگرام کو تین ایسی چیزیں ملتی ہیں جو پہلے اس کے پاس نہیں تھیں (fullnode docs/program-state.md، v0.6.8 پر crates/randprotocol-core/src/ledger/program_state.rs):
| خانے | ہر پروگرام کے لیے 8 ورڈ کی کلید سے 8 ورڈ کی قدر تک ایک نقشہ۔ غیر موجود خانہ آٹھ صفر کے طور پر پڑھا جاتا ہے؛ آٹھ صفر لکھنے سے خانہ حذف ہو جاتا ہے۔ اسٹیٹ روٹ میں کمٹ ہوتے ہیں |
| ایک تجوری | ہر اثاثے کے لیے ایک عوامی بیلنس (0 سے مراد RAND ہے)۔ قدر کسی انووک کے بنڈل کے ذریعے داخل ہوتی ہے اور چین کے شمار کردہ نوٹس کی صورت میں نکلتی ہے |
| اپنا ٹوکن | rand token create --program <id> کے ذریعے رجسٹر کیا گیا ٹوکن (اجرا کا اختیار Program(id)، کوئی ابتدائی رسد نہیں) صرف اسی پروگرام کے انووکس کے ذریعے جاری اور تلف ہوتا ہے |
خانے اور تجوری کے بیلنس کسی ٹوکن کی رسد کی طرح عوامی ہیں۔ ان میں سے کوئی چیز نوٹ نہیں۔
Invoke (Action 33) ایسی کال ہے جو ایک تبدیلی کا اعلان بھی کرتی ہے، اور اس کا کال ثبوت یہ دکھاتا ہے کہ پروگرام بالکل یہی تبدیلی قبول کرتا ہے:
Invoke { program, proof, input_envelope, transition }
Transition { reads: [{ key, value }] // cells read, with the values read; keys strictly ascending
writes: [{ key, value }] // cells written; keys strictly ascending
inflow: none | deposit | burn
pays: [{ asset, amount, recipient, r, envelope }] // notes out of the vault
mints: [{ asset, amount, recipient, r, envelope }] } // new units of the program's own token
جو اندر آتا ہے وہ وہی ہے جو بنڈل تلف کرتا ہے: burn_r تجوری میں جمع کیا گیا RAND ہے؛ burn_asset کا burn_a ایسا ٹوکن ہے جو جمع کیا جاتا ہے (آمد deposit) یا تلف کیا جاتا ہے (آمد burn، صرف پروگرام کا اپنا ٹوکن)۔ جو باہر جاتا ہے وہ ہر ادائیگی کے لیے چین کا شمار کردہ ایک نوٹ ہے، پہلے ادائیگیاں پھر اجرا، جن میں رقم اور وصول کنندہ کا pk عوامی ہوتے ہیں، جیسے اجرا میں ہوتے ہیں۔ لیجر یہ تبدیلی صرف اس صورت میں لاگو کرتا ہے کہ پروگرام موجود ہو، ساخت جائز ہو، reads کا ہر خانہ اب بھی اعلان شدہ قدر رکھتا ہو، تجوری (اسی ٹرانزیکشن کی اپنی جمع شدہ رقم کے بعد) ہر ادائیگی پوری کرتی ہو، ہر اجرا پروگرام کے اپنے ٹوکن کا ہو، اور ثبوتوں کی تصدیق ہو جائے۔ جو قراءت اب مطابقت نہیں رکھتی اسے StaleRead کے طور پر مسترد کر دیا جاتا ہے؛ والٹ دوبارہ پڑھتا ہے اور نیا ثبوت بناتا ہے۔
انووک کال سے کیسے مختلف ہے۔
Call (RPL-1) | Invoke (RPL-2) | |
|---|---|---|
| وہ عوامی حصہ جس پر ثبوت بنایا جاتا ہے | public ‖ call_binding | public ‖ call_binding ‖ context، یعنی ورڈز کی صورت میں تبدیلی |
| کامیابی پر چین کیا کرتی ہے | رسید محفوظ کرتی ہے؛ آؤٹ پٹس محض ڈیٹا ہیں | رسید محفوظ کرتی ہے اور تبدیلی لاگو کرتی ہے: خانے لکھتی ہے، تجوری میں رد و بدل کرتی ہے، ادائیگی کے نوٹس شامل کرتی ہے |
| قدر | صرف بنڈل کی اپنی منتقلی | بنڈل کے تلف کے ذریعے تجوری میں جمع؛ ادائیگیاں اور اجرا اسی میں سے |
| اسٹیٹ پر انحصار | نہیں | ثبوت کا نہیں (حصہ ٹرانزیکشن سے بنتا ہے)، لیکن قراءت کی جانچ کا ہے، داخلے کے وقت بھی اور پول میں بھی |
| فیس | کال کی کم از کم فیس | کال کی کم از کم فیس جمع ہر نئے بنائے گئے خانے پر cell_fee |
پروگرام سیاق کا ورڈ i READ_PUBLIC(public_len + 8 + i) کے ذریعے پڑھتا ہے۔ ورڈ 0 ورژن (1) ہے، ورڈ 1 تا 4 قراءتوں، تحریروں، ادائیگیوں اور اجرا کی تعداد، پھر burn_r، آمد کی قسم، burn_asset اور burn_a، پھر ہر قراءت اور تحریر بطور کلید اور قدر (ہر ایک 8 ورڈ)، پھر ہر ادائیگی بطور اثاثہ اور رقم۔ وصول کنندگان سیاق میں شامل نہیں: رقوم پروگرام طے کرتا ہے، اور ادائیگی کسے ہو یہ بائنڈنگ طے کرتی ہے۔ پروگرام کے لیے لازم ہے کہ اسے دکھائے گئے ہر سیاقی ورڈ پر قید عائد کرے، اور اس میں کوئی پینک والا راستہ نہ ہو، کیونکہ guest-sdk کا پینک ہینڈلر رن کو روک دیتا ہے اور رکا ہوا رن بھی قابلِ ثبوت رن ہے۔
چین 20 کی حدود (rand_getLimits.program_state):
| حد | چین 20 |
|---|---|
cell_fee | 10,000,000 یونٹ، یعنی 0.01 RAND، ہر نئے بنائے گئے خانے پر (ایسا خانہ جس میں غیر صفر قدر لکھی جائے جہاں پہلے کچھ محفوظ نہ تھا)؛ کسی خانے کو دوبارہ لکھنا یا حذف کرنا مفت ہے |
max_reads | 8 خانے |
max_writes | 8 خانے |
max_payouts | 4 نوٹس، ادائیگیاں اور اجرا ملا کر |
حصے کا قاعدہ عموماً زیادہ سخت ہوتا ہے: پورا حصہ اس عوامی جدول میں سمانا چاہیے جس پر اسی پروگرام کی کال کا ثبوت بنایا جاتا ہے، جو عوامی ان پٹ کے بغیر پروگرام کے لیے 127 ورڈ ہے۔ اس سے 119 سیاقی ورڈ بچتے ہیں، مثلاً تین قراءتیں، تین تحریریں اور چار ادائیگیاں۔
کمانڈز اور RPC (والٹ v0.6.8):
rand program build --guest rpl2_counter --out counter.json # one cell, incremented by one per invoke
rand program invoke <id> --transition step.json [--input N | --inputs-file F.json]
rand program state <id> [--cell <64 hex>] # rand_getProgramCell / rand_getProgramCells
rand program vault <id> # rand_getProgramVault
program invoke ثبوت بنانے سے پہلے reads کے ہر اندراج کو موجودہ خانے سے جانچتا ہے، اور فرسودہ قراءت پر، خواہ ثبوت بنانے سے پہلے ہو یا شمولیت کے وقت، کوڈ 3 کے ساتھ ختم ہوتا ہے، تاکہ اسکرپٹ دوبارہ پڑھ کر پھر کوشش کرے۔ "kind": "invoke" کے ساتھ rand_estimateFee فیس کا تخمینہ دیتا ہے۔ تبدیلی کی فائل کا فارمیٹ fullnode کی docs/cli.md میں درج ہے۔ چین 20 پر ڈیپلائے کیے گئے مکمل RPL-2 پروگرام (amm، stableswap، orderbook، stablecoin، lending، perp، crowdfund، stoploss)، اور RPL-1 پروگرام (sealed-auction، ballot، eligibility، private-join، credit-score)، randprotocol/example-programs میں موجود ہیں۔
کیا عوامی ہے اور کیا پوشیدہ
| عوامی | پوشیدہ |
|---|---|
پروگرام کی شناخت اور اس کا کوڈ؛ درجہ؛ اعلان کردہ گیس کی حد؛ آٹھ آؤٹ پٹس؛ H_IN؛ بنڈل کی فیس اور عوامی فیلڈز؛ لفافے کا حجم؛ کال میں Keccak استعمال ہوا یا SHA-256، اور تقریباً کتنی بار (ثبوت کا ہیڈر ہر ہیش جدول کی اونچائی ظاہر کرتا ہے) | نجی ان پٹس؛ رجسٹر، میموری، برانچز؛ سائیکلوں کی اصل تعداد اور گیس کی ٹھیک مقدار؛ H_IN کا سالٹ؛ کال کس نے کی اور ادائیگی کس چیز سے کی |
ایک ہی رن کے دو ثبوت مختلف بائٹس پر مشتمل ہوتے ہیں۔ چین 15 اور اس سے پہلے یہ کافی نہیں تھا: 31 یا اس سے کم نجی ورڈز والی کال ایک ایسا جدول ثابت کرتی تھی جو چھپانے کے لیے بہت چھوٹا تھا، اور اس کے ان پٹس ثبوت سے بازیافت کیے جا سکتے تھے۔ v0.6 سے ثابت کنندہ ان جدولوں کو کم از کم 128 قطاروں تک رکھتا ہے، اور قیود کا مجموعہ 7 (چین 16 اور بعد کی چینز) فی جدول ان مجموعی اعداد کو بھی چھپاتا ہے جو اب تک افشا ہو رہے تھے۔ hc پابند کرتا ہے مگر چھپاتا نہیں: جو کوئی بھی ممکنہ پروگراموں کی فہرست بنا سکے وہ تصدیق کر سکتا ہے کہ ان میں سے کون سا ڈیپلائے کیا گیا تھا۔
جو ابھی ممکن نہیں
جیسا کہ فل نوڈ بیان کرتا ہے:
- پروگراموں کے درمیان کوئی کال نہیں، اور RPL-2 کے باہر کوئی اسٹیٹ نہیں۔ ایک
Callایک رن پر ایک ثبوت ہے؛ ایک کال سے دوسری کال تک کچھ منتقل نہیں ہوتا سوائے اس کے جو کال کرنے والا خود دوبارہ فراہم کرے۔ چین 20 پر ایکInvokeپروگرام کے اپنے سیلز اور والٹ کو پڑھتا اور لکھتا ہے (اوپر)؛ چین 20 سے پہلے کسی چین میں پروگرام اسٹیٹ نہیں ہے، اور ایک invoke کسی دوسرے پروگرام کے سیلز کو نہیں چھو سکتا۔ - والٹ کے باہر پروگرام کے ذریعے کوئی منتقلی نہیں۔ اثر کی قسم 1، یعنی پروگرام کی جانب سے کسی اکاؤنٹ کو ادا کی گئی منتقلی، اکاؤنٹس کے ساتھ ہی حذف کر دی گئی، اور ایک
Callکے آؤٹ پٹس محض بیانات ہیں۔ چین 20 پر ایکInvokeپروگرام کے اپنے والٹ سے ادائیگی کرتا ہے، زیادہ سے زیادہ چار نوٹس، جن کی رقوم اور وصول کنندگان عوامی ہوتے ہیں۔ - والٹ میں کوئی کمپائلر نہیں۔ پروگرام یا تو پہلے سے شامل اسمبل شدہ گیسٹس ہیں، یا circuits ریپوزٹری میں
rand-guestسے بنائی گئی امیجز۔ - عوامی ان پٹ ڈیپلائے کے وقت طے ہوتا ہے، ہر کال کے لیے نہیں۔ قیود کے مجموعہ 6 نے
READ_PUBLICاورH_PUBشامل کیے۔ چین 20 پر ایک ڈیپلائے زیادہ سے زیادہ 32,768 عوامی ورڈز لے جا سکتا ہے، پروگرام کی شناخت انہیں پابند کرتی ہے، اور ہر کال کے ثبوت کی جانچ ان کے ڈائجسٹ کے مقابل کی جاتی ہے۔ فی کال کوئی عوامی ورڈز نہیں ہیں۔ - ہیش سسکالز بڑے ثبوت بناتے ہیں۔ Keccak پر مشتمل ثبوت تقریباً 3.2 MB کا ہوتا ہے، جو 2 MiB کی طے شدہ ثبوت کی حد سے صاف طور پر زیادہ ہے؛ sha256 پر مشتمل ثبوت میں تقریباً 400 KB کا اضافہ ہوتا ہے۔ چین 20 کی حد 4,194,304 بائٹس ہے (4 MiB، جیسا کہ چین 17 سے 19 پر؛ چین 13 سے 16 پر یہ 8 MiB تھی)، جو دونوں کو قبول کرتی ہے: چین 18 پر Keccak جدول کے ساتھ درجہ 12 کی ایک کال 3.35 MB اور SHA-256 جدول کے ساتھ درجہ 14 کی ایک کال 1.91 MB ناپی گئی (مثالی پروگرام)۔ ایک کال 128 Keccak-f پرمیوٹیشنز اور 128 SHA-256 کمپریشنز تک بھی محدود ہے (نیچے)، اور ثبوت کے ہر KiB پر بائٹ کی قیمت کے حساب سے فیس لی جاتی ہے۔
- EVM اور Solana پروگرام چین 20 پر ڈیپلائے نہیں ہوتے، اور ان کی کالز کال کے درجے کی حد سے اوپر ہیں۔ انٹرپریٹر گیسٹس (
evm.bin، 18,009 ورڈز؛sbpf.bin، 8,317) اور ترجمہ شدہ امیجز (ERC-20، 11,686 ورڈز؛ SPL Token، 65,096) 4,096 ورڈز کی طے شدہ حد سے اوپر اور 65,535 کی اس حد سے نیچے ہیں جو چین 13 نے مقرر کی اور اس کے بعد ہر چین نے برقرار رکھی۔ دونوں ترجمہ شدہ امیجز 2026-09-19 کو چین 13 پر ڈیپلائے کی گئیں، SPL Token اپنے ELF کو عوامی ان پٹ کے طور پر لے کر۔ چین 14 اور 15 نئے سرے سے شروع کی گئیں، اور ان میں سے کسی پر بھی کوئی امیج دوبارہ ڈیپلائے نہیں کی گئی۔ چین 20، چین 19 کی طرح، ان چاروں میں سے کسی کو بھی ڈیپلائے کرنے سے انکار کرتی ہے: اس کےhardening_v6قاعدے کے تحت ایسا پروگرام جسے درجہ 14 کی کوئی کال سما نہ سکے، یعنی عوامی سیگمنٹ کے بغیر 8,180 سے زیادہ ورڈز اور عوامی سیگمنٹ کے ساتھ اس سے کم، ڈیپلائے کے وقت مسترد کر دیا جاتا ہے (ProgramUncallable)، تاکہ کسی ایسے پروگرام کے لیے ڈیپلائے فیس ادا نہ ہو جسے کوئی کال نہ کر سکے۔ ERC-20 کی کال درجہ 16 یا 18 پر ثابت ہوتی ہے: درجہ 16 کاapproveچین 13 پر 2026-09-19 کو 3,412,405 بائٹس کے پروڈکشن ثبوت کے ساتھ کال کیا گیا (Ethereum ٹرانسپائلر)، اور چین 20 درجہ 14 سے اوپر کی ہر کال مسترد کرتی ہے (اگلا نکتہ)، لہٰذا آج وہاں ERC-20 کی کوئی کال قابلِ قبول نہیں۔ SPL Token کی کالز درجہ 20 کی ہیں، جن کے لیے تقریباً 330 GB درکار ہیں؛ SPL کی کسی کال کا کوئی ثبوت موجود نہیں (ثبوت سازی کی میموری)۔ EVM کے بلاک سیاق کے آپ کوڈز ٹریپ کرتے ہیں، اور آن چین کوئی EVM اسٹیٹ نہیں ہے۔ - ایک کال درجہ 14 یا اس سے نیچے ثابت ہوتی ہے۔ فل نوڈ v0.5.6 (2026-09-25) سے درجہ 14 سے اوپر کی کال کا ثبوت مسترد کر دیا جاتا ہے (
CallTierTooHigh)، اور اسی طرح وہ ثبوت بھی جس میں 128 سے زیادہ Keccak-f پرمیوٹیشنز یا 128 SHA-256 کمپریشنز ہوں۔ چین 13 کا درجہ 16 والا ERC-20approveچین 20 پر مسترد ہو جاتا، جیسا کہ چین 15، 18 اور 19 پر ہوتا، اور اسی طرح درجہ 18 کی ہر ERC-20 کال یا درجہ 20 کی ہر SPL Token کال بھی؛ یہ اب بھی آف چین ثابت ہوتی ہیں (بجٹ)۔ - GPU پر ثبوت سازی کبھی ہارڈویئر پر نہیں چلی۔
--cudaکے لیے--features cudaوالا بلڈ اور کمٹ شدہ PTX درکار ہیں؛ فلیٹ پر ان میں سے کوئی بھی موجود نہیں۔ چین 20 پر کال کا ثبوت بلڈ خواہ کچھ بھی ہو، CPU بیک اینڈ پر بنتا ہے۔ hcچھپاتا نہیں، جیسا کہ اوپر بیان ہوا، اور وٹنس کی درخواست اب بھی نوڈ کو بتا دیتی ہے کہ والٹ کون سی لیف خرچ کر رہا ہے۔