Ethereum: understanding transaction identifiers and creating your own
As a developer creating blockchain applications on the Ethereum network, you are probably familiar with the importance of a unique identifier for each transaction. In this article, we will delve into how to generate a transaction identifier (Tx ID) in Ethereum and explore its intricacies.
What is a Transaction ID?
In Ethereum, the transaction identifier serves as a unique identifier for each transaction sent over the network. It is used by the Ethereum Virtual Machine (EVM) to identify and verify a transaction in the blockchain. The Tx identifier is usually generated when creating a transaction using the transaction
function in Solidity or Ethers.js.
How to generate a transaction ID
To generate a transaction ID, you need to create a serialized version of your transaction data that includes:
- Transaction data: fields such as gas price, gas limit, one-time number and value can be included here.
- Encryption Keys: You need to encrypt these fields with a pair of keys (private key and public key).
Here’s an example on Solidity:
`solidity
pragma solidity ^0.8.0;
import "
contract MyContract {
function transaction() public payable returns (uint256) {
// Create a new transaction data object
TransactionData txData = TransactionData(
bytes4(abi.encodePacked("value", "gasPrice", "gasLimit"))
);
// Encrypt fields using a private key
bytes memory encryptedTxData = encrypt(txData);
// Compute the transaction identifier as a double SHA-256 hash of the serialized transaction
uint256 txId = keccak256(encryptedTxData, 0x6e8738a2a35fcd5b1c9f24d8f3e4dd7bfbe94b1caafec9ceffebf2c44bd51a14);
return txId;
}
}
struct TransactionData {
bytes value; // Amount to send
uint256 gasPrice; // In wei (unit of gas price measurement)
uint256 gasLimit; // The maximum allowable number of gas units that can be executed in one block
}
function encrypt(TransactionData txData) internal pure returns (bytes memory) {
bytes memory encryptedTxData = abi.encodePacked(
txData.value,
txData.gasPrice,
txData.gasLimit
);
return keccak256(encryptedTxData, 0x6e8738a2a35fcd5b1c9f24d8f3e4dd7bfbe94b1caafec9ceffebf2c44bd51a14);
}
`
In this example, we create aTransactionDatastructure to store transaction data and an
encryptfunction that takes this structure and returns its encrypted version.
Tx ID
The TX identifier is calculated using thekeccak256hash function with the encrypted transaction data as the second argument. The first 128 bits of the resulting hash are the SHA-256 hash of the encrypted transaction data, and the last 64 bits are a timestamp and a unique number (ie, the number of the current block).
To generate a Tx ID for your own transactions, you can use this formula:
TxID = keccak256(encryptedTxData, timestamp + one-time number)
Here is an example:
`solidity
pragma solidity ^0.8.0;
contract MyContract {
function transaction() public payable returns (uint256) {
// Create a new transaction data object
TransactionData txData = TransactionData(
abi.