Ethereum Gas Optimization: Tips untuk Developer Smart Contract
Best practices hemat gas di Solidity: storage packing, memory vs calldata, dan loop optimization untuk smart contract.
Gas adalah satuan biaya komputasi di Ethereum, dan setiap operasi di smart contract punya harga gas spesifik yang ditetapkan oleh protocol. Untuk developer Solidity, gas optimization bukan opsional - kontrak yang boros gas membuat transaksi mahal, user pindah ke kompetitor, dan kadang transaksi gagal karena out-of-gas. Artikel ini merangkum teknik fundamental yang harus dikuasai developer pemula sampai menengah.
Yang Anda butuhkan: pemahaman dasar Solidity (state variable, function modifier, mapping), tooling Hardhat atau Foundry, dan kebiasaan menjalankan gas reporter di test suite.
Storage Packing: Hemat Slot 32 Byte
State variable di Solidity disimpan dalam storage slot 32 byte. Setiap operasi tulis ke slot baru biaya SSTORE 20.000 gas (untuk slot kosong) atau 5.000 gas (slot yang sudah ada nilainya). Membaca biaya SLOAD 2.100 gas untuk cold access.
Solidity compiler otomatis packing variable kecil yang berdekatan ke dalam satu slot. Trik developer: urutkan deklarasi variable agar yang kecil berkumpul.
// BURUK: 3 slot dipakai
contract Bad {
uint256 a; // slot 0
uint128 b; // slot 1 (terbuang setengah)
uint256 c; // slot 2
uint128 d; // slot 3 (terbuang setengah)
}
// BAIK: 2 slot dipakai
contract Good {
uint256 a; // slot 0
uint256 c; // slot 1
uint128 b; // slot 2 (sharing dengan d)
uint128 d; // slot 2
}
Hemat 2 slot = hemat 40.000 gas saat deployment ditambah saving SLOAD/SSTORE setiap kali variable diakses bersamaan. Untuk kontrak yang sering update state, ini akumulasi besar.
Tip: Pakai
uint128,uint64,uint32untuk variable yang Anda yakin tidak melebihi range, tapi jangan paksakan untuk variable counter besar - overflow lebih mahal dari saving gas.
Memory vs Calldata: Pilih yang Tepat
Untuk function parameter berupa array atau string, ada dua data location:
- memory: data disalin ke memori kontrak, bisa dimodifikasi
- calldata: data dibaca langsung dari calldata transaksi, read-only
Calldata jauh lebih murah karena tidak ada penyalinan. Aturannya: kalau parameter tidak perlu dimodifikasi di function body, selalu pakai calldata.
// BURUK: copy ke memory tanpa alasan
function processArray(uint256[] memory data) external view {
for (uint i = 0; i < data.length; i++) {
// hanya baca
}
}
// BAIK: calldata read-only
function processArray(uint256[] calldata data) external view {
for (uint i = 0; i < data.length; i++) {
// hanya baca
}
}
Saving bisa ribuan gas per call untuk array berukuran sedang. Hanya pakai memory kalau perlu modify data lokal atau passing ke function internal yang butuh memory.
Loop Optimization
Loop adalah sumber utama gas waste. Beberapa teknik:
1. Cache panjang array
// BURUK: data.length dievaluasi setiap iterasi
for (uint i = 0; i < data.length; i++) { ... }
// BAIK: cache di local variable
uint256 len = data.length;
for (uint i = 0; i < len; i++) { ... }
2. Hindari storage access di loop
Setiap SLOAD biaya 2.100 gas cold dan 100 gas warm. Loop yang membaca storage variable sama berulang kali = pemborosan masif.
// BURUK: SLOAD setiap iterasi
for (uint i = 0; i < users.length; i++) {
balances[i] += rewardRate; // rewardRate adalah storage
}
// BAIK: cache ke memory
uint256 rate = rewardRate;
for (uint i = 0; i < users.length; i++) {
balances[i] += rate;
}
3. Unchecked increment
Sejak Solidity 0.8.0, integer arithmetic punya overflow check otomatis. Untuk counter loop yang tidak mungkin overflow, pakai unchecked block:
for (uint i = 0; i < len;) {
// body
unchecked { ++i; }
}
Hemat ~30-40 gas per iterasi. Untuk loop panjang, signifikan.
Function Selector & External vs Public
Function visibility punya implikasi gas:
- external: cuma bisa dipanggil dari luar kontrak, parameter dari calldata
- public: bisa dipanggil dari luar dan internal, parameter di-copy ke memory
Kalau function tidak dipanggil dari dalam kontrak yang sama, pakai external. Selain saving gas, ini juga signal intent yang lebih jelas untuk reviewer kode.
Selector function (4 byte pertama) di-sort EVM saat dispatching. Function dengan selector lebih kecil di-check duluan. Trik: kalau ada function yang sangat sering dipanggil, rename agar selector-nya kecil (hash-nya rendah). Tool seperti forge inspect membantu cek.
Custom Errors vs Require String
Sejak Solidity 0.8.4, ada custom error yang lebih hemat gas dari require dengan string message.
// BURUK: string disimpan di bytecode dan abi-encoded saat revert
require(msg.sender == owner, "Caller is not owner");
// BAIK: custom error
error NotOwner();
if (msg.sender != owner) revert NotOwner();
Saving deployment gas (~kontrak lebih kecil) dan runtime gas saat revert. Untuk kontrak dengan banyak require statement, total saving substansial.
Risiko Over-Optimization
Optimasi gas punya batas. Beberapa anti-pattern:
- Assembly inline tanpa audit: bisa hemat gas signifikan tapi rentan bug. Hanya pakai kalau Anda yakin dan akan diaudit profesional.
- Storage packing ekstrem: variable yang dipack sangat ketat sulit dibaca dan rentan bug saat upgrade.
- Skip safety check: pakai
uncheckeddi tempat yang mungkin overflow = bug menunggu terjadi.
Prinsip umum: readability > saving 100 gas. Optimasi yang sebanding biasanya saving ribuan gas, bukan puluhan.
Tools Wajib
- Foundry / Hardhat gas reporter: jalankan setiap test, lihat gas per function
- forge snapshot: track gas regression di CI
- Slither: static analyzer yang flag pattern boros gas
- eth_estimateGas: cek estimate sebelum deploy ke mainnet
Kesimpulan
Gas optimization adalah disiplin yang dipelajari bertahap. Storage packing, calldata vs memory, dan loop hygiene adalah dasar yang harus dikuasai. Custom errors dan unchecked arithmetic adalah quick win modern Solidity.
Tapi ingat: prioritas pertama selalu correctness dan security. Smart contract paling hemat gas pun useless kalau punya bug yang membuat dana user hilang. Tulis test komprehensif, audit sebelum mainnet, dan jangan sacrifice keamanan demi saving beberapa puluh gas.
Disclaimer: Artikel ini panduan teknis untuk developer. Semua contoh kode untuk ilustrasi - tes di environment lokal sebelum deploy. Smart contract di mainnet butuh audit profesional.
Sumber
- Solidity Docs - Gas Costs(akses 20 Mei 2026)
- Ethereum.org - Smart Contract Development(akses 20 Mei 2026)
- EIP-2929: Gas Cost Increases for State Access Opcodes(akses 20 Mei 2026)
- CoinGecko Learn - Smart Contract Gas Explained(akses 20 Mei 2026)
Konten ini hanya untuk tujuan informasi dan bukan rekomendasi investasi. Aset kripto memiliki risiko tinggi termasuk kerugian total modal. Lakukan riset mandiri dan konsultasikan dengan penasihat keuangan terdaftar sebelum mengambil keputusan investasi.