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 --versionorsncast --versionin your terminal and install the required version if necessary. -
Scarb: Install Scarb v2.6.4. You can check your current version by running
scarb --versionin 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
-
Clone the chainlink-starknet repository, which includes the example contracts for this guide:
git clone https://github.com/smartcontractkit/chainlink-starknet.git -
Navigate to the
aggregator_consumerdirectory:cd chainlink-starknet/examples/contracts/aggregator_consumer/
After you prepare the requirements, 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
-
Run the
create-accountscript to create a new OpenZeppelin local account for the Sepolia testnet:make create-accountThe account details are stored locally in your
~/.starknet_accounts/starknet_open_zeppelin_accounts.jsonfile.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 after0x. - The
max_feevalue, which is the minimum amount of testnet ETH required to deploy the account.
- Your account address. In this example, it is
-
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 use 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.
-
Deploy your account to Starknet Sepolia:
make deploy-accountExpect an output similar to the following:
command: account deploy transaction_hash: 0x541ffae49f77dd942376391286052d9fb87dc8d6848139ab1508c114e3aa005Wait a few seconds for the transaction to complete.
Deploy and interact with a consumer contract
The consumer contract contains two functions that you interact with in this example:
set_answerretrieves the latestanswerfrom the specified aggregator contract and stores it in the_answerinternal storage variable.read_answerreads the stored_answervalue.
-
Navigate to
/scripts/src/consumer/and open thedeploy_aggregator_consumerscript. -
Update the
aggregator_addressvariable within themainfunction with the ETH / USD Chainlink proxy aggregator contract address on Starknet Sepolia :0x228128e84cdfc51003505dd5733729e57f7d1f7e54da679474e73db4ecaad44. -
Run the
deploy_aggregator_consumerscript to deploy a consumer contract to Starknet Sepolia. Use the following command:make ac-deploy NETWORK=testnetExpect 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: successThe 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 is0x06892f22691473dc5a413a7626062604155516ec91a82d3734dc68bcf3d72d4f. Save your consumer address for the next steps. -
In
/scripts/src/consumer/, open theset_answerscript and update theconsumer_addressvariable with your deployed consumer address. -
Run the following command to update the answer:
make ac-set-answer NETWORK=testnetThis command runs the
set_answerscript to retrieve the latestanswerfrom the ETH / USD aggregator contract and stores it in the internal storage variable_answerof 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 -
In
/scripts/src/consumer/, open theread_answerscript and update theconsumer_addressvariable with your deployed consumer address. -
Run the following command to read the stored
answervalue from your consumer contract:make ac-read-answer NETWORK=testnetExpect an output similar to the following:
Result::Ok(CallResult { data: [354661371569] }) command: script run status: successThe answer on the ETH / USD feed uses 8 decimal places, so an answer of
354661371569indicates an ETH / USD price of3546.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.