Langsung ke konten utama
BlockchainMar 28, 2026

Deep EVM #3: Memahami Gas — Mengapa Kontrak Anda Mahal

OS
Open Soft Team

Engineering Team

Apa Itu Gas dan Mengapa Ada?

Gas adalah unit pengukuran komputasi di Ethereum. Setiap operasi dalam EVM memerlukan sejumlah gas tertentu, dan pengguna membayar gas ini dengan ETH. Gas memecahkan dua masalah fundamental:

  1. Halting problem — Tanpa batas gas, smart contract bisa berjalan selamanya, membekukan seluruh jaringan.
  2. Penetapan harga sumber daya — Gas memastikan bahwa penggunaan CPU, storage, dan bandwidth jaringan dihargai secara adil.

Total biaya transaksi = gas_used * gas_price. Sejak EIP-1559, gas_price terdiri dari base_fee (dibakar) + priority_fee (ke validator).

Anatomi Biaya Gas Transaksi

Ketika Anda mengirim transaksi, biaya gas dipecah menjadi beberapa komponen:

1. Gas Intrinsik (21.000 minimum)

Setiap transaksi membayar setidaknya 21.000 gas hanya untuk eksis. Ini mencakup verifikasi tanda tangan, pembaruan nonce, dan biaya overhead jaringan.

2. Biaya Calldata

  • 4 gas per byte zero
  • 16 gas per byte non-zero

Ini mengapa teknik kompresi calldata penting. EIP-4844 (proto-danksharding) memperkenalkan blob space yang lebih murah untuk data rollup.

3. Biaya Eksekusi

Setiap opcode yang dieksekusi menambah biaya gas. Opcode aritmatika sederhana (ADD, SUB) memerlukan 3 gas. Operasi storage bisa memerlukan ribuan gas.

4. Biaya Ekspansi Memory

Memory EVM tumbuh secara dinamis, dan biaya tumbuh secara kuadratik:

biaya_memory(ukuran) = 3 * a + floor(a^2 / 512)
di mana a = ceil(ukuran / 32)

Untuk 1 KB memory: ~96 gas. Untuk 1 MB: ~3.145.728 gas. Pertumbuhan kuadratik ini mencegah kontrak menggunakan memory berlebihan.

EIP-1559: Mekanisme Biaya Base Fee

Sebelum EIP-1559, gas price ditentukan melalui lelang first-price — pengguna menebak berapa yang harus dibayar. EIP-1559 (London, Agustus 2021) memperkenalkan:

  • Base fee — Ditetapkan secara algoritmik berdasarkan utilisasi block sebelumnya. Jika block sebelumnya penuh, base fee naik ~12.5%. Jika kosong, turun ~12.5%.
  • Priority fee (tip) — Biaya tambahan langsung ke validator untuk memprioritaskan transaksi Anda.
  • Max fee — Jumlah maksimum yang bersedia Anda bayar (base + priority).
// Biaya efektif per gas:
effective_gas_price = min(max_fee, base_fee + priority_fee)

// Yang dibakar:
burned = base_fee * gas_used

// Yang ke validator:
tip = (effective_gas_price - base_fee) * gas_used

Opcode Termahal

Berikut opcode yang paling berdampak pada biaya gas:

OpcodeBiaya GasPenjelasan
SSTORE (cold, 0→1)22.100Menulis ke slot storage baru
SSTORE (cold, 1→1)5.000Mengubah slot storage yang ada
CREATE32.000Membuat kontrak baru
CREATE232.000Membuat kontrak dengan alamat deterministik
SLOAD (cold)2.100Membaca slot storage pertama kali
CALL (cold)2.600Memanggil kontrak lain pertama kali
LOG41.875+Menerbitkan event dengan 4 topik
EXTCODESIZE (cold)2.600Memeriksa ukuran kode kontrak

Teknik Optimasi Gas

1. Caching Storage

Pola paling berdampak — cache pembacaan storage ke variabel lokal:

// Buruk: 2 SLOAD = 2200 gas (warm)
function buruk() external view returns (uint256) {
    return balances[msg.sender] + balances[msg.sender];
}

// Baik: 1 SLOAD + 1 DUP = 103 gas
function baik() external view returns (uint256) {
    uint256 bal = balances[msg.sender];
    return bal + bal;
}

2. Short-Circuit dengan Assembly

// Solidity menghasilkan branching yang berat
require(a > 0 && b > 0 && c > 0);

// Yul: single-pass check
assembly {
    if iszero(and(and(gt(a, 0), gt(b, 0)), gt(c, 0))) {
        revert(0, 0)
    }
}

3. Packed Storage

Gabungkan variabel kecil ke dalam satu slot:

// 3 slot storage (66.300 gas untuk menulis semua):
uint256 a; uint256 b; uint256 c;

// 1 slot storage (22.100 gas):
uint64 a; uint64 b; uint128 c;

4. Gunakan Errors Kustom

// String error: ~130+ byte calldata (mahal)
require(x > 0, "Value must be greater than zero");

// Kustom error: 4 byte selector (murah)
error ValueTooLow();
if (x == 0) revert ValueTooLow();

5. Unchecked Arithmetic

Ketika Anda yakin tidak ada overflow:

// Dengan pemeriksaan overflow (default Solidity 0.8+):
for (uint256 i = 0; i < length; i++) { ... }

// Tanpa pemeriksaan (hemat ~60 gas per iterasi):
for (uint256 i = 0; i < length; ) {
    // ...
    unchecked { ++i; }
}

Gas Refund

Beberapa operasi memberikan refund gas:

  • SSTORE (nonzero → zero): Refund 4.800 gas
  • Refund dibatasi pada 20% dari total gas yang digunakan (EIP-3529)

Ini berarti membersihkan storage masih menguntungkan, tetapi tidak sebanyak sebelum EIP-3529 yang membatasi refund dari 50% ke 20%.

Access List (EIP-2930)

Anda dapat menyertakan access list dalam transaksi untuk “memanaskan” alamat dan slot storage di muka:

{
  "accessList": [
    {
      "address": "0x1234....",
      "storageKeys": ["0x00", "0x01"]
    }
  ]
}

Biaya: 2400 gas per alamat + 1900 per slot. Ini lebih murah daripada akses cold pertama (2600/2100), sehingga menghemat gas ketika Anda tahu slot mana yang akan diakses.

Profiling Gas dengan Foundry

Foundry menyediakan alat untuk menganalisis biaya gas:

# Gas report per fungsi:
forge test --gas-report

# Snapshot untuk perbandingan:
forge snapshot
forge snapshot --diff

# Tracing detail:
forge test -vvvv

Kesimpulan

Optimasi gas adalah campuran ilmu dan seni. Memahami biaya setiap opcode, menggunakan caching storage, mengemas variabel, dan memanfaatkan teknik assembly bisa mengurangi biaya gas secara dramatis. Untuk MEV bot dan kontrak frekuensi tinggi, setiap unit gas yang dihemat langsung diterjemahkan menjadi keuntungan.