VeChain Docs
  • Welcome to VeChain
  • Blockchain Basics
    • Introduction to blockchain
    • Introduction to digital property
    • The evolution of the internet
  • Introduction to VeChain
    • About the VeChain blockchain
      • Consensus Deep Dive
      • Governance
    • Dual-Token Economic Model
      • VeChain (VET)
      • VeThor (VTHO)
    • Acquire VeChain Assets
    • Sustainability
  • Core Concepts
    • Networks
      • Thor Solo Node
      • Testnet
      • Mainnet
    • Nodes
      • Node Rewards Programme
    • Blocks
      • Block Model
    • Transactions
      • Transaction Model
      • Transaction Fees
      • Transaction Calculation
      • Meta Transaction Features
        • Transaction Uniqueness
        • Controllable Transaction Lifecycle
        • Clauses (Multi-Task Transaction)
        • Fee Delegation
          • Multi-Party Payment (MPP)
          • Designated Gas Payer (VIP-191)
        • Transaction Dependency
    • Block Explorers
    • Wallets
      • VeWorld
        • User Guide
          • Setup
          • Wallet
          • Signing
          • Activities
          • Settings
        • FAQ
      • Sync2
        • User Guide
          • Setup
          • Wallet
          • Signing
          • Activities
          • Settings
        • FAQ
      • Sync
        • User Guide
          • Wallet
          • Ledger Device
          • Browser dApps and web
          • Interact with dApps
          • Activities
          • Settings
          • Report an Issue
          • Contributing
        • FAQ
    • EVM Compatibility
      • VeChain Modifications
      • Methodology
      • Test Coverage
        • Gas model
        • Raw transaction
        • hardhat specific
          • Ganache failures
          • evm_increaseTime
        • Failures in constructor
        • eth_sign
        • Contract address prediction
        • BadBeacon proxy address at 0x1
      • How to Recreate
      • Additional Information
        • Using Governance Contracts
        • ERC1820/ERC777 Testnet
        • Delegate Options
    • Account Abstraction
      • UserOperation
      • Bundler
      • EntryPoint Contract
      • Account Factory Contract
      • Paymaster Contract
    • Token Bound Accounts
  • How to run a node
    • Nodes
    • How to run a Thor Solo Node
    • Custom Network
    • Connect Sync2 to a Thor Solo Node
  • Developer Resources
    • Getting Started
    • How to build on VeChain
      • Connect to the Network
      • Read Data
        • Read Blocks
        • Read Transactions
        • Read Accounts
        • States & Views
        • Events & Logs
        • VET Transfers
      • Write Data
        • Transactions
        • Fee Delegation
      • Listen to Changes
        • Events
        • VET Transfers
        • Transactions
        • Blocks
        • Beats
      • Build with Hardhat
      • Utilities
        • BigInt and Unit-Handling
        • Name Service Lookups
    • Example dApps
      • Buy me a Coffee
      • Token Bound Accounts
      • PWA with Privy and Account Abstraction
    • EVM Compatibility for Developers
      • Key Architectural Differences and Optimizations
      • Practical Implications for Developers: Key Considerations
      • RPC Methods (Detailed Breakdown)
      • Frequently Asked Questions (FAQs)
      • VeChain Blockchain Specifications
      • Key Differences Between VeChain and Ethereum (Summary)
      • Best Practices for Developing on VeChainThor
    • How to verify Address-Ownership
      • Next.js Session Verification
    • Debug Reverted Transactions
    • Account Abstraction
    • VIP-191: Designated Gas Payer
      • How to Integrate VIP-191 (I)
      • How to Integrate VIP-191 (II)
      • How to Integrate VIP-191 (III)
    • Index with Graph Node
      • Setup with Docker
      • Index with OpenZeppelin
        • Create Subgraph Project
        • Configure Contracts
        • Deploy Subgraph and start Indexing
        • Track Subgraph Indexing
        • Access Subgraph
        • Update Subgraph
    • SDKs & Providers
      • SDK
        • Architecture
        • Accounts
        • Bloom Filter
        • Certificates
        • Contracts
        • Cryptography
        • Debug
        • Encoding
        • Polls
        • Subscriptions
        • Thor Client
        • Transactions
      • Thor DevKit
        • Installation
        • Usage
          • Cryptography
          • Accounts
          • Encoding
          • Transactions
          • Certificates
          • Bloom Filter
      • DApp Kit
        • v2
          • Installation
          • React
            • Installation
            • Usage
          • Vanilla JS
            • Installation
            • Usage
          • Core
            • Installation
            • Usage
          • Theme Variables
          • i18n
        • v1
          • Installation
          • React
            • Installation
            • Usage
          • Vanilla JS
            • Installation
            • Usage
          • Core
            • Installation
            • Usage
          • Theme Variables
          • i18n
          • Node Polyfills
          • V0 to V1
        • v0
          • Installation
          • Usage
          • React
            • Installation
            • Usage
          • Vanilla (UI)
            • Installation
            • Usage
          • Styles (UI)
          • i18n
      • DevPal
      • Web3-Providers-Connex
        • Installation
        • Usage
      • Connex
        • Installation
        • API Specification
    • Frameworks & IDEs
      • Hardhat
      • Remix
    • Built-in Contracts
    • VORJ
    • Useful Links
  • How to contribute
Powered by GitBook
On this page
  • Introduction
  • VeChain's Approach to Transaction Uniqueness
  • Comparison to Ethereum
  • Conclusion

Was this helpful?

  1. Core Concepts
  2. Transactions
  3. Meta Transaction Features

Transaction Uniqueness

A unique transaction id for each transaction on the VeChainThor blockchain.

Introduction

Every blockchain must have a way to uniquely identify each transaction otherwise it would be vulnerable to a transaction replay attack. For an unspent transaction output (UTXO) based blockchain like Bitcoin, transactions are linked and can be uniquely identified and verified by the associated spending history. However, such uniqueness no longer holds for an account-based blockchain like VeChain. For account-based blockchains we need to inject additional information into transactions to make them uniquely identifiable.

VeChain's Approach to Transaction Uniqueness

In the VeChainThor blockchain every transaction has a unique transaction ID, TxIDTxIDTxID, which is calculated as:

TxID=hash(hash(rlp{Ω−sig})),signer_address)TxID = hash(hash(rlp\lbrace\Omega - sig \rbrace)), signer\_address)TxID=hash(hash(rlp{Ω−sig})),signer_address)

  • Ω\OmegaΩ - represents a set that contains all fields within the transaction body.

  • sigsigsig - refers to the signature field in the transaction body.

  • rlprlprlp - recursive length prefix (RLP) encoding function.

  • signer_addresssigner\_addresssigner_address - refers to the sender's address.

The first element that contributes to transaction uniqueness is the presence of the Nonce within the transaction body, which is denoted by Ω\OmegaΩ in the formula above. The transaction Nonce is a 64-bit unsigned integer that is determined by the transaction sender.

The second element that contributes to transaction uniqueness is the use of hash functions. A hash function is any function that can be used to convert data of any size to a fixed size. The VeChainThor blockchain uses the blake2b hash function for hashing transaction data. So given a single transaction two hashes are computed. The first hash is of the RLP of the encoded transaction data without the signature, denoted by hash(rlp{Ω−sig})hash(rlp\lbrace\Omega - sig \rbrace)hash(rlp{Ω−sig}). The second hash takes the output of the previous hash concatenated with the sender's account address, signer_addresssigner\_addresssigner_address. The result of this second hash function is 256-bits long and is used as the TxIDTxIDTxID which uniquely identifies the given transaction on the VeChainThor blockchain. Note that the calculation of the TxIDTxIDTxID does not require a private key to sign the transaction.

When validating a given transaction, VeChainThor computes the TxIDTxIDTxID and checks whether it has been used before. For any two transactions, so long as both transactions have a field in Ω−sig\Omega - sigΩ−sig with different values, their transaction IDs would be different. The first element that we introduced which contributes to transaction uniqueness, the Nonce, contributes to the transaction body, Ω\OmegaΩ, being different for each transaction.

Comparison to Ethereum

Ethereum's approach to transaction uniqueness is to add the AccountNonce field to each transaction and set a rule that a pending transaction can only be processed when its AccountNonce value equals the latest Nonce value of the account that sends the transaction. Where the Nonce value is the number of transactions the account has sent so far. So in Ethereum a transaction is uniquely identifiable by combining the AccountNonce and the sender's account address.

The major downside of this approach is the limitation it places on the sender. Within this design transactions sent from the same account are forced to adhere to a transaction order based on the Nonce value of the transaction. An account with multiple transactions will have only one transaction processed at a time, the transaction which has a Nonce value the same as the AccountNonce. All other transactions sent by this account will be in a pending state waiting until the transaction Nonce equals the AccountNonce. Additionally, when a user has multiple pending transactions within an account and wants to send a new transaction, the user runs the risk of having the new transaction stuck in the transaction pool if any of the pending transactions fail. Overall, this is a poor user experience with the user occasionally having to resubmit transactions and overwrite the transaction Nonce to "unblock" their account.

Conclusion

The Ethereum approach to transaction uniqueness has introduced a restriction on the Ethereum blockchain in the form of synchronous transaction processing, for transactions sent from a single account. The same restriction does not apply to the VeChainThor blockchain and transaction processing is asynchronous, for transactions sent from a single account.

PreviousMeta Transaction FeaturesNextControllable Transaction Lifecycle

Last updated 1 year ago

Was this helpful?

This provides additional information and a demonstration of transaction uniqueness on the VeChainThor blockchain.

article