NEW

CCIP is now live for all developers. See what's new.

Back

Deploy and Interact with a Consumer Contract using Starknet Foundry

This example uses a local OpenZeppelin account to deploy and interact with a consumer contract onchain. This contract retrieves data from a specified Chainlink data feed on Starknet Sepolia and stores the information for the latest round of data.

Requirements

Set up your environment

This guide uses the Starknet Foundry toolkit and the Scarb project management tool so you can compile, deploy, and interact with your Starknet smart contracts.

  • Starknet Foundry: Install Starknet Foundry v0.21.0. You can check your current version by running snforge --version or sncast --version in your terminal and install the required version if necessary.

  • Scarb: Install Scarb v2.6.4. You can check your current version by running scarb --version in your terminal and install the required version if necessary.

Alternatively, you can use the asdf tool version manager to install both Starknet Foundry and Scarb. Read the setup instructions for Starknet Foundry and Scarb for more information.

Clone and configure the code examples repository

  1. Clone the chainlink-starknet repository, which includes the example contracts for this guide:

    git clone https://github.com/smartcontractkit/chainlink-starknet.git
    
  2. Navigate to the aggregator_consumer directory:

    cd chainlink-starknet/examples/contracts/aggregator_consumer/
    

After you prepare the requirements, check to make sure the required tools are configured correctly by running the tests:

make test

The contracts should compile successfully and the tests should pass.

Tutorial

Create, deploy, and fund an account

  1. Run the create-account script to create a new OpenZeppelin local account for the Sepolia testnet:

    make create-account
    

    The account details are stored locally in your ~/.starknet_accounts/starknet_open_zeppelin_accounts.json file.

    Expect an output similar to the following:

    command: account create
    address: 0x3e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d
    max_fee: 9529927566560
    message: Account successfully created. Prefund generated address with at least <max_fee> tokens. It is good to send more in the case of higher demand.
    
    Your accounts:
    {
      "alpha-sepolia": {
        "testnet-account": {
          "address": "0x3e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d",
          "class_hash": "0x4c6d6cf894f8bc96bb9c525e6853e5483177841f7388f74a46cfda6f028c755",
          "deployed": false,
          "legacy": false,
          "private_key": <PRIVATE_KEY>,
          "public_key": "0x2972c3cb7aa85403fa1e038f9ce7a93f025ea57017eb7ef735bae989bfb15bd",
          "salt": "0x61a062d2dd4e7656"
        }
      }
    }
    

    From the output, note:

    • Your account address. In this example, it is 0x03e7ee3d05d3efae4e493c9733c8c391d4a5cc63d34f95a164c832060fcdd43d, with an added zero after 0x.
    • The max_fee value, which is the minimum amount of testnet ETH required to deploy the account.
  2. Fund the newly created account with testnet ETH to cover the account deployment, the consumer contract deployment, and the network interaction costs.

    Go to the Blast Starknet Sepolia ETH Faucet and enter your account address to receive testnet ETH. Wait a few seconds for the transaction to complete.

    Alternatively, you can transfer ETH tokens from a Starknet-compatible wallet, such as Argent or Braavos, or utilize the StarkGate bridge to transfer testnet ETH from Ethereum Sepolia to Starknet Sepolia. If you need testnet ETH on Ethereum Sepolia, you can use the Chainlink faucet.

  3. Deploy your account to Starknet Sepolia:

    make deploy-account
    

    Expect an output similar to the following:

    command: account deploy
    transaction_hash: 0x541ffae49f77dd942376391286052d9fb87dc8d6848139ab1508c114e3aa005
    

    Wait a few seconds for the transaction to complete.

Deploy and interact with a consumer contract

The consumer contract contains two functions that you'll interact with in this example:

  • set_answer retrieves the latest answer from the specified aggregator contract and stores it in the _answer internal storage variable.
  • read_answer reads the stored _answer value.
  1. Navigate to /scripts/src/consumer/ and open the deploy_aggregator_consumer script.

  2. Update the aggregator_address variable within the main function with the ETH / USD Chainlink proxy aggregator contract address on Starknet Sepolia : 0x228128e84cdfc51003505dd5733729e57f7d1f7e54da679474e73db4ecaad44.

  3. Run the deploy_aggregator_consumer script to deploy a consumer contract to Starknet Sepolia. Use the following command:

    make ac-deploy NETWORK=testnet
    

    Expect an output similar to the following:

    Declaring and deploying AggregatorConsumer
    Declaring contract...
    
    Class hash = 2231728956022539490111802723283413449895905447951536434260474920103409356221
    
    Deploying contract...
    Transaction hash = 0x46b39d79cf90ed75fbae5d097d6026cf7ab1184e852d36aed336528fc77220d
    Waiting for transaction to be accepted (59 retries / 295s left until timeout)
    
    AggregatorConsumer deployed at address: 2956260449156927152048242588422796467290585049226993045191257886158889626959
    
    command: script run
    status: success
    

    The consumer address is represented in its decimal form: 2956260449156927152048242588422796467290585049226993045191257886158889626959. You can use a converter tool to get the hexadecimal format. In this example, the hexadecimal equivalent is 0x06892f22691473dc5a413a7626062604155516ec91a82d3734dc68bcf3d72d4f. Save your consumer address for the next steps.

  4. In /scripts/src/consumer/, open the set_answer script and update the consumer_address variable with your deployed consumer address.

  5. Run the following command to update the answer:

    make ac-set-answer NETWORK=testnet
    

    This command runs the set_answer script to retrieve the latest answer from the ETH / USD aggregator contract and stores it in the internal storage variable _answer of your consumer contract.

    Expect an output similar to the following:

    Result::Ok(CallResult { data: [3374557091160001179079409876363576078229871685244120671563970051729036896526] })
    Result::Ok(CallResult { data: [340282366920938463463374607431768224268, 354661371569, 54349, 1711716556, 1711716514] })
    Transaction hash = 0x20edd6388041d78a36f153a7694fd8c0849d81aff3fc2d5a0606d7275ea4837
    Waiting for transaction to be accepted (59 retries / 295s left until timeout)
    Result::Ok(InvokeResult { transaction_hash: 930889525374955449815155593419397099236202282693723934594292211164864202807 })
    command: script run
    status: success
    
  6. In /scripts/src/consumer/, open the read_answer script and update the consumer_address variable with your deployed consumer address.

  7. Run the following command to read the stored answer value from your consumer contract:

    make ac-read-answer NETWORK=testnet
    

    Expect an output similar to the following:

    Result::Ok(CallResult { data: [354661371569] })
    command: script run
    status: success
    

    The answer on the ETH / USD feed uses 8 decimal places, so an answer of 354661371569 indicates an ETH / USD price of 3546.61371569. Each feed uses a different number of decimal places for answers. You can find the correct number of decimal places on the Price Feed addresses page by clicking the Show more details checkbox.

What's next

Stay updated on the latest Chainlink news