← Semua pembelajaran / Blockchain Nol → RWA
Fase 0 · Fondasi Kriptografi & Struktur Data

Hash function — SHA-256 & Keccak-256

Sebelum menyentuh Solidity sekalipun, kamu perlu paham satu operasi yang dipakai di hampir setiap baris data on-chain: hash. Bukan enkripsi, bukan kompresi — fungsi satu arah yang mengubah data sebesar apa pun jadi string tetap.

Intisari

  • Hash itu satu arah (tidak bisa dibalik), deterministik (input sama → output sama selalu), dan panjang keluarannya tetap berapa pun ukuran inputnya.
  • Ethereum memakai Keccak-256, bukan SHA3-256 standar NIST — meski keduanya sering disebut tertukar. Paddingnya beda, hasilnya beda.
  • Avalanche effect: ubah satu bit input, sekitar separuh bit output ikut berubah. Ini yang membuat hash berguna untuk deteksi perubahan data sekecil apa pun.
  • Address akun Ethereum diturunkan dari hash public key — bukan angka acak yang didaftarkan ke server mana pun.
  • Solidity: keccak256(abi.encodePacked(...)) adalah pola yang sangat umum, tapi encodePacked punya jebakan collision kalau kamu tidak hati-hati.

Bukan enkripsi — jangan tertukar

Pendatang dari dunia Web2 sering menyamakan hash dengan enkripsi. Bedanya mendasar: enkripsi bisa dibalik (dengan kunci yang benar), hash tidak bisa. Begitu data di-hash, tidak ada operasi apa pun — termasuk oleh pembuatnya sendiri — yang mengembalikan input asli dari outputnya.

SifatArtinyaKenapa penting di blockchain
Satu arah (one-way)Tidak ada fungsi balik dari hash ke inputPassword/private key bisa direpresentasikan tanpa membocorkan aslinya
DeterministikInput sama selalu hasil samaSemua node bisa memverifikasi hasil yang sama, tanpa koordinasi
Panjang tetapInput 1 byte atau 1 GB, output tetap 32 byte (Keccak-256)Header block bisa merepresentasikan jutaan transaksi dalam ukuran konstan
Avalanche effect1 bit input berubah → ~50% bit output berubahTidak ada pola yang bisa ditebak dari perubahan kecil
Collision-resistantSangat sulit menemukan dua input beda dengan hash samaHash bisa dipercaya sebagai "sidik jari" data

SHA-256 vs Keccak-256 — jebakan penamaan

Ini yang paling sering membingungkan orang yang datang dari dunia backend biasa. Bitcoin memakai SHA-256 (standar NIST, FIPS 180-4). Ethereum memakai fungsi yang di Solidity dipanggil keccak256 — dan ini bukan SHA3-256 yang juga distandarkan NIST (FIPS 202).

Ceritanya: Keccak adalah pemenang kompetisi SHA-3 milik NIST. Tapi sebelum distandarkan resmi, NIST mengubah skema padding-nya. Ethereum sudah lebih dulu mengadopsi Keccak versi asli (pra-standardisasi), jadi keccak256(x) di Solidity menghasilkan nilai berbeda dari sha3_256(x) di pustaka kriptografi modern mana pun — meski algoritmanya nyaris identik.

Kalau kamu memverifikasi hash on-chain dari luar (Java/PHP), pastikan pustaka yang kamu pakai eksplisit menyediakan varian "Keccak" — bukan "SHA3". Di Java, ini berarti Bouncy Castle dengan digest "KECCAK-256", bukan "SHA3-256" dari java.security bawaan. Hash yang "hampir benar" akan lolos compile, lolos type-check, dan menghasilkan alamat atau selector yang salah tanpa satu pun error.

Ke mana saja Keccak-256 dipakai di Ethereum

Dipakai untukCaranya
Address akun20 byte terakhir dari keccak256(public_key)
Function selector4 byte pertama dari keccak256("transfer(address,uint256)")
Event topickeccak256 dari signature event, jadi topic pertama di log
Storage slot mappingkeccak256(key . slot) menentukan lokasi nilai mapping
Merkle Patricia TrieSetiap node trie diidentifikasi oleh hash kontennya sendiri

Memakai keccak256 di Solidity

// Menghitung function selector secara manual — inilah yang membuat
// ABI encoding "hanya" soal mencocokkan 4 byte pertama data transaksi.
bytes4 selector = bytes4(keccak256("transfer(address,uint256)"));

// Pola umum: hash gabungan beberapa nilai untuk jadi kunci unik
function buatId(address pemilik, uint256 nomor) public pure returns (bytes32) {
    return keccak256(abi.encodePacked(pemilik, nomor));
}

Jebakan abi.encodePacked. Fungsi ini menggabungkan byte tanpa padding maupun pemisah. Akibatnya encodePacked("ab", "c") menghasilkan byte yang sama persis dengan encodePacked("a", "bc") — dua pasangan dinamis (string/bytes) yang berbeda tapi hash-nya identik. Kalau kamu menghitung hash dari lebih dari satu nilai bertipe dinamis, pakai abi.encode (dengan padding) untuk mencegah collision jenis ini.

Menghitung hash dari luar rantai (Java & PHP)

Backend yang memverifikasi data on-chain sering perlu menghitung hash yang sama secara independen — misalnya memverifikasi bahwa payload yang ditandatangani belum diubah sebelum dikirim sebagai transaksi.

import org.web3j.crypto.Hash;
import org.web3j.utils.Numeric;

// web3j sudah menyediakan Keccak-256 yang BENAR — bukan SHA3-256 bawaan JDK
byte[] data = "halo dunia".getBytes();
String hashHex = Numeric.toHexString(Hash.sha3(data));
// Ekstensi kriptografi bawaan PHP (openssl, hash()) TIDAK punya Keccak-256 —
// hash('sha3-256', ...) di PHP adalah SHA3 standar NIST, bukan Keccak Ethereum.
// Perlu pustaka khusus, misalnya kornrunner/keccak:
$keccak = new \kornrunner\Keccak();
$hashHex = $keccak::hash('halo dunia', 256);

Latihan: hitung keccak256("transfer(address,uint256)") lewat Remix (fungsi pure sederhana), lalu bandingkan 4 byte pertamanya dengan selector yang muncul di tab "Method ID" saat kamu memanggil fungsi transfer token ERC-20 mana pun di Etherscan. Keduanya harus identik — itulah yang membuat node tahu fungsi mana yang kamu panggil hanya dari data mentah transaksi.

Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.