📔Contract

SightOracle contract is the core component of the Sight Oracle system, enabling users to delegate computations over encrypted data using Fully Homomorphic Encryption (FHE) technology. The contract operates on the Ethereum Virtual Machine (EVM) and facilitates secure and efficient encrypted computations.

Key Features

  1. Request Management:

    • The contract manages requests for computations using in-contract mappings.

    • Users can send computation requests to the contract, which are then stored and emitted via events.

  2. Callback Handling:

    • After the computations are completed by the off-chain Oracle Service Nodes, the results are sent back to the contract using callback functions.

    • The contract ensures the correct execution of callbacks by verifying ownership and proper function signatures.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./RequestBuilder.sol";
import "./ReencryptRequestBuilder.sol";
import "@openzeppelin/contracts/access/Ownable2Step.sol";

contract SightOracle is Ownable2Step {

    mapping(bytes32 => RequestBuilder.Request) requests;
    mapping(bytes32 => ReencryptRequestBuilder.ReencryptRequest) reenc_requests;

    event RequestSent(RequestBuilder.Request);
    event RequestCallback(bytes32 indexed, bool indexed);

    event ReencryptSent(ReencryptRequestBuilder.ReencryptRequest);
    event ReencryptCallback(bytes32 indexed, bool indexed);

    constructor() Ownable(msg.sender) {}

    function send(RequestBuilder.Request calldata request) external {
        require(request.id != bytes32(0), "id not generated, use .complete()");
        requests[request.id] = request;
        emit RequestSent(request);
    }

    function callback(bytes32 requestId, CapsulatedValue[] memory result) public onlyOwner {
        RequestBuilder.Request memory request = requests[requestId];
        (bool success, bytes memory bb) = request.callbackAddr.call(
            abi.encodeWithSelector(request.callbackFunc, requestId, result)
        );
        if (!success) {
            string memory err = abi.decode(bb, (string));
            revert(err);
        }
        emit RequestCallback(requestId, success);
    }

    function send(ReencryptRequestBuilder.ReencryptRequest calldata reen_req) public {
        reenc_requests[reen_req.id] = reen_req;
        emit ReencryptSent(reen_req);
    }

    function reencryptCallback(
        bytes32 requestId,
        bytes memory result
    ) public onlyOwner {
        ReencryptRequestBuilder.ReencryptRequest memory reen_req = reenc_requests[requestId];
        (bool success, bytes memory bb) = reen_req.callbackAddr.call(
            abi.encodeWithSelector(reen_req.callbackFunc, reen_req, result)
        );
        if (!success) {
            string memory err = abi.decode(bb, (string));
            revert(err);
        }
        emit ReencryptCallback(requestId, success);
    }
}

Libraries and Types

Opcode Library

The Opcode library defines constants for various operations that can be performed on encrypted data. These operations include arithmetic, bitwise, and comparison operations.

RequestBuilder Library

The RequestBuilder library is used to create computation requests. It defines the structure and methods for building requests, by defining various operations as op_codes and managing their execution.

ResponseResolver Library

The ResponseResolver library is used to decode the results of computations performed on encrypted data. It provides methods to interpret the results as encrypted / plaintext data types such as bool, uint64, ebool, and euint64.

Last updated