Using Data Feeds on StarkNet
StarkNet is a permissionless decentralized ZK-Rollup operating as an L2 network over Ethereum. Unlike other Ethereum L2 networks, StarkNet is not EVM-compatible and uses Cairo as its smart contract language. Chainlink Data Feeds are available on the StarkNet testnet as Cairo smart contracts.
You can read Chainlink Data Feeds on StarkNet using an on-chain contract that you compile and deploy. Alternatively, you can read the data feed off-chain without a StarkNet account. You can complete these steps using only the StarkNet CLI commands, but the example scripts demonstrate how to compile, deploy, and interact with StarkNet contracts programmatically. StarkNet.js, HardHat, and the StarkNet Hardhat Plugin simplify the processes, which normally require you to keep track of your class hashes and ABI files. See https://docs.starknet.io/ for more information about writing and compiling Cairo contracts for StarkNet.
For a complete list of Chainlink Price Feeds available on StarkNet testnet, see the Price Feed Contract Addresses page.
Set up your environment to run the examples.
Set up your local StarkNet environment. Note that a Python version in the
>=3.6 <=3.9range is required for compiling and deploying contracts on-chain. The
cairo-langPython package is not compatible with newer versions of Python as of the
cairo-lang0.10.3 package. Check starknet.io for the latest requirements.
Install NodeJS in the version in the
>=14 <=18version range.
Clone and configure the code examples:
Clone the smartcontractkit/chainlink-starknet repository, which includes the example contracts for this guide:
git clone https://github.com/smartcontractkit/chainlink-starknet.git
In your clone of the chainlink-starknet repository, change directories to the proxy consumer example:
If you want to run the on-chain examples, you must set up a StarkNet account on StarkNet's
alpha-goerlinetwork and fund it with testnet ETH. These examples expect the OpenZeppelin wallet, which stores your addresses and private keys in the following default path:
After you prepare the requirements, check to make sure the required tools are configured correctly:
starknet -v starknet 0.10.3
cairo-compile -v cairo-compile 0.10.3
node -v v18.12.1
yarn --version 1.22.19
Running the on-chain example
The on-chain proxy consumer example uses a local OpenZeppelin wallet as the account to deploy a contract on-chain. This contract reads a specified Chainlink data feed and stores the information for the latest round of data. This example has the following components:
- The example proxy_consumer.cairo contract: You will compile and deploy this example contract to the StarkNet Goerli testnet where it can read and store values from one of the data feed proxy contracts. The proxy address is defined in the constructor when you deploy the contract.
- The deployConsumer.ts script: This script uses StarkNet.js to identify your OpenZeppelin wallet and deploy the compiled contract.
- The readLatestRound.ts script: This script submits an invoke transaction on the
get_stored_roundfunction in your contract and prints the result.
Build, deploy, and invoke the example contract:
Find the account address and private key for your funded StarkNet testnet account. By default, the OpenZeppelin wallet contains these values at
Export your address to the
DEPLOYER_ACCOUNT_ADDRESSenvironment variable and your private key to the
yarn buildto run Hardhat and create
./starknet-artifacts/with the compiled contracts. The
@shardlabs/starknet-hardhat-pluginpackage handles the compile step.
yarn deployto deploy the example consumer contract to the StarkNet Goerli testnet. The deployment might take several minutes depending on network conditions. The console prints the contract address and transaction hash. Record the contract address.
yarn deploy yarn run v1.22.19 Contract address: 0x297d4d4e0dc667c82a452cf809176c50a3e3707408ce39d0f1a1a881d35a83f Transaction hash: 0x545bf14dd55447c95065092a142cdf240806a594af39e25fd283e3059131f7d Done in 110.04s.
yarn readLatestRound <CONTRACT_ADDRESS>to send an invoke transaction to the deployed contract. Specify the contract address printed by the deploy step. The deployed contract reads the latest round data from the proxy, stores the values, and prints the resulting values.
yarn readLatestRound 0x297d4d4e0dc667c82a452cf809176c50a3e3707408ce39d0f1a1a881d35a83f Invoking the get_latest_round_data function. Transaction hash: 0x44ce5582f0ae7d144fec2d47ffa879096f7b01a540d7b1d2169aa1fe3798d4f Waiting for transaction... Transaction status is: NOT_RECEIVED Transaction status is: RECEIVED Transaction status is: PENDING Transaction is: ACCEPTED_ON_L2 Stored values are: round_id = 3.402823669209385e+38 answer = 6 block_num = 613094 observation_timestamp = 1673365796 transmission_timestamp = 1673365809 Done in 99.10s.
If the invoke request is successful, you can see the stored values in the StarkScan testnet explorer. Search for your contract by the address. Under the Read Contract tab, run a query on the
get_stored_round() method. For example, you can see the contract methods from the previous output examples.
You can achieve a similar result by running the
starknet deploy, and
starknet invoke CLI commands, but the scripts are useful for interacting with StarkNet contracts and accounts programmatically.
Running the off-chain example
This example reads the proxy contract to get the latest values with no account or contract compiling steps required. The readLatestRoundOffChain.ts script uses StarkNet.js to make a call directly to the data feed proxy address. By default, the script reads the LINK / USD feed, but you can change the address to read any of the available data feeds on the StarkNet testnet.
./chainlink-starknet/examples/contracts/proxy-consumer/ directory, run
yarn readLatestRoundOffChain yarn run v1.22.19 round_id = 3.402823669209385e+38 answer = 6 block_num = 613151 observation_timestamp = 1673367749 transmission_timestamp = 1673367801 Done in 3.09s.
You can achieve a similar result by running the
starknet call CLI command and specifying the proxy address, function, and the ABI file for the data feed proxy contract. For this example, the ABI file is available in the repository, but you can also generate the ABI yourself from the aggregator_proxy.cairo contract source file.
starknet call --address 0x2579940ca3c41e7119283ceb82cd851c906cbb1510908a913d434861fdcb245 --function latest_round_data --abi ./contracts/aggregator_proxy_abi.json
The command prints the result:
0x100000000000000000000000000017c51 6 613174 1673368490 1673368507