Introduction
This technical tutorial explores Ethereum, the pioneer of blockchain 2.0 and smart contracts. For foundational concepts, refer to this tutorial.
Key Ethereum Features:
- Supports smart contracts via the Ethereum Virtual Machine (EVM).
- Uses an account-balance model (not UTXO like Bitcoin).
- Launched in 2015 by Vitalik Buterin, employing PoW consensus (~13โ15 sec/block).
1. Ethereum Accounts
Ethereum accounts are categorized into:
- Externally Owned Accounts (EOAs): Controlled by private keys (user wallets).
- Contract Accounts: Hold smart contract code, lacking private keys.
Address Generation
Ethereum addresses derive from Keccak-256 hashes of uncompressed public keys (secp256k1 curve). The last 20 bytes prefix with 0x
form the address.
Code Example:
const randomBytes = require('randombytes');
const ethUtil = require('ethereumjs-util');
let priKey = randomBytes(32).toString('hex');
let pubKey = ethUtil.privateToPublic(new Buffer(priKey, 'hex')).toString('hex');
let addr = ethUtil.pubToAddress(new Buffer(pubKey, 'hex')).toString('hex');
EIP-55 Checksum:
Addresses can include uppercase letters for checksum validation (e.g., 0xAa...
). This prevents typos but remains backward-compatible.
2. Smart Contracts
Example: Voting Contract
pragma solidity ^0.8.0;
contract Vote {
event Voted(address indexed voter, uint8 proposal);
mapping(address => bool) public voted;
uint256 public endTime;
uint256 public proposalA;
// ... (additional proposals)
constructor(uint256 _endTime) { endTime = _endTime; }
function vote(uint8 _proposal) public {
require(block.timestamp < endTime, "Voting closed.");
require(!voted[msg.sender], "Already voted.");
voted[msg.sender] = true;
if (_proposal == 1) proposalA++;
// ... (handle other proposals)
emit Voted(msg.sender, _proposal);
}
function votes() public view returns (uint256) {
return proposalA + proposalB + proposalC;
}
}
Key Points:
view
functions read data without gas costs.- Write functions (e.g.,
vote()
) modify state and consume gas. - Events (e.g.,
Voted
) log actions for off-chain monitoring.
3. Deploying Contracts
Steps:
- Testnet Setup: Use Ropsten and acquire test ETH from faucets.
Tools:
- Remix IDE: Browser-based deployment.
- Truffle: Automated deployment via scripts.
4. Building a DApp
Architecture:
- Frontend: Connects to MetaMask via
ethers.js
. - Backend (Optional): Aggregates contract data for non-wallet users.
Frontend Code Snippet:
const VOTE_ADDR = '0x5b2a057e1db47463695b4629114cbdae99235a46';
const VOTE_ABI = [...]; // From Remix JSON
async function vote(proposal) {
const contract = new ethers.Contract(VOTE_ADDR, VOTE_ABI, window.ethereum);
const tx = await contract.vote(proposal);
await tx.wait(1); // Wait for confirmation
}
Backend Best Practices:
- Cache contract data.
- Listen to events via
eth_getLogs
.
FAQs
Q1: Can contract and user addresses collide?
No. Both derive from the same hashing method, but contracts lack private keys. Transactions to contracts trigger their fallback function.
Q2: How to verify an address?
Use checksum (EIP-55) or libraries like ethers.utils.getAddress()
.
Q3: Why use a backend server?
To serve data when users lack wallet connectivity or need historical analytics.
References
๐ Explore advanced Ethereum development tools
๐ Learn about decentralized applications