Documentation Index
Fetch the complete documentation index at: https://docs.inco.org/llms.txt
Use this file to discover all available pages before exploring further.
Attested compute allows to perform a computation on a handle completely off-chain and get the decryption attestation containing decryption result and attestation.
Only handles that are allowed with e.allow() or e.reveal() can be used in computation.
The attestation can then be verified on-chain to perform certain on-chain actions, avoiding unnecessary transaction.
Getting Started
Take this example contract that holds an encrypted credit score of a user, to determine whether they’re eligible for a loan:
import {euint256, e, ebool, inco} from "@inco/lightning/src/Lib.sol";
import {DecryptionAttestation} from "@inco/lightning/src/lightning-parts/DecryptionAttester.types.sol";
import {asBool} from "@inco/lightning/src/shared/TypeUtils.sol";
contract TestAttestedCompute {
euint256 hiddenCreditScore;
constructor(address owner) payable {
require(msg.value == inco.getFee(), "Fee not paid");
hiddenCreditScore = e.asEuint256(800);
e.allow(hiddenCreditScore, address(this));
e.allow(hiddenCreditScore, owner);
}
function GetHandle() external returns (euint256) {
return hiddenCreditScore;
}
function SubmitCreditCheck(
DecryptionAttestation memory decryption,
bytes[] memory signatures
) external {
// Verify covalidator signatures over the attested result
require(
inco.incoVerifier().isValidDecryptionAttestation(decryption, signatures),
"Invalid signature"
);
// Recompute the expected "creditScore >= 700" handle on-chain
require(
ebool.unwrap(e.ge(hiddenCreditScore, 700)) == decryption.handle,
"Computed handle mismatch"
);
// Check that the decrypted boolean is true
require(asBool(decryption.value) == true, "Credit check failed");
// Credit check passed - proceed with loan approval
}
}
Presume we want to know whether the credit score is greater than or equal 700 without sending an additional transaction.
We can do that by calling attestedCompute (similar to Attested Decrypt):
import { Lightning } from '@inco/js/lite';
import { getViemChain, supportedChains, type HexString } from '@inco/js';
import { AttestedComputeSupportedOps } from '@inco/js/lite';
import { createWalletClient, custom } from 'viem'
const zap = await Lightning.latest('testnet', supportedChains.baseSepolia);
//Connect to Metamask or other wallet provider
const walletClient = createWalletClient({
chain: getViemChain(supportedChains.baseSepolia),
transport: custom(window.ethereum!)
})
// Retrieve the hiddenCreditScore handle from the contract by calling GetHandle(), e.g. using viem
const hiddenCreditScore = '0x<handle>' as HexString;
// isGreaterOrEqual = hiddenCreditScore >= 700
const isGreaterOrEqual = await zap.attestedCompute(
walletClient,
hiddenCreditScore,
AttestedComputeSupportedOps.Ge,
700n,
);
const creditScoreSufficient = isGreaterOrEqual.plaintext.value; // always boolean
Which is equivalent to:
ebool creditScoreSufficient = e.ge(hiddenCreditScore, 700);
isGreaterOrEqual also contains a signature from covalidator attesting to the computation, which can be used to submit decryption back on-chain, even if the handle doesn’t exist on chain yet.
Supported operations
| Name | Op | Type | Returns |
|---|
| Equal | AttestedComputeSupportedOps.Eq | Scalar Binary* | bool |
| Not equal | AttestedComputeSupportedOps.Ne | Scalar Binary* | bool |
| Greater than or equal | AttestedComputeSupportedOps.Ge | Scalar Binary* | bool |
| Greater than | AttestedComputeSupportedOps.Gt | Scalar Binary* | bool |
| Less than or equal | AttestedComputeSupportedOps.Le | Scalar Binary* | bool |
| Less than | AttestedComputeSupportedOps.Lt | Scalar Binary* | bool |
- Scalar binary operation - operation that takes in two operands, one of which is a handle and the second one is a number (aka scalar).
Compute with Allowance Voucher/Session Key
Compute on a handle can be performed with a session key instead of a wallet provider using sessionKeyAttestedCompute(), see Allowance Voucher.