Belajar Blockchain Developer - Solidity Dasar
Episode 4 of 28

Belajar Blockchain Developer - Solidity Dasar

Menguasai fondasi Solidity: tipe data, fungsi dan visibility, modifier, events, serta token standard ERC-20 — dengan praktik membangun kontrak token ERC-20 lengkap yang siap diuji

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

Pendahuluan

Setelah di episode 3 kita men-deploy kontrak pertama ke Sepolia, pada episode ini kita masuk ke jantung profesi kalian: Solidity — bahasa smart contract utama di EVM. Lebih dari sekadar sintaks, episode ini membangun pola pikir: bagaimana state disimpan, siapa yang boleh memanggil fungsi apa, dan bagaimana kontrak berkomunikasi dengan dunia luar.

Praktik kita di episode ini adalah kontrak ERC-20 — standard token yang melandasi hampir seluruh DeFi dan stablecoin. Menguasainya berarti menguasai 70% kontrak yang ada di ekosistem.

Tipe Data dan Variabel

Solidity punya tipe dasar dan tiga area penyimpanan (storage, memory, calldata) yang harus dipahami sejak awal:

contracts/DataTypes.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
contract DataTypes {
    uint256 public counter;          // integer tanpa tanda
    address public owner;            // alamat akun
    bool public isPaused;            // boolean
    string public name;              // string (dinamis)
 
    mapping(address => uint256) public balances; // key-value storage
    uint256[] public numbers;        // array dinamis
 
    // storage vs memory vs calldata
    function inspect(
        string memory _memoryData,
        string calldata _calldataData
    ) external view returns (uint256 length) {
        return bytes(_calldataData).length;
    }
}

Tiga area penyimpanan adalah konsep yang paling sering membingungkan pemula:

  • Storage: data permanen di chain, mahal — mapping, array state, variabel kontrak.
  • Memory: data sementara dalam eksekusi fungsi, murah — parameter string dan array.
  • Calldata: data input hanya-baca dari pemanggil, paling murah — pakai untuk argumen yang tidak dimodifikasi.

Fungsi dan Visibility

Solidity punya empat tingkat visibility yang menentukan siapa yang bisa memanggil fungsi:

VisibilityEksternalInternalCatatan
externalYaTidakHanya dari luar kontrak
publicYaYaGetter otomatis untuk state variable
internalTidakYaDipakai internal/inheritance
privateTidakHanya kontrak iniTerlihat tapi tidak bisa dipanggil

Dua modifier perilaku lain yang wajib dipahami:

  • view — membaca state tanpa mengubahnya, tidak bayar gas saat dipanggil via call.
  • pure — tidak membaca maupun mengubah state, murni komputasi.
contracts/Visibility.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
contract Visibility {
    uint256 public total;
 
    function add(uint256 _n) external {
        total += _n;
    }
 
    function getTotal() public view returns (uint256) {
        return total;
    }
 
    function multiply(uint256 a, uint256 b) public pure returns (uint256) {
        return a * b;
    }
}

Note

Ingat: visibility private tidak menyembunyikan data dari dunia luar — semua storage kontrak bisa dibaca siapa pun via explorer. private hanya membatasi siapa yang bisa memanggil fungsi dari dalam kode, bukan enkripsi.

Modifier dan Events

Modifier menyediakan reuse logika sebelum/eksekusi fungsi — pola paling umum untuk kontrol akses:

contracts/WithModifier.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
contract WithModifier {
    address public owner;
 
    constructor() {
        owner = msg.sender;
    }
 
    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }
 
    function updateOwner(address _newOwner) external onlyOwner {
        owner = _newOwner;
    }
}

Events adalah cara kontrak "berbicara" ke dunia luar. Saat di-emit, event tersimpan di log transaksi dan bisa di-index oleh frontend atau subgraph:

contracts/WithEvent.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
contract WithEvent {
    event Deposit(address indexed from, uint256 amount);
 
    function deposit() external payable {
        emit Deposit(msg.sender, msg.value);
    }
}

Indexed parameter memungkinkan filtering — frontend bisa query "semua Deposit dari alamat X" dengan cepat. Ini jadi bahan penting untuk indexing The Graph di episode 16.

Token Standard ERC-20

ERC-20 adalah standard antarmuka token fungible. Standar ini penting karena membuat token dari kontrak mana pun bisa dipakai oleh DEX, wallet, dan protokol lain secara plug-and-play. Inti antarmukanya:

contracts/MyToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
 
contract MyToken {
    string public name = "MyToken";
    string public symbol = "MTK";
    uint8 public decimals = 18;
    uint256 public totalSupply;
 
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
 
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
 
    constructor(uint256 _initialSupply) {
        totalSupply = _initialSupply * 10 ** decimals;
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);
    }
 
    function transfer(address _to, uint256 _amount) external returns (bool) {
        require(balanceOf[msg.sender] >= _amount, "insufficient balance");
        balanceOf[msg.sender] -= _amount;
        balanceOf[_to] += _amount;
        emit Transfer(msg.sender, _to, _amount);
        return true;
    }
 
    function approve(address _spender, uint256 _amount) external returns (bool) {
        allowance[msg.sender][_spender] = _amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }
 
    function transferFrom(address _from, address _to, uint256 _amount) external returns (bool) {
        require(balanceOf[_from] >= _amount, "insufficient balance");
        require(allowance[_from][msg.sender] >= _amount, "insufficient allowance");
        allowance[_from][msg.sender] -= _amount;
        balanceOf[_from] -= _amount;
        balanceOf[_to] += _amount;
        emit Transfer(_from, _to, _amount);
        return true;
    }
}

Perhatikan pola approve + transferFrom: pengguna memberi izin ke kontrak lain (misal DEX) untuk menarik token dalam batas tertentu. Ini adalah mekanisme inti seluruh ekosistem DeFi — kita pakai lagi di episode 9.

Warning

Di production, jangan pernah menulis ERC-20 dari nol seperti contoh di atas. Gunakan library teruji OpenZeppelin (@openzeppelin/contracts) — implementasi yang di-audit dan menghindari jebakan klasik seperti missing event, fee on transfer, dan integer overflow. Contoh ini murni untuk memahami cara kerjanya.

Penutup

Inti yang harus dibawa pulang:

  • Solidity punya storage, memory, dan calldata — paham perbedaannya = paham biaya gas.
  • Visibility external/public/internal/private menentukan siapa yang memanggil.
  • Modifier mengontrol akses; events menghubungkan kontrak dengan dunia luar.
  • ERC-20 = antarmuka standard balanceOf, allowance, transfer, transferFrom, approve.
  • Di production, pakai OpenZeppelin, bukan implementasi custom.

Di episode 5 selanjutnya kita membahas smart contract patterns yang membuat kontrak kalian production-ready: Ownable, proxy, pull-over-push, dan reentrancy guard — pola yang memisahkan kontrak amatir dari kontrak profesional. Mari lanjut!

Belajar Blockchain Developer - Solidity Dasar | Belajar Blockchain Developer