大多数 on-chain applications 都由同一小撮零件组成:wallets、smart contracts、tokens 与 dApps。搞清楚它们如何串连,以及每一块建立什么 trust model,就足以读懂多数 Web3 architectures,而不必淹没在 cryptography 里。
这篇 note 用 Ethereum / EVM 作为框架,因为 ERC token standards 住在那里。同样的想法可以转移到其他 chains,即使名称不同。
Blockchain 基础
Blockchain 是一份由许多独立 nodes 共同同意的 shared ledger。一旦 transaction 被确认,改写历史在设计上就是昂贵的。
- Accounts — chain 上的身份。Externally owned accounts (EOAs) 由 private keys 控制。Contract accounts 由 code 控制。
- Transactions — 已签署的 messages,提出一次 state change:送 value、调用 contract、deploy code。
- Consensus — 网络同意哪些 transactions 有效、以及顺序为何的方式。
- Gas — 在 on-chain 执行工作所付的 fee。每次 write 都有成本;通过 RPC node 的 reads 通常没有。
Signed transaction → Mempool → Included in a block → Shared state updatedchain 是 programmable settlement layer:跟普通 database 相比又慢又贵,但当 ownership 与规则必须可公开验证时,它就有用。
Wallets
Wallet 是持有 cryptographic keys、并帮你签署 transactions 的软件(或硬件)。它不是银行账户。Chain 存 balances;wallet 存你控制某个 address 的证明。
Private key → Public key → Address
Private key -(signs)→ Transaction signature- Private key 证明控制权。任何人拿到它,就可以从该 address 移走 assets。
- Public key / address 是别人用来送你 assets,或在 on-chain 识别你的东西。
- Signing 代表授权一笔特定 transaction,而不广播 private key 本身。
- Custody 是谁持有 keys。Self-custody 代表你自己持有。Custodial wallets 代表服务代表你持有。
- Browser extensions 与 mobile wallets 主要是 keys 周围的 UX。Hardware wallets 把 private key 留在 offline,只暴露 signatures。
当 dApp 说「connect wallet」,它是在要一个 address 与一条 signing channel,而不是要你登录某间公司 database 的密码:
const accounts = (await window.ethereum.request({
method: "eth_requestAccounts",
})) as string[]
const address = accounts[0]
// address is public; the private key never leaves the walletFailure: 把「connect」当成 Web2 login。Phishing sites 要你签错东西,而不是输入密码。
Smart Contracts
Smart contract 是部署在 blockchain 上的 program。在 Ethereum 上通常用 Solidity 写,跑在 EVM 上。一旦 deployed,它的 code 与 storage 就住在一个 contract address。
- Public state — 任何人都可以读 balances、ownership,常常也能读 bytecode。
- Deterministic execution — 同样的 inputs 与 state,在诚实 nodes 上产生同样的结果。
- Permissionless calling — 任何付得起 gas 的人都可以调用 public function,仍受 contract 自己的 access checks 约束。
- Hard to change — upgrades 需要明确 pattern(proxy、governance、migration)。Immutable code 上没有静默 hotfix。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract Escrow {
address public payer;
address public payee;
bool public released;
constructor(address _payee) payable {
payer = msg.sender;
payee = _payee;
}
function release() external {
require(msg.sender == payer, "only payer");
require(!released, "already released");
released = true;
payable(payee).transfer(address(this).balance);
}
}- Contracts 编码规则:谁能调用什么、在什么条件下、以及 state 如何改变。
- Smart contract 是一份 开放、按 fee 计量的 API,database 就是 chain。UI 可以撒谎;真正结算的是 contract 的 state。
Failure: 把 UI 当成 source of truth。Bugs 很贵,因为 funds 与 ownership 常常就坐在 contract 里面。
Tokens
Tokens 是由遵循共享 interfaces 的 smart contracts 表示的 assets。Wallets、explorers 与 dApps 不必为每个 project 写自定义 code 就能支持它们——这就是 ERC standards 重要的原因。
ERC-20 是 fungible tokens 的标准:每一单位都可以互换。心智模型是 balances,不是独特物品。approve + transferFrom 是 protocol 代表你花 tokens 的方式。
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}ERC-721 是 unique tokens 的标准。每个 tokenId 都是自己的 asset,只有一个 owner。Collectibles、tickets 与 on-chain deeds 是常见用途。同一份 contract 里的两个 tokens,只要 IDs 不同,就 不可互换。
ERC-1155 让一份 contract 管理多种 token types——fungible、non-fungible,或两者都有——并支持 batch transfers。Games 与 marketplaces 在单一 collection 混了 gold coins(fungible)、unique swords(supply 为一)与 limited skins(supply 为 N)时,往往偏好它。更少 deployments,更便宜的 batch operations。
| Standard | Fungibility | Identity model | Common uses |
|---|---|---|---|
| ERC-20 | Fungible | Amount per address | Currencies, points, governance |
| ERC-721 | Non-fungible | One owner per tokenId | Collectibles, tickets, unique rights |
| ERC-1155 | Mixed | Balance per address per id | Games, multi-asset collections |
三者仍然只是 smart contracts。ERC number 是共享 interface,让 tooling 能一致地对待它们。
Decentralized Applications (dApps)
dApp 是 critical logic 或 ownership 住在 on-chain 的应用。
- 一个 frontend(常常是普通 web app)负责 UX
- 一个 wallet 负责 identity 与 transaction signing
- Smart contracts 作为 assets 与规则的 source of truth
- 一个 RPC provider,让 frontend 能读 chain state 并广播已签署的 transactions
User → Wallet
User → dApp Frontend
dApp Frontend -(read state)→ RPC Node
dApp Frontend -(request signature)→ Wallet
Wallet -(signed tx)→ RPC Node → Blockchain → Smart Contracts- Reads 可以免费且频繁。Writes 需要 signature 与 gas。
- 许多 dApps 仍使用中心化零件——indexers、APIs、IPFS gateways、admin keys。「Decentralized」是一条光谱。真正重要的是:哪些部分失败或审查时,不会夺走用户的 assets。
它们如何组合
许多产品共用的一条具体流程:
User → dApp UI: Open app
dApp UI → Wallet: eth_requestAccounts
Wallet → dApp UI: address
dApp UI → Blockchain: balanceOf(address)
Blockchain → dApp UI: token balance
User → dApp UI: Deposit
dApp UI → Wallet: approve(protocol, amount)
Wallet → Blockchain: signed approve tx
dApp UI → Wallet: deposit(amount)
Wallet → Blockchain: signed deposit tx
Blockchain → dApp UI: updated state- User 打开 dApp 并 connect wallet。App 得知他们的 address。
- UI 通过 RPC 读取 balances 与 ownership(
balanceOf、ownerOf)。 - 要 deposit 一笔 ERC-20,他们先 approve contract 作为 spender,再调用 deposit——两次 signatures、两笔 transactions,除非被更高层 pattern batch。
- Smart contract 更新 on-chain state。UI 从 chain 或 indexer 刷新。
import { parseAbi, parseUnits } from "viem"
const amount = parseUnits("100", 6) // 100 USDC (6 decimals)
await walletClient.writeContract({
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
abi: parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]),
functionName: "approve",
args: ["0xProtocolAddress", amount],
})
await walletClient.writeContract({
address: "0xProtocolAddress",
abi: parseAbi(["function deposit(uint256 amount)"]),
functionName: "deposit",
args: [amount],
})把那笔 ERC-20 换成 ERC-721 mint,或 ERC-1155 batch claim,wallet / contract / RPC 的形状仍然一样。变的只有 token interface 与 contract 的业务规则。
要点
- Wallet 持有 keys,不是 ledger 本身——custody 讲的是谁能签。
- Smart contract 是公开、按 fee 计量的 logic,其 state 结算 ownership。
- ERC-20、ERC-721 与 ERC-1155 的主要差别在 fungibility,以及 identity 如何建模。
- dApp 组合 frontend、wallet signatures、RPC 与 contracts——对 assets 来说,source of truth 是 chain,不是 UI。
其他一切——L2s、account abstraction、indexers、bridges——都建立在这个底座上。