Deployment Summary for Developers
This page summarizes what you need to know when developing or deploying smart contracts for Monad.
Network Information
See Network Information for chain id, public RPC, block explorer, and canonical contract deployments.
Accounts
Address space | Same address space as Ethereum (last 20 bytes of ECDSA public key) |
EIP-7702 | Supported. See EIP-7702 reference |
Smart Contracts
Opcodes | All opcodes as of the Pectra fork are supported. |
Precompiles | All Ethereum precompiles as of the Pectra fork (0x01 to 0x11 ), plus precompile 0x0100 (RIP-7212) are supported. See Precompiles |
Max contract size | 128 kb (up from 24.5 kb in Ethereum) |
Transaction types
Full article: Transactions
Transaction types | Supported:
|
Gas limits
Per-transaction gas limit | 30M gas |
Block gas limit | 200M gas |
Block gas target | 80% (160M gas) |
Gas throughput | 500M gas/sec (200M gas/block divided by 0.4 sec/block) |
Gas pricing
Full article: Gas pricing
Gas charged | The gas limit is what is charged. That is: total tokens deducted from the sender's balance is value + gas_price * gas_limit . See discussion. |
EIP-1559 dynamics | Monad is EIP-1559-compatible; base fee and priority fee work as on Ethereum. EIP-1559 explainer |
Base fee | Monad uses a different base fee controller (details), and has a min base fee of 100 MON-gwei (100 * 10^-9 MON ) |
Opcode pricing
Full article: Opcode Pricing and Refunds
Opcode pricing is the same as on Ethereum (see: evm.codes), except for the below repricings needed to reweight relative scarcities of resources due to Monad optimizations.
Item | Ethereum | Monad | Notes |
---|---|---|---|
Cold access cost - account | 2,600 | 10,100 | Affected opcodes: BALANCE , EXTCODESIZE , EXTCODECOPY , EXTCODEHASH , CALL , CALLCODE , DELEGATECALL , STATICCALL , SELFDESTRUCT See details |
Cold access cost - storage | 2,100 | 8,100 | Affected opcodes: SLOAD , SSTORE . See details |
Storage slot creation cost (changing zero to nonzero) | 20,000 | 122,900 | See details. Paired with higher refund amount to encourage cleanup |
Storage slot cleanup rebate (changing nonzero to zero) | 1,900 | 117,100 | See details |
CREATE and CREATE2 | 32,000 + 200 gas/byte | 160,000 + 1200 gas/byte | See details |
ecRecover , ecAdd , ecMul , ecPairing , blake2f , point_eval precompiles | See details Precompiles 0x01 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0a |
Timing considerations
Block frequency | 400 ms |
TIMESTAMP opcode | As in Ethereum, TIMESTAMP is a second-granularity unix timestamp. Since blocks
are every 400 ms, this means that 2-3 blocks will likely have the same timestamp. |
Finality | Blocks are finalized after two blocks (800 ms). Once a block is finalized, it cannot be reorged. See MonadBFT for a fuller discussion. |
Speculative finality | Blocks can be
speculatively finalized
after one block (400 ms), when it is marked as being in the Voted stage.Speculative finality can revert under very rare circumstances (see fuller discussion here), but most frontends should be able to reflect state based on speculative finality. |
Mempool
Full article: Local Mempool
Monad does not have a global mempool, as this approach is not suitable for high-performance blockchains.
Each validator maintains a local mempool with transactions that it is aware of. When an RPC receives a transaction, it forwards it strategically to upcoming leaders, repeating this process if it doesn't observe the transaction getting included.
Although this is an important part of Monad's design, it is not one that should generally affect smart contract developers in their system designs.
Parallel Execution and JIT Compilation
Monad utilizes parallel execution and JIT compilation for efficiency, but smart contract developers don't need to change anything to account for this.
In Monad, transactions are still linearly ordered, and the only correct outcome of execution is the result as if the transactions were serially executed. All aspects of parallel execution can be treated by smart contract developers as implementation details. See further discussion.
Asynchronous Execution
Full article: Asynchronous Execution
Monad utilizes asynchronous execution for efficiency, but most developers shouldn't need to change anything.
Developers with significant off-chain financial logic (e.g. exchanges, bridges, and
stablecoin/RWA issuers) should wait until blocks reach the
Verified
phase (aka state root finality), three blocks later than
Finalized
,
to be sure that the entire network agrees with their own node's local execution of a
finalized block.
More detail: asynchronous execution is a technique that allows Monad to substantially increase execution throughput by decoupling consensus from execution. In asynchronous execution, validators vote first, execute later - because once the transaction order is determined, the state is determined. Afterward, each node executes locally. There is a delayed merkle root three blocks later which confirms that the network got the same state trie as local execution.
From the developer perspective:
- Someone submits a transaction through your frontend which interacts with your smart contract. You make note of the hash.
- The transaction gets included in a block.
- The block gets
Voted
(speculatively finalized) one block later. (T+1
) - The block gets
Finalized
one block later (T+2
) - The block gets
Verified
(state root finalized) three blocks later (T+5
)
You listen for transaction receipts by calling
eth_getTransactionReceipt
.
Receipts will first be available after a block becomes Voted
(speculatively finalized).
Your choice of when to update your UI to give feedback to the user depends on risk preference, but
for most applications it is reasonable to do so when the block becomes Voted
because speculative
finality reversion is extremely rare. A more conservative approach would be to wait until the
block is Finalized
, since then you will never have to handle a reorg. Waiting until Verified
is not generally necessary (except for the aforementioned developers with off-chain financial
logic).
Reserve balance
Full article: Reserve Balance
Monad introduces the Reserve Balance mechanism to enable Asynchronous Execution.
The Reserve Balance mechanism places light restrictions on when transactions can be included at consensus time, and imposes some conditions under which transactions will revert at execution time.
The Reserve Balance mechanism is designed to preserve safety under asynchronous execution without interfering with normal usage patterns. Most users and developers need not worry about the Reserve Balance constraints, but check out the docs if you are interested in learning more.
Parameter | Value |
---|---|
Default reserve balance | 10 MON |
Reading blockchain data
The following methods are supported for reading blockchain data:
JSON-RPC | See RPC API. Monad supports all standard RPC methods from Ethereum. Differences are noted here. |
WebSocket | See the WebSocket Guide. Monad implements the eth_subscribe method with the following subscription types:
syncing and newPendingTransactions subscription types are not supported.
For more details see Real-time Data Sources. |
Execution Events | See Execution Events. The Execution Events system allows developers to build high-performance applications that receive lowest-latency event data from a Monad node via shared memory queue. |
You can also use the supported Indexers.
Historic data
Monad full nodes provide access to all historic ledger data (blocks, transactions, receipts, events, and traces).
Monad full nodes do not provide access to arbitrary historic state.
See further discussion of historic data here.
Canonical contract addresses
Supported third-party infrastructure
See Tooling and Infrastructure