دا پاڼه یو کوچنی Rust پروګرام له سرچینې څخه تر Rand پر ځنځیر د ځای پر ځای شوي پروګرام پورې رسوي. لاندې هر rand-guest کمانډ اجرا شوی، او پایله یې پرته له لنډیز څخه همداسې دلته ایښودل شوې. دا اجراوې په 2026-09-19 د circuits پر کمېټ 7ef3220 ترسره شوې. testnet اوس ځنځیر 20 دی، چې د وسایلو ځنځیر یې د 18 او 19 ځنځیرونو په څېر پر aeacf31 جوړ شوی (fullnode v0.6.8 هماغه کمېټ ټاکي چې v0.6.7 ټاکلی و)، او پایلې یې هلته بیا نه دي اجرا شوې. The RISC-V ISA ماشین، سیسکالونه او د فایل بڼه تشریح کوي.
1. د وسایلو ځنځیر نصب کړئ
hc په دقیق کمپایلر پورې تړلی دی، نو د وسایلو ځنځیر ټاکلی او ثابت شوی دی.
| وسیله | نسخه | ولې |
|---|---|---|
| Rust | 1.98.1 | مېلمه پروګرام او پخپله rand-guest کمپایلوي |
د riscv32im-unknown-none-elf هدف | د 1.98.1 لپاره | د مېلمه پروګرام هدف |
| د circuits یوه کاپي | randprotocol/zkp-circuits پر aeacf31 د 18 تر 20 ځنځیرونو لپاره | rand-guest، guest-sdk او د لینکر سکرېپټ لري |
git clone https://github.com/randprotocol/zkp-circuits circuits
cd circuits
git checkout aeacf31 # branch feat/v067-circuits, what fullnode v0.6.7 and v0.6.8 pin
rustup toolchain install 1.98.1
rustup target add riscv32im-unknown-none-elf --toolchain 1.98.1
(cd rand-guest && cargo +1.98.1 build --release)
alias rand-guest="$PWD/rand-guest/target/release/rand-guest"
rand-guest پنځه فرعي کمانډونه لري: build، check، pack، run او info.
کمېټ ځکه مهم دی چې hc د سرچینې او د وسایلو د ځنځیر تابع ده: هغه مېلمه پروګرام چې د guest-sdk د بل کمېټ پر وړاندې بیا جوړ شي، کېدای شي بل hc ترلاسه کړي. د 7ef3220 او aeacf31 ترمنځ د rand-guest لارښود بدل نه شو، خو guest-sdk/src/lib.rs بدل شو (دویم ګام).
2. مېلمه پروګرام ولیکئ
مېلمه پروګرام یو no_std، no_main باینري کرېټ دی چې پر guest-sdk تکیه کوي. دا باید د circuits د کاپي دننه وي: rand-guest build کاپي د مېلمه پروګرام له لارښود څخه پورته د guest-sdk/ په لټولو پیدا کوي، او هغه مېلمه پروګرام ردوي چې له کاپي بهر وي.
دا مېلمه پروګرام یو حد، یو شمېر او په هماغه شمېر پټ بیلانسونه لولي. که بیلانسونه حد پوره کړي، 1 او اضافي مقدار خپروي. بیلانسونه هېڅکله نه خپروي.
circuits/
guest-sdk/
rand-guest/
my-guests/
threshold/
Cargo.toml
src/main.rs
my-guests/threshold/Cargo.toml:
[package]
name = "threshold"
version = "0.1.0"
edition = "2021"
[dependencies]
guest-sdk = { path = "../../guest-sdk" }
[profile.release]
opt-level = 3
lto = true
panic = "abort"
codegen-units = 1
[workspace]
تش [workspace] کرېټ له هر مور workspace څخه بهر ساتي، لکه څنګه چې کمېټ شوی fib مېلمه پروګرام کوي.
my-guests/threshold/src/main.rs:
#![no_std]
#![no_main]
use guest_sdk::{halt, read_input, write_output};
/// Input 0 is a threshold, input 1 a count n, inputs 2..2+n are private balances.
/// Output 0 is 1 if the balances sum to at least the threshold, else 0.
/// Output 1 is the surplus when they do. The balances themselves are never published.
#[no_mangle]
pub extern "C" fn main() -> ! {
let threshold = read_input(0);
let n = read_input(1);
let mut sum: u32 = 0;
for i in 0..n {
sum = sum.wrapping_add(read_input(2 + i));
}
if sum >= threshold {
write_output(0, 1);
write_output(1, sum - threshold);
}
halt();
}
guest-sdk دا توابع صادروي: read_input، read_public، write_output، poseidon2، keccak، keccak256، sha256_compress، sha256 او halt، او _start برابروي، چې د سټک اشاره ګر ټاکي او main رابولي. هېڅ تخصیص کوونکی (allocator) او هېڅ شناور ټکی نشته.
پر aeacf31 د دغو توابعو درې لاسلیکونه له 7ef3220 څخه توپیر لري، او یو نوی صادر شوی تابع هم شته:
| تابع | پر 7ef3220 | پر aeacf31 |
|---|---|---|
keccak | fn keccak(ptr: *mut u32) | fn keccak(state: &mut [u32; 50]) |
sha256_compress | fn sha256_compress(ptr: *mut u32) | fn sha256_compress(buf: &mut [u32; 24]) |
poseidon2 | fn poseidon2(ptr: *mut u32, n: usize) | unsafe fn poseidon2(ptr: *mut u32, n: usize) |
poseidon2_len | شتون نه لري | fn poseidon2_len(buf: &mut [u32], n: usize) -> [u32; 8]، سیسکال 7 |
poseidon2_len د پیغام اوږدوالی په سپنج کې تړي او خوندي غوښتنه ده. rand-guest check پر aeacf31 لا هم یوازې له 0 تر 6 سیسکالونه لېست کوي، نو هغه مېلمه پروګرام چې دا رابولي داسې ایمیج جوړوي چې build یې د ecall with a7 = 7, which is no syscall the machine implements سره ردوي (zkp-circuits issue #1). تر هغه چې دا سم شي، مېلمه پروګرام د unsafe { poseidon2(ptr, n) } په واسطه پر ثابت اوږدوالي، نښه شویو پیغامونو هش کوي. په دې پاڼه کې مېلمه پروګرام له دغو څلورو څخه هېڅ یو نه کاروي.
د مېلمه پروګرام د لارښود قواعد:
- هېڅ
.cargo/configیا.cargo/config.tomlباید په دې لارښود، په هېڅ مور لارښود، یا په$CARGO_HOMEکې نه وي.buildردوي او هر فایل په نوم یادوي، ځکه cargo به یې له جوړونې سره یوځای کړي. - ستاسو خپل هېڅ کمپایلر بیرغونه نه.
buildټول پخپله ټاکي: د لینکر سکرېپټ،-unaligned-scalar-mem، او د لارې یو بیا نقشه کول چې ایمیج له دې خپلواک کوي چې کاپي چېرې پرته ده. - تر ټولو ډېر یو
.ldفایل.buildد مېلمه پروګرام په لارښود کې یوازینی.ldکاروي، یا که نه وي،guest-sdk/guest.ld. که تر یوه ډېر وي، هغه د--ldپه واسطه وټاکئ.
3. جوړول او کتنه
$ rand-guest build my-guests/threshold --out threshold.bin
Compiling guest-sdk v0.1.0 (…/circuits/guest-sdk)
warning: unstable feature specified for `-Ctarget-feature`: `unaligned-scalar-mem`
|
= note: this feature is not stably supported; its behavior can change in the future
warning: `guest-sdk` (lib) generated 1 warning
Compiling threshold v0.1.0 (…/circuits/my-guests/threshold)
warning: `threshold` (bin "threshold") generated 1 warning (1 duplicate)
Finished `release` profile [optimized] target(s) in 0.15s
40 words against a cap of 4096 (fits); 0 ecall(s) with a non-static a7
OK
wrote threshold.bin and its .sha256 (40 words, hc a491df99f289d81e2b6e09849a850b14e36e2bd6edc5f5a6de46c3d67c703665, program id 1b129cbce89df252150ab3d387a927beb1650a40e6cb0b04e86cdc203ca1b853)
د unaligned-scalar-mem خبرداری تمه کېږي: د وسایلو ځنځیر بېترتیبه لاسرسی په قصدي ډول بندوي.
build د cargo +1.98.1 build --release --target riscv32im-unknown-none-elf سره کمپایلوي، پر پایله check اجرا کوي، او د ایمیج کانټېنر او یو .sha256 ټاکنه لیکي. که check پروګرام رد کړي، build بیا هم ایمیج لیکي او له صفر پرته کوډ سره وځي.
| بیرغ | ډیفالټ | مانا |
|---|---|---|
--out <path> | <dir>/image.bin | ایمیج چېرې ځي |
--max-words <n> | 4096 | هغه سقف چې check ورسره اندازه کوي؛ د هدف ځنځیر سقف ورکړئ (پر ځنځیر 20 کې 65,535) |
--ld <path> | په لارښود کې یوازینی .ld، که نه نو guest-sdk/guest.ld | د لینکر سکرېپټ |
--lang rust|c | rust | کمپایلر |
4. پر امولېټر یې اجرا کړئ
پټ ورودي د --input سره ورکړئ، هر یو یوه کلمه. --tier t دا هم راپور کوي چې آیا اجرا په t کچه کې ځاییږي.
$ rand-guest run threshold.bin --input 1000 --input 4 --input 400 --input 250 --input 300 --input 75 --tier 10
out[0] = 1
out[1] = 25
out[2] = 0
out[3] = 0
out[4] = 0
out[5] = 0
out[6] = 0
out[7] = 0
cycles 52
tier 10
tier 10: fits (cycles 66 of 1023, Poseidon2 permutations 14 of 128)
د بیلانسونو مجموعه 1,025 ده، نو پروګرام 1 او د 25 اضافي مقدار خپروي. د 400 او 250 بیلانسونو سره مجموعه کمه ده، او هره پایله صفر ده. یو ټرپ trap: <error> چاپوي او د 2 کوډ سره وځي.
5. ایمیج وڅېړئ
$ rand-guest info threshold.bin
form: image container
text 40 words at 0x1000; data 0 words (0 non-zero) at 0x0; prologue 0 words; program 40 words from base_pc 0x1000
hc a491df99f289d81e2b6e09849a850b14e36e2bd6edc5f5a6de46c3d67c703665
program id 1b129cbce89df252150ab3d387a927beb1650a40e6cb0b04e86cdc203ca1b853
40 words against a cap of 4096: fits
hc هغه څه دي چې د یوې غوښتنې ثبوت ورسره تایید کېږي. د پروګرام پېژند هغه څه دي چې تاسو یې لاندې ځای پر ځای کوئ او رابولئ.
6. ځای پر ځای کول
د fullnode v0.3 یا ورپسې نسخې rand بټوه وکاروئ؛ زړې بټوې د ایمیج کانټېنر نه لولي. له ځنځیر 14 راهیسې د بنډل هر ثبوت د خپلې راکړې ورکړې د تړنې پر وړاندې تایید کېږي، نو هغه بټوه چې د ځنځیر 14 له جوړونې (b3c594c) څخه زړه وي داسې بنډل ثابتوي چې ځنځیر یې ردوي. پر ځنځیر 20، چې ژوندی ځنځیر دی، د fullnode v0.6.8 یا ورپسې نسخې rand وکاروئ (بېړۍ v0.6.8 چلوي، او پر Linux جوړ شوی rand د هغې په GitHub خپرونه کې ضمیمه دی). د v0.6.7 بټوه پر ځنځیر 20 نه شي لېږلای: د ځنځیر 20 جنسیس binding_domain: 1 ټاکي، نو د ثبوت هره تړنه او هر لاسلیک شوی پیغام د جنسیس هش لري، خو د v0.6.7 بټوه یوازې د ځنځیر پېژند تړي. عامه پای ټکی https://rpc.randprotocol.org د بټوې د همغږي کولو، ځای پر ځای کولو او راغوښتلو لپاره بس دی (تنظیم).
rand fee deploy 40 # the floor for a 40-word program
rand program deploy threshold.bin
program deploy د پروګرام پېژند، د کلمو شمېر او hc چاپوي. بیا له نوډ څخه د rand_estimateFee په واسطه د ځای پر ځای کولو فیس پوښتي، چې د ځنځیر له سقف څخه لوی پروګرام تر هر ډول ثابتولو مخکې ردوي. بیا یو صفر ارزښت لرونکی ځان ته لېږد بنډل ثابتوي چې فیس ورکوي، وړاندې کوي یې، او د ثبت انتظار باسي. بنډل هماغه یو 4 ورودي او 4 خروجي پټ-شتمنۍ بنډل دی چې هره راکړه ورکړه یې لري. له ځنځیر 17 راهیسې دا دوه ثبوتونه دي، او بټوه د هر یوه لپاره یوه کرښه چاپوي: د 10 کچې د لګښت اجازه (څو ثانیې، شاوخوا 1.37 MB) او د 14 کچې بنډل (پر لپټاپ شاوخوا دوه دقیقې، شاوخوا 1.5 MB). پر ځنځیر 15 دا د 14 کچې یو ثبوت و، شاوخوا 100 s او شاوخوا 1.42 MB. یوه ناڅرګنده رایه پر ځنځیر 18 یو ځای پر ځای کول هماغسې ښيي لکه بټوې چې چاپ کړی و.
د ځای پر ځای کولو فیس 0.001 RAND + 0.0001 RAND × words دی، پر ځنځیر 20 هم لکه پخوا. ګاز د غوښتنو بیه ټاکي، نه د ځای پر ځای کولو:
| پروګرام | کلمې | د ځای پر ځای کولو فیس |
|---|---|---|
threshold | 40 | 0.005 RAND |
| په ډیفالټ سقف کې یو پروګرام (ځنځیر 12) | 4,096 | 0.4106 RAND |
| تر ټولو لوی پروګرام چې ځنځیر 20 یې پرته له عامه برخې ځای پر ځای کوي | 8,180 | 0.819 RAND |
| د 65,535 کلمو په سقف کې یو پروګرام (له 13 تر 15 ځنځیرونه) | 65,535 | 6.5545 RAND |
threshold له 4,096 کلمو کم دی، نو په ډیفالټ سقف او د ځنځیر 20 په 65,535 کې ځاییږي. له 4,096 کلمو لوی پروګرام داسې ځنځیر ته اړتیا لري چې جنسیس یې max_program_words لږ تر لږه هومره لوړ وټاکي، لکه ځنځیر 20 (The RISC-V ISA). ځنځیر 20، د ځنځیر 19 په څېر، دویم ټیټ حد هم لري: هغه پروګرام نه ځای پر ځای کوي چې د 14 کچې هېڅ غوښتنه یې نه شي ساتلای (ProgramUncallable)، چې پرته له عامه برخې له 8,180 کلمو ډېر دی او د عامه برخې سره تر دې کم. rand program deploy --input <word> … (یا --check-call پرته له ورودي غوښتنې لپاره) هغه غوښتنه چې ستاسو په پام کې ده لومړی د امولېټر له لارې اجرا کوي او تر هغه ځای پر ځای کول ردوي چې غوښتنه په 14 کچه یا تر هغې لاندې ونه لوېږي.
ثبت وګورئ:
rand program show 1b129cbce89df252150ab3d387a927beb1650a40e6cb0b04e86cdc203ca1b853
د هغه code_hash هماغه hc دی چې rand-guest چاپ کړی و، یوازې په بل ډول لیکل شوی. rand-guest د ډایجسټ هره یوه له اتو کلمو big-endian چاپوي، او بټوه، rand program show او rand_getProgram د هرې کلمې بایټونه little-endian چاپوي. نو a491df99…3665 د 99df91a4…707c په بڼه ښکاري: د اتو hex عددونو هره ډله په بایټ کچه سرچپه شوې ده. د پروګرام پېژند په دواړو کې یو ډول لیکل کېږي.
7. راوبولئ یې
rand call 1b129cbce89df252150ab3d387a927beb1650a40e6cb0b04e86cdc203ca1b853 \
--input 1000 --input 4 --input 400 --input 250 --input 300 --input 75
بټوه کوډ راوړي، غوښتنه په امولېټر کې اجرا کوي، او تر هر ډول ثابتولو مخکې gas: <exact> (declaring <limit>, tier <t>) او فیس چاپوي. بیا د ورودي لیکنه مهر کوي، اجرا په محلي ډول ثابتوي، فیس د یوه بنډل له لارې ورکوي، او رسید چاپوي. پر ځنځیر 20 دا درې ثبوتونه دي: غوښتنه، د 10 کچې د لګښت اجازه او د 14 کچې بنډل.
په chain 20 کې فیس نور 0.001 + call_fee(tier) نه دی، چې په chain 15 کې یې دا غوښتنه 0.002 RAND کوله. لږترلږه فیس BUNDLE_BASE + gas_price × declared gas limit + byte_price × ⌈bytes / 1024⌉ دی: 0.001 RAND، جمع د ګاز په بیه اعلان شوی حد (په genesis کې 100 واحده، چې هر واحد 10⁻⁹ RAND دی)، جمع د بایټ په بیه د ثبوت او پوښ بایټونه (په genesis کې د هر KiB لپاره 800 واحده). په chain 20 کې دا دوه بیې له 10,000 او 80,000 واحدونو څخه نشي اوښتلی. دقیق ګاز پټ پاتې کېږي. Wallet په ډیفالټ ډول ګاز د 2^(tier − 2) تر ټولو نږدې پورتني مضرب ته ګردوي او اعلانوي یې. Wallet د ثبوت بیه د chain په 4,194,304-بایټه سقف ټاکي، ځکه فیس د ثبوت له جوړېدو مخکې ټاکل کېږي. په پای کې د احتیاط لپاره دوه د بیې ګامونه ورزیاتوي. په chain 18 کې څلور اندازه شوې غوښتنې هره یوه له 0.0057 تر 0.0075 RAND پورې لګښت درلود (د بېلګې پروګرامونه). دا غوښتنه په 18 تر 20 chains کې نه ده ترسره شوې، نو د هغې لپاره هېڅ شمېره نه ده ورکړل شوې.
Chain یوازې tier، اعلان شوی د ګاز حد، H_IN او د وتنې اته کلمې [1, 25, 0, 0, 0, 0, 0, 0] ویني. هغه هېڅکله بیلانسونه نه ویني.
پروګرامونه رسیدونه، د ننوتنې پوښونه او rand open-call تشریح کوي. د دې په څېر Call بېحالته دی. په chain 20 کې یو پروګرام کولی شي د Invoke له لارې cells او vault هم وساتي (د پروګرام حالت (RPL-2)).
نورو ته اجازه ورکړئ چې ستاسو hc وڅېړي
جوړونه بیا تولیدېدونکې ده. build د کمپایلر چاپېریال پاکوي (RUSTFLAGS، د CARGO_* بدلونونه، د RUSTC پوښونکي او نور)، د cargo تنظیمي فایلونه ردوي، او د checkout لاره /rand-circuits ته بیا نقشه کوي. له Rust 1.98.1 سره ورته سرچینه په هر ماشین کې ورته hc ورکوي. د دې لپاره چې نور هغه څه تایید کړي چې تاسو پلي کړي، د guest سرچینه او د circuits هغه commit خپور کړئ چې کارولی مو دی (د 18 تر 20 chains لپاره جوړ شوي guest لپاره aeacf31). بیا هر څوک کولی شي هغه بیا جوړ کړي او hc د rand_getProgram له code_hash سره پرتله کړي. Chain یوازې کلمې ساتي، نه سرچینه.
د ستونزو حل
| پیغام | لامل |
|---|---|
… is not inside a circuits checkout (no guest-sdk/ above it) | د guest ډایرکټري د checkout دننه ولېږدوئ |
build د .cargo/config.toml نوم اخلي | هغه ړنګ یا بل ځای ته یې ولېږدوئ؛ هغه نشي پاکېدای |
REJECTED له Cap سره | پروګرام له --max-words څخه اوښتی دی؛ هغه د هدف chain تر سقف پورې لوړ کړئ، یا پروګرام کوچنی کړئ (opt-level = "s") |
REJECTED له Syscall او a7 = 7 سره | guest poseidon2_len غواړي؛ په aeacf31 کې rand-guest check لا syscall 7 نه پېژني (د zkp-circuits مسئله #1) |
REJECTED له Fence، Csr یا Ebreak سره | جوړونې داسې لارښوونه تولید کړې چې ماشین یې نه لري؛ څه ردېږي وګورئ |
له run څخه trap: … | د اجرا پر مهال تېروتنه، لکه نابرابره پته یا داسې syscall شمېره چې نه ده پلي شوې |
run وايي چې اجرا په هېڅ tier کې نه ځاییږي | اجرا له 2²⁰ قطارونو یا د خپل Poseidon2 بودیجې څخه اوښتې ده؛ ثبوت یې نشي جوړېدای |