Inputs

There are two ways to input external values into a handle that you can perform confidential operations on:

Case 1. The value comes from an offchain source

In the confidential transfer example, the first external method is meant to be called by an EOA / Smart account. It is using newEuint256 to convert the input value into a handle.

function transfer(
        address to,
        bytes memory valueInput
    ) external returns (ebool) {
        euint256 value = valueInput.newEuint256(msg.sender);
        // stuff
    }

newEuint256 takes two arguments, the encrypted input value (in the form of bytes) and the address of the account doing the input (here msg.sender). This account should always be the one that created the input, it will be given decryption right over the handle. Passing another address than the user doing the input would be a malicious implementation.

valueInput has to be a ciphertext, meaning it has to be the value intended to be transferred, encrypted in a way that Inco can understand. To do this, you can use the encrypt method from the JavaScript SDK.

If the bytes memory valueInput is malformed, Inco will fallback to the handle default value. The default value of euint256 is 0, and the default value of ebool is false.

After newEuint256 has been used, the resulting handle can be used immediately, there is no need for Inco to issue a confirmation to start using it in the contract logic. Inco will decrypt the corresponding ciphertext safely inside its TEE after the transaction has been included onchain. All operations onchain are performed virtually over identifiers, and reproduced over the actual values by Inco asynchronously. We call this model “symbolic execution”.

One could try to reuse the same ciphertext as another user to gain decryption access over it. Our JS SDK embeds context information in the ciphertext (originating account, chain, contract), and the value of the created handle will fallback to the default if it is used in another context.

Case 2. The value comes from a variable

A known value can be turned into a handle using the asEuint256 method. This is sometimes called performing a “trivial encrypt” because the resulting handle will be of a known value. We can see it in the constructor of the token example:

constructor() {
    balanceOf[msg.sender] = uint256(1000 * 1e9).asEuint256();
}

Anyone can see that the initial value of balanceOf[msg.sender] is 1000 * 1e9, but after the deployer sends a few transfers, its balance will be unknown to the public.