Skip to main content

EVM Compatibility Layer

Nigo Protocol provides an EVM for general Solidity contracts and an Ethereum JSON-RPC adapter. It does not, however, replicate Ethereum mainnet's account, state, fee, or consensus models in the Nigo ledger.

Evaluate compatibility across four separate areas:

  1. EVM execution: bytecode, opcodes, call/create, gas, and precompiles
  2. Transaction ingress: supported signed Ethereum envelopes and nonce/fee validation
  3. JSON-RPC projection: SDK methods and the queryable state scope
  4. Nigo policy: StateCell commitments, ZERO/FIXED fees, and finalized-only queries

Support in one area must not be interpreted as complete Ethereum compatibility.

Layer structure

The compatibility layer converts an Ethereum raw transaction into a validated Nigo transaction carrier. Execution finalizes as a Nigo receipt and StateCell delta, which the Ethereum RPC adapter projects as transactions, receipts, logs, and blocks.

Execution revisions

Execution modeRevisionPurpose
General EVMOsakaSolidity contract deployment and calls
Native validatorParisConstrained execution pinned by an immutable descriptor

The general execution profile targets Osaka and includes opcode activation boundaries introduced in Shanghai, Cancun, and Prague. Nigo does not expose each of those historical revisions as a separate, complete public execution profile.

Native Programs use a different policy from general contracts. They share the interpreter, but their descriptor pins the Paris revision and restricts opcodes such as state reads and external calls. See Native Program.

Contract execution

The current general EVM includes these execution boundaries:

  • contract deployment with CREATE and CREATE2;
  • CALL, CALLCODE, DELEGATECALL, and STATICCALL;
  • per-child-frame checkpoints for state, logs, return data, and gas;
  • rollback on call/create failure and revert;
  • transaction-scoped transient storage and context;
  • constrained SELFDESTRUCT following EIP-6780;
  • StateCell persistence for EVM storage slots, account nonces, and code references; and
  • canonical inclusion of transaction logs in receipts.

Built-in bytecode frames run through an explicit frame scheduler so the protocol maximum depth does not depend directly on Java method recursion. This guarantee does not extend to arbitrary recursion inside custom Java contracts or providers.

Precompiles

The support catalog maintains revision activation and gas rules together.

Address rangeFunction
0x01..0x04ECRECOVER, SHA-256, RIPEMD-160, IDENTITY
0x05Modular exponentiation
0x06..0x08BN254 add, mul, pairing
0x09BLAKE2F
0x0aKZG point evaluation
0x0b..0x11EIP-2537 BLS12-381 family
0x100EIP-7951 P-256 signature verification

Provider-backed cryptography validates input shape, field and subgroup membership, canonical output, and gas policy at the VM boundary. Packaged JARs, supported platforms, provider faults, licenses/notices, and the SBOM require separate release evidence.

Supported transaction envelopes

Ethereum formatNigo kindStatus
Legacy EIP-155EVM(2)Supported
EIP-1559 type 2EVM_TYPE2(4)Supported
EIP-7702 type 4EVM_SET_CODE(3)Supported
Pre-EIP-155 legacyNoneRejected
EIP-2930 type 1NoneUnsupported
EIP-4844 type 3 blob transactionNoneUnsupported

Types 2 and 4 preserve the signed raw bytes as the authoritative body. Chain ID, nonce, fee fields, value, calldata, access list, and signature are revalidated from the raw transaction; only the Nigo-specific fee-funding identity is added in a separate carrier.

A supported envelope does not imply the full Ethereum transaction policy. For example, Nigo supports the type-2 wire format but does not reproduce Ethereum's base-fee adjustment, burn, priority auction, or replacement policy in its fee settlement.

Fee-policy differences

The current chain profile canonically represents ZERO and FIXED fees.

ProfileExact type-2 fee pair
ZERO(maxPriorityFeePerGas, maxFeePerGas) = (0, 0)
FIXED P(0, P)

eth_gasPrice returns the active Nigo price, while eth_maxPriorityFeePerGas currently returns 0. These values are not a quote from Ethereum's public fee market. Clients must use the exact fee required by the active profile.

State and block-context differences

EVM accounts, code, and storage commit into Nigo StateCells and the compact SMT state root. Consequently:

  • Nigo does not produce an Ethereum account Merkle Patricia Trie root.
  • eth_getProof does not return Ethereum MPT account/storage proofs.
  • EVM storage slots are stored as StateCells in the EVM domain.
  • Canonical account nonces follow a StateCell-based lifecycle.
  • Context fields that Nigo consensus does not supply—COINBASE, PREVRANDAO, BASEFEE, and BLOBBASEFEE—may use zero under the active profile policy.
  • GASLIMIT reflects the Nigo block gas limit.

These are intentional chain-policy differences, not compatibility shims hiding missing implementation.

JSON-RPC support boundaries

The current inventory contains 20 implemented Ethereum/Web3 methods. Some have semantic constraints and are classified as CONDITIONAL.

Directly supported

web3_clientVersion
net_version
eth_chainId
eth_blockNumber
eth_getTransactionByHash

Conditionally supported

net_listening
eth_syncing
eth_gasPrice
eth_maxPriorityFeePerGas
eth_getBalance
eth_getTransactionCount
eth_getCode
eth_getStorageAt
eth_call
eth_estimateGas
eth_sendRawTransaction
eth_getTransactionReceipt
eth_getBlockByNumber
eth_getBlockByHash
eth_getLogs

The main constraints are:

  • State queries and simulations use the current finalized state.
  • latest, safe, and finalized may all resolve to the current finalized view; historical and pending state are unavailable.
  • Pending nonce projection includes at most one canonical reservation.
  • Receipts, blocks, and logs expose finalized locations.
  • Large log ranges require bounded pagination.
  • net_listening and eth_syncing are not indicators of operational readiness or sync progress.

Unsupported areas

  • eth_fillTransaction
  • server-managed filter lifecycle
  • WebSocket eth_subscribe / eth_unsubscribe
  • eth_getProof
  • admin_*, debug_*, and trace_*

An application that requires an unsupported method must not be classified as a configuration-only migration. Distinguish replaceable flows such as stateless eth_getLogs polling from flows that require an explicit feature decision, such as pending streams or execution traces.

SDK validation boundaries

Pinned validation flows in the repository target:

  • ethers 6.17.0
  • viem 2.55.19
  • Web3j 4.10.0

The validation scope includes contract deployment, calls, state changes, events, receipts, NIGO value, and reads after restarting against the same database. This is evidence for the specified versions and tested flows; it does not imply every SDK version, every API, or drop-in compatibility for existing dApps.

Type-4 authoring and signing with Web3j 4.10.0 is not in the validated scope. Evaluate protocol-level type-4 execution support separately from a particular SDK's authoring capability.

Compatibility assessment checklist

Before migrating an application to BXDL/Nigo, determine:

  1. Does it create legacy, type-2, or type-4 envelopes?
  2. Does it depend on Ethereum base-fee, tip, or replacement semantics?
  3. Does it require historical or pending state?
  4. Does it require WebSocket subscriptions, server filters, traces, or MPT proofs?
  5. Does it queue multiple pending nonces for one account?
  6. Are its opcodes and precompiles active in the Osaka profile?
  7. Can its SDK set the exact Nigo fee pair?

Next