# Arbitrum vs. Ethereum API Differences

> Learn about the differences between Arbitrum and Ethereum

> For the complete documentation index, see [llms.txt](/docs/llms.txt).

Arbitrum is designed to be as compatible and consistent with Ethereum as possible, from its high-level RPCs to its low-level bytecode and everything in between. Dapp developers with experience building on Ethereum will likely find that little-to-no new L2-specific knowledge is required to build on Arbitrum.

This document presents an overview of some of the minor differences, perks, and gotchas that devs are advised to be aware of.

# Block and Transaction Properties

## Blocks and Time

Time in L2 is tricky; the timing assumptions one is used to making about L1 blocks don't exactly carry over into the timing of Arbitrum blocks. For details, see [Block Numbers and Time](https://developer.offchainlabs.com/time).

## Block hashes and randomness

Arbitrum's L2 block hashes should not be relied on as a secure source of randomness (see ['blockhash(x);](https://developer.offchainlabs.com/solidity-support))

## L1 Fees

The L2 fees an Arbitrum transaction pays essentially work identically to gas fees on Ethereum. Arbitrum transactions must also, however, pay an L1-fee component to cover the cost of their calldata. (See [L1 pricing](https://developer.offchainlabs.com/arbos/l1-pricing).)

# L1 to L2 Messages

Arbitrum chains support arbitrary L1 to L2 message passing; developers using this functionality should familiarize themselves with how they work (see [L1 to L2 Messaging](https://developer.offchainlabs.com/arbos/l1-to-l2-messaging)). Of particular note:

* The result of a successful initial/"auto"-execution of an L1 to L2 message will be an unsigned L2 tx receipt.
* The `msg.sender` of the L2 side of an L1 to L2 message will be not the initiating L1 address, but rather its address alias.
* Using the special `ethDeposit` method will not result in an L2 contract's fallback function getting triggered. Etc.

# Precompiles

Arbitrum chains include a number of special precompiles not present on Ethereum; see [Common Precompiles](https://developer.offchainlabs.com/arbos/common-precompiles) / [All Precompiles](https://developer.offchainlabs.com/arbos/precompiles).

Of particular note is the [ArbAddressTable](https://developer.offchainlabs.com/arbos/precompiles#ArbAddressTable), which allows contracts to map addresses to integers, saving calldata / fees for addresses expected to be reused as parameters; see [Arb Address Table tutorial](https://github.com/OffchainLabs/arbitrum-tutorials/tree/master/packages/address-table) for example usage.

# Solidity

You can deploy Solidity contracts onto Arbitrum just like you do Ethereum; there are only a few minor differences in behavior. See [Solidity Support](https://developer.offchainlabs.com/solidity-support) for details.

# JSON-RPC Comparisons

This section covers the differences in response body fields you'll find when using the Arbitrum JSON-RPC vs Ethereum mainnet.

<Info>
  Comprehensive documentation on all generally available JSON-RPC methods for Ethereum [can be found at ethereum.org](https://ethereum.org/en/developers/docs/apis/json-rpc/). As Arbitrum has `go-ethereum` at its core, most of the documented methods there can be used with no modifications.
</Info>

## Blocks

When calling `eth_getBlockByHash` or `eth_getBlockByNumber`, Arbitrum includes a few additional fields and leverages some existing fields in different ways than mainnet Ethereum.

### Additional Fields

* `l1BlockNumber`: An approximate L1 block number that occurred before this L2 block. See [Block Numbers and Time](https://developer.offchainlabs.com/time) for more info.
* `sendCount`: The number of L2-to-L1 messages since Nitro genesis.
* `sendRoot`: The Merkle root of the Outbox tree state.

### Existing Fields With Different Behavior

* `extraData`: This field is equivalent to `sendRoot`
* `mixHash`: First 8 bytes is equivalent to `sendCount`, second 8 bytes is equivalent to `l1BlockNumber` difficulty: Fixed at `0x1`
* `gasLimit`: Value is fixed at `0x4000000000000`, but it's important to note that Arbitrum currently has a 32M gas limit per block See full list of [mainnet block fields](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getblockbyhash) for additional reference.

## Transactions

### Transaction Types

In addition to the [three transaction types](https://ethereum.org/en/developers/docs/transactions/#types-of-transactions) currently supported on mainnet, Arbitrum adds additional types listed below and [documented in full detail here](https://developer.offchainlabs.com/arbos/geth#transaction-types).

On RPC calls that return transactions, such as [`eth_getTransactionByHash`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash), the `type` field will reflect the custom codes where applicable.

* `100` - `ArbitrumDepositTxType`: A deposit of ETH from L1 to L2 via the Arbitrum bridge.
* `101` - `ArbitrumUnsignedTxType`: An L1 user can use to call an L2 contract via the bridge.
* `102` - `ArbitrumContractTxType`: Allows an L1 contract to call an L2 contract method via the bridge.
* `104` - `ArbitrumRetryTxType`: Used to [redeem a retryable ticket](https://developer.offchainlabs.com/arbos/l1-to-l2-messaging#redeeming-a-retryable) on L2, which finalizes a [retryable](https://developer.offchainlabs.com/arbos/l1-to-l2-messaging#retryables) that failed to execute automatically (usually due to low gas).
* `105` - `ArbitrumSubmitRetryableTxType`: Retryable tickets are [submitted via the L1 bridge](https://developer.offchainlabs.com/arbos/l1-to-l2-messaging#submitting-a-retryable) and allow arbitrary L1 to L2 messages to be created and executed on L2.
* `106` - `ArbitrumInternalTxType`: Internal transactions created by the ArbOS itself for certain state updates, like L1 base fee and block number.

### Additional Fields

* `requestId`: Added to L1-to-L2 transactions to indicate position in the `Inbox` queue.

### Existing Fields With Different Behavior

* `from`: For L1-to-L2 related transactions, will be the aliased version of the L1's `msg.sender`. See [L1 to L2 Messaging](https://developer.offchainlabs.com/arbos/l1-to-l2-messaging) for more info.

See full list of [mainnet transaction fields](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash) for additional reference.

## Tx Receipts

### Additional Fields

* `l1BlockNumber`: The L1 block number that would be used [for `block.number` calls](https://developer.offchainlabs.com/time).
* `gasUsedForL1`: Amount of gas spent on L1 calldata in units of L2 gas.

See full list of [mainnet transaction receipt](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionreceipt) fields for additional reference.