Skip to main content

Precompiles Overview

OXN offers two families of precompiles:

  • Standard EVM precompiles — identical to Ethereum, at addresses 0x010x0a. Used for ecrecover, sha256, elliptic curve math, and other common primitives.
  • OXN confidential precompiles — additional built-ins for encryption, randomness, key derivation, and signing. These are what make confidential smart contracts practical.

All confidential precompiles are wrapped by the Sapphire Solidity library. Import it and call the functions — you never have to construct raw staticcall invocations yourself.

The confidential precompile catalog

FunctionPurposeCategory
Sapphire.randomBytes(uint, bytes)TEE-attested random bytesRandomness
Sapphire.encrypt(...)Deoxys-II symmetric encryptionEncryption
Sapphire.decrypt(...)Deoxys-II symmetric decryptionEncryption
Sapphire.deriveSymmetricKey(pub, priv)X25519 shared secret derivationKey Derivation
Sapphire.generateSigningKeyPair(alg, seed)Ed25519 / secp256k1 / sr25519 keypair generationSignatures
Sapphire.sign(alg, sk, ctx, msg)Sign a message with a private key held by the contractSignatures
Sapphire.verify(alg, pk, ctx, msg, sig)Verify a signatureSignatures

Full parameter details are on each linked reference page.

Installing the Sapphire library

The Solidity wrappers live in @oasisprotocol/sapphire-contracts:

npm install @oasisprotocol/sapphire-contracts

Import in your contract:

import "@oasisprotocol/sapphire-contracts/contracts/Sapphire.sol";

contract MyContract {
function makeRandom() external view returns (bytes memory) {
return Sapphire.randomBytes(32, "");
}
}

Standard EVM precompile support

Every Ethereum precompile at 0x010x09 is supported. 0x0a (pointEvaluation, EIP-4844 KZG) is not supported — OXN does not have blob transactions.

See Standard EVM Precompiles for the full support matrix.

Common patterns

On-chain randomness for a raffle:

function pickWinner() external view returns (address) {
bytes memory r = Sapphire.randomBytes(32, "");
uint256 idx = uint256(bytes32(r)) % participants.length;
return participants[idx];
}

Contract-controlled off-chain signing:

bytes private signingKey; // encrypted in storage

function initialize() external onlyOwner {
(bytes memory pk, bytes memory sk) = Sapphire.generateSigningKeyPair(
Sapphire.SigningAlg.Ed25519_Pure, "seed"
);
signingKey = sk;
// expose pk publicly for verifiers
}

function signMessage(bytes calldata msg_) external returns (bytes memory) {
require(canSign(msg.sender, msg_), "not authorized");
return Sapphire.sign(
Sapphire.SigningAlg.Ed25519_Pure,
signingKey,
"context",
msg_
);
}

Encrypted messaging between users:

// Alice sends a symmetric key to Bob via X25519 derivation
bytes32 shared = Sapphire.deriveSymmetricKey(bobsPublicKey, alicesPrivateKey);
bytes memory ciphertext = Sapphire.encrypt(shared, nonce, plaintext, "");

See Guides for full application examples.

Gas costs

Each precompile has a base gas cost plus a per-byte cost for payload size. See Gas Cost Reference for exact numbers.

Next steps