EVM
Armchain runs a full Ethereum Virtual Machine (EVM) supporting the London hard fork. If you've written Solidity contracts for Ethereum, they'll work on Armchain without any changes. The differences are at the network and signing level, not the contract level.
This page covers EVM compatibility details, gas costs, precompiled contracts, and what's different from Ethereum.
EVM Version and Hard Fork Support
Homestead
✅ Supported
Basic EVM
Byzantium
✅ Supported
REVERT, precompiles, STATICCALL
Constantinople
✅ Supported
CREATE2, bitwise shifting
Istanbul
✅ Supported
CHAINID opcode, gas repricing
Berlin
✅ Supported
EIP-2929 (gas cost changes), EIP-2930 (access lists)
London
✅ Supported
EIP-1559 (dynamic base fee), EIP-3529 (refund reduction)
Shanghai
❌ Not yet
PUSH0 opcode
Solidity Compiler Compatibility
Use Solidity 0.8.x for best results. Recommended pragma:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;Avoid Shanghai/Cancun features (e.g.,
PUSH0, transient storage) as they are not yet supported.
How the EVM Fits into Armchain
State Transition
The state transition model is a fork of go-ethereum's core/state_transition.go, adapted for Armchain:
Pre-validation: Check nonce, balance, gas limits
Gas purchase: Deduct upfront gas cost from sender
EVM execution: Run contract bytecode
Gas refund: Refund unused gas (with EIP-3529 limits)
Reward: Validator receives transaction fees
Key Differences from Ethereum
Block Production
Single proposer per slot
All validators create events in parallel
Finality
~15 minutes (2 epochs)
Instant (aBFT)
Block Time
12 seconds fixed
Variable (event-driven)
Transaction Signing
ECDSA (secp256k1)
ML-DSA44 (Type 3)
Empty Block Policy
Always produces blocks
Skips empty blocks (1 min devnet, 3s fakenet)
Transaction Pool
Armchain maintains a standard Ethereum-compatible transaction pool (mempool):
Gas Price Model (EIP-1559)
Armchain uses EIP-1559 dynamic fee pricing:
Minimum Gas Price
1 Gwei
Max Block Gas
20,500,000
Base Fee Adjustment
EIP-1559 algorithm
Precompiled Contracts
Armchain supports all Ethereum precompiles through Berlin, plus a new PQC-specific precompile:
0x01
ecRecover
ECDSA public key recovery (retained for smart contract compatibility; not used for Armchain transaction signing)
0x02
SHA-256
SHA-256 hash
0x03
RIPEMD-160
RIPEMD-160 hash
0x04
Identity
Data copy
0x05
ModExp
Modular exponentiation
0x06
ecAdd
BN256 point addition
0x07
ecMul
BN256 scalar multiplication
0x08
ecPairing
BN256 pairing check
0x09
Blake2F
BLAKE2b compression
0x13
pqcRecover
ML-DSA44 signature recovery (Armchain-specific)
pqcRecover Precompile (0x13)
The pqcRecover precompile recovers the signer's Ethereum address from an ML-DSA44 signature. This is the post-quantum equivalent of ecRecover and is the correct precompile to use for on-chain signature verification on Armchain.
Input: signatureBlob (3,732 bytes, containing the ML-DSA44 signature + public key)
Output: 32-byte padded address (last 20 bytes are the signer's address)
Behavior:
Validates the ML-DSA44 signature format
Extracts the public key from the signature blob
Derives the Ethereum address from the ML-DSA44 public key (
keccak256(publicKey), last 20 bytes)Returns the 32-byte zero-padded address
Solidity usage:
Note:
ecRecover(0x01) still exists for backward compatibility with contracts that use ECDSA internally (e.g., signature verification of off-chain ECDSA signatures). However, all Armchain transaction signatures use ML-DSA44, sopqcRecover(0x13) should be used for verifying Armchain transaction/message signatures on-chain.
Smart Contract Considerations
Contract Size Limit
The maximum smart contract bytecode size is 24,576 bytes (same as Ethereum's EIP-170 limit).
Gas Costs
Gas costs follow Berlin pricing:
Simple transfer
21,000
Storage write (cold)
20,000
Storage write (warm)
5,000
Storage read (cold)
2,100
Storage read (warm)
100
Contract creation
32,000 + bytecode costs
CALL (cold)
2,600
LOG per topic
375
Token Standards
All standard ERC token interfaces work on Armchain:
ERC-20: Fungible tokens
ERC-721: Non-fungible tokens (NFTs)
ERC-1155: Multi-token standard
ERC-4626: Tokenized vaults
Solidity Example
This deploys and works identically on Armchain as it would on Ethereum.
Account Abstraction Opcodes
Armchain's native Account Abstraction introduces additional EVM opcodes beyond the standard London opcode set. These opcodes support the AA execution model: invoking account validation contracts, managing paymaster interactions, and enforcing gas accounting at the protocol level.
These opcodes are not part of the standard Ethereum opcode set and are not recognized by the Solidity compiler (solc). Any contract that uses them must be written in Yul, the EVM intermediate representation language. This affects:
AA validation scheme contracts (MLDSA, Passkey, SLH-DSA, MPC wallets)
Paymaster contracts that interact with AA-specific execution hooks
Custom account validation logic written by third-party developers
Standard Solidity contracts that do not interact with these opcodes are unaffected and compile normally.
For more on the AA system contracts and the Yul requirement, see Account Abstraction: System Contracts.
Further Reading
Consensus (Lachesis aBFT): How blocks are produced
Transaction Lifecycle: From submission to EVM execution
Smart Contract Development: Writing contracts for Armchain
Transaction Types: Type 3 PQC transactions
Account Abstraction: Native AA and how it uses the EVM
Last updated