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 โ
- A requester deploys the smart contract that should receive the callback data.
- The requester executes an iApp and specifies the callback address.
- The iApp writes
${IEXEC_OUT}/computed.json
with acallback-data
field (ABIโencoded bytes you crafted). - After the task completes and is validated, the iExec protocol invokes your contractโs
receiveResult(bytes32,bytes)
. - 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 thetaskId
, passed as the first argumentcallback
: exactly the bytes you encoded ascallback-data
Decode using the same tuple. (Optional) Add protections: authorized caller check (iExec hub / proxy), replay guard, bounds checks.
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 gas limit of 100,000.
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)
.
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 Getting Started).
// 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 Case | Description |
---|---|
Price oracle | Multi-source API aggregation |
Reputation / scoring | Off-chain ML / analytics pushed on-chain |
Audit hash | Security scan or verification artifact |
Automation | Workflow step completion signal |
Dynamic parameters | Adjust rates / thresholds / quorums |
Logical bridge | Sync external (IoT / legacy) state |