Belajar Solidity - Fungsi, Modifier & Visibility
Episode 5 of 23

Belajar Solidity - Fungsi, Modifier & Visibility

Mendalami fungsi Solidity: visibility public, external, internal, dan private, mutability view, pure, dan payable, return multiple values, pola modifier onlyOwner, serta perbandingan require, assert, revert, dan custom error yang lebih hemat gas

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 4 kalian menguasai tipe data dan data location, pada episode ini kita mempelajari bahasa antarmuka kontrak: fungsi, modifier, dan visibility. Inilah yang menentukan siapa yang boleh memanggil apa, dan bagaimana kontrak memvalidasi input.

Mengapa episode ini penting? Karena hampir semua kerentanan akses kontrol berawal dari visibility atau modifier yang salah: fungsi yang seharusnya private ternyata public, atau guard onlyOwner yang lupa dipasang. Memahami keempat visibility dan cara kerja modifier sejak awal akan menyelamatkan kalian di episode 15 (security).

Visibility: Siapa yang Boleh Memanggil

VisibilityDari kontrak lainTurunan kontrakDalam kontrak
publicYaYaYa
externalYaTidakTidak (lewat this)
internalTidakYaYa
privateTidakTidakYa

Perbedaan penting public vs external:

  • external lebih hemat gas untuk data besar karena argumen dibaca dari calldata tanpa disalin ke memory.
  • public membuat state variable otomatis punya getter — tetapi untuk fungsi, external lebih disarankan saat tidak dipanggil internal.
solidity
function setData(bytes calldata data) external {
    // data dibaca langsung dari calldata, hemat gas
}

Mutability: view, pure, payable

  • view — membaca state, tidak mengubahnya. Bisa dipanggil tanpa gas.
  • pure — tidak membaca atau mengubah state; hanya komputasi murni.
  • payable — bisa menerima ETH. Fungsi non-payable akan revert jika dikirimi ETH.
solidity
function read() public view returns (uint256) {
    return totalSupply;
}
 
function add(uint256 a, uint256 b) public pure returns (uint256) {
    return a + b;
}
 
function deposit() public payable {
    balances[msg.sender] += msg.value;
}

Tip

Memakai view/pure dengan benar bukan hanya soal style — frontend bisa memanggil fungsi tanpa transaksi (gratis) jika mutability-nya view/pure. Label yang salah juga bikin kompiler mengeluh dan pembaca audior bingung.

Return Multiple Values

Solidity mendukung multiple return:

solidity
function getUser() public view returns (address, uint256) {
    return (owner, balance);
}

Pemanggilnya bisa menerima tuple dengan destructuring (di frontend dengan ethers.js, atau lewat tuple). Untuk hasil yang lebih terstruktur, kembalikan struct:

solidity
function getInfo() public view returns (User memory) {
    return user;
}

Modifier: Pola onlyOwner

Modifier adalah "wrapper" yang mengeksekusi logika sebelum dan/atau sesudah fungsi:

solidity
address public owner;
 
modifier onlyOwner() {
    require(msg.sender == owner, "Not owner");
    _;
}
 
function setOwner(address _newOwner) public onlyOwner {
    owner = _newOwner;
}

Tanda _; adalah titik tempat tubuh fungsi asli dijalankan. Dengan onlyOwner, setiap fungsi yang memasangnya otomatis memeriksa msg.sender sebelum dieksekusi. Ini pola yang paling banyak dipakai di dunia nyata.

require, assert, revert, dan Custom Error

Tiga mekanisme pembatalan transaksi (semuanya membuat transaksi revert):

MekanismePenggunaanBiaya gas
require(kondisi, "pesan")Validasi input & kondisi bisnisMenengah (string disimpan)
assert(kondisi)Invariant yang harus selalu benarLebih mahal
revert()Pembatalan di tengah logikaMenengah
error Nama()Custom errorPaling murah
solidity
error NotOwner();
error AmountTooSmall(uint256 amount);
 
function withdraw(uint256 amount) public onlyOwner {
    if (amount < 1 ether) revert AmountTooSmall(amount);
    // ...
}

Custom error di deklarasi dengan error jauh lebih hemat gas daripada require dengan string — error string disimpan di calldata (gratis ketika revert, tapi 4-byte selector custom error lebih kecil) dan mendukung parameter. Ini rekomendasi modern untuk kontrak baru.

Warning

assert seharusnya dipakai untuk invariant yang "tidak mungkin gagal" — jika assert gagal, itu tanda bug serius (bisa memakai seluruh gas). Untuk validasi input biasa, pakai require atau custom error.

Penutup

Inti yang harus dibawa pulang:

  • Pilih visibility dengan sadar: external hemat gas untuk argumen besar, internal/private untuk enkapsulasi.
  • view/pure gratis dipanggil; payable satu-satunya yang menerima ETH.
  • Modifier seperti onlyOwner memusatkan validasi akses di satu tempat.
  • Prefer custom error (error Nama()) dibanding require ber-string karena lebih hemat gas.

Di episode 6 selanjutnya kita akan membahas storage, memory, dan gas optimization — layout storage berbasis slot 32-byte, cara EVM menempatkan uint128, address, dan bool dalam satu slot, kapan immutable/constant menghemat gas, serta strategi menghindari SSTORE yang mahal. Sampai jumpa di episode 6!

Belajar Solidity - Fungsi, Modifier & Visibility | Belajar Solidity