evm2rv EVM रनटाइम बाइटकोड लेता है, जो solc --bin-runtime का आउटपुट है, और उसे एक Rand प्रोग्राम में बदल देता है। यह C लिखता है, और rand-guest build उस C को एक RV32IM इमेज में कंपाइल करता है। यह इमेज वही इनपुट वेक्टर लेती है जो Rand का EVM इंटरप्रेटर गेस्ट, evm.bin, लेता है, और वही आठ आउटपुट शब्द प्रकाशित करती है। यह कॉन्ट्रैक्ट को ऑपकोड-दर-ऑपकोड इंटरप्रेट करने के बजाय नेटिव रूप से चलाती है। यह पृष्ठ एक ERC-20 पर पूरा मार्ग दिखाता है।
यह क्या है
| इनपुट | EVM रनटाइम बाइटकोड, हेक्स टेक्स्ट (.hex) या कच्चे बाइट्स के रूप में |
| आउटपुट | एक C शिम क्रेट; rand-guest build उसे एक इमेज कंटेनर बनाता है |
| यह कहाँ चलता है | ऑफ़-चेन, डेवलपर की मशीन पर; चेन केवल इमेज देखती है |
| इसे किससे मेल खाना चाहिए | evm.bin की स्थिति, आठ आउटपुट शब्द और gas_used |
| रिपॉज़िटरी | circuits रिपॉज़िटरी में evm2rv/ |
| निर्धारित टूलचेन | Rust 1.98.1, clang 23.1.1, cc क्रेट 1.4.6 |
ट्रांसलेटर रनटाइम कोड लेता है, क्रिएशन कोड नहीं। एक प्रूफ़ किसी डिप्लॉय किए गए कॉन्ट्रैक्ट की एक कॉल को कवर करता है, इसलिए कंस्ट्रक्टर कभी नहीं चलता। कंस्ट्रक्टर जो स्टेट लिखता, वह इसके बजाय प्री-स्टेट का हिस्सा होती है, स्टोरेज विटनेस के रूप में।
अनुवाद के दो चरण हैं। दोनों समान परिणाम और गैस देते हैं; प्रत्येक अपना अलग प्रोग्राम है जिसका अपना hc है।
| चरण | फ़्लैग | यह क्या करता है |
|---|---|---|
| एक | --stage 1 | मेमोरी स्टैक पर हर ऑपकोड |
| दो | --stage 2, डिफ़ॉल्ट | हर ब्लॉक के स्टैक शब्द C लोकल वेरिएबल में, स्थिरांक अनुवाद के समय फ़ोल्ड किए जाते हैं |
इनपुट वेक्टर इंटरप्रेटर वाला ही है: कोड, कॉलडेटा, कॉलर और अन्य परिवेश शब्द, गैस सीमा, प्री-स्टेट रूट, और कॉल जिस भी स्लॉट को छूती है उसके लिए एक स्टोरेज विटनेस। आउटपुट हैं out[0], स्थिति (1 सफलता, 0 रिवर्ट, 2 असाधारण हॉल्ट), और out[1..8], कोड हैश, दोनों स्टेट रूट, रिटर्न डेटा और लॉग पर EVM_OUT डाइजेस्ट।
विश्वास मॉडल
एक सत्यापनकर्ता अनुवादित कॉन्ट्रैक्ट की जाँच दो चरणों में करता है।
hc == translate(bytecode)। प्रकाशित बाइटकोड पर उसी--stageऔर--chain-idके साथevm2rvफिर से चलाएँ, निर्धारित टूलचेन से फिर से बिल्ड करें, औरhcकी तुलना करें। जनरेट किया गया क्रेटccको सटीक रूप से निर्धारित करता है और उसका अपनाCargo.lockहोता है।- कोड गार्ड
hcको बाइटकोड से बाँधता है। अनुवादित लॉजिक इमेज में कंपाइल होता है, लेकिनCODECOPYऔरCODESIZEइनपुट वेक्टर का कोड पढ़ते हैं। जाँच के बिना, एक हीhcकॉलर द्वारा चुने गए कोड बाइट्स के साथ चल सकता था। इसलिएcontract.cस्रोत बाइटकोड (उसकी लंबाई और बाइट्स) का एक Poseidon2 डाइजेस्ट रखता है, और कोई भी अनुवादित कोड चलने से पहले शिम इनपुट वेक्टर के कोड को उसी तरह हैश करता है। अन्य कोड अस्वीकार कर दिया जाता है: स्थिति 2,gas_used0, हॉल्टOutOfBounds।
EVM_OUT डाइजेस्ट कोड के keccak256 को भी बाँधता है, जैसा इंटरप्रेटर का डाइजेस्ट करता है। चेन स्रोत बाइटकोड या उसका हैश दर्ज नहीं करती। दूसरों को hc की जाँच करने देने के लिए, बाइटकोड प्रकाशित करें, या Solidity स्रोत और सटीक solc बिल्ड।
ट्रांसफ़र पर गार्ड की लागत 1,008 साइकिल है। स्रोत से एक बाइट भी भिन्न कोड चरण दो पर 30,418 साइकिल में अस्वीकार हो जाता है (टियर 16)।
कवरेज, और क्या ट्रैप होता है
ऑपकोड। Shanghai सेट। --evm-version shanghai के साथ कंपाइल करें: नए टारगेट MCOPY और अन्य Cancun ऑपकोड उत्पन्न करते हैं, जो ट्रैप होते हैं।
परिवेश ऑपकोड:
| ऑपकोड | अनुवाद |
|---|---|
ADDRESS, CALLER, CALLVALUE, CALLDATASIZE, CODESIZE | इनपुट वेक्टर से, जैसे इंटरप्रेटर उन्हें पढ़ता है |
CHAINID | --chain-id का मान, अनुवाद के समय अंतर्निहित, इसलिए hc उसे बाँधता है; जब कोड में CHAINID हो तब आवश्यक |
ORIGIN | CALLER के बराबर (एक कॉल, कोई रिलेयर नहीं) |
GASPRICE, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, SELFBALANCE, BASEFEE, BLOCKHASH | ट्रैप (स्थिति 2), जैसा इंटरप्रेटर में |
नौ ब्लॉक-संदर्भ ऑपकोड तब तक ट्रैप होते हैं जब तक उन्हें किसी ब्लॉक से बाँधने का डिज़ाइन नहीं बन जाता। एक निजी इनपुट किसी ब्लॉक तथ्य को नहीं ले जा सकता, क्योंकि सत्यापनकर्ता H_IN को खोल नहीं सकता। जब तक यह निर्णय नहीं हो जाता, समय या ब्लॉक संख्या पढ़ने वाला कॉन्ट्रैक्ट (उदाहरण के लिए, एक permit की समय-सीमा) ट्रैप होता है।
कॉल। CALL, CALLCODE, DELEGATECALL और STATICCALL एक प्रीकंपाइल चलाते हैं जब लक्ष्य पता 1 से 9 हो। कोई भी अन्य लक्ष्य ट्रैप होता है। CALL या CALLCODE पर शून्येतर मान ट्रैप होता है: कोई बैलेंस मॉडल नहीं है।
प्रीकंपाइल। सभी नौ सॉफ़्टवेयर में चलते हैं। कुछ आज प्रूव करने के लिए बहुत धीमे हैं, क्योंकि एक प्रूफ़ में अधिकतम 2²⁰ पंक्तियाँ होती हैं:
| प्रीकंपाइल | वेक्टर | साइकिल | 2²⁰ में समाता है |
|---|---|---|---|
| 1 ecrecover | ValidKey | 14,510,525 | नहीं |
| 2 sha256 | ”abc” / 200 बाइट्स | 2,791 / 5,289 | हाँ |
| 3 ripemd160 | ”abc” | 12,195 | हाँ |
| 4 identity | 100 बाइट्स | 4,498 | हाँ |
| 5 modexp | nagydani-1-square / -1-pow0x10001 | 122,332 / 874,548 | हाँ |
| 5 modexp | eip_example1 (256-बिट) | 11,170,118 | नहीं |
| 5 modexp | nagydani-5-pow0x10001 (1,024-बाइट) | 55,076,950 | नहीं |
| 6 bn256 add | chfast1 | 978,262 | हाँ, बमुश्किल |
| 7 bn256 mul | chfast1 | 3,060,669 | नहीं |
| 8 bn256 pairing | 1 जोड़ी / 2 जोड़ियाँ | 1,853,656,212 / 2,019,000,469 | नहीं |
| 9 blake2f | 12 राउंड | 14,493 | हाँ, लगभग 1,800 राउंड तक |
modexp का बेस और मॉड्यूलस प्रत्येक 1,024 बाइट्स तक सीमित हैं।
स्वीकृत विचलन। स्थिति, आठ शब्द और gas_used मेल खाने चाहिए। तीन अंतर स्वीकार्य हैं: हॉल्ट का प्रकार भिन्न हो सकता है (स्थैतिक गैस हर ब्लॉक के आरंभ में ली जाती है, इसलिए OutOfGas और कोई अन्य हॉल्ट आपस में बदल सकते हैं; दोनों स्थिति 2 हैं और पूरी गैस उपयोग होती है); अनुवाद CHAINID, ORIGIN और प्रीकंपाइल कॉल लागू करता है, जिन पर इंटरप्रेटर ट्रैप होता है; और कोड गार्ड अपने स्रोत के अलावा अन्य कोड को अस्वीकार करता है।
आँकड़े
ERC-20 कॉल, कोड गार्ड सहित। साइकिल rand-guest run से; टियर कोष्ठक में।
| कॉल | इंटरप्रेटर (evm.bin) | चरण एक | चरण दो (डिफ़ॉल्ट) |
|---|---|---|---|
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) |
| प्रोग्राम | शब्द | hc |
|---|---|---|
evm.bin, इंटरप्रेटर | 18,009 | 7e1aea2b…854c08 |
| ERC-20, चरण एक | 15,804 | 9cdb79e7…2fd048c8 |
| ERC-20, चरण दो | 11,686 | a0feae92a7311c9562495717100eb7aea71270a38ed435d06dc31387e0ea8ff6 |
चरण दो तीनों कॉल इंटरप्रेटर के साइकिलों के 54.5%, 56.2% और 55.0% में चलाता है। ट्रांसफ़र टियर 18 पर ही रहता है: उसके 66,235 साइकिल और 3,155 डाइजेस्ट पंक्तियाँ मिलकर 69,390 पंक्तियाँ होती हैं, जो टियर 16 की 65,535 से 3,855 अधिक हैं।
चरण-दो ट्रांसफ़र का लगभग 60% (लगभग 39,928 साइकिल) वह हार्नेस है जो दोनों इमेज साझा करती हैं: इनपुट को डिकोड करना, स्टोरेज विटनेस का सत्यापन, ABI की keccak256 कॉल और आउटपुट डाइजेस्ट। कोई भी अनुवाद कार्य इस न्यूनतम स्तर से नीचे नहीं जाता।
पूर्ण उदाहरण: एक ERC-20, Solidity से मेल खाते आउटपुट तक
हर कमांड 7ef3220 पर circuits चेकआउट के रूट से चलती है, Rust प्रोग्राम डिप्लॉय करें के टूलचेन और RISC-V प्रोग्राम डिप्लॉय करें के clang 23.1.1 के साथ। लंबा आउटपुट वहाँ काटा गया है जहाँ … अंकित है।
0. टूल बिल्ड करें
(cd evm2rv && cargo +1.98.1 build --release)
(cd rand-guest && cargo +1.98.1 build --release)
1. Solidity को रनटाइम बाइटकोड में कंपाइल करें
कॉन्ट्रैक्ट कमिट किया गया guests-compiled/evm/contracts/ERC20.sol है: OpenZeppelin v4 के स्टोरेज लेआउट वाला एक स्व-निहित ERC-20, pragma solidity 0.8.37। ठीक solc 0.8.37 का ही उपयोग करें; कोई अन्य संस्करण अलग ढंग से ऑप्टिमाइज़ करता है और भिन्न बाइटकोड देता है।
| रिलीज़ | github.com/ethereum/solidity/releases से v0.8.37 |
| macOS एसेट | solc-macos, sha256 a27396e7732aa52e80ff89ad7bd8a2e46fec2a6dcc4ef20cd16e5e0c502d6821 |
| Linux एसेट | solc-static-linux, उसी रिलीज़ से |
$ 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
अंतिम पंक्ति रनटाइम बाइटकोड है, 1,296 बाइट्स। यह कमिट किए गए guests-compiled/evm/contracts/erc20.runtime.hex से बाइट-दर-बाइट समान है; SOLC=$PWD/solc bash guests-compiled/evm/contracts/build.sh इसकी जाँच करता है और contracts: erc20.runtime.hex reproduces प्रिंट करता है।
फ़्लैग महत्वपूर्ण हैं:
--bin-runtime: डिप्लॉय किया गया कोड, क्रिएशन कोड नहीं।--evm-version shanghai: 0.8.37 का डिफ़ॉल्ट टारगेटMCOPYउत्पन्न करता है, जो ट्रैप होता है।--optimize --optimize-runs 200: डिप्लॉय किए गए कॉन्ट्रैक्ट की प्रोफ़ाइल।
2. अनुवाद करें
$ 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
--outकिसी circuits चेकआउट के भीतर होना चाहिए। इसके बिना,evm2rvकेवल कोड का विश्लेषण करता है।- कोई भी ट्रैप होने वाला ऑपकोड यहाँ चेतावनी के रूप में, अपने pc के साथ, सूचीबद्ध होता।
- यह सत्र
--chain-id 12के साथ रिकॉर्ड किया गया था। इस ERC-20 में कोईCHAINIDनहीं है, इसलिए--chain-idइसकेhcको नहीं बदलता।CHAINIDपढ़ने वाले कॉन्ट्रैक्ट के लिए यह फ़्लैग आवश्यक है; इसे उस चेन पर सेट करें जिस पर आप डिप्लॉय करेंगे (लाइव चेन के लिए--chain-id 19)।
contract.c कोड गार्ड के डाइजेस्ट के साथ समाप्त होता है:
const uint32_t *evm_code_digest(void) {
static const uint32_t d[8] = {0xf679280fu, 0x86c10e83u, 0x7e8f1f39u, 0xa2377de3u, 0x8a2e282fu, 0xc54cad42u, 0xddfaf009u, 0x7d28a8afu};
return d;
}
3. इमेज बिल्ड करें
डिफ़ॉल्ट सीमा 4,096 शब्द है, इसलिए --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
यह प्रकाशित चरण-दो hc है। क्रेट का नाम इसे प्रभावित नहीं करता।
4. एक इनपुट वेक्टर बनाएँ और एक ट्रांसफ़र चलाएँ
erc20_vector उदाहरण पैरिटी टेस्ट के वेक्टर इनपुट शब्दों के रूप में प्रिंट करता है: transfer (ALICE अपने 1,000 में से 250 BOB को भेजती है), approve (ALICE, BOB को 5 ख़र्च करने देती है) और transferFrom (BOB, 300 की अनुमति के विरुद्ध ALICE के 1,000 में से 100 स्थानांतरित करता है)। अपने कॉन्ट्रैक्ट के लिए, Rust में इसी तरह एक EvmCall बनाएँ; यह उदाहरण टेम्पलेट है।
$ (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. इंटरप्रेटर से तुलना करें
वही इनपुट इंटरप्रेटर गेस्ट पर:
$ 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
और होस्ट पर नेटिव रूप से चलाया गया interpreter, जो परीक्षणों का oracle है:
$ (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
एक ही कमांड के रूप में जाँच:
$ 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
चरण 4 और 5 को approve और transferFrom के साथ दोहराएँ; दोनों समान words देते हैं। cd evm2rv && cargo +1.98.1 test --release इन्हें और पाँच अन्य vectors को दोनों चरणों में चलाता है, और gas_used की भी जाँच करता है (70 परीक्षण, साथ में 2 उपेक्षित proofs)।
| अनूदित (चरण दो) | interpreter (evm.bin) | |
|---|---|---|
| आठ आउटपुट words | समान | समान |
| cycles, transfer | 66,235 | 121,638 |
| tier | 18 | 18 |
| प्रोग्राम words | 11,686 | 18,009 |
6. डिप्लॉय
rand program deploy evm2rv/target/mytoken/image.bin
वॉलेट प्रोग्राम id, words की संख्या और hc प्रिंट करता है, फिर कुछ भी prove करने से पहले चेन की सीमा जाँचता है। इमेज 11,686 words की है, इसलिए इसे ऐसी चेन चाहिए जिसका genesis max_program_words को कम से कम 11,686 पर सेट करे। चेन 12 डिफ़ॉल्ट 4,096 पर चलती थी, इसलिए वहाँ डिप्लॉय अस्वीकार हो गया। चेन 13, यानी v0.4 चेन, ने max_program_words को 65,535 पर सेट किया, और उसके बाद की हर चेन यही मान रखती है। चेन 20, जो लाइव चेन है (genesis 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135), चेन 13 की block, call-envelope और public-input सीमाएँ भी रखती है और proof की सीमा आधी करके 4 MiB कर देती है (4,194,304 bytes, चेन 17 से; चेन 13 से 16 ने 8 MiB सेट किया था)। अब word सीमा ही एकमात्र अवरोध नहीं है। चेन 20 का genesis hardening_v6 सेट करता है, और इसके अंतर्गत ऐसा डिप्लॉय अमान्य है (ProgramUncallable) जिसमें tier-14 call सीमा पर एक call में समा सकने वाले words से अधिक प्रोग्राम words हों: बिना public input के अधिकतम 8,180 words। यह इमेज 11,686 words की है, इसलिए चेन 20 डिप्लॉय अस्वीकार करती है, और वह calls भी अस्वीकार कर देती: हर ERC-20 call tier 16 या 18 पर prove होता है, जो tier-14 call सीमा से ऊपर है (चरण 7)। चेन 20 पर block aggregation बंद है (उसके genesis में कोई aggregation खंड नहीं है); उसके bootstrap नोड वैलिडेटर चलाना में सूचीबद्ध हैं। डिप्लॉय शुल्क 0.001 + 0.0001 × 11,686 = 1.1696 RAND है, वही शुल्क जो नीचे दिए गए चेन-13 डिप्लॉय ने चुकाया।
यह डिप्लॉय 2026-09-19 को चेन 13 पर चला, जब चेन 13 लाइव चेन थी (production FRI प्रोफ़ाइल, genesis 8123ccac1883a45750e4df6964fb7cd3f0b321798cde4c0ef406a0293939ece3), genesis वॉलेट shielded-1 से। उसके बाद की हर चेन (14 से 19) चेन 13 के प्रोग्रामों के बिना नई चेन के रूप में शुरू की गई, और इमेज को उनमें से किसी पर फिर से डिप्लॉय नहीं किया गया है, इसलिए नीचे दिया गया transaction और height चेन 13 के हैं और अब explorer पर नहीं मिलते। प्रोग्राम id केवल base_pc और words का hash है, इसलिए वही इमेज ऐसी किसी भी चेन पर वही id पाती है जो डिप्लॉय स्वीकार करे। वॉलेट का आउटपुट, प्रगति पंक्तियाँ छोड़कर (…):
$ rand program deploy <image.bin>
program id: f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d (11686 words, hc 92aefea0951c31a717574962aeb70e10a37012a7d035d48e8713c36df68feae0)
…
proved in 92.2s: tier 14, 1419655 bytes
submitted deploy c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0
…
| प्रोग्राम id | f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d |
| इमेज | 11,686 words; rand-guest की लिखावट में hc a0feae92…, वॉलेट की लिखावट में 92aefea0… |
| शुल्क bundle (चेन 13 का 2-in-2-out bundle) | tier 14, 1,419,655 bytes, 92.2 s में prove हुआ |
| डिप्लॉय tx (चेन 13) | c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0 |
| जिस height पर committed हुआ (चेन 13) | 381 |
चेन 14 से भुगतान करने वाला bundle वही एक 4-in-4-out hidden-asset bundle है जो हर transaction साथ रखता है, और यह transaction के binding के विरुद्ध prove होता है। यह अब भी tier 14 है: चेन 14 और 15 पर production प्रोफ़ाइल में लगभग 100 s और लगभग 1.42 MB। चेन 17 से एक bundle में tier-10 auth proof (विभाजित प्राधिकरण) भी होता है, इसलिए चेन 18 और 19 पर किसी transaction का शुल्क bundle लगभग 1.49 MB का bundle proof और लगभग 1.37 MB का auth proof होता है।
7. Call
एक transfer call 921-word vector को private inputs के रूप में ले जाता है, जो किसी भी चेन की input सीमा के भीतर है (डिफ़ॉल्ट रूप से 4,295 words, चेन 20 पर 16,071), और कोई public words नहीं। इसे चेन 20 पर सबमिट नहीं किया जा सकता: प्रोग्राम वहाँ डिप्लॉय नहीं किया जा सकता (चरण 6), transfer tier 18 पर prove होता है, और fullnode v0.5.6 (2026-09-25) से नोड tier 14 से ऊपर के किसी भी call proof को verifier key बनाने से पहले ही CallTierTooHigh के साथ अस्वीकार कर देता है। नीचे दी गई कमांड स्थानीय रूप से prove करती है और चेन परिणाम को अस्वीकार कर देती है; माप off-chain proofs के हैं। rand call हर word को दोहराए गए --input के रूप में लेता है:
rand call f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d \
$(for w in $(cat evm2rv/target/transfer.words); do printf -- '--input %s ' "$w"; done)
अब इसका माप लिया जा चुका है। 48 GB लैपटॉप पर एक tier-18 proof 24.7 GB पर रोक दिया गया, लेकिन 128 GB droplet (m-16vcpu-128gb) पर अनूदित transfer call prove हो गया: 85.0 GB peak RSS, 3,230.5 s (53.8 मिनट), 811,600-byte का proof। यह droplet पर 101.4 s में और 48 GB Apple-silicon लैपटॉप पर 3.66 GB RSS के साथ 50.2 s में verify हुआ (proving मेमोरी)। ledger की सपाट tier अनुसूची के अंतर्गत, जो gas खंड रहित चेनों (चेन 17 तक) का नियम था, tier 18 पर call शुल्क 0.0024 RAND था। चेन 18 और 19 इसके बजाय call का मूल्य उसकी घोषित gas सीमा और उसके bytes के आधार पर तय करती हैं, genesis कीमतों पर प्रति gas 100 इकाइयाँ और प्रति KiB 800, और tier 14 से ऊपर कोई call स्वीकार नहीं करतीं।
चेन 13 पर call, 2026-09-19
approve(BOB, 5) call (649 private words, tier 16) 2026-09-19 को चेन 13 पर चला, जब वह लाइव चेन थी, production FRI प्रोफ़ाइल के साथ, उसी वॉलेट से। बाद की किसी भी चेन पर, जहाँ प्रोग्राम डिप्लॉय नहीं है, कोई call नहीं किया गया है, और चेन 20 इस tier-16 call proof को अस्वीकार करती है (CallTierTooHigh)। वॉलेट का आउटपुट, प्रगति पंक्तियाँ छोड़कर (…):
$ 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
…
| call proof | tier 16, 3,412,405 bytes, 388.7 s में prove हुआ |
| शुल्क bundle (चेन 13 का 2-in-2-out bundle) | tier 14, 1,420,423 bytes, 96.0 s में prove हुआ |
| sealed envelope | 2,700 bytes |
| call tx (चेन 13) | 279e1f62abf3f177ca71b08c633e051c37bc4720118c79ddb00936f036c4bfa7 |
| anchored at / committed at | height 802 / height 919 |
| शुल्क | 0.00357 RAND |
receipt h_pub | null |
| receipt outputs | उसी vector के लिए interpreter के आठ words के बराबर |
| कुल समय, peak RSS | 622.8 s, 22.9 GB, 48 GB M-series लैपटॉप पर |
- production proof 3,412,405 bytes का है, जो चेन 12 की 2 MiB proof सीमा से अधिक है। चेन 12 इस call को स्वीकार नहीं कर सकती थी; चेन 13 की 8 MiB सीमा ने इसे स्वीकार किया। चेन 14 से 16 ने वही सीमा रखी, और चेन 17 से 20 ने 4 MiB (4,194,304 bytes) सेट की, जिसके भीतर इस आकार का proof अब भी समा जाता है। v0.5.6 से नोड call को उसके आकार को देखने से पहले ही उसके tier के कारण अस्वीकार कर देता है।
- शुल्क में चेन 13 की अनुसूची का byte घटक शामिल है: 3.41 MB का proof 2 MiB + 18,432-byte की निःशुल्क सीमा से ऊपर है। चेन 18 से हर call byte 0 से ही प्रति KiB भुगतान करता है।
receipt के आठ words वही हैं जो चरण 4 में हैं। चेन कोई EVM state नहीं रखती: caller pre-state root और storage witnesses देता है, और post-state root EVM_OUT digest के भीतर होता है।
सीमाएँ
- कोई ब्लॉक संदर्भ नहीं। ब्लॉक-संदर्भ वाले नौ opcode तब तक trap करते हैं जब तक ब्लॉक-बाइंडिंग का कोई डिज़ाइन उपलब्ध नहीं हो जाता।
- कोई मूल्य अंतरण नहीं। शून्येतर मूल्य वाला
CALLtrap करता है। precompile के अतिरिक्त अन्य कॉन्ट्रैक्टों को किए गए कॉल भी trap करते हैं। - ecrecover, bn256 mul, pairing और बड़े modexp को आज प्रमाणित नहीं किया जा सकता। इनमें से प्रत्येक 2²⁰ पंक्तियों की टियर सीमा से अधिक है। इनके लिए coprocessor तालिकाएँ चाहिए।
- चेन पर कोई EVM स्थिति नहीं। एक कॉल एक रन पर एक प्रूफ़ है। स्थिति कॉल करने वाला साथ रखता है।
- chain 20 पर न डिप्लॉय स्वीकार्य है, न कोई ERC-20 कॉल। chain 20 के
hardening_v6के अंतर्गत, यदि किसी डिप्लॉय में उससे अधिक शब्द हों जितने एक टियर-14 कॉल में समा सकते हैं, तो वह डिप्लॉय अमान्य है (ProgramUncallable; अधिकतम 8,180 शब्द), और इमेज 11,686 शब्दों की है। fullnode v0.5.6 से कॉल प्रूफ़ का टियर 14 या उससे नीचे होना अनिवार्य है (CallTierTooHigh)।approveटियर 16 पर प्रमाणित होता है,transferऔरtransferFromटियर 18 पर। यही जाँच उन हैश तालिकाओं की भी सीमा तय करती है जिन्हें कोई कॉल घोषित कर सकता है: 2¹² Keccak पंक्तियाँ (128 permutation) और 2¹³ SHA-256 पंक्तियाँ (128 compression)। फिर भी ये कॉल ऑफ़-चेन प्रमाणित हो जाते हैं, जैसा नीचे बताया गया है। - स्टोरेज इंडेक्स की गहराई 32 बिट है।
evm-coreकॉन्ट्रैक्ट के स्टोरेज लीफ़ कोkeccak256(slot)के शीर्ष 32 बिट के आधार पर रखता है। इसलिए किसी चुने हुए स्लॉट से टकराने वाला स्लॉट खोजने में लगभग 2³² Keccak हैश लगते हैं। जब तक उस टकराने वाले स्लॉट में शून्येतर मान रहता है, चुना हुआ स्लॉट फ़्रीज़ रहता है (इससे न जालसाज़ी संभव है, न मूल्य की हानि होती है)। यह समस्या अभी सुप्त है:evm.bin18,009 शब्दों का है, जबकि टियर-14 सीमा पर एक कॉल में अधिकतम 8,184 शब्द समाते हैं। इसलिए किसी भी चेन पर कोई EVM रनटाइम कॉल करने योग्य नहीं है। fullnode काdocs/confidential.mdकॉल सीमा के साथ यह पूर्वशर्त भी दर्ज करता है (audit v6, ZKV-6; 2026-09-30 सेmainपर, v0.6.7 टैग के बाद): कोई चेन टियर-14 कॉल सीमा हटाए या कॉल करने योग्य आकार का कोई EVM रनटाइम स्वीकार करे, उससे पहले स्टोरेज इंडेक्स को गहरा करना होगा औरevm.binको फिर से पिन करना होगा। - प्रमाणित। टियर 18 का एक चरण-एक transfer प्रूफ़ 48 GB वाले लैपटॉप पर 1,016 s के बाद 24.7 GB पर SIGKILL हो गया। लेकिन चरण-दो का
transferकॉल 128 GB वाले droplet (m-16vcpu-128gb) पर प्रमाणित हुआ: 85.0 GB peak RSS, 3,230.5 s (53.8 min), 811,600-बाइट का प्रूफ़। इसका सत्यापन droplet पर 101.4 s में हुआ और 48 GB वाले लैपटॉप पर 3.66 GB RSS के साथ 50.2 s में। इंटरप्रेटर केevm.binवाले transfer प्रूफ़ के आँकड़े लगभग समान रहे: 85.5 GB, 3,143.3 s (52.4 min), 805,108-बाइट का प्रूफ़। दोनों प्रूफ़ के सार्वजनिक आउटपुट शब्द एक जैसे हैं, जिससे वास्तविक prover पर दोनों की समतुल्यता की पुष्टि होती है। अनूदितapprove(टियर 16) काफ़ी सस्ता है: 21.7 GB, 786.7 s (13.1 min), 798,930-बाइट का प्रूफ़। अनुवाद से प्रूविंग लागत तभी घटती है जब उसके कारण कोई कॉल छोटे टियर में आ जाए। - चेन बाइटकोड को दर्ज नहीं करती। इसे प्रकाशित करें ताकि दूसरे लोग
hcको फिर से बना सकें।