Menguasai tipe data Solidity: value types (bool, uint/int 8-256, address, bytes1-32, enum) dan reference types (string, bytes, array, struct, mapping), serta memahami data location storage, memory, dan calldata yang menentukan biaya gas dan perilaku variabel

Setelah di episode 3 kalian berhasil men-deploy Hello World — state variable, getter otomatis, dan transaksi pertama — pada episode ini kita membangun fondasi yang paling sering dipakai sehari-hari: tipe data dan variabel.
Mengapa episode ini penting? Karena hampir semua bug biaya dan bug logika di Solidity berakar dari kesalahpahaman tipe: memakai uint8 untuk nilai yang bisa lebih besar dari 255, memanipulasi string seperti array padahal tidak, atau tidak sadar bahwa mapping tidak bisa di-iterasi. Menguasai tipe data sejak awal akan menghemat waktu debugging yang panjang di episode-episode berikutnya.
Value types disalin berdasarkan nilai — saat di-assign, datanya disalin, bukan direferensikan. Ini yang paling sering dipakai:
| Tipe | Ukuran | Catatan |
|---|---|---|
bool | 1 bit logis | true / false |
uint / uint256 | 256-bit | Integer tak bertanda (default) |
int / int256 | 256-bit | Integer bertanda |
uint8 ... uint248 | 8-248-bit | Per-langkah 8 bit |
address | 160-bit | Alamat akun/kontrak |
bytes1 ... bytes32 | 1-32 byte | Array byte fixed-size |
enum | custom | Set nilai bernama |
uint256 public totalSupply;
uint8 public small = 255;
int256 public temperature = -10;uint8 hanya bisa menampung 0-255; menambahkan 1 lagi akan error (overflow dicek otomatis sejak 0.8.0). Karena EVM menangani word 256-bit paling efisien, uint256 adalah tipe yang paling murah untuk dipakai. Selalu mulai dari uint256 dan kecilkan hanya jika benar-benar yakin nilai dibatasi.
address mewakili akun atau kontrak. Ada dua varian:
address public owner;
address payable public treasury;address payable bisa menerima dan mengirim ETH (transfer/send), sedangkan address biasa hanya untuk membaca. Nilai msg.sender (pemanggil) dan address(this) (alamat kontrak sendiri) akan sangat sering dipakai.
bytes32 public merkleRoot;
enum Status { Pending, Approved, Rejected }
Status public status;bytes32 cocok untuk hash. enum membuat pilihan bernama yang mudah dibaca dan lebih hemat storage daripada uint.
Reference types menyimpan lokasi data, bukan nilainya. Data location-nya wajib ditentukan: storage, memory, atau calldata.
| Tipe | Deskripsi |
|---|---|
string | Teks dinamis (di atas bytes) |
bytes | Array byte dinamis |
array | Koleksi elemen bertipe sama |
struct | Kelompok field bernama |
mapping | Pasangan key/value (hash table) |
struct User {
address addr;
uint256 balance;
}
User[] public users;
mapping(address => uint256) public balances;struct mengelompokkan data, array menyimpan urutan, dan mapping mencari nilai berdasarkan key.
Seperti kita pelajari di episode 2, EVM punya tiga area data. Aturannya di level bahasa:
storage (tidak perlu ditulis).calldata hanya untuk parameter fungsi, read-only, dan paling murah.function getFirst(bytes calldata data) external pure returns (bytes1) {
return data[0];
}
function copyArr(uint256[] memory source) public pure returns (uint256[] memory) {
uint256[] memory result = source;
return result;
}Warning
Aturan lokasi ini adalah salah satu sumber error kompilasi paling umum: "Data location must be storage, memory or calldata". external function dengan parameter reference types sebaiknya memakai calldata — lebih murah karena tidak menyalin ke memory.
Beberapa kesalahan klasik yang akan kalian temui:
mapping tidak bisa di-iterasi — tidak ada cara langsung mengambil semua key. Jika butuh list, simpan juga array key secara terpisah.string bukan array char — tidak bisa str[0]; butuh konversi ke bytes untuk akses per-byte.uint8 yang di-increment melebihi 255 akan revert di 0.8.x.memory dari struct yang sama akan terlihat di kedua variabel karena keduanya menunjuk data yang sama.Inti yang harus dibawa pulang:
bool, uint/int, address, bytes1-32, enum) disalin per nilai; mulai dari uint256.string, bytes, array, struct, mapping) butuh data location.calldata untuk parameter external read-only; memory untuk kerja sementara; storage untuk state.mapping itu efisien tapi tidak iterable; kombinasikan dengan array jika butuh daftar.Di episode 5 selanjutnya kita akan membahas fungsi, modifier, dan visibility — public/external/internal/private, view/pure/payable, return multiple values, pola onlyOwner, serta require/assert/revert dan custom error yang hemat gas. Pastikan pemahaman tipe data kalian solid, karena episode 5 membangun logika kontrak di atasnya!