[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-16-bundling-resolusi-konflik-mengemas-transaksi":3},{"article":4,"author":62},{"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-000000000116","a0000000-0000-0000-0000-000000000026","Deep EVM #16: Bundling dan Resolusi Konflik — Mengemas Transaksi Menguntungkan","deep-evm-16-bundling-resolusi-konflik-mengemas-transaksi","Strategi mengemas transaksi MEV ke dalam bundle yang menguntungkan: deteksi konflik state, resolusi prioritas, bidding ke block builder, dan mengirim melalui Flashbots.","## Dari Peluang ke Bundle\n\nSetelah menemukan dan mensimulasikan peluang MEV, langkah terakhir adalah mengemasnya ke dalam bundle transaksi dan mengirimnya ke pembangun block. Proses ini bukan semudah mengirim transaksi — ada konflik state, persaingan dengan pencari lain, dan strategi bidding yang harus diperhatikan.\n\n## Apa Itu Bundle MEV?\n\nBundle adalah kumpulan transaksi yang harus dieksekusi secara berurutan dan atomik — semua berhasil atau semua gagal. Bundle dikirim ke pembangun block, bukan ke mempool publik.\n\n```rust\nstruct MevBundle {\n    transactions: Vec\u003CSignedTransaction>,\n    block_number: u64,\n    min_timestamp: Option\u003Cu64>,\n    max_timestamp: Option\u003Cu64>,\n    reverting_tx_hashes: Vec\u003CB256>, \u002F\u002F TX yang boleh revert\n}\n```\n\nKomponen bundle:\n- **Transaksi berurutan** — Urutan eksekusi dijamin\n- **Target block** — Bundle hanya valid untuk block tertentu\n- **Atomisitas** — Jika satu transaksi gagal, seluruh bundle dibatalkan\n\n## Deteksi Konflik State\n\nDua peluang MEV berkonflik ketika mereka menyentuh state yang sama. Misalnya, dua arbitrase yang keduanya swap di pool yang sama:\n\n```rust\n#[derive(Hash, Eq, PartialEq)]\nenum StateKey {\n    StorageSlot(Address, U256),\n    Balance(Address),\n}\n\nstruct StateAccess {\n    reads: HashSet\u003CStateKey>,\n    writes: HashSet\u003CStateKey>,\n}\n\nfn conflicts(a: &StateAccess, b: &StateAccess) -> bool {\n    \u002F\u002F Konflik jika satu menulis apa yang lain baca atau tulis\n    !a.writes.is_disjoint(&b.reads)\n        || !a.writes.is_disjoint(&b.writes)\n        || !a.reads.is_disjoint(&b.writes)\n}\n```\n\nDeteksi konflik dilakukan selama simulasi — revm melacak semua akses storage.\n\n## Resolusi Konflik\n\nKetika peluang berkonflik, Anda harus memilih mana yang disertakan:\n\n### Strategi 1: Greedy by Profit\nPilih peluang dengan profit tertinggi, tandai yang berkonflik sebagai diblokir, lanjut:\n\n```rust\nfn resolve_greedy(opportunities: &mut Vec\u003COpportunity>) -> Vec\u003COpportunity> {\n    \u002F\u002F Urutkan berdasarkan profit (terbesar dulu)\n    opportunities.sort_by(|a, b| b.profit.cmp(&a.profit));\n    \n    let mut selected = Vec::new();\n    let mut blocked_states = HashSet::new();\n    \n    for opp in opportunities {\n        if opp.state_access.writes.is_disjoint(&blocked_states)\n            && opp.state_access.reads.is_disjoint(&blocked_states)\n        {\n            blocked_states.extend(opp.state_access.writes.iter().cloned());\n            blocked_states.extend(opp.state_access.reads.iter().cloned());\n            selected.push(opp.clone());\n        }\n    }\n    \n    selected\n}\n```\n\n### Strategi 2: Simulasi Kombinatorial\nUntuk sejumlah kecil peluang, simulasikan semua kombinasi yang tidak berkonflik dan pilih yang memaksimalkan total profit:\n\n```rust\nfn resolve_optimal(\n    opportunities: &[Opportunity],\n    db: &CacheDB\u003Cimpl DatabaseRef>,\n) -> Vec\u003COpportunity> {\n    let non_conflicting = find_independent_sets(opportunities);\n    \n    let mut best_set = Vec::new();\n    let mut best_profit = U256::ZERO;\n    \n    for set in non_conflicting {\n        let mut sim_db = db.clone();\n        let total = simulate_set(&mut sim_db, &set);\n        \n        if total > best_profit {\n            best_profit = total;\n            best_set = set;\n        }\n    }\n    \n    best_set\n}\n```\n\n## Strategi Bidding\n\nPembangun block menerima bundle dari banyak pencari. Untuk memastikan bundle Anda disertakan, Anda perlu menawar cukup tinggi:\n\n### Tip sebagai Persentase Profit\n```rust\nfn calculate_tip(\n    gross_profit: U256,\n    gas_cost: U256,\n    tip_percentage: u64, \u002F\u002F 80-95%\n) -> U256 {\n    let net_profit = gross_profit - gas_cost;\n    net_profit * U256::from(tip_percentage) \u002F U256::from(100)\n}\n```\n\nPencari MEV kompetitif biasanya memberikan 85-95% profit sebagai tip ke pembangun. Margin tipis ini masih menguntungkan karena volume tinggi.\n\n### Transfer ETH untuk Tip\nTip dikirim sebagai transfer ETH ke coinbase (alamat pembangun block):\n\n```rust\nfn create_tip_transaction(\n    searcher: Address,\n    tip_amount: U256,\n    nonce: u64,\n) -> Transaction {\n    Transaction {\n        from: searcher,\n        to: Address::ZERO, \u002F\u002F Diganti dengan coinbase saat runtime\n        value: tip_amount,\n        data: Bytes::new(),\n        gas_limit: 21_000,\n        nonce,\n        ..Default::default()\n    }\n}\n```\n\n## Mengirim Bundle via Flashbots\n\n```rust\nuse reqwest::Client;\n\nasync fn send_bundle(\n    client: &Client,\n    bundle: &MevBundle,\n    signer: &LocalWallet,\n) -> Result\u003CB256, Error> {\n    let payload = json!({\n        \"jsonrpc\": \"2.0\",\n        \"method\": \"eth_sendBundle\",\n        \"params\": [{\n            \"txs\": bundle.transactions.iter()\n                .map(|tx| format!(\"0x{}\", hex::encode(tx.rlp())))\n                .collect::\u003CVec\u003C_>>(),\n            \"blockNumber\": format!(\"0x{:x}\", bundle.block_number),\n        }],\n        \"id\": 1,\n    });\n    \n    let signature = sign_payload(signer, &payload).await?;\n    \n    let response = client\n        .post(\"https:\u002F\u002Frelay.flashbots.net\")\n        .header(\"X-Flashbots-Signature\", signature)\n        .json(&payload)\n        .send()\n        .await?;\n    \n    let result: JsonRpcResponse = response.json().await?;\n    Ok(result.result)\n}\n```\n\n## Pipeline Lengkap\n\nAlur lengkap dari deteksi hingga pengiriman:\n\n```\n1. Event listener mendeteksi perubahan state\n   |\n2. Pencari siklus menemukan peluang\n   |\n3. Simulator memverifikasi dan mengoptimasi\n   |\n4. Resolver menangani konflik\n   |\n5. Bundler mengemas transaksi + tip\n   |\n6. Sender mengirim ke Flashbots\u002Fpembangun\n   |\n7. Pembangun menyertakan di block (atau tidak)\n```\n\nSeluruh pipeline harus selesai dalam 2-4 detik untuk kompetitif.\n\n## Monitoring dan Analitik\n\n```rust\nstruct BundleMetrics {\n    bundles_sent: u64,\n    bundles_included: u64,\n    bundles_reverted: u64,\n    total_profit: U256,\n    total_tips_paid: U256,\n    avg_inclusion_rate: f64,\n}\n```\n\nTrack:\n- **Inclusion rate** — Berapa persen bundle Anda disertakan? Di bawah 20% berarti tip terlalu rendah atau timing terlalu lambat.\n- **Revert rate** — Bundle yang revert mengindikasikan simulasi yang tidak akurat.\n- **Profit per gas** — Metrik efisiensi yang menormalkan profitabilitas.\n\n## Kesimpulan\n\nBundling adalah langkah terakhir dalam pipeline MEV — mengubah peluang terdeteksi menjadi keuntungan aktual. Deteksi konflik memastikan bundle konsisten, strategi bidding kompetitif memastikan inklusi, dan monitoring memberikan feedback untuk iterasi. Keseluruhan seri Deep EVM dari artikel 1 hingga 16 telah membangun fondasi lengkap: dari opcode EVM, melalui Yul dan Huff, hingga arsitektur bot MEV produksi.","\u003Ch2 id=\"dari-peluang-ke-bundle\">Dari Peluang ke Bundle\u003C\u002Fh2>\n\u003Cp>Setelah menemukan dan mensimulasikan peluang MEV, langkah terakhir adalah mengemasnya ke dalam bundle transaksi dan mengirimnya ke pembangun block. Proses ini bukan semudah mengirim transaksi — ada konflik state, persaingan dengan pencari lain, dan strategi bidding yang harus diperhatikan.\u003C\u002Fp>\n\u003Ch2 id=\"apa-itu-bundle-mev\">Apa Itu Bundle MEV?\u003C\u002Fh2>\n\u003Cp>Bundle adalah kumpulan transaksi yang harus dieksekusi secara berurutan dan atomik — semua berhasil atau semua gagal. Bundle dikirim ke pembangun block, bukan ke mempool publik.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct MevBundle {\n    transactions: Vec&lt;SignedTransaction&gt;,\n    block_number: u64,\n    min_timestamp: Option&lt;u64&gt;,\n    max_timestamp: Option&lt;u64&gt;,\n    reverting_tx_hashes: Vec&lt;B256&gt;, \u002F\u002F TX yang boleh revert\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Komponen bundle:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Transaksi berurutan\u003C\u002Fstrong> — Urutan eksekusi dijamin\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Target block\u003C\u002Fstrong> — Bundle hanya valid untuk block tertentu\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Atomisitas\u003C\u002Fstrong> — Jika satu transaksi gagal, seluruh bundle dibatalkan\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"deteksi-konflik-state\">Deteksi Konflik State\u003C\u002Fh2>\n\u003Cp>Dua peluang MEV berkonflik ketika mereka menyentuh state yang sama. Misalnya, dua arbitrase yang keduanya swap di pool yang sama:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">#[derive(Hash, Eq, PartialEq)]\nenum StateKey {\n    StorageSlot(Address, U256),\n    Balance(Address),\n}\n\nstruct StateAccess {\n    reads: HashSet&lt;StateKey&gt;,\n    writes: HashSet&lt;StateKey&gt;,\n}\n\nfn conflicts(a: &amp;StateAccess, b: &amp;StateAccess) -&gt; bool {\n    \u002F\u002F Konflik jika satu menulis apa yang lain baca atau tulis\n    !a.writes.is_disjoint(&amp;b.reads)\n        || !a.writes.is_disjoint(&amp;b.writes)\n        || !a.reads.is_disjoint(&amp;b.writes)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Deteksi konflik dilakukan selama simulasi — revm melacak semua akses storage.\u003C\u002Fp>\n\u003Ch2 id=\"resolusi-konflik\">Resolusi Konflik\u003C\u002Fh2>\n\u003Cp>Ketika peluang berkonflik, Anda harus memilih mana yang disertakan:\u003C\u002Fp>\n\u003Ch3>Strategi 1: Greedy by Profit\u003C\u002Fh3>\n\u003Cp>Pilih peluang dengan profit tertinggi, tandai yang berkonflik sebagai diblokir, lanjut:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn resolve_greedy(opportunities: &amp;mut Vec&lt;Opportunity&gt;) -&gt; Vec&lt;Opportunity&gt; {\n    \u002F\u002F Urutkan berdasarkan profit (terbesar dulu)\n    opportunities.sort_by(|a, b| b.profit.cmp(&amp;a.profit));\n    \n    let mut selected = Vec::new();\n    let mut blocked_states = HashSet::new();\n    \n    for opp in opportunities {\n        if opp.state_access.writes.is_disjoint(&amp;blocked_states)\n            &amp;&amp; opp.state_access.reads.is_disjoint(&amp;blocked_states)\n        {\n            blocked_states.extend(opp.state_access.writes.iter().cloned());\n            blocked_states.extend(opp.state_access.reads.iter().cloned());\n            selected.push(opp.clone());\n        }\n    }\n    \n    selected\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Strategi 2: Simulasi Kombinatorial\u003C\u002Fh3>\n\u003Cp>Untuk sejumlah kecil peluang, simulasikan semua kombinasi yang tidak berkonflik dan pilih yang memaksimalkan total profit:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn resolve_optimal(\n    opportunities: &amp;[Opportunity],\n    db: &amp;CacheDB&lt;impl DatabaseRef&gt;,\n) -&gt; Vec&lt;Opportunity&gt; {\n    let non_conflicting = find_independent_sets(opportunities);\n    \n    let mut best_set = Vec::new();\n    let mut best_profit = U256::ZERO;\n    \n    for set in non_conflicting {\n        let mut sim_db = db.clone();\n        let total = simulate_set(&amp;mut sim_db, &amp;set);\n        \n        if total &gt; best_profit {\n            best_profit = total;\n            best_set = set;\n        }\n    }\n    \n    best_set\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"strategi-bidding\">Strategi Bidding\u003C\u002Fh2>\n\u003Cp>Pembangun block menerima bundle dari banyak pencari. Untuk memastikan bundle Anda disertakan, Anda perlu menawar cukup tinggi:\u003C\u002Fp>\n\u003Ch3>Tip sebagai Persentase Profit\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn calculate_tip(\n    gross_profit: U256,\n    gas_cost: U256,\n    tip_percentage: u64, \u002F\u002F 80-95%\n) -&gt; U256 {\n    let net_profit = gross_profit - gas_cost;\n    net_profit * U256::from(tip_percentage) \u002F U256::from(100)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Pencari MEV kompetitif biasanya memberikan 85-95% profit sebagai tip ke pembangun. Margin tipis ini masih menguntungkan karena volume tinggi.\u003C\u002Fp>\n\u003Ch3>Transfer ETH untuk Tip\u003C\u002Fh3>\n\u003Cp>Tip dikirim sebagai transfer ETH ke coinbase (alamat pembangun block):\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-rust\">fn create_tip_transaction(\n    searcher: Address,\n    tip_amount: U256,\n    nonce: u64,\n) -&gt; Transaction {\n    Transaction {\n        from: searcher,\n        to: Address::ZERO, \u002F\u002F Diganti dengan coinbase saat runtime\n        value: tip_amount,\n        data: Bytes::new(),\n        gas_limit: 21_000,\n        nonce,\n        ..Default::default()\n    }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"mengirim-bundle-via-flashbots\">Mengirim Bundle via Flashbots\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">use reqwest::Client;\n\nasync fn send_bundle(\n    client: &amp;Client,\n    bundle: &amp;MevBundle,\n    signer: &amp;LocalWallet,\n) -&gt; Result&lt;B256, Error&gt; {\n    let payload = json!({\n        \"jsonrpc\": \"2.0\",\n        \"method\": \"eth_sendBundle\",\n        \"params\": [{\n            \"txs\": bundle.transactions.iter()\n                .map(|tx| format!(\"0x{}\", hex::encode(tx.rlp())))\n                .collect::&lt;Vec&lt;_&gt;&gt;(),\n            \"blockNumber\": format!(\"0x{:x}\", bundle.block_number),\n        }],\n        \"id\": 1,\n    });\n    \n    let signature = sign_payload(signer, &amp;payload).await?;\n    \n    let response = client\n        .post(\"https:\u002F\u002Frelay.flashbots.net\")\n        .header(\"X-Flashbots-Signature\", signature)\n        .json(&amp;payload)\n        .send()\n        .await?;\n    \n    let result: JsonRpcResponse = response.json().await?;\n    Ok(result.result)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"pipeline-lengkap\">Pipeline Lengkap\u003C\u002Fh2>\n\u003Cp>Alur lengkap dari deteksi hingga pengiriman:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>1. Event listener mendeteksi perubahan state\n   |\n2. Pencari siklus menemukan peluang\n   |\n3. Simulator memverifikasi dan mengoptimasi\n   |\n4. Resolver menangani konflik\n   |\n5. Bundler mengemas transaksi + tip\n   |\n6. Sender mengirim ke Flashbots\u002Fpembangun\n   |\n7. Pembangun menyertakan di block (atau tidak)\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Seluruh pipeline harus selesai dalam 2-4 detik untuk kompetitif.\u003C\u002Fp>\n\u003Ch2 id=\"monitoring-dan-analitik\">Monitoring dan Analitik\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-rust\">struct BundleMetrics {\n    bundles_sent: u64,\n    bundles_included: u64,\n    bundles_reverted: u64,\n    total_profit: U256,\n    total_tips_paid: U256,\n    avg_inclusion_rate: f64,\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Track:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Inclusion rate\u003C\u002Fstrong> — Berapa persen bundle Anda disertakan? Di bawah 20% berarti tip terlalu rendah atau timing terlalu lambat.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Revert rate\u003C\u002Fstrong> — Bundle yang revert mengindikasikan simulasi yang tidak akurat.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Profit per gas\u003C\u002Fstrong> — Metrik efisiensi yang menormalkan profitabilitas.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"kesimpulan\">Kesimpulan\u003C\u002Fh2>\n\u003Cp>Bundling adalah langkah terakhir dalam pipeline MEV — mengubah peluang terdeteksi menjadi keuntungan aktual. Deteksi konflik memastikan bundle konsisten, strategi bidding kompetitif memastikan inklusi, dan monitoring memberikan feedback untuk iterasi. Keseluruhan seri Deep EVM dari artikel 1 hingga 16 telah membangun fondasi lengkap: dari opcode EVM, melalui Yul dan Huff, hingga arsitektur bot MEV produksi.\u003C\u002Fp>\n","id","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:24.909089Z","Deep EVM #16: Bundling dan Resolusi Konflik — Mengemas Transaksi MEV","Strategi bundling MEV: deteksi konflik state, resolusi prioritas, bidding ke pembangun block, dan pengiriman via Flashbots.","bundling MEV Flashbots",null,"index, follow",[22,27,31,35],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000019","MEV","mev","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000001","Rust","rust",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000013","Security","security",{"id":36,"name":37,"slug":38,"created_at":26},"c0000000-0000-0000-0000-000000000009","Web3","web3","Rekayasa",[41,48,55],{"id":42,"title":43,"slug":44,"excerpt":45,"locale":12,"category_name":46,"published_at":47},"d0000000-0000-0000-0000-000000000642","WASI 0.3 dan Kematian Cold Start: Wasm Sisi Server di Produksi","wasi-0-3-kematian-cold-start-wasm-sisi-server-di-produksi","WASI 0.3 dirilis pada Februari 2026 dengan async I\u002FO native, tipe stream, dan dukungan socket penuh. WebAssembly sisi server kini menghadirkan cold start dalam hitungan mikrodetik, dan setiap penyedia cloud besar menawarkan Wasm serverless.","DevOps","2026-03-28T10:44:47.445780Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":53,"published_at":54},"d0000000-0000-0000-0000-000000000620","Stack Backend Modern 2026: Rust + PostgreSQL 18 + Wasm + eBPF","stack-backend-modern-2026-rust-postgresql-wasm-ebpf","Empat teknologi konvergen untuk mendefinisikan ulang infrastruktur backend di 2026: Rust menghilangkan overhead garbage collection dan mengurangi jumlah container hingga 3x, PostgreSQL 18 menggantikan database khusus, WASI 0.3 memberikan cold start mikrodetik untuk fungsi serverless, dan eBPF memungkinkan observabilitas tanpa instrumentasi dengan biaya yang jauh lebih rendah dari monitoring tradisional.","Engineering","2026-03-28T10:44:45.804120Z",{"id":56,"title":57,"slug":58,"excerpt":59,"locale":12,"category_name":60,"published_at":61},"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.","Blockchain","2026-03-28T10:44:44.364342Z",{"id":13,"name":63,"slug":64,"bio":65,"photo_url":19,"linkedin":19,"role":66,"created_at":67,"updated_at":67},"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"]