evm2rv mengambil bytecode runtime EVM, yaitu keluaran solc --bin-runtime, dan mengubahnya menjadi program Rand. Ia menulis C, dan rand-guest build mengompilasi C tersebut menjadi image RV32IM. Image ini menerima vektor input yang sama dengan guest interpreter EVM milik Rand, evm.bin, dan menerbitkan delapan kata keluaran yang sama. Ia menjalankan kontrak secara native alih-alih menginterpretasikannya opcode demi opcode. Halaman ini menunjukkan seluruh alurnya pada sebuah ERC-20.
Apa itu
| input | bytecode runtime EVM, sebagai teks hex (.hex) atau byte mentah |
| output | sebuah crate shim C; rand-guest build menjadikannya kontainer image |
| tempat berjalan | di luar rantai, pada mesin pengembang; rantai hanya melihat image |
| yang harus dicocokkan | status, delapan kata keluaran, dan gas_used milik evm.bin |
| repositori | evm2rv/ dalam repositori circuits |
| toolchain yang dipatok | Rust 1.98.1, clang 23.1.1, crate cc 1.4.6 |
Penerjemah ini mengambil kode runtime, bukan kode pembuatan (creation code). Sebuah bukti mencakup satu panggilan ke kontrak yang telah di-deploy, sehingga constructor tidak pernah dijalankan. Keadaan yang akan ditulis oleh constructor menjadi bagian dari pra-keadaan, sebagai saksi storage.
Terdapat dua tahap penerjemahan. Keduanya menghasilkan hasil dan gas yang sama; masing-masing adalah program tersendiri dengan hc-nya sendiri.
| tahap | flag | fungsi |
|---|---|---|
| satu | --stage 1 | setiap opcode melalui stack di memori |
| dua | --stage 2, bawaan | kata-kata stack setiap blok disimpan dalam variabel lokal C, konstanta dilipat saat penerjemahan |
Vektor input sama dengan milik interpreter: kode, calldata, caller dan kata lingkungan lainnya, batas gas, root pra-keadaan, dan satu saksi storage untuk setiap slot yang disentuh panggilan. Keluarannya adalah out[0], yaitu status (1 berhasil, 0 revert, 2 halt eksepsional), dan out[1..8], digest EVM_OUT atas hash kode, kedua root keadaan, data kembalian, dan log.
Model kepercayaan
Seorang verifier memeriksa kontrak yang diterjemahkan dalam dua langkah.
hc == translate(bytecode). Jalankan ulangevm2rvpada bytecode yang diterbitkan dengan--stagedan--chain-idyang sama, bangun ulang dengan toolchain yang dipatok, lalu bandingkanhc. Crate yang dihasilkan mematokccsecara tepat dan membawaCargo.lock-nya sendiri.- Penjaga kode mengikat
hcpada bytecode. Logika hasil terjemahan dikompilasi ke dalam image, tetapiCODECOPYdanCODESIZEmembaca kode pada vektor input. Tanpa pemeriksaan, satuhcdapat berjalan dengan byte kode yang dipilih pemanggil. Karena itucontract.cmemuat digest Poseidon2 dari bytecode sumber (panjang dan byte-nya), dan shim meng-hash kode pada vektor input dengan cara yang sama sebelum kode hasil terjemahan apa pun dijalankan. Kode lain ditolak: status 2,gas_used0, haltOutOfBounds.
Digest EVM_OUT juga mengikat keccak256 dari kode, sebagaimana digest milik interpreter. Rantai tidak mencatat bytecode sumber maupun hash-nya. Agar pihak lain dapat memeriksa hc, terbitkan bytecode-nya, atau sumber Solidity beserta build solc yang persis.
Penjaga ini memakan 1.008 siklus pada transfer. Kode yang berbeda satu byte dari sumbernya ditolak dalam 30.418 siklus pada tahap dua (tier 16).
Cakupan, dan apa yang memicu trap
Opcode. Set Shanghai. Kompilasi dengan --evm-version shanghai: target yang lebih baru menghasilkan MCOPY dan opcode Cancun lainnya, yang memicu trap.
Opcode lingkungan:
| opcode | penerjemahan |
|---|---|
ADDRESS, CALLER, CALLVALUE, CALLDATASIZE, CODESIZE | dari vektor input, sebagaimana dibaca interpreter |
CHAINID | nilai --chain-id, ditanamkan saat penerjemahan sehingga hc mengikatnya; wajib bila kode memuat CHAINID |
ORIGIN | sama dengan CALLER (satu panggilan, tanpa relayer) |
GASPRICE, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, SELFBALANCE, BASEFEE, BLOCKHASH | trap (status 2), seperti pada interpreter |
Kesembilan opcode konteks blok ini memicu trap sampai ada rancangan untuk mengikatnya pada sebuah blok. Input privat tidak dapat membawa fakta blok, karena verifier tidak dapat membuka H_IN. Sampai keputusan itu dibuat, kontrak yang membaca waktu atau nomor blok (misalnya tenggat permit) akan memicu trap.
Panggilan. CALL, CALLCODE, DELEGATECALL, dan STATICCALL menjalankan precompile bila targetnya adalah alamat 1 sampai 9. Target lain memicu trap. Nilai bukan nol pada CALL atau CALLCODE memicu trap: tidak ada model saldo.
Precompile. Kesembilannya berjalan di perangkat lunak. Sebagian terlalu lambat untuk dibuktikan saat ini, karena sebuah bukti memuat paling banyak 2²⁰ baris:
| precompile | vektor | siklus | muat dalam 2²⁰ |
|---|---|---|---|
| 1 ecrecover | ValidKey | 14.510.525 | tidak |
| 2 sha256 | ”abc” / 200 byte | 2.791 / 5.289 | ya |
| 3 ripemd160 | ”abc” | 12.195 | ya |
| 4 identity | 100 byte | 4.498 | ya |
| 5 modexp | nagydani-1-square / -1-pow0x10001 | 122.332 / 874.548 | ya |
| 5 modexp | eip_example1 (256-bit) | 11.170.118 | tidak |
| 5 modexp | nagydani-5-pow0x10001 (1.024 byte) | 55.076.950 | tidak |
| 6 bn256 add | chfast1 | 978.262 | ya, tipis |
| 7 bn256 mul | chfast1 | 3.060.669 | tidak |
| 8 bn256 pairing | 1 pasangan / 2 pasangan | 1.853.656.212 / 2.019.000.469 | tidak |
| 9 blake2f | 12 ronde | 14.493 | ya, hingga sekitar 1.800 ronde |
Basis dan modulus modexp dibatasi masing-masing 1.024 byte.
Divergensi yang diterima. Status, kedelapan kata, dan gas_used harus cocok. Tiga perbedaan diterima: jenis halt boleh berbeda (gas statis dibebankan pada kepala setiap blok, sehingga OutOfGas dan halt lain dapat tertukar; keduanya berstatus 2 dengan seluruh gas terpakai); terjemahan mengimplementasikan CHAINID, ORIGIN, dan panggilan precompile, yang di-trap oleh interpreter; dan penjaga kode menolak kode selain sumbernya.
Angka-angkanya
Panggilan ERC-20, dengan penjaga kode disertakan. Siklus dari rand-guest run; tier dalam tanda kurung.
| panggilan | interpreter (evm.bin) | tahap satu | tahap dua (bawaan) |
|---|---|---|---|
transfer(BOB, 250) | 121.638 (18) | 80.211 (18) | 66.235 (18) |
approve(BOB, 5) | 85.645 (18) | 56.261 (16) | 48.119 (16) |
transferFrom(ALICE, BOB, 100) | 161.434 (18) | 110.074 (18) | 88.824 (18) |
| program | kata | hc |
|---|---|---|
evm.bin, interpreter | 18.009 | 7e1aea2b…854c08 |
| ERC-20, tahap satu | 15.804 | 9cdb79e7…2fd048c8 |
| ERC-20, tahap dua | 11.686 | a0feae92a7311c9562495717100eb7aea71270a38ed435d06dc31387e0ea8ff6 |
Tahap dua menjalankan ketiga panggilan dalam 54,5%, 56,2%, dan 55,0% dari siklus interpreter. Transfer tetap berada di tier 18: 66.235 siklusnya ditambah 3.155 baris digest menjadi 69.390 baris, 3.855 di atas 65.535 milik tier 16.
Sekitar 60% dari sebuah transfer tahap dua (sekitar 39.928 siklus) adalah harness yang dipakai bersama oleh kedua image: mendekode input, memverifikasi saksi storage, pemanggilan keccak256 oleh ABI, dan digest keluaran. Tidak ada pekerjaan penerjemahan yang dapat turun di bawah batas dasar itu.
Panduan langkah demi langkah: sebuah ERC-20, dari Solidity hingga keluaran yang cocok
Setiap perintah dijalankan dari root checkout circuits pada 7ef3220, dengan toolchain dari Deploy a Rust program dan clang 23.1.1 dari Deploy a RISC-V program. Keluaran yang panjang dipotong pada bagian yang ditandai ….
0. Bangun alat-alatnya
(cd evm2rv && cargo +1.98.1 build --release)
(cd rand-guest && cargo +1.98.1 build --release)
1. Kompilasi Solidity menjadi bytecode runtime
Kontraknya adalah guests-compiled/evm/contracts/ERC20.sol yang telah di-commit: ERC-20 mandiri dengan tata letak storage OpenZeppelin v4, pragma solidity 0.8.37. Gunakan persis solc 0.8.37; versi lain mengoptimasi secara berbeda dan menghasilkan bytecode yang berbeda.
| rilis | v0.8.37 dari github.com/ethereum/solidity/releases |
| aset macOS | solc-macos, sha256 a27396e7732aa52e80ff89ad7bd8a2e46fec2a6dcc4ef20cd16e5e0c502d6821 |
| aset Linux | solc-static-linux, dari rilis yang sama |
$ curl -sSL -o solc https://github.com/ethereum/solidity/releases/download/v0.8.37/solc-macos
$ shasum -a 256 solc
a27396e7732aa52e80ff89ad7bd8a2e46fec2a6dcc4ef20cd16e5e0c502d6821 solc
$ chmod +x solc && ./solc --version
solc, the solidity compiler commandline interface
Version: 0.8.37+commit.f401782d.Darwin.appleclang
$ (cd guests-compiled/evm && ../../solc --optimize --optimize-runs 200 --evm-version shanghai \
--bin-runtime contracts/ERC20.sol) | tee solc.out
======= contracts/ERC20.sol:ERC20 =======
Binary of the runtime part:
608060405234801561000f575f5ffd5b5060043610610060575f3560e01c8063095ea7b31461006457806318160ddd1461008c57806323b872dd1461…
$ tail -1 solc.out > evm2rv/target/mytoken.hex
Baris terakhir adalah bytecode runtime, sebesar 1.296 byte. Isinya identik byte demi byte dengan guests-compiled/evm/contracts/erc20.runtime.hex yang telah di-commit; SOLC=$PWD/solc bash guests-compiled/evm/contracts/build.sh memeriksanya dan mencetak contracts: erc20.runtime.hex reproduces.
Flag-flag ini penting:
--bin-runtime: kode yang di-deploy, bukan kode pembuatan.--evm-version shanghai: target bawaan untuk 0.8.37 menghasilkanMCOPY, yang memicu trap.--optimize --optimize-runs 200: profil untuk kontrak yang di-deploy.
2. Terjemahkan
$ evm2rv/target/release/evm2rv evm2rv/target/mytoken.hex --out evm2rv/target/mytoken --chain-id 12
1296 code bytes: 74 blocks, 798 opcodes, 51 jumpdests (stage 2)
CHAINID is the constant 12
no trapping opcodes present
wrote evm2rv/target/mytoken (crate mytoken): contract.c, Cargo.toml, Cargo.lock, build.rs, src/main.rs, shim.ld
--outharus berada di dalam checkout circuits. Tanpa flag ini,evm2rvhanya menganalisis kode.- Opcode apa pun yang memicu trap akan dicantumkan di sini sebagai peringatan, beserta pc-nya.
- Sesi ini direkam dengan
--chain-id 12. ERC-20 ini tidak memilikiCHAINID, sehingga--chain-idtidak mengubahhc-nya. Kontrak yang membacaCHAINIDmewajibkan flag ini; setel ke rantai tempat Anda akan men-deploy (--chain-id 19untuk rantai yang aktif).
contract.c diakhiri dengan digest penjaga kode:
const uint32_t *evm_code_digest(void) {
static const uint32_t d[8] = {0xf679280fu, 0x86c10e83u, 0x7e8f1f39u, 0xa2377de3u, 0x8a2e282fu, 0xc54cad42u, 0xddfaf009u, 0x7d28a8afu};
return d;
}
3. Bangun image
Batas bawaan adalah 4.096 kata, sehingga berikan --max-words 65535.
$ rand-guest/target/release/rand-guest build evm2rv/target/mytoken --max-words 65535
…
11686 words against a cap of 65535 (fits); 0 ecall(s) with a non-static a7
OK
wrote evm2rv/target/mytoken/image.bin and its .sha256 (11686 words, hc a0feae92a7311c9562495717100eb7aea71270a38ed435d06dc31387e0ea8ff6, program id f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d)
$ rand-guest/target/release/rand-guest info evm2rv/target/mytoken/image.bin
form: image container
text 11147 words at 0x10000; data 408 words (205 non-zero) at 0x1ae2c; prologue 539 words; program 11686 words from base_pc 0xf794
hc a0feae92a7311c9562495717100eb7aea71270a38ed435d06dc31387e0ea8ff6
program id f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d
11686 words against a cap of 4096: does not fit
Ini adalah hc tahap dua yang diterbitkan. Nama crate tidak memengaruhinya.
4. Bangun vektor input dan jalankan sebuah transfer
Contoh erc20_vector mencetak vektor-vektor uji paritas sebagai kata input: transfer (ALICE mengirim 250 dari 1.000 miliknya kepada BOB), approve (ALICE mengizinkan BOB membelanjakan 5), dan transferFrom (BOB memindahkan 100 dari 1.000 milik ALICE dengan allowance 300). Untuk kontrak Anda sendiri, bangun sebuah EvmCall dengan cara yang sama di Rust; contoh tersebut adalah templatnya.
$ (cd evm2rv && cargo +1.98.1 run -q --release --example erc20_vector -- transfer > target/transfer.words)
921 input words
$ rand-guest/target/release/rand-guest run evm2rv/target/mytoken/image.bin --input $(cat evm2rv/target/transfer.words)
out[0] = 1
out[1] = 513227413
out[2] = 3087537901
out[3] = 995619457
out[4] = 4004100029
out[5] = 234390638
out[6] = 3262201797
out[7] = 3842361427
cycles 66235
tier 18
5. Bandingkan dengan interpreter
Input yang sama pada guest interpreter:
$ rand-guest/target/release/rand-guest run guests-compiled/bin/evm.bin --input $(cat evm2rv/target/transfer.words)
out[0] = 1
out[1] = 513227413
out[2] = 3087537901
out[3] = 995619457
out[4] = 4004100029
out[5] = 234390638
out[6] = 3262201797
out[7] = 3842361427
cycles 121638
tier 18
Dan interpreter yang dijalankan secara native pada host, yaitu oracle untuk pengujian:
$ (cd evm2rv && cargo +1.98.1 run -q --release --example erc20_vector -- transfer --expected)
out[0] = 1
out[1] = 513227413
…
out[7] = 3842361427
interpreter (native): status 1, Return, gas_used 29956
Pemeriksaan sebagai satu perintah:
$ diff <(rand-guest/target/release/rand-guest run evm2rv/target/mytoken/image.bin --input $(cat evm2rv/target/transfer.words) | grep '^out') \
<(rand-guest/target/release/rand-guest run guests-compiled/bin/evm.bin --input $(cat evm2rv/target/transfer.words) | grep '^out') \
&& echo "the eight words are identical"
the eight words are identical
Ulangi langkah 4 dan 5 dengan approve dan transferFrom; keduanya menghasilkan word yang identik. cd evm2rv && cargo +1.98.1 test --release menjalankan ini beserta lima vektor lainnya pada kedua tahap, dan juga memeriksa gas_used (70 pengujian, ditambah 2 bukti yang diabaikan).
| diterjemahkan (tahap dua) | interpreter (evm.bin) | |
|---|---|---|
| delapan word keluaran | identik | identik |
| siklus, transfer | 66,235 | 121,638 |
| tier | 18 | 18 |
| word program | 11,686 | 18,009 |
6. Deploy
rand program deploy evm2rv/target/mytoken/image.bin
Wallet mencetak id program, jumlah word, dan hc, lalu memeriksa batas (cap) chain sebelum membuktikan apa pun. Image tersebut berukuran 11,686 word, sehingga memerlukan chain yang genesis-nya menetapkan max_program_words setidaknya 11,686. Chain 12 menjalankan nilai bawaan 4,096, sehingga deploy ditolak di sana. Chain 13, chain v0.4, menetapkan max_program_words sebesar 65,535, dan setiap chain sesudahnya mempertahankan nilai itu. Chain 20, chain yang sedang aktif (genesis 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135), juga mempertahankan batas blok, call-envelope, dan public-input milik chain 13, serta memangkas batas proof menjadi setengahnya, yakni 4 MiB (4,194,304 byte, sejak chain 17; chain 13 sampai 16 menetapkan 8 MiB). Batas word bukan lagi satu-satunya gerbang. Genesis chain 20 menetapkan hardening_v6, dan dengan pengaturan itu deploy program yang jumlah word-nya melebihi kapasitas sebuah call pada batas call tier-14 dinyatakan tidak valid (ProgramUncallable): paling banyak 8,180 word tanpa public input. Image ini berukuran 11,686 word, sehingga chain 20 menolak deploy-nya, dan juga akan menolak call-nya: setiap call ERC-20 dibuktikan pada tier 16 atau 18, di atas batas call tier-14 (langkah 7). Agregasi blok nonaktif pada chain 20 (genesis-nya tidak memiliki bagian aggregation); node bootstrap-nya tercantum di Menjalankan validator. Biaya deploy adalah 0.001 + 0.0001 × 11,686 = 1.1696 RAND, yaitu biaya yang dibayar oleh deploy pada chain 13 di bawah ini.
Deploy ini dijalankan pada chain 13 pada 2026-09-19, ketika chain 13 menjadi chain yang aktif (profil FRI produksi, genesis 8123ccac1883a45750e4df6964fb7cd3f0b321798cde4c0ef406a0293939ece3), dari wallet genesis shielded-1. Setiap chain sesudahnya (14 sampai 19) dibuat sebagai chain baru tanpa program milik chain 13, dan image tersebut belum pernah di-deploy ulang pada chain mana pun di antaranya, sehingga transaksi dan tinggi blok di bawah ini milik chain 13 dan tidak lagi dapat ditemukan di explorer. Id program adalah hash dari base_pc dan word saja, sehingga image yang sama memperoleh id yang sama pada chain mana pun yang menerima deploy-nya. Output wallet, dengan baris progresnya dihilangkan (…):
$ rand program deploy <image.bin>
program id: f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d (11686 words, hc 92aefea0951c31a717574962aeb70e10a37012a7d035d48e8713c36df68feae0)
…
proved in 92.2s: tier 14, 1419655 bytes
submitted deploy c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0
…
| id program | f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d |
| image | 11,686 word; hc a0feae92… dalam penulisan rand-guest, 92aefea0… dalam penulisan wallet |
| bundel biaya (bundel 2-in-2-out chain 13) | tier 14, 1,419,655 byte, dibuktikan dalam 92.2 s |
| tx deploy (chain 13) | c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0 |
| di-commit pada tinggi (chain 13) | 381 |
Sejak chain 14, bundel pembayaran adalah satu bundel hidden-asset 4-in-4-out yang dibawa setiap transaksi, dibuktikan terhadap binding transaksi. Bundel ini masih berada pada tier 14: sekitar 100 s dan sekitar 1.42 MB pada profil produksi di chain 14 dan 15. Sejak chain 17, sebuah bundel juga membawa proof auth tier-10 (otorisasi terpisah), sehingga pada chain 18 dan 19 bundel biaya sebuah transaksi berukuran sekitar 1.49 MB proof bundel dan sekitar 1.37 MB proof auth.
7. Call
Sebuah call transfer membawa vektor 921 word sebagai input privat, di bawah batas input pada chain mana pun (4,295 word secara bawaan, 16,071 pada chain 20), dan tanpa word publik. Call ini tidak dapat diajukan ke chain 20: program tidak dapat di-deploy di sana (langkah 6), transfer dibuktikan pada tier 18, dan sejak fullnode v0.5.6 (2026-09-25) sebuah node menolak setiap proof call di atas tier 14 dengan CallTierTooHigh, sebelum membangun verifier key. Perintah di bawah membuktikan secara lokal dan chain menolak hasilnya; pengukuran tersebut adalah proof off-chain. rand call menerima setiap word sebagai --input berulang:
rand call f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d \
$(for w in $(cat evm2rv/target/transfer.words); do printf -- '--input %s ' "$w"; done)
Kini telah terukur. Proof tier-18 dihentikan paksa pada laptop 48 GB di 24.7 GB, tetapi pada droplet 128 GB (m-16vcpu-128gb) call transfer hasil terjemahan berhasil dibuktikan: RSS puncak 85.0 GB, 3,230.5 s (53.8 menit), proof berukuran 811,600 byte. Proof itu terverifikasi dalam 101.4 s pada droplet dan 50.2 s pada RSS 3.66 GB pada laptop Apple-silicon 48 GB (memori pembuktian). Di bawah jadwal tier datar milik ledger, yaitu aturan pada chain tanpa bagian gas (hingga chain 17), biaya call pada tier 18 adalah 0.0024 RAND. Chain 18 dan 19 menetapkan harga call berdasarkan batas gas yang dideklarasikan dan ukuran byte-nya, 100 unit per gas dan 800 per KiB pada harga genesis, serta tidak menerima call di atas tier 14.
Call pada chain 13, 2026-09-19
Call approve(BOB, 5) (649 word privat, tier 16) dijalankan pada chain 13 pada 2026-09-19, ketika chain itu menjadi chain yang aktif, dengan profil FRI produksi, dari wallet yang sama. Tidak ada call yang dilakukan pada chain mana pun sesudahnya, karena program tidak di-deploy di sana, dan chain 20 menolak proof call tier-16 ini (CallTierTooHigh). Output wallet, dengan baris progresnya dihilangkan (…):
$ rand call f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d --input <w0> --input <w1> … # the 649 words of approve(BOB, 5)
…
proved in 388.7s: tier 16, 3412405 bytes, outputs [1, 942495465, 790002515, 1351749335, 1059083501, 2923046783, 2814575942, 696258848]
…
proved in 96.0s: tier 14, 1420423 bytes
submitted call 279e1f62abf3f177ca71b08c633e051c37bc4720118c79ddb00936f036c4bfa7
…
| proof call | tier 16, 3,412,405 byte, dibuktikan dalam 388.7 s |
| bundel biaya (bundel 2-in-2-out chain 13) | tier 14, 1,420,423 byte, dibuktikan dalam 96.0 s |
| envelope tersegel | 2,700 byte |
| tx call (chain 13) | 279e1f62abf3f177ca71b08c633e051c37bc4720118c79ddb00936f036c4bfa7 |
| di-anchor pada / di-commit pada | tinggi 802 / tinggi 919 |
| biaya | 0.00357 RAND |
receipt h_pub | null |
| output receipt | sama dengan delapan word interpreter untuk vektor yang sama |
| waktu total, RSS puncak | 622.8 s, 22.9 GB, pada laptop seri M 48 GB |
- Proof produksi berukuran 3,412,405 byte, melampaui batas proof 2 MiB milik chain 12. Chain 12 tidak dapat menerima call ini; batas 8 MiB milik chain 13 dapat menerimanya. Chain 14 sampai 16 mempertahankan batas yang sama, dan chain 17 sampai 20 menetapkan 4 MiB (4,194,304 byte), yang masih dapat menampung proof sebesar ini. Sejak v0.5.6 sebuah node menolak call berdasarkan tier-nya sebelum memeriksa ukurannya.
- Biaya mencakup suku byte dari jadwal chain 13: proof 3.41 MB berada di atas kelonggaran gratis 2 MiB + 18,432 byte. Sejak chain 18 setiap call membayar per KiB sejak byte 0.
Delapan word receipt adalah yang tercantum pada langkah 4. Chain tidak menyimpan state EVM: pemanggil menyediakan root pra-state dan saksi storage, dan root pasca-state berada di dalam digest EVM_OUT.
Limits
- Tanpa konteks blok. Sembilan opcode konteks blok akan trap hingga ada rancangan pengikatan blok.
- Tanpa transfer nilai.
CALLdengan nilai bukan nol akan trap. Pemanggilan ke kontrak selain precompile akan trap. - ecrecover, bn256 mul, pairing, dan modexp berukuran besar belum dapat dibuktikan saat ini. Masing-masing melampaui batas tier 2²⁰ baris; semuanya memerlukan tabel koprosesor.
- Tidak ada state EVM di rantai. Satu pemanggilan adalah satu bukti atas satu eksekusi; pemanggil yang membawa state tersebut.
- Baik deploy maupun pemanggilan ERC-20 tidak dapat diterima di chain 20. Berdasarkan
hardening_v6pada chain 20, deploy dengan jumlah word yang lebih banyak daripada yang dapat dimuat oleh pemanggilan tier 14 dinyatakan tidak valid (ProgramUncallable; maksimum 8.180 word), sedangkan image-nya berukuran 11.686. Sejak fullnode v0.5.6, bukti pemanggilan harus berada pada tier 14 atau lebih rendah (CallTierTooHigh);approvedibuktikan pada tier 16, sedangkantransferdantransferFrompada tier 18. Pemeriksaan yang sama juga membatasi tabel hash yang boleh dideklarasikan oleh sebuah pemanggilan: 2¹² baris Keccak (128 permutasi) dan 2¹³ baris SHA-256 (128 kompresi). Pemanggilan tersebut tetap dapat dibuktikan di luar rantai, seperti diuraikan di bawah. - Indeks storage memiliki kedalaman 32 bit.
evm-coremenempatkan leaf storage kontrak berdasarkan 32 bit teratas darikeccak256(slot), sehingga untuk menemukan slot yang bertabrakan dengan slot yang dipilih diperlukan sekitar 2³² hash Keccak, dan selama slot tersebut berisi nilai bukan nol, slot yang dipilih akan terkunci (tanpa pemalsuan dan tanpa kehilangan nilai). Hal ini bersifat dorman:evm.binberukuran 18.009 word, sedangkan pemanggilan pada batas tier 14 memuat paling banyak 8.184, sehingga tidak ada runtime EVM yang dapat dipanggil di rantai mana pun. Berkasdocs/confidential.mdmilik fullnode mencatat prasyarat tersebut di samping batas pemanggilan (audit v6, ZKV-6; dimainsejak 2026-09-30, setelah tag v0.6.7): sebelum sebuah rantai mengangkat batas pemanggilan tier 14 atau menerima runtime EVM yang cukup kecil untuk dipanggil, indeks storage harus diperdalam danevm.bindipin ulang. - Terbukti. Bukti transfer tahap satu (tier 18) di-SIGKILL pada laptop 48 GB di angka 24,7 GB setelah 1.016 detik, tetapi pemanggilan
transfertahap dua berhasil dibuktikan pada droplet 128 GB (m-16vcpu-128gb): RSS puncak 85,0 GB, 3.230,5 detik (53,8 menit), bukti sebesar 811.600 byte, diverifikasi dalam 101,4 detik (droplet) dan 50,2 detik pada RSS 3,66 GB (laptop 48 GB). Bukti transfer darievm.binmilik interpreter menunjukkan hasil yang sangat mirip: 85,5 GB, 3.143,3 detik (52,4 menit), bukti sebesar 805.108 byte — dan kedua bukti memuat word keluaran publik yang identik, yang mengonfirmasi paritas pada prover yang sesungguhnya.approve(tier 16, hasil translasi) jauh lebih murah: 21,7 GB, 786,7 detik (13,1 menit), bukti sebesar 798.930 byte. Translasi hanya menurunkan biaya pembuktian apabila sebuah pemanggilan turun ke tier yang lebih kecil. - Rantai tidak mencatat bytecode. Publikasikan bytecode tersebut agar pihak lain dapat membangun ulang
hc.