Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (2024)

Learn how to make requests to the Chainlink Functions Decentralized Oracle Network (DON) and make any computation or API calls offchain. Chainlink Functions is available on several blockchains (see the supported networks page), but this guide uses Sepolia to simplify access to testnet funds. Complete the following tasks to get started with Chainlink Functions:

  • Set up your web3 wallet and fund it with testnet tokens.
  • Simulate a Chainlink Functions on the Chainlink FunctionsPlayground.
  • Send a Chainlink Functions request to the DON. The JavaScript source code makes an API call to the Star Wars API and fetches the name of a given character.
  • Receive the response from Chainlink Functions and parse the result.

Simulation

Before making a Chainlink Functions request from your smart contract, it is always a good practice to simulate the source code offchain to make any adjustments or corrections.

  1. Open the Functions playground.

  2. Copy and paste the following source code into the playground's code block.

    const characterId = args[0];const apiResponse = await Functions.makeHttpRequest({ url: `https://swapi.info/api/people/${characterId}/`,});if (apiResponse.error) { throw Error("Request failed");}const { data } = apiResponse;return Functions.encodeString(data.name);
  3. Under Argument, set the first argument to 1. You are going to fetch the name of the first Star Wars character.

  4. Click on Run code. Under Output, you should see Luke Skywalker.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (1)

Configure your resources

Configure your wallet

You will test on Sepolia, so you must have an Ethereum web3 wallet with enough testnet ETH and LINK tokens. Testnet ETH is the native gas fee token on Sepolia. You will use testnet ETH tokens to pay for gas whenever you make a transaction on Sepolia. On the other hand, you will use LINK tokens to pay the Chainlink Functions Decentralized Oracles Network (DON) for processing your request.

  1. Install the MetaMask wallet or other Ethereum web3 wallet.

  2. Set the network for your wallet to the Sepolia testnet. If you need to add Sepolia to your wallet, you can find the chain ID and the LINK token contract address on the LINK Token Contracts page.

    • Sepolia testnet and LINK token contract
  3. Request testnet LINK and ETH from faucets.chain.link/sepolia.

Deploy a Functions consumer contract on Sepolia

  1. Open the GettingStartedFunctionsConsumer.sol contract in Remix.

    Open in RemixWhat is Remix?

  2. Compile the contract.

  3. Open MetaMask and select the Sepolia network.

  4. In Remix under the Deploy & Run Transactions tab, select Injected Provider - MetaMask in the Environment list. Remix will use the MetaMask wallet to communicate with Sepolia.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (2)
  5. Click the Deploy button to deploy the contract. MetaMask prompts you to confirm the transaction. Check the transaction details to make sure you are deploying the contract to Sepolia.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (3)
  6. After you confirm the transaction, the contract address appears in the Deployed Contracts list. Copy the contract address and save it for later. You will use this address with a Functions Subscription.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (4)

Create a subscription

You use a Chainlink Functions subscription to pay for, manage, and track Functions requests.

  1. Go to functions.chain.link.

  2. Click Connect wallet:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (5)
  3. Read and accept the Chainlink Foundation Terms of Service. Then click MetaMask.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (6)
  4. Make sure your wallet is connected to the Sepolia testnet. If not, click the network name in the top right corner of the page and select Sepolia.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (7)
  5. Click Create Subscription:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (8)
  6. Provide an email address and an optional subscription name:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (9)
  7. The first time you interact with the Subscription Manager using your EOA, you must accept the Terms of Service (ToS). A MetaMask popup appears and you are asked to accept the ToS:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (10)
  8. After you approve the ToS, another MetaMask popup appears, and you are asked to approve the subscription creation:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (11)
  9. After the subscription is created, MetaMask prompts you to sign a message that links the subscription name and email address to your subscription:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (12) Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (13)

Fund your subscription

  1. After the subscription is created, the Functions UI prompts you to fund your subscription. Click Add funds:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (14)
  2. For this example, add 2 LINK and click Add funds:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (15)

Add a consumer to your subscription

  1. After you fund your subscription, add your consumer to it. Specify the address for the consumer contract that you deployed earlier and click Add consumer. MetaMask prompts you to confirm the transaction.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (16) Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (17)
  2. Subscription creation and configuration is complete. You can always see the details of your subscription again at functions.chain.link:

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (18)

Run the example

The example is hardcoded to communicate with Chainlink Functions on Sepolia. After this example is run, you can examine the code and see a detailed description of all components.

  1. In Remix under the Deploy & Run Transactions tab, expand your contract in the Deployed Contracts section.

  2. Expand the sendRequest function to display its parameters.

  3. Fill in the subscriptionId with your subscription ID and args with [1]. You can find your subscription ID on the Chainlink Functions Subscription Manager at functions.chain.link. The [1] value for args specifies which argument in the response will be retrieved.

  4. Click the transact button.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (19)
  5. Wait for the request to be fulfilled. You can monitor the status of your request on the Chainlink Functions Subscription Manager.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (20)
  6. Refresh the Functions UI to get the latest request status.

  7. After the status is Success, check the character name. In Remix, under the Deploy & Run Transactions tab, click the character function. If the transaction and request ran correctly, you will see the name of your character in the response.

    Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (21)

Chainlink Functions is capable of much more than just retrieving data. Try one of the Tutorials to see examples that can GET and POST to public APIs, securely handle API secrets, handle custom responses, and query multiple APIs.

Examine the code

Solidity code

// SPDX-License-Identifier: MITpragma solidity 0.8.19;import {FunctionsClient} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/FunctionsClient.sol";import {ConfirmedOwner} from "@chainlink/contracts/src/v0.8/shared/access/ConfirmedOwner.sol";import {FunctionsRequest} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/libraries/FunctionsRequest.sol";/** * Request testnet LINK and ETH here: https://faucets.chain.link/ * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/resources/link-token-contracts/ *//** * @title GettingStartedFunctionsConsumer * @notice This is an example contract to show how to make HTTP requests using Chainlink * @dev This contract uses hardcoded values and should not be used in production. */contract GettingStartedFunctionsConsumer is FunctionsClient, ConfirmedOwner { using FunctionsRequest for FunctionsRequest.Request; // State variables to store the last request ID, response, and error bytes32 public s_lastRequestId; bytes public s_lastResponse; bytes public s_lastError; // Custom error type error UnexpectedRequestID(bytes32 requestId); // Event to log responses event Response( bytes32 indexed requestId, string character, bytes response, bytes err ); // Router address - Hardcoded for Sepolia // Check to get the router address for your supported network https://docs.chain.link/chainlink-functions/supported-networks address router = 0xb83E47C2bC239B3bf370bc41e1459A34b41238D0; // JavaScript source code // Fetch character name from the Star Wars API. // Documentation: https://swapi.info/people string source = "const characterId = args[0];" "const apiResponse = await Functions.makeHttpRequest({" "url: `https://swapi.info/api/people/${characterId}/`" "});" "if (apiResponse.error) {" "throw Error('Request failed');" "}" "const { data } = apiResponse;" "return Functions.encodeString(data.name);"; //Callback gas limit uint32 gasLimit = 300000; // donID - Hardcoded for Sepolia // Check to get the donID for your supported network https://docs.chain.link/chainlink-functions/supported-networks bytes32 donID = 0x66756e2d657468657265756d2d7365706f6c69612d3100000000000000000000; // State variable to store the returned character information string public character; /** * @notice Initializes the contract with the Chainlink router address and sets the contract owner */ constructor() FunctionsClient(router) ConfirmedOwner(msg.sender) {} /** * @notice Sends an HTTP request for character information * @param subscriptionId The ID for the Chainlink subscription * @param args The arguments to pass to the HTTP request * @return requestId The ID of the request */ function sendRequest( uint64 subscriptionId, string[] calldata args ) external onlyOwner returns (bytes32 requestId) { FunctionsRequest.Request memory req; req.initializeRequestForInlineJavaScript(source); // Initialize the request with JS code if (args.length > 0) req.setArgs(args); // Set the arguments for the request // Send the request and store the request ID s_lastRequestId = _sendRequest( req.encodeCBOR(), subscriptionId, gasLimit, donID ); return s_lastRequestId; } /** * @notice Callback function for fulfilling a request * @param requestId The ID of the request to fulfill * @param response The HTTP response data * @param err Any errors from the Functions request */ function fulfillRequest( bytes32 requestId, bytes memory response, bytes memory err ) internal override { if (s_lastRequestId != requestId) { revert UnexpectedRequestID(requestId); // Check if request IDs match } // Update the contract's state variables with the response and any errors s_lastResponse = response; character = string(response); s_lastError = err; // Emit an event to log the response emit Response(requestId, character, s_lastResponse, s_lastError); }}

Open in RemixWhat is Remix?

  • To write a Chainlink Functions consumer contract, your contract must import FunctionsClient.sol and FunctionsRequest.sol. You can read the API references: FunctionsClient and FunctionsRequest.

    These contracts are available in an NPM package so that you can import them from within your project.

    import {FunctionsClient} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/FunctionsClient.sol";import {FunctionsRequest} from "@chainlink/contracts/src/v0.8/functions/v1_0_0/libraries/FunctionsRequest.sol";
  • Use the FunctionsRequest.sol library to get all the functions needed for building a Chainlink Functions request.

    using FunctionsRequest for FunctionsRequest.Request;
  • The latest request ID, latest received response, and latest received error (if any) are defined as state variables:

    bytes32 public s_lastRequestId;bytes public s_lastResponse;bytes public s_lastError;
  • We define the Response event that your smart contract will emit during the callback

    event Response(bytes32 indexed requestId, string character, bytes response, bytes err);
  • The Chainlink Functions router address and donID are hardcoded for Sepolia. Check the supported networks page to try the code sample on another testnet.

  • The gasLimit is hardcoded to 300000, the amount of gas that Chainlink Functions will use to fulfill your request.

  • The JavaScript source code is hardcoded in the source state variable. For more explanation, read the JavaScript code section.

  • Pass the router address for your network when you deploy the contract:

    constructor() FunctionsClient(router)
  • The two remaining functions are:

    • sendRequest for sending a request. It receives the subscription ID and list of arguments to pass to the source code. Then:

      • It uses the FunctionsRequest library to initialize the request and add the source code and arguments. You can read the API Reference for Initializing a request and adding arguments.

        FunctionsRequest.Request memory req;req.initializeRequestForInlineJavaScript(source);if (args.length > 0) req.setArgs(args);
      • It sends the request to the router by calling the FunctionsClient sendRequest function. You can read the API reference for sending a request. Finally, it stores the request id in s_lastRequestId and returns it.

        s_lastRequestId = _sendRequest( req.encodeCBOR(), subscriptionId, gasLimit, jobId);return s_lastRequestId;

        Note: _sendRequest accepts requests encoded in bytes. Therefore, you must encode it using encodeCBOR.

  • fulfillRequest to be invoked during the callback. This function is defined in FunctionsClient as virtual (read fulfillRequest API reference). So, your smart contract must override the function to implement the callback. The implementation of the callback is straightforward: the contract stores the latest response and error in s_lastResponse and s_lastError, parses the response from bytes to string to fetch the character name before emitting the Response event.

    s_lastResponse = response;character = string(response);s_lastError = err;emit Response(requestId, s_lastResponse, s_lastError);

JavaScript code

const characterId = args[0];const apiResponse = await Functions.makeHttpRequest({ url: `https://swapi.info/api/people/${characterId}/`,});if (apiResponse.error) { throw Error("Request failed");}const { data } = apiResponse;return Functions.encodeString(data.name);

This JavaScript source code uses Functions.makeHttpRequest to make HTTP requests. The source code calls the https://swapi.info/ API to request a Star Wars character name. If you read the Functions.makeHttpRequest documentation and the Star Wars API documentation, you notice that URL has the following format where $characterId is provided as parameter when making the HTTP request:

url: `https://swapi.info/api/people/${characterId}/`

To check the expected API response for the first character, you can directly paste the following URL in your browser https://swapi.info/api/people/1/ or run the curl command in your terminal:

curl -X 'GET' \ 'https://swapi.info/api/people/1/' \ -H 'accept: application/json'

The response should be similar to the following example:

{ "name": "Luke Skywalker", "height": "172", "mass": "77", "hair_color": "blond", "skin_color": "fair", "eye_color": "blue", "birth_year": "19BBY", "gender": "male", "homeworld": "https://swapi.info/api/planets/1/", "films": [ "https://swapi.info/api/films/1/", "https://swapi.info/api/films/2/", "https://swapi.info/api/films/3/", "https://swapi.info/api/films/6/" ], "species": [], "vehicles": ["https://swapi.info/api/vehicles/14/", "https://swapi.info/api/vehicles/30/"], "starships": ["https://swapi.info/api/starships/12/", "https://swapi.info/api/starships/22/"], "created": "2014-12-09T13:50:51.644000Z", "edited": "2014-12-20T21:17:56.891000Z", "url": "https://swapi.info/api/people/1/"}

Now that you understand the structure of the API. Let's delve into the JavaScript code. The main steps are:

  • Fetch characterId from args. Args is an array. The characterId is located in the first element.
  • Make the HTTP call using Functions.makeHttpRequest and store the response in apiResponse.
  • Throw an error if the call is not successful.
  • The API response is located at data.
  • Read the name from the API response data.name and return the result as a buffer using the Functions.encodeString helper function. Because the name is a string, we use encodeString. For other data types, you can use different data encoding functions.Note: Read this article if you are new to Javascript Buffers and want to understand why they are important.
Blockchain Oracles for Connected Smart Contracts | Chainlink Documentation (2024)
Top Articles
Does A Will Override A Beneficiary On A Bank Account?
Why Men Pull Away And Then Come Back
Katie Pavlich Bikini Photos
Gamevault Agent
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Free Atm For Emerald Card Near Me
Craigslist Mexico Cancun
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Doby's Funeral Home Obituaries
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Select Truck Greensboro
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Craigslist In Flagstaff
Shasta County Most Wanted 2022
Energy Healing Conference Utah
Testberichte zu E-Bikes & Fahrrädern von PROPHETE.
Aaa Saugus Ma Appointment
Geometry Review Quiz 5 Answer Key
Walgreens Alma School And Dynamite
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Dmv In Anoka
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Pixel Combat Unblocked
Umn Biology
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Rogold Extension
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Weekly Math Review Q4 3
Facebook Marketplace Marrero La
Nobodyhome.tv Reddit
Topos De Bolos Engraçados
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hampton In And Suites Near Me
Stoughton Commuter Rail Schedule
Bedbathandbeyond Flemington Nj
Free Carnival-themed Google Slides & PowerPoint templates
Otter Bustr
Selly Medaline
Latest Posts
Article information

Author: Rev. Leonie Wyman

Last Updated:

Views: 5958

Rating: 4.9 / 5 (79 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Rev. Leonie Wyman

Birthday: 1993-07-01

Address: Suite 763 6272 Lang Bypass, New Xochitlport, VT 72704-3308

Phone: +22014484519944

Job: Banking Officer

Hobby: Sailing, Gaming, Basketball, Calligraphy, Mycology, Astronomy, Juggling

Introduction: My name is Rev. Leonie Wyman, I am a colorful, tasty, splendid, fair, witty, gorgeous, splendid person who loves writing and wants to share my knowledge and understanding with you.