Gunakan halaman ini untuk membina atau mengaudit apa-apa sahaja yang membaca kolam: dompet yang mengimbas nota miliknya, pengindeks yang mengikuti komitmen dan nullifier, atau alat yang menyemak apa yang diterbitkan oleh sesuatu transaksi. Nilai pada rantaian ini ialah satu set nota; rantaian menyimpan komitmen nota tersebut, tidak pernah kandungannya.
Sebuah nota
Nota ialah { pk, from, amount, asset, time, r }: 28 perkataan 32-bit, 112 bait, disusun sebagai pk(8) from(8) amount_lo amount_hi asset time r(8). pk ialah nilai awam nota milik pemilik (diperoleh daripada kunci pandangan), from ialah nilai milik penghantar, amount ialah u64 dalam unit (1 RAND = 10⁹ unit), asset ialah u32 (0 untuk RAND, jika tidak indeks padat daftar token bagi token RPL, sama ada yang dijambatankan atau natif; lihat token RPL), time ialah ketinggian blok yang disasarkan oleh penghantar, dan r ialah lapan perkataan rawak untuk penyamaran.
Teks biasa tidak pernah muncul pada rantaian. Yang muncul ialah:
- komitmennya
cm = H(CM, words), cincangan Poseidon2 bagi 28 perkataan di bawah tag domain 4, ditambah sebagai daun pada pokok; - sampulnya, teks biasa yang dimeteraikan kepada alamat pemilik supaya hanya pemilik, atau penghantar melalui kunci pandangan keluarannya, dapat membacanya. Sejak chain 18 (termasuk chain 20) sampul turut membawa memo yang disulitkan. Beberapa nota yang dikira oleh rantaian daripada medan awam tidak membawa sampul langsung (di bawah).
Membelanjakan nota menerbitkan nullifiernya H(NF, nk, cm), cincangan Poseidon2 di bawah tag domain 3 bagi kunci pandangan pemilik dan komitmen. Tanpa nk, nullifier tidak dapat dipautkan kepada komitmennya. Set nullifier ialah perkara yang menghalang perbelanjaan berganda.
Sampul
Envelope { kem_ct, to_receiver, to_sender, body }
| bahagian | bait | apakah itu |
|---|---|---|
kem_ct | 1,088 | enkapsulasi ML-KEM-768 kepada alamat penerima |
to_receiver | 60 | kunci setiap transaksi TxKey yang dibungkus di bawah rahsia yang dienkapsulasi |
to_sender | 60 | TxKey yang sama dibungkus di bawah kunci pandangan keluaran penghantar ovk |
body | 652 | nota 112 bait dan medan memo 512 bait di bawah TxKey (140 bait, nota sahaja, hingga chain 17) |
Setiap bahagian menggunakan ChaCha20-Poly1305 dengan nonce rawak 12 bait di hadapan dan tag 16 bait, dan data berkaitan ialah satu tag (rand-envelope-receiver, rand-envelope-sender, rand-envelope-body) diikuti dengan komitmen nota, supaya sesuatu kunci tidak dapat membuka sampul yang tidak dimeteraikannya dan nota yang dibuka terikat pada daun tempat ia berada. Itu ialah 1,860 bait teks sifir; awalan panjang bincode menjadikannya 1,892 pada wayar. Genesis chain 20 menetapkan envelope_bytes: 1860, dan lejarnya menolak sampul nota yang berpanjang lain (envelope is 1348 bytes, this chain requires exactly 1860); lejar tidak menyemak apa-apa lagi tentangnya. Hingga chain 17 sampul tidak mempunyai medan memo dan berukuran 1,348 bait (1,380 pada wayar), dan lejar hanya mengehadkannya kepada 2,048 bait, yang masih menjadi peraturan pada rantaian yang genesisnya tidak mempunyai envelope_bytes.
Medan memo ialah len (u16 LE) ‖ UTF-8 text ‖ zero padding, 512 bait, jadi paling banyak 510 bait teks. Setiap sampul nota pada chain 20 mempunyainya, sama ada terdapat memo atau tidak: output baki, output dummy dan pembayaran tanpa memo diisi dengan cara yang sama, dan tiada apa-apa pada rantaian yang membezakan memo, panjangnya atau ketiadaannya. Memo tidak terdapat dalam nota, komitmen atau mana-mana bukti. Ia boleh dibaca oleh sesiapa sahaja yang sudah dapat membaca nota itu: pemilik, penghantar melalui ovk, atau sesiapa yang diberi TxKey output tersebut. Medan memo yang cacat (panjang yang salah, UTF-8 tidak sah, pengisian bukan sifar) dibuka sebagai tiada memo dan tidak pernah menyebabkan pemilik kehilangan nota. Memo ialah teks sesiapa sahaja, kerana sesiapa boleh membayar nota debu ke alamat awam: paparkan ia sebagai tidak dipercayai, dengan aksara kawalan dan aksara format Unicode digantikan, seperti yang dilakukan oleh dompet rand. rand send --memo memeteraikan satu memo ke dalam output pembayaran; rand notes --memo dan rand history --memo memaparkannya.
Pokok, sauh dan tetingkap
Komitmen ditambah pada satu pokok Poseidon2 berkedalaman 32, yang terlama dahulu, dan tidak pernah dibuang. Daun i ialah nota ke-i yang pernah dicipta oleh rantaian; nota deposit genesis ialah daun pertama. Sesuatu bundle menambah empat daun dan empat nullifier walau apa pun yang dipindahkannya, termasuk dummy. Daun kosong ialah semua sifar dan nod ialah H(NODE, left, right) (tag domain 7). Nod hanya menyimpan frontier, jadi keadaan konsensus tidak pernah menyimpan daun; rand_getWitness membina semula pokok penuh daripada daun yang disimpan apabila diminta, sebab itulah ia bacaan paling mahal yang disediakan oleh nod.
Sesuatu bundle membuktikan keahlian inputnya terhadap satu sauh, iaitu akar pokok. Dua peraturan memastikan sauh sentiasa jujur:
| pemalar | nilai | peraturan |
|---|---|---|
ANCHOR_WINDOW | 256 blok; 1,024 pada chain 20 | sauh mestilah salah satu daripada window akar hujung blok yang terakhir; akar yang dilalui pokok di pertengahan blok tidak pernah menjadi sauh |
TIME_WINDOW | 256 blok; 1,024 pada chain 20 | time bundle mestilah dalam lingkungan [height − window, height] |
Kedua-dua tetingkap ialah 256 blok melainkan genesis menetapkan proof_window_blocks (v0.6.8, 256 hingga 4,096), yang menggantikan kedua-duanya sekali gus. Chain 20 menetapkan 1,024; chain 14 hingga 19 tidak mempunyai medan itu.
Tetingkap wujud kerana pembuktian memerlukan masa sebenar: bukti bundle tier-14 diukur kira-kira 100 saat pada komputer riba (dan sejak chain 17 dompet membuat bukti auth kedua, tier-10, kira-kira 7 saat). 256 blok ialah kira-kira lima minit pada blok 1.17 s chain 18, dan bukti yang diwakilkan pada prover yang perlahan telah ditolak pada 294 s; 1,024 blok chain 20 ialah kira-kira 23 minit pada 1.34 s yang dilaporkan oleh penjelajah di sana. Dompet yang kalah dalam perlumbaan ini dimaklumkan anchor is not one of the last 1024 roots dan membuat bukti semula. rand_getAnchor tanpa parameter mengembalikan akar hujung blok kepala, satu-satunya sauh yang patut digunakan oleh prover untuk membina bukti.
Bundle
Setiap transaksi yang memindahkan nilai membawa tepat satu bundle aset tersembunyi 4-masuk-4-keluar yang tetap (sejak chain 14; ia 2-masuk-2-keluar hingga chain 13), dibuktikan oleh tetamu zkVM aset tersembunyi yang digest hc_bundlenya disematkan dalam fail genesis (60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce, tetamu bundle v3, pada chain 17 hingga 20; ia ialah 83d3a3704a1fcdb9bae7136c0a947ffa34bd53f055388395ed705fe8cacd0ef8, tetamu v1, pada chain 14 dan 15):
Bundle { anchor, nullifiers[4], commitments[4], fee, burn_a, burn_r, burn_asset, time, envelopes[4], proof,
auth_commit, auth_proof } // the last two since chain 17
Slot 0–1, masuk dan keluar, membawa aset persendirian A; slot 2–3 sentiasa membawa RAND. Pada pembayaran RAND sahaja, slot 0–1 ialah dummy dan nilai serta yuran bergerak melalui slot 2–3. Pada pemindahan token, token bergerak melalui slot 0–1 dan yuran RAND dibayar daripada slot 2–3 bukti yang sama. A ialah perkataan saksi bagi bukti dan tiada dalam mana-mana medan awam, jadi pemindahan mana-mana token RPL ialah Action::None dengan burn_a = burn_r = burn_asset = 0, medan demi medan sama bentuknya dengan pembayaran RAND.
Bukti itu menyatakan bahawa setiap input sebenar ialah daun di bawah anchor dan membawa aset slotnya, bahawa keempat-empat nullifier ialah yang diterbitkan, bahawa setiap kumpulan seimbang (in0 + in1 = out0 + out1 + burn_a dalam aset persendirian, in2 + in3 = out2 + out3 + fee + burn_r dalam RAND), dan bahawa pembelanja memegang kunci — tanpa mendedahkan daun yang mana, jumlah berapa, aset apa, atau siapa. Tiga medan burn ialah satu-satunya pernyataan awam bundle tentang nilai yang keluar daripada kolam: burn_a dan burn_asset bukan sifar hanya pada TokenBurn atau BridgeBurn, yang menyamai jumlah dan aset tindakan itu; burn_r ialah RAND yang dibakar, bukan sifar hanya pada Bond (pertaruhan) dan RegisterAggregator (bon). Yuran sentiasa dalam RAND.
Sejak chain 17 kuasa untuk membelanjakan dipecahkan kepada dua bukti (pengesahihan terpisah). Tetamu bundle v3 mengambil kunci pandangan nk dan satu salt di tempat tetamu terdahulu mengambil kunci belanja: ia memperoleh pk_self = H(PK, nk), menghendaki setiap input dimiliki olehnya, dan melipat c = H(AUTH, nk ‖ salt) ke dalam digest yang diterbitkannya. Tetamu kedua, tetamu auth (genesis hc_auth, 1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1), mengambil kunci belanja sk dan salt yang sama, memperoleh nk = H(NK, sk) dan menerbitkan c yang sama. Bundle membawa c sebagai auth_commit dan bukti tier-10 tetamu auth sebagai auth_proof, dan lejar menghendaki kedua-dua bukti disahkan terhadap pengikatan transaksi yang sama serta kedua-dua nilai c bersetuju. Prover yang memegang nk dan salt itu oleh itu boleh membuat bukti bundle tetapi tidak bukti auth, dan inilah asas pembuktian yang diwakilkan. Salt ialah 256 bit rawak baharu bagi setiap bundle, jadi auth_commit bersifat awam dan tidak memautkan apa-apa. Dompet yang membuktikan sendiri turut membuat kedua-dua bukti, jadi transaksi yang dibuktikan sendiri dan yang diwakilkan kelihatan sama pada rantaian.
Slot sering kali kosong (dummy), kerana bentuknya tetap: input dummy ialah nota bernilai sifar milik pembelanja (nullifier-nya tetap diterbitkan), output dummy ialah nota berjumlah sifar, dan output baki wujud walaupun bakinya sifar. Transaksi yang kelihatan berbeza apabila tiada baki akan membocorkan bahawa baki itu tiada. Akibatnya bagi dompet: setiap satu daripada dua kumpulan dalam sesuatu bundle membelanjakan paling banyak dua nota. Pembayaran RAND, bon, deploy atau panggilan membelanjakan paling banyak dua nota RAND; pemindahan atau pembakaran token membelanjakan paling banyak dua nota token tersebut dan paling banyak dua nota RAND untuk yuran. Nilai yang tersebar pada tiga nota atau lebih dalam satu kumpulan perlu disatukan dahulu, dengan penghantaran ke alamat sendiri.
Sejak chain 14, bukti juga terikat pada transaksinya: ia dibuat ke atas dan disahkan terhadap cincangan keseluruhan transaksi dengan bukti-buktinya dikosongkan, maka ia tidak boleh disalin ke tindakan lain, sampul lain atau chain lain; pada chain 20 cincangan itu turut merangkumi cincangan genesis, maka ia juga tidak boleh disalin ke chain yang berkongsi chain id yang sama (Transaksi).
Apa yang awam dan apa yang tersembunyi
| awam di chain | tersembunyi | |
|---|---|---|
| pemindahan, sama ada RAND atau mana-mana token RPL | anchor, keempat-empat nullifier, keempat-empat komitmen, yuran, burn_a = burn_r = burn_asset = 0, time, empat sifertek sampul, bukti, auth_commit dan bukti auth | siapa penghantarnya, siapa yang dibayar, jumlah, memo, aset yang mana dipindahkan, baki, daun yang mana dibelanjakan, slot yang mana dummy |
| pembakaran token atau pembakaran bridge | segala-galanya yang diterbitkan oleh pemindahan, dengan burn_asset dan burn_a sama dengan aset dan jumlah tindakan itu (dan, bagi pembakaran bridge, yuran relayer, token sokongan dan destinasi) | nota yang mana dibakar, dan siapa yang membakarnya |
| mint faucet | komitmen, sampul, jumlah, validator yang melakukan mint, dan sejak chain 14 pembukaan nota (pk, time, r), yang daripadanya kemasukan mengira semula komitmen | setiap pembelanjaan nota itu selepas ini |
| deposit genesis | { cm, envelope, amount, opening: { pk, time, r } } dalam fail genesis, dengan asset dalam pembukaan bagi nota token yang tersenarai (genesis chain 20 membawa dua nota zUSD): pk pemilik, jumlah dan aset adalah awam secara reka bentuk | bilakah dan ke dalam apa ia dibelanjakan kemudian |
| withdraw, deposit bridge, mint token atau mint awal pendaftaran | jumlah, penerima, time nota dan pembutaan r (chain mengira komitmen itu sendiri) | setiap pembelanjaan nota itu selepas ini |
| bayaran keluar invoke atau mint program (chain 20) | jumlah, aset, penerima dan r; time nota ialah milik bundle | setiap pembelanjaan nota itu selepas ini |
| nota yuran bridge (chain 20) | jumlah, aset dan time, pembutaan terterbit, perbendaharaan genesis sebagai pemilik, dan tiada sampul | setiap pembelanjaan nota itu selepas ini |
Nilai memasuki kolam dengan jumlah awam — mint faucet, deposit genesis, withdraw validator, pengesahan bridge dan nota yurannya, mint token, bayaran keluar peti simpanan program — dan keluar sebagai yuran atau pembakaran awam. Segala-galanya di antaranya ialah nota.
Jadual ini ialah apa yang disembunyikan oleh bukti chain 20, dan ia tidak sentiasa begitu. Pada chain 14 dan 15, bukti bundle itu sendiri mendedahkan lebih banyak (semakan zkVM 2026-09-27, INT-2 / GV-1): jumlah larian LogUp bagi setiap jadual diterbitkan tanpa pembutaan, dan guest v1 melangkau semakan Merkle dan aset bagi input dummy serta bercabang pada setiap bit laluan Merkle, sehingga sesiapa boleh membaca daripada bukti bundle slot input yang mana satu daripada empat itu benar, dan dengan itu sama ada ia memindahkan token atau RAND sahaja, serta bilangan bit 1 dalam setiap indeks daun yang dibelanjakan. Dua perubahan menutupnya. Chain 16 beralih kepada set kekangan 7, yang membutakan setiap terminal LogUp dan meletakkan lantai 2^7 baris pada setiap jadual yang diisytiharkan, dan kepada guest bundle v2 tanpa cabang, yang setiap slotnya, dummy atau benar, menjalankan semakan keahlian dan aset yang penuh melalui arahan yang sama. Guest v3, yang dijalankan oleh chain 17 hingga 20, ialah hubungan v2 dengan nk dan salt menggantikan kunci belanja, dan juga tanpa cabang. Bundle yang dikomit pada chain 14 dan 15 kekal dengan apa yang telah bocor. Apa yang masih ditunjukkan oleh bukti pada chain 20 ialah pengepalanya: bagi bundle, satu bentuk tetap (tier 14, had gas yang diisytiharkan 20,479 pada setiap bundle), dan bagi Call atau Invoke, ia ialah tier, had gas yang diisytiharkan, dan sama ada serta lebih kurang berapa kerap panggilan itu menggunakan prakompil keccak atau sha256 (Bukti).
Nota tanpa sampul
Kebanyakan nota ditemui dengan membuka sampulnya. Sesetengahnya dikira oleh chain daripada medan awam, dan bagi nota itu sampulnya sama ada tiada atau tidak boleh dipercayai.
- Nota yuran bridge (chain 20). Di bawah
bridge.fees, chain menambah nota zUSD kepada perbendaharaan genesis pada setiap deposit dan setiap pembakaran (Token RPL). Ia tidak mempunyai sampul: storan mengindeksnya dengan sampul kosong, yang dimeterai kepada sesiapa pun tiada, danrand_getCompactBlockssertarand_getCommitmentsmenunjukkannya sedemikian, nota bagi deposit selepas nota deposit dan nota bagi pembakaran selepas empat nota bundle. Setiap perkataan nota itu adalah awam: jumlah daripada transaksi dan kadar genesis, aset dantimedaripada transaksi,from = 0, pembutaanblake3("rand-bridge-fee-r-1" ‖ mu)bagi deposit ataublake3("rand-bridge-burn-fee-r-1" ‖ txid)bagi pembakaran, dan pemilik ialahrecipientgenesis. - Nota yang sampulnya tidak mengikat apa-apa. Deposit bridge, mint token, mint awal pendaftaran dan, pada chain 20, bayaran keluar serta mint program bagi invoke membawa sampul yang dimeterai oleh sesiapa yang menghantar transaksi, tetapi chain mengira nota itu daripada medan awam tindakan dan tidak pernah menyemak sampul terhadapnya. Penghantar yang cuai atau berniat jahat boleh memeterai sampah, maka penerima tidak boleh bergantung padanya.
Oleh itu dompet rand membina semula nota ini sendiri (wallet::rebuilt_notes_with), dalam satu laluan awam di sebelah penyahsulitan percubaan: bagi setiap transaksi sedemikian yang menamakan pk-nya sendiri, dan bagi nota yuran apabila alamatnya ialah perbendaharaan, ia mengira nota itu dan merekodkannya pada daun yang komitmennya dicincang olehnya. Nota yang dibina semula hanyalah calon: nod yang berdusta tentang sesuatu transaksi, kadar yuran atau cincangan menyebabkan nota tidak ditemui, tetapi tidak pernah mengkreditkan nota. Sejak v0.6.8, pengepala yang dikembalikan oleh rand_getBlocks membawa transaksi deposit, mint dan pendaftaran dalam public_notes, dan pada chain dengan yuran bridge, pembakaran juga, dengan bukti dilucutkan, di bawah id sebenar, maka laluan itu hanya membaca halaman pengepala. Invoke tidak terdapat dalam public_notes pada v0.6.8, maka terhadap nod v0.6.8 dompet hanya menemui bayaran keluar invoke melalui sampulnya, yang dimeterai oleh pemanggil dan tidak disemak oleh apa-apa pun. main fullnode turut membawa invoke di sana, dengan bukti dilucutkan, sejak d0bb73fb; ia ialah perubahan nod sahaja, belum diterapkan pada armada chain 20, dan dompet tidak memerlukan perubahan untuknya.
Pengimbasan: bagaimana dompet menemui notanya
Nod menjawab “ini keseluruhan pokok”, tidak pernah “ini baki anda”. Dompet:
- memuatkan daun halaman demi halaman dengan
rand_getCommitments(from_index, limit)(paling banyak 1,000 setiap panggilan) atau strim setiap blokrand_getCompactBlocks(from_height, to_height)(paling banyak 128 blok setiap panggilan); setiap transaksi yang membawa bundle menyenaraikan empat nota dan empat nullifier di sana, dan tiada pembaca boleh membezakan slot dummy daripada slot benar; - menyahsulit secara percubaan setiap sampul: sebagai penerima melalui kunci dekapsulasi ML-KEM-nya, sebagai penghantar melalui
ovk; menyimpan nota yangpk-nya ialah miliknya; dan membina semula nota yang berjumlah awam daripada transaksinya (di atas); - mengira nullifier bagi setiap nota yang disimpan dan menandakan yang muncul dalam
rand_getNullifiers(from_height, limit); - menjumlahkan baki yang selebihnya.
rand_getTreeInfo menyatakan sejauh mana imbasan perlu dibuat: { "next_index", "root", "nullifiers" }. Bagi pembelanjaan, dompet memerlukan laluan Merkle 32 aras bagi setiap input yang benar. Dompet rand menyimpan salinan pokok komitmennya sendiri, dibina semasa imbasan daripada halaman rand_getCommitments yang sama, dan mengira setiap laluan sendiri, maka satu-satunya soalan pokok yang dikemukakan penghantaran kepada nod ialah rand_getAnchor, yang tidak menamakan sebarang daun. rand_getWitness(index) kekal pada nod untuk klien lain. Ia memberitahu nod daun mana yang bakal dibelanjakan oleh pemanggil, iaitu kebocoran terbesar kolam sebelum pokok setempat wujud: klien yang terpaksa menggunakannya harus menjalankan nodnya sendiri, atau meminta saksi yang tidak diperlukannya bersama-sama saksi yang diperlukan.
rand sync # scanned 41 leaves and 37 blocks; 1 notes, 1 unspent
rand notes # index, asset, amount, height, spent, pending, memo
rand history # notes this wallet created for others, opened through ovk
Sebuah nota berstatus pending antara rand send --no-wait dengan sync seterusnya yang melihat sama ada nullifier-nya atau blok yang melepasi time + window (1,024 pada chain 20, dibaca daripada rand_getLimits.proof_window_blocks; 256 tanpanya). Selepas itu, bundle tersebut tidak dapat diterima masuk lagi dan nota itu boleh dibelanjakan semula.