Understanding Request Model

Sight Oracle interacts with requests using the following Request format:

struct Request {
    address requester;
    Operation[] ops;
    uint256 opsCursor;
    address callbackAddr;
    bytes4 callbackFunc;
    bytes payload;
}

Key Concept: Operation

The ops array in the request defines the sequence of computations. Each Operation includes an opcode, operands (references to other operations by index), and optionally, a direct value:

struct Operation {
    uint8 opcode;
    uint256[] operands; // Indices of the operands within the request
    uint64 value; // Direct value if applicable
}

The FHE compute engine processes the ops array, executing the operations sequentially. Notably, except for getXXX operations (e.g., getEuint64), all operations accept indices of other operations as input, not raw variables or values.

Example: Requesting an Addition Operation

Below is an example demonstrating how to construct a request that adds two encrypted values (euint64):

contract Example {
    euint64 a; // Assume these are initialized with valid values
    euint64 b; // Assume these are initialized with valid values
    Oracle public oracle;
    
    function request() public {
        // Create a new request with 3 operations
        Request memory r = RequestBuilder.newRequest(
            msg.sender,              // Requester address
            3,                       // Number of operations
            address(this),           // Callback address
            this.callback.selector,  // Callback function
            ""                       // Payload
        );
        
        // Load encrypted values into request execution context
        op load_a = r.getEuint64(a);
        op load_b = r.getEuint64(b);
        
        // Add the two loaded values
        op compute_sum = r.add(load_a, load_b) // Accepts op indices, not variables     
        
        // Send the request to the Oracle
        bytes32 reqId = oracle.send(r);
    }
    
    function callback() public onlyOracle {
        // Handle the result of the computation
    }
}

Important Notes:

  • Operands as Indices: Operations (except getXXX) only accept indices of prior operations as inputs. For example, r.add(load_a, load_b) passes the indices of load_a and load_b within the ops array.

  • Sequential Execution: Operations are executed in the order they are defined in the ops array.

  • Callback Handling: The callback function is invoked by the Oracle once the computation is complete, allowing the contract to handle the results.

Last updated