Rand Protocol
Dokumentasi
Program contoh

Keputusan kredit privat

Program rahasia yang menjalankan model penilaian yang dipublikasikan atas data pemohon yang bersifat privat dan hanya mempublikasikan persetujuan atau penolakan, dengan komitmen SHA-256 yang mengikat data tersebut pada seorang attester - antarmuka, aritmetika titik tetap, guest Rust, skrip host, dan program yang berjalan langsung di chain 18.

Pemberi pinjaman mempublikasikan model penilaiannya. Pemohon menjalankannya atas datanya sendiri dan menyerahkan kepada pemberi pinjaman sebuah tanda terima yang berbunyi “disetujui” atau “ditolak”. Pemberi pinjaman tidak pernah melihat datanya, dan pemohon tidak dapat mengubah model maupun memasukkan data rekaan ke dalamnya.

Ini adalah kasus berguna yang paling kecil dari pembuktian sebuah komputasi dengan program publik dan parameter publik atas masukan privat. Modelnya adalah jaringan saraf dua lapis dalam aritmetika bilangan bulat. Bentuk yang sama cocok untuk setiap aturan yang ingin dapat dibaca oleh regulator atau pihak lawan transaksi: rumus penetapan harga, uji kelayakan, batas risiko.

Example programs memuat pengaturan awal yang sama untuk keempat halaman contoh.

1. Apa yang dibuktikan

Tiga pihak:

  • Pemberi pinjaman men-deploy program dengan model sebagai segmen publiknya. Id program menamai model tersebut. Siapa pun dapat membaca kembali bobotnya dari chain.
  • Pengatestasi (biro kredit, bank, pemberi kerja) mengetahui data pemohon. Ia memberikan kepada pemohon nilai-nilai fitur, sebuah salt acak sepanjang 16 byte, dan tanda tangannya atas komitmen SHA-256(salt ‖ features).
  • Pemohon memanggil program dengan salt dan fitur sebagai masukan privat.

Pemanggilan tersebut membuktikan bahwa:

  1. setiap fitur berada di dalam rentang yang dinyatakan model untuknya;
  2. skor model atas fitur-fitur tersebut sama dengan atau di atas ambang batas (status 1) atau di bawahnya (status 2);
  3. komitmen yang dipublikasikan adalah SHA-256 dari salt dan fitur-fitur yang sama tersebut.

Pemberi pinjaman memeriksa id program pada tanda terima, statusnya, dan bahwa komitmennya adalah komitmen yang telah ditandatangani pengatestasi. Ia hanya mengetahui satu bit tentang pemohon.

Masukan privat tidak membuktikan apa pun tentang dunia nyata dengan sendirinya. Tanpa butir 3, pemohon dapat mengetikkan angka apa pun. Komitmenlah yang menghubungkan angka-angka di dalam bukti dengan angka-angka yang dijamin oleh seseorang. Tanda tangannya sendiri diperiksa di luar chain oleh pemberi pinjaman: verifikasi Dilithium atau ECDSA tidak muat dalam anggaran sebuah pemanggilan, dan tidak perlu berada di dalam bukti, karena komitmennya bersifat publik.

2. Antarmuka

Setiap word publik adalah i32, disimpan sebagai u32 komplemen dua-nya.

word publikarti
0jumlah fitur n, 1 sampai 16
1jumlah unit tersembunyi h, 1 sampai 16
2ambang batas
3jumlah bit pecahan, yaitu pergeseran s, 0 sampai 31
lalu 2n wordmin dan max yang diizinkan untuk setiap fitur
lalu h × n wordbobot lapisan pertama, baris demi baris
lalu h wordbias lapisan pertama
lalu h wordbobot lapisan kedua
lalu 1 wordbias lapisan kedua
word privatarti
0 sampai 3salt, 16 byte sebagai empat word big-endian
4 dan seterusnyan fitur, masing-masing berupa i32
slot keluaranarti
0status: 1 disetujui, 2 ditolak, 3 sebuah fitur di luar rentang, 4 model tidak valid (ukuran di luar batas, atau aritmetikanya mengalami overflow)
1tidak digunakan
2 sampai 620 byte pertama komitmen, sebagai lima word big-endian
7tidak digunakan; panic pada Rust menuliskan 0xdeadbeef di sini

Komitmen dipublikasikan hanya pada status 1 atau 2. Masukan di luar rentang menghentikan eksekusi sebelum apa pun di-hash.

3. Aritmetika

Model ini hanya menggunakan bilangan bulat. Mesinnya tidak memiliki bilangan titik mengambang, dan verifier harus dapat mereproduksi skor secara persis, hal yang tidak dijamin oleh bilangan titik mengambang antarmesin.

hidden[j] = max( (b1[j] + Σ w1[j][i] · x[i]) >> s , 0 )      for each hidden unit j
score     = (b2 + Σ w2[j] · hidden[j]) >> s
approved  = score >= threshold

Bobot berupa bilangan titik tetap dengan s bit pecahan: dengan s = 8, bobot 256 berarti 1,0. Penjumlahan menggunakan i64, dan setiap perkalian serta penjumlahan diperiksa, sehingga model dengan bobot yang cukup besar untuk menyebabkan overflow menghasilkan status 4 alih-alih skor yang salah. >> pada i64 negatif membulatkan ke arah minus tak hingga di Rust, dan >> di Python melakukan hal yang sama, sehingga sebuah fungsi Python sepuluh baris dapat menjadi acuannya.

Model demonstrasi memiliki delapan fitur dan empat unit tersembunyi. Bobotnya ditulis tangan untuk halaman ini. Model ini bukan model yang dilatih dan tidak menyatakan apa pun tentang kredit.

{
  "shift": 8,
  "threshold": 600,
  "features": [
    {"name": "age_years", "min": 18, "max": 120},
    {"name": "income_thousands", "min": 0, "max": 100000},
    {"name": "debt_to_income_pct", "min": 0, "max": 1000},
    {"name": "on_time_payments_pct", "min": 0, "max": 100},
    {"name": "utilisation_pct", "min": 0, "max": 100},
    {"name": "history_years", "min": 0, "max": 100},
    {"name": "inquiries_12m", "min": 0, "max": 100},
    {"name": "delinquencies", "min": 0, "max": 100}
  ],
  "w1": [
    [  64,   96,  -512,  1536,  -640,  1024, -2048, -8192],
    [   0,  256, -1024,     0,     0,     0,     0,     0],
    [   0,    0,     0,  2560, -1280,     0, -4096, -16384],
    [ 128,    0,     0,     0,     0,  2048,     0,     0]
  ],
  "b1": [25600, 12800, -128000, 0],
  "w2": [160, 96, 224, 128],
  "b2": 76800
}

4. Guest

my-guests/score/src/main.rs, lengkap:

#![no_std]
#![no_main]

use guest_sdk::{halt, read_input, read_public, sha256_compress, write_output};

const MAX_FEATURES: usize = 16;
const MAX_HIDDEN: usize = 16;

const APPROVED: u32 = 1;
const DECLINED: u32 = 2;
const OUT_OF_RANGE: u32 = 3;
const BAD_MODEL: u32 = 4;

/// SHA-256's initial state (FIPS 180-4 §5.3.3).
const IV: [u32; 8] = [
    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
];

/// SHA-256 of `words`, each word taken as four big-endian bytes. The message is whole words,
/// so the padding is whole words too: `0x80000000`, zeros, then the bit length in the last
/// word of a block (the length's high word is always zero here).
fn sha256_words(words: &[u32]) -> [u32; 8] {
    let mut buf = [0u32; 24];
    buf[16..].copy_from_slice(&IV);
    let mut fill = 0;
    for &w in words {
        buf[fill] = w;
        fill += 1;
        if fill == 16 {
            sha256_compress(&mut buf);
            fill = 0;
        }
    }
    buf[fill] = 0x8000_0000;
    fill += 1;
    if fill > 14 {
        buf[fill..16].fill(0);
        sha256_compress(&mut buf);
        fill = 0;
    }
    buf[fill..15].fill(0);
    buf[15] = 32 * words.len() as u32;
    sha256_compress(&mut buf);
    let mut out = [0u32; 8];
    out.copy_from_slice(&buf[16..]);
    out
}

/// `weight · x`, added to `acc`; `None` when it does not fit an i64.
fn mul_add(acc: i64, weight: u32, x: i64) -> Option<i64> {
    acc.checked_add((weight as i32 as i64).checked_mul(x)?)
}

/// Runs the model in the public segment over the private features.
fn score(features: &[i32], hidden: usize, shift: u32) -> Option<i64> {
    let n = features.len();
    // The public segment after the header and the feature ranges:
    // hidden × n first-layer weights, hidden biases, hidden second-layer weights, one bias.
    let w1 = 4 + 2 * n;
    let b1 = w1 + hidden * n;
    let w2 = b1 + hidden;
    let b2 = w2 + hidden;

    let mut out = read_public(b2 as u32) as i32 as i64;
    for j in 0..hidden {
        let mut acc = read_public((b1 + j) as u32) as i32 as i64;
        for (i, &x) in features.iter().enumerate() {
            acc = mul_add(acc, read_public((w1 + j * n + i) as u32), x as i64)?;
        }
        // Fixed point: drop the fractional bits, then ReLU.
        let h = (acc >> shift).max(0);
        out = mul_add(out, read_public((w2 + j) as u32), h)?;
    }
    Some(out >> shift)
}

/// Public segment, fixed at deploy (every value an i32):
///   [features n, hidden units, threshold, fractional bits,
///    n × (min, max), hidden × n weights, hidden biases, hidden weights, bias]
/// Private input: [salt (4 words), n features].
/// Outputs: [status, 0, commitment (first 5 words), 0], where
/// commitment = SHA-256(salt ‖ features), every word big-endian.
#[no_mangle]
pub extern "C" fn main() -> ! {
    let n = read_public(0) as usize;
    let hidden = read_public(1) as usize;
    let threshold = read_public(2) as i32 as i64;
    let shift = read_public(3);
    if n == 0 || n > MAX_FEATURES || hidden == 0 || hidden > MAX_HIDDEN || shift > 31 {
        write_output(0, BAD_MODEL);
        halt();
    }

    // The committed message: the salt, then the features, in input order.
    let mut message = [0u32; 4 + MAX_FEATURES];
    for (i, w) in message.iter_mut().enumerate().take(4 + n) {
        *w = read_input(i as u32);
    }
    let mut features = [0i32; MAX_FEATURES];
    let mut in_range = true;
    for i in 0..n {
        let x = message[4 + i] as i32;
        let min = read_public(4 + 2 * i as u32) as i32;
        let max = read_public(5 + 2 * i as u32) as i32;
        in_range &= min <= x && x <= max;
        features[i] = x;
    }
    if !in_range {
        write_output(0, OUT_OF_RANGE);
        halt();
    }

    let status = match score(&features[..n], hidden, shift) {
        Some(s) if s >= threshold => APPROVED,
        Some(_) => DECLINED,
        None => BAD_MODEL,
    };
    let commitment = sha256_words(&message[..4 + n]);

    write_output(0, status);
    for k in 0..5 {
        write_output(2 + k as u32, commitment[k]);
    }
    halt();
}

Model adalah data, bukan kode. Bobot dibaca dengan read_public, sehingga satu image yang di-deploy melayani model apa pun hingga 16 fitur dan 16 unit tersembunyi. Mengubah model berarti men-deploy kode yang sama dengan segmen publik baru, dan id program baru. Pemberi pinjaman tidak dapat menukar bobot di belakang pemohon, dan pemohon tidak dapat memilih model yang lebih lunak: tanda terima menyebutkan id program, dan id tersebut mengikat bobotnya.

Rentang adalah bagian dari model. Tanpa rentang, pemohon tidak dapat berbohong tentang suatu nilai (komitmen mencegahnya), tetapi pengatestasi dapat menandatangani nilai yang tidak masuk akal, misalnya usia −5, yang akan diberi ganjaran oleh model dengan bobot negatif. Pemeriksaan ini juga membatasi aritmetikanya.

Salt memiliki dua fungsi. Salt membuat komitmen tidak dapat ditebak: delapan bilangan bulat kecil memiliki entropi yang rendah, dan tanpa salt siapa pun dapat meng-hash calon pemohon lalu membandingkannya. Salt juga meneruskan 128 bit acak melalui komputasi. Sebelum constraint set 7 menyamarkan total bus pada bukti, sebuah pemanggilan atas beberapa word privat kecil dapat di-brute-force dari bukti itu sendiri, dan catatan fullnode memerintahkan program semacam itu untuk membaca word acak. Chain 18 menjalankan constraint set 8, yang telah memperbaikinya, tetapi salt hanya memerlukan empat word masukan dan menghilangkan keraguan tersebut.

5. Sisi host

score.py hanya menggunakan pustaka standar Python:

score.py setup   <model.json>                            writes public.txt
score.py witness <model.json> <salt: 32 hex> <x0> <x1> …  prints the private words;
                                                        stderr: the score, the decision, the commitment
score.py commit  <salt: 32 hex> <x0> <x1> …              prints the commitment alone

Penilai acuan dan komitmennya, secara lengkap:

def score(m, x):
    """The guest's arithmetic exactly: integers, a floor shift after each layer, ReLU between."""
    out = m["b2"]
    for row, b, w2 in zip(m["w1"], m["b1"], m["w2"]):
        h = max((b + sum(w * xi for w, xi in zip(row, x))) >> m["shift"], 0)
        out += w2 * h
    return out >> m["shift"]

def commitment(salt: bytes, x):
    return hashlib.sha256(salt + b"".join(struct.pack(">i", xi) for xi in x)).digest()
$ cd my-guests/score
$ python3 score.py setup model.json
wrote public.txt (61 words)
$ cat public.txt
8 4 600 8 18 120 0 100000 0 1000 0 100 0 100 0 100 0 100 0 100 64 96 4294966784 1536 4294966656 1024 4294965248 4294959104 0 256 4294966272 0 0 0 0 0 0 0 0 2560 4294966016 0 4294963200 4294950912 128 0 0 0 0 2048 0 0 25600 12800 4294839296 0 160 96 224 128 76800

Angka-angka besar itu adalah bobot negatif: 4294966784 adalah −512.

Guest diuji terhadap acuan ini pada 300 pemohon acak, dengan membandingkan keputusan dan kelima word komitmen, serta pada pemohon yang skornya 599 dan 600. Hasilnya sama pada setiap kasus.

6. Build dan jalankan

$ rand-guest build my-guests/score --max-words 65535
462 words against a cap of 65535 (fits); 0 ecall(s) with a non-static a7
OK
wrote my-guests/score/image.bin and its .sha256 (462 words, hc c63d7b15a165a11d007ce48bc37563b71f77fcc4991ffe0182c8cf4c77b6e7b5, program id ce8d234faf737c24bdd2826933ac843973c140c53e76fbb2cccaef3073da9818)

Seorang pemohon berusia 41 tahun dengan pendapatan 85 ribu, rasio utang terhadap pendapatan 28%, 97% pembayaran tepat waktu, utilisasi 22%, riwayat 12 tahun, satu inquiry, dan tanpa tunggakan:

$ python3 score.py witness model.json 00112233445566778899aabbccddeeff 41 85 28 97 22 12 1 0 > witness.txt
score 1075 approved
commitment 9430c3818f5966f8dd33f78e05a7d079355191e6
$ cat witness.txt
1122867 1146447479 2291772091 3437096703 41 85 28 97 22 12 1 0
$ rand-guest run image.bin --public $(cat public.txt) --input $(cat witness.txt) --tier 14
out[0] = 1
out[1] = 0
out[2] = 2486223745
out[3] = 2405000952
out[4] = 3711170446
out[5] = 94883961
out[6] = 894538214
out[7] = 0
cycles 1810
tier 12
tier 14: fits (cycles 1946 of 16383, Poseidon2 permutations 136 of 2048)

2486223745 adalah 0x9430c381, empat byte pertama komitmen. Skornya, 1075, tidak muncul di mana pun dalam keluaran.

Pemohon kedua (23, 31, 55, 82, 91, 2, 6, 2, dengan salt lain) memperoleh skor 417 dan menghasilkan out[0] = 2 dengan komitmennya sendiri, dalam 1.810 siklus yang sama. Pemohon pertama dengan usia diubah menjadi 17 menghasilkan out[0] = 3 dan tanpa komitmen.

7. Anggaran

program462 word
segmen publik61 word
word privat12
siklus1.810
kompresi SHA-2561 (48 byte pesan muat dalam satu blok)
tier12

Ini adalah program termurah dari keempat program. Forward pass-nya adalah 36 perkalian. Model pada batas program, yaitu 16 fitur dan 16 unit tersembunyi, adalah 272 perkalian dan segmen publik 325 word. Model itu terukur 7.900 siklus di emulator, sekitar separuh dari tier 14.

Eksekusinya tidak bergantung pada data: 200 pemohon acak, yang disetujui maupun ditolak, masing-masing memerlukan tepat 1.810 siklus. Batas gas yang dinyatakan sebuah pemanggilan bersifat publik dan dibulatkan dari gas eksekusi, sehingga program yang jumlah siklusnya mengikuti masukannya akan membocorkan sedikit darinya. Program ini tidak memiliki apa pun yang dapat bocor dengan cara itu.

Sejak chain 18, wallet mencetak gas persis dari eksekusi dan batas yang dinyatakannya:

gas: 2011 (declaring 2048, tier 12)

1.948 baris dengan 1 gas masing-masing, ditambah 63 untuk satu kompresi tersebut.

8. Deploy

Ke-61 word model dibayar seperti word kode: 0.001 + 0.0001 × (462 + 61) = 0,0533 RAND.

$ rand fee deploy 462 --public-words 61
0.0533 RAND
$ rand program deploy image.bin --public public.txt
program id: 7bbec14289f4446231b3a9a5ac18cb0613a373ca8a14fe4f046f3fde7ae6c73c (462 words, hc 157b3dc61da165a18be47c00b76375c3c4fc771f01fe1f994ccfc882b5e7b677, public input 61 words, digest a08a7c691c45babeb39e953930d4d7174662b7b8adcc2d0f4e6c193d362d6668)
proving the spend authorisation on this machine (tier 10; seconds)…
authorisation proved in 7.4s: tier 10, 1364940 bytes
proving the bundle (tier 14; about a minute and a half on a laptop)…
proved in 123.5s: tier 14, 1497319 bytes
submitted deploy d47a9323ea53bfafc3faa36d004416d374bf3c2a48971d87e346be426b0caf14
  0 RAND out, 59.7229 RAND change, fee 0.0533 RAND, anchored at height 98062, proved in 123.5s (bundle) + 7.4s (auth)

9. Panggil

$ rand call 7bbec14289f4446231b3a9a5ac18cb0613a373ca8a14fe4f046f3fde7ae6c73c \
    $(sed 's/[0-9][0-9]*/--input &/g' witness.txt)
proving the call locally (12 inputs stay private, over the program's 61-word public input)…
gas: 2011 (declaring 2048, tier 12)
fee 0.005673037 RAND (incl. two price steps of headroom)
proved in 30.6s: tier 12, 1838256 bytes, outputs [1, 0, 2486223745, 2405000952, 3711170446, 94883961, 894538214, 0]
proving the spend authorisation on this machine (tier 10; seconds)…
authorisation proved in 6.8s: tier 10, 1369611 bytes
proving the bundle (tier 14; about a minute and a half on a laptop)…
proved in 124.3s: tier 14, 1499112 bytes
submitted call 454c1b9eb1e159e682d4ff26b71f77d8a950b813533d91a89293dd432fdcf6f7
  0 RAND out, 59.696058627 RAND change, fee 0.005673037 RAND, anchored at height 98832, proved in 124.3s (bundle) + 6.8s (auth)
{
  "h_in": "ef80c744a8cdea62b56e334baaf7372e4a2e6c8282d37aa8ae96b4f039ec1a22",
  "h_pub": "a08a7c691c45babeb39e953930d4d7174662b7b8adcc2d0f4e6c193d362d6668",
  "height": 98993,
  "index": 0,
  "outputs": [
    1,
    0,
    2486223745,
    2405000952,
    3711170446,
    94883961,
    894538214,
    0
  ],
  "program": "7bbec14289f4446231b3a9a5ac18cb0613a373ca8a14fe4f046f3fde7ae6c73c",
  "tier": 12,
  "tx": "454c1b9eb1e159e682d4ff26b71f77d8a950b813533d91a89293dd432fdcf6f7"
}
input transcript published; open it with `rand open-call 454c1b9eb1e159e682d4ff26b71f77d8a950b813533d91a89293dd432fdcf6f7`

Status 1 dan komitmen 9430c381 8f5966f8 dd33f78e 05a7d079 355191e6 dalam heksadesimal. h_pub adalah digest dari 61 word model. Fitur, salt, dan skor tidak ada di dalam transaksi.

Pemanggilan ini memakan waktu sedikit di atas tiga menit pada laptop Apple Silicon: 31 detik untuk bukti pemanggilan, 7 detik untuk otorisasi pembelanjaan, dan 124 detik untuk bundle, dengan puncak 6,2 GB. Ukuran buktinya 1.838.256 byte.

10. Periksa sendiri

Sisi pemberi pinjaman, hanya dengan tanda terima dan komitmen yang ditandatangani pengatestasi:

  1. Model. rand_getProgramPublic pada id program mengembalikan 61 word. Bandingkan dengan model.json yang dipublikasikan (score.py setup membangunnya kembali).
  2. Kode. Bangun ulang my-guests/score pada commit circuits yang sama dan bandingkan hc dengan code_hash milik program.
  3. Tanda terima. program adalah id model, keluaran 0 adalah 1, slot 7 bukan 3735928559.
  4. Komitmen. Keluaran 2 sampai 6, dicetak sebagai heksadesimal, adalah 20 byte pertama komitmen yang ditandatangani pengatestasi:
$ python3 score.py commit 00112233445566778899aabbccddeeff 41 85 28 97 22 12 1 0
9430c3818f5966f8dd33f78e05a7d079355191e6

Penolakan juga merupakan tanda terima. Panggilan pemohon kedua, 119e7834…1b3b pada chain 18 (diulang pada chain 20 sebagai c8a60183…9f73, yang juga menolak), dibuktikan dan di-commit dengan cara yang sama:

$ python3 score.py witness model.json 0f1e2d3c4b5a69788796a5b4c3d2e1f0 23 31 55 82 91 2 6 2 > witness.txt
score 417 declined
commitment 0313ea462178574c49a10fe7ea1d84207652e1a3
$ rand call 7bbec14289f4446231b3a9a5ac18cb0613a373ca8a14fe4f046f3fde7ae6c73c \
    $(sed 's/[0-9][0-9]*/--input &/g' witness.txt)
…
gas: 2011 (declaring 2048, tier 12)
proved in 26.1s: tier 12, 1836624 bytes, outputs [2, 0, 51636806, 561534796, 1235292135, 3927802912, 1985143203, 0]
…
submitted call 119e7834033edd19bba8e10c1a764e8bdbc0b1c8415a42f041faa392c6411b3b

Status 2, dan 51636806 adalah 0x0313ea46. Gas, batas yang dideklarasikan, dan tier-nya sama dengan panggilan yang disetujui, sehingga kedua panggilan itu hanya berbeda di dalam chain pada kata status dan commitment, dan tidak pada hal lain. Pemohon tidak punya alasan untuk mempublikasikan penolakan, tetapi pemberi pinjaman dapat meminta tanda terimanya bagaimanapun juga, dan pemohon yang ditolak tidak dapat menghasilkan tanda terima persetujuan.

Apa yang tidak diberikan oleh bukti ini

  • Data yang benar. Bukti menunjukkan bahwa model dijalankan pada nilai-nilai yang di-commit. Benar atau tidaknya nilai-nilai tersebut bergantung pada pernyataan attester, dan pemberi pinjaman harus memercayai tanda tangan attester untuk hal itu.
  • Pemohon yang tidak dapat ditautkan. Commitment adalah pengenal yang stabil: attester dapat mengenalinya, dan dua tanda terima dengan commitment yang sama adalah pemohon yang sama dan data yang sama. Salt baru dari attester untuk setiap permohonan mengatasi hal yang kedua, tetapi tidak yang pertama.
  • Model rahasia. Bobotnya bersifat publik. Itulah tujuannya untuk aturan yang harus dapat dibaca orang, dan menjadi kelemahan bagi pemberi pinjaman yang memperlakukan modelnya sebagai rahasia dagang. Pemohon juga dapat mencari masukan yang akan lolos, tetapi tidak dapat menggunakannya tanpa tanda tangan attester atas masukan tersebut.
  • Perlindungan dari penyelidikan oleh attester yang tidak jujur. Siapa pun yang mengetahui fitur-fiturnya dapat menjalankan model publik itu sendiri. Privasi di sini adalah milik pemohon terhadap pemberi pinjaman dan publik, bukan terhadap pihak yang menyediakan data.
  • Model yang besar. Enam belas fitur dan enam belas unit tersembunyi adalah kartu skor, bukan jaringan dalam. Satu panggilan dibatasi pada tier 14, sekitar enam belas ribu siklus.

Terakhir diverifikasi terhadap commit fullnode 48dc04b (chain 18) pada 2026-09-30, dan circuits `aeacf31` (`guest-sdk/src/lib.rs`, `rand-guest`), the commit fullnode v0.6.7 vendors; every `rand-guest`, `python3` and `rand` output on this page was produced on 2026-09-30, the deploy and the call on chain 18. Jika kode dan halaman ini tidak sesuai, kodelah yang benar; beri tahu kami.