[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-1-cara-evm-mengeksekusi-kode-opcode-stack-gas":3},{"article":4,"author":54},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d2000000-0000-0000-0000-000000000101","a0000000-0000-0000-0000-000000000022","Deep EVM #1: Cara EVM Mengeksekusi Kode Anda — Opcode, Stack, dan Gas","deep-evm-1-cara-evm-mengeksekusi-kode-opcode-stack-gas","Panduan mendalam tentang Ethereum Virtual Machine: bagaimana opcode memanipulasi stack, cara kerja pengukuran gas, dan apa yang sebenarnya terjadi saat transaksi Anda dieksekusi.","## EVM Adalah Mesin Stack\n\nEthereum Virtual Machine tidak seperti prosesor x86 di laptop Anda. Ia tidak memiliki register. Sebaliknya, EVM adalah **mesin stack** — setiap komputasi mendorong ke atau mengambil dari stack 1024-elemen di mana setiap elemen adalah word 256-bit (32-byte).\n\nKetika Anda memanggil smart contract, EVM menerima bytecode kontrak — urutan datar opcode byte tunggal — dan mulai mengeksekusi dari byte 0. Tidak ada tabel fungsi, tidak ada header ELF, tidak ada langkah linking. Bytecode adalah programnya.\n\n```\n\u002F\u002F Solidity:\n\u002F\u002F uint256 result = 2 + 3;\n\n\u002F\u002F Dikompilasi menjadi bytecode:\n\u002F\u002F PUSH1 0x02  PUSH1 0x03  ADD\n\n\u002F\u002F Jejak stack:\n\u002F\u002F []           -> PUSH1 0x02 -> [2]\n\u002F\u002F [2]          -> PUSH1 0x03 -> [2, 3]\n\u002F\u002F [2, 3]       -> ADD        -> [5]\n```\n\nSetiap opcode mengkonsumsi operand dari atas stack dan mendorong hasilnya kembali. Opcode ADD mengambil dua nilai, menjumlahkannya, dan mendorong hasilnya. Ini secara fundamental berbeda dari arsitektur berbasis register di mana Anda menentukan register sumber dan tujuan.\n\n## Kategori Opcode\n\nEVM mendefinisikan sekitar 140 opcode, dikelompokkan ke dalam kategori fungsional:\n\n### Aritmatika dan Perbandingan\n- **ADD, SUB, MUL, DIV, MOD** — Aritmatika integer 256-bit dasar. Semua memerlukan 3 gas (tier G_verylow).\n- **SDIV, SMOD** — Pembagian dan modulo bertanda menggunakan two's complement.\n- **ADDMOD, MULMOD** — Aritmatika modular: `(a + b) % N` dan `(a * b) % N` dalam satu opcode. Ini krusial untuk operasi kurva eliptik dan memerlukan 8 gas.\n- **EXP** — Eksponensial. Memerlukan 10 gas + 50 per byte dalam eksponen, menjadikannya salah satu opcode aritmatika termahal.\n- **LT, GT, SLT, SGT, EQ, ISZERO** — Opcode perbandingan yang mendorong 1 (benar) atau 0 (salah).\n\n### Operasi Bitwise\n- **AND, OR, XOR, NOT** — Logika bitwise, masing-masing 3 gas.\n- **SHL, SHR, SAR** — Shift left, logical shift right, arithmetic shift right (ditambahkan di Constantinople, EIP-145). Sebelum ini ada, shift memerlukan MUL\u002FDIV dengan pangkat 2.\n- **BYTE** — Mengekstrak satu byte dari word 32-byte. `BYTE(0, x)` mengembalikan byte paling signifikan.\n\n### Manipulasi Stack\n- **POP** — Buang elemen teratas.\n- **PUSH1 hingga PUSH32** — Dorong 1 hingga 32 byte data langsung ke stack. PUSH1 adalah opcode paling umum dalam bytecode yang di-deploy.\n- **DUP1 hingga DUP16** — Duplikasi elemen stack ke-N ke atas.\n- **SWAP1 hingga SWAP16** — Tukar elemen teratas dengan elemen ke-N di bawahnya.\n\n### Informasi Lingkungan dan Block\n- **CALLER** (msg.sender), **CALLVALUE** (msg.value), **CALLDATALOAD**, **CALLDATASIZE**, **CALLDATACOPY** — Akses konteks transaksi.\n- **NUMBER**, **TIMESTAMP**, **BASEFEE**, **CHAINID** — Informasi tingkat block.\n- **BALANCE**, **EXTCODESIZE**, **EXTCODECOPY** — Query akun lain.\n\n## Jadwal Gas\n\nSetiap opcode memiliki biaya gas. Gas memiliki dua tujuan: mencegah loop tak terbatas (halting problem) dan menetapkan harga sumber daya komputasi secara adil.\n\nBiaya gas jatuh ke dalam beberapa tier:\n\n| Tier | Gas | Contoh |\n|------|-----|--------|\n| Zero | 0 | STOP, RETURN, REVERT |\n| Base | 2 | ADDRESS, ORIGIN, CALLER |\n| Very Low | 3 | ADD, SUB, LT, GT, AND, OR, POP |\n| Low | 5 | MUL, DIV, MOD |\n| Mid | 8 | ADDMOD, MULMOD, JUMP |\n| High | 10 | JUMPI |\n| Special | bervariasi | SLOAD, SSTORE, CALL, CREATE |\n\nOpcode yang mahal adalah yang menyentuh state:\n\n```\n\u002F\u002F Biaya gas untuk akses state (pasca EIP-2929):\n\u002F\u002F SLOAD (cold):   2100 gas\n\u002F\u002F SLOAD (warm):    100 gas\n\u002F\u002F SSTORE (cold, 0->nonzero): 22100 gas\n\u002F\u002F SSTORE (warm):   100 gas (+ 20000 jika 0->nonzero)\n\u002F\u002F CALL (cold):    2600 gas\n\u002F\u002F CALL (warm):     100 gas\n\u002F\u002F BALANCE (cold): 2600 gas\n\u002F\u002F BALANCE (warm):  100 gas\n```\n\n## Akses Cold vs Warm (EIP-2929)\n\nEIP-2929 (upgrade Berlin, April 2021) memperkenalkan konsep **daftar akses** — kumpulan per-transaksi dari alamat dan slot penyimpanan yang telah disentuh.\n\nPertama kali Anda mengakses slot penyimpanan atau alamat eksternal dalam suatu transaksi, ia \"cold\" dan memerlukan gas ekstra. Akses berikutnya \"warm\" dan murah. Inilah mengapa urutan Anda membaca slot penyimpanan berpengaruh untuk optimasi gas.\n\n```solidity\n\u002F\u002F Di Solidity, pola ini mahal:\nfunction buruk() external view returns (uint256) {\n    uint256 a = myStorage; \u002F\u002F Pembacaan pertama: 2100 gas (cold)\n    \u002F\u002F ... logika ...\n    uint256 b = myStorage; \u002F\u002F Pembacaan kedua: 100 gas (warm)\n    return a + b;\n}\n\n\u002F\u002F Cache di memory:\nfunction baik() external view returns (uint256) {\n    uint256 cached = myStorage; \u002F\u002F 2100 gas (cold), hanya sekali\n    return cached + cached;     \u002F\u002F 6 gas (ADD + DUP)\n}\n```\n\n## Alur Eksekusi: Apa yang Terjadi dalam Transaksi\n\nKetika Anda mengirim transaksi yang memanggil kontrak, berikut urutan eksekusi lengkapnya:\n\n1. **Validasi transaksi** — Pemeriksaan nonce, saldo >= value + gas * gasPrice, verifikasi tanda tangan.\n2. **Pengurangan gas intrinsik** — 21000 gas untuk transaksi itu sendiri, ditambah 16 gas per byte calldata non-zero dan 4 per byte zero.\n3. **Pengaturan konteks** — EVM membuat konteks eksekusi: kode, calldata, pemanggil, value, gas tersisa.\n4. **Program counter mulai dari 0** — EVM membaca opcode di posisi 0 dan mengeksekusinya.\n5. **Eksekusi sekuensial** — Setiap opcode dieksekusi, gas dikurangi. JUMP dan JUMPI memungkinkan alur kontrol non-linear, tetapi hanya ke posisi yang ditandai dengan JUMPDEST.\n6. **Terminasi** — Eksekusi berakhir dengan STOP (sukses, tanpa data kembali), RETURN (sukses, dengan data kembali), REVERT (gagal, state dikembalikan), atau kehabisan gas.\n7. **Commit atau rollback state** — Pada sukses, semua perubahan state di-commit. Pada revert, semua perubahan dalam konteks panggilan ini di-rollback.\n\n## Program Counter dan JUMP\n\nProgram counter (PC) adalah register implisit yang melacak posisi saat ini dalam bytecode. Sebagian besar opcode memajukan PC sebanyak 1 (atau 1 + N untuk opcode PUSH). Dua opcode memodifikasi PC secara langsung:\n\n- **JUMP** — Mengambil tujuan dari stack, mengatur PC ke nilai tersebut. Tujuan harus berisi opcode JUMPDEST atau transaksi di-revert.\n- **JUMPI** — Jump bersyarat. Mengambil tujuan dan kondisi. Jika kondisi bukan nol, jump; jika tidak, lanjut sekuensial.\n\nIni adalah cara EVM mengimplementasikan if\u002Felse, loop, dan dispatch fungsi. Compiler Solidity menghasilkan selektor fungsi yang memuat 4 byte pertama calldata, membandingkan dengan tanda tangan fungsi yang diketahui, dan JUMPI ke blok kode yang cocok.\n\n## Sub-panggilan: CALL, STATICCALL, DELEGATECALL\n\nKontrak dapat memanggil kontrak lain menggunakan tiga opcode panggilan:\n\n- **CALL** — Panggilan standar. Membuat konteks eksekusi baru dengan stack dan memory sendiri.\n- **STATICCALL** — Panggilan hanya-baca (EIP-214). Opcode yang memodifikasi state dalam callee menyebabkan revert langsung.\n- **DELEGATECALL** — Mengeksekusi kode callee tetapi dalam konteks storage pemanggil. msg.sender dan msg.value dipertahankan dari panggilan asli. Ini adalah cara kerja pola proxy dan library.\n\n## Implikasi Praktis untuk MEV\n\nJika Anda membangun bot MEV, memahami EVM di tingkat opcode bukan opsional — ini adalah kebutuhan kompetitif. Setiap unit gas yang dihemat dalam eksekusi bot Anda adalah margin keuntungan.\n\n- **Simulasikan sebelum mengirim** — Gunakan `eth_call` atau EVM lokal (revm, EVMONE) untuk menelusuri eksekusi.\n- **Minimalkan akses cold** — Panaskan slot penyimpanan melalui daftar akses (EIP-2930).\n- **Gunakan STATICCALL untuk pembacaan** — Sedikit lebih murah dan menjamin tidak ada mutasi state.\n- **Ketahui biaya opcode Anda** — Satu SLOAD yang salah tempat bisa memerlukan 2100 gas.\n\n## Kesimpulan\n\nEVM elegan dalam kesederhanaannya: mesin stack dengan word 256-bit, format bytecode datar, dan sistem pengukuran gas yang menetapkan harga setiap operasi. Memahami fondasi ini — opcode, stack, dan gas — adalah prasyarat untuk segala sesuatu yang mengikuti dalam seri ini: tata letak memory, optimasi storage, primitif keamanan, dan akhirnya menulis Yul dan Huff mentah.","\u003Ch2 id=\"evm-adalah-mesin-stack\">EVM Adalah Mesin Stack\u003C\u002Fh2>\n\u003Cp>Ethereum Virtual Machine tidak seperti prosesor x86 di laptop Anda. Ia tidak memiliki register. Sebaliknya, EVM adalah \u003Cstrong>mesin stack\u003C\u002Fstrong> — setiap komputasi mendorong ke atau mengambil dari stack 1024-elemen di mana setiap elemen adalah word 256-bit (32-byte).\u003C\u002Fp>\n\u003Cp>Ketika Anda memanggil smart contract, EVM menerima bytecode kontrak — urutan datar opcode byte tunggal — dan mulai mengeksekusi dari byte 0. Tidak ada tabel fungsi, tidak ada header ELF, tidak ada langkah linking. Bytecode adalah programnya.\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Solidity:\n\u002F\u002F uint256 result = 2 + 3;\n\n\u002F\u002F Dikompilasi menjadi bytecode:\n\u002F\u002F PUSH1 0x02  PUSH1 0x03  ADD\n\n\u002F\u002F Jejak stack:\n\u002F\u002F []           -&gt; PUSH1 0x02 -&gt; [2]\n\u002F\u002F [2]          -&gt; PUSH1 0x03 -&gt; [2, 3]\n\u002F\u002F [2, 3]       -&gt; ADD        -&gt; [5]\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Setiap opcode mengkonsumsi operand dari atas stack dan mendorong hasilnya kembali. Opcode ADD mengambil dua nilai, menjumlahkannya, dan mendorong hasilnya. Ini secara fundamental berbeda dari arsitektur berbasis register di mana Anda menentukan register sumber dan tujuan.\u003C\u002Fp>\n\u003Ch2 id=\"kategori-opcode\">Kategori Opcode\u003C\u002Fh2>\n\u003Cp>EVM mendefinisikan sekitar 140 opcode, dikelompokkan ke dalam kategori fungsional:\u003C\u002Fp>\n\u003Ch3>Aritmatika dan Perbandingan\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>ADD, SUB, MUL, DIV, MOD\u003C\u002Fstrong> — Aritmatika integer 256-bit dasar. Semua memerlukan 3 gas (tier G_verylow).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SDIV, SMOD\u003C\u002Fstrong> — Pembagian dan modulo bertanda menggunakan two’s complement.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>ADDMOD, MULMOD\u003C\u002Fstrong> — Aritmatika modular: \u003Ccode>(a + b) % N\u003C\u002Fcode> dan \u003Ccode>(a * b) % N\u003C\u002Fcode> dalam satu opcode. Ini krusial untuk operasi kurva eliptik dan memerlukan 8 gas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>EXP\u003C\u002Fstrong> — Eksponensial. Memerlukan 10 gas + 50 per byte dalam eksponen, menjadikannya salah satu opcode aritmatika termahal.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>LT, GT, SLT, SGT, EQ, ISZERO\u003C\u002Fstrong> — Opcode perbandingan yang mendorong 1 (benar) atau 0 (salah).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Operasi Bitwise\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>AND, OR, XOR, NOT\u003C\u002Fstrong> — Logika bitwise, masing-masing 3 gas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SHL, SHR, SAR\u003C\u002Fstrong> — Shift left, logical shift right, arithmetic shift right (ditambahkan di Constantinople, EIP-145). Sebelum ini ada, shift memerlukan MUL\u002FDIV dengan pangkat 2.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>BYTE\u003C\u002Fstrong> — Mengekstrak satu byte dari word 32-byte. \u003Ccode>BYTE(0, x)\u003C\u002Fcode> mengembalikan byte paling signifikan.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Manipulasi Stack\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>POP\u003C\u002Fstrong> — Buang elemen teratas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>PUSH1 hingga PUSH32\u003C\u002Fstrong> — Dorong 1 hingga 32 byte data langsung ke stack. PUSH1 adalah opcode paling umum dalam bytecode yang di-deploy.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>DUP1 hingga DUP16\u003C\u002Fstrong> — Duplikasi elemen stack ke-N ke atas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>SWAP1 hingga SWAP16\u003C\u002Fstrong> — Tukar elemen teratas dengan elemen ke-N di bawahnya.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Informasi Lingkungan dan Block\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Cstrong>CALLER\u003C\u002Fstrong> (msg.sender), \u003Cstrong>CALLVALUE\u003C\u002Fstrong> (msg.value), \u003Cstrong>CALLDATALOAD\u003C\u002Fstrong>, \u003Cstrong>CALLDATASIZE\u003C\u002Fstrong>, \u003Cstrong>CALLDATACOPY\u003C\u002Fstrong> — Akses konteks transaksi.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>NUMBER\u003C\u002Fstrong>, \u003Cstrong>TIMESTAMP\u003C\u002Fstrong>, \u003Cstrong>BASEFEE\u003C\u002Fstrong>, \u003Cstrong>CHAINID\u003C\u002Fstrong> — Informasi tingkat block.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>BALANCE\u003C\u002Fstrong>, \u003Cstrong>EXTCODESIZE\u003C\u002Fstrong>, \u003Cstrong>EXTCODECOPY\u003C\u002Fstrong> — Query akun lain.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"jadwal-gas\">Jadwal Gas\u003C\u002Fh2>\n\u003Cp>Setiap opcode memiliki biaya gas. Gas memiliki dua tujuan: mencegah loop tak terbatas (halting problem) dan menetapkan harga sumber daya komputasi secara adil.\u003C\u002Fp>\n\u003Cp>Biaya gas jatuh ke dalam beberapa tier:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Tier\u003C\u002Fth>\u003Cth>Gas\u003C\u002Fth>\u003Cth>Contoh\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Zero\u003C\u002Ftd>\u003Ctd>0\u003C\u002Ftd>\u003Ctd>STOP, RETURN, REVERT\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Base\u003C\u002Ftd>\u003Ctd>2\u003C\u002Ftd>\u003Ctd>ADDRESS, ORIGIN, CALLER\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Very Low\u003C\u002Ftd>\u003Ctd>3\u003C\u002Ftd>\u003Ctd>ADD, SUB, LT, GT, AND, OR, POP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Low\u003C\u002Ftd>\u003Ctd>5\u003C\u002Ftd>\u003Ctd>MUL, DIV, MOD\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Mid\u003C\u002Ftd>\u003Ctd>8\u003C\u002Ftd>\u003Ctd>ADDMOD, MULMOD, JUMP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>High\u003C\u002Ftd>\u003Ctd>10\u003C\u002Ftd>\u003Ctd>JUMPI\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Special\u003C\u002Ftd>\u003Ctd>bervariasi\u003C\u002Ftd>\u003Ctd>SLOAD, SSTORE, CALL, CREATE\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Opcode yang mahal adalah yang menyentuh state:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>\u002F\u002F Biaya gas untuk akses state (pasca EIP-2929):\n\u002F\u002F SLOAD (cold):   2100 gas\n\u002F\u002F SLOAD (warm):    100 gas\n\u002F\u002F SSTORE (cold, 0-&gt;nonzero): 22100 gas\n\u002F\u002F SSTORE (warm):   100 gas (+ 20000 jika 0-&gt;nonzero)\n\u002F\u002F CALL (cold):    2600 gas\n\u002F\u002F CALL (warm):     100 gas\n\u002F\u002F BALANCE (cold): 2600 gas\n\u002F\u002F BALANCE (warm):  100 gas\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"akses-cold-vs-warm-eip-2929\">Akses Cold vs Warm (EIP-2929)\u003C\u002Fh2>\n\u003Cp>EIP-2929 (upgrade Berlin, April 2021) memperkenalkan konsep \u003Cstrong>daftar akses\u003C\u002Fstrong> — kumpulan per-transaksi dari alamat dan slot penyimpanan yang telah disentuh.\u003C\u002Fp>\n\u003Cp>Pertama kali Anda mengakses slot penyimpanan atau alamat eksternal dalam suatu transaksi, ia “cold” dan memerlukan gas ekstra. Akses berikutnya “warm” dan murah. Inilah mengapa urutan Anda membaca slot penyimpanan berpengaruh untuk optimasi gas.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F Di Solidity, pola ini mahal:\nfunction buruk() external view returns (uint256) {\n    uint256 a = myStorage; \u002F\u002F Pembacaan pertama: 2100 gas (cold)\n    \u002F\u002F ... logika ...\n    uint256 b = myStorage; \u002F\u002F Pembacaan kedua: 100 gas (warm)\n    return a + b;\n}\n\n\u002F\u002F Cache di memory:\nfunction baik() external view returns (uint256) {\n    uint256 cached = myStorage; \u002F\u002F 2100 gas (cold), hanya sekali\n    return cached + cached;     \u002F\u002F 6 gas (ADD + DUP)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"alur-eksekusi-apa-yang-terjadi-dalam-transaksi\">Alur Eksekusi: Apa yang Terjadi dalam Transaksi\u003C\u002Fh2>\n\u003Cp>Ketika Anda mengirim transaksi yang memanggil kontrak, berikut urutan eksekusi lengkapnya:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Validasi transaksi\u003C\u002Fstrong> — Pemeriksaan nonce, saldo &gt;= value + gas * gasPrice, verifikasi tanda tangan.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pengurangan gas intrinsik\u003C\u002Fstrong> — 21000 gas untuk transaksi itu sendiri, ditambah 16 gas per byte calldata non-zero dan 4 per byte zero.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Pengaturan konteks\u003C\u002Fstrong> — EVM membuat konteks eksekusi: kode, calldata, pemanggil, value, gas tersisa.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Program counter mulai dari 0\u003C\u002Fstrong> — EVM membaca opcode di posisi 0 dan mengeksekusinya.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Eksekusi sekuensial\u003C\u002Fstrong> — Setiap opcode dieksekusi, gas dikurangi. JUMP dan JUMPI memungkinkan alur kontrol non-linear, tetapi hanya ke posisi yang ditandai dengan JUMPDEST.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Terminasi\u003C\u002Fstrong> — Eksekusi berakhir dengan STOP (sukses, tanpa data kembali), RETURN (sukses, dengan data kembali), REVERT (gagal, state dikembalikan), atau kehabisan gas.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Commit atau rollback state\u003C\u002Fstrong> — Pada sukses, semua perubahan state di-commit. Pada revert, semua perubahan dalam konteks panggilan ini di-rollback.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"program-counter-dan-jump\">Program Counter dan JUMP\u003C\u002Fh2>\n\u003Cp>Program counter (PC) adalah register implisit yang melacak posisi saat ini dalam bytecode. Sebagian besar opcode memajukan PC sebanyak 1 (atau 1 + N untuk opcode PUSH). Dua opcode memodifikasi PC secara langsung:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>JUMP\u003C\u002Fstrong> — Mengambil tujuan dari stack, mengatur PC ke nilai tersebut. Tujuan harus berisi opcode JUMPDEST atau transaksi di-revert.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>JUMPI\u003C\u002Fstrong> — Jump bersyarat. Mengambil tujuan dan kondisi. Jika kondisi bukan nol, jump; jika tidak, lanjut sekuensial.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Ini adalah cara EVM mengimplementasikan if\u002Felse, loop, dan dispatch fungsi. Compiler Solidity menghasilkan selektor fungsi yang memuat 4 byte pertama calldata, membandingkan dengan tanda tangan fungsi yang diketahui, dan JUMPI ke blok kode yang cocok.\u003C\u002Fp>\n\u003Ch2 id=\"sub-panggilan-call-staticcall-delegatecall\">Sub-panggilan: CALL, STATICCALL, DELEGATECALL\u003C\u002Fh2>\n\u003Cp>Kontrak dapat memanggil kontrak lain menggunakan tiga opcode panggilan:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>CALL\u003C\u002Fstrong> — Panggilan standar. Membuat konteks eksekusi baru dengan stack dan memory sendiri.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>STATICCALL\u003C\u002Fstrong> — Panggilan hanya-baca (EIP-214). Opcode yang memodifikasi state dalam callee menyebabkan revert langsung.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>DELEGATECALL\u003C\u002Fstrong> — Mengeksekusi kode callee tetapi dalam konteks storage pemanggil. msg.sender dan msg.value dipertahankan dari panggilan asli. Ini adalah cara kerja pola proxy dan library.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"implikasi-praktis-untuk-mev\">Implikasi Praktis untuk MEV\u003C\u002Fh2>\n\u003Cp>Jika Anda membangun bot MEV, memahami EVM di tingkat opcode bukan opsional — ini adalah kebutuhan kompetitif. Setiap unit gas yang dihemat dalam eksekusi bot Anda adalah margin keuntungan.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Simulasikan sebelum mengirim\u003C\u002Fstrong> — Gunakan \u003Ccode>eth_call\u003C\u002Fcode> atau EVM lokal (revm, EVMONE) untuk menelusuri eksekusi.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Minimalkan akses cold\u003C\u002Fstrong> — Panaskan slot penyimpanan melalui daftar akses (EIP-2930).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Gunakan STATICCALL untuk pembacaan\u003C\u002Fstrong> — Sedikit lebih murah dan menjamin tidak ada mutasi state.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Ketahui biaya opcode Anda\u003C\u002Fstrong> — Satu SLOAD yang salah tempat bisa memerlukan 2100 gas.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"kesimpulan\">Kesimpulan\u003C\u002Fh2>\n\u003Cp>EVM elegan dalam kesederhanaannya: mesin stack dengan word 256-bit, format bytecode datar, dan sistem pengukuran gas yang menetapkan harga setiap operasi. Memahami fondasi ini — opcode, stack, dan gas — adalah prasyarat untuk segala sesuatu yang mengikuti dalam seri ini: tata letak memory, optimasi storage, primitif keamanan, dan akhirnya menulis Yul dan Huff mentah.\u003C\u002Fp>\n","id","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:24.587587Z","Panduan mendalam tentang Ethereum Virtual Machine: opcode, operasi stack, pengukuran gas, dan akses cold vs warm dijelaskan.","EVM opcode",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity","Blockchain",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"d0000000-0000-0000-0000-000000000596","Lapisan Interoperabilitas Ethereum: Bagaimana 55+ L2 Menjadi Satu Chain","lapisan-interoperabilitas-ethereum-bagaimana-55-l2-menjadi-satu-chain","Ethereum memiliki 55+ rollup Layer 2, memecah likuiditas dan pengalaman pengguna. Lapisan Interoperabilitas Ethereum — menggabungkan pesan lintas-rollup, shared sequencer, dan based rollup — bertujuan menyatukan mereka menjadi satu jaringan yang dapat dikomposisi.","2026-03-28T10:44:44.364342Z",{"id":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"d0000000-0000-0000-0000-000000000595","ZK Proofs Melampaui Rollups: Inferensi AI Terverifikasi di Ethereum","zk-proofs-melampaui-rollups-inferensi-ai-terverifikasi-ethereum","Zero-knowledge proofs bukan lagi sekadar alat penskalaan. Pada 2026, zkML memungkinkan inferensi AI terverifikasi on-chain, ZK coprocessor memindahkan komputasi berat off-chain dengan verifikasi on-chain, dan sistem pembuktian baru seperti SP1 dan Jolt menjadikannya praktis.","2026-03-28T10:44:44.358370Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"d0000000-0000-0000-0000-000000000572","EIP-7702 dalam Praktik: Membangun Alur Akun Pintar Setelah Pectra","eip-7702-dalam-praktik-membangun-alur-akun-pintar-setelah-pectra","EIP-7702 memungkinkan EOA Ethereum mana pun untuk sementara bertindak sebagai kontrak pintar dalam satu transaksi. Berikut cara mengimplementasikan transaksi batch, sponsorship gas, dan social recovery menggunakan primitif account abstraction baru.","2026-03-28T10:44:42.816894Z",{"id":13,"name":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]