EVM Compatibility
Orbinum runs a standard EVM through Frontier. Solidity contracts deploy and execute unmodified, and the usual Ethereum tooling connects without a custom adapter.
What works
- EVM bytecode — deploy Solidity contracts as-is
- Ethereum JSON-RPC — MetaMask, Hardhat, Foundry, Remix, ethers.js, viem
- Transaction types — Legacy, EIP-2930, EIP-1559, EIP-7702
- EIP-1559 fee market — dynamic base fee with priority tips
- Transient storage — EIP-1153
- Precompiles
0x01–0x05— ecRecover, SHA-256, RIPEMD-160, identity, modexp
The one gap: precompiles 0x06–0x09
The BN128 precompiles (0x06 add, 0x07 mul, 0x08 pairing) and BLAKE2F (0x09) are not
currently registered.
This affects contracts that verify ZK proofs on-chain — a snarkjs-generated Groth16Verifier.sol,
Semaphore, Tornado-style mixers, or any BLS/pairing-based scheme. All of them call 0x08.
A call to an unregistered precompile address does not revert. The EVM treats it as a call to an
empty account: the call succeeds and returns empty data. A verifier contract that decodes that
result as false will reject every valid proof without any error to trace.
If your contract depends on pairing operations, test it on testnet before building on top of it.
Orbinum's own privacy layer does not go through these precompiles — proofs are verified natively by
pallet-zk-verifier in the runtime, which is both cheaper and faster than an in-EVM pairing check.
For on-chain ZK verification, see the ShieldedPool precompile.
Network parameters
| Field | Value |
|---|---|
| Network | Orbinum Testnet |
| Chain ID | 2700 |
| Native currency | ORB (18 decimals) |
| HTTP RPC | https://rpc-1.testnet.orbinum.io |
| WebSocket | wss://rpc-1.testnet.orbinum.io |
| Explorer | explorer.testnet.orbinum.network |
| Test tokens | faucet.orbinum.network — 5 ORB per 24 h |
A node started with --dev uses Chain ID 42. Chain ID 270 is reserved for
mainnet in the runtime genesis presets, but mainnet is not live — do not
configure wallets or contracts against it.
Example: paying a Substrate-native account from Solidity
This is something a plain EVM chain cannot do. The Balances precompile lets a contract send native
tokens to an AccountId32 that has no EVM address at all:
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;
interface IBalances {
function transfer(bytes32 dest, uint256 value) external;
function transferKeepAlive(bytes32 dest, uint256 value) external;
}
contract Payouts {
IBalances constant balances =
IBalances(0x0000000000000000000000000000000000000802);
/// @param recipient AccountId32 of a Substrate-native account
function payout(bytes32 recipient, uint256 amount) external {
balances.transferKeepAlive(recipient, amount);
}
}
Standard Solidity, standard tooling — the only difference is the precompile address.
Learn More
📄️ @orbinum/protocol
The public TypeScript SDK — chain access, addresses, payment slips. It holds no keys.
📄️ @orbinum/wallet-sdk
The custody half of the protocol — what it holds, why it is closed, and how to get access.
📄️ EVM Compatibility
What works out of the box, and the one gap to know about.
📄️ Precompile Addresses
Every precompile Orbinum registers, at its real address.
📄️ ShieldedPool
Address: 0x0000000000000000000000000000000000000801
📄️ Balances
Address: 0x0000000000000000000000000000000000000802