# Ethereum Methods

The `eth_*` namespace contains all core Ethereum protocol methods. OPN Chain implements every standard Ethereum JSON-RPC method, ensuring complete compatibility.

### Table of Contents

#### Reading Blockchain Data

* eth\_blockNumber - Get latest block number
* eth\_getBalance - Get account balance
* eth\_getCode - Get contract code
* eth\_getStorageAt - Get storage value
* eth\_getBlockByHash - Get block by hash
* eth\_getBlockByNumber - Get block by number
* eth\_getTransactionByHash - Get transaction
* eth\_getTransactionReceipt - Get receipt

#### Sending Transactions

* eth\_sendRawTransaction - Send signed transaction
* eth\_call - Execute call without creating transaction
* eth\_estimateGas - Estimate gas needed

#### Network Information

* eth\_chainId - Get chain ID
* eth\_gasPrice - Get current gas price
* eth\_syncing - Get sync status
* eth\_mining - Check if mining
* eth\_hashrate - Get hashrate

#### Account Methods

* eth\_accounts - List accounts
* eth\_getTransactionCount - Get nonce

#### Filters and Logs

* eth\_newFilter - Create log filter
* eth\_newBlockFilter - Create block filter
* eth\_getFilterChanges - Get filter updates
* eth\_getLogs - Get historical logs

***

### eth\_blockNumber

Returns the number of the most recent block.

#### Parameters

None

#### Returns

`QUANTITY` - Integer of the current block number

#### Example

```bash
# Request
curl -X POST https://testnet-rpc.iopn.tech \
  -H "Content-Type: application/json" \
  --data '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

# Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x5bad55" // 6008149 in decimal
}
```

**JavaScript:**

```javascript
const blockNumber = await web3.eth.getBlockNumber();
console.log('Latest block:', blockNumber);
```

***

### eth\_getBalance

Returns the balance of the account at given address.

#### Parameters

1. `DATA`, 20 bytes - Address to check balance
2. `QUANTITY|TAG` - Block number or "latest", "earliest", "pending"

#### Returns

`QUANTITY` - Balance in wei

#### Example

```javascript
// Get balance at latest block
const balance = await web3.eth.getBalance(
  '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD40',
  'latest'
);
console.log('Balance:', web3.utils.fromWei(balance, 'ether'), 'OPN');

// Get balance at specific block
const historicalBalance = await web3.eth.getBalance(
  '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD40',
  1000000 // Block number
);
```

***

### eth\_getCode

Returns code at a given address.

#### Parameters

1. `DATA`, 20 bytes - Address
2. `QUANTITY|TAG` - Block number or tag

#### Returns

`DATA` - The code from the given address

#### Example

```javascript
// Check if address is a contract
async function isContract(address) {
  const code = await web3.eth.getCode(address);
  return code !== '0x';
}

// Get contract bytecode
const bytecode = await web3.eth.getCode(contractAddress);
console.log('Contract size:', (bytecode.length - 2) / 2, 'bytes');
```

***

### eth\_getStorageAt

Returns the value from a storage position at a given address.

#### Parameters

1. `DATA`, 20 bytes - Address
2. `QUANTITY` - Storage position
3. `QUANTITY|TAG` - Block number or tag

#### Returns

`DATA` - The value at this storage position

#### Example

```javascript
// Read storage slot 0
const value = await web3.eth.getStorageAt(
  contractAddress,
  0,
  'latest'
);

// Read mapping value
// For mapping at slot 1: mapping(address => uint)
function getMappingValue(address, slot) {
  const key = web3.utils.soliditySha3(
    { type: 'address', value: address },
    { type: 'uint256', value: slot }
  );
  return web3.eth.getStorageAt(contractAddress, key);
}
```

***

### eth\_getBlockByHash

Returns information about a block by hash.

#### Parameters

1. `DATA`, 32 bytes - Block hash
2. `Boolean` - If true returns full transaction objects, if false only hashes

#### Returns

`Object` - Block object or null

#### Example

```javascript
// Get block with transaction hashes
const block = await web3.eth.getBlock(
  '0x7d2f6e35ac8b29a07c3a6b8f892c7c0ce2d1b5fcbb0de7a295d1fb0c8f0dc0d3',
  false
);

// Get block with full transactions
const blockWithTxs = await web3.eth.getBlock(blockHash, true);

console.log('Block:', {
  number: block.number,
  timestamp: block.timestamp,
  transactions: block.transactions.length,
  gasUsed: block.gasUsed
});
```

***

### eth\_getBlockByNumber

Returns information about a block by number.

#### Parameters

1. `QUANTITY|TAG` - Block number or "latest", "earliest", "pending"
2. `Boolean` - If true returns full transaction objects

#### Returns

`Object` - Block object or null

#### Example

```javascript
// Get latest block
const latestBlock = await web3.eth.getBlock('latest');

// Get genesis block
const genesisBlock = await web3.eth.getBlock(0);

// Get block with full transactions
const block = await web3.eth.getBlock(1000000, true);

// Process block transactions
block.transactions.forEach(tx => {
  console.log(`TX ${tx.hash}: ${tx.from} -> ${tx.to}`);
});
```

#### Block Object Structure

```javascript
{
  number: 1234567,
  hash: '0x...',
  parentHash: '0x...',
  nonce: '0x0000000000000000',
  sha3Uncles: '0x...',
  logsBloom: '0x...',
  transactionsRoot: '0x...',
  stateRoot: '0x...',
  receiptsRoot: '0x...',
  miner: '0x0000000000000000000000000000000000000000',
  difficulty: '0x0',
  totalDifficulty: '0x0',
  extraData: '0x',
  size: 1234,
  gasLimit: 30000000,
  gasUsed: 21000,
  timestamp: 1640995200,
  transactions: [...],
  uncles: []
}
```

***

### eth\_getTransactionByHash

Returns information about a transaction by hash.

#### Parameters

1. `DATA`, 32 bytes - Transaction hash

#### Returns

`Object` - Transaction object or null

#### Example

```javascript
const tx = await web3.eth.getTransaction(
  '0x88df016429689c079f3b2f6ad39fa052532c56795b733da0e61eacf82bd8c7a5'
);

console.log('Transaction:', {
  from: tx.from,
  to: tx.to,
  value: web3.utils.fromWei(tx.value, 'ether'),
  gasPrice: web3.utils.fromWei(tx.gasPrice, 'gwei'),
  status: tx.blockNumber ? 'Mined' : 'Pending'
});
```

***

### eth\_getTransactionReceipt

Returns the receipt of a transaction by transaction hash.

#### Parameters

1. `DATA`, 32 bytes - Transaction hash

#### Returns

`Object` - Receipt object or null

#### Example

```javascript
const receipt = await web3.eth.getTransactionReceipt(txHash);

if (receipt) {
  console.log('Transaction receipt:', {
    status: receipt.status ? 'Success' : 'Failed',
    blockNumber: receipt.blockNumber,
    gasUsed: receipt.gasUsed,
    logs: receipt.logs.length
  });
  
  // Process events
  receipt.logs.forEach(log => {
    console.log('Event:', {
      address: log.address,
      topics: log.topics,
      data: log.data
    });
  });
}
```

#### Receipt Object Structure

```javascript
{
  transactionHash: '0x...',
  transactionIndex: 0,
  blockHash: '0x...',
  blockNumber: 1234567,
  from: '0x...',
  to: '0x...',
  cumulativeGasUsed: 21000,
  gasUsed: 21000,
  contractAddress: null, // or address if contract creation
  logs: [...],
  logsBloom: '0x...',
  status: true // true = success, false = failure
}
```

***

### eth\_sendRawTransaction

Submits a pre-signed transaction.

#### Parameters

1. `DATA` - Signed transaction data

#### Returns

`DATA`, 32 bytes - Transaction hash

#### Example

```javascript
// Sign transaction
const signedTx = await web3.eth.accounts.signTransaction({
  from: account.address,
  to: recipient,
  value: web3.utils.toWei('1', 'ether'),
  gas: 21000,
  gasPrice: await web3.eth.getGasPrice(),
  nonce: await web3.eth.getTransactionCount(account.address),
  chainId: 984
}, privateKey);

// Send signed transaction
const txHash = await web3.eth.sendSignedTransaction(
  signedTx.rawTransaction
);

console.log('Transaction sent:', txHash);

// Wait for confirmation
const receipt = await web3.eth.waitForTransactionReceipt(txHash);
console.log('Transaction confirmed in block:', receipt.blockNumber);
```

***

### eth\_call

Executes a new message call without creating a transaction.

#### Parameters

1. `Object` - Transaction call object
2. `QUANTITY|TAG` - Block number or tag

#### Returns

`DATA` - Return value of executed contract

#### Example

```javascript
// Call contract method without sending transaction
const result = await web3.eth.call({
  to: contractAddress,
  data: contract.methods.balanceOf(account).encodeABI()
}, 'latest');

// Decode result
const balance = web3.eth.abi.decodeParameter('uint256', result);

// Call with specific block
const historicalResult = await web3.eth.call({
  to: contractAddress,
  data: callData
}, 1000000); // Block number
```

#### Advanced Call Options

```javascript
// Call with all options
const result = await web3.eth.call({
  from: '0x...', // Optional: msg.sender
  to: contractAddress,
  gas: 100000, // Optional: gas limit
  gasPrice: '7000000000', // Optional: gas price
  value: '0', // Optional: msg.value
  data: encodedData
}, 'latest');
```

***

### eth\_estimateGas

Estimates gas needed for a transaction.

#### Parameters

1. `Object` - Transaction object (same as eth\_call)
2. `QUANTITY|TAG` - Optional block number

#### Returns

`QUANTITY` - Estimated gas amount

#### Example

```javascript
// Estimate simple transfer
const gasEstimate = await web3.eth.estimateGas({
  from: sender,
  to: recipient,
  value: web3.utils.toWei('1', 'ether')
});
console.log('Estimated gas:', gasEstimate);

// Estimate contract call
const contractGas = await contract.methods
  .transfer(recipient, amount)
  .estimateGas({ from: sender });

// Add buffer for safety
const gasLimit = Math.ceil(contractGas * 1.1);
```

***

### eth\_chainId

Returns the chain ID.

#### Parameters

None

#### Returns

`QUANTITY` - Chain ID (984 for OPN testnet)

#### Example

```javascript
const chainId = await web3.eth.getChainId();
console.log('Chain ID:', chainId); // 984

// Verify correct network
if (chainId !== 984) {
  throw new Error('Please connect to OPN testnet');
}
```

***

### eth\_gasPrice

Returns the current gas price.

#### Parameters

None

#### Returns

`QUANTITY` - Gas price in wei

#### Example

```javascript
const gasPrice = await web3.eth.getGasPrice();
console.log('Current gas price:', 
  web3.utils.fromWei(gasPrice, 'gwei'), 
  'Gwei'
);

// OPN Chain returns minimum 7 Gwei
// Use for transaction
const tx = {
  gasPrice: gasPrice,
  // ... other fields
};
```

***

### eth\_getTransactionCount

Returns the number of transactions sent from an address (nonce).

#### Parameters

1. `DATA`, 20 bytes - Address
2. `QUANTITY|TAG` - Block number or tag

#### Returns

`QUANTITY` - Transaction count

#### Example

```javascript
// Get current nonce
const nonce = await web3.eth.getTransactionCount(
  account.address,
  'latest'
);

// Get pending nonce (includes pending transactions)
const pendingNonce = await web3.eth.getTransactionCount(
  account.address,
  'pending'
);

// Use for transaction
const tx = {
  nonce: nonce,
  // ... other fields
};
```

***

### eth\_getLogs

Returns logs matching filter criteria.

#### Parameters

1. `Object` - Filter object:
   * `fromBlock`: Starting block
   * `toBlock`: Ending block
   * `address`: Contract address or array
   * `topics`: Array of topics

#### Returns

`Array` - Array of log objects

#### Example

```javascript
// Get all Transfer events
const logs = await web3.eth.getPastLogs({
  fromBlock: 0,
  toBlock: 'latest',
  address: tokenAddress,
  topics: [
    web3.utils.sha3('Transfer(address,address,uint256)')
  ]
});

// Filter by indexed parameters
const specificTransfers = await web3.eth.getPastLogs({
  fromBlock: 1000000,
  toBlock: 'latest',
  address: tokenAddress,
  topics: [
    web3.utils.sha3('Transfer(address,address,uint256)'),
    null, // any from address
    web3.utils.padLeft(recipientAddress, 64) // specific to
  ]
});

// Process logs
logs.forEach(log => {
  const decoded = web3.eth.abi.decodeLog(
    [
      { type: 'address', name: 'from', indexed: true },
      { type: 'address', name: 'to', indexed: true },
      { type: 'uint256', name: 'value' }
    ],
    log.data,
    log.topics.slice(1)
  );
  
  console.log(`Transfer: ${decoded.from} -> ${decoded.to}: ${decoded.value}`);
});
```

***

### Error Handling

#### Common Errors

```javascript
try {
  const result = await web3.eth.call({
    to: contractAddress,
    data: invalidData
  });
} catch (error) {
  if (error.code === -32000) {
    console.error('Execution reverted:', error.message);
  } else if (error.code === -32602) {
    console.error('Invalid parameters:', error.message);
  } else if (error.code === -32603) {
    console.error('Internal error:', error.message);
  }
}
```

#### Handling Reverts

```javascript
// Catch revert reasons
try {
  const result = await contract.methods.riskyMethod().call();
} catch (error) {
  // Extract revert reason
  const reason = error.reason || error.message;
  console.error('Reverted:', reason);
  
  // Handle specific revert reasons
  if (reason.includes('Insufficient balance')) {
    // Handle insufficient balance
  }
}
```

### Performance Tips

#### Batch Requests

```javascript
const batch = new web3.BatchRequest();

batch.add(web3.eth.getBlockNumber.request((err, block) => {
  console.log('Block:', block);
}));

batch.add(web3.eth.getGasPrice.request((err, price) => {
  console.log('Gas price:', price);
}));

batch.execute();
```

#### Caching Strategies

```javascript
class CachedProvider {
  constructor() {
    this.cache = new Map();
  }
  
  async getCode(address) {
    if (this.cache.has(address)) {
      return this.cache.get(address);
    }
    
    const code = await web3.eth.getCode(address);
    this.cache.set(address, code);
    return code;
  }
}
```

***
