Sesi 1: Fondasi Web3 & Pengaturan Infrastruktur
๐ Informasi Sesiโ
Tanggal: Sabtu, 25 Oktober 2025 Waktu: 09:00 - 17:00 WIB (8 jam) Lokasi: BINUS University Kemanggisan Format: Workshop tatap muka (offline) Peserta: 40-80 pengembang terpilih
๐ฏ Tujuan Pembelajaranโ
Setelah menyelesaikan sesi ini, Anda akan mampu:
- Memahami Evolusi Web - Menjelaskan perbedaan mendasar antara Web1, Web2, dan Web3
- Arsitektur Blockchain - Memahami cara kerja blockchain, mekanisme konsensus, dan blockchain trilemma
- Layer 2 & Lisk - Mengerti solusi skalabilitas dan keunggulan Lisk sebagai Layer 2
- Wallet & Kriptografi - Menguasai konsep private key, public key, address, dan keamanan
- Sistem Gas - Memahami mekanisme gas dan siklus hidup transaksi
- Dasar Solidity - Menulis smart contract sederhana dengan tipe data, fungsi, dan modifier
- Deployment Pertama - Melakukan deployment dan verifikasi smart contract pertama ke Lisk Sepolia testnet
๐ Jadwal Lengkapโ
| Waktu | Durasi | Aktivitas | Format |
|---|---|---|---|
| 08:30 - 09:00 | 30m | Registrasi & Persiapan | Persiapan |
| 09:00 - 09:30 | 30m | Pembukaan & Ice Breaking | Interaktif |
| 09:30 - 10:45 | 75m | Modul 1: Evolusi Web & Fondasi Blockchain | Learning |
| 10:45 - 11:00 | 15m | Istirahat Kopi | Istirahat |
| 11:00 - 12:15 | 75m | Modul 2: Layer 2, Lisk & Wallet | Learning |
| 12:15 - 13:15 | 60m | Istirahat Makan Siang & Networking | Istirahat |
| 13:15 - 14:30 | 75m | Modul 3: Sistem Gas & Transaksi | Learning |
| 14:30 - 14:45 | 15m | Istirahat Kopi | Istirahat |
| 14:45 - 16:00 | 75m | Modul 4: Praktik Solidity | Workshop |
| 16:00 - 16:45 | 45m | Tantangan: Deploy Game LiskGarden | Praktik |
| 16:45 - 17:00 | 15m | Penutupan & Preview Sesi 2 | Penutup |
๐ Modul 1: Evolusi Web & Fondasi Blockchain (09:30 - 10:45)โ
1.1 Evolusi Web: Dari Web1 Hingga Web3โ
Web1 (1990-2005): Era Baca Sajaโ
Karakteristik:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WEB 1.0: Informasi Statis โ
โ ---------------------------------------- โ
โ โข Halaman HTML statis โ
โ โข Komunikasi satu arah โ
โ โข Didominasi pembuat konten โ
โ โข Tanpa interaksi pengguna โ
โ โ
โ Contoh: GeoCities, Altavista, Yahoo โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Ciri Khas:
- ๐ Baca saja: Pengguna hanya bisa membaca konten
- ๐ข Tersentralisasi: Server tunggal mengelola semua data
- ๐ Statis: Konten jarang berubah
- ๐ฐ Model Bisnis: Iklan banner, direktori listing
Web2 (2004-Sekarang): Era Interaktifโ
Karakteristik:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WEB 2.0: Platform Interaktif โ
โ ---------------------------------------- โ
โ โข Konten buatan pengguna โ
โ โข Platform media sosial โ
โ โข Komputasi awan โ
โ โข Pengalaman mobile-first โ
โ โ
โ Contoh: Facebook, YouTube, Twitter โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Ciri Khas:
- โ๏ธ Baca-Tulis: Pengguna dapat membuat dan membagikan konten
- ๐ฆ Dikontrol Platform: Data dikontrol oleh perusahaan besar
- ๐ Pemanenan Data: Data pengguna dijadikan produk yang dijual
- ๐ธ Model Bisnis: Periklanan, monetisasi data
Masalah Nyata Web2:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐จ SISI GELAP WEB2 โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ ๐ฐ Biaya platform: Pemotongan 30% dari creator โ
โ ๐ Kebocoran data: Miliaran data pengguna bocor โ
โ ๐ Deplatforming: Akun bisa diblokir tanpa sebabโ
โ ๐ญ Privasi: Pelacakan tanpa persetujuan โ
โ ๐ Sensor: Platform mengontrol kebebasan bicara โ
โ โ
โ Kasus Nyata: โ
โ โข Facebook-Cambridge Analytica (87 juta user) โ
โ โข Demonetisasi sewenang-wenang YouTube โ
โ โข Pemblokiran akun Twitter โ
โ โข Skandal pengumpulan data TikTok โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Web3 (2008-Sekarang): Era Kepemilikanโ
Karakteristik:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WEB 3.0: Kepemilikan Terdesentralisasi โ
โ ---------------------------------------- โ
โ โข Data dimiliki pengguna โ
โ โข Infrastruktur terdesentralisasi โ
โ โข Cryptocurrency & token โ
โ โข Smart contract โ
โ โข Inovasi tanpa izin โ
โ โ
โ Contoh: Uniswap, Aave, OpenSea, ENS โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Pergeseran Paradigma:
Platform Web2 โ Protokol Web3
"Anda adalah produk" โ "Anda memiliki nilai"
Berbasis izin โ Tanpa izin
Risiko platform โ Kepastian protokol
Perbandingan:
| Aspek | Web2 | Web3 |
|---|---|---|
| Kepemilikan Data | Milik platform | Milik pengguna |
| Identitas | Dikontrol platform | Berdaulat sendiri |
| Monetisasi | Periklanan | Kepemilikan langsung |
| Tata Kelola | Korporat | Komunitas |
| Sensor | Mungkin terjadi | Tahan sensor |
| Inovasi | Perlu izin | Tanpa izin |
1.2 Teknologi Blockchain Mendalamโ
Apa itu Blockchain?โ
Definisi: Buku besar terdistribusi - daftar catatan yang disimpan dalam "blok" data yang dirantai bersama.
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
โ Blok 1 โโโโโถโ Blok 2 โโโโโถโ Blok 3 โ
โ โ โ โ โ โ
โ Prev: 0x00 โ โ Prev: 0xA1 โ โ Prev: 0xB2 โ
โ Hash: 0xA1 โ โ Hash: 0xB2 โ โ Hash: 0xC3 โ
โ Data: [Txs] โ โ Data: [Txs] โ โ Data: [Txs] โ
โ Nonce: 4521 โ โ Nonce: 7832 โ โ Nonce: 1293 โ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
Sifat Intiโ
1. Transparan
- Setiap node memiliki salinan blockchain
- Semua transaksi terlihat oleh peserta
- Siapa pun dapat memverifikasi riwayat
- Blockchain publik sepenuhnya dapat diaudit
2. Aman
- Menggunakan kriptografi dan tanda tangan digital
- Pasangan kunci publik/privat membuktikan identitas
- Tanda tangan digital memaksakan akses baca/tulis
- Enkripsi melindungi data sensitif
3. Tidak Dapat Diubah
- Mekanisme konsensus membuat sulit mengubah catatan
- Data yang sudah dicatat sangat sulit diubah
- Memerlukan kontrol mayoritas jaringan
- Data historis bersifat permanen
Fungsi Hash Kriptografiโ
Contoh SHA-256:
Input: "Hello World"
Output: a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
Input: "Hello world" (huruf w kecil)
Output: 64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c
Properti:
- โ Deterministik: Input sama โ output sama
- โ Komputasi Cepat: Cepat untuk dihitung
- โ Resistensi Pre-image: Tidak bisa dibalik
- โ Efek Longsoran: Perubahan kecil โ perbedaan besar
- โ Tahan Tabrakan: Hampir mustahil menemukan duplikat
Merkle Tree: Struktur Data Blockchainโ
Apa itu Merkle Tree?
Merkle Tree (juga disebut Hash Tree) adalah struktur data yang digunakan blockchain untuk memverifikasi data dengan efisien.
Visualisasi Merkle Tree:
Root Hash
(Hash ABCD)
/ \
/ \
Hash AB Hash CD
/ \ / \
/ \ / \
Hash A Hash B Hash C Hash D
| | | |
Data A Data B Data C Data D
(Tx 1) (Tx 2) (Tx 3) (Tx 4)
Cara Kerja Merkle Tree:
-
Level Paling Bawah: Setiap transaksi di-hash
- Data A โ Hash A (0x1a2b...)
- Data B โ Hash B (0x3c4d...)
- Data C โ Hash C (0x5e6f...)
- Data D โ Hash D (0x7g8h...)
-
Level Tengah: Hash digabungkan berpasangan
- Hash A + Hash B โ Hash AB
- Hash C + Hash D โ Hash CD
-
Root Hash: Hash terakhir yang merepresentasikan semua data
- Hash AB + Hash CD โ Root Hash
Mengapa Penting?
1. Verifikasi Efisien
Tanpa Merkle Tree:
- Untuk verifikasi 1 transaksi dari 1000 transaksi
- Harus download semua 1000 transaksi โ
- Butuh banyak bandwidth dan waktu
Dengan Merkle Tree:
- Hanya perlu download ~10 hash (logโ 1000) โ
- Sangat cepat dan hemat bandwidth
2. Integritas Data
Jika satu transaksi berubah:
Data A โ Data A' (diubah)
โ
Hash A โ Hash A' (berubah)
โ
Hash AB โ Hash AB' (berubah)
โ
Root Hash โ Root Hash' (berubah)
Semua node langsung tahu ada perubahan! ๐จ
Contoh Praktis:
Misalkan Anda ingin membuktikan Transaksi C ada dalam blok:
Yang dibutuhkan:
1. Hash C (transaksi yang ingin dibuktikan)
2. Hash D (pasangan Hash C)
3. Hash AB (untuk menghitung Root)
Verifikasi:
Hash C + Hash D = Hash CD โ
Hash CD + Hash AB = Root Hash โ
Terbukti! Transaksi C valid di blok ini.
Keuntungan Merkle Tree:
โ Efisiensi Penyimpanan
- Tidak perlu simpan semua transaksi untuk verifikasi
- Hanya perlu beberapa hash sebagai "proof"
โ Verifikasi Cepat
- Kompleksitas O(log n) bukan O(n)
- 1000 transaksi hanya perlu 10 hash untuk verifikasi
โ Light Client
- Wallet mobile bisa verifikasi transaksi
- Tanpa download seluruh blockchain
โ Integritas Terjamin
- Satu bit berubah โ Root Hash berubah
- Tidak mungkin manipulasi data tanpa ketahuan
Penggunaan di Ethereum:
- State Tree: Menyimpan semua account state
- Transaction Tree: Menyimpan semua transaksi dalam blok
- Receipt Tree: Menyimpan semua receipt transaksi
Analogi Sederhana:
Bayangkan Merkle Tree seperti daftar isi buku:
- Buku memiliki 1000 halaman (transaksi)
- Daftar isi hanya 5 halaman (hash tree)
- Anda bisa cepat verifikasi apakah halaman 537 ada di buku
- Tanpa harus membaca semua 1000 halaman
1.3 Perjalanan Ethereumโ
Peluncuran (2015)โ
Misi Ethereum: Internet terbuka di mana pengguna mengontrol data mereka, aplikasi berjalan tanpa penjaga gerbang, dan nilai mengalir bebas.
Pencapaian Pentingโ
1. DAI: Stablecoin Perintis (Desember 2015)
- Stablecoin terdesentralisasi pertama
- Mempertahankan patokan dolar melalui jaminan kripto
- Tata kelola DAO
- Tanpa single point of failure
2. CryptoKitties & Era NFT (November 2017)
- Game NFT besar pertama
- Menunjukkan blockchain di luar keuangan
- Membuktikan kolektibilitas dan budaya online
- Membuka kemungkinan kreatif
3. Musim Panas DeFi (Juni 2020)
- Pertumbuhan eksplosif DeFi
- Peminjaman, perdagangan, generasi hasil
- Infrastruktur keuangan terbuka dan komposabel
- Miliaran nilai on-chain
- Platform: Uniswap, Aave, Compound
4. Pembaruan The Merge (15 September 2022)
- Transisi dari Proof of Work ke Proof of Stake
- Memangkas konsumsi energi hingga 99,95%
- Memperkuat keamanan jaringan
- Menetapkan dasar untuk peningkatan skalabilitas masa depan
1.4 Mekanisme Konsensusโ
Proof of Work (PoW)โ
Proses Mining:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PROSES MINING โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ 1. Kumpulkan transaksi dari mempool โ
โ 2. Buat blok dengan data transaksi โ
โ 3. Temukan nonce di mana: โ
โ Hash(blok) < Target Difficulty โ
โ 4. Siarkan blok valid ke jaringan โ
โ 5. Jaringan verifikasi & tambahkan โ
โ 6. Miner terima hadiah blok โ
โ โ
โ Bitcoin: 10 menit/blok, 6.25 BTC hadiah โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Karakteristik:
- โก Intensif Energi: Memerlukan daya komputasi tinggi
- ๐ Aman: Serangan 51% sangat mahal
- ๐ข Lebih Lambat: Throughput transaksi lebih rendah
- ๐ฏ Terbukti: Bitcoin berjalan 15+ tahun tanpa downtime
Proof of Stake (PoS)โ
Proses Staking:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ PROSES STAKING โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ 1. Kunci cryptocurrency sebagai stake โ
โ 2. Terpilih sebagai validator โ
โ (probabilitas โ jumlah stake) โ
โ 3. Usulkan & validasi blok โ
โ 4. Dapatkan hadiah staking โ
โ 5. Di-slash jika bertindak jahat โ
โ โ
โ Ethereum: Minimum 32 ETH stake โ
โ Hadiah staking ~4% APR โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Karakteristik:
- ๐ฑ Hemat Energi: 99,95% lebih sedikit energi
- โก Lebih Cepat: Throughput lebih tinggi
- ๐ฐ Persyaratan Modal: Perlu stake signifikan
- ๐ Keamanan Ekonomi: Penyerang kehilangan stake mereka
1.5 Blockchain Trilemmaโ
Keamanan
(Kesulitan serangan tinggi)
/\
/ \
/ \
/ \
Desentralisasi ---- Skalabilitas
(Persyaratan node (Performa tinggi
operator rendah) yaitu TPS)
Tantangan: Hanya bisa mengoptimalkan 2 dari 3
- Keamanan Tinggi + Desentralisasi Tinggi = Skalabilitas Rendah (Bitcoin, Ethereum L1)
- Keamanan Tinggi + Skalabilitas Tinggi = Desentralisasi Rendah (Beberapa rantai DPoS)
- Desentralisasi Tinggi + Skalabilitas Tinggi = Keamanan Rendah (Beberapa mekanisme baru)
Perbandingan:
โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ Chain โ Desentralisasiโ Keamanan โ Skalabilitasโ
โโโโโโโโโโโโผโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโโโโโโโโค
โ Bitcoin โ โญโญโญโญโญ โ โญโญโญโญโญ โ โญโโโโ โ
โ Ethereum โ โญโญโญโญโ โ โญโญโญโญโญ โ โญโญโโโ โ
โ BSC โ โญโญโโโ โ โญโญโญโโ โ โญโญโญโญโญ โ
โ Solana โ โญโญโโโ โ โญโญโญโโ โ โญโญโญโญโญ โ
โโโโโโโโโโโโดโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโโ
๐ Modul 2: Layer 2, Lisk & Wallet (11:00 - 12:15)โ
2.1 Apa itu Layer 2?โ
Definisi: Jaringan yang dibangun di atas Ethereum (Layer 1) untuk menyelesaikan masalah skalabilitas.
Cara Kerja Layer 2:
- Memproses transaksi off-chain (di luar blockchain utama Ethereum)
- Menyelesaikan/menambatkan transaksi pada Layer 1 untuk keamanan
- Membuat transaksi lebih cepat dan murah
- Mewarisi jaminan keamanan Ethereum
Optimistic Rollup:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Optimistic Rollup (L2) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Node Eksekusi โ โ
โ โ Eksekusi cepat off-chain โ โ
โ โ โ โ
โ โ Node Rollup โ โ
โ โ Batch & kirim ke L1 โ โ
โ โ โ โ
โ โ Skema Pembuktian โ โ
โ โ Fraud proof โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ Kirim Batch ke Layer 1 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
Turunkan Data Blok Layer 2
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Ethereum (L1) โ
โ Keamanan & Penyelesaian โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Manfaat Utama:
- Skalabilitas: Ribuan TPS vs ~15 TPS di L1
- Biaya Lebih Rendah: Biaya hanya sebagian kecil dari L1
- Keamanan Ethereum: Diamankan oleh Ethereum
- Kompatibilitas EVM: Tool, kode, dan wallet yang sama
2.2 Memperkenalkan Liskโ
Apa itu Lisk?
Lisk adalah jaringan Layer 2 (L2) yang sangat efisien, sangat cepat, dan mudah diskalakan, dibangun di atas Optimism (OP) dan diamankan oleh Ethereum.
Dibangun di Superchain:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Ekosistem OP Superchain โ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ โ Optimism โ โ Base โ โ Lisk โโ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โ โ Mode โ โ Zora โ โ dll โโ
โ โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Keamanan Bersama
โ Standar Bersama
โ Interoperabilitas
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Ethereum (L1) โ
โ Keamanan & Penyelesaian โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Karakteristik Utama:
-
Performa Sangat Cepat
- Konfirmasi transaksi sub-detik
- Throughput tinggi untuk aplikasi yang menuntut
- Dioptimalkan untuk kasus penggunaan dunia nyata
-
Sangat Efisien
- Biaya gas berkurang drastis dibanding Ethereum L1
- Pemrosesan batch yang efisien
- Pemanfaatan sumber daya optimal
-
Mudah Diskalakan
- Menangani volume transaksi tinggi
- Dirancang untuk berkembang dengan aplikasi Anda
- Tanpa mengorbankan desentralisasi
-
Kompatibel dengan EVM
- Gunakan tool yang sama (Hardhat, Foundry, Remix)
- Deploy smart contract Solidity tanpa perubahan
- Migrasi mulus dari Ethereum
-
Keamanan Ethereum
- Transaksi diselesaikan di Ethereum
- Mewarisi model keamanan kuat Ethereum
- Tidak perlu mempercayai set validator terpisah
Informasi Jaringan:
Lisk Sepolia Testnet (untuk pengembangan):
- Nama Jaringan: Lisk Sepolia
- RPC URL:
https://rpc.sepolia-api.lisk.com - Chain ID:
4202 - Simbol Mata Uang:
ETH - Block Explorer:
https://sepolia-blockscout.lisk.com
Lisk Mainnet (untuk produksi):
- Nama Jaringan: Lisk
- RPC URL:
https://rpc.api.lisk.com - Chain ID:
1135 - Simbol Mata Uang:
ETH - Block Explorer:
https://blockscout.lisk.com
2.3 Memahami Walletโ
Apa itu Wallet?โ
Definisi: Alat yang menyimpan kunci, mengelola akun, menandatangani transaksi, dan berinteraksi dengan blockchain.
Penting: Kripto Anda TIDAK "berada di" wallet - kripto ada di blockchain. Wallet hanya membuktikan Anda memilikinya!
Analogi Dunia Nyata: Sistem Kotak Posโ
๐ Rumah Anda = Blockchain
๐ฌ Kotak Pos = Akun/Address Anda (0x123...)
๐ Kunci Kotak Pos = Private Key Anda
๐ฎ Nomor Kotak Pos = Public Address Anda
- Kotak pos (address) terlihat oleh semua orang
- Kunci kotak pos (private key) rahasia, hanya Anda yang bisa membuka
- Siapa pun bisa melihat nomor kotak pos untuk mengirim surat
- Tapi hanya Anda dengan kunci yang bisa membuka dan mengambil isinya
2.4 Private Key, Public Key, dan Addressโ
Proses Pembuatan Kunci:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Langkah 1: Buat Private Key (Angka Acak) โ
โ โ
โ Private Key (Rahasia, angka 256-bit): โ
โ 0xf8f8a2f43c8376ccb0871305060d7b27b0554d2cc72... โ
โ โ
โ โ ๏ธ JANGAN PERNAH BAGIKAN - Seperti password! โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Matematika Kriptografi (ECDSA)
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Langkah 2: Turunkan Public Key โ
โ โ
โ Public Key (Boleh dibagikan): โ
โ 0x04a598a8030da6d86c6bc7f2f5144544beb2dd0d4e... โ
โ โ
โ โ
Boleh dibagikan secara publik โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Hashing (Keccak-256)
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Langkah 3: Buat Address โ
โ โ
โ Address (Identitas publik Anda): โ
โ 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb4 โ
โ โ
โ โ
Ini yang Anda bagikan untuk terima dana โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Fungsi Satu Arah:
Private Key --[ECDSA]--> Public Key --[Keccak-256]--> Address
โ
Maju mudah dan cepat
โ Mundur secara komputasi mustahil
Seed Phrase: Cadangan Masterโ
Apa itu: 12 atau 24 kata acak
Contoh: witch collapse practice feed shame open despair creek road again ice least
Cara kerjanya:
Seed Phrase (12-24 kata)
โ
โโ> Akun 1: 0x742d35Cc...
โโ> Akun 2: 0x8f3b2e1d...
โโ> Akun 3: 0xa2c4f7b9...
โโ> ... (jutaan kemungkinan lainnya)
Aturan Keamanan:
- โ JANGAN PERNAH bagikan
- โ JANGAN PERNAH simpan secara digital
- โ Tulis di kertas
- โ Simpan di tempat aman
- โ Pertimbangkan cadangan metal
2.5 Jenis-jenis Walletโ
Hot Wallet (Perangkat Lunak) ๐ฅโ
Ekstensi Browser:
- Contoh: MetaMask, Rabby
- Kelebihan: Nyaman, mudah berinteraksi dengan dApp
- Kekurangan: Rentan jika komputer terkompromi
Wallet Mobile:
- Contoh: Trust Wallet, Argent
- Kelebihan: Portabel, autentikasi biometrik
- Kekurangan: Risiko kehilangan ponsel
Cold Wallet (Hardware) โ๏ธโ
Hardware Wallet:
- Contoh: Ledger, Trezor
- Kelebihan: Kunci tidak pernah menyentuh internet, konfirmasi fisik
- Kekurangan: Berbayar, kurang praktis
Perbandingan:
| Jenis Wallet | Keamanan | Kemudahan | Terbaik Untuk |
|---|---|---|---|
| Hardware | โญโญโญโญโญ | โญโญ | Jumlah besar |
| Mobile | โญโญโญ | โญโญโญโญ | Penggunaan harian |
| Browser | โญโญโญ | โญโญโญโญโญ | Interaksi dApp |
Custodial vs Non-Custodialโ
Non-Custodial (Self-Custody):
- Anda mengontrol private key
- Kepemilikan sejati
- Tidak ada yang bisa membekukan akun
- Anda bertanggung jawab atas keamanan
Custodial (Pihak Ketiga):
- Perusahaan mengontrol kunci
- Mudah digunakan
- Pemulihan password tersedia
- Dapat dibekukan/dibatasi
Prinsip: "Not your keys, not your crypto"
2.6 Jenis Akun di Ethereumโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AKUN ETHEREUM โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ โ Externally Owned โ โ Contract โโ
โ โ Account (EOA) โ โ Account โโ
โ โ โ โ โโ
โ โ Dikontrol oleh โ โ Dikontrol oleh โโ
โ โ Private Key โ โ Kode Smart โโ
โ โ โ โ Contract โโ
โ โโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
EOA (Externally Owned Account):
- Dikontrol oleh private key
- Dapat memulai transaksi
- Akun MetaMask Anda
- Tanpa kode
Contract Account:
- Dikontrol oleh kode
- Tidak dapat memulai transaksi
- Memiliki kode yang dapat dieksekusi
- Memiliki penyimpanan persisten
- Contoh: Uniswap, token USDC
Perbedaan Utama:
| Fitur | EOA | Contract Account |
|---|---|---|
| Dikontrol Oleh | Private Key | Kode Smart Contract |
| Dapat Memulai Transaksi | โ Ya | โ Tidak |
| Memiliki Kode | โ Tidak | โ Ya |
| Biaya Pembuatan | Gratis | Memerlukan gas |
| Contoh | Wallet MetaMask | Uniswap, USDC |
๐ Modul 3: Sistem Gas & Transaksi (13:15 - 14:30)โ
3.1 Apa itu Gas?โ
Definisi: Unit yang mengukur pekerjaan komputasi yang diperlukan untuk menjalankan operasi di Ethereum.
Analogi Restoranโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ฝ๏ธ ANALOGI RESTORAN โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Item Menu = Operasi โ
โ (Salad Sederhana) (Transaksi sederhana) โ
โ โ
โ Harga per Item = Gas Price (Gwei) โ
โ (Rp150.000/item) (50 Gwei per gas) โ
โ โ
โ Jumlah Item = Gas Limit โ
โ (Pesan 3 item) (Perlu 21.000 gas) โ
โ โ
โ Total Tagihan = Transaction Fee โ
โ (Rp450.000) (21.000 ร 50 Gwei) โ
โ โ
โ Tip = Priority Fee โ
โ (Layanan cepat) (Konfirmasi lebih cepat)โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Komponen Gasโ
1. Gas Limit (Berapa banyak pekerjaan yang diperlukan):
Operasi Biaya Gas
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Kirim ETH (transfer sederhana) 21.000
Transfer token ERC-20 ~65.000
Swap token Uniswap ~150.000
Deploy contract sederhana ~200.000+
Mint NFT ~80.000
2. Gas Price (Berapa yang Anda bayar per unit):
- Diukur dalam Gwei (gigawei)
- 1 Gwei = 0,000000001 ETH = 10^-9 ETH
- Bervariasi berdasarkan kemacetan jaringan
Gas Price Tipikal:
Status Jaringan Gas Price
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ข Tidak Sibuk 5-20 Gwei
๐ก Sedang 20-50 Gwei
๐ด Macet 50-100 Gwei
๐ฅ Sangat Sibuk 100+ Gwei
3. Transaction Fee (Total biaya):
Biaya Transaksi = Gas Terpakai ร Gas Price
Contoh:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Gas Terpakai: 21.000
Gas Price: 50 Gwei
Biaya = 21.000 ร 50 Gwei
= 1.050.000 Gwei
= 0,00105 ETH
Jika ETH = $2.000:
Biaya = $2,10
3.2 Unit Ethereum: Wei, Gwei, dan ETHโ
Mengapa Ada Unit Berbeda?โ
Seperti uang Rupiah memiliki sen (Rp0,01), Ethereum juga memiliki unit-unit kecil untuk transaksi presisi tinggi. Unit terkecil disebut Wei.
Daftar Lengkap Unit Ethereumโ
Dari Terkecil ke Terbesar:
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
โ Nama Unit โ Nilai Wei โ Nilai Ether โ Penggunaan โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโค
โ Wei โ 1 โ 10โปยนโธ ETH โ Unit terkecilโ
โ Kwei โ 1.000 โ 10โปยนโต ETH โ Jarang โ
โ Mwei โ 1.000.000 โ 10โปยนยฒ ETH โ Jarang โ
โ Gwei โ 1.000.000.000 โ 10โปโน ETH (0,000000001)โ Gas price โ
โ Szabo โ 10ยนยฒ โ 10โปโถ ETH (0,000001) โ Jarang โ
โ Finney โ 10ยนโต โ 10โปยณ ETH (0,001) โ Micro paymentโ
โ Ether (ETH) โ 10ยนโธ โ 1 ETH โ Standar โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโ
Unit yang Paling Sering Digunakanโ
1. Wei - Unit Terkecil
1 Wei = 0,000000000000000001 ETH
Penggunaan:
- Perhitungan internal smart contract
- Presisi matematis blockchain
- Hindari desimal floating point
Contoh:
1 ETH = 1.000.000.000.000.000.000 Wei
= 1 ร 10ยนโธ Wei
2. Gwei (Gigawei) - Gas Price
1 Gwei = 1.000.000.000 Wei
= 0,000000001 ETH
= 10โปโน ETH
Penggunaan:
- Harga gas (gas price)
- Biaya transaksi
- Mudah dibaca untuk manusia
Contoh:
Gas price 50 Gwei = 50.000.000.000 Wei
3. Ether (ETH) - Standar
1 ETH = 1.000.000.000.000.000.000 Wei
= 1.000.000.000 Gwei
= 10ยนโธ Wei
Penggunaan:
- Transfer antar user
- Harga token/NFT
- Saldo wallet
- Nilai pasar
3.3 Memahami Desimal dan Notasi Eksponenโ
Sistem Desimal di Blockchainโ
Blockchain tidak menggunakan desimal (floating point) karena tidak presisi. Sebagai gantinya, semua nilai disimpan sebagai integer dalam Wei.
Mengapa Tidak Pakai Desimal?
Masalah Floating Point:
0,1 + 0,2 = 0,30000000000000004 โ (di komputer)
Solusi Blockchain:
100000000000000000 + 200000000000000000 = 300000000000000000 โ
(0,1 ETH) + (0,2 ETH) = (0,3 ETH) dalam Wei
Notasi Eksponen 10โฟโ
Apa itu 10โฟ?
Notasi untuk bilangan yang sangat besar atau kecil:
10โฐ = 1
10ยน = 10
10ยฒ = 100
10ยณ = 1.000
10โถ = 1.000.000 (juta)
10โน = 1.000.000.000 (miliar)
10ยนยฒ = 1.000.000.000.000 (triliun)
10ยนโต = 1.000.000.000.000.000 (kuadriliun)
10ยนโธ = 1.000.000.000.000.000.000 (ETH dalam Wei!)
Dan negatif:
10โปยน = 0,1
10โปยฒ = 0,01
10โปยณ = 0,001
10โปโน = 0,000000001 (Gwei dalam ETH)
10โปยนโธ = 0,000000000000000001 (Wei dalam ETH)
Konversi Praktisโ
Konversi ETH โ Wei:
ETH ke Wei:
Kalikan dengan 10ยนโธ
Contoh:
1 ETH = 1 ร 10ยนโธ Wei = 1000000000000000000 Wei
0,5 ETH = 0,5 ร 10ยนโธ Wei = 500000000000000000 Wei
0,001 ETH = 0,001 ร 10ยนโธ Wei = 1000000000000000 Wei
Wei ke ETH:
Bagi dengan 10ยนโธ
Contoh:
1000000000000000000 Wei = 1000000000000000000 รท 10ยนโธ = 1 ETH
21000000000000 Wei = 21000000000000 รท 10ยนโธ = 0,000021 ETH
Konversi Gwei โ ETH:
Gwei ke ETH:
Bagi dengan 10โน (atau 1.000.000.000)
Contoh:
50 Gwei = 50 รท 10โน ETH = 0,00000005 ETH
ETH ke Gwei:
Kalikan dengan 10โน
Contoh:
0,00000005 ETH = 0,00000005 ร 10โน Gwei = 50 Gwei
Contoh Perhitungan Lengkapโ
Contoh 1: Hitung Biaya Transaksi dalam Wei
Data:
- Gas Terpakai: 21.000
- Gas Price: 50 Gwei
Langkah 1: Konversi Gwei ke Wei
50 Gwei = 50 ร 10โน Wei = 50.000.000.000 Wei
Langkah 2: Hitung Total
Biaya = 21.000 ร 50.000.000.000 Wei
= 1.050.000.000.000.000 Wei
Langkah 3: Konversi ke ETH
1.050.000.000.000.000 Wei รท 10ยนโธ = 0,00105 ETH
Jawaban: 0,00105 ETH
Contoh 2: Bayar 0,001 ETH, Berapa Wei?
0,001 ETH ร 10ยนโธ = 1.000.000.000.000.000 Wei
= 1 ร 10ยนโต Wei
= 1 Finney
Contoh 3: Contract Menerima 2.500.000.000.000.000 Wei
2.500.000.000.000.000 Wei รท 10ยนโธ = 0,0025 ETH
= 2,5 Finney
Tabel Konversi Cepatโ
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ
โ ETH โ Wei โ Gwei โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโค
โ 1 ETH โ 1.000.000.000.000.000.000 โ 1.000.000.000โ
โ 0,1 ETH โ 100.000.000.000.000.000 โ 100.000.000 โ
โ 0,01 ETH โ 10.000.000.000.000.000 โ 10.000.000 โ
โ 0,001 ETH โ 1.000.000.000.000.000 โ 1.000.000 โ
โ 0,0001 ETH โ 100.000.000.000.000 โ 100.000 โ
โ 0,00001 ETH โ 10.000.000.000.000 โ 10.000 โ
โ 0,000001 ETH โ 1.000.000.000.000 โ 1.000 โ
โ 0,0000001 ETHโ 100.000.000.000 โ 100 โ
โ 0,00000001 ETHโ 10.000.000.000 โ 10 โ
โ 0,000000001 ETHโ 1.000.000.000 โ 1 โ
โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโ
Praktik di Solidityโ
Solidity Memiliki Helper untuk Konversi:
// Dalam Solidity, Anda bisa tulis langsung:
uint256 price = 1 ether; // = 1000000000000000000 Wei
uint256 price = 1 gwei; // = 1000000000 Wei
uint256 price = 1 wei; // = 1 Wei
// Contoh penggunaan:
require(msg.value >= 0.001 ether, "Minimum 0.001 ETH");
// Ini otomatis dikonversi ke Wei: 1000000000000000
Tips Pentingโ
Untuk Developer:
โ
Selalu gunakan Wei dalam perhitungan smart contract
โ
Gunakan ether keyword di Solidity untuk readability
โ
Hindari floating point - gunakan integer Wei
โ
Validasi input untuk mencegah overflow/underflow
Untuk Pengguna:
โ Gas price selalu dalam Gwei (lebih mudah dibaca) โ Transfer biasanya dalam ETH โ Periksa kembali angka sebelum mengirim transaksi โ Gunakan calculator jika ragu: eth-converter.com
3.4 EIP-1559: Sistem Gas Modernโ
Sistem Lama (Sebelum EIP-1559):
Anda tentukan: Gas Price (satu nilai)
Sistem Baru (EIP-1559):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Base Fee (otomatis) โ โ Ditentukan protokol (dibakar ๐ฅ)
โ + โ
โ Priority Fee (tip Anda) โ โ Anda tentukan (untuk validator)
โ = โ
โ Max Fee Per Gas (maksimum Anda) โ โ Anda tentukan (perlindungan)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Contoh:
Base Fee: 30 Gwei (dibakar)
Priority Fee: 2 Gwei (untuk validator)
Max Fee: 100 Gwei (perlindungan Anda)
Biaya Aktual Per Gas: 30 + 2 = 32 Gwei โ
(Lebih rendah dari maksimum 100 Gwei)
Total Biaya: 21.000 ร 32 Gwei = 0,000672 ETH
3.3 Gas di Layer 2 (Lisk)โ
Mengapa L2 lebih murah:
Layer 1 (Ethereum Mainnet):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Kirim ETH: 21.000 gas ร 50 Gwei
Biaya: $2-10+ per transaksi ๐ธ
Layer 2 (Lisk):
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Kirim ETH: 21.000 gas ร 0,001 Gwei
Biaya: $0,001-0,01 per transaksi โจ
Mengapa berbeda?
- Kompetisi lebih sedikit: Lebih sedikit pengguna per L2
- Batching: Banyak transaksi L2 โ satu transaksi L1
- Eksekusi optimal: Efisiensi lebih baik
- Kompresi data: Data yang dikirim ke L1 lebih sedikit
Contoh Perbandingan:
Swap Uniswap di L1:
Gas: 180.000 ร 50 Gwei = $18 ๐ธ
Swap Uniswap di Lisk L2:
Gas: 180.000 ร 0,001 Gwei = $0,00036 โจ
L2 lebih murah ~50.000 kali!
3.4 Anatomi Transaksiโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ TRANSAKSI โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ From: 0x742d35Cc6634C0532925a3b844Bc... โ โ Pengirim
โ To: 0x3f5CE5FBFe3E9af3B33d4e456Cd3... โ โ Penerima
โ Value: 0.5 ETH โ โ Jumlah
โ Data: 0xa9059cbb000000000000000... โ โ Pemanggilan fungsi
โ Gas Limit: 21000 โ โ Maksimum gas
โ Max Fee: 50 Gwei โ โ Harga maksimum
โ Nonce: 42 โ โ Nomor transaksi
โ Signature: 0x8f3b2e1d4c5a6f7b8... โ โ Bukti
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
3.5 Siklus Hidup Transaksiโ
Langkah 1: Buat Transaksi
โ Pengguna: "Saya ingin mengirim 0,5 ETH"
โ Wallet mengisi detail
โ
Langkah 2: Tanda Tangani Transaksi
โ Wallet: "Silakan konfirmasi"
โ Pengguna klik "Konfirmasi"
โ Wallet tanda tangani dengan private key
โ
Langkah 3: Siarkan ke Jaringan
โ Wallet kirim ke node RPC
โ Node siarkan ke mempool
โ
Langkah 4: Menunggu di Mempool
โ Transaksi dalam status "pending"
โ Gas price lebih tinggi = prioritas lebih tinggi
โ
Langkah 5: Masuk ke Blok
โ Validator pilih transaksi
โ Eksekusi transaksi
โ Masukkan ke blok
โ
Langkah 6: Konfirmasi Blok
โ Blok ditambahkan ke blockchain
โ Transaksi memiliki "1 konfirmasi"
โ
Langkah 7: Terfinalisasi
โ Setelah konfirmasi cukup
โ Di Lisk L2: Biasanya 1-2 detik!
๐ป Modul 4: Praktik Solidity (14:45 - 16:00)โ
Persiapan: Remix IDE & MetaMaskโ
1. Buka Remix IDEโ
- Kunjungi https://remix.ethereum.org
- Klik "File Explorer"
- Siap!
2. Persiapan MetaMaskโ
-
Install MetaMask dari https://metamask.io
-
Buat wallet (simpan seed phrase dengan aman!)
-
Tambahkan Jaringan Lisk Sepolia:
- Nama Jaringan:
Lisk Sepolia - RPC URL:
https://rpc.sepolia-api.lisk.com - Chain ID:
4202 - Mata Uang:
ETH - Explorer:
https://sepolia-blockscout.lisk.com
- Nama Jaringan:
-
Dapatkan ETH testnet: https://sepolia-faucet.lisk.com
3. Hubungkan Remix ke MetaMaskโ
- Di Remix: "Deploy & Run Transactions"
- Pilih "Injected Provider - MetaMask"
- Klik "Connect"
- Selesai!
4.1 Solidity 101: Tipe Data Dasarโ
Kita akan belajar satu tipe data per waktu menggunakan contoh tanaman.
1. String (Teks)โ
Apa itu: Menyimpan teks seperti "Rose" atau "Hello World"
Buat file LearnString.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnString {
// Variabel string untuk menyimpan nama tanaman
string public plantName;
// Constructor mengatur nilai awal
constructor() {
plantName = "Rose";
}
// Fungsi untuk mengubah nama
function changeName(string memory _newName) public {
plantName = _newName;
}
}
Coba:
- Deploy โ Klik
plantNameโ Lihat "Rose" - Ketik "Tulip" โ Klik
changeName - Klik
plantNameโ Sekarang "Tulip"!
2. Number (uint256)โ
Apa itu: Menyimpan bilangan bulat dari 0 hingga sangat besar (2^256-1)
Buat LearnNumber.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnNumber {
// Angka untuk data tanaman
uint256 public plantId;
uint256 public waterLevel;
constructor() {
plantId = 1;
waterLevel = 100;
}
function changePlantId(uint256 _newId) public {
plantId = _newId;
}
function addWater() public {
waterLevel = waterLevel + 10;
// Bisa juga ditulis: waterLevel += 10;
}
}
Coba:
- Deploy โ Klik
waterLevelโ Lihat 100 - Klik
addWater3 kali - Klik
waterLevelโ Sekarang 130!
3. Boolean (Benar/Salah)โ
Apa itu: Hanya dua nilai - true atau false
Buat LearnBoolean.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnBoolean {
bool public isAlive;
bool public isBlooming;
constructor() {
isAlive = true;
isBlooming = false;
}
function changeStatus(bool _status) public {
isAlive = _status;
}
function bloom() public {
isBlooming = true;
}
}
4. Address (Alamat Wallet)โ
Apa itu: Menyimpan alamat wallet Ethereum (20 bytes, seperti 0x742d35Cc...)
Mengapa penting: Untuk identifikasi kepemilikan, pengirim transaksi, dan tujuan pembayaran
Buat LearnAddress.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnAddress {
address public owner;
address public gardener;
constructor() {
owner = msg.sender; // msg.sender = alamat wallet Anda
}
function setGardener(address _gardener) public {
gardener = _gardener;
}
}
Poin Penting:
address- menyimpan alamat wallet (0x742d35Cc...)msg.sender- alamat yang memanggil fungsi- Digunakan untuk kepemilikan, pembayaran, kontrol akses
Coba:
- Deploy โ Klik
ownerโ Lihat alamat wallet Anda! - Salin alamat lain โ Tempel di
setGardener - Klik
gardenerโ Lihat alamat tersebut
5. ๐ฏ TANTANGAN: Buat SimplePlant Sendiri!โ
Apa yang dipelajari: Menggabungkan semua tipe data dalam satu contract
Tujuan: Tulis contract SimplePlant.sol SENDIRI tanpa copy-paste!
๐ Spesifikasi Contract:
Buat contract yang menggabungkan semua tipe data yang sudah dipelajari:
State Variables yang dibutuhkan:
1. plantName (tipe: string, public) โ nama tanaman
2. waterLevel (tipe: uint256, public) โ level air
3. isAlive (tipe: bool, public) โ status hidup
4. owner (tipe: address, public) โ pemilik
5. plantedTime (tipe: uint256, public) โ waktu tanam
Constructor:
- Set plantName = "Rose"
- Set waterLevel = 100
- Set isAlive = true
- Set owner = alamat yang deploy (gunakan msg.sender)
- Set plantedTime = waktu sekarang (gunakan block.timestamp)
Fungsi yang dibutuhkan:
1. water()
- Tipe: public
- Aksi: Set waterLevel kembali ke 100
2. getAge()
- Tipe: public view
- Return: uint256
- Aksi: Hitung umur tanaman (waktu sekarang - waktu tanam)
๐จ Mulai Coding:
Buat file baru SimplePlant.sol di Remix dan mulai dari template ini:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract SimplePlant {
// TODO 1: Deklarasikan 5 state variables
// Hint: string public plantName;
// Hint: uint256 public ...
// ... tulis 4 lainnya!
// TODO 2: Buat constructor
constructor() {
// Set nilai awal untuk semua variables
// Hint: plantName = "Rose";
// Hint: owner = msg.sender;
}
// TODO 3: Buat fungsi water()
// Hint: function water() public { ... }
// TODO 4: Buat fungsi getAge()
// Hint: function getAge() public view returns (uint256) { ... }
// Hint: return block.timestamp - plantedTime;
}
โ Checklist Verifikasi:
Setelah selesai, cek apakah contract Anda memenuhi ini:
- Ada 5 state variables (string, uint256, bool, address, uint256)
- Semua variables adalah
public - Constructor mengatur semua nilai awal
- Fungsi
water()mengubah waterLevel ke 100 - Fungsi
getAge()adalahviewdan returnuint256 - Fungsi
getAge()menghitung selisih waktu - Contract dapat di-compile tanpa error
๐งช Test Contract Anda:
-
Deploy
- Klik "Deploy" di Remix
- Lihat contract muncul di "Deployed Contracts"
-
Test Variables
- Klik
plantNameโ Harus tampil "Rose" - Klik
waterLevelโ Harus tampil 100 - Klik
isAliveโ Harus tampil true - Klik
ownerโ Harus tampil alamat wallet Anda - Klik
plantedTimeโ Harus tampil angka (Unix timestamp)
- Klik
-
Test Fungsi water()
- Klik
waterโ Popup MetaMask muncul (karena mengubah state) - Confirm transaksi
- Klik
waterLevellagi โ Masih 100
- Klik
-
Test Fungsi getAge()
- Klik
getAgeโ Langsung tampil angka (GRATIS, no MetaMask popup!) - Tunggu 1 menit
- Klik
getAgelagi โ Angka bertambah ~60 detik!
- Klik
๐ Penjelasan Konsep:
Variabel Khusus Solidity:
msg.sender- alamat wallet yang memanggil fungsiblock.timestamp- waktu blok saat ini (Unix timestamp dalam detik)
Modifier Fungsi:
public- siapa saja dapat memanggil fungsiview- hanya membaca, tidak mengubah state โ GRATIS!returns (uint256)- fungsi mengembalikan angka
Cara Kerja:
- Constructor berjalan sekali saat deploy
- State variables tersimpan permanen di blockchain
- Fungsi
viewGRATIS dipanggil dari luar (no gas!) - Fungsi yang mengubah state butuh gas (popup MetaMask)
๐ก Tips Debugging:
Error Umum:
"ParserError: Expected ';' but got '}'"
โ Lupa titik koma di akhir statement
"TypeError: Member 'sender' not found"
โ Salah ketik: msg.sender (huruf kecil semua!)
"DeclarationError: Undeclared identifier"
โ Variabel belum dideklarasikan atau typo nama
"TypeError: Different number of arguments"
โ Cek parameter fungsi, apakah sudah sesuai?
Jika Stuck:
- Cek kembali 4 contract sebelumnya (String, Number, Boolean, Address)
- Lihat pattern yang sama
- Kombinasikan pattern tersebut
- Jangan menyerah! Ini proses belajar ๐ช
๐ Setelah Berhasil:
Selamat! Anda sudah menguasai:
- โ 4 tipe data dasar (string, uint256, bool, address)
- โ State variables
- โ Constructor
- โ Public functions
- โ View functions (read-only)
- โ Global variables (msg.sender, block.timestamp)
Selanjutnya: Pelajari Struct & Enum untuk data yang lebih kompleks!
4.2 Solidity 102: Struct & Enumโ
Enum (Angka Bernama)โ
Buat LearnEnum.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnEnum {
enum GrowthStage {
SEED, // 0
SPROUT, // 1
GROWING, // 2
BLOOMING // 3
}
GrowthStage public currentStage;
constructor() {
currentStage = GrowthStage.SEED;
}
function grow() public {
if (currentStage == GrowthStage.SEED) {
currentStage = GrowthStage.SPROUT;
}
else if (currentStage == GrowthStage.SPROUT) {
currentStage = GrowthStage.GROWING;
}
else if (currentStage == GrowthStage.GROWING) {
currentStage = GrowthStage.BLOOMING;
}
}
}
Struct (Kelompok Data)โ
Buat LearnStruct.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnStruct {
enum GrowthStage { SEED, SPROUT, GROWING, BLOOMING }
struct Plant {
uint256 id;
address owner;
GrowthStage stage;
uint8 waterLevel;
bool isAlive;
}
Plant public myPlant;
constructor() {
myPlant = Plant({
id: 1,
owner: msg.sender,
stage: GrowthStage.SEED,
waterLevel: 100,
isAlive: true
});
}
function water() public {
myPlant.waterLevel = 100;
}
function grow() public {
if (myPlant.stage == GrowthStage.SEED) {
myPlant.stage = GrowthStage.SPROUT;
}
}
}
Penjelasan:
struct Plant { ... }- membuat tipe kustom baru yang mengelompokkan data terkait- Seperti membuat template: setiap Plant memiliki id, owner, stage, waterLevel, isAlive
Plant public myPlant- membuat variabel bertipe PlantmyPlant = Plant({ ... })- mengisi struct dengan data (menggunakan nama)myPlant.waterLevel = 100- akses dan ubah field tertentumyPlant.stage- akses field tertentu untuk membacanya
Coba:
- Deploy
- Klik
myPlantโ Lihat semua data: id=1, alamat Anda, stage=0, water=100, alive=true - Klik
waterdangrowuntuk mengubah data - Klik
myPlantlagi untuk melihat perubahan!
4.3 Solidity 103: Mapping & Arrayโ
Pelajari cara mengelola banyak tanaman.
1. Mapping (Kamus)โ
Apa itu: Seperti kamus - memetakan kunci ke nilai (plantId โ owner, plantId โ water level)
Mengapa penting: Mengasosiasikan data dengan identifier unik. Pencarian cepat berdasarkan kunci
Buat LearnMapping.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnMapping {
// Mapping: plantId => waterLevel
mapping(uint256 => uint8) public plantWater;
// Mapping: plantId => owner
mapping(uint256 => address) public plantOwner;
function addPlant(uint256 _plantId) public {
plantWater[_plantId] = 100;
plantOwner[_plantId] = msg.sender;
}
function waterPlant(uint256 _plantId) public {
plantWater[_plantId] = 100;
}
}
Penjelasan:
mapping(uint256 => uint8)- seperti kamus, memetakan plantId (kunci) ke waterLevel (nilai)mapping(uint256 => address)- memetakan plantId ke alamat ownerplantWater[_plantId] = 100- mengatur level air untuk plant ID tertentuplantOwner[_plantId] = msg.sender- mengatur owner untuk plant ID tertentupublicpada mapping otomatis membuat fungsi getter
Coba:
- Deploy
- Ketik 1 di kotak
addPlantโ Klik - Ketik 2 di kotak
addPlantโ Klik - Ketik 1 di kotak
plantWaterโ Lihat 100 - Ketik 2 di kotak
plantWaterโ Lihat 100 - Sekarang Anda punya 2 tanaman!
2. Array (Daftar)โ
Apa itu: Daftar berurutan yang dapat bertambah ukurannya ([1, 2, 3, ...])
Mengapa penting: Menyimpan koleksi yang dapat diiterasi. Mendapatkan semua item sekaligus
Buat LearnArray.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnArray {
// Array untuk menyimpan plant ID
uint256[] public allPlantIds;
// Tambah tanaman
function addPlant(uint256 _plantId) public {
allPlantIds.push(_plantId);
}
// Dapatkan total tanaman
function getTotalPlants() public view returns (uint256) {
return allPlantIds.length;
}
// Dapatkan semua plant ID
function getAllPlants() public view returns (uint256[] memory) {
return allPlantIds;
}
}
Penjelasan:
uint256[]- array dinamis (daftar) yang dapat bertambah ukurannyaallPlantIds.push(_plantId)- menambahkan elemen ke akhir arrayallPlantIds.length- mengembalikan jumlah elemen dalam arrayallPlantIds[0]- akses elemen pertama (array dimulai dari indeks 0!)returns (uint256[] memory)- mengembalikan seluruh array
Coba:
- Deploy
- Tambah tanaman dengan ID: 1, 2, 3
- Klik
getTotalPlantsโ Lihat 3 - Klik
getAllPlantsโ Lihat [1, 2, 3]
3. Mapping + Struct (Banyak Tanaman)โ
Apa itu: Menggabungkan mapping dengan struct untuk menyimpan banyak item kompleks (plantId โ Plant struct)
Mengapa penting: Mengelola banyak item dengan data kompleks. Pola smart contract dunia nyata
Buat MultiplePlants.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract MultiplePlants {
enum GrowthStage { SEED, SPROUT, GROWING, BLOOMING }
struct Plant {
uint256 id;
address owner;
GrowthStage stage;
uint8 waterLevel;
bool exists;
}
// Mapping untuk menyimpan tanaman
mapping(uint256 => Plant) public plants;
// Counter
uint256 public plantCounter;
// Tambah tanaman baru
function addPlant() public returns (uint256) {
plantCounter++;
plants[plantCounter] = Plant({
id: plantCounter,
owner: msg.sender,
stage: GrowthStage.SEED,
waterLevel: 100,
exists: true
});
return plantCounter;
}
// Siram tanaman
function waterPlant(uint256 _plantId) public {
plants[_plantId].waterLevel = 100;
}
// Dapatkan info tanaman
function getPlant(uint256 _plantId) public view returns (Plant memory) {
return plants[_plantId];
}
}
Penjelasan:
mapping(uint256 => Plant) public plants- memetakan plantId ke Plant structplantCounter++- meningkatkan counter sebesar 1 (membuat ID unik)plants[plantCounter] = Plant({ ... })- menyimpan tanaman baru di mappingreturns (uint256)- fungsi mengembalikan ID tanaman barureturns (Plant memory)- fungsi mengembalikan salinan Plant struct- Menggabungkan mapping + struct untuk mengelola banyak tanaman!
Coba:
- Deploy
- Klik
addPlantโ Mengembalikan plantId=1 - Klik
addPlantlagi โ Mengembalikan plantId=2 - Ketik 1 di
getPlantโ Lihat data tanaman #1 - Ketik 2 di
getPlantโ Lihat data tanaman #2 - Ketik 1 di
waterPlantโ Siram tanaman #1!
4.4 Solidity 104: Modifier & Eventโ
Tambahkan keamanan dan komunikasi.
1. Require (Validasi)โ
Apa itu: Penjaga keamanan yang memeriksa kondisi sebelum menjalankan kode
Mengapa penting: Mencegah tindakan tidak sah. Validasi input. Penting untuk keamanan
Buat LearnRequire.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnRequire {
mapping(uint256 => address) public plantOwner;
mapping(uint256 => uint8) public waterLevel;
function addPlant(uint256 _plantId) public {
plantOwner[_plantId] = msg.sender;
waterLevel[_plantId] = 100;
}
function waterPlant(uint256 _plantId) public {
// Cek apakah pemanggil memiliki tanaman ini
require(plantOwner[_plantId] == msg.sender, "Bukan tanaman Anda!");
waterLevel[_plantId] = 100;
}
}
Penjelasan:
require(condition, "error message")- memeriksa apakah kondisi benar- Jika kondisi FALSE โ transaksi gagal dan menampilkan pesan error
- Jika kondisi TRUE โ kode berlanjut ke baris berikutnya
plantOwner[_plantId] == msg.sender- memeriksa apakah pemanggil memiliki tanaman- Digunakan untuk validasi dan pemeriksaan keamanan
Coba:
- Deploy
- Tambah tanaman dengan ID=1
- Coba siram โ BERHASIL (Anda memilikinya)
- Ganti ke akun lain di MetaMask
- Coba siram tanaman #1 โ GAGAL dengan "Bukan tanaman Anda!"
2. Modifier (Pemeriksaan Reusable)โ
Apa itu: Pembungkus validasi yang dapat digunakan kembali untuk banyak fungsi
Mengapa penting: Hindari pengulangan pemeriksaan require. Kode lebih bersih. Prinsip DRY (Don't Repeat Yourself)
Buat LearnModifier.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnModifier {
address public owner;
mapping(uint256 => address) public plantOwner;
mapping(uint256 => uint8) public waterLevel;
uint256 public ownerActionCount;
constructor() {
owner = msg.sender;
}
// Modifier: hanya owner yang bisa memanggil
modifier onlyOwner() {
require(msg.sender == owner, "Hanya owner!");
_;
}
// Modifier: harus memiliki tanaman
modifier onlyPlantOwner(uint256 _plantId) {
require(plantOwner[_plantId] == msg.sender, "Bukan tanaman Anda!");
_;
}
function addPlant(uint256 _plantId) public {
plantOwner[_plantId] = msg.sender;
waterLevel[_plantId] = 100;
}
// Hanya owner yang bisa memanggil ini
function ownerFunction() public onlyOwner {
ownerActionCount++;
}
// Hanya pemilik tanaman yang bisa menyiram
function waterPlant(uint256 _plantId) public onlyPlantOwner(_plantId) {
waterLevel[_plantId] = 100;
}
}
Penjelasan:
modifier onlyOwner() { ... }- membuat pemeriksaan yang dapat digunakan kembali_- placeholder di mana kode fungsi akan berjalanfunction ownerFunction() public onlyOwner- menerapkan modifier- Modifier berjalan SEBELUM fungsi (memeriksa kondisi dulu)
ownerActionCount++- menambah counter (hanya owner yang bisa melakukan ini)- Lebih bersih daripada menulis require di setiap fungsi!
- Dapat menggunakan beberapa modifier pada satu fungsi
Coba:
- Deploy
- Klik
ownerActionCountโ Lihat 0 - Klik
ownerFunctionโ BERHASIL (Anda owner) - Klik
ownerActionCountโ Sekarang 1! - Ganti akun โ Coba
ownerFunctionโ GAGAL dengan "Hanya owner!" - Tambah tanaman dengan ID=1, coba siram โ BERHASIL
- Ganti akun โ Coba siram tanaman #1 โ GAGAL dengan "Bukan tanaman Anda!"
3. Event (Komunikasi)โ
Apa itu: Menyiarkan log tentang apa yang terjadi di contract Anda (disimpan di blockchain)
Mengapa penting: Frontend mendengarkan pembaruan real-time. Melacak riwayat. Alat debugging
Buat LearnEvents.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnEvents {
// Deklarasi event
event PlantAdded(address indexed owner, uint256 indexed plantId);
event PlantWatered(uint256 indexed plantId, uint8 waterLevel);
mapping(uint256 => address) public plantOwner;
uint256 public plantCounter;
function addPlant() public {
plantCounter++;
plantOwner[plantCounter] = msg.sender;
// Emit event
emit PlantAdded(msg.sender, plantCounter);
}
function waterPlant(uint256 _plantId) public {
// Emit event
emit PlantWatered(_plantId, 100);
}
}
Penjelasan:
event PlantAdded(...)- mendeklarasikan event (data apa yang akan dicatat)indexed- membuat parameter dapat dicari (maksimal 3 parameter indexed)emit PlantAdded(msg.sender, plantCounter)- memicu event- Event disimpan di blockchain tapi TIDAK menghabiskan gas untuk dibaca
- Frontend dapat mendengarkan event secara real-time
- Digunakan untuk: logging, notifikasi, melacak riwayat
Coba:
- Deploy
- Klik
addPlant - Lihat transaksi di konsol Remix
- Klik "logs" โ Lihat event PlantAdded!
- Klik
waterPlantdengan ID=1 - Lihat event PlantWatered di logs!
4.5 Solidity 105: Payable & LiskGarden Lengkapโ
Akhirnya, tambahkan uang (ETH) dan bangun game lengkap!
1. Fungsi Payableโ
Apa itu: Keyword yang memungkinkan fungsi menerima ETH (msg.value)
Mengapa penting: Menerima pembayaran, donasi, hadiah. Tanpa ini, mengirim ETH akan gagal
Buat LearnPayable.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnPayable {
uint256 public plantCounter;
// Fungsi payable dapat menerima ETH
function buyPlant() public payable returns (uint256) {
require(msg.value >= 0.001 ether, "Perlu 0.001 ETH");
plantCounter++;
return plantCounter;
}
// Cek saldo contract
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
Penjelasan:
payable- keyword yang memungkinkan fungsi menerima ETHmsg.value- jumlah ETH yang dikirim dengan transaksi (dalam wei)0.001 ether- compiler mengkonversi ke wei (1 ether = 10^18 wei)require(msg.value >= 0.001 ether)- memeriksa pembayaran minimumaddress(this).balance- saldo ETH contract- Tanpa payable, mengirim ETH akan gagal!
Coba:
- Deploy
- Di Remix, cari field "VALUE" (di atas tombol Deploy)
- Masukkan 1 dan pilih milliether (= 0,001 ETH)
- Klik
buyPlantโ Konfirmasi di MetaMask - Klik
getBalanceโ Lihat 0,001 ETH di contract!
2. Mengirim ETHโ
Apa itu: Mengirim ETH dari contract ke alamat menggunakan .call\{value: amount\}("")
Mengapa penting: Membayar hadiah, refund, penarikan. Selalu periksa keberhasilan!
Buat LearnSendETH.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnSendETH {
address public owner;
constructor() {
owner = msg.sender;
}
// Terima ETH
function deposit() public payable {}
// Kirim ETH ke seseorang
function sendReward(address _to) public {
require(msg.sender == owner, "Hanya owner");
// Kirim 0.001 ETH
(bool success, ) = _to.call{value: 0.001 ether}("");
require(success, "Transfer gagal");
}
// Cek saldo
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
Penjelasan:
function deposit() public payable {}- menerima ETH tanpa kode (hanya menerima)_to.call\{value: 0.001 ether\}("")- mengirim ETH ke alamat(bool success, ) = ...- menangkap apakah transfer berhasilrequire(success, "Transfer gagal")- revert jika pengiriman gagal.calladalah cara modern dan aman untuk mengirim ETH- Cara lama:
.transfer()dan.send()TIDAK direkomendasikan
Coba:
- Deploy
- Kirim ETH menggunakan
deposit(dengan field VALUE) - Klik
getBalanceโ Lihat deposit Anda - Gunakan
sendRewarduntuk mengirim 0,001 ETH ke alamat!
4.6 Solidity 106: Scopes, Visibility & Error Handlingโ
Konsep penting untuk menulis smart contract yang aman dan efisien.
1. Variable Scopes (Lingkup Variabel)โ
Apa itu: Tempat di mana variabel dapat diakses dan berapa lama variabel tersebut hidup
Mengapa penting: Memahami biaya gas, keamanan data, dan struktur code yang baik
Buat LearnScopes.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnScopes {
// 1. STATE VARIABLE: Disimpan di blockchain storage
uint256 public plantCounter; // Permanen, tersimpan selamanya
address public owner; // Biaya gas untuk write/update
// 2. GLOBAL VARIABLES: Built-in Solidity
function getGlobalVariables() public view returns (
address sender,
uint256 timestamp,
uint256 blockNumber,
address contractAddress
) {
sender = msg.sender; // Alamat yang memanggil fungsi
timestamp = block.timestamp; // Waktu blok saat ini (Unix)
blockNumber = block.number; // Nomor blok saat ini
contractAddress = address(this); // Alamat contract ini
return (sender, timestamp, blockNumber, contractAddress);
}
// 3. LOCAL VARIABLES: Temporary dalam function
function calculateAge(uint256 _plantedTime) public view returns (uint256) {
// Local variable - hanya ada selama fungsi berjalan
uint256 currentTime = block.timestamp;
uint256 age = currentTime - _plantedTime;
// age dan currentTime hilang setelah fungsi selesai
return age;
}
constructor() {
owner = msg.sender;
plantCounter = 0;
}
function addPlant() public {
// Local variable
uint256 newId = plantCounter + 1;
// Update state variable (biaya gas!)
plantCounter = newId;
}
}
Penjelasan Scopes:
State Variables (Blockchain Storage):
- Disimpan permanen di blockchain
- Biaya gas TINGGI untuk write/update
- Dapat diakses dari semua fungsi dalam contract
- Contoh:
plantCounter,owner
Local Variables (Memory/Stack):
- Hanya ada selama fungsi berjalan
- Hilang setelah fungsi selesai
- Biaya gas RENDAH
- Contoh:
newId,age,currentTime
Global Variables (Built-in):
msg.sender- alamat yang memanggil fungsimsg.value- jumlah ETH yang dikirim (wei)block.timestamp- waktu blok Unix (detik)block.number- nomor blok saat initx.origin- alamat EOA asli (HATI-HATI: security risk!)address(this)- alamat contract ini
Coba:
- Deploy
- Klik
getGlobalVariablesโ Lihat info blockchain! - Klik
addPlantbeberapa kali - Klik
plantCounterโ Lihat bertambah (state variable tersimpan)
2. Visibility Modifiers (Pengaturan Akses)โ
Apa itu: Menentukan siapa yang dapat mengakses variabel dan fungsi
Mengapa penting: Keamanan contract - batasi akses ke data dan fungsi sensitif
Buat LearnVisibility.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnVisibility {
// STATE VARIABLES VISIBILITY
uint256 public publicVar = 100; // Otomatis ada getter
uint256 private privateVar = 200; // Hanya contract ini
uint256 internal internalVar = 300; // Contract ini + turunan
// PUBLIC: Bisa dipanggil dari mana saja
function publicFunction() public pure returns (string memory) {
return "Semua bisa panggil ini";
}
// EXTERNAL: Hanya dari LUAR contract (tidak bisa dipanggil internal)
function externalFunction() external pure returns (string memory) {
return "Hanya bisa dipanggil dari luar";
}
// INTERNAL: Hanya dari contract ini dan turunannya
function internalFunction() internal pure returns (string memory) {
return "Hanya untuk internal";
}
// PRIVATE: HANYA contract ini
function privateFunction() private pure returns (string memory) {
return "Hanya contract ini";
}
// Fungsi untuk test internal call
function testInternalCall() public pure returns (string memory) {
// Bisa panggil internal function
return internalFunction();
}
// Fungsi untuk akses private variable
function getPrivateVar() public view returns (uint256) {
return privateVar; // Bisa akses karena dalam contract yang sama
}
}
Penjelasan Visibility:
Untuk Fungsi:
โโโโโโโโโโโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ Visibility โ Contract โ Turunan โ External Call โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ public โ โ
Ya โ โ
Ya โ โ
Ya โ
โ external โ โ Tidak* โ โ Tidak* โ โ
Ya โ
โ internal โ โ
Ya โ โ
Ya โ โ Tidak โ
โ private โ โ
Ya โ โ Tidak โ โ Tidak โ
โโโโโโโโโโโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ
* external bisa dipanggil dengan this.functionName()
Untuk State Variables:
public- otomatis membuat getter functioninternal- default jika tidak disebutkanprivate- hanya contract ini (tapi tetap visible di blockchain!)
Kapan Pakai Apa:
public- API contract, fungsi utamaexternal- Lebih hemat gas untuk fungsi yang hanya dipanggil dari luarinternal- Helper functions, dipakai turunanprivate- Helper yang sangat spesifik
Coba:
- Deploy
- Klik
publicVarโ Berhasil (ada getter otomatis) - Coba akses
privateVarโ Tidak ada fungsi! (gunakangetPrivateVar) - Klik
publicFunctionโ Berhasil - Klik
externalFunctionโ Berhasil (dari luar)
3. Function Modifiers (State Mutability)โ
Apa itu: Menentukan apakah fungsi membaca atau mengubah blockchain state
Mengapa penting: Optimasi gas dan keamanan - fungsi read-only GRATIS!
Buat LearnFunctionModifiers.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnFunctionModifiers {
uint256 public counter = 0;
address public owner;
constructor() {
owner = msg.sender;
}
// VIEW: Membaca state, tidak mengubah (GRATIS!)
function getCounter() public view returns (uint256) {
return counter; // Hanya baca
}
function getOwner() public view returns (address) {
return owner; // Hanya baca
}
function calculateDouble(uint256 x) public pure returns (uint256) {
// Bisa baca state variable + parameter
return x * 2;
}
// PURE: TIDAK baca dan TIDAK ubah state (GRATIS!)
function add(uint256 a, uint256 b) public pure returns (uint256) {
// Hanya kalkulasi murni
return a + b;
}
function multiply(uint256 a, uint256 b) public pure returns (uint256) {
return a * b;
}
// PAYABLE: Dapat menerima ETH
function deposit() public payable {
// Terima ETH tanpa kode
}
function buyItem() public payable returns (bool) {
require(msg.value >= 0.001 ether, "Minimal 0.001 ETH");
return true;
}
// REGULAR (no modifier): Mengubah state (BAYAR GAS!)
function incrementCounter() public {
counter++; // Ubah state = butuh gas
}
function setCounter(uint256 _newValue) public {
counter = _newValue; // Ubah state = butuh gas
}
// Check balance
function getBalance() public view returns (uint256) {
return address(this).balance;
}
}
Penjelasan Function Modifiers:
1. view (Read-Only):
- Membaca state variables
- TIDAK mengubah state
- GRATIS untuk dipanggil (no gas dari external call)
- Contoh: getter functions, calculations dengan state
2. pure (Pure Calculation):
- TIDAK membaca state
- TIDAK mengubah state
- GRATIS untuk dipanggil
- Contoh: math functions, string operations
3. payable (Dapat Terima ETH):
- Fungsi dapat menerima Ether
- Akses
msg.value - Tanpa
payable, transfer ETH gagal
4. Regular (No Modifier):
- Dapat membaca DAN mengubah state
- BAYAR GAS untuk eksekusi
- Default jika tidak ada modifier
Perbandingan:
โโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโโ
โ Modifier โ Baca โ Ubah โ ETH โ Gas โ
โโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโค
โ view โ โ
Ya โ โ No โ โ No โ 0 (ext) โ
โ pure โ โ No โ โ No โ โ No โ 0 (ext) โ
โ payable โ โ
Ya โ โ
Ya โ โ
Ya โ Bayar โ
โ (none) โ โ
Ya โ โ
Ya โ โ No โ Bayar โ
โโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโ
Coba:
- Deploy
- Klik
getCounterโ GRATIS (view) - Klik
add(5, 3)โ Hasil 8, GRATIS (pure) - Klik
incrementCounterโ Bayar gas (mengubah state) - Klik
getCounterโ Lihat bertambah - Kirim ETH ke
depositdengan VALUE โ Berhasil (payable)
4. Error Handling (Penanganan Error)โ
Apa itu: Cara menghentikan eksekusi dan revert transaksi jika ada masalah
Mengapa penting: Validasi input, keamanan, dan mencegah state invalid
Buat LearnErrorHandling.sol:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LearnErrorHandling {
address public owner;
uint256 public balance;
mapping(address => uint256) public userBalance;
constructor() {
owner = msg.sender;
balance = 100;
}
// REQUIRE: Validasi input dan kondisi (yang paling umum!)
function withdraw(uint256 amount) public {
// Validasi 1: Cek saldo cukup
require(balance >= amount, "Saldo tidak cukup");
// Validasi 2: Cek amount tidak 0
require(amount > 0, "Amount harus lebih dari 0");
// Jika semua require pass, jalankan
balance -= amount;
userBalance[msg.sender] += amount;
}
function deposit(uint256 amount) public {
require(amount > 0, "Harus deposit lebih dari 0");
balance += amount;
}
// Require dengan kondisi kompleks
function transferOwnership(address newOwner) public {
require(msg.sender == owner, "Hanya owner");
require(newOwner != address(0), "Address tidak valid");
require(newOwner != owner, "Sudah jadi owner");
owner = newOwner;
}
// REVERT: Manual error dengan kondisi custom
function checkEven(uint256 number) public pure returns (bool) {
if (number % 2 != 0) {
revert("Angka harus genap!");
}
return true;
}
function complexCheck(uint256 value) public pure returns (string memory) {
if (value < 10) {
revert("Nilai terlalu kecil");
}
if (value > 100) {
revert("Nilai terlalu besar");
}
if (value == 50) {
revert("Nilai 50 tidak diperbolehkan");
}
return "Nilai valid!";
}
// ASSERT: Internal error checking (jarang dipakai)
function internalCheck(uint256 newBalance) public {
balance = newBalance;
// Assert untuk cek invariant (kondisi yang HARUS selalu benar)
// Jika assert gagal = ada BUG di code!
assert(balance >= 0); // uint256 selalu >= 0, ini contoh saja
}
}
Penjelasan Error Handling:
1. require() - Input Validation (90% use case)
require(kondisi, "pesan error");
- Cek kondisi SEBELUM eksekusi
- Jika FALSE โ revert + kembalikan gas
- Jika TRUE โ lanjut eksekusi
- Untuk: validasi input, permissions, business logic
Contoh Umum:
require(msg.sender == owner, "Not owner");
require(amount > 0, "Amount must be positive");
require(balance >= amount, "Insufficient balance");
require(address != address(0), "Invalid address");
2. revert() - Manual Error
revert("pesan error");
- Hentikan eksekusi manual
- Sama seperti
require(false, "pesan") - Bagus untuk error handling kompleks
- Gunakan dalam
if/else
Contoh:
if (kondisiError) {
revert("Error terjadi");
}
3. assert() - Internal Check (Jarang)
assert(kondisi);
- Untuk cek invariant (kondisi yang HARUS selalu benar)
- Jika gagal = ada BUG di contract!
- TIDAK mengembalikan gas (berbeda dengan require)
- Untuk: overflow check, invariant validation
Kapan Pakai Apa:
โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
โ Function โ Use Case โ Gas Refund โ
โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ require โ Input validation โ โ
Ya โ
โ โ Access control โ โ
โ โ Business logic โ โ
โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ revert โ Complex error handling โ โ
Ya โ
โ โ Custom errors โ โ
โโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ assert โ Internal invariants โ โ Tidak โ
โ โ Check for bugs โ โ
โโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโ
Best Practices:
- โ
Gunakan
require()untuk 99% kasus - โ Pesan error jelas dan deskriptif
- โ Cek kondisi paling murah dulu (gas optimization)
- โ
revert()untuk logika bercabang kompleks - โ ๏ธ
assert()hanya untuk debug internal
Coba:
- Deploy dengan balance = 100
- Coba
withdraw(150)โ GAGAL "Saldo tidak cukup" - Coba
withdraw(50)โ BERHASIL - Coba
withdraw(0)โ GAGAL "Amount harus lebih dari 0" - Coba
checkEven(5)โ GAGAL "Angka harus genap!" - Coba
checkEven(4)โ BERHASIL - Coba
complexCheck(50)โ GAGAL "Nilai 50 tidak diperbolehkan"
3. Game LiskGarden Lengkapโ
Apa itu: Game blockchain lengkap yang menggabungkan SEMUA konsep - tanam benih, siram tanaman, panen untuk profit
Mengapa penting: Contoh dunia nyata yang menunjukkan bagaimana semuanya bekerja bersama
๐ TANTANGAN AKHIR: Build LiskGarden Game! (16:00 - 16:45)โ
๐ฎ Apa yang Akan Anda Bangun:
Game blockchain LENGKAP di mana pemain:
- ๐ฑ Tanam benih dengan bayar 0.001 ETH
- ๐ง Siram tanaman untuk jaga tetap hidup
- โณ Tunggu tanaman tumbuh (3 tahap)
- ๐ธ Panen saat BLOOMING โ dapat 0.003 ETH
- ๐ฐ PROFIT: 0.002 ETH per tanaman!
๐ Review: Konsep yang Digunakanโ
Contract ini menggunakan SEMUA yang sudah Anda pelajari hari ini:
โ
Solidity 101: Basic Types
โโ string, uint256, bool, address โ
โโ State variables โ
โโ Constructor โ
โ
Solidity 102: Struct & Enum
โโ enum GrowthStage โ
โโ struct Plant โ
โ
Solidity 103: Mapping & Array
โโ mapping(uint256 => Plant) โ
โโ mapping(address => uint256[]) โ
โโ Array operations โ
โ
Solidity 104: Modifiers & Events
โโ require() validation โ
โโ modifier (internal) โ
โโ Events (5 events!) โ
โ
Solidity 105: Payable
โโ payable functions โ
โโ msg.value โ
โโ .call untuk kirim ETH โ
โ
Solidity 106: Advanced
โโ public/external/internal โ
โโ view/pure โ
โโ storage vs memory โ
Ini adalah ujian FINAL untuk skills Anda! ๐ฅ
๐ฏ PILIH LEVEL TANTANGAN ANDA:โ
Pilih satu level sesuai dengan skill Anda. Klik untuk expand!
๐ข LEVEL 1: GUIDED (Recommended untuk pemula)
๐ข LEVEL 1: GUIDED CHALLENGEโ
Untuk siapa: Pemula yang baru belajar Solidity hari ini
Yang didapat:
- โ Template lengkap dengan TODO
- โ Hints di setiap bagian
- โ Step-by-step instructions
- โ Helper functions sudah lengkap
Estimasi waktu: 30-45 menit
๐ Spesifikasi Contract LiskGardenโ
Game Mechanics:
- Player bayar 0.001 ETH untuk tanam benih
- Tanaman tumbuh melalui 4 stage: SEED โ SPROUT โ GROWING โ BLOOMING
- Setiap stage butuh 1 menit
- Tanaman kehilangan 2% air setiap 30 detik
- Jika air = 0% โ Tanaman MATI!
- Player harus siram tanaman untuk jaga hidup
- Panen saat BLOOMING โ dapat 0.003 ETH reward
- PROFIT per plant = 0.002 ETH
๐๏ธ STRUKTUR CONTRACT (8 Bagian)โ
// BAGIAN 1: Enum & Struct (Data Types)
// BAGIAN 2: State Variables (Storage)
// BAGIAN 3: Constants (Game Parameters)
// BAGIAN 4: Events (Logging)
// BAGIAN 5: Constructor
// BAGIAN 6: Plant Seed Function (Payable)
// BAGIAN 7: Water System (View + Internal)
// BAGIAN 8: Harvest Function (Payable Out)
๐ป TEMPLATE CONTRACTโ
Buat file LiskGarden.sol dan isi dengan template ini:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract LiskGarden {
// ============================================
// BAGIAN 1: ENUM & STRUCT
// ============================================
// TODO 1.1: Buat enum GrowthStage dengan 4 nilai:
// SEED, SPROUT, GROWING, BLOOMING
// Hint: enum GrowthStage { SEED, SPROUT, GROWING, BLOOMING }
// TODO 1.2: Buat struct Plant dengan 8 fields:
// - uint256 id
// - address owner
// - GrowthStage stage
// - uint256 plantedDate
// - uint256 lastWatered
// - uint8 waterLevel
// - bool exists
// - bool isDead
// ============================================
// BAGIAN 2: STATE VARIABLES
// ============================================
// TODO 2.1: Mapping plantId ke Plant
// Hint: mapping(uint256 => Plant) public plants;
// TODO 2.2: Mapping address ke array plantId (track tanaman user)
// Hint: mapping(address => uint256[]) public userPlants;
// TODO 2.3: Counter untuk ID tanaman baru
// Hint: uint256 public plantCounter;
// TODO 2.4: Address owner contract
// Hint: address public owner;
// ============================================
// BAGIAN 3: CONSTANTS (Game Parameters)
// ============================================
// TODO 3.1: Harga tanam = 0.001 ether
// Hint: uint256 public constant PLANT_PRICE = 0.001 ether;
// TODO 3.2: Reward panen = 0.003 ether
// TODO 3.3: Durasi per stage = 1 menit
// Hint: uint256 public constant STAGE_DURATION = 1 minutes;
// TODO 3.4: Waktu deplesi air = 30 detik
// TODO 3.5: Rate deplesi = 2 (2% setiap interval)
// Hint: uint8 public constant WATER_DEPLETION_RATE = 2;
// ============================================
// BAGIAN 4: EVENTS
// ============================================
// TODO 4.1: Event PlantSeeded(address indexed owner, uint256 indexed plantId)
// TODO 4.2: Event PlantWatered(uint256 indexed plantId, uint8 newWaterLevel)
// TODO 4.3: Event PlantHarvested(uint256 indexed plantId, address indexed owner, uint256 reward)
// TODO 4.4: Event StageAdvanced(uint256 indexed plantId, GrowthStage newStage)
// TODO 4.5: Event PlantDied(uint256 indexed plantId)
// ============================================
// BAGIAN 5: CONSTRUCTOR
// ============================================
// TODO 5: Set owner = msg.sender
constructor() {
}
// ============================================
// BAGIAN 6: PLANT SEED (Fungsi Utama #1)
// ============================================
// TODO 6: Lengkapi fungsi plantSeed
// Tipe: external payable, returns uint256
// Steps:
// 1. require msg.value >= PLANT_PRICE
// 2. Increment plantCounter
// 3. Buat Plant baru dengan struct
// 4. Simpan ke mapping plants
// 5. Push plantId ke userPlants
// 6. Emit PlantSeeded
// 7. Return plantId
function plantSeed() external payable returns (uint256) {
// TODO: Implement fungsi ini
// Hint: Lihat spesifikasi di atas!
}
// ============================================
// BAGIAN 7: WATER SYSTEM (3 Fungsi)
// ============================================
// TODO 7.1: calculateWaterLevel (public view returns uint8)
// Steps:
// 1. Ambil plant dari storage
// 2. Jika !exists atau isDead, return 0
// 3. Hitung timeSinceWatered = block.timestamp - lastWatered
// 4. Hitung depletionIntervals = timeSinceWatered / WATER_DEPLETION_TIME
// 5. Hitung waterLost = depletionIntervals * WATER_DEPLETION_RATE
// 6. Jika waterLost >= waterLevel, return 0
// 7. Return waterLevel - waterLost
function calculateWaterLevel(uint256 plantId) public view returns (uint8) {
// TODO: Implement
}
// TODO 7.2: updateWaterLevel (internal)
// Steps:
// 1. Ambil plant dari storage
// 2. Hitung currentWater dengan calculateWaterLevel
// 3. Update plant.waterLevel
// 4. Jika currentWater == 0 && !isDead, set isDead = true dan emit PlantDied
function updateWaterLevel(uint256 plantId) internal {
// TODO: Implement
}
// TODO 7.3: waterPlant (external)
// Steps:
// 1. require exists
// 2. require owner == msg.sender
// 3. require !isDead
// 4. Set waterLevel = 100
// 5. Set lastWatered = block.timestamp
// 6. Emit PlantWatered
// 7. Call updatePlantStage
function waterPlant(uint256 plantId) external {
// TODO: Implement
}
// ============================================
// BAGIAN 8: STAGE & HARVEST (2 Fungsi)
// ============================================
// TODO 8.1: updatePlantStage (public)
// Steps:
// 1. require exists
// 2. Call updateWaterLevel
// 3. Jika isDead, return
// 4. Hitung timeSincePlanted
// 5. Simpan oldStage
// 6. Update stage berdasarkan waktu (3 if statements)
// 7. Jika stage berubah, emit StageAdvanced
function updatePlantStage(uint256 plantId) public {
// TODO: Implement
}
// TODO 8.2: harvestPlant (external)
// Steps:
// 1. require exists
// 2. require owner
// 3. require !isDead
// 4. Call updatePlantStage
// 5. require stage == BLOOMING
// 6. Set exists = false
// 7. Emit PlantHarvested
// 8. Transfer HARVEST_REWARD dengan .call
// 9. require success
function harvestPlant(uint256 plantId) external {
// TODO: Implement
}
// ============================================
// HELPER FUNCTIONS (Sudah Lengkap)
// ============================================
function getPlant(uint256 plantId) external view returns (Plant memory) {
Plant memory plant = plants[plantId];
plant.waterLevel = calculateWaterLevel(plantId);
return plant;
}
function getUserPlants(address user) external view returns (uint256[] memory) {
return userPlants[user];
}
function withdraw() external {
require(msg.sender == owner, "Bukan owner");
(bool success, ) = owner.call\{value: address(this).balance\}("");
require(success, "Transfer gagal");
}
receive() external payable {}
}
๐ PENJELASAN SETIAP BAGIANโ
BAGIAN 1: Enum & Structโ
Enum = Named numbers untuk growth stages Struct = Custom type untuk menyimpan data tanaman
BAGIAN 2: State Variablesโ
plants = Mapping untuk akses tanaman by ID userPlants = Track semua tanaman milik user plantCounter = Auto-increment ID owner = Contract deployer
BAGIAN 3: Constantsโ
constant = Nilai tetap, hemat gas! ether/minutes/seconds = Solidity time units
BAGIAN 4: Eventsโ
Events untuk frontend listen perubahan real-time indexed = Bisa di-filter dan di-search
BAGIAN 5: Constructorโ
Run sekali saat deploy, set owner
BAGIAN 6: plantSeed()โ
external payable = Bisa dipanggil dari luar + terima ETH Buat tanaman baru, simpan ke blockchain
BAGIAN 7: Water Systemโ
calculateWaterLevel = view function (read-only, gratis) updateWaterLevel = internal (helper function) waterPlant = external (public API)
BAGIAN 8: Stage & Harvestโ
updatePlantStage = Cek waktu dan update stage harvestPlant = Panen dan kirim reward ETH
โ CHECKLIST IMPLEMENTASIโ
Bagian 1-2: Data Structuresโ
- Enum GrowthStage dengan 4 nilai
- Struct Plant dengan 8 fields
- 2 mappings (plants, userPlants)
- 2 state variables (plantCounter, owner)
Bagian 3-4: Constants & Eventsโ
- 5 constants dengan nilai benar
- 5 events dengan indexed parameters
Bagian 5-6: Constructor & Plantโ
- Constructor set owner
- plantSeed: require, create, store, emit, return
Bagian 7: Water Systemโ
- calculateWaterLevel: 7 steps logic
- updateWaterLevel: update + emit death
- waterPlant: 3 requires + update + emit
Bagian 8: Harvestโ
- updatePlantStage: time-based stage update
- harvestPlant: validations + ETH transfer
๐งช TEST CONTRACT ANDAโ
Test 1: Deploy & Initial Stateโ
1. Compile contract (no errors)
2. Deploy ke Remix VM atau Lisk Sepolia
3. Cek owner == your address
4. Cek plantCounter == 0
Test 2: Plant Seedโ
1. Set VALUE = 0.001 ETH (1000000000000000 wei)
2. Call plantSeed()
3. Cek return value = 1 (plantId)
4. Cek plantCounter == 1
5. Call getPlant(1) โ lihat data plant
Test 3: Water Plantโ
1. Call waterPlant(1)
2. Cek PlantWatered event emitted
3. Call getPlant(1) โ waterLevel = 100
Test 4: Growth Stagesโ
1. Tunggu 1 menit
2. Call updatePlantStage(1)
3. Call getPlant(1) โ stage = 1 (SPROUT)
4. Tunggu 2 menit total
5. Call updatePlantStage(1) โ stage = 2 (GROWING)
6. Tunggu 3 menit total โ stage = 3 (BLOOMING)
Test 5: Harvestโ
1. Pastikan stage = BLOOMING
2. Cek balance Anda sebelum harvest
3. Call harvestPlant(1)
4. Cek balance Anda โ bertambah 0.003 ETH!
5. Call getPlant(1) โ exists = false
Test 6: Death Mechanicโ
1. Plant seed baru (plantId = 2)
2. JANGAN siram
3. Tunggu 50 detik ร 25 interval = ~25 menit
4. Call getPlant(2) โ waterLevel = 0, isDead = true
5. Try waterPlant(2) โ REVERT "Tanaman sudah mati"
๐ก TIPS DEBUGGINGโ
Error Umum:
"Stack too deep" error
โ Terlalu banyak local variables
โ Solusi: Pecah fungsi jadi lebih kecil
"Out of gas" error
โ Loop atau kalkulasi terlalu kompleks
โ Cek logic calculateWaterLevel
"Transfer failed"
โ Contract tidak punya cukup ETH
โ Pastikan plant beberapa seed dulu sebelum harvest
"Tanaman belum siap"
โ Stage masih belum BLOOMING
โ Call updatePlantStage dulu, tunggu 3 menit
Type conversion errors
โ uint8 vs uint256 mismatch
โ Gunakan uint8(value) untuk cast
Debug Strategy:
- Compile error โ Cek syntax, semicolon, brackets
- Revert error โ Baca error message, cek require
- Wrong result โ Tambah emit events, track values
- Gas issue โ Simplify logic, avoid loops
๐ SETELAH SELESAIโ
Selamat! Anda telah menguasai:
โ Complete smart contract development โ Complex data structures (enum, struct, mapping) โ State management & storage โ Time-based logic (block.timestamp) โ Payable functions & ETH transfers โ Event emission & indexing โ Access control & validation โ Internal vs external functions โ View vs state-changing functions โ Game mechanics implementation
Ini adalah FULL-STACK smart contract developer skill! ๐
๐ก LEVEL 2: INTERMEDIATE (Untuk yang sudah familiar)
๐ก LEVEL 2: INTERMEDIATE CHALLENGEโ
Untuk siapa: Developer yang sudah pernah coding Solidity sebelumnya
Yang didapat:
- โ Spesifikasi lengkap
- โ Architecture overview
- โ Requirements checklist
- โ Tidak ada template atau hints
Estimasi waktu: 20-30 menit
๐ Requirements Checklist:โ
Data Structures:
- Enum: GrowthStage (4 values: SEED, SPROUT, GROWING, BLOOMING)
- Struct: Plant (8 fields)
- Mapping: plantId โ Plant
- Mapping: address โ uint256[] (user plants)
- State: plantCounter, owner
Game Parameters (Constants):
- PLANT_PRICE = 0.001 ether
- HARVEST_REWARD = 0.003 ether
- STAGE_DURATION = 1 minutes
- WATER_DEPLETION_TIME = 30 seconds
- WATER_DEPLETION_RATE = 2
Events:
- PlantSeeded(address indexed owner, uint256 indexed plantId)
- PlantWatered(uint256 indexed plantId, uint8 newWaterLevel)
- PlantHarvested(uint256 indexed plantId, address indexed owner, uint256 reward)
- StageAdvanced(uint256 indexed plantId, GrowthStage newStage)
- PlantDied(uint256 indexed plantId)
Core Functions:
- constructor() - set owner
- plantSeed() external payable returns (uint256) - create plant
- calculateWaterLevel(uint256) public view returns (uint8) - compute water
- updateWaterLevel(uint256) internal - update & check death
- waterPlant(uint256) external - refresh water to 100%
- updatePlantStage(uint256) public - time-based stage update
- harvestPlant(uint256) external - validate & send reward
- getPlant(uint256) external view returns (Plant) - with current water
- getUserPlants(address) external view returns (uint256[]) - user's plants
- withdraw() external - owner withdraw balance
- receive() external payable - accept ETH
๐๏ธ Architecture Overview:โ
contract LiskGarden {
// 1. Data Types
enum GrowthStage { ... }
struct Plant { ... }
// 2. State
mapping(...) plants;
mapping(...) userPlants;
uint256 plantCounter;
address owner;
// 3. Constants
uint256 constant PLANT_PRICE = ...;
// ... 4 more
// 4. Events
event PlantSeeded(...);
// ... 4 more
// 5. Constructor
constructor() { ... }
// 6. Main Functions (8 functions)
function plantSeed() external payable { ... }
function calculateWaterLevel(...) public view { ... }
function updateWaterLevel(...) internal { ... }
function waterPlant(...) external { ... }
function updatePlantStage(...) public { ... }
function harvestPlant(...) external { ... }
// 7. Helper Functions (3 functions)
function getPlant(...) external view { ... }
function getUserPlants(...) external view { ... }
function withdraw() external { ... }
// 8. Receive ETH
receive() external payable {}
}
๐ฏ Function Logic:โ
plantSeed():
- Validate payment >= PLANT_PRICE
- Increment plantCounter
- Create Plant struct with initial values
- Store in plants mapping
- Add to userPlants array
- Emit PlantSeeded
- Return plantId
calculateWaterLevel():
- Get plant from storage
- Return 0 if !exists or isDead
- Calculate time since last watered
- Calculate depletion intervals (time / WATER_DEPLETION_TIME)
- Calculate water lost (intervals * RATE)
- Return max(0, waterLevel - waterLost)
waterPlant():
- Validate exists, owner, !isDead
- Set waterLevel = 100
- Update lastWatered = block.timestamp
- Emit PlantWatered
- Call updatePlantStage
harvestPlant():
- Validate exists, owner, !isDead
- Call updatePlantStage
- Require stage == BLOOMING
- Set exists = false
- Emit PlantHarvested
- Transfer HARVEST_REWARD dengan .call
- Validate transfer success
๐ก Implementation Tips:โ
- Use
Plant storage plant = plants[plantId]untuk modify - Use
Plant memory plant = plants[plantId]untuk read-only - Cast uint256 โ uint8:
uint8(value) - Time units:
1 minutes,30 secondswork in Solidity - ETH units:
0.001 etherauto-converts to wei - .call syntax:
recipient.call{value: amount}("")
Kode sendiri tanpa copy-paste! Gunakan dokumentasi di atas sebagai referensi.
๐ด LEVEL 3: EXPERT (Hardcore Challenge!)
๐ด LEVEL 3: EXPERT CHALLENGEโ
Untuk siapa: Expert developer yang ingin test pure skills
Yang didapat:
- โ High-level requirements only
- โ Tidak ada spesifikasi detail
- โ Tidak ada template
- โ Tidak ada hints
- โ Tidak ada architecture
Estimasi waktu: 15-20 menit (jika expert) atau 1+ jam (jika stuck)
๐ฏ Requirements:โ
Build a blockchain farming game with these specifications:
Game Concept:
- Players invest small amount of ETH to plant seeds
- Plants grow over time through multiple stages
- Players must maintain plants (watering mechanic)
- Neglected plants die (lose investment)
- Successfully grown plants can be harvested for profit
- Harvest reward > initial investment (profitable for players)
Technical Requirements:
- Use enum for growth stages
- Use struct for plant data
- Track multiple plants per user
- Time-based growth mechanics
- Water depletion over time (death mechanic)
- Payable function for planting
- Payable function for harvesting (send rewards)
- Event emissions for all major actions
- Access control (owner functions)
- View functions for game state
Economics:
- Must be profitable for successful players
- Balance risk/reward (death mechanic)
- Consider gas costs in pricing
- Testable on testnet (use small amounts)
Quality Standards:
- Gas efficient
- Secure (validate all inputs)
- No obvious exploits
- Clean code structure
- Proper use of visibility modifiers
- Proper use of state mutability (view/pure/payable)
๐ Bonus Challenges:โ
If you finish quickly, add these features:
- Multiple plant types with different growth rates and rewards
- Fertilizer system to speed up growth (pay extra ETH)
- Disease mechanic - random chance of plant getting sick
- Leaderboard - track most profitable farmers
- Seasons - time windows with bonus rewards
๐ Deliverables:โ
- Complete working contract
- Deployed to Lisk Sepolia testnet
- At least 1 successful plant โ harvest cycle
- Contract verified on block explorer (optional)
- README explaining your implementation choices
No hints. No templates. Pure skills. ๐ช
Show what you're made of! ๐ฅ
๐ฑ CARA BERMAIN LISKGARDENโ
Game Flow:โ
START โ PLANT (pay 0.001 ETH) โ WATER (keep alive) โ WAIT (3 min) โ HARVEST (get 0.003 ETH) โ PROFIT!
Step-by-Step Guide:โ
1. ๐ฑ Tanam Benih (Biaya 0.001 ETH)โ
1. Di Remix, set VALUE = 0.001 ETH
(atau 1000000000000000 Wei)
2. Klik plantSeed()
3. Konfirmasi di MetaMask
4. Lihat plantId di return value (contoh: 1)
5. Save plantId ini!
Economics:
- Biaya: 0.001 ETH
- Reward: 0.003 ETH
- PROFIT: 0.002 ETH (200%!)
2. โณ Tunggu Pertumbuhan (Otomatis)โ
Timeline:
0 min โ SEED ๐ฑ
1 min โ SPROUT ๐ฟ
2 min โ GROWING ๐ณ
3 min โ BLOOMING ๐ธ (siap panen!)
Cara Cek Stage:
1. Call getPlant(plantId)
2. Lihat field "stage":
- 0 = SEED
- 1 = SPROUT
- 2 = GROWING
- 3 = BLOOMING โ Target!
3. ๐ง Siram Tanaman (Wajib!)โ
1. Call waterPlant(plantId)
2. Confirm transaksi
3. Water level reset ke 100%
4. Timer deplesi reset
โ ๏ธ PENTING:
- Tanaman kehilangan 2% air every 30 seconds
- Jika air = 0% โ TANAMAN MATI!
- Tanaman mati = tidak bisa harvest = RUGI!
- Siram setiap ~20 menit untuk aman
Death Timer:
100% water / 2% per 30sec = 50 intervals
50 ร 30 seconds = 1500 seconds = 25 menit
Jadi: Siram minimal setiap 20 menit!
4. ๐ธ Panen Saat Siap (Profit Time!)โ
1. Tunggu sampai stage = BLOOMING (3 menit)
2. Call harvestPlant(plantId)
3. Confirm transaksi
4. Cek wallet Anda โ +0.003 ETH! ๐ฐ
5. Plant sudah exists = false (harvested)
Profit Calculation:
Investment: 0.001 ETH
Reward: 0.003 ETH
โโโโโโโโโโโโโโโโโโโโโโโโ
PROFIT: 0.002 ETH (200% ROI!)
Example:
10 plants = 0.01 ETH invest โ 0.03 ETH return = 0.02 ETH profit
5. ๐ฎ Strategy Tipsโ
Beginner Strategy:
- Plant 1 seed pertama
- Set timer 20 menit untuk siram
- Harvest setelah 3 menit
- Repeat dengan profit!
Advanced Strategy:
- Plant multiple seeds
- Stagger planting (1 menit apart)
- Harvest pipeline: ada yang selalu siap
- Scale up dengan profit
Common Mistakes:
- โ Lupa siram โ tanaman mati
- โ Harvest sebelum BLOOMING โ revert
- โ Plant tanpa cukup ETH โ revert
- โ Set reminder untuk siram!
๐ LANGKAH DEPLOYMENTโ
Persiapan:โ
Yang Dibutuhkan:
- โ Remix IDE terbuka
- โ MetaMask terinstall
- โ Lisk Sepolia testnet ETH (dari faucet)
- โ Contract LiskGarden sudah selesai ditulis
Step 1: Kompilasi Contractโ
1. Buka Remix IDE
2. Pastikan LiskGarden.sol sudah lengkap
3. Klik tab "Solidity Compiler" (icon kompilasi)
4. Pilih Compiler Version: 0.8.30
5. Klik "Compile LiskGarden.sol"
6. Tunggu beberapa detik
7. Lihat โ
hijau = Sukses!
Jika ada error:
- Baca error message dengan teliti
- Cek syntax: semicolons, brackets, spelling
- Gunakan tips debugging di atas
- Jangan lanjut sampai compile sukses!
Step 2: Setup Lisk Sepolia Testnetโ
Add Network ke MetaMask:
Network Name: Lisk Sepolia
RPC URL: https://rpc.sepolia-api.lisk.com
Chain ID: 4202
Currency Symbol: ETH
Block Explorer: https://sepolia-blockscout.lisk.com
Get Testnet ETH:
- Kunjungi: https://sepolia-faucet.lisk.com
- Connect wallet
- Request ETH (biasanya 0.05 ETH)
- Tunggu 1-2 menit
- Cek MetaMask โ ada ETH!
Step 3: Deploy Contractโ
1. Klik tab "Deploy & Run Transactions"
2. Environment: Pilih "Injected Provider - MetaMask"
3. MetaMask popup โ Klik "Connect"
4. Pastikan Network = Lisk Sepolia
5. Pastikan Account punya ETH
6. Contract: Pilih "LiskGarden"
7. Klik "Deploy" (tombol orange)
8. MetaMask popup โ Klik "Confirm"
9. Tunggu transaksi (10-30 detik)
10. Lihat "Deployed Contracts" muncul! ๐
Save Info Penting:
Contract Address: 0x... (copy ini!)
Transaction Hash: 0x... (bukti deploy)
Deployer Address: Your wallet address
Timestamp: Waktu deploy
Step 4: Verifikasi Deploymentโ
Test Basic Functions:
1. Expand contract di "Deployed Contracts"
2. Klik "owner" โ Harus = your address โ
3. Klik "plantCounter" โ Harus = 0 โ
4. Klik "PLANT_PRICE" โ Harus = 1000000000000000 Wei โ
Test Plant Seed:
1. Set VALUE = 0.001 ETH
2. Klik "plantSeed"
3. Confirm MetaMask
4. Cek return: plantId = 1
5. Klik "getPlant" dengan input: 1
6. Lihat data plant lengkap! โ
Step 5: Lihat di Block Explorerโ
1. Copy contract address
2. Buka: https://sepolia-blockscout.lisk.com
3. Paste address di search
4. BOOM! Contract Anda live di blockchain! ๐
Yang Bisa Dilihat:
- โ Balance contract
- โ Transaction history
- โ Contract creation
- โ Internal transactions
- โ Events emitted
- โ Contract source (jika verified)
Step 6: Share Your Achievement!โ
Screenshot ini:
- Contract address di explorer
- First plantSeed transaction
- First harvest transaction (setelah 3 menit)
- Your wallet balance +0.003 ETH
Post Format:
๐ I just deployed LiskGarden to Lisk Sepolia!
Contract: 0x...
Explorer: [link]
Features:
โ
Plant seeds (0.001 ETH)
โ
Time-based growth (3 minutes)
โ
Water depletion mechanic
โ
Harvest reward (0.003 ETH)
โ
200% ROI!
Built with 100% Solidity skills learned in Session 1!
#LiskGarden #Web3 #Solidity #EthereumJakarta
๐ค DEPLOYMENT CHECKLISTโ
Pre-Deployment:โ
- Contract compiled successfully (no errors)
- All functions implemented
- All TODOs completed
- MetaMask has testnet ETH
- Network set to Lisk Sepolia
Deployment:โ
- Contract deployed successfully
- Contract address copied & saved
- Transaction hash saved
- Verified in block explorer
Post-Deployment Testing:โ
- owner check โ
- plantCounter = 0 โ
- plantSeed works โ
- getPlant returns data โ
- waterPlant works โ
- updatePlantStage works โ
- harvestPlant works โ
- Received 0.003 ETH reward โ
Documentation:โ
- Screenshots taken
- Contract info documented
- Code pushed to GitHub
- README written
- Refleksi ditulis
๐ Hasil yang Harus Diserahkanโ
Hasil Wajibโ
โ 1. Contract LiskGarden yang Ter-deploy
- Contract ter-deploy ke Lisk Sepolia
- Alamat contract terdokumentasi
- Hash transaksi tercatat
โ 2. Repository GitHub
- Semua file contract
- README dengan instruksi
- Alamat deployment
โ 3. Refleksi Pembelajaran
- Apa yang dipelajari hari ini
- Tantangan yang dihadapi
- Tujuan untuk sesi berikutnya
Format Pengumpulanโ
sesi-1-liskgarden/
โโโ contracts/
โ โโโ 01-LearnString.sol
โ โโโ 02-LearnNumber.sol
โ โโโ 03-LearnBoolean.sol
โ โโโ 04-LearnAddress.sol
โ โโโ 05-SimplePlant.sol
โ โโโ 06-LearnEnum.sol
โ โโโ 07-LearnStruct.sol
โ โโโ 08-LearnMapping.sol
โ โโโ 09-LearnArray.sol
โ โโโ 10-MultiplePlants.sol
โ โโโ 11-LearnRequire.sol
โ โโโ 12-LearnModifier.sol
โ โโโ 13-LearnEvents.sol
โ โโโ 14-LearnPayable.sol
โ โโโ 15-LearnSendETH.sol
โ โโโ 16-LearnScopes.sol
โ โโโ 17-LearnVisibility.sol
โ โโโ 18-LearnFunctionModifiers.sol
โ โโโ 19-LearnErrorHandling.sol
โ โโโ 20-LiskGarden.sol
โโโ README.md
โโโ REFLEKSI.md
Batas Waktu: Sebelum Sesi 2 (Minggu, 26 Oktober 2025)
๐ Ringkasan & Langkah Selanjutnyaโ
Pencapaian Hari Ini ๐โ
Modul 1: Evolusi Web & Blockchain
- โ Memahami Web1, Web2, Web3
- โ Fondasi blockchain
- โ Mekanisme konsensus
- โ Blockchain trilemma
Modul 2: Layer 2, Lisk & Wallet
- โ Memahami Layer 2
- โ Pengenalan Lisk
- โ Teknologi wallet
- โ Jenis-jenis akun
Modul 3: Sistem Gas
- โ Mekanika gas
- โ EIP-1559
- โ Keuntungan gas L2
- โ Siklus hidup transaksi
Modul 4: Praktik Solidity
- โ Tipe data dasar
- โ Struct & Enum
- โ Modifier & Event
- โ Fungsi payable
- โ Game LiskGarden lengkap ter-deploy!
Preview: Sesi 2 - Arsitektur Modular Smart Contractโ
Minggu, 26 Oktober 2025 (09:00-17:00 @ JURA Kemanggisan):
Topik:
- Standar Token ERC (ERC-20, ERC-721, ERC-1155)
- Inheritance & komposisi contract
- Library OpenZeppelin
- Pola proxy untuk contract yang dapat diupgrade
- Implementasi pola factory
- Sistem multi-contract
Proyek:
- Deploy token ERC-20 lengkap
- Buat koleksi NFT
- Bangun token factory
๐ Sumber Belajarโ
Link Penting:
Komunitas:
- Discord: Ethereum Jakarta
- Telegram: BlockDevID
- Twitter: @ethjkt
๐ Terima Kasih!โ
Selamat! Anda telah menyelesaikan Sesi 1 dari Kelas Rutin Batch IV.
Fondasi yang dibangun hari ini adalah batu loncatan untuk menjadi pengembang Web3 profesional.
Ingat:
"Setiap ahli dulunya pemula. Terus bangun, terus belajar!"
Sampai jumpa besok di Sesi 2! ๐
Kontak & Dukungan:
- Discord: Ethereum Jakarta
- Email: hello@ethjkt.com
- Twitter: @ethjkt
Dibuat dengan โค๏ธ untuk Kelas Rutin BlockDevID Batch IV Komunitas Ethereum Jakarta ยฉ 2025