Belajar Solidity - Interaksi dengan Data & Oracles
Episode 13 of 23

Belajar Solidity - Interaksi dengan Data & Oracles

Menghubungkan kontrak pintar ke dunia luar: mengatasi oracle problem dengan Chainlink Price Feeds dan Chainlink VRF untuk randomness, membaca data off-chain dari event, indexing lewat subgraph The Graph, serta Chainlink Functions untuk komputasi off-chain

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

Pendahuluan

Setelah di episode 12 kalian membangun pola DeFi dasar — AMM, vault, dan interest model — pada episode ini kita menghadapi batasan fundamental kontrak pintar: kontrak tidak bisa mengakses internet.

Ini disebut oracle problem. Kontrak hanya tahu apa yang ada di blockchain: balance, timestamp, block number, dan state kontrak lain. Ia tidak bisa membuka browser, menelepon API cuaca, atau mengecek harga saham. Padahal banyak aplikasi — asuransi, prediksi pasar, lending dengan likuidasi — butuh data dunia nyata.

Mengapa episode ini penting? Karena cara data masuk ke kontrak menentukan keamanan dan kepercayaan protokol. Data yang bisa dimanipulasi satu titik (misal harga dari satu exchange) membuka celah eksploitasi. Memahami pola oracle yang benar adalah pembeda antara protokol yang survive dan yang dieksploitasi.

Solusi paling umum untuk harga aset adalah Chainlink Price Feeds: jaringan node independent yang mengagregasi harga dari banyak exchange, lalu mempublikasikannya ke kontrak aggregator di chain. Kontrak kalian tinggal membaca harga tersebut.

src/PriceConsumer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.36;
 
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
 
contract PriceConsumer {
    AggregatorV3Interface internal immutable priceFeed;
 
    constructor(address _aggregator) {
        priceFeed = AggregatorV3Interface(_aggregator);
    }
 
    function getEthPriceInUsd() external view returns (uint256) {
        (, int256 price, , uint256 updatedAt, ) = priceFeed.latestRoundData();
        require(block.timestamp - updatedAt < 1 hours, "feed sudah basi");
        return uint256(price) * 1e10; // konversi ke 18 decimals
    }
}

Poin penting dalam kode di atas:

  • latestRoundData() mengembalikan harga plus timestamp update.
  • Pengecekan block.timestamp - updatedAt < 1 hours adalah stale data check — jangan pernah pakai harga yang sudah lama tidak diupdate.
  • Feed yang dipakai harus dari daftar resmi Chainlink sesuai jaringan (misal ETH/USD di Sepolia punya alamat aggregator tertentu).

Warning

Jangan pernah menggunakan harga "bawaan" atau harga dari satu sumber tanpa agregasi. Kasus hack terbesar di DeFi umumnya memakai oracle manipulation — memanipulasi harga agar protokol memberi pinjaman/aset lebih dari seharusnya.

Kontrak tidak bisa memakai block.timestamp atau blockhash sebagai random — bisa diprediksi atau dimanipulasi oleh miner/validator. Chainlink VRF menyediakan random number yang verifiable:

src/RandomConsumer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.36;
 
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol";
 
contract RandomConsumer is VRFConsumerBaseV2Plus {
    uint256 public lastRandom;
 
    function requestRandom() external returns (uint256 requestId) {
        requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: 0xKEYHASH,
                subId: s_subscriptionId,
                requestConfirmations: 3,
                callbackGasLimit: 100_000,
                numWords: 1
            })
        );
    }
 
    function fulfillRandomWords(uint256, uint256[] calldata randomWords) internal override {
        lastRandom = randomWords[0];
    }
}

Alurnya asinkron: kalian request → node VRF menghasilkan bukti kriptografik → bukti diverifikasi on-chain → fulfillRandomWords dipanggil. Hasilnya tidak bisa diprediksi oleh siapa pun sebelum terpublikasi.

Tip

Pattern "commit-reveal" dan request-response asinkron seperti VRF adalah gaya interaksi umum di DeFi: fungsi kalian tidak langsung mendapat hasil, melainkan harus menunggu callback. Pahami pola asinkron ini — banyak integrasi oracle bekerja persis seperti itu.

Membaca Data Off-chain dari Event

Terkadang data "off-chain" sebenarnya bisa dibaca dari chain — yaitu lewat event log. Subgraph dan indexer menangkap event, mengolahnya, dan menyajikan data lewat query cepat:

Subgraph The Graph
query {
  swaps(first: 10, orderBy: timestamp, orderDirection: desc) {
    sender
    amount0In
    amount1Out
  }
}

Untuk DApp yang butuh riwayat, analytics, atau daftar user, The Graph jauh lebih efisien daripada memindai block satu per satu. Pola ini kita kenalkan di episode 8 dan kini menjadi bagian dari arsitektur data produksi.

Chainlink Functions membawa komputasi off-chain (JavaScript) ke dalam alur kontrak — misalnya memanggil API, menjalankan logika kompleks, atau komputasi yang tidak mungkin di chain:

  • Upload script JS yang dieksekusi node off-chain.
  • Node mengambil data dari API mana pun, lalu mengembalikan hasil (dan bukti) ke kontrak.
  • Cocok untuk skenario "butuh data web + komputasi" tanpa membangun infra oracle sendiri.

Penggunaannya lebih mahal dan lebih spesifik; untuk mayoritas kasus, Price Feeds + VRF sudah cukup.

Pitfall Umum Oracle

  • Memakai harga stale — tanpa stale check, harga bisa sudah kedaluwarsa berjam-jam.
  • Satu sumber data — manipulasi harga di satu exchange memengaruhi protokol.
  • Randomness prediktabelblock.timestamp/blockhash bisa dimanipulasi.
  • Callback asinkron tanpa timeout — jika fulfill tidak pernah dipanggil, request user menggantung; rancang dengan timeout atau idempotent logic.

Penutup

Inti yang harus dibawa pulang:

  • Kontrak tidak bisa akses internet — inilah oracle problem.
  • Chainlink Price Feeds untuk harga teragregasi + selalu cek stale data.
  • Chainlink VRF untuk randomness verifiable yang tidak bisa diprediksi.
  • Data riwayat dibaca lewat event + subgraph; Chainlink Functions untuk komputasi off-chain.

Di episode 14 selanjutnya kita akan membahas upgradeable contracts & proxies — EIP-1967 untuk penyimpanan proxy, pola Transparent dan UUPS, plugin OpenZeppelin Upgrades, serta governance dengan timelock dan multi-sig Safe. Sampai jumpa di episode 14!

Belajar Solidity - Interaksi dengan Data & Oracles | Belajar Solidity