Rand Protocol
مستندات
راهنماها

اثبات‌ها

کیف پول چگونه یک اثبات بسته (bundle) تولید می‌کند، این کار چه هزینه‌ای از نظر زمان و بایت دارد، یک node چگونه آن را راستی‌آزمایی می‌کند، مجموعه قیود (constraint set) چیست و چرا تغییر آن یک هاردفورک است - و تجمیع بلوکی، تغییر پیش‌رو در نحوهٔ رسیدن اثبات‌ها به بلوک.

از این صفحه برای اندازه‌گیری ماشین اثبات‌دهی استفاده کنید، برای فهمیدن اینکه چرا یک انتقال بیش از یک دقیقه طول می‌کشد و چرا توان عبوری را فضای بلوک محدود می‌کند و نه توان محاسباتی، و برای دانستن اینکه با تغییر سامانهٔ اثبات چه چیزی از کار می‌افتد. هر چیزی که یک اعتبارسنج می‌پذیرد، پشتوانه‌اش اثباتی است که خودش راستی‌آزمایی کرده است.

یک اثبات چه چیزی را بیان می‌کند

یک رابطه، برای هر برنامه‌ای که زنجیره اجرا می‌کند:

این برنامهٔ RV32IM که از base_pc آغاز شده، روی یک بردار ورودی خصوصی که H_IN به آن متعهد است و یک قطعهٔ ورودی عمومی که H_PUB به آن متعهد است اجرا شده، ظرف 2ᵗ − 1 چرخه متوقف شده، حداکثر GAS_LIMIT گس مصرف کرده و این هشت کلمهٔ خروجی را منتشر کرده است.

برنامه با چکیدهٔ درون‌مداری‌اش hc شناسایی می‌شود؛ تأییدکننده هرگز یک کلمهٔ دستورالعمل را نمی‌بیند. یک انتقال محافظت‌شده همین رابطه است که بر guest بستهٔ دارایی پنهان اعمال می‌شود، برنامه‌ای ۴ورودی-۴خروجی که با دست اسمبل شده و hc آن در فایل genesis با نام hc_bundle ثابت شده است. زنجیرهٔ 20 نسخهٔ v3 این guest را ثابت می‌کند (guests::bundle_hidden_v3، 60af094a…6e3fce، از زنجیرهٔ 17). زنجیره‌های 14 و 15 نسخهٔ v1 (83d3a370…cd0ef8) و زنجیرهٔ 16 نسخهٔ v2 بدون انشعاب (651043e2…839b) را ثابت کرده بودند. از زنجیرهٔ 17، هر بسته اثبات دومی هم دارد، از guest احراز مجوز (guests::auth، hc_auth در genesis، 1e4e347f…5639c1): اثبات بسته کلید مشاهده را می‌گیرد و اثبات احراز مجوز نشان می‌دهد که فرستنده کلید خرج پشت آن را در اختیار دارد. این همان مجوزدهی تفکیک‌شده است و کاری می‌کند که یک اثبات‌کنندهٔ جفت‌شده که فقط کلید مشاهده دارد بتواند اثبات بسته را بسازد. guest دارایی پنهان جایگزین guest bundle دو‌ورودی-دو‌خروجی زنجیره‌های تا 13 شد که فقط برای آزمون‌ها در fullnode باقی مانده و هیچ زنجیره‌ای آن را ثابت نمی‌کند. یک فراخوانی محرمانه همین رابطه است که بر یک برنامهٔ مستقرشده اعمال می‌شود (برنامه‌ها).

کیف پول چگونه یک بسته را اثبات می‌کند

rand send <rand1…> <amount> کار خصوصی را به‌صورت محلی انجام می‌دهد و فقط اثبات‌ها، تعهدها، nullifierها و پاکت‌های مهروموم‌شده به زنجیره می‌رسند:

  1. پویش درخت با کلید مشاهده و انتخاب ورودی‌ها: حداکثر دو یادداشت RAND که مبلغ به‌علاوهٔ کارمزد را در شکاف‌های 2 تا 3 پوشش دهند، و برای انتقال یا سوزاندن توکن، حداکثر دو یادداشت از آن توکن در شکاف‌های 0 تا 1 که یادداشت‌های RAND تنها کارمزد را پوشش می‌دهند. شکاف ورودیِ استفاده‌نشده یک ساختگی است: مبلغ 0، متعلق به کیف پول، شکست عضویتش در مدار پوشانده می‌شود و nullifier همچنان منتشر می‌شود. از guest نسخهٔ v2، guest بدون انشعاب است: مسیر یک ساختگی هم مانند یک یادداشت واقعی در هر 32 سطح هش می‌شود.
  2. دریافت لنگر سر (rand_getAnchor) و شاهد مرکل 32‌سطحی هر ورودی واقعی (rand_getWitness(index))، با بررسی ریشهٔ بازگشتی در برابر لنگر.
  3. ساخت چهار خروجی: یادداشت گیرنده و یادداشت باقی‌مانده در گروهی که ارزش را جابه‌جا می‌کند، حتی با مقدار صفر، و ساختگی‌های با مبلغ صفر در جاهای دیگر، که به یک کلید یک‌بارمصرف مهر می‌شوند.
  4. مهر کردن هر خروجی در یک پاکت (ML-KEM-768 برای گیرنده، به‌علاوهٔ کلید تراکنش که زیر ovk کیف پول بسته شده)، سرهم کردن کل تراکنش با کنش آن، و محاسبهٔ binding آن: blake3("rand-tx-bind-1" || …) روی تراکنش با اثبات‌های تهی‌شده، هشت کلمه (تراکنش‌ها). در زنجیرهٔ 20 که genesis آن binding_domain: 1 را تنظیم می‌کند، این مقدار blake3("rand-tx-bind-2" || …) است که هش genesis و سپس شناسهٔ زنجیره در ابتدای آن می‌آیند، تا اثباتی که برای یک زنجیره ساخته شده روی هیچ زنجیرهٔ دیگری، حتی با همان شناسهٔ زنجیره، راستی‌آزمایی نشود. کیف پولی قدیمی‌تر از v0.6.8 binding قدیمی را به کار می‌برد و زنجیرهٔ 20 اثبات‌هایش را رد می‌کند.
  5. مجوزدهی: یک نمک 256‌بیتی تازه بکشید و guest احراز مجوز را روی ورودی خصوصی 16‌کلمه‌ای‌اش، یعنی کلید خرج و نمک، با binding به‌عنوان قطعهٔ ورودی عمومی، در سطح 10 اثبات کنید. این guest nk را از کلید خرج مشتق می‌کند و c = H(AUTH, nk ‖ salt) را منتشر می‌کند که بسته آن را به‌صورت auth_commit حمل می‌کند.
  6. اثبات guest بسته روی ورودی خصوصی 1,212‌کلمه‌ای‌اش (کلید مشاهده nk، چهار شکاف ورودی با مسیرهایشان، لنگر، چهار خروجی، fee، burn_a، burn_r، دارایی خصوصی A، time، نمک) با همان binding به‌عنوان قطعهٔ ورودی عمومی، در سطح 14. اثبات مالکیت، عضویت، اینکه هر ورودی واقعی دارایی شکاف خود را حمل می‌کند، چهار nullifier، همان c و دو توازن in₀ + in₁ = out₀ + out₁ + burn_a و in₂ + in₃ = out₂ + out₃ + fee + burn_r را نشان می‌دهد. این اثباتی است که یک اثبات‌کنندهٔ جفت‌شده می‌تواند به‌جای کیف پول بسازد؛ اثبات احراز مجوز روی ماشین خود کیف پول ساخته می‌شود.
  7. بررسی چکیدهٔ منتشرشدهٔ اثبات در برابر چکیده‌ای که از متن آشکار محاسبه شده، و ارسال Transaction { chain_id, bundle, action: None }.

از زنجیرهٔ 14 ترتیب اهمیت دارد: پاکت‌ها و کنش پیش از اثبات‌ها وجود دارند، چون اثبات‌ها به آن‌ها متعهد می‌شوند. برای یک فراخوانی، اثبات فراخوانی ابتدا ساخته می‌شود و آن هم درون binding قرار می‌گیرد. در زنجیرهٔ hardening_v6، اثبات فراخوانی خودش روی یک binding فراخوانی ساخته می‌شود، شامل تراکنش با هر دو اثبات تهی‌شده (rand-call-bind-1 در زنجیره‌های 16 تا 19، rand-call-bind-2 با هش genesis در زنجیرهٔ 20)، که nullifierهای بستهٔ کارمزد را در بر می‌گیرد و در نتیجه نمی‌توان آن را زیر بستهٔ دیگری کپی کرد.

proving bundle (tier 14; about a minute on a laptop)…
proved in 98.3s: tier 14, 1423170 bytes
submitted transfer 4f2c…  1.5 RAND out, 98.499 RAND change, fee 0.001 RAND, anchored at height 192

این گزارش، قالب خروجی کیف پول از راهنمای fullnode تا زنجیرهٔ 14 است؛ اندازهٔ بایت نمایش‌داده‌شده مربوط به اثبات بستهٔ با پروفایل تولیدی است که روی زنجیرهٔ 14 ثبت شد. کیف پول از زنجیرهٔ 17 به بعد، از جمله v0.6.8 روی زنجیرهٔ 20، پیش از این خطوط دو خط چاپ می‌کند، proving the spend authorisation on this machine (tier 10; seconds)… و authorisation proved in …: tier 10, … bytes، و خط بسته را به‌صورت proving the bundle (tier 14; about a minute and a half on a laptop)… می‌نویسد.

همین سازوکار هزینهٔ هر کنشی را می‌پردازد، همیشه با دقیقاً یک بسته: یک استقرار، یک فراخوانی، یک ثبت توکن یا یک ضرب توکن بر یک خودانتقال با ارزش صفر از RAND سوار می‌شود، یک سپرده‌گذاری (bond) بر بسته‌ای که سهم را از طریق burn_r می‌سوزاند، و یک سوزاندن توکن یا سوزاندن پل بر یک بسته که دارایی را از شکاف‌های 0 تا 1 می‌سوزاند (burn_a، burn_asset) و کارمزد RAND را از شکاف‌های 2 تا 3 می‌پردازد. دارایی‌ای که یک انتقال جابه‌جا می‌کند یک کلمهٔ شاهد است و در هیچ فیلد عمومی‌ای نیست.

هزینه چقدر است

اندازه‌گیری‌شده روی لپ‌تاپ توسعه (Apple Silicon، ساخت release)، اعدادی که اسناد خود fullnode ثبت کرده‌اند:

guestکلمه‌هاچرخه‌هاسطحاثباتاندازهٔ اثبات (تولیدی، 80 پرس‌وجو)
bundle guest v3 (زنجیره‌های 17 تا 20)—4,024 چرخه و 273 جایگشت Poseidon2 فضای باقی‌مانده در بودجهٔ سطح 1414≈ 100 s، اوج 5.7 GB؛ 102.5 تا 134.0 s اندازه‌گیری‌شده روی زنجیرهٔ 18 (2026-09-30)≈ 1.50 MB؛ 1,494,151 تا 1,504,260 بایت اندازه‌گیری‌شده روی زنجیرهٔ 18 (2026-09-30)
auth guest (زنجیره‌های 17 تا 20)—25010≈ 7 s؛ 6.6 تا 19.9 s اندازه‌گیری‌شده روی زنجیرهٔ 18 (2026-09-30)≈ 1.37 MB؛ 1,364,940 تا 1,375,371 بایت اندازه‌گیری‌شده روی زنجیرهٔ 18 (2026-09-30)
hidden-asset bundle v1، ۴ورودی-۴خروجی (زنجیره‌های 14 و 15)—زیر بودجهٔ سطح 14 با حدود 2,071 چرخه (13%) باقی‌مانده14≈ 98–100 s، اوج 5.7 GB≈ 1.43 MB؛ 1,422,116 و 1,423,170 بایت اندازه‌گیری‌شده روی زنجیرهٔ 14
bundle، ۲ورودی-۲خروجی (بازنشسته؛ زنجیره‌های تا 13)3,811≈ 9,16014≈ 100 s (94.6–97.9 s به‌تنهایی؛ 114 s برای هر یک وقتی دو تا هم‌زمان)1,321,773 بایت اندازه‌گیری‌شده روی زنجیرهٔ 8
private_payment (یک فراخوانی)اندک< 1,00010≈ 7 s≈ 1.37 MB (fib در سطح 10: 1,367,688 بایت زیر مجموعهٔ قیود 7؛ 1,298,729 زیر مجموعهٔ 6)
یک فراخوانی بدون جدول هش (دفتر کل بیرون‌زنجیره، زنجیرهٔ 18)773—14114.8 s1,498,589 بایت
یک فراخوانی با جدول SHA-256 (اثبات بدهی‌ها، زنجیرهٔ 18)994—14122.9 s1,911,152 بایت
یک فراخوانی با جدول Keccak (رأی ناشناس، زنجیرهٔ 18)——1229.2 s3,346,865 بایت

راستی‌آزمایی همان هزینهٔ اجماع است که هر گره می‌پردازد: حدود 16 ms با کلید تأییدکنندهٔ گرم، و حدود 230 ms نخستین باری که کلیدی برای یک شکل مشخص ساخته می‌شود. کلید تأییدکننده به محتوای برنامه بستگی ندارد — کلید آن (tier, program_log_height, input_log_height, keccak_log_height, sha256_log_height, public_log_height) است — پس هر گره یک کلید برای هر شکل می‌سازد و دوباره به کار می‌برد؛ برای یک برنامهٔ مستقرشده، کلید یک بار در پس‌زمینه هنگام استقرار محاسبه می‌شود (حدود 2 s روی یک لپ‌تاپ، 7 s روی یک سرور 2‌vCPU). بستهٔ ۲ورودی-۲خروجی زنجیرهٔ 13 و پیش از آن شکل program 12, input 10, keccak 0, sha256 0, public 2, mem 16 را اعلام می‌کرد؛ اثبات بستهٔ زنجیرهٔ 14 مقدار public 4 را اعلام می‌کند، ارتفاع هشت کلمهٔ binding، هیچ‌یک از دو جدول هش را حمل نمی‌کند، و اگر سطح دیگری، هر یک از دو جدول یا ارتفاع عمومی دیگری اعلام کند، پیش از ساخته شدن هر کلید تأییدکننده‌ای رد می‌شود. از مجموعهٔ قیود 7، هر جدول اعلام‌شده دست‌کم 2⁷ ردیف دارد، پس اثبات بستهٔ زنجیرهٔ 20 مقدار public 7 را اعلام می‌کند.

روی زنجیرهٔ 20، یک تراکنش انتقال حدود 2.87 MB اثبات حمل می‌کند، یعنی اثبات بسته (bundle) و اثبات احراز هویت (auth)، و یک فراخوانی اثبات سومی هم به آن اضافه می‌کند. هر کدام باید در max_proof_bytes مقرر در genesis جا شود. این مقدار روی زنجیرهٔ 20 برابر 4,194,304 (4 MiB) است، همان‌طور که روی زنجیره‌های 17 تا 19 بود، و روی زنجیره‌های 13 تا 16 از 8 MiB کاهش یافته است.

guest مربوط به دارایی پنهان فقط به این دلیل در لایهٔ 14 جا می‌شود که ورودی‌های خصوصی‌اش را در یک حلقه می‌خواند و خواندن‌های همسایه در بررسی Merkle را در هم ادغام می‌کند. اگر به سبک قدیمی‌تر بازشده (unrolled) نوشته شود، همین رابطه در لایهٔ 16 قرار می‌گیرد، با حدود 400 s و 21–22 GB، که کیف‌پول‌های 16 GB را کنار می‌گذارد.

اثبات‌سازی به CPU وابسته است و کیف‌پول امروز روی همهٔ پلتفرم‌ها از backend مبتنی بر CPU استفاده می‌کند. در اجراهای لایه‌های بزرگ، اثبات‌کننده تک‌نخی بود. یک droplet با 16 vCPU روی 99% از یک هسته کار می‌کرد، و حافظه، نه تعداد هسته‌ها، تعیین می‌کرد که اثبات به پایان برسد یا نه (حافظهٔ اثبات‌سازی). پرچم --cuda روی send، bond، call، deploy، bridge-mint و bridge-burn یک backend انویدیا را انتخاب می‌کند که به build با --features cuda نیاز دارد. kernelهای آن برای نخستین بار در تاریخ 2026-09-28 روی سخت‌افزار واقعی، یک NVIDIA H100، اجرا شدند و با مرجع CPU مطابقت داشتند، اما هیچ PTX‌ای در checkout مربوط به circuits که انتشار آن را vendor می‌کند commit نشده است، بنابراین build تا زمانی که kernelها کامپایل نشوند با no PTX for the GPU kernels شکست می‌خورد. هیچ اثبات تولیدی‌ای روی یک گره GPU از ناوگان اندازه‌گیری نشده است. عمداً هیچ بازگشتی (fallback) به CPU وجود ندارد. یک فراخوانی CUDA همچنین نمی‌تواند پاکت ورودی (input envelope) را مهروموم کند، زیرا salt هرگز از اثبات‌کننده خارج نمی‌شود. اوج حافظه برای اثبات بستهٔ دارایی پنهان در لایهٔ 14 حدود 5.7 GB است (Production FRI، CPU)؛ ردههای حافظهٔ بزرگ‌تر به اثبات‌های مفسر و بازگشتی در ادامه مربوط‌اند (≥ 64 GB به بالا).

گره چگونه راستی‌آزمایی می‌کند

پذیرش ابتدا بررسی‌های ارزان را انجام می‌دهد (تراکنش‌ها)، سپس:

  • چکیدهٔ بسته (bundle digest) را از متن آشکار منتشرشده بازمحاسبه می‌کند (anchor، چهار nullifier، چهار commitment، fee، burn_a، burn_r، burn_asset، time، auth_commit همان بسته، و یک کلمهٔ taint که روی صفر ثابت است) و الزام می‌کند با آنچه اثبات منتشر کرده برابر باشد — اثباتی که witness آن رابطه را شکسته باشد، چکیده‌ای آلوده (tainted) منتشر می‌کند که با هیچ متن آشکاری مطابقت ندارد. برخی بررسی‌ها به‌جای آن ساختاری‌اند (guest خودش فرستنده، دارایی و زمان یک خروجی را فراهم می‌کند، بنابراین اثبات‌کننده نمی‌تواند آن‌ها را انتخاب کند)، و دارایی خصوصی در چکیده نیست؛
  • اثبات را رمزگشایی می‌کند و ارتفاع‌های اعلام‌شدهٔ آن را با لایه بررسی می‌کند (check_declared_heights)، تا کران شکل اثبات در زنجیره همان کران تأییدکننده باشد. پیش از بررسی هر امضا یا اثبات، یک غربال اثبات متعارف (canonical-proof screen) روی هر تراکنش ارسالی یا گاسیپ‌شده اجرا می‌شود (و تحت hardening_v6 در اعتبارسنجی بلوک نیز)؛ از fullnode v0.6.8 (audit v6، ZKV-4) این غربال ابتدا هر درجهٔ اعلام‌شده را در 25 بیت محدود می‌کند (MAX_HONEST_DEGREE_BITS، سقف جدول حافظه به‌علاوهٔ یک)، بنابراین سرآیندی با درجهٔ بسیار بزرگ دیگر گره را درگیر نمی‌کند در حالی که برنامهٔ تاشدن صادقانه برای آن بازمحاسبه می‌شود، و panic درون غربال به‌جای متوقف کردن گره، همان تراکنش را رد می‌کند؛
  • binding تراکنش را محاسبه می‌کند و Machine::verify_public(hc_bundle, &binding, proof) را اجرا می‌کند — تأییدکنندهٔ دسته‌ای به‌علاوهٔ بررسی اینکه H_PUB چکیدهٔ همان هشت کلمه است، بنابراین اثباتی که روی تراکنشی با کنش دیگر، پاکت دیگر یا شناسهٔ زنجیرهٔ دیگر، یا روی زنجیرهٔ 20 روی genesis زنجیرهٔ دیگر کپی شده باشد، تأیید نمی‌شود (تا زنجیرهٔ 13 این بخش خالی بود و چیزی اثبات را به تراکنشش نمی‌بست)؛
  • اثبات auth را در برابر hc_auth و همان binding تأیید می‌کند و الزام می‌کند c منتشرشدهٔ آن با auth_commit برابر باشد. بسته‌ای بدون اثبات auth رد می‌شود (AuthMissing)، و همین‌طور بسته‌ای که c آن متفاوت باشد (AuthMismatch)؛
  • الزام می‌کند GAS_LIMIT اثبات بسته با bundle_gas_limit مقرر در genesis، یعنی 20,479، برابر باشد و GAS_LIMIT اثبات auth با 1,279، سقف‌های سرآیند دو guest (BundleGasLimit، AuthGasLimit)؛
  • برای یک فراخوانی، همین کار را در برابر code_hash ذخیره‌شدهٔ برنامه انجام می‌دهد، با کلمات عمومی برنامه که binding فراخوانی به‌عنوان بخش (segment) به دنبال آن می‌آید (یک Invoke از RPL-2 گذار خود را به‌صورت کلمات زمینه (context) اضافه می‌کند، برنامه‌ها)، سپس کارمزد را با سقف gas که اثبات اعلام می‌کند و با بایت‌های آن بررسی می‌کند (کارمزدها).

تراکنشی که از راه RPC یا گاسیپ ارسال شود روی یکی از چهار worker پشت یک صف با عمق 64 راستی‌آزمایی می‌شود، بیرون از حلقهٔ اجماع، و فقط پس از تأیید شدن به بقیه گاسیپ می‌شود؛ یک token bucket برای هر همتا (burst برابر 16، پرشدن 4 در ثانیه) میزان کاری را که یک همتا می‌تواند گره را به راستی‌آزمایی آن وادار کند محدود می‌کند، و یک حافظهٔ نهان با 8,192 مدخل تکرار تراکنشی را که برای همیشه رد شده بدون هزینه پاسخ می‌دهد. راستی‌آزمایی اثبات‌های درون یک بلوک پیشنهادی همچنان هنگام اعمال بلوک روی حلقهٔ اجماع اجرا می‌شود. گرهی که همگام‌سازی می‌کند پیش از پذیرفتن هر بلوک، هر گواهی و هر اثبات آن را دوباره راستی‌آزمایی می‌کند؛ چیزی صرفاً به این دلیل که حد نصابی آن را امضا کرده مورد اعتماد نیست.

لایه‌ها

لایهبودجهٔ چرخه (2ᵗ − 1)ردیف‌های cpuاستفاده‌کننده
101,0232¹⁰guest مربوط به auth؛ private_payment، fib
124,0952¹²
1416,3832¹⁴guest بستهٔ دارایی پنهان (و guest بازنشستهٔ bundle)؛ بزرگ‌ترین فراخوانی
1665,5352¹⁶اثبات فراخوانی EVM در مجموعهٔ آزمون؛ approve ترجمه‌شدهٔ ERC-20 (فراخوانی‌شده روی زنجیرهٔ 13)
18262,1432¹⁸transfer و transferFrom از ERC-20، ترجمه‌شده یا مفسرشده
201,048,5752²⁰SPL Token، ترجمه‌شده یا روی guest مفسر sBPF

از fullnode v0.5.6 (2026-09-25) اثبات فراخوانی بالاتر از لایهٔ 14 پیش از ساخته شدن کلید تأییدکننده رد می‌شود (CallTierTooHigh) و بلوکی که یکی از آن‌ها را حمل کند نامعتبر است؛ یک فراخوانی همچنین می‌تواند حداکثر 128 جایگشت Keccak-f و 128 فشرده‌سازی SHA-256 داشته باشد. لایه‌های 16 تا 20 همچنان اثبات می‌شوند، اما فقط خارج از زنجیره: هیچ‌یک از ردیف‌های بالاتر از آن‌ها را روی زنجیرهٔ 20 نمی‌توان فراخوانی کرد، و زنجیرهٔ 20 استقرار برنامه‌ای را که برای هر فراخوانی لایهٔ 14 بیش از حد بزرگ باشد رد می‌کند، یعنی بیش از 8,180 کلمه بدون ورودی عمومی (ProgramUncallable) (بودجه).

اثبات‌کننده کوچک‌ترین لایه‌ای را برمی‌گزیند که بودجه‌اش چرخه‌ها به‌علاوهٔ ردیف‌های برنامه و چکیدهٔ ورودی را پوشش دهد؛ اجرایی که جا نشود پیش از اثبات‌سازی شکست می‌خورد. فقط لایه عمومی است. هر پله زمان اثبات‌سازی را تقریباً چهار برابر می‌کند و اندکی به اندازهٔ اثبات می‌افزاید. روی زنجیرهٔ 20 کارمزد یک فراخوانی از سقف gas که اثبات اعلام می‌کند و از اندازهٔ آن به بایت پیروی می‌کند، نه از لایه (کارمزدها).

مجموعه‌های قید و هارد فورک‌ها

مجموعهٔ قید (constraint set) مجموعهٔ دقیق جدول‌ها، ستون‌ها، باس‌ها، مقادیر عمومی و پارامترهای FRI است که تأییدکننده بررسی می‌کند. اثباتی که تحت یک مجموعه ساخته شده تحت مجموعهٔ دیگر تأیید نمی‌شود، در هیچ‌یک از دو جهت، و بازپخش راه‌اندازی گره هر اثبات زنجیرهٔ خود را دوباره راستی‌آزمایی می‌کند — بنابراین گرهی که از مجموعه‌ای متفاوت ساخته شده باشد در نخستین اثبات شکست می‌خورد و زنجیره را کوتاه می‌کند. به همین دلیل است که هر تغییر در مجموعه به‌صورت شناسهٔ زنجیرهٔ جدید با همهٔ گره‌ها روی یک build منتشر می‌شود، و به همین دلیل rand_status مقادیر hc_bundle و hc_auth را گزارش می‌کند و گرهی که buildش با genesis ناسازگار باشد از راه‌اندازی خودداری می‌کند.

مجموعهتاریخچه تغییر کرد
22026-09-10پنج رفع مشکل درستی (soundness) پس از بازبینی نخست
32026-09-11تراشهٔ Poseidon2، hc درون مدار، جدول برنامه به‌عنوان witness، حافظهٔ زیرکلمه‌ای، RV32M، تنظیم مجدد FRI روی 27 پرس‌وجو
42026-09-11تعهد ورودی نمک‌دار H_IN با جدول مخصوص خود؛ بارگذار باینری تخت
52026-09-12جدول اختیاری keccak؛ ارتفاع حافظهٔ اعلام‌شده توسط اثبات؛ دو رفع مشکل بحرانی از ممیزی zk؛ بازگشت FRI به 80 پرس‌وجو؛ MAX_PROOF_BYTES به 2 MiB
62026-09-14جدول اجباری public و H_PUB؛ جدول اختیاری sha256؛ guestهای مفسر EVM و sBPF به‌صورت کتابخانه؛ 34 مقدار عمومی. آنچه زنجیره‌های 12 تا 15 اجرا کردند.
72026-09-28هر پایانهٔ LogUp از راه باس BLIND کور شد؛ هر جدول اعلام‌شده روی 2⁷ ردیف کف‌گذاری شد؛ بررسی‌های بازهٔ 32 بیتی روی کلمات ورودی، عمومی و salt؛ فراخوانی سیستمی POSEIDON2_LEN (7)؛ JALR بیت 0 مقصد خود را پاک می‌کند و funct3 = 0 را الزام می‌کند؛ کلیدهای تأییدکننده با key_derivation_v2 نمک‌دار شدند. آنچه زنجیره‌های 16 و 17 اجرا کردند.
82026-09-29شمارندهٔ gas: ستون GAS در جدول cpu و مقدار عمومی GAS_LIMIT؛ 35 مقدار عمومی. آنچه زنجیره‌های 18 تا 20 اجرا می‌کنند.

زنجیره‌های 14 و 15 هیچ قیدی را تغییر ندادند. گرهٔ زنجیرهٔ 15 ثابت‌های 86 دور Poseidon2 را به‌جای نمونه‌گیری با seed، به‌صورت جدول لفظی نگه می‌دارد (audit ZKV-2) — همان مقادیر، پس هیچ هش، چکیده یا اثباتی جابه‌جا نشد. زنجیرهٔ 14: بستهٔ دارایی پنهان یک guest جدید است (یک hc_bundle جدید) و binding تراکنش از بخش عمومی‌ای استفاده می‌کند که مجموعهٔ 6 از پیش در مدار می‌بندد. با این همه یک هارد فورک است — قالب سیمی بسته، guest پین‌شده و هر شناسهٔ تراکنش تغییر کرد، تراکنش زنجیرهٔ 13 که بسته‌ای حمل کند توسط build جدید رد می‌شود، و کیف‌پولی که پیش از فورک ساخته شده باشد اثبات‌هایی با بخش خالی تولید می‌کند که زنجیره رد می‌کند.

سه زنجیرهٔ بعدی هرکدام معنای «اثبات» را تغییر دادند. زنجیرهٔ ۱۶ (fullnode v0.6.1، ‏2026-09-28) به مجموعهٔ قیود ۷ رفت، guest بستهٔ بدون انشعاب نسخهٔ ۲ را تثبیت کرد و hardening_v6 را فعال کرد. این اقدام پس از آن بود که بازبینی 2026-09-27 نشان داد جدول‌های کوتاه و پایانه‌های LogUp بدون پوشش تصادفی (unblinded)، داده‌های خصوصی را نشت می‌دهند (zkVM چگونه کار می‌کند). همهٔ کلیدهای verifier تغییر کردند. زنجیرهٔ ۱۷ (v0.6.3، ‏2026-09-29) مجموعهٔ ۷ را نگه داشت و احراز مجوز تفکیک‌شده را افزود: guest بسته نسخهٔ ۳، guest احراز مجوز، دو فیلد تازه در قالب انتقالی بسته و دامنهٔ شناسهٔ تراکنش rand-txid-3. زنجیرهٔ ۱۸ (v0.6.7-rc1، ‏2026-09-29) برای شمارندهٔ گاز به مجموعهٔ قیود ۸ رفت. هزینهٔ اندازه‌گیری‌شدهٔ آن در اندازهٔ اثبات کمتر از ۱٪ است. زنجیرهٔ ۱۹ (2026-10-01) یک re-genesis از زنجیرهٔ ۱۸ روی همان build نسخهٔ v0.6.7 است و هیچ چیزی را در اثبات‌ها تغییر نداد. زنجیرهٔ ۲۰ (fullnode v0.6.8، ‏2026-10-01) مجموعهٔ قیود ۸ و همان guestها و کلیدهای verifier را نگه می‌دارد و آنچه را اثبات به آن مقید است تغییر می‌دهد: مقیدسازی‌های تراکنش و فراخوانی، هش genesis را حمل می‌کنند (binding_domain: 1)، که ورودی عمومی است و کیف پول و دفتر کل آن را محاسبه می‌کنند؛ بنابراین هیچ مداری جابه‌جا نشده است. با این حال این یک hard fork است، زیرا اثبات‌های کیف پول v0.6.7 روی آن تأیید نمی‌شوند. هر build زنجیره‌های پیش از خود را بر پایهٔ هش genesis رد می‌کند.

دو یادداشت ممیزی که در کد آمده و دانستنشان ارزش دارد: مقدار عمومی TIER را verifier با سرآیند اثبات و بیت‌های درجهٔ دسته بررسی می‌کند، اما خود مدار آن را مقید نمی‌کند (ممیزی ZL1؛ برای مجموعهٔ بعدی علامت‌گذاری شده و رفع نشده است، چون حذف آن چیدمان مقادیر عمومی را جابه‌جا می‌کند)؛ و H_IN تعهدی است که guest آن را می‌بیند و verifier آن را، به‌طور عمدی، با مقداری که فراخواننده بدهد مقایسه نمی‌کند.

به‌زودی: تجمیع در سطح بلوک

با حدود 1.43 MB برای هر اثبات بستهٔ دارایی پنهان در زنجیره‌های ۱۴ و ۱۵، یک بلوک 4 MiB (پیش‌فرض و بلوک زنجیرهٔ ۱۲) دو انتقال shielded را در خود جا می‌داد؛ با بستهٔ ۲-ورودی-۲-خروجی به اندازهٔ ~1.3 MB سه انتقال جا می‌گرفت. زنجیره‌های ۱۳، ۱۴ و ۱۵ سقف بلوک را به 20 MiB (max_block_bytes) رساندند، که جای چهارده انتقال را دارد. زنجیرهٔ ۲۰ همان 20 MiB را نگه می‌دارد و یک انتقال در آن حدود 2.87 MB اثبات حمل می‌کند، پس یک بلوک حدود هفت انتقال در خود جا می‌دهد. راه‌حلی که fullnode (در 2026-09-12) به‌جای هرس‌کردن و به‌جای بلوک بزرگ‌تر برگزید، تجمیع در سطح بلوک است: یک اثبات بازگشتی برای هر پنجرهٔ مهرشده که N اثبات بسته را تأیید می‌کند، تا تاریخچه از آغاز تا انجام اثبات‌دار بماند و اثبات‌های خام قابل حذف باشند. این قابلیت ساخته و ادغام شده اما فعال نشده است و از زنجیرهٔ ۱۴ به بعد پیش از فعال‌سازی باید دوباره اندازه‌گیری شود: شکل بستهٔ پذیرفته‌شدهٔ آن با قطعهٔ عمومی تهی (public 2) اندازه‌گیری شده بود، در حالی که بستهٔ مقید به تراکنش public 4 اعلام می‌کند، پس هیچ بسته‌ای که روی زنجیرهٔ ۱۴ اثبات شده با آن جور نیست. مجموعه‌های قیود ۷ و ۸ شکل را بار دیگر جابه‌جا کردند: اثبات یک بسته اکنون public 7 اعلام می‌کند و ۳۵ مقدار منتشر می‌کند، پس رابط تجمیع برای هر اثبات ۳۵ کلمه است. یک build گره روی هر genesis که بخش aggregation داشته باشد راه‌اندازی نمی‌شود، و زنجیره‌های ۱۴ تا ۲۰ بدون آن ساخته شدند. genesis با قیمت‌های پویای گاز، مانند genesis زنجیرهٔ ۲۰، نیز در کنار بخش aggregation رد می‌شود. از fullnode v0.5.8 اثبات تجمیعی aggregator خود را نیز مقید می‌کند (ممیزی AGG-2: برنامه aggregate_binding(chain_id, aggregator, nonce) را جذب می‌کند)، پس چکیدهٔ برنامهٔ شکل پذیرفته‌شده باید روی buildی اندازه‌گیری شود که این تغییر را دارد. فعال‌سازی همچنین هنوز منتظر یک تمرین سرتاسری تجمیع جعلی روی verifier بازگشتیِ اصلاح‌شده است که اجرا نشده، و منتظر تصمیمی دربارهٔ اثبات احراز مجوز: برنامهٔ تجمیع فقط اثبات‌های بسته را تأیید می‌کند، پس در زنجیرهٔ احراز مجوز تفکیک‌شده، مهر کردن یک پنجره انتقال را از حدود 2.87 MB به حدود 1.37 MB کاهش می‌دهد، نه به هیچ.

آنچه ساخته شده است:

  • ماشین دوم بومی Goldilocks (recursion VM با نام randprotocol-rvm) که برنامهٔ verifier آن یک اثبات RV32 را در حدود 1.97 میلیون سطر در tier 21 بررسی می‌کند (2,044,506 زیر مجموعهٔ قیود ۷)، و یک برنامهٔ تجمیعی N-عمومی روی پنجره‌ای از اثبات‌های بسته؛
  • دو نقش: اعتبارسنج‌ها (validators) از نظر CPU ارزان می‌مانند و برای هر بلوک مهرشده یک تجمیع را تأیید می‌کنند؛ تجمیع‌کننده‌ها (aggregators)، که ثبت‌نامی بدون مجوز و دارای وثیقه با نشانی پرداخت shielded است، تجمیع‌ها را روی ماشین‌های هم‌رده با GPU اثبات می‌کنند و سهم اثبات بسته‌های پوشش‌داده‌شده را به‌علاوهٔ یارانهٔ بلوک به شکل RAND تازه با برنامهٔ نصف‌شونده دریافت می‌کنند؛
  • پنج کنش (RegisterAggregator، UnbondAggregator، WithdrawAggregator، SlashAggregator، Aggregate؛ SlashAggregator روی wire می‌ماند و رد می‌شود، زیرا تجمیعِ تکرارشده همان nonce را دوباره امضا می‌کند و دوگانه‌امضایی (equivocation) نیست)، پذیرشی نُه‌مرحله‌ای، مهر و هرس بسته‌های پوشش‌داده‌شده تا حدود 3 KB فیلد عمومی برای هرکدام، همگام‌سازی به شکل مهرشده که برای یک گرهٔ تازه به‌ازای هر پنجره یک تأیید بازگشتی هزینه دارد، متدهای RPC با نام‌های rand_getAggregate، rand_getAggregators، rand_getUnsealed، rand_getRawTransaction، و دیمن rand-node aggregate --watch.

اندازه‌گیری روی پروفایل FRI آزمایشی: یک تجمیع N=1 در حدود ۲۶ دقیقه روی یک لپ‌تاپ زیر بار اثبات شد (327,035 بایت)؛ یک گرهٔ تازه یک دستهٔ مهرشدهٔ هفت‌بلوکی را در کمتر از یک ثانیه با یک تأیید بازگشتی اعمال کرد. ردهٔ ماشین‌ها در نخستین کران‌بندی: N=1 دست‌کم 64 GB حافظهٔ میزبان می‌خواهد، N=2 دست‌کم 128 GB، N=3 دست‌کم 160 GB؛ N ≥ 2 در تولید به بک‌اند CUDA تعلق دارد که به گرهٔ GPU نیاز دارد و هنوز وجود ندارد. در اندازه‌گیری روی ماشین 256 GB زیر مجموعهٔ قیود ۷ (2026-09-28 و 29)، تجمیع N=2 برابر 133 GB، N=3 برابر 221 GB مصرف کرد و اثبات خروج تولیدی (برنامهٔ verifier روی یک اثبات درونی) از 256 GB فراتر رفت. هیچ‌یک از این‌ها زیر مجموعهٔ قیود ۸ دوباره اندازه‌گیری نشده است. تا زمانی که تجمیع فعال شود، هیچ تجمیعی جای یک اثبات را در زنجیرهٔ ۲۰ نمی‌گیرد: دو گرهٔ آرشیو آن همهٔ اثبات‌های خام را نگه می‌دارند و اعتبارسنج‌هایش تاریخچهٔ قدیمی‌تر از ۲۴ ساعت را هرس می‌کنند.

آخرین بار با کامیت c0878c3f از fullnode (زنجیرهٔ 21) در تاریخ 2026-10-12 بررسی شد. هرجا کد و این صفحه با هم اختلاف دارند، حق با کد است؛ به ما اطلاع دهید.