Skip to content

Result callback

This guide explains how to trigger a callback function at the end of a successful task on your smart contract.

Use a callback when your smart contract should:

  • Ingest off-chain computed data (API aggregation, ML inference, analytics) and persist it
  • React to an execution outcome (conditional trigger, state transition)
  • Store a timestamped record (price feed, score, KPI, proof hash)
  • Bridge logic between external systems and on-chain state

High-level flow

  1. A requester deploys the smart contract that should receive the callback data.
  2. The requester executes an iApp and specifies the callback address.
  3. The iApp writes ${IEXEC_OUT}/computed.json with a callback-data field (ABI‑encoded bytes you crafted).
  4. After the task completes and is validated, the iExec protocol invokes your contract’s receiveResult(bytes32,bytes).
  5. Your contract decodes and processes those bytes if callback data have been provided.

Step-by-step implementation

Step 1: Implement the callback contract

Your contract must expose the function receiveResult(bytes32,bytes)ERC1154. The protocol calls it with:

  • _callID: This parameter represents the taskId, passed as the first argument
  • callback: exactly the bytes you encoded as callback-data

Decode using the same tuple. (Optional) Add protections: authorized caller check (iExec hub / proxy), replay guard, bounds checks.

solidity
contract IExecCallbackReceiver {
    // Your business logic here ...

    // ERC1154 - Callback processing
    function receiveResult(bytes32 _callID, bytes memory callback) external {
        // Parse results
        (uint256 timestamp, string memory pairAndPrecision, uint256 scaledValue) =
            abi.decode(callback, (uint256, string, uint256));
    }
}

Important

The callback transaction is subject to a maximum gas limit of 200,000 enforced by the protocol.
Ensure your callback logic fits within this limit to avoid out-of-gas errors.

Step 2: Prepare the callback payload in the iApp

You only need to write computed.json containing the key callback-data.
That value must be the ABI‑encoded bytes your contract knows how to decode.
Example tuple schema we'll use: (uint256 timestamp, string pairAndPrecision, uint256 scaledValue).

ts

async function 
main
() {
// Your business logic here ... const
abiCoder
= new
AbiCoder
();
const
abiPayload
=
abiCoder
.
encode
(
['uint256', 'string', 'uint256'], [
timestamp
,
pair
,
scaled
]
);
writeFileSync
(
`${
process
.
env
.
IEXEC_OUT
}/computed.json`,
JSON
.
stringify
({
'callback-data':
abiPayload
,
}) ); }

Step 3: Run the iApp with a callback

When creating the request order, set the callback field to your callback contract address.
After completion, the protocol calls your contract, passing the callback-data bytes.

First install the iExec SDK if you have not already (see the iExec SDK documentation).

ts
// Basic arguments
const 
requestorderToSign
= await
iexec
.
order
.
createRequestorder
({
app
: '0x456def...',
category
: 0,
appmaxprice
: 10,
workerpool
: '0xa5de76...',
callback
: '0x8e5bB6...', // Callback contract address
}); const
requestOrder
= await
iexec
.
order
.
signRequestorder
(
requestorderToSign
);
// Fetch app orders const
appOrders
= await
iexec
.
orderbook
.
fetchAppOrderbook
(
'0x456def...' // Filter by specific app ); if (
appOrders
.
orders
.
length
=== 0) {
throw new
Error
('No app orders found for the specified app');
} // Fetch workerpool orders const
workerpoolOrders
= await
iexec
.
orderbook
.
fetchWorkerpoolOrderbook
({
workerpool
: '0xa5de76...', // Filter by specific workerpool
}); if (
workerpoolOrders
.
orders
.
length
=== 0) {
throw new
Error
('No workerpool orders found for the specified workerpool');
} // Execute the task const
taskId
= await
iexec
.
order
.
matchOrders
({
requestorder
:
requestOrder
,
apporder
:
appOrders
.
orders
[0].
order
,
workerpoolorder
:
workerpoolOrders
.
orders
[0].
order
,
});

Other use cases

Use CaseDescription
Price oracleMulti-source API aggregation
Reputation / scoringOff-chain ML / analytics pushed on-chain
Audit hashSecurity scan or verification artifact
AutomationWorkflow step completion signal
Dynamic parametersAdjust rates / thresholds / quorums
Logical bridgeSync external (IoT / legacy) state