# Table of Contents - [MegaETH Docs – Overview](#megaeth-docs-overview) - [MegaETH Docs – Mainnet](#megaeth-docs-mainnet) - [MegaETH Docs – Testnet](#megaeth-docs-testnet) - [MegaETH Docs – Architecture](#megaeth-docs-architecture) - [MegaETH Docs – RPC](#megaeth-docs-rpc) - [MegaETH Docs – Realtime API](#megaeth-docs-realtime-api) - [MegaETH Docs – Mainnet](#megaeth-docs-mainnet) - [MegaETH Docs – Testnet](#megaeth-docs-testnet) - [MegaETH Docs – MegaEVM](#megaeth-docs-megaevm) - [MegaETH Docs – Realtime API](#megaeth-docs-realtime-api) - [MegaETH Docs – Mini Blocks](#megaeth-docs-mini-blocks) - [MegaETH Docs – MegaEVM](#megaeth-docs-megaevm) --- # MegaETH Docs – Overview You have reached the user manual of MegaETH. * [Mainnet](https://docs.megaeth.com/frontier) : instructions on connecting to and using MegaETH Mainnet * [Testnet](https://docs.megaeth.com/testnet) : instructions on connecting to the testnet * [MegaEVM](https://docs.megaeth.com/megaevm) : differences between MegaETH’s execution environment and vanilla EVM * [Realtime API](https://docs.megaeth.com/realtime-api) : MegaETH’s performance-focused enhancements to Ethereum JSON-RPC * [Faucet](https://docs.megaeth.com/faucet) : supply of free gas tokens for the testnet --- # MegaETH Docs – Mainnet Chain Parameters ---------------- | Item | Value | | --- | --- | | **Chain ID** | 4326 (0x10e6) | | **Native & Gas Token** | Ether (ETH), 18 decimals | | **Block Time** | Mini blocks: 10ms
EVM blocks: 1s | | **Block Gas Limit** | 10 billion (1010) gas per EVM block | | **Base Fee Per Gas** | 0.001 gwei (106 wei) | | **EIP-1559 Parameters** | Base fee adjustment is effectively disabled | Connecting to MegaETH Mainnet ----------------------------- ### RPC MegaETH hosts a public RPC endpoint at https://mainnet.megaeth.com/rpc. See [Realtime API](https://docs.megaeth.com/realtime-api.html) for a list of additional features on top of the standard Ethereum JSON-RPC. These features are available on RPC endpoints provided by MegaETH; availability varies on third-party endpoints. ### Block Explorer [Blockscout](https://megaeth.blockscout.com/) and [Etherscan](https://mega.etherscan.io/) are available. Developing Smart Contracts -------------------------- MegaETH’s execution environment is called _MegaEVM_. It is fully compatible with Ethereum smart contracts but introduces a few differences compared to Ethereum’s EVM especially around the gas model. See the [MegaEVM manual page](https://docs.megaeth.com/megaevm.html) for a list of differences. Implementation of MegaEVM is opensource and can be found on [GitHub](https://github.com/megaeth-labs/mega-evm) . Because of the said differences, toolchains not yet customized for MegaETH might incorrectly estimate the amount of gas a transaction needs if they use their own EVM implementations, as opposed to MegaEVM, to locally simulate the transaction. Sometimes, this issue causes the RPC to throw “intrinsic gas too low” errors or the transaction to run out of gas and revert. The solution is to either tell the toolchain to skip local gas estimation and use a hardcoded gas limit (for `forge script`, as an example, `--gas-limit` with a sufficiently large number plus `--skip-simulation`), or use MegaETH’s RPC servers to estimate gas. _The best tool for debugging MegaETH transactions is `mega-evme`._ It uses the aforementioned opensource implementation of MegaEVM and can thus perfectly simulate any transaction’s behavior on MegaETH. Instructions on building and using `mega-evme` are available [here](https://github.com/megaeth-labs/mega-evm/blob/main/bin/mega-evme/README.md) . Using the Canonical Bridge -------------------------- MegaETH’s canonical bridge is the preferred method to bridge Ether (ETH) from Ethereum to MegaETH. The Ethereum side of the bridge is at `0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75` on Ethereum mainnet. Currently, it runs OP Stack’s [Standard Bridge](https://docs.optimism.io/app-developers/guides/bridging/standard-bridge) in its [op-contracts/v3.0.0 release](https://github.com/ethereum-optimism/optimism/blob/backports/op-contracts/v3.0.0/packages/contracts-bedrock/src/universal/StandardBridge.sol) with a small patch adjusting a few parameters. The easiest way to bridge Ether to MegaETH is sending Ether to the aforementioned address on Ethereum mainnet in a plain native transfer. The same amount of Ether sans gas fees will appear in sender’s address on MegaETH after the transfer is finalized on Ethereum mainnet. For more control, use the `depositETH` method of the bridge contract. It allows for specifying the (approximate) amount of gas that should be charged by and forwarded from Ethereum mainnet to MegaETH for the deposit transaction to use, as well as adding extra data to the transaction. As an example, the following `cast send` command calls `depositETH` to bridge 0.001 Ether with 61000 gas and extra data `bunny`. cast send 0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75 'depositETH(uint32, bytes)' 61000 "0x62756e6e79" --value 0.001ether Contracts of Potential Interest ------------------------------- ### On MegaETH Mainnet | Item | Address | Remarks | | --- | --- | --- | | MEGA Token | `0x28B7E77f82B25B95953825F1E3eA0E36c1c29861` | ERC20; 18 decimals. | | WETH9 | `0x4200000000000000000000000000000000000006` | | | Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | | | USDM | `0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7` | | See OP Stack docs for a complete list of [predeployed](https://docs.optimism.io/op-stack/protocol/smart-contracts#layer-2-contracts-predeploys) and [preinstalled](https://docs.optimism.io/op-stack/features/preinstalls#contracts-and-deployed-addresses) contracts. See the [mega-tokenlist](https://github.com/megaeth-labs/mega-tokenlist) for a more comprehensive list of tokens in the ecosystem. ### On Ethereum Mainnet | Item | Address | Remarks | | --- | --- | --- | | L1CrossDomainMessengerProxy | `0x6C7198250087B29A8040eC63903Bc130f4831Cc9` | | | L1ERC721BridgeProxy | `0x3D8ee269F87A7f3F0590c5C0d825FFF06212A242` | | | L1StandardBridgeProxy | `0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75` | | | OptimismPortalProxy | `0x7f82f57F0Dd546519324392e408b01fcC7D709e8` | | | OptimismMintableERC20FactoryProxy | `0xF875030B9464001fC0f964E47546b0AFEEbD7C61` | | | SystemConfigProxy | `0x1ED92E1bc9A2735216540EDdD0191144681cb77E` | | | USDM | `0xEc2AF1C8B110a61fD9C3Fa6a554a031Ca9943926` | | MegaETH’s smart contracts are from OP Stack’s [op-contracts/v3.0.0 release](https://github.com/ethereum-optimism/optimism/tree/backports/op-contracts/v3.0.0/packages/contracts-bedrock) . See OP Stack docs for [descriptions of these contracts](https://docs.optimism.io/op-stack/protocol/smart-contracts#l1-contract-details) . --- # MegaETH Docs – Testnet Important Messages ------------------ * **RPC Endpoints Are Rate Limited And May Change.** Always check this page for the latest URLs and status. * **Network Maintenance May Occur.** RPCs may go offline during upgrades. Contracts and states may be rolled back in rare cases. * **Testnet Is Not Incentivized.** Testnet tokens and transactions have no real monetary value. _Everything happening on the chain is solely for experimental purposes._ Chain Parameters ---------------- | Item | Value | | --- | --- | | **Chain ID** | 6343 | | **Native & Gas Token** | Ether (ETH), 18 decimals | | **Block Time** | Mini blocks: 10ms
EVM blocks: 1s | | **Block Gas Limit** | 10 billion (1010) gas per EVM block | | **Base Fee Per Gas** | 0.001 gwei (106 wei) | | **EIP-1559 Parameters** | Base fee adjustment is effectively disabled | Connecting to the Testnet ------------------------- ### RPC MegaETH provides a public endpoint at https://carrot.megaeth.com/rpc. Alchemy sells managed endpoints. ### Block Explorer Check out [Blockscout](https://megaeth-testnet-v2.blockscout.com/) and [uptime.megaeth.com](https://uptime.megaeth.com/) . --- # MegaETH Docs – Architecture The complete MegaETH system will consist of the following logical components: **Sequencers.** Users’ transactions (write requests) coming into the system end up with them. They execute users’ transactions, assemble executed transactions into blocks, and disseminate execution results such as transaction receipts and state changes. They also submit the blocks to the L1 for finality. **Read replicas.** They maintain replicas of the chain’s state and (recent) history to service read requests. They may also choose to screen write requests by validating them against local replicas of the chain’s state. Depending on how a replica maintains the state and the history, there are two types of nodes. * _Replica nodes._ They receive new blocks and execution results and apply them to local replicas of the chain’s state and history without validation. * _Full nodes._ They receive new blocks, locally re-execute the blocks, and update local replicas of the chain’s state and history. **Provers.** They receive new blocks, locally re-execute the blocks, and generate proofs for the blocks. These proofs might be fault proofs or validity proofs, depending on how the chain is operated. **Data availability (DA) service.** When a sequencer produces a block, it must submit to the DA service any associated data that the rest of the network depends on to process the block; the DA service will return a receipt certifying that the data is received and make the data publicly available for a finite period of time. Without the receipt, the sequencer cannot submit the block to the L1. The DA service ensures that replica nodes and full nodes can keep up with the chain’s state, and prover nodes can produce proofs for any block that is submitted to the L1, even if the sequencer maliciously withholds data. The current phase of the MegaETH Testnet contains the following components: * One sequencer * Multiple replica nodes maintained by MegaETH to serve RPC requests * EigenDA devnet as the DA service * An Ethereum devnet as the L1 Upcoming phases of the Testnet will introduce * Multiple sequencers for failover and rotation * Permissionless full nodes * Permissionless replica nodes * Permissionless prover nodes running in optimistic (fault proof) mode * Ethereum Testnet as the L1 --- # MegaETH Docs – RPC Available Methods ----------------- | Method | Availability | Additional Restrictions | | --- | --- | --- | | `debug_getRawBlock` | Unavailable | | | `debug_getRawHeader` | Unavailable | | | `debug_getRawReceipts` | Unavailable | | | `debug_getRawTransaction` | Unavailable | | | `debug_replyBlock` | Unavailable | | | `debug_traceBlock` | Unavailable | | | `debug_traceBlockByHash` | Unavailable | | | `debug_traceBlockByNumber` | Unavailable | | | `debug_traceCall` | Unavailable | | | `debug_traceCallMany` | Unavailable | | | `debug_traceTransaction` | Unavailable | | | `eth_accounts` | Available | | | `eth_blockNumber` | Available | | | `eth_call` | Available | Gas is limited to 10,000,000. | | `eth_chainId` | Available | | | `eth_createAccessList` | Available | Gas is limited to 10,000,000. | | `eth_estimateGas` | Available | Gas is limited to 10,000,000. | | `eth_feeHistory` | Available | Block range is limited to 10,000. | | `eth_gasPrice` | Available | | | `eth_getBalance` | Available | | | `eth_getBlockByHash` | Available | Full block is disabled. | | `eth_getBlockByNumber` | Available | Full block is disabled. | | `eth_getBlockReceipts` | Unavailable | | | `eth_getBlockTransactionCountByHash` | Available | | | `eth_getBlockTransactionCountByNumber` | Available | | | `eth_getCode` | Available | | | `eth_getFilterChanges` | Available | | | `eth_getFilterLogs` | Available | | | `eth_getLogs` | Available | | | `eth_getLogsWithCursor` | Available | | | `eth_getStorageAt` | Available | | | `eth_getTransactionByBlockHashAndIndex` | Available | | | `eth_getTransactionByBlockNumberAndIndex` | Available | | | `eth_getTransactionByHash` | Available | | | `eth_getTransactionCount` | Available | | | `eth_getTransactionReceipt` | Available | | | `eth_getUncleByBlockHashAndIndex` | Available | | | `eth_getUncleByBlockNumberAndIndex` | Available | | | `eth_getUncleCountByBlockHash` | Available | | | `eth_getUncleCountByBlockNumber` | Available | | | `eth_maxPriorityFeePerGas` | Available | | | `eth_mining` | Available | | | `eth_newBlockFilter` | Available | | | `eth_newFilter` | Available | | | `eth_newPendingTransactionFilter` | Available | | | `eth_protocolVersion` | Available | | | `eth_sendRawTransaction` | Available | | | `eth_sendTransaction` | Unavailable | | | `eth_sign` | Unavailable | | | `eth_signTransaction` | Unavailable | | | `eth_signTypedData` | Unavailable | | | `eth_subscribe` | Unavailable | | | `eth_syncing` | Available | | | `eth_uninstallFilter` | Available | | | `eth_unsubscribe` | Available | | | `net_listening` | Available | | | `net_peerCount` | Available | | | `net_version` | Available | | | `realtime_sendRawTransaction` | Available | | | `trace_block` | Unavailable | | | `trace_call` | Unavailable | | | `trace_callMany` | Unavailable | | | `trace_get` | Unavailable | | | `trace_rawTransaction` | Unavailable | | | `trace_replayBlockTransactions` | Unavailable | | | `trace_replayTransaction` | Unavailable | | | `trace_transaction` | Unavailable | | | `txpool_content` | Unavailable | | | `txpool_contentFrom` | Unavailable | | | `txpool_inspect` | Unavailable | | | `txpool_status` | Unavailable | | | `web3_clientVersion` | Available | | Rate Limiting ------------- All available methods are subject to rate limiting based on two criteria: * **Compute Unit (CU) Limiting**: Limits the computational cost of requests based on their complexity. * **Network Bandwidth Limiting**: Limits the network traffic based on response sizes. User limits are dynamically updated in response to individual behavior. Error Codes ----------- | HTTP Error Code | RPC Error Code | Error Message | Explanation | Mitigation | | --- | --- | --- | --- | --- | | 400 | \-32700 | parse error | The request body contains invalid JSON. | Check the request format and ensure valid JSON syntax. | | 403 | \-32601 | rpc method is not whitelisted | The requested RPC method is not allowed by the proxy configuration. | Use only whitelisted RPC methods. Contact MegaETH if you need access to additional methods. | | 400 | \-32019 | block is out of range | The requested block number is out of range. | Check the block number and ensure it’s within the valid range. | | 500 | \-32020 | backend response too large | The backend response is too large. | Reduce the scope of the request or contact MegaETH for assistance. | | 429 | \-32021 | over network traffic limit, retry in X seconds | The user is incurring too much network traffic. | Wait for the specified number of seconds before retrying. Reduce the number of requests sent per second. | | 429 | \-32022 | over compute unit limit, retry in X seconds | The user is incurring too much computation on the backend RPC server. | Wait for the specified number of seconds before retrying. Reduce the number of requests sent per second. | | 200 | \-32000 | permanent error forwarding request context deadline exceeded | The API proxy cannot connect to the backend RPC server. | Pause for a while and retry. Notify MegaETH if the error persists. | --- # MegaETH Docs – Realtime API MegaETH executes transactions as soon as they arrive at the sequencer. The sequencer emits _preconfirmations_ and _execution results_ of the transactions within 10 milliseconds of their arrival at the sequencer. Such information is exposed through MegaETH’s _Realtime API_, an extension to Ethereum JSON-RPC API optimized for low-latency access. This API queries against the most recent _mini block_. In other words, receipts and state changes associated with a transaction are reflected in this API as soon as the transaction is packaged into a mini block, which usually happens within 10 milliseconds of its arrival at the sequencer. In comparison, the vanilla Ethereum JSON-RPC API queries against the most recent _EVM block_, which leads to much longer delay before execution results are reflected. It is important to note that mini blocks in MegaETH are preconfirmed by the sequencer just like EVM blocks are. The sequencer makes as much effort not to roll back mini blocks as it does EVM blocks. Thus, results returned by the Realtime API still fall under the preconfirmation guarantee by the sequencer. This document specifies the Realtime API. Note that the Realtime API is an evolving standard. Additional functionalities will be added to the API based on feedbacks. This document will be kept up to date. Overview of the Changes ----------------------- The Realtime API introduces three types of changes to the vanilla Ethereum JSON-RPC API: 1. Most methods that query chain and account states return values as of the most recent mini block, when invoked with `pending` or `latest` as the block tag. 2. Most methods that query transaction data are able to “see” a transaction and return results as soon as the transaction of interest is packaged into a mini block. 3. `eth_subscribe`, when invoked over WebSocket, streams transaction logs, state changes, and block content as soon as the corresponding mini block is produced. 4. `realtime_sendRawTransaction` submits a transaction and returns the receipt in a single call — without requiring polling. 5. `eth_getLogsWithCursor` supports paginated log queries using a cursor, allowing applications to retrieve large datasets incrementally and reliably. Querying Account and Chain States --------------------------------- The following API methods that query account and chain states, when invoked with `pending` or `latest` as the block tag, return results up to the most recent mini block. | Method | | --- | | eth\_getBalance | | eth\_getStorageAt | | eth\_getTransactionCount | | eth\_getCode | | eth\_call | | eth\_callMany | | eth\_createAccessList | | eth\_estimateGas | ### Example At 5pm, the height of the most recent mini block is 10000, and the height of the most recent EVM block is 100. At this point, Alice’s account has a balance of 10 Ether. At 100 milliseconds past 5pm, the height of the most recent mini block is 10010, and the height of the most recent EVM block is still 100. Now, Alice sends a transaction that transfers 1 Ether to Bob. This transaction will decrease her account balance by 1 Ether. At 110 milliseconds past 5pm, the transaction is picked up and executed by the sequencer, and packaged into the mini block at height 10011. Now, Bob invokes `eth_getBalance` on Alice’s account with `latest` as the block tag; he get a response of 9 Ether, because the transaction has been packaged into a mini block and is thus reflected in the Realtime API. However, Charlie, who makes the same query with `100` as the block tag, still sees 10 Ether, because the transaction has not been packaged into an EVM block, which will not happen until 1 second past 5pm. Querying Transactions --------------------- The following API methods that query transaction data are able to locate a transaction in the database and return results as soon as the transaction is packaged into a mini block. No special parameters are needed when invoking the methods. | Method | | --- | | eth\_getTransactionByHash | | eth\_getTransactionReceipt | ### Example Continuing the previous example, Alice invokes `eth_getTransactionReceipt` on her transaction at 110 milliseconds past 5pm. The API responds with the correct receipt, even though no EVM block has been produced since she sent her transaction. This is because her transaction is already packaged into the mini block at height 10011 and the Realtime API can thus see the transaction. `eth_subscribe` over WebSocket ------------------------------ When invoked over WebSocket, `eth_subscribe` streams data as soon as the corresponding mini block is produced. This is the mechanism to get transaction preconfirmation and execution results with the minimum amount of latency. As a reminder, please call `eth_unsubscribe` when a subscription is no longer needed. **Note:** WebSocket connections require periodic client activity to remain open. Clients should send `eth_chainId` at least once every 30 seconds to keep the WebSocket connection alive. Idle connections may be closed by the server. ### Logs When both `startBlock` and `endBlock` are set to `pending`, the API returns logs as soon as transactions are packaged into mini blocks. The following query is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "logs",\ {\ "fromBlock": "pending",\ "toBlock": "pending"\ }\ ], "id": 83 } It is also possible to filter the logs by contract addresses and topics. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "logs",\ {\ "address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",\ "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],\ "fromBlock": "pending",\ "toBlock": "pending"\ }\ ], "id": 83 } The schema of each log entry is the same as in `eth_getLogs`. ### State Changes `stateChanges` is a new type of subscription that streams state changes of an account as soon as the transactions making the changes are packaged into mini blocks. It takes a list of account addresses to monitor as a parameter. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "stateChanges",\ ["0x2ef038991d64c72646d4f06ba78d93f4f1654e3f"]\ ], "id": 83 } Here is an example of the response. It shows the latest account balance, nonce, and values of storage slots that are changed. The schema is as the following. { "address": Address, // The address of the account that is changed. "nonce": number, // The latest nonce of the account. "balance": U256, // The latest balance of the account. "storage": { // Updated storage slots and new values of the account. U256: U256, ... } } Here is an example. { "address": "0x2ef038991d64c72646d4f06ba78d93f4f1654e3f", "nonce": 1, "balance": "0x16345785d8a0000", "storage": { "0xb6318d15e99499c465cc5e3d630975bf37b5641a8beb2614b018219310f4ea12": "0x68836e425f5", "0xbf0f571b7368c19b53ab5ef0ff767ed8e0aef55a462778a6119b7871b017ce8f": "0x71094412456b0" } } ### Mini Blocks `miniBlocks` is a new type of subscription that streams mini blocks as they are produced. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "miniBlocks"\ ], "id": 83 } The returned mini blocks use the following schema. { "block_number": HexString, // The block number of that EVM block that this mini-block belongs to "block_timestamp": HexString, // Timestamp of the EVM block "index": HexString, // Index of this mini-block in the EVM block "mini_block_number": HexString, // The number of this mini-block in blockchain history "mini_block_timestamp": HexString, // The timestamp when this mini-block is created. Unix timestamp in microseconds. "gas_used": HexString, // Gas used inside this mini-block "transactions": [ ... ], // Transactions included in this mini-block. The schema of each transaction is the same as `eth_getTransactionByHash`. "receipts": [ ... ] // Receipts of the transactions in this mini-block. The schema of each receipt is the same as `eth_getTransactionReceipt`. } Sending and Confirming Transactions in One Round Trip ----------------------------------------------------- ### Overview `realtime_sendRawTransaction` simplifies realtime dApp development by returning the transaction receipt directly, without requiring polling `eth_getTransactionReceipt`. It accepts the same parameters as `eth_sendRawTransaction` but waits for the transaction to be executed and returns its receipt as the response. This method times out after 10 seconds, in which case it returns a `realtime transaction expired` error, indicating that the user should revert to querying `eth_getTransactionReceipt`. ### Example `realtime_sendRawTransaction` is a drop-in replacement of `eth_sendRawTransaction`. { "jsonrpc": "2.0", "method": "realtime_sendRawTransaction", "params": [\ "0x"\ ], "id": 1 } If the submitted transaction is executed within 10 seconds, it returns the receipt of the executed transaction. { "jsonrpc": "2.0", "id": 1, "result": { "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10", "contractAddress": null, "cumulativeGasUsed": "0x11dde", "effectiveGasPrice": "0x23ebdf", "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0xa7b8c275b3dde39e69a5c0ffd9f34f974364941a", "transactionHash": "0xf98a6b5de84ee59666d0ff3d8c361f308c3a22fc0bb94466810777d60a3ed7a7", "transactionIndex": "0x1", "type": "0x0" } } If the transaction is not executed within 10 seconds, e.g., because of congestion at the sequencer, it returns an error. { "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "realtime transaction expired" } } Paginated Log Queries with Cursors ---------------------------------- ### Overview `eth_getLogsWithCursor` is an enhanced version of `eth_getLogs` that adds support for pagination via a cursor. This allows applications to query large sets of logs while gracefully handing execution or memory limits on the RPC server. When a query exceeds server-side resource caps, the server returns a partial result and a cursor that marks where it left off. The client can then continue the query from that point. This method accepts the same parameters as `eth_getLogs`, with an additional optional `cursor`, which is an opaque string. If the query is too large and hits the server-side caps, it returns a partial list of logs and a `cursor` pointing to the next log to fetch. Clients can resume the query using the provided `cursor`. Absence of a `cursor` in the request indicates that the server should start the query at `fromBlock` as usual. Absence of a returned `cursor` indicates the query is complete. The cursor is derived from `(blockNumber + logIndex)` of the last log in the current batch, but users should treat it as an opaque string. ### Example To send an initial request, start with a standard `eth_getLogs`\-style query. Set `fromBlock` and `toBlock` (or `blockHash`) and do _not_ include a cursor. { "jsonrpc": "2.0", "method": "eth_getLogsWithCursor", "params": [\ {\ "fromBlock": "0x100",\ "toBlock": "0x200",\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "topics": ["0xddf252ad..."]\ }\ ], "id": 1 } If the server reaches its processing limit (e.g. max logs or execution time), it will return the logs retrieved so far and include a `cursor` indicating the last log processed. { "jsonrpc": "2.0", "id": 1, "result": { "logs": [\ {\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "blockNumber": "0x101",\ "logIndex": "0x0",\ "topics": ["0xddf252ad..."],\ "data": "0x...",\ "transactionHash": "0x...",\ "transactionIndex": "0x0",\ "blockHash": "0x...",\ "removed": false\ }\ ], "cursor": "0x0000010100000000" } } The client should submit a second request with the same filter (e.g. address, topics, block range) and the `cursor` from the previous response (mandatory). The server will resume the query from where it left off. { "jsonrpc": "2.0", "method": "eth_getLogsWithCursor", "params": [\ {\ "fromBlock": "0x100",\ "toBlock": "0x200",\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "topics": ["0xddf252ad..."],\ "cursor": "0x0000010100000000"\ }\ ], "id": 2 } When the server returns a response _without_ a `cursor`, it means that all matching logs have been retrieved and no further requests are needed { "jsonrpc": "2.0", "id": 2, "result": { "logs": [\ {\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "blockNumber": "0x102",\ "logIndex": "0x3",\ "topics": ["0xddf252ad..."],\ "data": "0x...",\ "transactionHash": "0x...",\ "transactionIndex": "0x2",\ "blockHash": "0x...",\ "removed": false\ }\ ] // No cursor field — query is complete } } --- # MegaETH Docs – Mainnet Chain Parameters ---------------- | Item | Value | | --- | --- | | **Chain ID** | 4326 (0x10e6) | | **Native & Gas Token** | Ether (ETH), 18 decimals | | **Block Time** | Mini blocks: 10ms
EVM blocks: 1s | | **Block Gas Limit** | 10 billion (1010) gas per EVM block | | **Base Fee Per Gas** | 0.001 gwei (106 wei) | | **EIP-1559 Parameters** | Base fee adjustment is effectively disabled | Connecting to MegaETH Mainnet ----------------------------- ### RPC MegaETH hosts a public RPC endpoint at https://mainnet.megaeth.com/rpc. See [Realtime API](https://docs.megaeth.com/realtime-api.html) for a list of additional features on top of the standard Ethereum JSON-RPC. These features are available on RPC endpoints provided by MegaETH; availability varies on third-party endpoints. ### Block Explorer [Blockscout](https://megaeth.blockscout.com/) and [Etherscan](https://mega.etherscan.io/) are available. Developing Smart Contracts -------------------------- MegaETH’s execution environment is called _MegaEVM_. It is fully compatible with Ethereum smart contracts but introduces a few differences compared to Ethereum’s EVM especially around the gas model. See the [MegaEVM manual page](https://docs.megaeth.com/megaevm.html) for a list of differences. Implementation of MegaEVM is opensource and can be found on [GitHub](https://github.com/megaeth-labs/mega-evm) . Because of the said differences, toolchains not yet customized for MegaETH might incorrectly estimate the amount of gas a transaction needs if they use their own EVM implementations, as opposed to MegaEVM, to locally simulate the transaction. Sometimes, this issue causes the RPC to throw “intrinsic gas too low” errors or the transaction to run out of gas and revert. The solution is to either tell the toolchain to skip local gas estimation and use a hardcoded gas limit (for `forge script`, as an example, `--gas-limit` with a sufficiently large number plus `--skip-simulation`), or use MegaETH’s RPC servers to estimate gas. _The best tool for debugging MegaETH transactions is `mega-evme`._ It uses the aforementioned opensource implementation of MegaEVM and can thus perfectly simulate any transaction’s behavior on MegaETH. Instructions on building and using `mega-evme` are available [here](https://github.com/megaeth-labs/mega-evm/blob/main/bin/mega-evme/README.md) . Using the Canonical Bridge -------------------------- MegaETH’s canonical bridge is the preferred method to bridge Ether (ETH) from Ethereum to MegaETH. The Ethereum side of the bridge is at `0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75` on Ethereum mainnet. Currently, it runs OP Stack’s [Standard Bridge](https://docs.optimism.io/app-developers/guides/bridging/standard-bridge) in its [op-contracts/v3.0.0 release](https://github.com/ethereum-optimism/optimism/blob/backports/op-contracts/v3.0.0/packages/contracts-bedrock/src/universal/StandardBridge.sol) with a small patch adjusting a few parameters. The easiest way to bridge Ether to MegaETH is sending Ether to the aforementioned address on Ethereum mainnet in a plain native transfer. The same amount of Ether sans gas fees will appear in sender’s address on MegaETH after the transfer is finalized on Ethereum mainnet. For more control, use the `depositETH` method of the bridge contract. It allows for specifying the (approximate) amount of gas that should be charged by and forwarded from Ethereum mainnet to MegaETH for the deposit transaction to use, as well as adding extra data to the transaction. As an example, the following `cast send` command calls `depositETH` to bridge 0.001 Ether with 61000 gas and extra data `bunny`. cast send 0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75 'depositETH(uint32, bytes)' 61000 "0x62756e6e79" --value 0.001ether Contracts of Potential Interest ------------------------------- ### On MegaETH Mainnet | Item | Address | Remarks | | --- | --- | --- | | MEGA Token | `0x28B7E77f82B25B95953825F1E3eA0E36c1c29861` | ERC20; 18 decimals. | | WETH9 | `0x4200000000000000000000000000000000000006` | | | Multicall3 | `0xcA11bde05977b3631167028862bE2a173976CA11` | | | USDM | `0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7` | | See OP Stack docs for a complete list of [predeployed](https://docs.optimism.io/op-stack/protocol/smart-contracts#layer-2-contracts-predeploys) and [preinstalled](https://docs.optimism.io/op-stack/features/preinstalls#contracts-and-deployed-addresses) contracts. See the [mega-tokenlist](https://github.com/megaeth-labs/mega-tokenlist) for a more comprehensive list of tokens in the ecosystem. ### On Ethereum Mainnet | Item | Address | Remarks | | --- | --- | --- | | L1CrossDomainMessengerProxy | `0x6C7198250087B29A8040eC63903Bc130f4831Cc9` | | | L1ERC721BridgeProxy | `0x3D8ee269F87A7f3F0590c5C0d825FFF06212A242` | | | L1StandardBridgeProxy | `0x0CA3A2FBC3D770b578223FBB6b062fa875a2eE75` | | | OptimismPortalProxy | `0x7f82f57F0Dd546519324392e408b01fcC7D709e8` | | | OptimismMintableERC20FactoryProxy | `0xF875030B9464001fC0f964E47546b0AFEEbD7C61` | | | SystemConfigProxy | `0x1ED92E1bc9A2735216540EDdD0191144681cb77E` | | | USDM | `0xEc2AF1C8B110a61fD9C3Fa6a554a031Ca9943926` | | MegaETH’s smart contracts are from OP Stack’s [op-contracts/v3.0.0 release](https://github.com/ethereum-optimism/optimism/tree/backports/op-contracts/v3.0.0/packages/contracts-bedrock) . See OP Stack docs for [descriptions of these contracts](https://docs.optimism.io/op-stack/protocol/smart-contracts#l1-contract-details) . --- # MegaETH Docs – Testnet Important Messages ------------------ * **RPC Endpoints Are Rate Limited And May Change.** Always check this page for the latest URLs and status. * **Network Maintenance May Occur.** RPCs may go offline during upgrades. Contracts and states may be rolled back in rare cases. * **Testnet Is Not Incentivized.** Testnet tokens and transactions have no real monetary value. _Everything happening on the chain is solely for experimental purposes._ Chain Parameters ---------------- | Item | Value | | --- | --- | | **Chain ID** | 6343 | | **Native & Gas Token** | Ether (ETH), 18 decimals | | **Block Time** | Mini blocks: 10ms
EVM blocks: 1s | | **Block Gas Limit** | 10 billion (1010) gas per EVM block | | **Base Fee Per Gas** | 0.001 gwei (106 wei) | | **EIP-1559 Parameters** | Base fee adjustment is effectively disabled | Connecting to the Testnet ------------------------- ### RPC MegaETH provides a public endpoint at https://carrot.megaeth.com/rpc. Alchemy sells managed endpoints. ### Block Explorer Check out [Blockscout](https://megaeth-testnet-v2.blockscout.com/) and [uptime.megaeth.com](https://uptime.megaeth.com/) . --- # MegaETH Docs – MegaEVM _MegaEVM_ is MegaETH’s execution environment. It is fully compatible with Ethereum smart contracts while introducing optimizations for the unique characteristics of MegaETH’s architecture. Overview -------- MegaEVM builds on established standards. Its latest hardfork, _Rex_, is based on [Optimism Isthmus](https://specs.optimism.io/protocol/isthmus/overview.html) , which in turn is adapted from [Ethereum Prague](https://ethereum.org/roadmap/pectra/) . This means: * All standard Solidity contracts work on MegaETH. * Standard development tools (Hardhat, Foundry, Remix, etc.) are compatible. * Existing Ethereum libraries and patterns apply. Meanwhile, MegaEVM introduces a few changes to accommodate MegaETH’s low fees and high capacity. The most important change is the _multidimensional gas model and resource limits_. In MegaEVM, transactions consume two types of gas: _compute gas_, which models computation at large and is identically defined as Ethereum’s gas; and _storage gas_, a new concept that models the storage subsystem in particular. Similarly, MegaEVM caps resource usage of transactions and blocks using rules that each targets an individual type of resource. Developers should consider these changes in contrast to Ethereum’s EVM, where gas is the singular metric for metering and limiting resource consumption. ### Key Differences at a Glance | Feature | Ethereum | MegaETH | Remarks | | --- | --- | --- | --- | | Max contract size | 24 KB | **512 KB** | | | Max initcode size | 48 KB | **536 KB** | | | Gas forwarding rule | 63/64 | **98/100** | As defined in [EIP-150](https://eips.ethereum.org/EIPS/eip-150)
. | | `SELFDESTRUCT` | Deprecated | **Disabled** | Deprecated in [EIP-6049](https://eips.ethereum.org/EIPS/eip-6049)
. | | Gas model | Unidimensional | **Multidimensional** | Compute gas and storage gas. Compute gas is identical to Ethereum’s gas. | | Resource limits | Unidimensional | **Multidimensional** | 4 limits in addition to total gas limit specified by sender. | | Base intrinsic gas | 21,000 | **60,000** | 21,000 compute gas plus 39,000 storage gas. | Multidimensional Gas Model -------------------------- MegaETH uses a _multidimensional gas model_ that separates gas costs into two categories: * **Compute Gas**: Standard execution costs as defined in Ethereum’s EVM * **Storage Gas**: Additional costs for operations that create persistent data The total gas of a transaction is the sum of its compute gas and storage gas. ### Compute Gas Costs For any operation, its compute gas cost in MegaEVM is equal to its gas cost in standard EVM. For example, updating a cold storage slot from zero to nonzero costs 22,100 gas in standard EVM, so the compute gas cost of the said operation in MegaEVM is also 22,100. As another example, every transaction incurs an intrinsic gas cost of 21,000 in standard EVM, so every transaction also incurs an intrinsic compute gas cost of 21,000 in MegaEVM. As a rule of thumb, the amount of compute gas a transaction burns is equal to the amount of gas it would burn in Ethereum’s EVM. ### Storage Gas Costs The storage gas cost of most operations is zero. The following table lists all operations where storage gas does apply. Some storage gas calculations involve a parameter called _bucket multiplier_ (denoted as m). The next section explains this concept. | Operation | Storage Gas Cost | Remarks | | --- | --- | --- | | Intrinsic | 39,000 | Incurred by every transaction. Combined with the intrinsic compute gas cost of 21,000, the total intrinsic gas cost of a transaction is 60,000. | | Zero-to-nonzero `SSTORE` | 20,000 × (m-1) | Only applies to zero-to-nonzero writes. | | Account creation | 25,000 × (m-1) | Value transfer to empty account. | | Contract creation | 32,000 × (m-1) | `CREATE`/`CREATE2` operations. | | Code deposit | 10,000/byte | Per byte of deployed bytecode. | | `LOG` topic | 3,750/topic | Per topic in event. | | `LOG` data | 80/byte | Per byte of event data. | | Calldata (zero) | 40/byte | Per zero byte in transaction input. | | Calldata (nonzero) | 160/byte | Per nonzero byte in transaction input. | | EIP-7623 floor (zero) | 100/byte | [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623)
floor cost per zero byte in transaction input. | | EIP-7623 floor (nonzero) | 400/byte | [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623)
floor cost per nonzero byte in transaction input. | All other operations not mentioned in the previous table incurs no storage gas cost. ### Bucket Multiplier Accounts and their storage slots are stored in segments of MegaETH’s SALT state trie called “buckets”. Buckets grow in size and capacity as they hold more data. The cost of writing new data to a bucket (creating new accounts or changing storage slots from zero to nonzero) varies based on its capacity, and such variation is reflected in storage gas costs of these operations in the form of the _bucket multiplier_ (denoted as m). The bucket multiplier of a bucket is simply defined as the ratio of its capacity and the minimum capacity of buckets. The latter is a system parameter. In other words, Bucket Multiplier = Bucket Capacity / MIN_BUCKET_CAP. SALT’s design ensures that bucket multiplier is always an integer. Without diving into details of SALT, here are a few rules of thumb for developers. * Unless a bucket has expanded to handle heavy storage needs, bucket multiplier is typically 1. * When bucket multiplier is 1, `SSTORE`, account creation, and contract creation incurs zero storage gas cost. * Bucket expand as they fill up; the multiplier increases and storage gas costs rise. * Developers typically do not need to consider bucket multiplier when designing contracts. Below are a few examples of storage gas costs at different bucket multiplier values. | Operation | m=1 | m=2 | m=4 | | --- | --- | --- | --- | | Zero-to-nonzero `SSTORE` | 0 | 20,000 | 60,000 | | Account creation | 0 | 25,000 | 75,000 | | Contract creation | 0 | 32,000 | 96,000 | ### Tips for Developers * **Use MegaETH’s native gas estimation APIs.** Tools not explicitly modified for MegaEVM do not account for storage gas and will report overly small numbers. * For example, when running `forge script`, use `--skip-simulation` to avoid its built-in EVM and use `--gas-limit` to manually specify a sufficiently high gas limit. * **Account for storage gas.** An Ether transfer costs 60,000 gas (21,000 compute gas plus 39,000 storage gas). This is the minimum gas cost (intrinsic gas) for any transaction. * The RPC returns “intrinsic gas too low” when transaction gas limit is smaller than 60,000. * **Prefer transient storage or memory over persistent storage.** Allocating new storage slots costs storage gas and counts towards various resource limits (explained in the next section). Use transient storage ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153) `TSTORE`/`TLOAD`) for data that only needs to persist within a transaction, or memory for data within a single call. This avoids storage gas costs entirely and ensures calling transactions stay within resource limits. * **Reuse storage slots.** Storage gas applies when changing a slot from zero to nonzero and does not apply when overwriting a slot that is already nonzero. When a slot can be freed (i.e., changed to zero) but is expected to be allocated again (i.e., changed to nonzero) very soon, consider keeping the slot at nonzero so that no storage gas is charged the next time it is used. * As a rule of thumb, avoid design patterns that allocate a lot of slots only to free them soon after. Multidimensional Resource Limits -------------------------------- In addition to limits already defined in standard EVM, MegaEVM enforces four additional limits on how much resources each transaction or block may consume. The following table is an overview. The next few sections explain what counts towards each type of resource and the respective limit. | Resource Type | Per-Transaction Limit | Per-Block Limit | | --- | --- | --- | | Compute Gas | 200,000,000 | N/A | | Data Size | 12.5 MB | 12.5 MB | | KV Updates | 500,000 | 500,000 | | State Growth | 1,000 | 1,000 | When a transaction hits _any_ of the aforementioned per-transaction limits, the following happens: 1. Execution halts immediately. 2. Any remaining gas is preserved and refunded to sender. 3. Transaction is included in the block with status set to failed (status=0). 4. No state changes from the transaction are applied. If any of the aforementioned per-block limits is hit when building a block, the following happens: 1. The transaction that caused the block to go over limits is allowed to execute to completion and will be included in the block. Per-transaction limits still apply. 2. No more transaction will be executed or added to this block. ### Definitions of Resource Types For all resource types, the usage incurred by a block is simply the sum of the usage incurred by each transaction in the block. For example, if a block contains two transactions, one using 300 KV updates and the other using 400 KV updates, then the block uses 700 KV updates. The usage incurred by an individual transaction is defined as following. #### Compute Gas Compute gas cost of a transaction as defined in previous sections. #### Data Size Data size measures the amount of data that needs to be transmitted and stored for each transaction. Both the transaction itself and its execution results are considered. It is the total size of the following items: * Transaction calldata * Event logs (topics and data) * Storage writes (40 bytes per write) * Account updates (40 bytes each) * Deployed contract code #### KV Updates KV updates measure the total number of state entries (accounts and storage slots) updated by a transaction. Each update to a storage slot or an account counts as one update towards the limit. Repeated updates to the same storage slot or account counts as only one update. #### State Growth State growth measures the number of new state entries (accounts and storage slots) created by a transaction. Each new storage slot (created by a zero-to-nonzero `SSTORE`), account, or contract counts as one unit towards the limit. If a newly created storage slot or account is cleared before the transaction ends, thus occupying no storage space permanently, it does not count towards the limit. Access to Volatile Data ----------------------- MegaEVM provides APIs for transactions to access _volatile data_, or data that changes frequently and thus expires quickly after being accessed. This includes metadata of the current block such as the block number, states of the block beneficiary, as well as data available through the native oracle interface (see below). When a transaction accesses volatile data, dependency forms between the transaction and other transactions or operations that attempt to update the data. Such dependency harms performance. For example, if a transaction reads the current block number using the `NUMBER` opcode, the sequencer cannot start a new block until the transaction finishes and gets included in the current block, as doing so would cause the block number to change and invalidate the value previously read by the transaction. If the transaction takes long to finish, block production would be blocked (no pun intended), which impacts latency. MegaEVM mitigates this issue by limiting the amount of compute gas a transaction may use _after it accesses volatile data_. This ensures transactions that access volatile data yield quickly. In the following subsections, we detail the limits. ### Opcodes for Access the Block Environment Accessing these opcodes caps remaining compute gas to 20,000,000. | Opcode | Description | | --- | --- | | `NUMBER` | Current block number | | `TIMESTAMP` | Current block timestamp | | `COINBASE` | Block beneficiary address | | `DIFFICULTY` | Block difficulty | | `GASLIMIT` | Block gas limit | | `BASEFEE` | Base fee per gas | | `PREVRANDAO` | Previous block randomness | | `BLOCKHASH` | Historical block hash | | `BLOBBASEFEE` | Blob base fee | | `BLOBHASH` | Blob hash lookup | ### Accessing the Beneficiary Account Accessing the block beneficiary (coinbase) account also caps remaining compute gas to 20,000,000. | Trigger | Description | | --- | --- | | `BALANCE`, `SELFBALANCE` | Reading beneficiary’s balance | | `EXTCODECOPY`, `EXTCODESIZE`, `EXTCODEHASH` | Accessing beneficiary’s code | | Transaction sender is beneficiary | When `msg.sender == block.coinbase` | | Transaction recipient is beneficiary | When call target is `block.coinbase` | | `DELEGATECALL` to beneficiary | Delegated context accessing beneficiary | ### Accessing the Native Oracle Interface Accessing the system contract of the native oracle interface caps remaining compute gas to 1,000,000. * Oracle contract address: `0x6342000000000000000000000000000000000001` * Applies to `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` ### Remarks When multiple types of volatile data are accessed in the same transaction, the _most restrictive limit applies_. For example, if a transaction accesses both the block environment (triggering the 20m limit) and the oracle interface (triggering the 1m limit), the cap will be 1m. The order in which the transaction accesses the data types does not matter. The lowest cap is enforced globally. Because these limits apply _after_ accesssing volatile data, developers should perform heavy computation before any attempt to access volatile data. The following is a counterexample. // Bad: Heavy computation after reading timestamp function processWithTimestamp() external { uint256 currentTime = block.timestamp; // Triggers 20M gas cap // This loop might run out of gas! for (uint i = 0; i < 10000; i++) { heavyComputation(i, currentTime); } } System Contracts & the Native Oracle Service -------------------------------------------- MegaEVM provides a native oracle interface that provides realtime access to data from off-chain sources. ### High-Precision Timestamp Oracle This oracle provides timestamps at microsecond resolution. Developers might find it useful if `block.timestamp` is not granular enough. **Address:** `0x6342000000000000000000000000000000000002` **Interface:** interface HighPrecisionTimestampOracle { function timestamp() external view returns (uint256); } Note that data for this oracle is supplied solely by the sequencer based on its local clock. This implies that the sequencer must be trusted to publish accurate data. Avoid using this oracle if such trust assumption is too strong for your use case. This oracle internally reads the core oracle contract `0x6342000000000000000000000000000000000001`. Hence, obtaining high-precision timestamps is accesses volatile data and is subject to the compute gas limits detailed in the previous section. Miscellaneous ------------- ### Increased Contract Size Limit MegaETH supports contracts up to 512 KB in size. This is increased from 24 KB in Ethereum. ### `SELFDESTRUCT` is Disabled The `SELFDESTRUCT` opcode is completely disabled and is treated as an `INVALID` opcode. It will cause any transaction using this opcode to fail. In Ethereum, `SELFDESTRUCT` is deprecated but still available. ### “98/100” Rule for Gas Forwarding MegaETH allows a caller to forward at most 98/100 of remaining gas to callee. The parameter is 63/64 in Ethereum. --- # MegaETH Docs – Realtime API MegaETH executes transactions as soon as they arrive at the sequencer. The sequencer emits _preconfirmations_ and _execution results_ of the transactions within 10 milliseconds of their arrival at the sequencer. Such information is exposed through MegaETH’s _Realtime API_, an extension to Ethereum JSON-RPC API optimized for low-latency access. This API queries against the most recent _mini block_. In other words, receipts and state changes associated with a transaction are reflected in this API as soon as the transaction is packaged into a mini block, which usually happens within 10 milliseconds of its arrival at the sequencer. In comparison, the vanilla Ethereum JSON-RPC API queries against the most recent _EVM block_, which leads to much longer delay before execution results are reflected. It is important to note that mini blocks in MegaETH are preconfirmed by the sequencer just like EVM blocks are. The sequencer makes as much effort not to roll back mini blocks as it does EVM blocks. Thus, results returned by the Realtime API still fall under the preconfirmation guarantee by the sequencer. This document specifies the Realtime API. Note that the Realtime API is an evolving standard. Additional functionalities will be added to the API based on feedbacks. This document will be kept up to date. Overview of the Changes ----------------------- The Realtime API introduces three types of changes to the vanilla Ethereum JSON-RPC API: 1. Most methods that query chain and account states return values as of the most recent mini block, when invoked with `pending` or `latest` as the block tag. 2. Most methods that query transaction data are able to “see” a transaction and return results as soon as the transaction of interest is packaged into a mini block. 3. `eth_subscribe`, when invoked over WebSocket, streams transaction logs, state changes, and block content as soon as the corresponding mini block is produced. 4. `realtime_sendRawTransaction` submits a transaction and returns the receipt in a single call — without requiring polling. 5. `eth_getLogsWithCursor` supports paginated log queries using a cursor, allowing applications to retrieve large datasets incrementally and reliably. Querying Account and Chain States --------------------------------- The following API methods that query account and chain states, when invoked with `pending` or `latest` as the block tag, return results up to the most recent mini block. | Method | | --- | | eth\_getBalance | | eth\_getStorageAt | | eth\_getTransactionCount | | eth\_getCode | | eth\_call | | eth\_callMany | | eth\_createAccessList | | eth\_estimateGas | ### Example At 5pm, the height of the most recent mini block is 10000, and the height of the most recent EVM block is 100. At this point, Alice’s account has a balance of 10 Ether. At 100 milliseconds past 5pm, the height of the most recent mini block is 10010, and the height of the most recent EVM block is still 100. Now, Alice sends a transaction that transfers 1 Ether to Bob. This transaction will decrease her account balance by 1 Ether. At 110 milliseconds past 5pm, the transaction is picked up and executed by the sequencer, and packaged into the mini block at height 10011. Now, Bob invokes `eth_getBalance` on Alice’s account with `latest` as the block tag; he get a response of 9 Ether, because the transaction has been packaged into a mini block and is thus reflected in the Realtime API. However, Charlie, who makes the same query with `100` as the block tag, still sees 10 Ether, because the transaction has not been packaged into an EVM block, which will not happen until 1 second past 5pm. Querying Transactions --------------------- The following API methods that query transaction data are able to locate a transaction in the database and return results as soon as the transaction is packaged into a mini block. No special parameters are needed when invoking the methods. | Method | | --- | | eth\_getTransactionByHash | | eth\_getTransactionReceipt | ### Example Continuing the previous example, Alice invokes `eth_getTransactionReceipt` on her transaction at 110 milliseconds past 5pm. The API responds with the correct receipt, even though no EVM block has been produced since she sent her transaction. This is because her transaction is already packaged into the mini block at height 10011 and the Realtime API can thus see the transaction. `eth_subscribe` over WebSocket ------------------------------ When invoked over WebSocket, `eth_subscribe` streams data as soon as the corresponding mini block is produced. This is the mechanism to get transaction preconfirmation and execution results with the minimum amount of latency. As a reminder, please call `eth_unsubscribe` when a subscription is no longer needed. **Note:** WebSocket connections require periodic client activity to remain open. Clients should send `eth_chainId` at least once every 30 seconds to keep the WebSocket connection alive. Idle connections may be closed by the server. ### Logs When both `startBlock` and `endBlock` are set to `pending`, the API returns logs as soon as transactions are packaged into mini blocks. The following query is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "logs",\ {\ "fromBlock": "pending",\ "toBlock": "pending"\ }\ ], "id": 83 } It is also possible to filter the logs by contract addresses and topics. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "logs",\ {\ "address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",\ "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],\ "fromBlock": "pending",\ "toBlock": "pending"\ }\ ], "id": 83 } The schema of each log entry is the same as in `eth_getLogs`. ### State Changes `stateChanges` is a new type of subscription that streams state changes of an account as soon as the transactions making the changes are packaged into mini blocks. It takes a list of account addresses to monitor as a parameter. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "stateChanges",\ ["0x2ef038991d64c72646d4f06ba78d93f4f1654e3f"]\ ], "id": 83 } Here is an example of the response. It shows the latest account balance, nonce, and values of storage slots that are changed. The schema is as the following. { "address": Address, // The address of the account that is changed. "nonce": number, // The latest nonce of the account. "balance": U256, // The latest balance of the account. "storage": { // Updated storage slots and new values of the account. U256: U256, ... } } Here is an example. { "address": "0x2ef038991d64c72646d4f06ba78d93f4f1654e3f", "nonce": 1, "balance": "0x16345785d8a0000", "storage": { "0xb6318d15e99499c465cc5e3d630975bf37b5641a8beb2614b018219310f4ea12": "0x68836e425f5", "0xbf0f571b7368c19b53ab5ef0ff767ed8e0aef55a462778a6119b7871b017ce8f": "0x71094412456b0" } } ### Mini Blocks `miniBlocks` is a new type of subscription that streams mini blocks as they are produced. Here is an example. { "jsonrpc": "2.0", "method": "eth_subscribe", "params": [\ "miniBlocks"\ ], "id": 83 } The returned mini blocks use the following schema. { "block_number": HexString, // The block number of that EVM block that this mini-block belongs to "block_timestamp": HexString, // Timestamp of the EVM block "index": HexString, // Index of this mini-block in the EVM block "mini_block_number": HexString, // The number of this mini-block in blockchain history "mini_block_timestamp": HexString, // The timestamp when this mini-block is created. Unix timestamp in microseconds. "gas_used": HexString, // Gas used inside this mini-block "transactions": [ ... ], // Transactions included in this mini-block. The schema of each transaction is the same as `eth_getTransactionByHash`. "receipts": [ ... ] // Receipts of the transactions in this mini-block. The schema of each receipt is the same as `eth_getTransactionReceipt`. } Sending and Confirming Transactions in One Round Trip ----------------------------------------------------- ### Overview `realtime_sendRawTransaction` simplifies realtime dApp development by returning the transaction receipt directly, without requiring polling `eth_getTransactionReceipt`. It accepts the same parameters as `eth_sendRawTransaction` but waits for the transaction to be executed and returns its receipt as the response. This method times out after 10 seconds, in which case it returns a `realtime transaction expired` error, indicating that the user should revert to querying `eth_getTransactionReceipt`. ### Example `realtime_sendRawTransaction` is a drop-in replacement of `eth_sendRawTransaction`. { "jsonrpc": "2.0", "method": "realtime_sendRawTransaction", "params": [\ "0x"\ ], "id": 1 } If the submitted transaction is executed within 10 seconds, it returns the receipt of the executed transaction. { "jsonrpc": "2.0", "id": 1, "result": { "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10", "contractAddress": null, "cumulativeGasUsed": "0x11dde", "effectiveGasPrice": "0x23ebdf", "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "gasUsed": "0x5208", "logs": [], "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "status": "0x1", "to": "0xa7b8c275b3dde39e69a5c0ffd9f34f974364941a", "transactionHash": "0xf98a6b5de84ee59666d0ff3d8c361f308c3a22fc0bb94466810777d60a3ed7a7", "transactionIndex": "0x1", "type": "0x0" } } If the transaction is not executed within 10 seconds, e.g., because of congestion at the sequencer, it returns an error. { "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "realtime transaction expired" } } Paginated Log Queries with Cursors ---------------------------------- ### Overview `eth_getLogsWithCursor` is an enhanced version of `eth_getLogs` that adds support for pagination via a cursor. This allows applications to query large sets of logs while gracefully handing execution or memory limits on the RPC server. When a query exceeds server-side resource caps, the server returns a partial result and a cursor that marks where it left off. The client can then continue the query from that point. This method accepts the same parameters as `eth_getLogs`, with an additional optional `cursor`, which is an opaque string. If the query is too large and hits the server-side caps, it returns a partial list of logs and a `cursor` pointing to the next log to fetch. Clients can resume the query using the provided `cursor`. Absence of a `cursor` in the request indicates that the server should start the query at `fromBlock` as usual. Absence of a returned `cursor` indicates the query is complete. The cursor is derived from `(blockNumber + logIndex)` of the last log in the current batch, but users should treat it as an opaque string. ### Example To send an initial request, start with a standard `eth_getLogs`\-style query. Set `fromBlock` and `toBlock` (or `blockHash`) and do _not_ include a cursor. { "jsonrpc": "2.0", "method": "eth_getLogsWithCursor", "params": [\ {\ "fromBlock": "0x100",\ "toBlock": "0x200",\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "topics": ["0xddf252ad..."]\ }\ ], "id": 1 } If the server reaches its processing limit (e.g. max logs or execution time), it will return the logs retrieved so far and include a `cursor` indicating the last log processed. { "jsonrpc": "2.0", "id": 1, "result": { "logs": [\ {\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "blockNumber": "0x101",\ "logIndex": "0x0",\ "topics": ["0xddf252ad..."],\ "data": "0x...",\ "transactionHash": "0x...",\ "transactionIndex": "0x0",\ "blockHash": "0x...",\ "removed": false\ }\ ], "cursor": "0x0000010100000000" } } The client should submit a second request with the same filter (e.g. address, topics, block range) and the `cursor` from the previous response (mandatory). The server will resume the query from where it left off. { "jsonrpc": "2.0", "method": "eth_getLogsWithCursor", "params": [\ {\ "fromBlock": "0x100",\ "toBlock": "0x200",\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "topics": ["0xddf252ad..."],\ "cursor": "0x0000010100000000"\ }\ ], "id": 2 } When the server returns a response _without_ a `cursor`, it means that all matching logs have been retrieved and no further requests are needed { "jsonrpc": "2.0", "id": 2, "result": { "logs": [\ {\ "address": "0x1234567890abcdef1234567890abcdef12345678",\ "blockNumber": "0x102",\ "logIndex": "0x3",\ "topics": ["0xddf252ad..."],\ "data": "0x...",\ "transactionHash": "0x...",\ "transactionIndex": "0x2",\ "blockHash": "0x...",\ "removed": false\ }\ ] // No cursor field — query is complete } } --- # MegaETH Docs – Mini Blocks MegaETH has two types of blocks: mini blocks and EVM blocks. EVM blocks are identical to their counterparts in other EVM chains, ensuring compatibility with existing tools and applications. Mini blocks are specific to MegaETH and anchor an ecosystem of applications, tools, and infrastructure propose-built for minimum end-to-end latency. Motivation ---------- Handling blocks at 10 millisecond intervals requires a significant amount of resources. While software optimizations and powerful hardware give the sequencer ample headroom to produce 100 blocks per second, pushing the data to other nodes, especially ones with limited connectivity, quickly becomes a bottleneck. The key issue with standard EVM blocks is that their headers take up quite some space—more than 500 bytes per block. At 100 blocks per second, this translates to 1.57 TB of data per year just for the headers, a significant burden for lightweight setups. Besides the resource overhead, the standard EVM block header is designed for chains whose block times are seconds or higher as well as light clients who use block headers as the sole root of trust. For example, timestamps have one second resolution, and the multiple Merkle roots optimize for succinctness of Merkle proofs rather than compactness of the headers. We believe that interactions with a chain in realtime—at tens of milliseconds of latency—will take on a different paradigm, and it is the right opportunity to redesign blocks for compactness and low latency. Properties of Mini Blocks ------------------------- Mini blocks share a lot of similarities with EVM blocks. Like EVM blocks, * Mini blocks are ordered lists of transactions executed and preconfirmed by the sequencer. * Mini blocks contain every transaction that has been processed by the system. That is, every transaction appears in one mini block and one EVM block. * Mini blocks are totally ordered by their block height, starting with 0 at the genesis. * Preconfirmation of mini blocks by the sequencer has the same level of guarantees as EVM blocks. On the other hand, there are some key differences * Mini blocks contain a different set of metadata fields compared to EVM blocks. * To make effective use of mini blocks, such as retrieving mini blocks with minimum latency, applications should use the [Realtime API](https://docs.megaeth.com/realtime-api) —MegaETH’s extension to the standard Ethereum JSON-RPC API. Transactions in a mini block never span multiple EVM blocks. In other words, for every mini block, the transactions it contains all appear in the same EVM block. Naturally, this establishes a mapping between mini blocks and EVM blocks; we say a mini block is _included_ in an EVM block if the former contains transactions that appear in the latter. MegaETH produces an EVM block roughly every second and a mini block roughly every 10 milliseconds. This implies a rough 1-to-100 ratio between the number of EVM blocks and the number of mini blocks. However, there is no guarantee on the number of mini blocks included in an EVM block. To get the precise number, developers should use the `miniBlockCount` field in the responses when calling `eth_subscribe` to subscribe to `newHeads`. This is an example of the responses: { ... "number": "0x57f898", "miniBlockCount": "0x57" ... } --- # MegaETH Docs – MegaEVM _MegaEVM_ is MegaETH’s execution environment. It is fully compatible with Ethereum smart contracts while introducing optimizations for the unique characteristics of MegaETH’s architecture. Overview -------- MegaEVM builds on established standards. Its latest hardfork, _Rex_, is based on [Optimism Isthmus](https://specs.optimism.io/protocol/isthmus/overview.html) , which in turn is adapted from [Ethereum Prague](https://ethereum.org/roadmap/pectra/) . This means: * All standard Solidity contracts work on MegaETH. * Standard development tools (Hardhat, Foundry, Remix, etc.) are compatible. * Existing Ethereum libraries and patterns apply. Meanwhile, MegaEVM introduces a few changes to accommodate MegaETH’s low fees and high capacity. The most important change is the _multidimensional gas model and resource limits_. In MegaEVM, transactions consume two types of gas: _compute gas_, which models computation at large and is identically defined as Ethereum’s gas; and _storage gas_, a new concept that models the storage subsystem in particular. Similarly, MegaEVM caps resource usage of transactions and blocks using rules that each targets an individual type of resource. Developers should consider these changes in contrast to Ethereum’s EVM, where gas is the singular metric for metering and limiting resource consumption. ### Key Differences at a Glance | Feature | Ethereum | MegaETH | Remarks | | --- | --- | --- | --- | | Max contract size | 24 KB | **512 KB** | | | Max initcode size | 48 KB | **536 KB** | | | Gas forwarding rule | 63/64 | **98/100** | As defined in [EIP-150](https://eips.ethereum.org/EIPS/eip-150)
. | | `SELFDESTRUCT` | Deprecated | **Disabled** | Deprecated in [EIP-6049](https://eips.ethereum.org/EIPS/eip-6049)
. | | Gas model | Unidimensional | **Multidimensional** | Compute gas and storage gas. Compute gas is identical to Ethereum’s gas. | | Resource limits | Unidimensional | **Multidimensional** | 4 limits in addition to total gas limit specified by sender. | | Base intrinsic gas | 21,000 | **60,000** | 21,000 compute gas plus 39,000 storage gas. | Multidimensional Gas Model -------------------------- MegaETH uses a _multidimensional gas model_ that separates gas costs into two categories: * **Compute Gas**: Standard execution costs as defined in Ethereum’s EVM * **Storage Gas**: Additional costs for operations that create persistent data The total gas of a transaction is the sum of its compute gas and storage gas. ### Compute Gas Costs For any operation, its compute gas cost in MegaEVM is equal to its gas cost in standard EVM. For example, updating a cold storage slot from zero to nonzero costs 22,100 gas in standard EVM, so the compute gas cost of the said operation in MegaEVM is also 22,100. As another example, every transaction incurs an intrinsic gas cost of 21,000 in standard EVM, so every transaction also incurs an intrinsic compute gas cost of 21,000 in MegaEVM. As a rule of thumb, the amount of compute gas a transaction burns is equal to the amount of gas it would burn in Ethereum’s EVM. ### Storage Gas Costs The storage gas cost of most operations is zero. The following table lists all operations where storage gas does apply. Some storage gas calculations involve a parameter called _bucket multiplier_ (denoted as m). The next section explains this concept. | Operation | Storage Gas Cost | Remarks | | --- | --- | --- | | Intrinsic | 39,000 | Incurred by every transaction. Combined with the intrinsic compute gas cost of 21,000, the total intrinsic gas cost of a transaction is 60,000. | | Zero-to-nonzero `SSTORE` | 20,000 × (m-1) | Only applies to zero-to-nonzero writes. | | Account creation | 25,000 × (m-1) | Value transfer to empty account. | | Contract creation | 32,000 × (m-1) | `CREATE`/`CREATE2` operations. | | Code deposit | 10,000/byte | Per byte of deployed bytecode. | | `LOG` topic | 3,750/topic | Per topic in event. | | `LOG` data | 80/byte | Per byte of event data. | | Calldata (zero) | 40/byte | Per zero byte in transaction input. | | Calldata (nonzero) | 160/byte | Per nonzero byte in transaction input. | | EIP-7623 floor (zero) | 100/byte | [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623)
floor cost per zero byte in transaction input. | | EIP-7623 floor (nonzero) | 400/byte | [EIP-7623](https://eips.ethereum.org/EIPS/eip-7623)
floor cost per nonzero byte in transaction input. | All other operations not mentioned in the previous table incurs no storage gas cost. ### Bucket Multiplier Accounts and their storage slots are stored in segments of MegaETH’s SALT state trie called “buckets”. Buckets grow in size and capacity as they hold more data. The cost of writing new data to a bucket (creating new accounts or changing storage slots from zero to nonzero) varies based on its capacity, and such variation is reflected in storage gas costs of these operations in the form of the _bucket multiplier_ (denoted as m). The bucket multiplier of a bucket is simply defined as the ratio of its capacity and the minimum capacity of buckets. The latter is a system parameter. In other words, Bucket Multiplier = Bucket Capacity / MIN_BUCKET_CAP. SALT’s design ensures that bucket multiplier is always an integer. Without diving into details of SALT, here are a few rules of thumb for developers. * Unless a bucket has expanded to handle heavy storage needs, bucket multiplier is typically 1. * When bucket multiplier is 1, `SSTORE`, account creation, and contract creation incurs zero storage gas cost. * Bucket expand as they fill up; the multiplier increases and storage gas costs rise. * Developers typically do not need to consider bucket multiplier when designing contracts. Below are a few examples of storage gas costs at different bucket multiplier values. | Operation | m=1 | m=2 | m=4 | | --- | --- | --- | --- | | Zero-to-nonzero `SSTORE` | 0 | 20,000 | 60,000 | | Account creation | 0 | 25,000 | 75,000 | | Contract creation | 0 | 32,000 | 96,000 | ### Tips for Developers * **Use MegaETH’s native gas estimation APIs.** Tools not explicitly modified for MegaEVM do not account for storage gas and will report overly small numbers. * For example, when running `forge script`, use `--skip-simulation` to avoid its built-in EVM and use `--gas-limit` to manually specify a sufficiently high gas limit. * **Account for storage gas.** An Ether transfer costs 60,000 gas (21,000 compute gas plus 39,000 storage gas). This is the minimum gas cost (intrinsic gas) for any transaction. * The RPC returns “intrinsic gas too low” when transaction gas limit is smaller than 60,000. * **Prefer transient storage or memory over persistent storage.** Allocating new storage slots costs storage gas and counts towards various resource limits (explained in the next section). Use transient storage ([EIP-1153](https://eips.ethereum.org/EIPS/eip-1153) `TSTORE`/`TLOAD`) for data that only needs to persist within a transaction, or memory for data within a single call. This avoids storage gas costs entirely and ensures calling transactions stay within resource limits. * **Reuse storage slots.** Storage gas applies when changing a slot from zero to nonzero and does not apply when overwriting a slot that is already nonzero. When a slot can be freed (i.e., changed to zero) but is expected to be allocated again (i.e., changed to nonzero) very soon, consider keeping the slot at nonzero so that no storage gas is charged the next time it is used. * As a rule of thumb, avoid design patterns that allocate a lot of slots only to free them soon after. Multidimensional Resource Limits -------------------------------- In addition to limits already defined in standard EVM, MegaEVM enforces four additional limits on how much resources each transaction or block may consume. The following table is an overview. The next few sections explain what counts towards each type of resource and the respective limit. | Resource Type | Per-Transaction Limit | Per-Block Limit | | --- | --- | --- | | Compute Gas | 200,000,000 | N/A | | Data Size | 12.5 MB | 12.5 MB | | KV Updates | 500,000 | 500,000 | | State Growth | 1,000 | 1,000 | When a transaction hits _any_ of the aforementioned per-transaction limits, the following happens: 1. Execution halts immediately. 2. Any remaining gas is preserved and refunded to sender. 3. Transaction is included in the block with status set to failed (status=0). 4. No state changes from the transaction are applied. If any of the aforementioned per-block limits is hit when building a block, the following happens: 1. The transaction that caused the block to go over limits is allowed to execute to completion and will be included in the block. Per-transaction limits still apply. 2. No more transaction will be executed or added to this block. ### Definitions of Resource Types For all resource types, the usage incurred by a block is simply the sum of the usage incurred by each transaction in the block. For example, if a block contains two transactions, one using 300 KV updates and the other using 400 KV updates, then the block uses 700 KV updates. The usage incurred by an individual transaction is defined as following. #### Compute Gas Compute gas cost of a transaction as defined in previous sections. #### Data Size Data size measures the amount of data that needs to be transmitted and stored for each transaction. Both the transaction itself and its execution results are considered. It is the total size of the following items: * Transaction calldata * Event logs (topics and data) * Storage writes (40 bytes per write) * Account updates (40 bytes each) * Deployed contract code #### KV Updates KV updates measure the total number of state entries (accounts and storage slots) updated by a transaction. Each update to a storage slot or an account counts as one update towards the limit. Repeated updates to the same storage slot or account counts as only one update. #### State Growth State growth measures the number of new state entries (accounts and storage slots) created by a transaction. Each new storage slot (created by a zero-to-nonzero `SSTORE`), account, or contract counts as one unit towards the limit. If a newly created storage slot or account is cleared before the transaction ends, thus occupying no storage space permanently, it does not count towards the limit. Access to Volatile Data ----------------------- MegaEVM provides APIs for transactions to access _volatile data_, or data that changes frequently and thus expires quickly after being accessed. This includes metadata of the current block such as the block number, states of the block beneficiary, as well as data available through the native oracle interface (see below). When a transaction accesses volatile data, dependency forms between the transaction and other transactions or operations that attempt to update the data. Such dependency harms performance. For example, if a transaction reads the current block number using the `NUMBER` opcode, the sequencer cannot start a new block until the transaction finishes and gets included in the current block, as doing so would cause the block number to change and invalidate the value previously read by the transaction. If the transaction takes long to finish, block production would be blocked (no pun intended), which impacts latency. MegaEVM mitigates this issue by limiting the amount of compute gas a transaction may use _after it accesses volatile data_. This ensures transactions that access volatile data yield quickly. In the following subsections, we detail the limits. ### Opcodes for Access the Block Environment Accessing these opcodes caps remaining compute gas to 20,000,000. | Opcode | Description | | --- | --- | | `NUMBER` | Current block number | | `TIMESTAMP` | Current block timestamp | | `COINBASE` | Block beneficiary address | | `DIFFICULTY` | Block difficulty | | `GASLIMIT` | Block gas limit | | `BASEFEE` | Base fee per gas | | `PREVRANDAO` | Previous block randomness | | `BLOCKHASH` | Historical block hash | | `BLOBBASEFEE` | Blob base fee | | `BLOBHASH` | Blob hash lookup | ### Accessing the Beneficiary Account Accessing the block beneficiary (coinbase) account also caps remaining compute gas to 20,000,000. | Trigger | Description | | --- | --- | | `BALANCE`, `SELFBALANCE` | Reading beneficiary’s balance | | `EXTCODECOPY`, `EXTCODESIZE`, `EXTCODEHASH` | Accessing beneficiary’s code | | Transaction sender is beneficiary | When `msg.sender == block.coinbase` | | Transaction recipient is beneficiary | When call target is `block.coinbase` | | `DELEGATECALL` to beneficiary | Delegated context accessing beneficiary | ### Accessing the Native Oracle Interface Accessing the system contract of the native oracle interface caps remaining compute gas to 1,000,000. * Oracle contract address: `0x6342000000000000000000000000000000000001` * Applies to `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` ### Remarks When multiple types of volatile data are accessed in the same transaction, the _most restrictive limit applies_. For example, if a transaction accesses both the block environment (triggering the 20m limit) and the oracle interface (triggering the 1m limit), the cap will be 1m. The order in which the transaction accesses the data types does not matter. The lowest cap is enforced globally. Because these limits apply _after_ accesssing volatile data, developers should perform heavy computation before any attempt to access volatile data. The following is a counterexample. // Bad: Heavy computation after reading timestamp function processWithTimestamp() external { uint256 currentTime = block.timestamp; // Triggers 20M gas cap // This loop might run out of gas! for (uint i = 0; i < 10000; i++) { heavyComputation(i, currentTime); } } System Contracts & the Native Oracle Service -------------------------------------------- MegaEVM provides a native oracle interface that provides realtime access to data from off-chain sources. ### High-Precision Timestamp Oracle This oracle provides timestamps at microsecond resolution. Developers might find it useful if `block.timestamp` is not granular enough. **Address:** `0x6342000000000000000000000000000000000002` **Interface:** interface HighPrecisionTimestampOracle { function timestamp() external view returns (uint256); } Note that data for this oracle is supplied solely by the sequencer based on its local clock. This implies that the sequencer must be trusted to publish accurate data. Avoid using this oracle if such trust assumption is too strong for your use case. This oracle internally reads the core oracle contract `0x6342000000000000000000000000000000000001`. Hence, obtaining high-precision timestamps is accesses volatile data and is subject to the compute gas limits detailed in the previous section. Miscellaneous ------------- ### Increased Contract Size Limit MegaETH supports contracts up to 512 KB in size. This is increased from 24 KB in Ethereum. ### `SELFDESTRUCT` is Disabled The `SELFDESTRUCT` opcode is completely disabled and is treated as an `INVALID` opcode. It will cause any transaction using this opcode to fail. In Ethereum, `SELFDESTRUCT` is deprecated but still available. ### “98/100” Rule for Gas Forwarding MegaETH allows a caller to forward at most 98/100 of remaining gas to callee. The parameter is 63/64 in Ethereum. ---