How transactions work

How transactions work on the SparqNet protocol
Transactions on SparqNet are abstracted by the Tx class in utils/transaction. The implementation logic and details are derived from the "Account" model, used by Ethereum and implemented mainly by the Aleth library, unlike the "UTXO" model used by Bitcoin and its derivatives.

How transactions are parsed

There are two ways a transaction can be parsed from a bytes string:
  • Directly from Recursive Length Prefix (RLP) – a data encoding method used by Ethereum. Please note that:
  • RLP requires deriving the "from" account and a validity check using Secp256k1
  • The transaction isn’t included in a block, which means it's a new transaction coming from the network
  • This method is equivalent to Ethereum's "rawTransaction"
  • Directly from the database. Please note that:
  • The transaction is considered trustworthy since it already went through the process above
  • The transaction is included in a block, therefore it's part of the blockchain

Transaction structure

Depending on the origin of the transaction, it'll contain data that comes from RLP, the DB, or is created independently.

RLP Data

This data is decoded from the RLP structure and/or generated by Secp256k1 at the point of building the transaction and includes the following elements:
  • to - address that will receive funds.
  • value - transaction value in its lowest unit, e.g. "satoshi", "wei", etc. - "100000000" satoshis would be 1.0 BTC, "5000000000" wei would be 0.000000005 ETH (or 5 gwei).
  • data - arbitrary data field, generally used in contracts.
  • chainId - unique blockchain ID where the transaction is made, e.g. "43114" = Avalanche C-Chain, "43113" = Avalanche Fuji Testnet.
  • nonce - number of the transaction made under the "from" account (starts at 0). It always starts at 0, so a nonce of "4" means this would be the fifth transaction made by the given address
  • gas (aka "Gas Limit") - maximum gas units that the transaction will use, in Wei (e.g. "21000"). If the transaction uses more than this limit, it will automatically fail. The original transaction value won't be spent, but what was already spent as gas is lost.
  • gasPrice - value paid by every unit of gas, in Gwei (e.g. "15" = 15000000000 Wei). The total transaction fee is calculated as (gas * gasPrice), e.g. 21000 * 15000000000 = 0.000315 ETH
  • Elliptic Curve Digital Signature Algorithm (ECDSA) signature for validating transaction integrity, split in three:
    • v - recovery ID (1 hex byte)
    • r - first half of the ECDSA signature (32 hex bytes)
    • s - second half of the ECDSA signature (32 hex bytes)

DB/Independent Data

This data is created outside the RLP structure, generally coming from the DB or created independently, and it includes:
  • blockIndex - transaction position index inside the block, starting with 0 (e.g. "4" means it's the fifth transaction in the block)
  • from - address that will send the funds
  • callsContract - indicates whether the transaction calls an external contract or not.
  • hasSig - shows if the transaction has an ECDSA signature or not. This part isn’t stored in the database and it’s only used during transaction creation.
  • inBlock - indicates if the transaction is included in a block or not. Needs at least one confirmation in the network
  • verified – shows whether the transaction is verified or not.
blockIndex and inBlock are set in State::processNewBlock and State::processNewTransaction, respectively.