Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Guides

How to Submit Transactions to Networks

A step-by-step guide for developers on constructing, signing, and broadcasting transactions to EVM and Solana networks using popular libraries and RPC providers.
Chainscore © 2026
introduction
INTRODUCTION

How to Submit Transactions to Networks

A technical overview of the transaction lifecycle, from creation to on-chain confirmation.

A blockchain transaction is a signed data package that instructs a network to execute a state change, such as transferring native tokens or interacting with a smart contract. This process is fundamental to all blockchain operations. The lifecycle involves constructing a transaction object with key fields: a nonce to ensure order, a gasLimit to cap computational work, a gasPrice or maxFeePerGas to pay validators, a to address for the recipient (or a zero-address for contract creation), a value for native token transfers, and data for contract calls or arbitrary messages. Tools like Ethers.js, web3.js, and viem provide libraries to construct these objects programmatically.

Before submission, the transaction must be cryptographically signed with the sender's private key. This signature proves ownership of the funds or contract and ensures the transaction cannot be altered. The signing process generates three new fields appended to the transaction: v, r, and s. Once signed, the raw transaction is a serialized, hex-encoded string ready for broadcast. Developers can sign transactions offline using a wallet's SDK or a backend service, a critical practice for security in applications like relayers or gasless meta-transactions.

To submit the signed transaction, you broadcast it to the network's peer-to-peer (P2P) mempool. This is typically done by sending the raw transaction data to a node or a node provider service like Alchemy, Infura, or a public RPC endpoint using the eth_sendRawTransaction JSON-RPC method. Nodes validate the signature and basic rules before propagating it. Transactions then sit in the mempool, a waiting area where validators (miners or sequencers) select them for inclusion in the next block based on factors like gas price.

Network congestion and fee markets directly impact transaction confirmation. In networks like Ethereum, users specify a maxPriorityFeePerGas (tip) and maxFeePerGas (max total fee) to bid for block space. During high traffic, transactions with lower fees may stall. Strategies to manage this include fee estimation using the eth_feeHistory API, implementing transaction replacement (bumping the fee on a stuck tx), or using private transaction pools like Flashbots to avoid frontrunning. Layer 2 networks often have different fee structures and faster confirmation times.

After a validator includes your transaction in a block, it undergoes execution and consensus. You can track its status by querying the transaction hash with eth_getTransactionReceipt. A successful receipt will have a status of 1 and contain logs from any smart contract interactions. A failed transaction (status 0) typically results from an error during execution, like a revert in a smart contract or insufficient gas, though the gas fee is still consumed. For critical applications, always implement error handling and receipt verification in your code.

prerequisites
PREREQUISITES

How to Submit Transactions to Networks

Before you can interact with a blockchain, you need to understand the fundamental components required to construct, sign, and broadcast a transaction.

Submitting a transaction requires a wallet with a private key and a connection to a node. The wallet, such as MetaMask or a programmatic library like ethers.js or web3.js, is responsible for creating the transaction object and signing it cryptographically with your private key. This signature proves you own the assets you're trying to move. You cannot submit a transaction without access to a node, which is your gateway to the blockchain network. Nodes can be public RPC endpoints (like Infura, Alchemy, or public ones from chainlist.org) or your own locally run node software like Geth or Erigon.

Every transaction must specify critical parameters that the network needs to process it. The core fields include the to address (the recipient), the value (amount of native token to send, in wei for Ethereum), and data (for contract interactions). You must also define the transaction's resource limits: gasLimit sets the maximum computational work units, and gasPrice (or maxFeePerGas/maxPriorityFeePerGas for EIP-1559) determines the fee you pay per unit. An incorrect gasLimit can cause the transaction to fail, while a low fee may result in it being stuck.

Once constructed, the transaction must be signed offline. Signing uses your private key to generate a unique cryptographic signature without exposing the key itself. This process creates the final raw transaction payload. For Ethereum, this includes the v, r, s signature values. Libraries handle this seamlessly: await wallet.sendTransaction(tx) in ethers.js or web3.eth.sendTransaction(tx) in web3.js. It is a security best practice to never expose your private key or mnemonic phrase to any application or website.

The signed transaction is then broadcast to the network via a node's RPC method, typically eth_sendRawTransaction. The node validates the signature and basic format before propagating it to peers. The transaction enters the mempool (memory pool), a waiting area where validators or miners select transactions to include in the next block based on fee priority. You will receive a transaction hash (txid) immediately upon broadcast, which you can use to track its status on a block explorer like Etherscan.

Transaction finality is not immediate. You must wait for block confirmations. A transaction with 1 confirmation is included in a block, but it could still be part of a discarded chain reorganization. For high-value transfers, waiting for multiple confirmations (e.g., 12 for Ethereum) is standard. Always check the status using your txid. A failed transaction (e.g., due to insufficient gas or a reverted smart contract call) will still incur gas fees, so it's crucial to estimate gas and simulate calls using eth_estimateGas or eth_call before broadcasting.

transaction-anatomy
BLOCKCHAIN FUNDAMENTALS

Transaction Anatomy

A transaction is the fundamental unit of execution on a blockchain. This guide explains its core components and the process of submitting one to a network.

A blockchain transaction is a signed data packet that instructs the network to execute a state change. At its core, every transaction contains a set of standard fields: a nonce (a unique sequence number for the sender's account), a gas limit, a gas price (or maxFeePerGas/maxPriorityFeePerGas for EIP-1559), a recipient to address, a value in native tokens, optional data for contract calls, and a cryptographic signature (v, r, s). This structure ensures transactions are ordered, paid for, and authenticated before execution.

The transaction lifecycle begins when a user's wallet constructs and signs the transaction object. The signed transaction is then broadcast to the network's peer-to-peer (P2P) layer. Nodes in the network, including validators or miners, receive this transaction and perform initial checks. These checks verify the signature's validity, ensure the sender's account has sufficient balance to cover the value and gas fees, and confirm the nonce is correct to prevent replay attacks.

Once validated, the transaction enters the mempool (memory pool), a waiting area for pending transactions. Here, network participants select transactions based on factors like gas price to include in the next block. For example, an Ethereum validator building a block will prioritize transactions with higher maxPriorityFeePerGas. This creates a fee market where users can pay more for faster inclusion.

When a validator proposes a new block, they bundle transactions from the mempool, execute them in order, and update the global state. Each transaction's execution consumes gas, a unit of computational work. If a transaction runs out of gas before completion, it reverts all state changes, but the gas fee is still paid to the validator. This prevents infinite loops and spam.

To submit a transaction programmatically, you typically use a library like ethers.js or web3.js. The process involves connecting to a node provider (e.g., Alchemy, Infura, or a local node), constructing the transaction object, signing it with a private key, and sending it. Below is a basic example using ethers v6:

javascript
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('RPC_URL');
const wallet = new ethers.Wallet('PRIVATE_KEY', provider);

const tx = await wallet.sendTransaction({
  to: '0xRecipientAddress',
  value: ethers.parseEther('0.1'),
  gasLimit: 21000,
});

console.log(`Transaction hash: ${tx.hash}`);
await tx.wait(); // Waits for block confirmation

After submission, monitor the transaction via its hash, a unique identifier. Use a block explorer like Etherscan or Solana Explorer to track its status (pending, confirmed, failed). Understanding this anatomy—from construction and signing to gas, mempool dynamics, and execution—is essential for debugging failed transactions and optimizing for cost and speed in applications.

METHODOLOGY

RPC Method Comparison: eth_sendTransaction vs eth_sendRawTransaction

A direct comparison of the two primary Ethereum JSON-RPC methods for submitting transactions, detailing their security, dependencies, and typical use cases.

Feature / Metriceth_sendTransactioneth_sendRawTransaction

Method Signature

eth_sendTransaction(transactionObject)

eth_sendRawTransaction(signedTransactionData)

Key Dependency

Node-managed private key

Externally signed transaction

Signing Location

Client node (e.g., Geth, Erigon)

External client (wallet, dApp, SDK)

Security Model

Gas Price Handling

Node can estimate/apply default

Must be specified in signed data

Nonce Management

Node can provide/pending count

Must be specified in signed data

Typical Use Case

Local development, trusted nodes

Production dApps, wallets, batch sends

Common Providers

Localhost, private nodes

All public RPCs (Alchemy, Infura, Chainscore)

gas-and-fee-strategy
GAS AND FEE STRATEGY

How to Submit Transactions to Networks

A guide to transaction lifecycle, fee estimation, and submission strategies for Ethereum and EVM-compatible networks.

Submitting a transaction to a blockchain network involves constructing, signing, and broadcasting a data packet that instructs the network to execute a specific operation, such as transferring tokens or interacting with a smart contract. Every transaction requires a fee, paid in the network's native token (e.g., ETH, MATIC), to compensate validators for the computational resources and block space consumed. This fee is calculated as Gas Units * Gas Price. The gas limit is the maximum computational work you authorize, while the gas price (or priority fee + base fee on EIP-1559 networks) determines how quickly miners or validators will prioritize your transaction.

On networks like Ethereum that use EIP-1559, the fee structure has two main components: a base fee that is burned and adjusts per block based on network congestion, and a priority fee (tip) paid directly to the validator to incentivize inclusion. To submit a transaction, you must first estimate the required gas. Tools like eth_estimateGas RPC calls or libraries such as Ethers.js (provider.estimateGas(tx)) can provide an estimate, but it's a best practice to add a buffer (e.g., 10-20%) to the estimate to avoid an out-of-gas error, which results in a failed transaction and lost fees.

A robust submission strategy involves monitoring the mempool—the pool of pending transactions—and current network conditions. Services like Etherscan's Gas Tracker or the eth_gasPrice RPC method provide real-time data on standard, fast, and rapid gas price tiers. For time-sensitive transactions, you can implement a gas price oracle or use a dynamic fee calculation from your provider. In Ethers v6, you can fetch a fee data object with provider.getFeeData() which returns the current maxFeePerGas and maxPriorityFeePerGas for EIP-1559 transactions.

Here is a basic example of submitting a transaction using Ethers.js, incorporating dynamic fee fetching and gas estimation:

javascript
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('RPC_URL');
const wallet = new ethers.Wallet('PRIVATE_KEY', provider);

async function sendTransaction(to, value) {
  const feeData = await provider.getFeeData();
  const gasEstimate = await provider.estimateGas({
    from: wallet.address,
    to: to,
    value: value
  });

  const tx = await wallet.sendTransaction({
    to: to,
    value: value,
    gasLimit: gasEstimate * 120n / 100n, // 20% buffer
    maxFeePerGas: feeData.maxFeePerGas,
    maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
  });

  console.log(`Transaction hash: ${tx.hash}`);
  await tx.wait(); // Wait for confirmation
  console.log('Transaction confirmed.');
}

After broadcasting, your transaction enters the mempool. You should monitor its status using the returned transaction hash via RPC calls like eth_getTransactionReceipt. A receipt with a status of 1 indicates success, while 0 indicates failure. For critical operations, consider implementing transaction replacement (bumping the gas price) if it's stuck, or setting a timeout to resubmit. Always validate that the nonce used is correct to prevent nonce gaps or conflicts. Using a wallet that manages nonces automatically, or querying the next nonce with provider.getTransactionCount(wallet.address, 'pending'), is essential for managing multiple transactions from the same address.

tools-and-libraries
TRANSACTION SUBMISSION

Tools and Libraries

Essential libraries and tools for constructing, signing, and broadcasting transactions across different blockchain networks.

best-practices
PRODUCTION READY

How to Submit Transactions to Networks

Submitting transactions reliably is a core requirement for any production Web3 application. This guide covers the essential practices for handling transaction lifecycle, error management, and user experience.

A production-ready transaction flow begins before the user signs. Gas estimation is critical: always use eth_estimateGas to simulate the transaction first. This catches revert errors and provides a baseline gas limit. For the gas price, implement a dynamic strategy. Use eth_gasPrice for a base estimate, but consider services like the EIP-1559 Fee Market for mainnet Ethereum, where you should monitor maxPriorityFeePerGas and maxFeePerGas from a reliable provider like Blocknative's Gas Platform or the chain's public RPC.

Once the transaction is signed and broadcast, you must handle the pending state. Immediately capture the transaction hash (txid) and store it in your application's state. Do not rely solely on the user's browser memory. Implement a robust transaction monitoring loop that polls the network using eth_getTransactionReceipt. A receipt with a status (0 for failure, 1 for success) confirms the transaction. Consider edge cases: a transaction may be dropped from the mempool. Set a timeout (e.g., 5 minutes for Ethereum) and, if no receipt is found, check the node's mempool via eth_getTransactionByHash to see if it's still pending.

User experience depends on clear feedback. Provide real-time updates: PendingConfirmedSuccess/Failed. For failures, parse the revert reason if possible. When using Ethers.js, you can catch the error and check error.reason or error.data. For web3.py, inspect the TransactionReceipt's revertReason. Log all transaction outcomes—successes and failures—with their hashes and block numbers for auditing and debugging. This data is invaluable for diagnosing issues with specific smart contract functions or network conditions.

Advanced scenarios require specific handling. For batch transactions, ensure each subsequent TX depends on the confirmation of the previous one to avoid nonce errors. Use private transactions (e.g., via Flashbots Protect RPC) for front-running protection on Ethereum when submitting sensitive trades. For high-frequency applications, manage nonces locally to avoid conflicts, fetching the initial count with eth_getTransactionCount and incrementing it manually, rather than relying on the provider's pending nonce which can be unreliable under load.

Finally, plan for network resilience. Your application should support fallback RPC endpoints. If a primary node fails or is rate-limited, seamlessly switch to a secondary provider like Alchemy, Infura, or a decentralized service like Pocket Network. Implement exponential backoff in your polling logic to avoid being rate-limited. By combining accurate gas estimation, diligent monitoring, clear user feedback, and resilient infrastructure, you can build a transaction submission system that is reliable enough for production workloads.