Skip to main content

Ethereum Virtual Machine (EVM)

Acurast can be used to get access to computational resources for various use cases and bring them to EVM chains. For that, the Consumer creates a Job that performs a given task on the Acurast Console.

Integration Example

The following example shows a possible integration approach for an EVM chain.

EVM smart contract implementation

The first step is the implementation and deployment of the EVM contract.

The example used is a simple entropy provider, which receives entropy from an Acurast Processor and exposes it to other contracts in the EVM environment.

In this example, the contract expects the Acurast Processor to be known in advance, this can also be adapted at a later stage, depending on how you want to assign your Job to one or more Processors.

For simplicity purposes, this example uses the address 0x176583fbcd4e378c138dea7a4630e7b2b759af96 as a Processor.

Deploy with Remix

// SPDX-License-Identifier: None
pragma solidity ^0.8.0;

contract EntropyProvider {
bytes entropy;
uint last_update;
address processor;

constructor(address _processor) {
processor = _processor;

* Receive entropy (random bytes) from an Acurast job.
function receive_entropy(bytes memory _entropy) public {
// Ensures that only the processor can call this function
require(msg.sender == processor, "NOT_ALLOWED");
// Update entropy
entropy = _entropy;
last_update = block.timestamp;

* A view that exposes the entropy to other contracts.
function consume_entropy(uint maxAge) public view returns (bytes memory) {
// Consumers can specify the maximum entropy age they are willing to accept
require(block.timestamp - last_update <= maxAge, "ENTROPY_TOO_OLD");

return entropy;

Deployed contract example on Goerli chain: 0x2c503cfba7178eb0ac2dc5df45279527d437657a

Job specification

Now that the contract has been deployed, we can prepare the script that will get executed by the Processor to provision the entropy.

The script below computes some random bytes securely and calls the function receive_entropy of the contract deployed above. The Consumer can also specify the gas limit and maximum costs per gas unit.

// Destination contract address
const destination = "<0x evm_contract_address>";
// Generate entropy
const entropy = _STD_.random.generateSecureRandomHex();
// Fulfill entropy
"", // RPC
destination, // Destination contract address
entropy, // Payload
// Transaction parameters
methodSignature: "receive_entropy(bytes)",
gasLimit: "9000000",
maxFeePerGas: "255000000000",
maxPriorityFeePerGas: "2550000000",
// Success callback
(opHash) => {
print("Succeeded: " + opHash);
// Error callback
(err) => {
print("Failed: " + err);

Job Registration

Check out How to get started with the Acurast Console to register your Job.

Price feeds with Chainlink-compatible contracts have been deployed to multiple protocols. These can be called by other smart contracts to fetch asset pricing data like the BTC / USD feed.

These feeds use data fetched by Acurast Processors and pushed directly to the contract. Each price feed has an on-chain address and functions that enable contracts to read pricing data from that address.

This guide shows you how to read Price Feeds and store the value on-chain using Solidity.

Consuming Price Feeds

This example contract obtains the latest price answer from the BTC / USD feed, but you can modify it to read any of the different types of data, depending on your script.

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorInterface.sol";

contract DataConsumer {
AggregatorInterface internal dataFeed;

* Network: Astar zKatana
* Aggregator: BTC/USD
constructor() {
dataFeed = AggregatorInterface(

* Returns the latest answer.
function getLatestAnswer() public view returns (int256) {
int256 answer = dataFeed.latestAnswer();
return answer;

The contract has the following components:

  • The import line imports an interface named AggregatorInterface. Interfaces define functions without their implementation, which leaves inheriting contracts to define the actual implementation themselves.

  • The constructor() {} initializes an interface object named dataFeed that uses AggregatorInterface and connects specifically to a proxy aggregator contract that is already deployed at 0xDBb23274EE9354367155C290c673733374d57967. The interface allows your contract to run functions on that deployed aggregator contract.

  • The getLatestAnswer() function calls your dataFeed object and runs the latestAnswer() function. When you deploy the contract, it initializes the dataFeed object to point to the aggregator at 0xDBb23274EE9354367155C290c673733374d57967, which is the proxy address for the Astar zKatana BTC / USD data feed. Your contract connects to that address and executes the function. The aggregator connects with one or several Acurast Processors and aggregates the pricing data from those nodes. The response from the aggregator includes several variables, but getlatestAnswer() returns only the answer variable.

Deployed Contracts

A list of deployed contracts updated regularly by Acurast Processors.

BoB (Build on Bitcoin)

BTC Fee Estimation0x452a09e72444cf6a526b02c1a27d250305d450b5

zKatana (Astar zkEVM)