Technology

Toward Ethereum Equivalence #4 — Ethereum transaction types

With Klaytn v1.8.0, we have added new Klaytn transaction types to support the existing Ethereum transaction types. In this article, we will explain the definition, the purpose, and some things to consider when using these new transaction types.

Purpose of supporting Ethereum transactions types

In the past, Ethereum used to support only one transaction type `LegacyTransaction`, whereas Klaytn has always supported various different transaction types from its inception. However, with the introduction of the EIP-2718 Typed Transaction Envelope, Ethereum has also now begun support for different types of transactions. This change in the way Ethereum handles its own transaction types, gave rise for the need to encompass both chains’ transaction types within Klaytn and at the same time distinguish between them. As such, for Klaytn v1.8.0, we have added transaction types that are compatible with Ethereum transaction formats.

We will start with an explanation of some of the things that you need to consider when using Ethereum formatted transactions on Klaytn, and then introduce Ethereum transaction types and Klaytn’s new transaction types.

Ethereum formatted transactions on Klaytn

First and foremost, it is important to take into account that some fields may not function as expected due to inherent differences between Klaytn and Ethereum. For example, as Klaytn has a fixed gas price, `GasTipCap` (`maxPriorityFeePerGas`) and `GasFeeCap` (`maxFeePerGas`) in `DynamicFeeTx` would only be processed when the gas price is set to the value as determined by the governance (currently at 25 ston).

To help Ethereum developers easily migrate their projects to Klaytn with minimum adjustments, Klaytn `eth` namespace APIs have adopted Ethereum transaction formats, meaning they will behave and process the same on Klaytn just as they do on Ethereum. The RLP serialization for the signature of the transaction hash is the same for both the `eth` namespace and the `klay` namespace. However, Klaytn has a different Raw Transaction RLP serialization rule specifically for the `klay` namespace interface, so as to process all transactions for Klaytn and Ethereum without there being conflicts between the existing transaction types of the two. For more details, please refer to Ethereum Tx Type and Klaytn New Tx Type. Below you will find explanations on the different RLP serializations for each respective namespace.

`eth` namespace API

You can use the exact transaction formats as defined in Ethereum with `eth` namespace APIs. Therefore, the RLP procedure for the signature, transaction hash and Raw Transaction are the same as on Ethereum.

SigHashRLP = EthereumTransactionType || TransactionPayloadTxHashRLP = EthereumTransactionType || TransactionPayloadRawTx = EthereumTransactionType || TransactionPayload

If you are using the `eth` namespace APIs while using a Geth client and Ethereum development tools (ethers.js, web3.js, Hardhat, Truffle, …), you can use Ethereum transactions on Klaytn without making any changes.

`klay` namespace API

The RLP procedure for the signature or transaction hash with the `klay` namespace is the same as with the `eth` namespace, however, there is one exception applied to Raw Transactions, as it requires the identifier `EthereumTxTypeEnvelope`.

SigHashRLP = EthereumTransactionType || TransactionPayloadTxHashRLP = EthereumTransactionType || TransactionPayloadRawTx= EthereumTxTypeEnvelope || EthereumTransactionType || TransactionPayload

Hence, if you are using the `klay` namespace APIs with a Klaytn Client, and Klaytn development tools (caver-js, caver-java, …), then you have to use the Ethereum transaction types following the instructions outlined above.

Ethereum Tx Type and Klaytn New Tx Type

With Klaytn v1.8.0, the transaction types `TxTypeEthereumAccessList` and `TxTypeEthereumDynamicFee` have been added to support Ethereum transactions AccessListTxType and DynamicFeeTxType. The table below shows the Ethereum transaction types and the corresponding transaction types for Klaytn.

The new Klaytn transaction types have been added for the sake of Ethereum compatibility. They have the same fields and format as Ethereum transactions, with the same RLP process. Below you can see the RLP encoding methods to obtain the hash for a signature in each case. You can see that Ethereum and Klaytn transactions are subject to the same procedure.

// AccessListTxType (Ethereum Tx)
sigRLP = 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList])
sigHash = keccak256(sigRLP)

// TxTypeEthereumAccessList (Klaytn Tx)
sigRLP = 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList])
sigHash = keccak256(sigRLP)

// DynamicFeeTxType (Ethereum Tx)
sigRLP = 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list])
sigHash = keccak256(sigRLP)

// TxTypeEthereumDynamicFee (Klaytn Tx)
sigRLP = 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list])
sigHash = keccak256(sigRLP)

The RLP encoding scheme for the transaction hash is also the same for Ethereum and Klaytn transactions.

// AccessListTxType (Ethereum Tx)
TxHashRLP = 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signature_y_parity, signature_r, signature_s])
TxHash = keccak256(TxHashRLP)

// TxTypeEthereumAccessList (Klaytn Tx)
TxHashRLP = 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signature_y_parity, signature_r, signature_s])
TxHash = keccak256(TxHashRLP)

// DynamicFeeTxType (Ethereum Tx)
TxHashRLP = 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])
TxHash = keccak256(TxHashRLP)

// TxTypeEthereumDynamicFee (Klaytn Tx)
TxHashRLP = 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])
TxHash = keccak256(TxHashRLP)

However, as noted, different rules apply for Ethereum and Klaytn when it comes to Raw Transactions. In Klaytn you will have to attach an additional `EthereumTxTypeEnvelope` type to Raw Transactions in order to distinguish the Ethereum transaction formats.

The table below shows these transaction types.

To differentiate the existing Klaytn transaction types from Ethereum transaction types, `EthereumTxTypeEnvelope` (`0x78`) will be used to designate these transactions on Klaytn. Using this identifier, it is possible to accommodate both current and future Ethereum transaction types on Klaytn.

The identifier `EthereumTxTypeEnvelope` is also used within Raw Transactions for the ‘klay’ API and interface namespace. As you can see below, Klaytn adds the identifier for Raw Transactions, unlike Ethereum.

(NOTE: `eth` namespace APIs still use the Ethereum formats without `EthereumTxTypeEnvelope`)

// AccessListTxType (Ethereum Tx)
RawTx = 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signature_y_parity, signature_r, signature_s])

// TxTypeEthereumAccessList (Klaytn Tx)
RawTx = EthereumTxTypeEnvelope || 0x01 || rlp([chainId, nonce, gasPrice, gasLimit, to, value, data, accessList, signature_y_parity, signature_r, signature_s])

// DynamicFeeTxType (Ethereum Tx)
RawTx = 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])

// TxTypeEthereumDynamicFee (Klaytn Tx)
RawTx = EthereumTxTypeEnvelope || 0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s])

In this article we explained Ethereum transaction types and Klaytn’s new transaction types to help you understand the purpose of this change, as well as how to use them. For more details on the new transaction types, please refer to Klaytn Docs.

Article Series