ERC-20 — token fungible
ERC-20 bukan pustaka, bukan framework — ia sekadar interface: sembilan fungsi dan dua event yang disepakati bersama. Kesepakatan sesederhana itu yang membuat MetaMask bisa menampilkan token apa pun tanpa integrasi khusus per token.
Intisari
- ERC-20 adalah token fungible — setiap unit identik dan bisa saling dipertukarkan, seperti saldo rupiah di rekening bank, bukan seperti sertifikat tanah yang unik.
- Interfacenya cuma 6 fungsi wajib + 2 event:
totalSupply, balanceOf, transfer, approve, transferFrom, allowance, dan eventTransfer,Approval. approve+transferFromadalah pola "izinkan pihak lain membelanjakan atas namamu" — dasar dari hampir semua DEX dan integrasi DeFi.decimals()standar 18 bukan bagian data on-chain yang "benar" — ia cuma metadata untuk tampilan; angka yang benar-benar disimpan selalu integer utuh.- Jangan tulis implementasi dari nol — warisi
ERC20dari OpenZeppelin dan override seperlunya, persis polaOwnabledi Fase 1.
Interface minimal yang disepakati semua orang
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address akun) external view returns (uint256);
function transfer(address ke, uint256 jumlah) external returns (bool);
function allowance(address pemilik, address pembelanja) external view returns (uint256);
function approve(address pembelanja, uint256 jumlah) external returns (bool);
function transferFrom(address dari, address ke, uint256 jumlah) external returns (bool);
event Transfer(address indexed dari, address indexed ke, uint256 jumlah);
event Approval(address indexed pemilik, address indexed pembelanja, uint256 jumlah);
}
Karena setiap token ERC-20 mengimplementasikan interface yang sama persis, wallet dan exchange tidak
perlu tahu apa pun soal kontrakmu secara spesifik — mereka cukup memanggil balanceOf(address)
dan mendapat jawaban yang selalu bisa ditafsirkan sama.
Kenapa ada approve dan transfer
Ini bagian yang paling sering membingungkan pendatang: kenapa tidak cukup satu fungsi transfer saja?
Jawabannya: transfer hanya bisa dipanggil oleh pemilik saldo itu sendiri. Tapi banyak
kasus butuh kontrak lain (DEX, marketplace) memindahkan token atas nama pengguna — dan
pengguna tidak mungkin memberikan private key-nya ke kontrak lain.
1. Pengguna: approve(alamatDEX, 100)
→ "DEX boleh membelanjakan sampai 100 token milikku"
2. DEX: transferFrom(alamatPengguna, alamatPenerima, 100)
→ DEX memindahkan token TANPA pernah memegang private key pengguna,
hanya karena allowance-nya cukup
Jebakan approve klasik: race condition perubahan allowance. Mengubah allowance dari
100 ke 50 lewat dua transaksi terpisah (approve(x, 0) lalu approve(x, 50)) bisa
dieksploitasi kalau pembelanja lama sempat menyisipkan transferFrom di antara keduanya.
OpenZeppelin menyediakan increaseAllowance/decreaseAllowance untuk mengubahnya
secara atomik — pakai itu, bukan dua approve terpisah.
Implementasi: warisi, jangan tulis dari nol
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract PoinLoyalitas is ERC20 {
constructor() ERC20("Poin Loyalitas", "POIN") {
_mint(msg.sender, 1_000_000 * 10 ** decimals());
}
}
| Fungsi internal OZ | Dipakai untuk |
|---|---|
_mint(ke, jumlah) | Menambah supply — dipanggil dari fungsi kustom yang kamu batasi aksesnya sendiri |
_burn(dari, jumlah) | Mengurangi supply |
_update(dari, ke, jumlah) | Hook internal semua perpindahan saldo — titik override untuk menambah aturan sendiri (mis. jeda transfer) |
decimals(): metadata tampilan, bukan data sungguhan
Nilai 1.5 token tidak pernah benar-benar tersimpan sebagai 1.5 — yang tersimpan
adalah integer 1_500_000_000_000_000_000 (18 nol), dan decimals() == 18 cuma
memberi tahu wallet "geser titik desimal 18 digit ke kiri saat menampilkan ke pengguna". Ini konsekuensi
langsung dari fakta bahwa EVM tidak punya tipe pecahan sama sekali (Fase 1).
Latihan: deploy PoinLoyalitas di Remix dengan dua akun. Dari akun pertama,
approve akun kedua untuk 100 token, lalu dari akun kedua panggil transferFrom
memindahkan 100 token ke akun ketiga. Perhatikan allowance akun pertama otomatis berkurang
jadi 0 setelahnya — tanpa akun pertama mengirim transaksi apa pun di langkah kedua.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.