Kembali ke seri

Belajar Dasar Blochchain: Mengirim Coin

Transaksi On-Chain Pertama, Membedah Bukti Jaringan, dan Misteri Saldo

Daftar Isi

Sebelumnya, kita telah menghubungkan skrip ke node Sepolia Testnet dan memeriksa saldo koin uji coba gratis. Kali ini kita akan melakukan aksi sesungguhnya: mengirim transaksi transfer Sepolia ETH, membaca bukti transaksinya di Block Explorer, dan memahami bagaimana ribuan validator di dunia mencatat perubahan saldo tanpa database sentral.

Namun, sebelum menyentuh kode, mari bedah satu istilah yang paling sering dipakai di dunia Web3: apa itu sebenarnya On-Chain?


1. Pahami Dulu: Apa Beda “Blockchain”, “On-Chain”, dan “Off-Chain”?

Banyak pemula mengira kata blockchain dan on-chain adalah hal yang sama. Keduanya memiliki perbedaan posisi:

  • Blockchain adalah wadah/teknologinya (ibarat lembaran buku kas terdistribusi).
  • On-Chain adalah status aktivitas yang terjadi langsung di dalam wadah tersebut—diproses oleh validator, membayar biaya gas, dan tercatat permanen di dalam blok.
  • Off-Chain adalah aktivitas komputasi atau penyimpanan data yang terjadi di luar rantai blockchain (tanpa validator dan tanpa gas fee).

Untuk memahami kontrasnya, perhatikan contoh dunia nyata berikut:

SkenarioKategoriPenjelasan Teknis
Transfer saldo via CEX (Binance / Indodax)Off-ChainHanya mengubah angka di database internal (PostgreSQL/MySQL) milik perusahaan. Jaringan blockchain tidak pernah memproses transaksi ini.
Transfer koin via kode skrip / wallet pribadiOn-ChainDitandatangani dengan private key, divalidasi validator, membayar gas, dan tercatat permanen di block explorer.
Trading di CEX vs DEX (Uniswap)CEX = Off-Chain


DEX = On-Chain | Di DEX, order swap dieksekusi langsung oleh kode Smart Contract di atas jaringan blockchain, bukan di server internal perusahaan. | | File Gambar NFT (JPG/PNG) | Off-Chain | Menyimpan file gambar 10 MB langsung di blockchain memakan biaya gas yang luar biasa mahal. Gambar disimpan off-chain (di web server biasa atau IPFS), sedangkan yang dicatat on-chain hanyalah sertifikat kepemilikannya. |

Karena skrip yang kita bangun memicu tanda tangan kriptografi dan menyiarkan data ke validator Sepolia, aktivitas kita disebut transaksi On-Chain.


2. Anatomi Kode: Mengirim Sepolia ETH dengan Bun & Viem

Untuk mengubah state (data) di blockchain, transaksi wajib ditandatangani (digitally signed) menggunakan Private Key. Di pustaka viem, fungsi ini dijalankan oleh createWalletClient.

Buat file baru bernama send-transaction.ts:

import { 
  createPublicClient, 
  createWalletClient, 
  http, 
  parseEther, 
  formatEther 
} from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { sepolia } from 'viem/chains';

// 1. Inisialisasi Akun Pengirim (Private Key dari Artikel 1)
// PERINGATAN: Jangan pernah menaruh private key wallet mainnet uang riil di dalam kode!
const SENDER_PRIVATE_KEY = '0xMASUKKAN_PRIVATE_KEY_SEPOLIA_ANDA';
const senderAccount = privateKeyToAccount(SENDER_PRIVATE_KEY as `0x${string}`);

// 2. Alamat Tujuan Transfer
const RECIPIENT_ADDRESS = '0x000000000000000000000000000000000000dEaD'; // Alamat burn/uji coba

const transport = http('https://ethereum-sepolia-rpc.publicnode.com');

const publicClient = createPublicClient({ chain: sepolia, transport });
const walletClient = createWalletClient({ 
  account: senderAccount, 
  chain: sepolia, 
  transport 
});

async function main() {
  console.log("==========================================");
  console.log("🚀 MENYIAPKAN TRANSAKSI ON-CHAIN");
  console.log("==========================================\n");
  
  const balance = await publicClient.getBalance({ address: senderAccount.address });
  console.log(`👤 Pengirim   : ${senderAccount.address}`);
  console.log(`💰 Saldo Awal : ${formatEther(balance)} SepoliaETH`);

  // Konversi 0.001 ETH ke Wei (10^15 Wei)
  const amountToSend = parseEther('0.001');

  if (balance < amountToSend) {
    throw new Error("Saldo tidak mencukupi untuk transfer + gas fee!");
  }

  console.log(`\n📤 Mengirim 0.001 SepoliaETH ke: ${RECIPIENT_ADDRESS}...`);

  // Menandatangani & menyiarkan transaksi ke jaringan
  const hash = await walletClient.sendTransaction({
    to: RECIPIENT_ADDRESS,
    value: amountToSend,
  });

  console.log(`\n✅ Transaksi berhasil disiarkan!`);
  console.log(`🔗 Transaction Hash : ${hash}`);
  console.log("⏳ Menunggu konfirmasi blok validator...");

  // Menunggu transaksi resmi masuk ke blok on-chain
  const receipt = await publicClient.waitForTransactionReceipt({ hash });

  console.log(`\n🎉 Transaksi On-Chain Sukses!`);
  console.log(`📦 Nomor Block      : ${receipt.blockNumber}`);
  console.log(`⛽ Gas Digunakan    : ${receipt.gasUsed.toString()} units`);
  console.log(`🌐 Cek Bukti di     : https://sepolia.etherscan.io/tx/${hash}`);
  console.log("==========================================");
}

main();

Jalankan menggunakan Bun:

bun run send-transaction.ts

Salin tautan Sepolia Etherscan yang muncul di terminal dan buka di browser. Di sanalah bukti transaksi on-chain Anda tersimpan. Contoh bukti transaksi dapat dilihat di sini https://sepolia.etherscan.io/tx/0x06bb817e1c05453e8eef667810fd5c0b3b1b53e7448b530bce55fe72b6ef3068


3. Membedah Bukti Transaksi di Etherscan

Saat membuka detail transaksi di Block Explorer, Anda akan melihat rincian teknis seperti ini:

Transaction Hash: 0xb9845f2c9b1e...[cite: 2]
Status:           Success[cite: 2]
Block:            11784109 (19 Block Confirmations)[cite: 2]
From:             0x6Cc9397c... (Alamat Faucet Pengirim)[cite: 2]
To:               0xAD3db351... (Alamat Anda)[cite: 2]
Value:            0.05225 ETH[cite: 2]
Gas Limit:        30,000 | Gas Used: 21,000 (70%)[cite: 2]
Gas Price:        3.080583463 Gwei[cite: 2]
Gas Fees:         Base: 1.0805 Gwei | Max: 500 Gwei | Max Priority: 2 Gwei[cite: 2]
Burnt Fees:       0.00002269 ETH[cite: 2]
Txn Type:         2 (EIP-1559)[cite: 2]
Nonce:            5587641[cite: 2]
Input Data:       0x[cite: 2]

Berikut penjelasannya satu per satu:

  1. **Block: 11784109 & Block Confirmations**: Transaksi Anda resmi disegel ke dalam blok nomor 11784109. Angka konfirmasi menunjukkan berapa banyak blok baru yang telah ditumpuk di atas blok ini sejak transaksi disahkan. Semakin bertambah blok di atasnya, semakin permanen dan mustahil transaksi tersebut dibatalkan.

  2. Gas Limit vs Gas Used (21,000): Pengirim menyiapkan pagu cadangan gas hingga 30.000 unit, tetapi operasi transfer ETH standar antar-akun selalu memakan biaya komputasi tetap: tepat 21.000 unit gas. Sisanya otomatis dikembalikan ke akun pengirim.

  3. Txn Type: 2 (EIP-1559) & Rincian Gas: Format transaksi modern Ethereum. Biaya gas tidak memakai lelang buta acak, melainkan dipecah menjadi:

  • Base Fee: Tarif minimum per unit gas yang dipatok jaringan dan wajib dibakar/dihancurkan (Burnt Fees) dari peredaran.

  • Max Priority Fee: Tip sukarela untuk validator.

  • Max Fee: Batas biaya maksimal yang rela dibayar pengirim.

  1. Nonce: Nomor urut transaksi keluar dari akun pengirim. Nonce mencegah serangan penggandaan transaksi (replay attack).

  2. Input Data: 0x: Bernilai kosong. Ini menandakan transaksi tersebut adalah transfer native biasa, bukan pemanggilan logika komputasi pada smart contract.


4. Memahami “Block”: Struktur Data Logis, Bukan Server Fisik

Sering muncul salah kaprah bagi software engineer: apakah “Block” itu mesin server fisik seperti node di Kubernetes (K8s)?

Jawabannya: Bukan.

  • Node di blockchain itulah yang setara dengan Worker Node di K8s (komputer server fisik/VPS yang menjalankan software).
  • Block adalah struktur data logis (objek JSON / struct) yang diproses, divalidasi, dan disimpan ke hard disk oleh node tersebut.

Analogi Sederhana: Git Commit

Jika Anda terbiasa dengan Git:

  • Komputer Anda yang menjalankan program git adalah Node.
  • Satu kali Anda menjalankan git commit -m "kirim saldo" adalah sebuah Block.
  • Riwayat rantai commit dari awal sampai akhir (git log) adalah Blockchain.

Bentuk Kode di Balik Block #11784109

Di balik layar engine Ethereum (seperti Hyperledger Besu atau Geth), sebuah blok di hard disk validator terlihat seperti objek data berikut:

{
  "header": {
    "number": 11784109,
    "parentHash": "0xabc123... (hash blok 11784108)",
    "timestamp": 1727328024,
    "stateRoot": "0x567def... (akar hash status saldo global)",
    "feeRecipient": "0x3826539Cbd8d68DCF119e80B994557B4278CeC9f",
    "gasUsed": 18762704,
    "gasLimit": 60000000
  },
  "transactions": [
    { "from": "0x6Cc9397c...", "to": "0xAD3db351...", "value": "0.05225 ETH" },
    { "from": "0x11111111...", "to": "0x22222222...", "value": "1.5 ETH" }
    // ... total ada 175 transaksi di dalam array ini
  ]
}

Jika kita telusuri halaman explorer pada blok nomor 11784109 di atas:

  • Block Height: 11784109: Nomor urut lembaran log sejak Genesis Block (blok ke-0).

  • Status: Finalized: Blok ini sudah melewati konsensus Proof-of-Stake dan terkunci permanen.

  • Transactions: 175 transactions: Validator tidak memproses transaksi satu per satu secara terpisah ke jaringan. 175 transaksi dari berbagai orang di dunia dikemas sekaligus ke dalam satu blok ini.

  • Fee Recipient: Alamat validator yang mengumpulkan dan memverifikasi blok ini.

  • Block Reward: 0.0302... ETH: Koin baru yang dicetak otomatis oleh protokol sebagai imbalan bagi validator.

  • Extra Data: besu 26.7-develop...: Identitas perangkat lunak node yang dipakai oleh server validator tersebut.


5. Jika Bank Punya Database, di Mana Saldo Dompet Kita Dicatat?

Banyak pemula beranggapan koin tersimpan di dalam file private key atau aplikasi wallet. Itu keliru.

Dompet Anda hanya menyimpan gantungan kunci kriptografi (private key). Koin Anda sebenarnya dicatat di dalam World State:

  • Setiap komputer validator di dunia menjalankan software node (seperti Besu atau Geth). Di hard disk komputer validator terdapat database key-value lokal (umumnya berbasis LevelDB atau PebbleDB).

  • Database ini mencatat tabel akun global (Merkle Patricia Trie):

Alamat 0xAD3db... => { nonce: 0, balance: 52250000000000000 Wei }
  • Saat transaksi di blok 11784109 tadi disahkan, seluruh validator di dunia secara serempak mengupdate database di disk masing-masing: saldo pengirim dipotong, dan saldo alamat Anda bertambah. Konsensus protokol memastikan data di ribuan validator selalu identik tanpa server pusat.

6. Dari Mana Asal Koin? (Coin vs Token & Max Supply)

Mengapa saldo koin bisa bertambah dari ketiadaan saat blok disahkan? Mengapa ada koin yang suplainya dibatasi dan ada yang tidak?

A. Bagaimana “Coin” Diciptakan?

Koin native (seperti ETH di Ethereum atau BTC di Bitcoin) tidak dibuat oleh smart contract, melainkan dicetak langsung oleh aturan matematika konsensus protokol:

  • Setiap kali blok baru valid, aturan kode protokol otomatis menambahkan angka saldo validator dengan koin baru (Block Reward).

  • Koin ini tidak ditarik dari rekening siapa pun; sebelum blok itu sah, koin tersebut memang belum pernah ada. Inilah mekanisme inflasi/emisi awal koin lahir.

B. Perbedaan Coin vs Token

  • Coin (Native): Mata uang bawaan layer-1 blockchain (ETH, SOL, NEAR). Fungsinya tertanam di level protokol inti untuk membayar biaya komputasi gas.
  • Token (Smart Contract): Buku kas mini buatan pengembang yang menumpang di atas blockchain (seperti USDT, USDC, atau token governance dApp). Token hanyalah program aplikasi yang mencatat daftar pemegang saldo.

C. Max Supply Tetap vs Supply Dinamis (Unlimited)

Di platform data pasar kripto, terdapat perbedaan model suplai aset:

Model SuplaiContoh AsetCara Kerja di Level Kode
Max Supply TerbatasBitcoin (21 Juta BTC), XRP (100 Miliar XRP)

| Dibatasi mutlak di kode. Bitcoin memangkas pencetakan koin tiap 4 tahun (Halving) hingga berhenti total di angka 21 juta. XRP mencetak seluruh 100 miliar koin di blok pertama tanpa ada fungsi cetak lagi. Tujuannya menjaga kelangkaan mutlak (digital scarcity).

| | Supply Dinamis (Unlimited) | Ethereum (ETH), Solana (SOL)

| Tidak memiliki angka pagu atas. Koin terus dicetak dalam persentase terukur untuk mendanai validator. Di Ethereum, ada mekanisme pembakaran Base Fee (EIP-1559): jika jaringan sedang padat transaksi, jumlah koin yang dibakar bisa melebihi koin baru yang dicetak, membuat total suplai menyusut secara otomatis.

|


7. Rangkuman Siklus Transaksi On-Chain

[Skrip TypeScript menandatangani tx] 
                 │
                 ▼
     [Siarkan ke Mempool via RPC]
                 │
                 ▼
[Validator merangkai transaksi ke dalam Block][cite: 3]
                 │
                 ▼
[Block Reward dicetak & Base Fee dibakar][cite: 2, 3]
                 │
                 ▼
[World State di database validator diupdate serentak][cite: 2, 3]
                 │
                 ▼
   [Transaksi On-Chain Finalized di Explorer][cite: 2, 3]

8. Checklist Screenshot untuk Dilampirkan di Artikel

  1. Screenshot 1: Terminal Output Eksekusi Transaksi
  • Yang ditampilkan: Jendela terminal saat bun run send-transaction.ts berjalan mulus hingga mencetak Hash transaksi, nomor blok, dan unit gas.
  • Penempatan: Di bawah Bagian 2.
  1. Screenshot 2: Rincian Transaksi di Sepolia Etherscan
  • Yang ditampilkan: Halaman sepolia.etherscan.io/tx/0x... yang memperlihatkan Status Success, Block Confirmation, Gas Used (21,000), dan Burnt Fees.

  • Penempatan: Di Bagian 3.

  1. Screenshot 3: Detail Block di Sepolia Etherscan
  • Yang ditampilkan: Halaman sepolia.etherscan.io/block/11784109 yang memperlihatkan Block Height, Status Finalized, Transactions Count (175), dan Block Reward.

  • Penempatan: Di Bagian 4.

  1. Screenshot 4: Tabel Perbandingan Suplai (CoinMarketCap)
  • Yang ditampilkan: Tangkapan layar tabel pasar yang memperlihatkan perbedaan bar suplai (BTC/XRP yang ada Max Supply vs ETH/SOL yang dinamis).

  • Penempatan: Di Bagian 6 (Subbagian C).


9. Sumber Belajar & Referensi Resmi


Langkah Selanjutnya

Mengirim koin native (Sepolia ETH) telah kita selesaikan. Menariknya, blockchain bukan sekadar mesin kirim-terima koin, melainkan sebuah “World Computer” tempat kita bisa memasang (deploy) aplikasi logika independen yang disebut Smart Contract.

Di Artikel 4, kita akan melangkah ke dunia komputasi tersebut: memahami konsep EVM, membedah ABI (Application Binary Interface), dan membaca data token ERC-20 langsung dari kode TypeScript kita.