Automation Interfaces
Your Automation-compatible contracts may use the following interfaces. You can find them in the Chainlink repository. To understand how to implement these contracts, visit the Compatible Contracts page.
- If you want a log event to trigger your upkeep, use the
ILogAutomation
interface. - If you want to use onchain state (excluding logs) in a custom calculation to trigger your upkeep, use
AutomationCompatibleInterface
interface. - If you want to call a function just based on time, consider using a time-based upkeep.
- If you want to use Automation with Data Streams, use
StreamsLookupCompatibleInterface
interface.
ILogAutomation
To use log triggers, you will need to implement the ILogAutomation.sol
interface in your smart contract. Click on the functions below to understand the parameters:
Function Name | Description |
---|---|
checkLog | Simulates offchain once a log that matches log specifications is emitted. |
performUpkeep | Contains the logic that should be executed onchain when checkUpkeep returns true . |
checkLog function
checkLog
is a view
function that will be simulated offchain once a log that matches your LogTriggerConfig
has been emitted. You should parse the log data and the check if something needs to happen onchain. For example, it can trigger the retrieval of Data Streams reports. See the Data Streams Getting Started guide to see an example.
Parameters
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
log | struct Log | Struct log data of the log triggering the upkeep; Automation will form the triggering log into a struct so the user can query log data in checkLog . | struct Log { uint256 index; uint256 timestamp; bytes32 txHash; uint256 blockNumber; bytes32 blockHash; address source; bytes32[] topics; bytes data; } |
checkData | bytes | Optional additional bytes the user wants to provide. checkData is set at the time of registering the upkeep. |
Example
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.7;
struct Log {
uint256 index;
uint256 timestamp;
bytes32 txHash;
uint256 blockNumber;
bytes32 blockHash;
address source;
bytes32[] topics;
bytes data;
}
function checkLog(
Log calldata log,
bytes memory checkData
) external returns (bool upkeepNeeded, bytes memory performData);
performUpkeep function for log triggers
This function contains the code that will be executed onchain to finalize the trade.
Parameters
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
performData | bytes | Data encoded in the checkLog function that will be used to execute the function onchain | bytes |
AutomationCompatibleInterface
Custom logic upkeeps need to use the AutomationCompatibleInterface.sol
interface. Click on one of the functions below to understand its parameters and limits.
Function Name | Description |
---|---|
checkUpkeep | Runs offchain to determine if the performUpkeep function should be called onchain. |
performUpkeep | Contains the logic that should be executed onchain when checkUpkeep returns true. |
checkUpkeep function
This view function contains the logic that runs offchain during every block as an eth_call
to determine if performUpkeep
should be executed onchain. To reduce onchain gas usage, attempt to do your gas intensive calculations offchain in checkUpkeep
and pass the result to performUpkeep
onchain. It is a best practice to import the AutomationCompatible.sol
contract and use the cannotExecute
modifier to ensure that the method can be used only for simulation purposes.
function checkUpkeep(
bytes calldata checkData
) external view override returns (bool upkeepNeeded, bytes memory performData);
Below are the parameters and return values of the checkUpkeep
function. Click each value to learn more about its design patterns and best practices:
Parameters:
checkData
: Fixed and specified at upkeep registration and used in everycheckUpkeep
. Can be empty (0x).
Return Values:
upkeepNeeded
: Boolean that when True will trigger the onchainperformUpkeep
call.performData
: Bytes that will be used as input parameter when callingperformUpkeep
. If you would like to encode data to decode later, tryabi.encode
.
checkData
You can pass information into your checkUpkeep
function from your upkeep registration to execute different code paths. For example, to check the balance on a specific address, set the checkData
to abi encode the address. To learn how to create flexible upkeeps with checkData, please see our flexible upkeeps page.
function checkUpkeep(
bytes calldata checkData
) public view returns (bool, bytes memory) {
address wallet = abi.decode(checkData, (address));
return (wallet.balance < 1 ether, bytes(""));
}
Tips on using checkData
:
-
Managing unbounded upkeeps: Limit the problem set of your onchain execution by creating a range bound for your upkeep to check and perform. This allows you to keep within predefined gas limits, which creates a predictable upper bound gas cost on your transactions. Break apart your problem into multiple upkeep registrations to limit the scope of work.
Example: You could create an upkeep for each subset of addresses that you want to service. The ranges could be 0 to 49, 50 to 99, and 100 to 149.
-
Managing code paths: Pass in data to your
checkUpkeep
to make your contract logic go down different code paths. This can be used in creative ways based on your use case needs.Example: You could support multiple types of upkeep within a single contract and pass a function selector through the
checkData
function.
performData
The response from checkUpkeep
is passed to the performUpkeep
function as performData
. This allows you to perform complex and gas intensive calculations as a simulation offchain and only pass the needed data onchain.
You can create a highly flexible offchain computation infrastructure that can perform precise actions onchain by using checkData
and performData
. Both of these computations are entirely programmable.
performUpkeep function for custom logic triggers
When checkUpkeep
returns upkeepNeeded == true
, the Automation node broadcasts a transaction to the blockchain to execute your performUpkeep
function onchain with performData
as an input.
Ensure that your performUpkeep
is idempotent. Your performUpkeep
function should change state such that checkUpkeep
will not return true
for the same subset of work once said work is complete. Otherwise the Upkeep will remain eligible and result in multiple performances by the Chainlink Automation Network on the exactly same subset of work. As a best practice, always check conditions for your upkeep at the start of your performUpkeep
function.
function performUpkeep(bytes calldata performData) external override;
Parameters:
performData
: Data which was passed back from thecheckData
simulation. If it is encoded, it can easily be decoded into other types by callingabi.decode
. This data should always be validated against the contract's current state.
performData
You can perform complex and broad offchain computation, then execute onchain state changes on a subset that meets your conditions. This can be done by passing the appropriate inputs within performData
based on the results from your checkUpkeep
. This pattern can greatly reduce your onchain gas usage by narrowing the scope of work intelligently in your own Solidity code.
- Identify a list of addresses that require work: You might have a number of addresses that you are validating for conditions before your contract takes an action. Doing this onchain can be expensive. Filter the list of addresses by validating the necessary conditions within your
checkUpkeep
function. Then, pass the addresses that meet the condition through theperformData
function. For example, if you have a "top up" contract that ensures several hundred account balances never decrease below a threshold, pass the list of accounts that meet the conditions so that theperformUpkeep
function validates and tops up only a small subset of the accounts. - Identify the subset of states that must be updated: If your contract maintains complicated objects such as arrays and structs, or stores a lot of data, you should read through your storage objects within your
checkUpkeep
and run your proprietary logic to determine if they require updates or maintenance. After that is complete, you can pass the known list of objects that require updates through theperformData
function.
StreamsLookupCompatibleInterface
See the Data Streams Getting Started guide to see an example of how to use this interface.
To use Data Streams with Automation, your contract must be Automation-compatible and include a StreamsLookupCompatibleInterface
interface. This interface fetches and processes Data Streams reports.
Function Name | Description |
---|---|
StreamsLookup revert | Triggers the retrieval of specified reports. |
checkCallback | Simulates offchain to receive signed reports and conduct final parsing before sending data onchain via performUpkeep . |
StreamsLookup revert
Automation network will use this revert to trigger fetching of the specified reports.
Parameters
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
feedParamKey | String | Specify the feed identifiers that will be provided | "feedIDs" |
feeds | String[] | String list of feed identifiers | e.g. ["feedID1","feedID2",..] with a maximum of 5 IDs |
timeParamKey | String | Specify query type | "timestamp" |
time | uint256 | Specify query value | block.timestamp |
extraData | bytes | Any extra data user wants to receive in callback, alongside API bytes[] | log data |
Outputs
The fetched signed reports will be provided to the user in checkCallback
. This is an offchain compute that the user can use to structure data as needed before performing the onchain confirmation and validation transactions.
Variable Name | Type | Description | Usage examples |
---|---|---|---|
values | bytes[] | List of signed reports fetched from API | List of signed reports values[0], values[1]… ordered to match order in feeds |
extraData | bytes | Bytes data sent as part of original MercuryLookup revert error | e.g. can send log data if you want to decode to use |
checkCallback function
This is a view
function that will be simulated offchain to receive the signed reports and conduct any final parsing before sending data onchain via performUpkeep
. Inputs will match outputs of the oracleLookup
revert.
Parameters
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
values | bytes[] | List of signed reports fetched from API | List of signed reports values[0], values[1]… ordered to match order in feeds |
extraData | bytes | Bytes data sent as part of original MercuryLookup revert error | e.g. can send log data if you want to decode to use |
Outputs
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
performData | bytes | Data encoded in the oracleCallback function that will be used to execute function onchain, e.g. encode signed reports and log data if need be | bytes |
upkeepNeeded | boolean | When set to true this will trigger the performUpkeep function to be executed onchain | true of false |
checkErrorHandler function
This function is simulated offchain to respond to error codes before sending data onchain in the performUpkeep
function.
Parameters
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
errorCode | uint | Error code returned by StreamsLookup error handler | Example: "800400" (ErrCodeStreamsBadRequest ) |
extraData | bytes | Bytes data sent as part of the original MercuryLookup revert error | This field can send log data if you want to decode it and use it. |
Outputs
Variable Name | Type | Description | Permissible Values |
---|---|---|---|
performData | bytes | Data encoded in the oracleCallback function that will be used to execute function onchain, e.g. encode signed reports and log data if need be | bytes |
upkeepNeeded | boolean | When set to true , this triggers the performUpkeep function to be executed onchain | true or false |