Differences between Ethereum and Rollux
It's important to note that there are various minor discrepancies between the behavior of Rollux and Syscoin NEVM or Ethereum. You should be aware of these descrepancies when building apps on top of Rollux.
# Opcode Differences
Opcode | Solidity equivalent | Behavior |
---|---|---|
COINBASE | block.coinbase | Undefined |
DIFFICULTY | block.difficulty | Random value. As this value is set by the sequencer, it is not as reliably random as the L1 equivalent. You can use an oracle for randomness. |
NUMBER | block.number | L2 block number |
TIMESTAMP | block.timestamp | Timestamp of the L2 block |
ORIGIN | tx.origin | If the transaction is an L1 ⇒ L2 transaction, then tx.origin is set to the aliased address of the address that triggered the L1 ⇒ L2 transaction. Otherwise, this opcode behaves normally. |
CALLER | msg.sender | If the transaction is an L1 ⇒ L2 transaction, and this is the initial call (rather than an internal transaction from one contract to another), the same address aliasing behavior applies. |
`tx.origin == msg.sender`
On L1 Ethereum tx.origin
is equal to msg.sender
only when the smart contract was called directly from an externally owned account (EOA).
However, on Rollux tx.origin
is the origin on Rollux.
It could be an EOA.
However, in the case of messages from L1, it is possible for a message from a smart contract on L1 to appear on L2 with tx.origin == msg.origin
.
This is unlikely to make a significant difference, because an L1 smart contract cannot directly manipulate the L2 state.
However, there could be edge cases we did not think about where this matters.
# Accessing L1 information
If you need the equivalent information from the latest L1 block, you can get it from the L1Block
contract (opens new window).
This contract is a predeploy at address 0x4200000000000000000000000000000000000015
(opens new window).
You can use the getter functions (opens new window) to get these parameters:
number
: The latest L1 block number known to L2timestamp
: The timestamp of the latest L1 blockbasefee
: The base fee of the latest L1 blockhash
: The hash of the latest L1 blocksequenceNumber
: The number of the L2 block within the epoch (the epoch changes when there is a new L1 block)
# Address Aliasing
Because of the behavior of the CREATE
opcode, it is possible for a user to create a contract on L1 and on L2 that share the same address but have different bytecode.
This can break trust assumptions, because one contract may be trusted and another be untrusted (see below).
To prevent this problem the behavior of the ORIGIN
and CALLER
opcodes (tx.origin
and msg.sender
) differs slightly between L1 and L2.
The value of tx.origin
is determined as follows:
Call source | tx.origin |
---|---|
L2 user (Externally Owned Account) | The user's address (same as in Ethereum or Syscoin) |
L1 user (Externally Owned Account) | The user's address (same as in Ethereum or Syscoin) |
L1 contract (using CanonicalTransactionChain.enqueue ) | L1_contract_address + 0x1111000000000000000000000000000000001111 |
The value of msg.sender
at the top-level (the very first contract being called) is always equal to tx.origin
.
Therefore, if the value of tx.origin
is affected by the rules defined above, the top-level value of msg.sender
will also be impacted.
Note that in general, tx.origin
should not be used for authorization (opens new window).
However, that is a separate issue from address aliasing because address aliasing also affects msg.sender
.
# Why is address aliasing an issue?
The problem with two identical source addresses (the L1 contract and the L2 contract) is that we extend trust based on the address. It is possible that we will want to trust one of the contracts, but not the other.
Helena Hacker forks Uniswap (opens new window) to create her own exchange (on L2), called Hackswap.
Note: There are actually multiple contracts in Uniswap, so this explanation is a bit simplified. See here if you want additional details (opens new window).
Helena Hacker provides Hackswap with liquidity that appears to allow for profitable arbitrage opportunities. For example, she can make it so that you can spend 1 DAI (opens new window)to buy 1.1 USDT (opens new window). Both of those coins are supposed to be worth exactly $1.
Nimrod Naive knows that if something looks too good to be true it probably is. However, he checks the Hackswap contract's bytecode and verifies it is 100% identical to Uniswap. He decides this means the contract can be trusted to behave exactly as Uniswap does.
Nimrod approves an allowance of 1000 DAI for the Hackswap contract. Nimrod expects to call the swap function on Hackswap and receive back nearly 1100 USDT.
Before Nimrod's swap transaction is sent to the blockchain, Helena Hacker sends a transaction from an L1 contract with the same address as Hackswap. This transaction transfers 1000 DAI from Nimrod's address to Helena Hacker's address. If this transaction were to come from the same address as Hackswap on L2, it would be able to transfer the 1000 DAI because of the allowance Nimrod had to give Hackswap in the previous step to swap tokens.
Nimrod, despite his naivete, is protected because Rollux modifies the transaction's
tx.origin
(which is also the initialmsg.sender
). That transaction comes from a different address, one that does not have the allowance.
Note: It is simple to create two different contracts on the same address in different chains. But it is nearly impossible to create two that are different by a specified amount, so Helena Hacker can't do that.
# Blocks
There are several differences in the way blocks are produced between Syscoin L1 and Rollux.
Parameter | Syscoin L1 | Rollux |
---|---|---|
Time between blocks (secs) | 150 (1) | 2 |
Block target size (gas) | 4,000,000 | 15,000,000 |
Block maximum size (gas) | 8,000,000 | 30,000,000 |
(1) This is the average blocktime on Syscoin L1 (2.5 minutes)
The Rollux values are taken from the Rollux specs (opens new window).
# Network specifications
# JSON-RPC differences
Rollux uses the same JSON-RPC API (opens new window) as Ethereum. Some additional Rollux specific methods have been introduced. See the full list of custom JSON-RPC methods for more information.
# Pre-EIP-155 support
Pre-EIP-155 (opens new window) transactions do not have a chain ID, which means a transaction on one Ethereum blockchain can be replayed on others. This is a security risk. pre-EIP-155 transactions are not supported on Rollux.
# Transaction costs
Transaction costs on Rollux include an L2 execution fee and an L1 data fee.
# Contract addresses
The addresses in which various infrastructure contracts are installed are different between L1 Syscoin and Rollux.