Skip to main content

Chainlink Oracle

Introduction

Developers can now use Chainlink's decentralized Oracle network to fetch data in the Pangolin TestNet. This tutorial goes through two different ways of using Chainlink Oracles:

  • Basic Request Model, where the end-user sends a request to an Oracle provider, which fetches the data through an API, and fulfils the request storing this data on-chain
  • Price Feeds, where data is continuously updated by Oracle operators in a smart contract so that other smart contracts can fetch it

Basic Request Model

Before we go into fetching the data itself, it is important to understand the basics of the "basic request model."

An Oracle node has a set of job IDs, where each corresponds to a task that can be requested by a user, for example, fetch a price feed. To do so, the user needs to send a request through a contract, we'll name it the Client contract, passing in the following information:

  • Oracle address: address of the contract deployed by the Oracle node
  • Job ID: task to be executed
  • Payment: payment in LINK tokens that the Oracle will receive for fulfiling the request

This request actually sends a transferAndCall to the LINK token contract, which handles the payment and relays the request to the Oracle contract. Here, an event is emited with the request, which is picked up by the Oracle node. Next, the node fetches the necessary data and executes the fulfilOracleRequest function, which executes a callback that stores the requested information in the Client contract. The following diagram explains this workflow.

Basic Request Diagram

The Client Contract

The Client contract is the element that starts the communication with the Oracle by sending a request. As shown in the diagram, it calls the transferAndCall method from the LINK token contract, but there is more processing that is needed to track the request to the Oracle. For this example, you can use the code in this file, and deploy it on Remix to try it out. Let's look at the core functions of the contract:

  • constructor: runs when the contract is deployed. It sets the address of the LINK token and the owner of the contract
  • requestPrice: needs the Oracle contract address, the job ID, and the payment (in LINK) tokens to the fulfiller of the request. Builds the new request that is sent using the sendChainlinkRequestTo function from the ChainlinkClient.sol import
  • fulfill: callback used by the Oracle node to fulfill the request by storing the queried information in the contract
pragma solidity 0.6.6;

import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.6/ChainlinkClient.sol";
/**
* @title Client based in ChainlinkClient
* @notice End users can deploy this contract to request the Prices from an Oracle
*/
contract Client is ChainlinkClient {
//... there is mode code here

// Deploy with the address of the LINK token
constructor(address _link) public {
// Set the address for the LINK token for the network
setChainlinkToken(_link);
owner = msg.sender;
}

// Creates Chainlink Request
function requestPrice(address _oracle, string memory _jobId, uint256 _payment)
public
onlyOwner
{
// newRequest takes a JobID, a callback address, and callback function as input
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), address(this), this.fulfill.selector);
// Sends the request with the amount of payment specified to the oracle
sendChainlinkRequestTo(_oracle, req, _payment);
}

// Callback function called by the Oracle when it has resolved the request
function fulfill(bytes32 _requestId, uint256 _price)
public
recordChainlinkFulfillment(_requestId)
{
currentPrice = _price;
}

//... there is more code here

Note that the Client contract must have a LINK tokens balance to be able to pay for this request. However, if you deploy your setup, you can set the LINK value to 0 in your ChainlinkClient.sol contract, but you still need to have the LINK token contract deployed.

Try it on Pangolin

If you want to skip the hurdles of deploying all contracts, setting up your Oracle node, creating job IDs, and so on, we've got you covered.

A custom Client contract on Pangolin that makes all requests to our Oracle contract, with a 0 LINK token payment, is available. These requests are fulfilled by an Oracle node that we are running. You can try it out with the following interface contract and the custom Client contract deployed at 0xab8eC6D46717a2CC91f4394F253a52E9719e308f:

pragma solidity 0.6.6;

/**
* @title Simple Interface to interact with Universal Client Contract
* @notice Client Address 0xab8eC6D46717a2CC91f4394F253a52E9719e308f
*/
interface ChainlinkInterface {

/**
* @notice Creates a Chainlink request with the job specification ID,
* @notice and sends it to the Oracle.
* @param _oracle The address of the Oracle contract fixed top
* @param _jobId The job spec ID that we want to call in string format
* @param _payment For this example the PAYMENT is set to zero
*/
function requestPrice(address _oracle, string calldata _jobId, uint256 _payment) external;

function currentPrice() external view returns (uint);

}

This provides two functions. requestPrice() needs the job ID of the data you want to query. This function starts the chain of events explained before. currentPrice() is a view function that returns the latest price stored in the contract.

Currently, the Oracle node has a set of Job IDs for different price datas for the following pairs:

Base/QuoteJob ID Reference
RING to USD4cda609794884c58a8690d402e80bfea
BTC to USD66f0d2a59b82482799bee1e714d94991
ETH to USD8f032a4cf422438b835f243b96ecfc7a
DOT to USDfd5e3c79e83344d5a6c3de75501a4c54
KSM to USDdd3a14692e68435da5b28b8716d06423
AAVE to USD764e831e1d30420ca52aab23c6489319
ALGO to USD5fa0cb97996f4e5cbe5954c09c3544b3
BAND to USDb494823291974e50bc5d8c6466a18b38
LINK to USDbf322091c7d44d418761754d367534d4
SUSHI to USD5e47777ecc664801a64bd4b23c5e912c
UNI to USDea3111fdc33e4a9c9af8dd0ede87b279

Let's go ahead and use the interface contract with the BTC to USD Job ID in Remix.

After creating the file and compiling the contract, head to the "Deploy and Run Transactions" tab, enter the Client contract address, and click on "At Address." Make sure you have set the "Environment" to "Injected Web3" so you are connected to Pangolin. This will create an instance of the Client contract that you can interact with. Use the function requestPrice() to query the data of the corresponding Job ID. Once the transaction is confirmed, we have to wait until the whole process explained before occurs. We can check the price using the view function currentPrice().

Chainlink Basic Request on Pangolin

If there is any specific pair you want us to include, feel free to reach out to us through our Telegram.

Run your Client Contract

If you want to run your Client contract but use our Oracle node, you can do so with the following information:

Contract TypeAddress
Oracle Contract0x97C02719aEf6B70f0abDa6402f9Bb136aFF7043d
LINK Token0xbE872fFa86274E9717884394f088C02EE929c18d

Remember that the LINK token payment is set to zero.

Other Requests

Chainlink's Oracles can tentatively provide many different types of data feeds with the use of external adapters. However, for simplicity, our Oracle node is configured to deliver only price feeds.

If you are interested in running your own Oracle node in Pangolin, please visit this guide. Also, we recommend going through Chainlink's documentation site.