Ethereum has emerged as one of the most powerful blockchain platforms for decentralized applications and token-based ecosystems. Understanding how transactions work—whether transferring Ether (ETH) or ERC-20 tokens—is essential for developers building on the network. This guide walks you through the core concepts of Ethereum transactions, including wallet structure, gas mechanics, and practical implementation using web3.js and Infura, while avoiding direct node management.
Core Concepts of Ethereum Transactions
At the heart of every Ethereum account are three critical components: mnemonic phrase, private key, and address. The mnemonic phrase is a human-readable representation of your private key, generated from a standardized 2048-word dictionary. It enables easy backup and recovery of wallets, while the private key (a 64-character hexadecimal string) is used to sign transactions cryptographically. These two can be interconverted using deterministic algorithms, meaning your mnemonic will always generate the same private key.
👉 Learn how to securely manage Ethereum transactions with trusted tools
Understanding Gas, Gas Price, and Transaction Fees
Ethereum operates like a global, decentralized computer powered by the Ethereum Virtual Machine (EVM). Every operation executed on this machine—such as sending ETH or interacting with smart contracts—consumes computational resources measured in gas.
- Gas Used (gasUsed): The total amount of gas consumed during a transaction.
- Gas Price (gasPrice): How much you're willing to pay per unit of gas, denominated in Gwei (1 Gwei = 1 billion Wei).
- Transaction Fee: Calculated as
fee = gasUsed × gasPrice.
You can set a gas limit to cap the maximum gas you’re willing to spend. If execution exceeds this limit, the transaction reverts, but the gas already spent is not refunded. However, if the transaction completes within the limit, only the actual gasUsed is charged.
Think of gas like fuel for a car: higher gas prices mean faster processing because miners prioritize profitable transactions. Unlike physical fuel, however, you don’t control market rates—you respond to network demand.
Example: A simple ETH transfer typically uses 21,000 gas. IfgasPriceis 13 Gwei, the fee is21,000 × 13 = 273,000 Gwei = 0.000273 ETH.
You can verify real-world examples using block explorers like Etherscan. For instance, analyzing a transaction with:
- Gas Used: 30,237
- Gas Price: 13 Gwei
Results in a fee of30,237 × 13 = 393,081 Gwei = 0.000393081 ETH, matching the recorded transaction cost.
Key Development Tools: Web3.js and Infura
To interact with Ethereum without running a full node, developers rely on two essential tools:
- web3.js: A JavaScript library for connecting and communicating with the Ethereum blockchain.
- Infura: A remote node provider offering scalable API access to Ethereum networks (mainnet and testnets).
These tools allow you to send transactions, query balances, and interact with smart contracts seamlessly.
👉 Start building on Ethereum with reliable infrastructure
Implementing ETH and ERC-20 Token Transfers
Setting Up Dependencies
Begin by installing required packages:
npm install bip39 eth-json-rpc-infura ethereumjs-wallet [email protected]Note: Using specific versions ensures compatibility due to breaking changes in newer releases.
Connecting to Ethereum via Infura
Create a provider file (provider.js) to connect to Ethereum mainnet through Infura:
const createInfuraProvider = require('eth-json-rpc-infura/src/createProvider');
const provider = { send: createInfuraProvider().sendAsync };
module.exports = provider;Initialize web3 in client.js:
const Web3 = require('web3');
const Transaction = require('ethereumjs-tx');
const provider = require('./provider');
const contractABI = require('./erc20-abi.json');
const web3 = new Web3(provider);Deriving Wallets from Mnemonic Phrases
Use BIP39 and HD Wallet standards to generate addresses from a mnemonic:
const bip39 = require('bip39');
const hdkey = require('ethereumjs-wallet/hdkey');
function generateAddressesFromSeed(seed, count = 2) {
const hdwallet = hdkey.fromMasterSeed(bip39.mnemonicToSeedSync(seed));
const path = "m/44'/60'/0'/0/";
const accounts = [];
for (let i = 0; i < count; i++) {
const wallet = hdwallet.derivePath(path + i).getWallet();
const address = '0x' + wallet.getAddress().toString('hex');
const privateKey = wallet.getPrivateKey().toString('hex');
accounts.push({ address, privateKey });
}
return accounts;
}
const accounts = generateAddressesFromSeed('your mnemonic phrase here');
const myAddress = accounts[0].address;
const privateKey = Buffer.from(accounts[0].privateKey, 'hex');Sending Ether (ETH)
const toAddress = '0xReceiverAddress';
const amount = web3.utils.toHex(web3.utils.toWei('1', 'ether'));
web3.eth.getTransactionCount(myAddress)
.then(nonce => {
const txParams = {
from: myAddress,
to: toAddress,
value: amount,
gasPrice: web3.utils.toHex(1 * 1e9), // 1 Gwei
gasLimit: web3.utils.toHex(21000),
nonce: web3.utils.toHex(nonce)
};
const tx = new Transaction(txParams);
tx.sign(privateKey);
web3.eth.sendSignedTransaction('0x' + tx.serialize().toString('hex'))
.on('transactionHash', console.log);
});Transferring ERC-20 Tokens
ERC-20 tokens require interaction with their contract. You must encode the transfer function call into the data field.
const contractAddress = '0xTokenContractAddress';
const contract = new web3.eth.Contract(contractABI, contractAddress);
contract.methods.decimals().call()
.then(decimals => {
const amount = web3.utils.toHex(web3.utils.toWei('1', 'ether')); // Adjust based on token decimals
return web3.eth.getTransactionCount(myAddress).then(nonce => {
const txParams = {
from: myAddress,
to: contractAddress,
value: '0x0',
gasPrice: web3.utils.toHex(1 * 1e9),
gasLimit: web3.utils.toHex(100000),
nonce: web3.utils.toHex(nonce),
data: contract.methods.transfer(toAddress, amount).encodeABI()
};
const tx = new Transaction(txParams);
tx.sign(privateKey);
return web3.eth.sendSignedTransaction('0x' + tx.serialize().toString('hex'))
.on('transactionHash', console.log);
});
});Estimating Gas and Exchange Rates
Dynamic Gas Price Estimation
Use public APIs to fetch current gas recommendations:
- EthGasStation API: Provides fast, average, and low-priority gas prices in Gwei.
- Etherchain Oracle: Offers real-time
gasPriceOracle. - web3.eth.getGasPrice(): Returns current average price in Wei.
Example using EthGasStation:
fetch('https://ethgasstation.info/json/ethgasAPI.json')
.then(res => res.json())
.then(data => {
const safeLowGwei = data.safeLow / 10; // Convert to actual Gwei
console.log(`Safe low gas price: ${safeLowGwei} Gwei`);
});Fetching Real-Time ETH-to-Fiat Rates
Use Infura’s ticker API:
fetch('https://api.infura.io/v1/ticker/ethusd')
.then(res => res.json())
.then(data => {
const ethToUsd = data.bid; // Buy-side rate
console.log(`Current ETH/USD rate: $${ethToUsd}`);
});Frequently Asked Questions
Q: What is the difference between ETH and ERC-20 tokens?
A: ETH is the native cryptocurrency of Ethereum, used to pay for transaction fees. ERC-20 tokens are smart contracts that represent assets or utilities built on top of Ethereum.
Q: Why does my transaction remain pending?
A: Low gasPrice may cause delays. Miners prioritize higher-paying transactions. You can speed it up by resubmitting with a higher gas price and same nonce.
Q: Can I recover funds if I send them to the wrong address?
A: No. Blockchain transactions are irreversible. Always double-check recipient addresses before confirming.
Q: How do I know how much gas a transaction will use?
A: Use web3.eth.estimateGas() before signing. Note: estimation fails if conditions aren’t met (e.g., insufficient balance).
Q: Is it safe to use Infura in production?
A: Yes, but consider redundancy. For mission-critical apps, combine with fallback providers or run your own node.
Q: What happens if I exceed the gas limit?
A: The transaction fails and consumes all gas allocated. However, state changes are reverted—nothing is permanently altered.
By mastering these fundamentals—wallet derivation, gas mechanics, and secure transaction signing—you’re well-equipped to build robust applications on Ethereum. Always test on testnets first and keep private keys secure.