About us Guides Projects Contacts
Админка
please wait

Ethereum enables decentralized applications (dApps) through smart contracts and a programmable blockchain. Web3.js provides the JavaScript interface for interacting with Ethereum nodes. This guide covers building blockchain applications from a senior developer's perspective.

Why Ethereum Development

Ethereum offers unique capabilities:

  1. Smart Contracts: Self-executing code on the blockchain
  2. Decentralization: No single point of failure or control
  3. Transparency: All transactions are publicly verifiable
  4. Programmable Money: Build financial applications without intermediaries
  5. NFTs and Tokens: Create digital assets

Development Environment Setup

Install Dependencies

# Node.js environment
npm init -y
npm install web3 ethers dotenv

Infrastructure Providers

Use providers like Infura or Alchemy instead of running your own node:

// .env
INFURA_API_KEY=your_api_key_here
PRIVATE_KEY_1=your_private_key_here
PRIVATE_KEY_2=second_private_key_here

Local Development with Ganache

Ganache provides a local Ethereum blockchain for testing:

# Install Ganache CLI
npm install -g ganache
# Start local blockchain
ganache --port 8545

Web3.js Basics

Connect to Network

import { Web3 } from 'web3';
import 'dotenv/config';
// Development vs. production
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2", // EIP-1559 transactions
},
});
// Check connection
const blockNumber = await web3.eth.getBlockNumber();
console.log('Current block:', blockNumber);

Account Management

// Create a new account
const newAccount = web3.eth.accounts.create();
console.log('Address:', newAccount.address);
console.log('Private Key:', newAccount.privateKey);
// Load an existing account from a private key
const account = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
console.log('Loaded address:', account.address);
// Get balance
const balance = await web3.eth.getBalance(account.address);
console.log('Balance:', web3.utils.fromWei(balance, 'ether'), 'ETH');

Making Transactions

Send ETH

import { Web3 } from 'web3';
const isProduction = false;
const web3 = new Web3({
provider: `https://${!isProduction ? 'sepolia' : 'mainnet'}.infura.io/v3/${process.env.INFURA_API_KEY}`,
config: {
defaultTransactionType: "0x2",
},
});
// Initialize accounts
const sender = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
const receiver = web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_2);
async function sendTransaction() {
// Log account links for verification
console.log(`Sender: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${sender.address}`);
console.log(`Receiver: https://${isProduction ? '' : 'sepolia.'}etherscan.io/address/${receiver.address}`);
// Check balance
const balance = await web3.eth.getBalance(sender.address);
console.log(`Sender balance: ${web3.utils.fromWei(balance, 'ether')} ETH`);
// Get transaction count (nonce)
const txCount = await web3.eth.getTransactionCount(sender.address);
// Build transaction
const txObject = {
nonce: web3.utils.toHex(txCount),
to: receiver.address,
value: web3.utils.toWei('0.001', 'ether'),
maxPriorityFeePerGas: 10_000,
maxFeePerGas: 10_000_000_000, // Maximum transaction cost allowed
};
// Sign transaction
const signedTx = await sender.signTransaction(txObject);
// Send transaction
console.log(`TX: https://${isProduction ? '' : 'sepolia.'}etherscan.io/tx/${signedTx.transactionHash}`);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
console.log('Transaction confirmed in block:', receipt.blockNumber);
// Check new balance
const newBalance = await web3.eth.getBalance(receiver.address);
console.log(`Receiver balance: ${web3.utils.fromWei(newBalance, 'ether')} ETH`);
}
sendTransaction();

Smart Contract Interaction

Compile Smart Contract

Using the Solidity compiler:

npm install solc

Simple contract SimpleStorage.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleStorage {
uint256 private storedValue;
event ValueChanged(uint256 newValue);
function set(uint256 value) public {
storedValue = value;
emit ValueChanged(value);
}
function get() public view returns (uint256) {
return storedValue;
}
}

Deploy Contract

import { Web3 } from 'web3';
import fs from 'fs';
import solc from 'solc';
const web3 = new Web3('http://localhost:8545'); // Ganache
// Compile contract
const source = fs.readFileSync('SimpleStorage.sol', 'utf8');
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': { content: source },
},
settings: {
outputSelection: {
'*': { '*': ['abi', 'evm.bytecode'] },
},
},
};
const compiled = JSON.parse(solc.compile(JSON.stringify(input)));
const contract = compiled.contracts['SimpleStorage.sol']['SimpleStorage'];
const abi = contract.abi;
const bytecode = contract.evm.bytecode.object;
async function deploy() {
const accounts = await web3.eth.getAccounts();
const SimpleStorage = new web3.eth.Contract(abi);
const deployed = await SimpleStorage
.deploy({ data: bytecode })
.send({
from: accounts[0],
gas: 1500000,
});
console.log('Contract deployed at:', deployed.options.address);
return deployed.options.address;
}
deploy();

Interact with Contract

const contractAddress = '0x...'; // Deployed address
const contract = new web3.eth.Contract(abi, contractAddress);
// Read value (free, no gas)
async function getValue() {
const value = await contract.methods.get().call();
console.log('Stored value:', value);
}
// Write value (costs gas)
async function setValue(newValue) {
const accounts = await web3.eth.getAccounts();
const receipt = await contract.methods
.set(newValue)
.send({
from: accounts[0],
gas: 100000,
});
console.log('Transaction hash:', receipt.transactionHash);
}
// Listen for events
contract.events.ValueChanged({
fromBlock: 'latest',
})
.on('data', (event) => {
console.log('Value changed to:', event.returnValues.newValue);
})
.on('error', console.error);

Using Ethers.js Alternative

Ethers.js is another popular library with a cleaner API:

import { ethers } from 'ethers';
// Connect to provider
const provider = new ethers.JsonRpcProvider(
`https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`
);
// Create wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Send transaction
async function sendEther() {
const tx = await wallet.sendTransaction({
to: '0xRecipientAddress',
value: ethers.parseEther('0.01'),
});
console.log('TX Hash:', tx.hash);
const receipt = await tx.wait();
console.log('Confirmed in block:', receipt.blockNumber);
}
// Contract interaction
const contract = new ethers.Contract(contractAddress, abi, wallet);
await contract.set(42);
const value = await contract.get();

ERC-20 Token Interaction

const tokenABI = [
'function balanceOf(address owner) view returns (uint256)',
'function transfer(address to, uint256 amount) returns (bool)',
'function decimals() view returns (uint8)',
'function symbol() view returns (string)',
];
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
// Get token info
const symbol = await tokenContract.methods.symbol().call();
const decimals = await tokenContract.methods.decimals().call();
const balance = await tokenContract.methods.balanceOf(walletAddress).call();
console.log(`Balance: ${balance / 10 ** decimals} ${symbol}`);
// Transfer tokens
const amount = BigInt(100) * BigInt(10 ** decimals); // 100 tokens
await tokenContract.methods
.transfer(recipientAddress, amount.toString())
.send({ from: senderAddress, gas: 100000 });

Testing Environment

Use Sepolia Testnet

  1. Get test ETH from a faucet: https://www.alchemy.com/faucets/ethereum-sepolia
  2. Switch to the testnet in your code:
const isProduction = process.env.NODE_ENV === 'production';
const network = isProduction ? 'mainnet' : 'sepolia';
const provider = `https://${network}.infura.io/v3/${process.env.INFURA_API_KEY}`;

Hardhat for Development

npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
npx hardhat init

Configure hardhat.config.js:

require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: "0.8.19",
networks: {
sepolia: {
url: `https://sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts: [process.env.PRIVATE_KEY],
},
},
};

Run tests:

npx hardhat test
npx hardhat run scripts/deploy.js --network sepolia

Useful Development Tools

  • Remix IDE: Browser-based Solidity editor - https://remix.ethereum.org
  • Etherscan: Block explorer - https://etherscan.io
  • Ganache: Local blockchain - https://github.com/trufflesuite/ganache-ui
  • Infura: Node infrastructure - https://www.infura.io
  • Alchemy: Enhanced API - https://www.alchemy.com

Security Considerations

  1. Never expose private keys: Use environment variables
  2. Validate all inputs: Smart contracts can't be changed after deployment
  3. Test thoroughly: Bugs cost real money
  4. Use audited contracts: Don't reinvent the wheel for tokens
  5. Understand gas: Optimize to save users money
  6. Handle failures: Transactions can fail for many reasons

Key Takeaways

  1. Use testnets first: Always test on Sepolia before mainnet
  2. Understand gas: Every operation costs money
  3. Events for UI updates: Listen to contract events for real-time updates
  4. BigInt for amounts: Ethereum uses 18 decimals; use BigInt
  5. Secure key management: Use hardware wallets for production
  6. Verify on Etherscan: Publish source code for transparency

Blockchain development requires careful attention to security and testing—mistakes are permanent and potentially costly. Start with testnets and small amounts until confident.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive