Skip to main content

EVM Precompiles

Precompiles are special contracts accessible at fixed addresses that execute native runtime logic instead of EVM bytecode. They allow EVM clients — including MetaMask and other Ethereum wallets — to interact directly with Substrate pallets and cryptographic primitives without needing a custom JSON-RPC endpoint.

Orbinum exposes three groups of precompiles: Ethereum standard precompiles, Frontier non-standard precompiles, and Orbinum-specific precompiles.


Address Convention

Precompile addresses follow the Frontier convention:

H160::from_low_u64_be(n)

where n is a small integer. This produces an address of the form 0x0000000000000000000000000000000000000NNN.


Ethereum Standard Precompiles

These are the precompiles defined in the Ethereum Yellow Paper and its EIPs. They are available at the same addresses as Ethereum mainnet.

AddressNameDescription
0x0000000000000000000000000000000000000001ECRecoverECDSA signature recovery
0x0000000000000000000000000000000000000002SHA-256SHA-2 256-bit hash
0x0000000000000000000000000000000000000003RIPEMD-160RIPEMD 160-bit hash
0x0000000000000000000000000000000000000004IdentityData copy (identity function)
0x0000000000000000000000000000000000000005ModexpModular exponentiation (EIP-198)

Frontier Non-Standard Precompiles

These precompiles are provided by Frontier for Substrate-based chains. They are not part of the Ethereum standard and are only available on Frontier-compatible networks.

AddressNameDescription
0x0000000000000000000000000000000000000400SHA3-FIPS-256FIPS 202-compliant Keccak-256
0x0000000000000000000000000000000000000401ECRecoverPublicKeyECDSA public key recovery
0x0000000000000000000000000000000000000402Curve25519AddCurve25519 point addition
0x0000000000000000000000000000000000000403Curve25519ScalarMulCurve25519 scalar multiplication

Orbinum Precompiles

These precompiles expose Orbinum-specific runtime pallets to EVM clients. They are deployed in the 0x08000x08FF range to avoid collisions with standard and Frontier precompiles.

AddressNameDescription
0x0000000000000000000000000000000000000800AccountMappingLink EVM and Substrate accounts
0x0000000000000000000000000000000000000801ShieldedPoolShield, transfer, and unshield tokens using ZK proofs

Address Derivation

Orbinum precompile indices map as follows:

IndexHex Address
2048 (0x800)0x…0000000000000000000000000000000000000800
2049 (0x801)0x…0000000000000000000000000000000000000801

Calling a Precompile

From Solidity:

interface IShieldedPool {
function shield(
uint32 assetId,
uint256 amount,
bytes32 commitment,
bytes calldata encryptedMemo
) external;
}

IShieldedPool pool = IShieldedPool(0x0000000000000000000000000000000000000801);
pool.shield(0, 1e18, commitment, memo);

From ethers.js:

import { ethers } from "ethers";

const abi = ["function shield(uint32,uint256,bytes32,bytes)"];
const precompile = new ethers.Contract(
"0x0000000000000000000000000000000000000801",
abi,
signer
);
await precompile.shield(0, ethers.parseEther("1"), commitment, memo);

Security Notes

  • Orbinum precompiles use AddressMapping to derive the caller's AccountId32 from the EVM H160 sender. No signature verification is repeated inside the precompile — the EVM transaction already provides authentication.
  • Precompiles do not return values beyond a success indicator. Use RPC or events to confirm state changes.
  • Gas costs are estimated conservatively. They may be adjusted before mainnet.