# EVM Compatibility

### Overview

OPN Chain provides full Ethereum Virtual Machine (EVM) compatibility, allowing developers to deploy existing Ethereum smart contracts without modification. This compatibility extends beyond basic functionality to include the latest Ethereum improvements, development tools, and ecosystem standards.

### Compatibility Levels

#### 1. Binary Compatibility

**Complete Bytecode Support:**

* All EVM opcodes supported
* Identical gas costs for operations
* Same execution semantics
* Bit-for-bit compatibility

**Example:**

```solidity
// This Ethereum contract works identically on OPN Chain
contract Example {
    mapping(address => uint256) public balances;
    
    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }
    
    function withdraw(uint256 amount) public {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        balances[msg.sender] -= amount;
        payable(msg.sender).transfer(amount);
    }
}
```

#### 2. API Compatibility

**JSON-RPC Compliance:**

```javascript
// All standard Ethereum RPC methods work
const web3 = new Web3('https://testnet-rpc.iopn.tech');

// Ethereum methods work identically
const balance = await web3.eth.getBalance(address);
const block = await web3.eth.getBlock('latest');
const receipt = await web3.eth.getTransactionReceipt(txHash);
```

**Supported Method Namespaces:**

* `web3_*` - Client version, SHA3
* `net_*` - Network ID, peer count, listening status
* `eth_*` - All standard Ethereum methods
* `debug_*` - Debugging and tracing
* `txpool_*` - Transaction pool inspection

#### 3. Tool Compatibility

**Development Frameworks:**

| Tool    | Compatibility | Notes                   |
| ------- | ------------- | ----------------------- |
| Hardhat | ✅ Full        | No modifications needed |
| Truffle | ✅ Full        | Standard config works   |
| Foundry | ✅ Full        | Native support          |
| Remix   | ✅ Full        | Direct deployment       |
| Brownie | ✅ Full        | Python framework        |
| Ape     | ✅ Full        | Modern Python tool      |

**Example Hardhat Config:**

```javascript
module.exports = {
  networks: {
    opn: {
      url: "https://testnet-rpc.iopn.tech",
      chainId: 984,
      accounts: [process.env.PRIVATE_KEY]
    }
  },
  solidity: "0.8.30"
};
```

#### 4. Library Compatibility

**Web3 Libraries:**

```javascript
// Web3.js
const Web3 = require('web3');
const web3 = new Web3('https://testnet-rpc.iopn.tech');

// Ethers.js
const { ethers } = require('ethers');
const provider = new ethers.providers.JsonRpcProvider('https://testnet-rpc.iopn.tech');

// Viem
import { createPublicClient, http } from 'viem';
const client = createPublicClient({
  chain: opnChain,
  transport: http('https://testnet-rpc.iopn.tech')
});
```

### Smart Contract Standards

#### ERC Standards Support

| Standard | Description         | Support |
| -------- | ------------------- | ------- |
| ERC-20   | Fungible tokens     | ✅ Full  |
| ERC-721  | Non-fungible tokens | ✅ Full  |
| ERC-1155 | Multi tokens        | ✅ Full  |
| ERC-165  | Interface detection | ✅ Full  |
| ERC-2981 | NFT royalties       | ✅ Full  |
| ERC-4626 | Tokenized vaults    | ✅ Full  |
| ERC-4337 | Account abstraction | ✅ Full  |

#### Example Implementations

**ERC-20 Token:**

```solidity
// Standard OpenZeppelin ERC-20 works perfectly
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {
        _mint(msg.sender, 1000000 * 10**18);
    }
}
```

**ERC-721 NFT:**

```solidity
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract MyNFT is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    
    constructor() ERC721("MyNFT", "MNFT") {}
    
    function mint(address to) public returns (uint256) {
        _tokenIds.increment();
        uint256 newTokenId = _tokenIds.current();
        _mint(to, newTokenId);
        return newTokenId;
    }
}
```

### Address System

#### Address Format

OPN Chain uses the standard Ethereum address format:

* 20-byte addresses (40 hex characters)
* Checksummed addresses supported
* Same derivation paths as Ethereum

```javascript
// Address validation works identically
function isValidAddress(address) {
    return /^0x[a-fA-F0-9]{40}$/.test(address);
}

// Checksum validation
const { toChecksumAddress, isAddress } = require('ethereum-address');
const checksummed = toChecksumAddress('0x742d35cc6634c0532925a3b844bc9e7595f2bd40');
```

#### Key Derivation

**HD Wallet Compatibility:**

```javascript
// Same derivation path as Ethereum
const hdPath = "m/44'/60'/0'/0/0";

// Works with all Ethereum wallets
const { hdkey } = require('ethereumjs-wallet');
const { mnemonicToSeedSync } = require('bip39');

const seed = mnemonicToSeedSync(mnemonic);
const hdWallet = hdkey.fromMasterSeed(seed);
const wallet = hdWallet.derivePath(hdPath).getWallet();
```

### Transaction Format

#### Transaction Types

OPN Chain supports all Ethereum transaction types:

**Legacy Transactions (Type 0):**

```javascript
{
  nonce: '0x0',
  gasPrice: '0x1a13b8600', // 7 Gwei
  gasLimit: '0x5208',
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD40',
  value: '0xde0b6b3a7640000', // 1 ETH in wei
  data: '0x',
  v: '0x7e5', // chainId * 2 + 35
  r: '0x...',
  s: '0x...'
}
```

**EIP-2930 Access List Transactions (Type 1):**

```javascript
{
  chainId: '0x3d8',
  nonce: '0x0',
  gasPrice: '0x1a13b8600',
  gasLimit: '0x5208',
  to: '0x...',
  value: '0x...',
  data: '0x',
  accessList: [
    {
      address: '0x...',
      storageKeys: ['0x...', '0x...']
    }
  ]
}
```

**EIP-1559 Transactions (Type 2):**

```javascript
{
  chainId: '0x3d8',
  nonce: '0x0',
  maxPriorityFeePerGas: '0x3b9aca00', // 1 Gwei
  maxFeePerGas: '0x2540be400', // 10 Gwei
  gasLimit: '0x5208',
  to: '0x...',
  value: '0x...',
  data: '0x',
  accessList: []
}
```

### Gas Compatibility

#### Gas Costs

OPN Chain uses Ethereum-compatible gas costs:

```solidity
// Gas costs match Ethereum exactly
contract GasExample {
    uint256 public value; // SSTORE: 20,000 gas (new slot)
    
    function update(uint256 newValue) public {
        value = newValue; // SSTORE: 5,000 gas (update)
    }
    
    function read() public view returns (uint256) {
        return value; // SLOAD: 2,100 gas
    }
}
```

#### Gas Estimation

```javascript
// Gas estimation works identically
const contract = new web3.eth.Contract(abi, address);

// Estimate gas for a transaction
const gasEstimate = await contract.methods
  .transfer(recipient, amount)
  .estimateGas({ from: sender });

// Add 10% buffer for safety
const gasLimit = Math.floor(gasEstimate * 1.1);
```

### Event System

#### Event Emission

```solidity
contract EventExample {
    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );
    
    function transfer(address to, uint256 value) public {
        // Event emission identical to Ethereum
        emit Transfer(msg.sender, to, value);
    }
}
```

#### Event Filtering

```javascript
// Event filtering works exactly like Ethereum
const filter = {
    address: contractAddress,
    topics: [
        web3.utils.sha3('Transfer(address,address,uint256)'),
        null, // any from address
        web3.utils.padLeft(toAddress, 64) // specific to address
    ],
    fromBlock: 0,
    toBlock: 'latest'
};

const events = await web3.eth.getPastLogs(filter);
```

### State Management

#### Storage Layout

Storage layout matches Ethereum exactly:

```solidity
contract StorageExample {
    uint256 a;      // slot 0
    uint256 b;      // slot 1
    address c;      // slot 2 (uses 20 bytes)
    bool d;         // slot 2 (uses 1 byte, packed with c)
    
    mapping(address => uint256) e; // slot 3 (base slot)
    uint256[] f;    // slot 4 (length), data at keccak256(4)
}
```

#### State Access

```javascript
// Direct storage access works identically
const slot0 = await web3.eth.getStorageAt(contractAddress, 0);
const slot1 = await web3.eth.getStorageAt(contractAddress, 1);

// Mapping access calculation
const mappingSlot = 3;
const key = '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD40';
const dataSlot = web3.utils.soliditySha3(
    { type: 'address', value: key },
    { type: 'uint256', value: mappingSlot }
);
const value = await web3.eth.getStorageAt(contractAddress, dataSlot);
```

### Precompiled Contracts

All Ethereum precompiled contracts are available:

```solidity
contract PrecompileExample {
    // ecrecover at 0x01
    function recoverSigner(bytes32 hash, uint8 v, bytes32 r, bytes32 s) 
        public pure returns (address) 
    {
        return ecrecover(hash, v, r, s);
    }
    
    // SHA256 at 0x02
    function hashSHA256(bytes memory data) public pure returns (bytes32) {
        return sha256(data);
    }
    
    // And all others...
}
```

### Differences from Ethereum

#### Block Time

The main difference is block time:

```javascript
// OPN Chain: ~1 second blocks
// Ethereum: ~12 second blocks

// Adjust time-based logic accordingly
contract TimeAware {
    // Ethereum: 7200 blocks ≈ 1 day
    // OPN Chain: 86400 blocks ≈ 1 day
    uint256 constant BLOCKS_PER_DAY = 86400;
}
```

#### Finality Model

```javascript
// OPN Chain has instant finality
// No need to wait for confirmations

const receipt = await web3.eth.sendTransaction(tx);
// Transaction is immediately final after 1 confirmation

// Ethereum requires multiple confirmations
// OPN Chain is final after 1 block
```

#### Gas Price Stability

```javascript
// OPN Chain has stable gas prices
const gasPrice = await web3.eth.getGasPrice();
// Always returns minimum (7 Gwei) or slightly above

// No need for complex gas price strategies
const tx = {
    gasPrice: '7000000000', // 7 Gwei always works
    // No need for maxFeePerGas/maxPriorityFeePerGas complexity
};
```

### Migration Guide

#### From Ethereum

1. **Update RPC Endpoint:**

```javascript
// Old
const web3 = new Web3('https://mainnet.infura.io/v3/...');

// New
const web3 = new Web3('https://testnet-rpc.iopn.tech');
```

2. **Update Chain ID:**

```javascript
// Old
const chainId = 1; // Ethereum mainnet

// New  
const chainId = 984; // OPN Chain
```

3. **Adjust Block Timing:**

```solidity
// Old (Ethereum)
uint256 constant DAY = 7200; // blocks

// New (OPN)
uint256 constant DAY = 86400; // blocks
```

That's it! Everything else remains the same.

#### Testing Compatibility

```javascript
// Test script to verify compatibility
async function testCompatibility() {
    const web3 = new Web3('https://testnet-rpc.iopn.tech');
    
    console.log('Testing OPN Chain compatibility...');
    
    // Test 1: Basic connectivity
    const chainId = await web3.eth.getChainId();
    console.assert(chainId === 984, 'Chain ID matches');
    
    // Test 2: Account access
    const accounts = await web3.eth.getAccounts();
    console.log('Accounts accessible:', accounts.length > 0);
    
    // Test 3: Gas estimation
    const gasPrice = await web3.eth.getGasPrice();
    console.log('Gas price:', web3.utils.fromWei(gasPrice, 'gwei'), 'Gwei');
    
    // Test 4: Block data
    const block = await web3.eth.getBlock('latest');
    console.log('Latest block:', block.number);
    
    console.log('✅ All compatibility tests passed!');
}

testCompatibility().catch(console.error);
```

### Best Practices

#### 1. Use Standard Tools

Stick to standard Ethereum development tools:

* OpenZeppelin for contracts
* Hardhat/Foundry for development
* Ethers.js/Web3.js for integration

#### 2. Test Thoroughly

```javascript
// Use the same test suites
describe('Token Contract', () => {
    it('should deploy on OPN Chain', async () => {
        const Token = await ethers.getContractFactory('Token');
        const token = await Token.deploy();
        await token.deployed();
        
        expect(await token.totalSupply()).to.equal(expectedSupply);
    });
});
```

#### 3. Monitor Differences

```javascript
// Account for block time differences in time-sensitive contracts
contract Auction {
    uint256 constant DURATION = 86400; // 1 day in blocks on OPN
    
    uint256 public endBlock;
    
    function startAuction() public {
        endBlock = block.number + DURATION;
    }
}
```

### Conclusion

OPN Chain's EVM compatibility means you can bring your entire Ethereum toolkit, knowledge, and existing contracts to a faster, more efficient blockchain. The few differences (like block time) are easy to account for, while the benefits of instant finality and low, stable gas costs make development simpler and more predictable.

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://iopn.gitbook.io/iopn/developer-docs/core-concepts/evm-compatibility.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
