Rand Protocol
الوثائق
برامج RISC-V

مُحوِّل Ethereum

يُحوِّل evm2rv شيفرة EVM البايتية الخاصة بالتنفيذ إلى مجموعة تعليمات RISC-V في Rand: ما هو، ونموذج الثقة وحارس الشيفرة فيه، وشفرات العمليات والعقود المُصرَّفة المسبقة التي يغطيها ومواضع التوقف الاضطراري، والأرقام المقيسة، وشرح كامل لعقد ERC-20 بدءًا من Solidity مرورًا بـ solc --bin-runtime وصولًا إلى مخرجات تطابق مفسِّر EVM كلمةً بكلمة.

evm2rv يأخذ شيفرة EVM البايتية الخاصة بوقت التشغيل، أي ناتج solc --bin-runtime، ويحوّلها إلى برنامج Rand. يكتب الأداة شيفرة C، ثم يُصرّف rand-guest build هذه الشيفرة إلى صورة RV32IM. تأخذ الصورة متجه الإدخال نفسه الذي يأخذه ضيف مفسّر EVM في Rand، أي evm.bin، وتنشر كلمات الإخراج الثماني نفسها. وهي تشغّل العقد أصلياً بدلاً من تفسيره شيفرة تشغيل بعد أخرى. تعرض هذه الصفحة المسار كاملاً على عقد ERC-20.

ما هو

المُدخلشيفرة EVM البايتية الخاصة بـوقت التشغيل، نصاً سداسياً عشرياً (.hex) أو بايتات خام
المُخرجحزمة C وسيطة (shim crate)؛ ويحوّلها rand-guest build إلى حاوية صورة
مكان التشغيلخارج السلسلة، على جهاز المطوّر؛ ولا ترى السلسلة سوى الصورة
ما يجب أن يطابقهحالة evm.bin وكلمات الإخراج الثماني وgas_used
المستودع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 على تجزئة الشيفرة وجذري الحالة وبيانات الإرجاع والسجلات.

نموذج الثقة

يتحقق المُتحقِّق من العقد المترجَم في خطوتين.

  1. hc == translate(bytecode). أعد تشغيل evm2rv على الشيفرة البايتية المنشورة بالقيمتين نفسيهما لـ--stage و--chain-id، ثم أعد البناء بسلسلة الأدوات المثبّتة وقارن hc. تثبّت الحزمة المولَّدة cc بدقة وتحمل ملف Cargo.lock خاصاً بها.
  2. حارس الشيفرة يربط hc بالشيفرة البايتية. المنطق المترجَم مُصرَّف داخل الصورة، لكن CODECOPY وCODESIZE تقرآن الشيفرة من متجه الإدخال. وبلا فحص، يمكن تشغيل hc واحد مع بايتات شيفرة يختارها المُستدعي. لذلك يحمل contract.c ملخّص Poseidon2 للشيفرة البايتية المصدر (طولها وبايتاتها)، ويحسب الـshim ملخّصاً للشيفرة الموجودة في متجه الإدخال بالطريقة نفسها قبل تشغيل أي شيفرة مترجمة. وتُرفض أي شيفرة أخرى: الحالة 2، وgas_used يساوي 0، والتوقف 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. وإلى أن يُتخذ هذا القرار، فإن العقد الذي يقرأ الوقت أو رقم الكتلة (مهلة إذن، مثلاً) يتوقف.

الاستدعاءات. تشغّل CALL وCALLCODE وDELEGATECALL وSTATICCALL عقداً مُسبقاً (precompile) حين يكون الهدف هو العنوان من 1 إلى 9. وأي هدف آخر يؤدي إلى إيقاف. وأي قيمة غير صفرية في CALL أو CALLCODE تؤدي إلى إيقاف: فلا يوجد نموذج للأرصدة.

العقود المُسبقة. تعمل التسعة كلها برمجياً. وبعضها أبطأ من أن يُبرهَن عليه اليوم، لأن البرهان يتسع لـ2²⁰ صفاً على الأكثر:

العقد المُسبقالمتجهالدوراتيتسع في 2²⁰
1 ecrecoverValidKey14,510,525لا
2 sha256”abc” / 200 بايت2,791 / 5,289نعم
3 ripemd160”abc”12,195نعم
4 identity100 بايت4,498نعم
5 modexpnagydani-1-square / -1-pow0x10001122,332 / 874,548نعم
5 modexpeip_example1 (256 بت)11,170,118لا
5 modexpnagydani-5-pow0x10001 (1,024 بايت)55,076,950لا
6 bn256 addchfast1978,262نعم، بالكاد
7 bn256 mulchfast13,060,669لا
8 bn256 pairingزوج واحد / زوجان1,853,656,212 / 2,019,000,469لا
9 blake2f12 جولة14,493نعم، حتى نحو 1,800 جولة

أساس modexp ومقياسها (modulus) محدودان بـ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,0097e1aea2b…854c08
ERC-20، المرحلة الأولى15,8049cdb79e7…2fd048c8
ERC-20، المرحلة الثانية11,686a0feae92a7311c9562495717100eb7aea71270a38ed435d06dc31387e0ea8ff6

تشغّل المرحلة الثانية الاستدعاءات الثلاثة في 54.5% و56.2% و55.0% من دورات المفسّر. ويبقى التحويل في الطبقة 18: فدوراته البالغة 66,235 مع 3,155 صفاً للملخّص تساوي 69,390 صفاً، أي أكثر بـ3,855 من 65,535 في الطبقة 16.

نحو 60% من تحويل المرحلة الثانية (نحو 39,928 دورة) هو الأساس المشترك بين الصورتين: فك ترميز الإدخال، والتحقق من شواهد التخزين، واستدعاءات keccak256 الخاصة بواجهة ABI، وملخّص الإخراج. ولا يخفض عمل الترجمة التكلفة عن هذا الحد الأدنى.

شرح تطبيقي: عقد ERC-20، من Solidity إلى مخرجات متطابقة

يُشغَّل كل أمر من جذر نسخة من مستودع الدارات عند 7ef3220، مع سلسلة الأدوات من انشر برنامج Rust وclang 23.1.1 من انشر برنامج RISC-V. والمخرجات الطويلة مقتطعة حيث وُضعت العلامة ….

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: عقد ERC-20 قائم بذاته بتخطيط تخزين OpenZeppelin v4، مع pragma solidity 0.8.37. استخدم solc 0.8.37 تحديداً؛ فأي إصدار آخر يحسّن بطريقة مختلفة ويعطي شيفرة بايتية مختلفة.

الإصدارv0.8.37 من github.com/ethereum/solidity/releases
ملف macOSsolc-macos، وقيمة sha256 هي a27396e7732aa52e80ff89ad7bd8a2e46fec2a6dcc4ef20cd16e5e0c502d6821
ملف Linuxsolc-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 داخل نسخة من مستودع الدارات. وبدونه يكتفي 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 إلى BOB مبلغ 250 من أصل 1,000 لديها)، وapprove (تسمح ALICE لـBOB بإنفاق 5)، وtransferFrom (ينقل BOB مبلغ 100 من 1,000 تخص ALICE مقابل مخصَّص قدره 300). ولعقدك الخاص، ابنِ EvmCall بالطريقة نفسها في Rust؛ والمثال هو القالب.

$ (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

والمفسِّر مُشغَّلًا أصليًا على المضيف، وهو المرجع الذي تُقارَن به نتائج الاختبارات:

$ (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؛ فكلتاهما تعطيان الكلمات نفسها. يشغّل الأمر cd evm2rv && cargo +1.98.1 test --release هذه الحالات وخمس متجهات أخرى في كلتا المرحلتين، ويتحقق أيضًا من gas_used (70 اختبارًا، إضافة إلى إثباتين متجاهَلين).

المُترجَم (المرحلة الثانية)المفسِّر (evm.bin)
كلمات المخرجات الثمانيمتطابقةمتطابقة
الدورات، transfer66,235121,638
المستوى1818
كلمات البرنامج11,68618,009

6. النشر

rand program deploy evm2rv/target/mytoken/image.bin

تطبع المحفظة معرّف البرنامج وعدد الكلمات وhc، ثم تتحقق من حدّ السلسلة قبل أن تُنتج أي إثبات. تبلغ الصورة 11,686 كلمة، فتحتاج إلى سلسلة يضبط genesis فيها max_program_words على 11,686 على الأقل. كانت السلسلة 12 تعمل بالقيمة الافتراضية 4,096، فرُفض النشر عليها. أما السلسلة 13، سلسلة الإصدار v0.4، فقد ضبطت max_program_words على 65,535، وتحتفظ كل سلسلة بعدها بهذه القيمة. وتحتفظ السلسلة 20، وهي السلسلة الحية (genesis 6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135)، بحدود الكتلة ومغلف الاستدعاء والمدخلات العامة نفسها التي وضعتها السلسلة 13، وتخفّض حدّ حجم الإثبات إلى النصف، أي 4 MiB (4,194,304 بايت، منذ السلسلة 17؛ وكانت السلاسل من 13 إلى 16 تضبطه على 8 MiB). ولم يعد حدّ الكلمات البوابة الوحيدة. فـ genesis السلسلة 20 يضبط hardening_v6، وبموجبه يكون نشر برنامج يزيد عدد كلماته على ما يتّسع له استدعاء عند حدّ الاستدعاء للمستوى 14 نشرًا غير صالح (ProgramUncallable): أي 8,180 كلمة على الأكثر دون مدخلات عامة. وهذه الصورة 11,686 كلمة، فترفض السلسلة 20 نشرها، وترفض الاستدعاءات أيضًا: إذ يُثبَت كل استدعاء لعقد ERC-20 عند المستوى 16 أو 18، أي فوق حدّ الاستدعاء للمستوى 14 (الخطوة 7). تجميع الكتل (block aggregation) معطّل في السلسلة 20 (فلا قسم aggregation في genesis الخاص بها)؛ وعُقد الإقلاع فيها مذكورة في تشغيل validator. رسوم النشر هي 0.001 + 0.0001 × 11,686 = 1.1696 RAND، وهي الرسوم التي دفعها النشر على السلسلة 13 أدناه.

جرى هذا النشر على السلسلة 13 في 2026-09-19، حين كانت السلسلة 13 هي السلسلة الحية (ملف FRI الإنتاجي، genesis 8123ccac1883a45750e4df6964fb7cd3f0b321798cde4c0ef406a0293939ece3)، من محفظة genesis shielded-1. وكل سلسلة بعدها (من 14 إلى 19) أُطلقت سلسلةً جديدة دون برامج السلسلة 13، ولم تُنشر الصورة من جديد على أيٍّ منها؛ لذا فالمعاملة والارتفاع المذكوران أدناه يخصّان السلسلة 13 ولم يعودا يُحلَّان في المستكشف. ومعرّف البرنامج هو تجزئة لـ base_pc والكلمات وحدها، فتحصل الصورة نفسها على المعرّف نفسه في أي سلسلة تقبل نشرها. مخرجات المحفظة، مع حذف أسطر التقدّم (…):

$ rand program deploy <image.bin>
program id: f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d (11686 words, hc 92aefea0951c31a717574962aeb70e10a37012a7d035d48e8713c36df68feae0)
…
proved in 92.2s: tier 14, 1419655 bytes
submitted deploy c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0
…
معرّف البرنامجf074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d
الصورة11,686 كلمة؛ hc a0feae92… بصيغة rand-guest، و92aefea0… بصيغة المحفظة
حزمة الرسوم (حزمة السلسلة 13 بمدخلين ومخرجين)المستوى 14، 1,419,655 بايت، أُنتج إثباتها في 92.2 s
معاملة النشر (السلسلة 13)c7a66dc4d9cdb7f9bfc4bde01f618c356e5abad7097e6bf7dc04e2e49c53acd0
أُدرجت عند الارتفاع (السلسلة 13)381

منذ السلسلة 14 صارت الحزمة الدافعة هي حزمة الأصول المخفية الواحدة بأربعة مدخلات وأربعة مخرجات التي تحملها كل معاملة، وتُثبَت مقابل ربط (binding) المعاملة. وهي ما تزال من المستوى 14: نحو 100 s ونحو 1.42 MB بملف الإنتاج على السلسلتين 14 و15. ومنذ السلسلة 17 تحمل الحزمة أيضًا إثبات تفويض من المستوى 10 (تفويض مجزّأ)، فتبلغ حزمة الرسوم لمعاملة على السلسلتين 18 و19 نحو 1.49 MB من إثبات الحزمة ونحو 1.37 MB من إثبات التفويض.

7. الاستدعاء

يحمل استدعاء transfer متجه الكلمات الـ 921 مدخلاتٍ خاصة، وهو دون حدّ المدخلات في أي سلسلة (4,295 كلمة افتراضيًا، و16,071 في السلسلة 20)، ولا يحمل كلمات عامة. ولا يمكن إرساله إلى السلسلة 20: فالبرنامج لا يمكن نشره هناك (الخطوة 6)، ويُثبَت transfer عند المستوى 18، ومنذ fullnode v0.5.6 (2026-09-25) ترفض العقدة أي إثبات استدعاء فوق المستوى 14 بالخطأ CallTierTooHigh، قبل أن تبني مفتاح المتحقق. يُنتج الأمر أدناه الإثبات محليًا وترفض السلسلة نتيجته؛ والقياسات هي إثباتات خارج السلسلة. يأخذ rand call كل كلمة بوصفها --input مكررًا:

rand call f074c4eb834cf01886a8241b6a2e0caf6e1cee5327fee6cb1a1a37436607280d \
    $(for w in $(cat evm2rv/target/transfer.words); do printf -- '--input %s ' "$w"; done)

والآن بعد القياس. أُوقف إثبات المستوى 18 على حاسوب محمول بذاكرة 48 GB عند 24.7 GB، لكن على droplet بذاكرة 128 GB (m-16vcpu-128gb) أُثبت استدعاء transfer المُترجَم: ذروة RSS بلغت 85.0 GB، في 3,230.5 s (53.8 min)، وحجم الإثبات 811,600 بايت. وجرى التحقق منه في 101.4 s على الـ droplet، وفي 50.2 s عند RSS قدرها 3.66 GB على حاسوب محمول بمعالج Apple silicon وذاكرة 48 GB (ذاكرة الإثبات). وفق جدول المستويات الثابت في دفتر الأستاذ، وهو القاعدة في السلاسل التي لا قسم gas فيها (حتى السلسلة 17)، كانت رسوم الاستدعاء عند المستوى 18 هي 0.0024 RAND. أما السلسلتان 18 و19 فتسعّران الاستدعاء بحدّ الغاز المعلن وبحجمه بالبايت، بواقع 100 وحدة لكل وحدة غاز و800 لكل KiB بأسعار genesis، ولا تقبلان أي استدعاء فوق المستوى 14.

الاستدعاء على السلسلة 13، 2026-09-19

جرى استدعاء approve(BOB, 5) (649 كلمة خاصة، المستوى 16) على السلسلة 13 في 2026-09-19، حين كانت السلسلة الحية، بملف FRI الإنتاجي، ومن المحفظة نفسها. ولم يُجرَ أي استدعاء على أي سلسلة لاحقة، إذ البرنامج غير منشور فيها، وترفض السلسلة 20 إثبات هذا الاستدعاء من المستوى 16 (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
…
إثبات الاستدعاءالمستوى 16، 3,412,405 بايت، أُنتج في 388.7 s
حزمة الرسوم (حزمة السلسلة 13 بمدخلين ومخرجين)المستوى 14، 1,420,423 بايت، أُنتج إثباتها في 96.0 s
المغلف المختوم2,700 بايت
معاملة الاستدعاء (السلسلة 13)279e1f62abf3f177ca71b08c633e051c37bc4720118c79ddb00936f036c4bfa7
مُثبَّتة عند / أُدرجت عندالارتفاع 802 / الارتفاع 919
الرسوم0.00357 RAND
الإيصال h_pubnull
مخرجات الإيصالمساوية لكلمات المفسِّر الثماني للمتجه نفسه
الزمن الكلي، ذروة RSS622.8 s، 22.9 GB، على حاسوب محمول 48 GB بمعالج من سلسلة M
  • يبلغ الإثبات الإنتاجي 3,412,405 بايت، أي فوق حدّ الإثبات في السلسلة 12 البالغ 2 MiB. ولم تكن السلسلة 12 قادرة على قبول هذا الاستدعاء؛ أما حدّ السلسلة 13 البالغ 8 MiB فقبله. وأبقت السلاسل من 14 إلى 16 الحدّ نفسه، وضبطت السلاسل من 17 إلى 20 الحدّ على 4 MiB (4,194,304 بايت)، وإثبات بهذا الحجم ما يزال يتّسع تحته. ومنذ v0.5.6 ترفض العقدة الاستدعاء بسبب مستواه قبل أن تنظر في حجمه.
  • تتضمن الرسوم حدّ البايتات من جدول السلسلة 13: فالإثبات البالغ 3.41 MB يتجاوز المسموح المجاني وقدره 2 MiB + 18,432 بايت. ومنذ السلسلة 18 يدفع كل استدعاء عن كل KiB ابتداءً من البايت 0.

كلمات الإيصال الثماني هي الواردة في الخطوة 4. لا تحتفظ السلسلة بأي حالة EVM: فالمستدعي يوفّر جذر الحالة السابقة وشواهد التخزين، وجذر الحالة اللاحقة داخل خلاصة EVM_OUT.

الحدود

  • لا سياق للكتل. تُنهي عملياتُ سياق الكتلة التسع التنفيذَ بخطأ (trap) إلى أن يوجد تصميم لربط الكتل.
  • لا تحويلات للقيمة. أي CALL بقيمة غير صفرية يُنهي التنفيذ بخطأ. وكذلك الاستدعاءات إلى عقود غير العقود المُترجَمة مسبقًا (precompiles).
  • لا يمكن إثبات ecrecover وعملية الضرب في bn256 والـ pairing وعمليات modexp الكبيرة اليوم. فكلٌّ منها يتجاوز سقف الشريحة البالغ 2²⁰ صفًّا، وتحتاج إلى جداول معالج مساعد (coprocessor).
  • لا حالة EVM على السلسلة. الاستدعاء إثبات واحد على تشغيل واحد، والمستدعي هو من يحمل الحالة.
  • لا يصلح النشر ولا أي استدعاء لـ ERC-20 للقبول على chain 20. بموجب hardening_v6 في chain 20، يكون نشر برنامج بعدد كلمات أكبر مما يتسع له استدعاء من الشريحة 14 غير صالح (ProgramUncallable؛ 8,180 كلمة كحد أقصى)، بينما تبلغ الصورة 11,686. ومنذ fullnode v0.5.6 يجب أن يكون إثبات الاستدعاء من الشريحة 14 أو أدنى (CallTierTooHigh)؛ ويُثبَت approve في الشريحة 16، وtransfer وtransferFrom في الشريحة 18. ويضع الفحص نفسه سقفًا لجداول التجزئة التي يجوز للاستدعاء التصريح بها: 2¹² صفًّا لـ Keccak (128 تبديلًا) و2¹³ صفًّا لـ SHA-256 (128 عملية ضغط). ومع ذلك ما زالت الاستدعاءات تُثبَت خارج السلسلة، كما يلي.
  • فهرس التخزين بعمق 32 بتًّا. تضع evm-core ورقة تخزين العقد بحسب أعلى 32 بتًّا من keccak256(slot)، فيكلّف العثور على خانة تتصادم مع خانة مختارة نحو 2³² تجزئة Keccak، وما دامت الخانة المختارة تحمل قيمة غير صفرية فهي مجمَّدة (لا تزوير ولا ضياع للقيمة). وهذا الوضع خامل: فحجم evm.bin يبلغ 18,009 كلمة، ويتسع الاستدعاء عند سقف الشريحة 14 لـ 8,184 كلمة على الأكثر، فلا يمكن استدعاء أي وقت تشغيل EVM على أي سلسلة. ويسجّل الملف docs/confidential.md في fullnode الشرط المسبق إلى جانب سقف الاستدعاء (تدقيق v6، ZKV-6؛ على main منذ 2026-09-30، بعد وسم v0.6.7): قبل أن ترفع سلسلة سقف الاستدعاء في الشريحة 14 أو تقبل وقت تشغيل EVM صغيرًا يكفي لاستدعائه، يجب تعميق فهرس التخزين وإعادة تثبيت evm.bin.
  • مُثبَت عمليًّا. أُنهي إثبات تحويل من المرحلة الأولى (الشريحة 18) بإشارة SIGKILL على حاسوب محمول بذاكرة 48 GB عند 24.7 GB بعد 1,016 s، لكن استدعاء transfer في المرحلة الثانية أُثبِت على droplet بذاكرة 128 GB (m-16vcpu-128gb): ذروة RSS بلغت 85.0 GB، و3,230.5 s (53.8 دقيقة)، وإثبات حجمه 811,600 بايت، جرى التحقق منه في 101.4 s (على droplet) وفي 50.2 s عند 3.66 GB RSS (حاسوب محمول 48 GB). وطابق إثبات التحويل عبر evm.bin المفسِّر ذلك عن قرب: 85.5 GB، و3,143.3 s (52.4 دقيقة)، وإثبات حجمه 805,108 بايت — ويحمل الإثباتان كلمات مخرجات عامة متطابقة، ما يؤكد التكافؤ على المُثبِت الفعلي. أما approve (الشريحة 16، مُترجَم) فأرخص بكثير: 21.7 GB، و786.7 s (13.1 دقيقة)، وإثبات حجمه 798,930 بايت. ولا تخفّض الترجمة كلفة الإثبات إلا حين تُسقِط الاستدعاء إلى شريحة أصغر.
  • لا تسجّل السلسلة الشيفرة البايتية. انشرها ليتمكن الآخرون من إعادة بناء hc.

آخر تحقق مقابل الإيداع c0878c3f في fullnode (السلسلة 21) بتاريخ 2026-10-12، وcircuits `7ef3220` (`evm2rv/README.md`, `guests-compiled/evm/contracts/SOLC.md`, `docs/superpowers/specs/2026-09-18-evm-to-rv32-translator-design.md`); the walkthrough re-run on 2026-09-19 with solc 0.8.37. إذا اختلف الكود عن هذه الصفحة فالكود هو الصحيح؛ أبلغونا بذلك.