OpenZeppelin — Ownable & access control
Kontrak yang menyimpan aset bernilai adalah target yang diperiksa banyak orang, termasuk yang berniat jahat. OpenZeppelin adalah pustaka kontrak yang sudah diaudit berulang kali dan dipakai di ribuan proyek produksi — pola pertama yang perlu kamu kenal sebelum menulis kontrak sendiri.
Intisari
- Jangan tulis ulang logika access control, ERC-20/721, atau matematika aman dari nol — pakai OpenZeppelin, yang sudah melalui banyak audit publik dan dipakai luas.
Ownable: satu pemilik, cocok untuk kontrak sederhana dengan satu admin.AccessControl: role-based, satu address bisa punya banyak role, cocok untuk sistem dengan beberapa jenis admin (mis.MINTER_ROLEterpisah dariPAUSER_ROLE).- Instalasi lewat package manager standar tiap tooling — npm untuk Hardhat,
forge installuntuk Foundry — laluimportseperti pustaka biasa. - Warisi (
is Ownable), jangan salin-tempel kodenya — supaya kalau OpenZeppelin merilis patch keamanan, kamu tinggalnpm update, bukan menambal manual di banyak file.
Kenapa tidak menulis sendiri
Pola "hanya pemilik boleh melakukan X" terlihat sepele untuk ditulis sendiri — beberapa baris
require(msg.sender == owner). Masalahnya bukan kesulitan menulisnya, tapi risiko kasus tepi yang
terlewat: transfer kepemilikan ke address nol yang mengunci kontrak selamanya, race condition saat mengganti
pemilik, atau lupa event saat kepemilikan berpindah. OpenZeppelin sudah menangani semua kasus tepi itu, dan
kodenya sudah dibaca ribuan auditor sebelum kamu.
Instalasi
# Hardhat
npm install @openzeppelin/contracts
# Foundry
forge install OpenZeppelin/openzeppelin-contracts
Ownable — satu pemilik
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
contract GoldToken is Ownable {
constructor(address pemilikAwal) Ownable(pemilikAwal) {}
function mintGold(address ke, uint256 jumlah) external onlyOwner {
// hanya pemilik yang lolos modifier onlyOwner
}
}
Ownable menyediakan onlyOwner, owner(),
transferOwnership(address baru), dan renounceOwnership() — lengkap dengan
perlindungan terhadap transfer ke address(0) yang bisa mengunci kontrak permanen tanpa pemilik.
AccessControl — banyak role
Begitu sistemmu butuh lebih dari satu jenis admin — misalnya tim operasional yang boleh mint tapi
tidak boleh mengubah parameter kontrak — Ownable jadi terlalu sempit. AccessControl
menyediakan role sebagai bytes32, dan satu address bisa memegang beberapa role sekaligus.
import "@openzeppelin/contracts/access/AccessControl.sol";
contract GoldToken is AccessControl {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
constructor(address admin) {
_grantRole(DEFAULT_ADMIN_ROLE, admin); // role bawaan: bisa grant/revoke role lain
_grantRole(MINTER_ROLE, admin);
}
function mintGold(address ke, uint256 jumlah) external onlyRole(MINTER_ROLE) {
// logika mint
}
function jeda() external onlyRole(PAUSER_ROLE) {
// logika jeda
}
}
Ownable | AccessControl | |
|---|---|---|
| Jumlah "jenis" admin | Satu | Sebanyak role yang kamu definisikan |
| Satu address, banyak peran? | Tidak relevan — cuma ada satu peran | Ya, lewat grantRole berulang |
| Cabut akses satu peran saja | Tidak bisa — harus ganti pemilik seutuhnya | revokeRole(MINTER_ROLE, address) |
| Kompleksitas | Rendah | Sedang — perlu memikirkan hierarki role |
Warisi, jangan salin-tempel. Kalau kamu menyalin kode Ownable.sol ke proyekmu
lalu mengedit-editnya, kamu kehilangan manfaat terbesarnya: saat OpenZeppelin merilis versi baru yang
menambal bug keamanan, proyek yang memakai import + npm update langsung mendapat
perbaikannya. Proyek yang menyalin kode harus menemukan sendiri bug itu, lalu menambalnya sendiri.
Latihan: ubah kontrak Sertifikat dari dua materi sebelumnya supaya mewarisi
AccessControl dengan dua role: PENERBIT_ROLE (boleh terbitkan())
dan DEFAULT_ADMIN_ROLE (boleh grantRole/revokeRole). Deploy di
Remix, beri satu address lain PENERBIT_ROLE, lalu buktikan address itu bisa
terbitkan() tanpa pernah menjadi "owner" tunggal.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.