Building on previous work where we explored using web3.js to query Ethereum (ETH) and ERC-20 token balances, this article dives into two critical aspects of blockchain application development: encapsulating transfer functions via Node.js APIs and optimizing transaction logic by validating user balances before execution. These enhancements ensure secure, efficient, and user-friendly interactions with the Ethereum network.
Whether you're developing a wallet service, exchange platform, or decentralized application (dApp), mastering these techniques is essential for reliable on-chain operations.
Creating Reusable Transfer Interfaces with Node.js
To make Ethereum functionality accessible across applications, we wrap core transfer operations into RESTful endpoints using Node.js and Koa/Express frameworks. This modular approach allows external systems—like front-end dashboards or mobile apps—to trigger transactions without directly handling low-level blockchain logic.
Below are fully functional API designs for both native ETH and ERC-20 token transfers.
ETH Transfer Endpoint
This endpoint enables the transfer of Ether between Ethereum addresses, with automatic validation of gas costs and sender balance.
API Specification
- Description: Transfer ETH from one address to another
- URL:
http://127.0.0.1:8084/eth/transfer - Method: GET
- Parameters:
| Parameter | Required | Type | Description |
|---|---|---|---|
| currentAccount | Yes | string | Sender's wallet address |
| to | Yes | string | Recipient's wallet address |
| amount | Yes | string | Amount in wei |
| privateKey | Yes | string | Private key of sender (hex format) |
| gasPrice | No | string | Gas price in Gwei (default: fetched dynamically) |
| gasLimit | No | string | Gas limit in Wei (default: 26000) |
Sample Response
{
"code": 10000,
"hash": "0x3aa7b47d69f38aa2e606c5b355c6c07e68d970cf5d891bbb6881011b5f2a4539",
"message": "ok"
}Key Features
- Automatically calculates required fees using
gasPrice × gasLimit - Validates that sender’s balance covers both transfer amount and maximum possible gas cost
- Returns error code
20001if insufficient funds
👉 Discover how to securely manage private keys and optimize transaction success rates
ERC-20 Token Transfer Endpoint
Transferring tokens requires interacting with smart contracts via encoded function calls. This endpoint simplifies that process.
API Specification
- Description: Transfer ERC-20 tokens between addresses
- URL:
http://127.0.0.1:8084/token/transfer - Method: GET
- Parameters:
| Parameter | Required | Type | Description |
|---|---|---|---|
| contractAddress | Yes | string | Token contract address |
| currentAccount | Yes | string | Sender's wallet address |
| to | Yes | string | Recipient's wallet address |
| amount | Yes | string | Token amount (must account for decimals) |
| privateKey | Yes | string | Sender's private key |
| gasPrice | No | string | Gas price in Gwei |
| gasLimit | No | string | Gas limit in Wei (default: 26000) |
Sample Response
{
"code": 10000,
"hash": "0xff4a1ccb26cd8c24796ed68075f11934a2561438a218463f31f897d5fb650e7c",
"message": "ok"
}Note: Unlike ETH transfers, token transfers only require ETH balance to cover gas fees—not the token amount itself. However, your dApp should separately verify token balance before initiating the transfer.
Optimizing Transaction Logic: Preventing Failed Transactions
One of the most common issues developers face is transaction failure due to miscalculated gas or insufficient funds. Let’s explore best practices for optimizing gas settings and pre-validating balances.
Dynamic Gas Pricing with web3.eth.getGasPrice()
Instead of forcing users to manually input gasPrice, we now make it optional:
if (!ctx.request.query.gasPrice) {
gasPrice = await web3.eth.getGasPrice();
} else {
gasPrice = web3.utils.toWei(ctx.request.query.gasPrice, 'gwei');
}The web3.eth.getGasPrice() method returns the median gas price from recent blocks, ensuring your transaction remains competitive without overpaying.
Optimal Default gasLimit Settings
Historically, a default gasLimit of 99,000 was used—but this often causes failures when account balances are low. Why?
Because Ethereum checks:
balance >= (gasLimit × gasPrice) + valueEven small transfers fail if (gasLimit × gasPrice) alone exceeds the balance.
After analyzing real-world usage (e.g., MetaMask, Trust Wallet), we set a more realistic default:
gasLimit = ctx.request.query.gasLimit || '26000';For simple ETH transfers or standard ERC-20 transfer() calls, 21,000–26,000 gas is sufficient.
👉 Learn how leading platforms optimize gas usage for faster, cheaper transactions
Pre-Transaction Balance Validation
Before broadcasting any transaction, always validate available funds.
For ETH Transfers:
const fees = gasLimit * gasPrice;
if (balance < (amount + fees)) {
return { code: 20001, message: 'Insufficient balance' };
}For Token Transfers:
Only gas fees need to be covered by ETH balance:
if (balance < fees) {
return { code: 20001, message: 'Insufficient ETH for gas' };
}Additionally, query the token contract to confirm sufficient token balance:
const tokenBalance = await contract.methods.balanceOf(currentAccount).call();
if (tokenBalance < amount) {
// Handle insufficient token balance
}Frequently Asked Questions (FAQ)
Q: Can I use POST instead of GET for security reasons?
A: Yes. While the example uses GET for simplicity, POST is strongly recommended in production to avoid exposing private keys in URLs or server logs.
Q: Is it safe to pass private keys via API parameters?
A: Only in secure, internal environments. For public-facing services, use encrypted key management systems or hardware wallets instead.
Q: How do I handle different token decimal places?
A: Use decimals() from the token contract. Convert human-readable amounts using web3.utils.toWei(amount, 'ether'), then multiply by 1e-decimals.
Q: What happens if a transaction runs out of gas?
A: The transaction fails, state changes are reverted, but gas fees are still deducted. Always ensure adequate gas limits and balance.
Q: Why does my transaction fail even with enough ETH?
A: Likely due to high gasLimit × gasPrice exceeding balance. Reduce gasLimit or wait for lower network congestion.
Q: How can I track transaction status after submission?
A: Use web3.eth.getTransactionReceipt(hash) polling or WebSocket event listeners to monitor confirmation status.
Core Keywords for SEO
- Ethereum development
- Node.js blockchain integration
- ETH transfer API
- ERC-20 token transfer
- Web3.js transaction optimization
- Gas limit best practices
- Smart contract interaction
- Balance validation in dApps
By implementing these patterns, you build robust, user-centric blockchain services that minimize errors and maximize reliability. Whether managing assets at scale or building the next-gen dApp, precision in transaction design is non-negotiable.
👉 Explore advanced tools to test and deploy your Ethereum APIs with confidence