Skip to content

Commit e3aee48

Browse files
committed
refactor: enhance clarity and update examples in Result Callback guide
1 parent b1ecd0a commit e3aee48

File tree

1 file changed

+57
-29
lines changed

1 file changed

+57
-29
lines changed

src/guides/build-iapp/advanced/result-callback.md

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,77 @@
11
---
22
title: Result Callback Guide
3-
description: Practical guide to using the iExec Result Callback mechanism to push an off-chain task result (iApp) directly into a smart contract—Oracles, automation, triggers, proofs, and more.
3+
description: Guide to using the iExec result callback to push an off-chain iApp task result directly into a smart contract (price feeds, automation, triggers, proofs, scoring, etc.).
44
---
55

66
# Result Callback
77

8-
This guide explains how to securely push an iExec task result into a smart contract using the callback mechanism.
9-
Oracles are only **one** of the possible use cases.
8+
This guide explains how to securely push an iExec task result into a smart contract using the callback mechanism.
9+
Oracles are only one of many possible use cases.
1010

1111
## When to Use a Callback
1212

13-
Use a callback whenever a smart contract should:
13+
Use a callback when a smart contract should:
1414

15-
- Consume off-chain computed data (API aggregation, ML inference, analytics) and store it on-chain
16-
- React on-chain to an execution outcome (conditional trigger, state transition)
17-
- Store a timestamped record (price feed, score, KPI, proof hash) on-chain
15+
- Ingest off-chain computed data (API aggregation, ML inference, analytics) and persist it on-chain
16+
- React to an execution outcome (conditional trigger, state transition)
17+
- Store a timestamped record (price feed, score, KPI, proof hash)
1818
- Act as a logic bridge between external systems and on-chain logic
1919

2020
## 🧩 High-Level Flow
2121

2222
1. A requester executes an iApp on iExec.
23-
2. The iApp writes in the file `${IEXEC_OUT}/computed.json` under the filed `callback-data` the necessary calldata to make on-chain call.
24-
3. iExec decentralized Protocol trigger corresponding on-chain contract based on the deal & task result `callback-data` field.
25-
4. Your smart contract (receiver) callback data, verifies, and ingests it.
23+
2. The iApp writes `${IEXEC_OUT}/computed.json` with a `callback-data` field containing ABI‑encoded calldata.
24+
3. The iExec protocol, once the task is completed, invokes the specified callback contract with that data.
25+
4. Your callback smart contract (receiver) ingests the data.
2626

2727
## Step-by-Step Implementation
2828

2929
### Step 1: Write the iApp
3030

31-
Your iApp must write a JSON file named `computed.json` in the directory pointed to by the environment variable `IEXEC_OUT`. This file must contain at least the key `callback-data`, which holds the ABI-encoded data you want to send to your smart contract.
31+
The iApp MUST write a file named `computed.json` in the directory pointed to by `IEXEC_OUT`.
32+
Required key: `callback-data` (raw ABI‑encoded bytes you want passed to your contract).
33+
34+
Replaced Web3.js example with ethers v6:
3235

3336
```js
34-
import fs from 'node:fs';
35-
import Web3 from 'web3';
36-
const web3 = new Web3();
37+
// ethers v6 example producing ABI-encoded callback data
38+
39+
import { writeFileSync } from 'node:fs';
40+
import { AbiCoder } from 'ethers';
41+
42+
// Placeholder: replace with real price retrieval / aggregation logic
43+
async function fetchPrice(pair) {
44+
// e.g. query multiple APIs, median, etc.
45+
return 12345.6789;
46+
}
3747

3848
async function main() {
3949
const [pair = 'BTC-USD', precision = '9'] = process.argv.slice(2);
40-
const price = await fetchPrice(pair); // Your logic
41-
const scaled = BigInt(Math.round(price * 10 ** Number(precision)));
4250

43-
const now = Math.floor(Date.now() / 1000);
44-
const abiPayload = web3.eth.abi.encodeParameters(
45-
['uint256','string','uint256'],
46-
[now, `${pair}-${precision}`, scaled.toString()]
51+
const price = await fetchPrice(pair);
52+
const scale = 10n ** BigInt(Number(precision));
53+
const scaled = BigInt(Math.round(price * Number(scale)));
54+
55+
const timestamp = Math.floor(Date.now() / 1000);
56+
57+
const abiCoder = new AbiCoder();
58+
const abiPayload = abiCoder.encode(
59+
['uint256', 'string', 'uint256'],
60+
[timestamp, `${pair}-${precision}`, scaled]
4761
);
4862

49-
fs.writeFileSync(
50-
process.env.IEXEC_OUT + '/computed.json',
51-
JSON.stringify({
52-
'callback-data': abiPayload,
53-
metadata: { pair, precision, now, source: 'demo' }
54-
})
63+
writeFileSync(
64+
`${process.env.IEXEC_OUT}/computed.json`,
65+
JSON.stringify(
66+
{
67+
'callback-data': abiPayload,
68+
metadata: {
69+
pair,
70+
precision,
71+
timestamp,
72+
}
73+
}
74+
)
5575
);
5676
}
5777

@@ -60,7 +80,8 @@ main().catch(() => process.exit(1));
6080

6181
### Step 2: Deploy the Callback Contract
6282

63-
The callback contract is the receiver of the off-chain computed data. Implement your custom logic based on your use case.
83+
The callback contract receives and processes the off-chain result.
84+
It can read the stored `resultsCallback` from the iExec hub (or proxy) to independently verify the task state.
6485

6586
```solidity
6687
interface IIexecProxy {
@@ -78,15 +99,22 @@ abstract contract IExecCallbackReceiver {
7899
79100
function _getCallback(bytes32 taskid) internal view returns (bytes memory) {
80101
IIexecProxy.Task memory t = iexec.viewTask(taskid);
81-
require(t.status == 3, "task-not-completed"); // Example: 3 = COMPLETED
102+
require(t.status == 3, "task-not-completed"); // 3 = COMPLETED (example)
82103
return t.resultsCallback;
83104
}
84105
}
85106
```
86107

87108
### Step 3: Run the iApp with Callback
88109

89-
When running the iApp, specify the callback contract address in the deal parameters. The iExec protocol will automatically call the specified contract with the `callback-data` once the task is completed.
110+
When requesting the execution, set the callback contract address in the deal (or order) parameters.
111+
After completion, the protocol calls your contract passing the `callback-data` bytes.
112+
113+
Checklist:
114+
115+
- Ensure the contract adheres to the expected callback function signature.
116+
- Guard against replay (e.g. track processed task IDs).
117+
- Validate business invariants (timestamps, ranges, freshness).
90118

91119
## 🔄 Other Use Cases
92120

0 commit comments

Comments
 (0)