[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-11-jump-table-huff-dispatch-fungsi":3},{"article":4,"author":59},{"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":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":39,"related_articles":40},"d2000000-0000-0000-0000-000000000111","a0000000-0000-0000-0000-000000000022","Deep EVM #11: Jump Table Huff — Dispatch Fungsi O(1) Tanpa Overhead Solidity","deep-evm-11-jump-table-huff-dispatch-fungsi","Bangun dispatcher fungsi O(1) di Huff menggunakan jump table yang dipadatkan. Bandingkan rantai if-else Solidity dengan jump table buatan tangan yang menghemat ribuan gas.","## Masalah dengan Dispatcher Solidity\n\nKetika Anda memanggil kontrak Solidity, hal pertama yang dieksekusi EVM adalah function dispatcher. Solidity menghasilkan rantai if-else linear yang membandingkan 4 byte pertama calldata (function selector) dengan setiap selector yang diketahui:\n\n```\nCALLDATASIZE -> CALLDATALOAD -> SHR 224 -> DUP1 -> PUSH4 selector\n-> EQ -> PUSH2 dest -> JUMPI -> ...\n```\n\nUntuk kontrak dengan N fungsi, ini O(N) — kasus terburuk memeriksa semua N selector sebelum menemukan kecocokan. Setiap perbandingan memerlukan sekitar 22 gas (DUP1 + PUSH4 + EQ + PUSH2 + JUMPI). Kontrak dengan 20 fungsi membuang hingga 440 gas hanya untuk dispatch.\n\nUntuk kontrak bot MEV yang dipanggil jutaan kali, 400+ unit gas per panggilan bertambah menjadi ETH nyata.\n\n## Pendekatan Jump Table: O(1)\n\nJump table memetakan function selector langsung ke offset kode menggunakan aritmatika, bukan perbandingan. Idenya dipinjam dari arsitektur CPU — computed GOTO telah digunakan dalam pemrograman sistem sejak 1960-an.\n\nKonsepnya:\n\n1. Ekstrak function selector dari calldata (4 byte).\n2. Gunakan aritmatika untuk menghitung tujuan jump dari selector.\n3. JUMP langsung ke tujuan tersebut.\n\nTanpa perbandingan, tanpa branching, waktu konstan terlepas dari berapa banyak fungsi yang ada.\n\n### Pendekatan 1: Encoding Selector Minimal\n\nJika kontrak Anda memiliki sejumlah kecil fungsi (1-8), Anda bisa menetapkan selector secara manual dengan mining vanity selector di mana byte pertama atau dua mengkodekan integer kecil yang unik:\n\n```huff\n#define macro DISPATCHER() = takes(0) returns(0) {\n    0x00 calldataload       \u002F\u002F [calldata_word]\n    0xe0 shr                \u002F\u002F [selector]\n\n    \u002F\u002F Ekstrak routing byte — byte pertama selector\n    0x18 shr                \u002F\u002F [first_byte]\n\n    \u002F\u002F Setiap entri di tabel kita adalah 2 byte (PUSH2 offset)\n    0x02 mul                \u002F\u002F [offset_dalam_tabel]\n    __tablestart(JumpTable) \u002F\u002F [table_start, offset_dalam_tabel]\n    add                     \u002F\u002F [entry_address]\n    \n    0x00 codecopy\n    0x00 mload\n    0xf0 shr\n    jump\n}\n\n#define jumptable JumpTable {\n    swap_exact\n    add_liq\n    remove_liq\n    flash_loan\n}\n```\n\n### Pendekatan 2: Tabel Kode yang Dipadatkan\n\nUntuk kepadatan maksimum, Anda bisa memadatkan jump table langsung ke dalam bytecode menggunakan `__tablestart` dan `__tablesize`. Huff secara native mendukung jump table sebagai konstruk kelas satu:\n\n```huff\n#define jumptable__packed SELECTOR_TABLE {\n    fn_swap\n    fn_transfer\n    fn_approve\n    fn_balance\n}\n\n#define macro MAIN() = takes(0) returns(0) {\n    0x00 calldataload 0xe0 shr\n    0x18 shr\n    dup1 0x04 lt\n    valid jumpi\n    0x00 0x00 revert\n\n    valid:\n    __tablestart(SELECTOR_TABLE)\n    swap1 0x02 mul add\n    0x1e mload\n    jump\n\n    fn_swap:\n        SWAP_IMPL()\n    fn_transfer:\n        TRANSFER_IMPL()\n    fn_approve:\n        APPROVE_IMPL()\n    fn_balance:\n        BALANCE_IMPL()\n}\n```\n\n## Perbandingan Gas\n\n| Fungsi | Solidity (if-else) | Solidity (binary) | Huff Jump Table |\n|--------|-------------------|-------------------|------------------|\n| 2 | 22-44 gas | 22-44 gas | 15 gas |\n| 4 | 22-88 gas | 22-66 gas | 15 gas |\n| 8 | 22-176 gas | 22-88 gas | 15 gas |\n| 16 | 22-352 gas | 22-110 gas | 15 gas |\n| 32 | 22-704 gas | 22-132 gas | 15 gas |\n\nBiaya jump table konstan: CALLDATALOAD (3) + SHR (3) + aritmatika (3-6) + JUMP (8) = ~15-18 gas. Tidak pernah berubah terlepas dari jumlah fungsi.\n\n## Mining Vanity Selector\n\nAgar pendekatan jump table berfungsi, Anda memerlukan function selector dengan routing byte yang bisa diprediksi. Anda bisa mining ini:\n\n```python\nimport hashlib\nimport itertools\n\ntarget_byte = 0x00\nbase_name = \"swap\"\n\nfor suffix in itertools.count():\n    name = f\"{base_name}{suffix}(uint256,address)\"\n    selector = hashlib.sha3_256(name.encode()).digest()[:4]\n    if selector[0] == target_byte:\n        print(f\"Ditemukan: {name} -> 0x{selector.hex()}\")\n        break\n```\n\nDalam praktik, kami menggunakan `cast sig` dari Foundry atau tool Rust yang brute-force nama fungsi untuk menemukan selector dengan prefix yang diinginkan.\n\n## Dampak Ukuran Bytecode\n\n| Pendekatan | Runtime Bytecode | Gas Deploy |\n|-----------|-----------------|------------|\n| Solidity (8 funcs) | ~800 byte | 160.000 gas |\n| Huff jump table (8 funcs) | ~200 byte | 40.000 gas |\n| Huff minimal (2 funcs) | ~61 byte | 12.200 gas |\n\nUntuk bot MEV yang sering men-redeploy kontrak, bytecode lebih kecil langsung diterjemahkan menjadi biaya operasional yang lebih rendah.\n\n## Batasan\n\n1. **ABI non-standar** — Tool eksternal (Etherscan, wallet) tidak bisa mendecode calldata Anda tanpa definisi ABI kustom.\n2. **Mining selector** — Memerlukan pekerjaan di muka dan membatasi penamaan fungsi.\n3. **Biaya pemeliharaan** — Huff lebih sulit diaudit dan dimodifikasi dari Solidity.\n4. **Tabel yang dipadatkan** — Builtin `__tablestart` dan `__tablesize` memiliki edge case dengan compiler Huff; uji secara menyeluruh.\n\n## Ringkasan\n\nJump table menggantikan rantai dispatch O(N) Solidity dengan computed jump O(1). Penghematan gas bertambah melintasi jutaan panggilan — keunggulan signifikan untuk kontrak frekuensi tinggi seperti bot MEV dan router DEX.","\u003Ch2 id=\"masalah-dengan-dispatcher-solidity\">Masalah dengan Dispatcher Solidity\u003C\u002Fh2>\n\u003Cp>Ketika Anda memanggil kontrak Solidity, hal pertama yang dieksekusi EVM adalah function dispatcher. Solidity menghasilkan rantai if-else linear yang membandingkan 4 byte pertama calldata (function selector) dengan setiap selector yang diketahui:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>CALLDATASIZE -&gt; CALLDATALOAD -&gt; SHR 224 -&gt; DUP1 -&gt; PUSH4 selector\n-&gt; EQ -&gt; PUSH2 dest -&gt; JUMPI -&gt; ...\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Untuk kontrak dengan N fungsi, ini O(N) — kasus terburuk memeriksa semua N selector sebelum menemukan kecocokan. Setiap perbandingan memerlukan sekitar 22 gas (DUP1 + PUSH4 + EQ + PUSH2 + JUMPI). Kontrak dengan 20 fungsi membuang hingga 440 gas hanya untuk dispatch.\u003C\u002Fp>\n\u003Cp>Untuk kontrak bot MEV yang dipanggil jutaan kali, 400+ unit gas per panggilan bertambah menjadi ETH nyata.\u003C\u002Fp>\n\u003Ch2 id=\"pendekatan-jump-table-o-1\">Pendekatan Jump Table: O(1)\u003C\u002Fh2>\n\u003Cp>Jump table memetakan function selector langsung ke offset kode menggunakan aritmatika, bukan perbandingan. Idenya dipinjam dari arsitektur CPU — computed GOTO telah digunakan dalam pemrograman sistem sejak 1960-an.\u003C\u002Fp>\n\u003Cp>Konsepnya:\u003C\u002Fp>\n\u003Col>\n\u003Cli>Ekstrak function selector dari calldata (4 byte).\u003C\u002Fli>\n\u003Cli>Gunakan aritmatika untuk menghitung tujuan jump dari selector.\u003C\u002Fli>\n\u003Cli>JUMP langsung ke tujuan tersebut.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Tanpa perbandingan, tanpa branching, waktu konstan terlepas dari berapa banyak fungsi yang ada.\u003C\u002Fp>\n\u003Ch3>Pendekatan 1: Encoding Selector Minimal\u003C\u002Fh3>\n\u003Cp>Jika kontrak Anda memiliki sejumlah kecil fungsi (1-8), Anda bisa menetapkan selector secara manual dengan mining vanity selector di mana byte pertama atau dua mengkodekan integer kecil yang unik:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define macro DISPATCHER() = takes(0) returns(0) {\n    0x00 calldataload       \u002F\u002F [calldata_word]\n    0xe0 shr                \u002F\u002F [selector]\n\n    \u002F\u002F Ekstrak routing byte — byte pertama selector\n    0x18 shr                \u002F\u002F [first_byte]\n\n    \u002F\u002F Setiap entri di tabel kita adalah 2 byte (PUSH2 offset)\n    0x02 mul                \u002F\u002F [offset_dalam_tabel]\n    __tablestart(JumpTable) \u002F\u002F [table_start, offset_dalam_tabel]\n    add                     \u002F\u002F [entry_address]\n    \n    0x00 codecopy\n    0x00 mload\n    0xf0 shr\n    jump\n}\n\n#define jumptable JumpTable {\n    swap_exact\n    add_liq\n    remove_liq\n    flash_loan\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Pendekatan 2: Tabel Kode yang Dipadatkan\u003C\u002Fh3>\n\u003Cp>Untuk kepadatan maksimum, Anda bisa memadatkan jump table langsung ke dalam bytecode menggunakan \u003Ccode>__tablestart\u003C\u002Fcode> dan \u003Ccode>__tablesize\u003C\u002Fcode>. Huff secara native mendukung jump table sebagai konstruk kelas satu:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-huff\">#define jumptable__packed SELECTOR_TABLE {\n    fn_swap\n    fn_transfer\n    fn_approve\n    fn_balance\n}\n\n#define macro MAIN() = takes(0) returns(0) {\n    0x00 calldataload 0xe0 shr\n    0x18 shr\n    dup1 0x04 lt\n    valid jumpi\n    0x00 0x00 revert\n\n    valid:\n    __tablestart(SELECTOR_TABLE)\n    swap1 0x02 mul add\n    0x1e mload\n    jump\n\n    fn_swap:\n        SWAP_IMPL()\n    fn_transfer:\n        TRANSFER_IMPL()\n    fn_approve:\n        APPROVE_IMPL()\n    fn_balance:\n        BALANCE_IMPL()\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"perbandingan-gas\">Perbandingan Gas\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Fungsi\u003C\u002Fth>\u003Cth>Solidity (if-else)\u003C\u002Fth>\u003Cth>Solidity (binary)\u003C\u002Fth>\u003Cth>Huff Jump Table\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>2\u003C\u002Ftd>\u003Ctd>22-44 gas\u003C\u002Ftd>\u003Ctd>22-44 gas\u003C\u002Ftd>\u003Ctd>15 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>4\u003C\u002Ftd>\u003Ctd>22-88 gas\u003C\u002Ftd>\u003Ctd>22-66 gas\u003C\u002Ftd>\u003Ctd>15 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>8\u003C\u002Ftd>\u003Ctd>22-176 gas\u003C\u002Ftd>\u003Ctd>22-88 gas\u003C\u002Ftd>\u003Ctd>15 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>16\u003C\u002Ftd>\u003Ctd>22-352 gas\u003C\u002Ftd>\u003Ctd>22-110 gas\u003C\u002Ftd>\u003Ctd>15 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>32\u003C\u002Ftd>\u003Ctd>22-704 gas\u003C\u002Ftd>\u003Ctd>22-132 gas\u003C\u002Ftd>\u003Ctd>15 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Biaya jump table konstan: CALLDATALOAD (3) + SHR (3) + aritmatika (3-6) + JUMP (8) = ~15-18 gas. Tidak pernah berubah terlepas dari jumlah fungsi.\u003C\u002Fp>\n\u003Ch2 id=\"mining-vanity-selector\">Mining Vanity Selector\u003C\u002Fh2>\n\u003Cp>Agar pendekatan jump table berfungsi, Anda memerlukan function selector dengan routing byte yang bisa diprediksi. Anda bisa mining ini:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-python\">import hashlib\nimport itertools\n\ntarget_byte = 0x00\nbase_name = \"swap\"\n\nfor suffix in itertools.count():\n    name = f\"{base_name}{suffix}(uint256,address)\"\n    selector = hashlib.sha3_256(name.encode()).digest()[:4]\n    if selector[0] == target_byte:\n        print(f\"Ditemukan: {name} -&gt; 0x{selector.hex()}\")\n        break\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Dalam praktik, kami menggunakan \u003Ccode>cast sig\u003C\u002Fcode> dari Foundry atau tool Rust yang brute-force nama fungsi untuk menemukan selector dengan prefix yang diinginkan.\u003C\u002Fp>\n\u003Ch2 id=\"dampak-ukuran-bytecode\">Dampak Ukuran Bytecode\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Pendekatan\u003C\u002Fth>\u003Cth>Runtime Bytecode\u003C\u002Fth>\u003Cth>Gas Deploy\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Solidity (8 funcs)\u003C\u002Ftd>\u003Ctd>~800 byte\u003C\u002Ftd>\u003Ctd>160.000 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Huff jump table (8 funcs)\u003C\u002Ftd>\u003Ctd>~200 byte\u003C\u002Ftd>\u003Ctd>40.000 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Huff minimal (2 funcs)\u003C\u002Ftd>\u003Ctd>~61 byte\u003C\u002Ftd>\u003Ctd>12.200 gas\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Untuk bot MEV yang sering men-redeploy kontrak, bytecode lebih kecil langsung diterjemahkan menjadi biaya operasional yang lebih rendah.\u003C\u002Fp>\n\u003Ch2 id=\"batasan\">Batasan\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>ABI non-standar\u003C\u002Fstrong> — Tool eksternal (Etherscan, wallet) tidak bisa mendecode calldata Anda tanpa definisi ABI kustom.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Mining selector\u003C\u002Fstrong> — Memerlukan pekerjaan di muka dan membatasi penamaan fungsi.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Biaya pemeliharaan\u003C\u002Fstrong> — Huff lebih sulit diaudit dan dimodifikasi dari Solidity.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Tabel yang dipadatkan\u003C\u002Fstrong> — Builtin \u003Ccode>__tablestart\u003C\u002Fcode> dan \u003Ccode>__tablesize\u003C\u002Fcode> memiliki edge case dengan compiler Huff; uji secara menyeluruh.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"ringkasan\">Ringkasan\u003C\u002Fh2>\n\u003Cp>Jump table menggantikan rantai dispatch O(N) Solidity dengan computed jump O(1). Penghematan gas bertambah melintasi jutaan panggilan — keunggulan signifikan untuk kontrak frekuensi tinggi seperti bot MEV dan router DEX.\u003C\u002Fp>\n","id","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:24.881224Z","Deep EVM #11: Jump Table Huff — Dispatch Fungsi O(1)","Bangun dispatcher fungsi O(1) di Huff menggunakan jump table. Bandingkan Solidity if-else dengan jump table yang menghemat ribuan gas.","Huff jump table dispatch",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000017","Huff","huff",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000018","Yul","yul","Blockchain",[41,47,53],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":39,"published_at":46},"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":48,"title":49,"slug":50,"excerpt":51,"locale":12,"category_name":39,"published_at":52},"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":54,"title":55,"slug":56,"excerpt":57,"locale":12,"category_name":39,"published_at":58},"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":60,"slug":61,"bio":62,"photo_url":19,"linkedin":19,"role":63,"created_at":64,"updated_at":64},"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"]