Web3.js: Mastering the eth Package for Ethereum Interaction

·

The web3-eth package is a cornerstone of the web3.js library, empowering developers to seamlessly interact with the Ethereum blockchain and smart contracts. Whether you're deploying contracts, sending transactions, or querying blockchain data, understanding how to use this package effectively is essential for any Web3 developer. In this comprehensive guide, we’ll walk through setting up your development environment, connecting to Ethereum networks, sending different types of transactions, and leveraging advanced features—all using web3.js v4 with TypeScript.


Setting Up Your Development Environment

Before diving into blockchain interactions, you need a proper development setup. This ensures you can test your code locally without risking real funds.

Required Tools

  1. Ganache – A personal Ethereum blockchain for local development. It simulates a full Ethereum network on your machine, complete with pre-funded accounts.
  2. Node.js – The JavaScript runtime that powers server-side execution and package management.
  3. npm or yarn – Package managers used to install dependencies like web3.js.

👉 Get started with Ethereum development tools and environments today.

Once installed, create a new project directory:

mkdir smart-contract-tutorial
cd smart-contract-tutorial
npm init -y

Install essential packages:

npm install web3 typescript @types/node

Initialize TypeScript:

npx tsc --init

Now you're ready to start coding.


Connecting to Ethereum with web3-eth

To interact with Ethereum, instantiate the Web3 object and connect it to a provider—either a local node like Ganache or a remote service like Infura.

Create a file named index.ts:

import { Web3 } from 'web3';

// Connect to Ganache (default URL)
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:7545'));

async function getBlockNumber() {
  const blockNumber = await web3.eth.getBlockNumber();
  console.log('Latest block number:', blockNumber);
}

getBlockNumber();

Run it using:

npx ts-node index.ts

If successful, you'll see the current block number. If you encounter ECONNREFUSED, ensure Ganache is running on port 7545.

Note: You can also connect to public testnets or mainnet via services like Infura or Alchemy, or use community-driven lists like Chainlist.

Sending Transactions on Ethereum

One of the most common operations is transferring ETH between accounts.

Basic ETH Transfer

Here’s how to send 1 ETH from one Ganache account to another:

import { Web3 } from 'web3';

const web3 = new Web3('http://localhost:7545');

async function sendTransaction() {
  const accounts = await web3.eth.getAccounts();
  const [from, to] = accounts;

  const balanceBefore = await web3.eth.getBalance(to);
  console.log('Balance before:', balanceBefore.toString());

  const tx = await web3.eth.sendTransaction({
    from,
    to,
    value: web3.utils.toWei('1', 'ether'),
  });

  const balanceAfter = await web3.eth.getBalance(to);
  console.log('Balance after:', balanceAfter.toString());
  console.log('Transaction hash:', tx.transactionHash);
}

sendTransaction();

Ganache automatically unlocks all accounts, so no private keys are needed during development.


Estimating Gas Usage Before Deployment

To avoid failed transactions due to insufficient gas, always estimate gas usage beforehand.

import { Web3, ETH_DATA_FORMAT } from 'web3';

const web3 = new Web3('http://localhost:7545');
const abi = [/* your contract ABI */];
const bytecode = '0x...'; // Your compiled bytecode

const contract = new web3.eth.Contract(abi);

const deployment = contract.deploy({
  data: bytecode,
  arguments: [42],
});

async function estimateDeploymentGas() {
  const gas = await deployment.estimateGas({ from: (await web3.eth.getAccounts())[0] });
  console.log('Estimated gas (bigint):', gas);

  const hexGas = await deployment.estimateGas(
    { from: (await web3.eth.getAccounts())[0] },
    ETH_DATA_FORMAT
  );
  console.log('Estimated gas (hex):', hexGas);
}

estimateDeploymentGas();

This helps optimize costs before deploying to live networks.


Signing and Sending Raw Transactions

For enhanced security or custom workflows, sign transactions offline and broadcast them.

import { Web3 } from 'web3';

const web3 = new Web3('http://localhost:7545');
const privateKey = '0x...'; // From Ganache UI

async function sendSignedTx() {
  const account = web3.eth.accounts.privateKeyToAccount(privateKey);
  const tx = {
    from: account.address,
    to: (await web3.eth.getAccounts())[1],
    value: web3.utils.toWei('1', 'ether'),
    gas: 21000,
    gasPrice: await web3.eth.getGasPrice(),
    nonce: await web3.eth.getTransactionCount(account.address),
  };

  const signed = await account.signTransaction(tx);
  const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction!);
  console.log('Transaction confirmed in block:', receipt.blockNumber);
}

sendSignedTx();

Use this method when handling sensitive keys or integrating with hardware wallets.


Direct Import of web3-eth for Smaller Builds

Instead of importing the full web3 library, import only web3-eth to reduce bundle size in production apps.

import { Web3Eth } from 'web3-eth';

const eth = new Web3Eth('http://localhost:7545');

async function getBalance() {
  const accounts = await eth.getAccounts();
  const balance = await eth.getBalance(accounts[0]);
  console.log('Account balance:', balance.toString());
}

getBalance();

You can also configure default settings like transaction type:

eth.setConfig({ defaultTransactionType: '0x1' });

Sending Different Types of Ethereum Transactions

Ethereum supports multiple transaction types for flexibility and efficiency.

Legacy Transactions (Type 0)

These are traditional transactions where gas price is manually set.

const txLegacy = {
  from: account.address,
  to: '0x...',
  value: '0x1',
  gas: 21000,
  gasPrice: await web3.eth.getGasPrice(),
  type: 0 as const,
};

Access List Transactions (EIP-2930, Type 1)

Improves gas efficiency by specifying which addresses/storage slots will be accessed.

const accessListTx = {
  from: account.address,
  to: deployedContract.options.address,
  data: '0xcfae3217',
  type: 1 as const,
  accessList: [
    {
      address: '0xce1f86f87bd3b8f32f0fb432f88e848f3a957ed7',
      storageKeys: ['0x0...001'],
    },
  ],
};

👉 Explore how modern transaction types improve scalability and reduce fees.

Dynamic Fee Transactions (EIP-1559, Type 2)

The modern standard offering predictable fees and fee burning.

const eip1559Tx = {
  from: account.address,
  to: '0x...',
  value: '0x1',
  gasLimit: 21000,
  type: 2 as const,
  maxFeePerGas: await web3.eth.getGasPrice(),
  maxPriorityFeePerGas: web3.utils.toWei('2', 'gwei'),
};

EIP-1559 improves user experience by eliminating guesswork in gas pricing.


Frequently Asked Questions (FAQ)

What is the web3-eth package used for?

The web3-eth package enables direct interaction with the Ethereum blockchain—sending transactions, reading block data, deploying contracts, and querying account balances.

Can I use web3-eth without installing the full web3.js library?

Yes. You can install and import only web3-eth to reduce application bundle size while retaining core Ethereum functionality.

How do I choose between legacy and EIP-1559 transactions?

Use EIP-1559 (type 2) whenever possible—it offers better fee predictability and user experience. Legacy transactions are still supported but less efficient.

Why should I estimate gas before sending a transaction?

Estimating gas prevents out-of-gas errors and failed transactions. It also helps optimize costs, especially for complex contract interactions.

Is it safe to expose private keys in code?

Never hardcode private keys in production. Use environment variables or secure key management systems like hardware wallets or vaults.

Can I connect web3-eth to networks other than Ethereum?

While designed for Ethereum, web3-eth works with any EVM-compatible chain like BSC, Polygon, Arbitrum, or Optimism by changing the provider URL.


Best Practices & Tips


Conclusion

The web3-eth package provides powerful, flexible tools for interacting with Ethereum and EVM-based blockchains. From simple ETH transfers to deploying complex smart contracts using EIP-1559 transactions, mastering this library is crucial for modern Web3 development.

With TypeScript support built-in and modular architecture for optimized builds, web3.js v4 sets a new standard for developer experience. As Ethereum evolves, staying current with transaction standards and best practices ensures your applications remain secure, efficient, and future-ready.

👉 Start building scalable dApps with cutting-edge Web3 tools and infrastructure.