Differences between EVM chains

  • Transaction signing is incompatible

    • QTUM is based on Bitcoin and therefore requires Bitcoin transaction signing

      • EVM transactions are done with special opcodes in Bitcoin output scripts (OP_CALL/OP_CREATE)

    • Use (Beta) QTUM ethers-js library to sign transactions for use in eth_sendRawTransaction

      • Currently, the library only supports sending 1 tx per block due to Bitcoin inputs being re-used so test your code to redo transactions if they are rejected with eth_sendRawTransaction

        • This will be fixed in a future version

  • Solidity

    • msg.value is denoted in satoshis, not wei, your dapp needs to handle this correctly

    • eth_sign

      • uses a different message prefix than Ethereum: "\u0015Qtum Signed Message:\n" (equal to "\x15Qtum Signed Message:\n")

        • you will need to update your contracts to use this prefix

      • ecrecover won't recover a QTUM address from eth_sign, you will need to implement QIP6 - btc_ecrecover in your contracts

  • Sending coins with the creation of a contract will cause a loss of coins

    • This is a Qtum intentional deisgn decision and will not change

    • Janus will prevent this with eth_sendTransaction but will permit it with eth_sendRawTransaction

    • (Beta) QTUM ethers-js library will reject creating such a transaction

  • Contract address generation differs from EVM chains

    • on EVM chains, the contract address is generated via a hash of the deployer address + the nonce

    • QTUM has no concept of a nonce because it is built on Bitcoin

      • instead the contract address is generated via a hash of the transaction which will always be different because the Bitcoin inputs will be different

      • so, if your app depends on a consistent contract address between deployments on different chains you need to pay special attention to this

      • For contract address generation code, see generateContractAddress

  • Account address generation differs from EVM chains

  • Block hash is computed differently from EVM chains

    • If you are generating the blockhash from the block header, it will be wrong

      • we plan to add a compatiblity layer in Janus to transparently serve the correct block when requesting an Ethereum block hash

        • this will eventually require hooking up Janus to a database to keep a map of hash(block header) => QTUM block hash

  • Remix

    • Debug calls are not supported so you will not be able to do any debugging in Remix

    • You can use Remix with Janus or (Alpha) QTUM Metamask fork

  • It is possible for a QTUM transaction to have more than one EVM transaction in it

    • this is because QTUM does EVM transactions inside Bitcoin outputs which there can be multiple of

    • Janus and (Beta) QTUM ethers-js library will not generate such a transaction

    • Janus will try and work around such a transaction when requesting information about the transaction

      • but it is not possible to map to the EVM model perfectly so there will always be some data missing for these transactions

  • QTUM is proof of stake and requires coins to be mature (older than 2000 blocks) to be used in a transaction

    • this includes staking rewards, gas refunds and block rewards on your local regtest environment

      • a gas refund is an output generated by the miner for every EVM transaction in the same block as the EVM transaction takes place in for unused gas

    • Janus will try to use mature coins first and will fall back to immature coins if there are no mature coins left

      • this can result in transactions being rejected

    • (Beta) QTUM ethers-js library will not use immature coins for transactions, but if you end up using high gas limits for your transactions you could quickly run out of usable coins

      • if there are no mature coins, the transaction will fail locally

  • Bitcoin input scripts

    • Bitcoin has many different types of scripts

    • eth_sendTransaction delegates transaction signing to QTUM so most input scripts should be supported

    • (Beta) QTUM ethers-js library deals with signing transactions locally and only supports Pay to public key hash (P2PKH) scripts, other script types will be ignored and not selected.

      • This can result in your spendable balance being lower than your actual balance.

      • Support for Pay to public key (P2PK) input scripts is on the roadmap

  • eth_estimateGas

    • Gas estimation on QTUM is not perfect, so a buffer of 10% is added in Janus

    • Gas will be refunded in the block that your transaction is mined

      • Keep in mind that to re-use this gas refund, you must wait 2000 blocks

  • eth_sendTransaction

    • When trying to send all your QTUM Balance in a transaction, in EVM you would do value = total - (gas limit * gas price)

    • Since QTUM uses Bitcoin transactions, the cost of a transaction differs based on how many bytes are in the transaction

      • This means if you have many inputs in a transaction, it will cost more to send

    • There is no easy way to send your entire QTUM balance in a single transaction with Janus

  • Since QTUM runs on Bitcoin, QTUM has the concept of dust

    • Janus delegates transaction signing to QTUM so QTUM will handle dealing with dust

    • (Beta) QTUM ethers-js library currently uses dust, but at some point will prevent spending dust by default with a semver change

  • On a transfer of Qtum to a Qtum address, there is no receipt generated for such a transfer

  • When converting from WEI -> QTUM, precision is lost due to QTUM's smallest demonination being 1 satoshi.

    • 1 satoshi = 0.00000001 QTUM = 10000000000 wei

  • QTUM's minimum gas price is 40 satoshi

    • When specifying a gas price in wei lower than that, the minimum gas price will be used (40 satoshi)

    • With the minimum fee per byte being 4 satoshi

  • QTUM will reject transactions with very large fees (to prevent accidents)

Last updated