Precompiles Overview
OXN offers two families of precompiles:
- Standard EVM precompiles — identical to Ethereum, at addresses
0x01–0x0a. Used forecrecover,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
| Function | Purpose | Category |
|---|---|---|
Sapphire.randomBytes(uint, bytes) | TEE-attested random bytes | Randomness |
Sapphire.encrypt(...) | Deoxys-II symmetric encryption | Encryption |
Sapphire.decrypt(...) | Deoxys-II symmetric decryption | Encryption |
Sapphire.deriveSymmetricKey(pub, priv) | X25519 shared secret derivation | Key Derivation |
Sapphire.generateSigningKeyPair(alg, seed) | Ed25519 / secp256k1 / sr25519 keypair generation | Signatures |
Sapphire.sign(alg, sk, ctx, msg) | Sign a message with a private key held by the contract | Signatures |
Sapphire.verify(alg, pk, ctx, msg, sig) | Verify a signature | Signatures |
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 0x01–0x09 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
- Standard EVM Precompiles — support matrix
- Randomness — secure on-chain randomness
- Signatures — sign, verify, generate keypairs