Smart contracts can trigger a public decryption of any ciphertext it has access to. This flow is asynchronous, the contract issues a request first and receives the decryption result in a callback function in a later block.

Inco will try calling the callback function once and won’t retry if it reverts.

Lets consider the following example where the sender of a confidential transfer decrypts if it has been successful:

function doATransfer() public {
    ebool success = token.transfer(bob, amount);
    // the third argument is arbitrary data that will be passed to the callback function
    success.requestDecryption(this.toCallback.selector, "");
}

function toCallback(
    uint256 /* requestId */, // unique id of the request, useful to track multiple requests
    bool result,
    bytes memory /* data */ // arbitrary data passed to the callback
) external {
    if (result) {
        // it worked !
    }
}

The callback will always expect these three arguments:

  • requestId: the unique id of the request, useful to track multiple requests
  • result: the result of the decryption (bool or uint256)
  • data: the arbitrary data passed to the callback

e.requestDecryption returns a unique id for the request, which can be used to track multiple requests. It can be called over an ebool or an euint256 that the contract has access to.

Signature of the e.requestDecryption function:

function requestDecryption(
    ebool a,
    bytes4 callbackSelector,
    bytes memory callbackData
) returns (uint256 requestId);

function requestDecryption(
    euint256 a, 
    bytes4 callbackSelector, 
    bytes memory callbackData
) returns (uint256 requestId);