签名证明私钥控制者认可精确内容,不证明内容真实、网站可信或结果安全。
第二十一章 · 第二课 / 自己使用以太坊
钱包弹窗出现时,你究竟同意了什么?
“确认”按钮长得都很像,后果却可能从只暴露一个公开地址, 一路跨到允许别人以后转走一类资产。本课把签名、授权、交易、 切网和查链拆成五种不同动作,让你在点击之前读懂意图,在点击之后验证结果。
RULE / 先识别请求类型,再核对网络、对象、范围、期限与可撤销性。
连接网站不等于代币授权;断开连接也不会删除已经写入链上的 allowance。
切换网络只是改变当前账本与 RPC 上下文;同一地址在不同链上有不同状态。
区块浏览器是链上数据的阅读器,不是神谕;要区分原始字段、解码和标签。
01 / ORIENTATION
先别问“安不安全”,先问“这是什么动作”
相同的按钮文案可以触发完全不同的技术请求。风险判断必须从动作类型开始,而不是从网站给它起的名字开始。
你在 DApp 上看到“连接”“登录”“领取”“兑换”“授权”“确认”时,看到的是产品语言; 钱包真正处理的是技术请求。产品语言可以模糊甚至误导,技术请求却决定了有没有签名、 会不会上链、是否需要 Gas、有没有交易哈希,以及第三方以后还能不能继续使用这份权限。
以太坊官方文档把交易定义为由账户密码学签名、用于更新网络状态的指令。 一笔交易通常包含发送者、接收方、nonce、value、input data、Gas 上限和费用参数; 交易被广播、进入交易池并由验证者纳入区块后,才形成链上状态变化。 [1] 这与“签署一段登录消息”不是一回事。
CONNECT
连接账户
允许站点看到所选公开地址、请求 RPC 或后续弹窗。当前动作本身通常没有签名、Gas 或链上记录。
SIGN
签署消息
对一段消息或结构化数据生成签名。通常不立即上链,但签名可能被服务器验证或被合约以后消费。
APPROVE
代币授权
让 spender 或 operator 获得转移特定代币的权限。可以是链上交易,也可以是可被提交的签名式 permit。
TRANSACT
发送交易
签名并广播状态变更指令。成功或失败都会留下链上痕迹;失败通常仍消耗 Gas 和 nonce。
SWITCH
切换网络
把钱包的活动链与 RPC 上下文改到另一条链。不会自动桥接或转移任何资产。
LAB 01 / REQUEST CLASSIFIER
点选请求,先判断它能改变什么
教学模型,不连接钱包、不读取地址、不发送网络请求。
连接账户通常只让站点获得所选公开地址和当前网络上下文;它不等于签名、转账或代币授权,但站点可以继续发起后续请求。
02 / SIGNATURES
签名不是“把私钥交出去”
私钥留在钱包里;钱包用它对精确内容的哈希生成密码学证明。真正困难的不是“签名会不会泄露私钥”,而是“你究竟签了哪些字节”。
对普通外部账户(EOA),签名可以让验证者从“消息 + 签名”恢复出签名者地址, 从而证明持有对应私钥的人认可了这份内容。签名不会把私钥写进消息,也不会让验证者倒推出私钥。 但这只证明控制关系与内容一致性,不证明签名者读懂了内容、网站没有欺骗、合约没有漏洞, 更不证明现实世界里某个名字或头像就是真实身份。
Verify(expectedAccount, hash, signature) = true / false
ERC-191 为已签数据增加类型前缀,使它与普通以太坊交易的编码空间分离;
其中 0x45 版本对应常见的 “Ethereum Signed Message” 文本签名,
0x01 对应 EIP-712 结构化数据。[5]
EIP-712 再引入 domain separator;当该 domain 采用应用名称、版本、chainId、
verifyingContract 等常见字段时,它们会与具体消息一起哈希,目的是让结构可读、可验证,
并减少跨应用误用。
但标准本身明确提醒:应用仍须正确设计 nonce、期限与重放保护。
[6]
签名的证明边界
CRYPTOGRAPHIC PROOF ≠ HUMAN INTENT
CAN PROVE
它能证明
某个控制根对精确字节生成了有效签名;字节被改动后验证会失败;在合适的域分离与 nonce 设计下,可绑定应用、链、合约与一次性意图。
CANNOT PROVE
它不能证明
域名真实、UI 没有误导、合约安全、报价合理、签名者理解后果,或这份签名永远不会被第三方在链上使用。
03 / MESSAGE CONTEXT
同样写着“签名”,权限后果完全不同
先判断签名承载的是登录、订单、代币权限,还是交易本身。不要把“没有 Gas”误读成“没有资产风险”。
PERSONAL SIGN
文本消息
适合证明“我控制这个地址”或接受一段声明。重点核对完整文本、域名、nonce、时间与资源;不应签无法解释的十六进制。
EIP-712
结构化消息
把 domain 与 message 分开显示。重点核对 chainId、verifyingContract、spender、value、nonce、deadline 和具体动作。
TRANSACTION
交易签名
把 nonce、to、value、data、Gas 参数与 chainId 等纳入签名。广播后可用该链的区块浏览器追踪。
在常见钱包接口里,普通文本消息请求常见方法名是 personal_sign,
EIP-712 结构化消息常见 eth_signTypedData_v4。方法名只能帮助你识别格式,
不能替代对 domain、message 与消费方式的逐项检查。
ERC-4361(Sign-In with Ethereum,SIWE)规定了可读的登录消息格式,包含请求域名、 地址、URI、Chain ID、nonce、签发时间,并可选过期时间与资源列表。nonce 用于降低重放, 域名应与实际请求来源匹配。[7] 所以“登录签名”的正确检查不是只看一句 “Sign in”,而是逐项核对是谁请求、用哪个地址、 绑定哪条链、何时失效、是否包含超出登录范围的资源。
一份可检查的登录消息
DOMAIN · ADDRESS · CHAIN · NONCE · TIME
learn.example wants you to sign in with your Ethereum account:
0x8A2f...91C4
只建立本次课程会话,不授予代币权限。
URI: https://learn.example/session
Version: 1
Chain ID: 1
Nonce: 7H4N8K2P
Issued At: 2026-07-26T14:00:00Z
Expiration Time: 2026-07-26T15:00:00Z
04 / APPROVALS
授权不是一次转账,而是一条可被以后使用的规则
资产还在地址里,不代表控制面没有变化。授权把“以后谁能怎样移动资产”写进代币合约或可验证签名。
ERC-20 的基本模式是:所有者先调用 approve(spender, amount),
代币合约记录 allowance[owner][spender];之后 spender 可调用
transferFrom(owner, recipient, amount),在余额与额度允许时转移代币。
[8] 这份权限属于“某条链上的某个代币合约”,
它不是钱包的全局开关,也不直接覆盖 ETH。
按代币与额度
owner 允许 spender 转移最多 amount。无限额度扩大便利,也扩大该代币的未来暴露面。
owner: 0xYou
spender: 0xRouter
amount: 250 USDC
按 tokenId 或全集
approve 可针对单个 NFT;setApprovalForAll 通常覆盖该合约下所有资产。
operator: 0xMarket
approved: true
scope: ALL
先签名,后提交
owner 对 spender、value、nonce、deadline 和 domain 签名;任何人都可在 deadline 前提交有效 permit。
token: 0xToken
spender: 0xRouter
deadline: 15:00Z
ERC-721 区分单个 tokenId 的 approve 与整套资产的
setApprovalForAll;ERC-1155 也提供 operator 全集授权。
[9][10]
ERC-2612 则用 EIP-712 签名表达 ERC-20 授权:消息包含 owner、spender、value、nonce、
deadline,并通过 chainId 与 verifyingContract 绑定域。有效签名必须在 deadline 前提交;
提交成功后写入的 allowance 不会因这个 deadline 自动失效,仍需耗尽或被重设。
[11]
LAB 02 / PERMISSION RADIUS
同一次操作,需要多大权限才够?
简化风险尺只用于理解“范围”,不判断某个真实项目是否可信。
有限额度把该代币当前可触达量限制在 120;操作完成后仍应检查剩余额度是否归零或符合预期。
REVOKE
撤销是新的链上状态变化
ERC-20 常见做法是把对应 spender 的额度设为 0;NFT operator 则设为 false。它们需要在正确的链和代币合约上发送交易并支付 Gas。
DISCONNECT
断开只结束站点会话
断开 DApp 可阻止它继续读取当前连接或发起便捷请求,但不会自动修改已经存在的 token allowance 或 operator 权限。
MetaMask 的官方安全说明也把“连接站点”和“代币 allowance”明确区分,并提醒无限授权可能让 某类代币的当前及未来余额暴露;撤销链上授权本身也需要链上交易与 Gas。 [16][17]
05 / NETWORKS
同一个地址,可以活在许多彼此独立的账本里
网络切换改变钱包向哪条链读取和发送请求。它不会复制余额、搬运代币,也不会让一条链上的授权自动出现在另一条链。
如果同一把私钥在多个 EVM 网络上使用,通常会得到相同的 EOA 地址;但每条链各自维护余额、 nonce、合约代码和存储。于是“地址相同”只说明控制根相同,不说明账本状态相同。 你在以太坊主网拥有 1 ETH,并不意味着切到测试网后仍有 1 个测试 ETH。
Ethereum Mainnet
应用测试网
某条 Layer 2
EIP-155 把 chainId 纳入交易签名,核心目的之一是防止一条链的签名交易被原样重放到另一条链;
以太坊主网的 chainId 是 1。[4]
EIP-1193 把钱包视为 DApp 与客户端之间的中间层,并规定 chainChanged 事件:
活动链改变时,DApp 必须重新理解当前账户、余额和合约上下文。
[12]
SWITCH
切换已有网络
wallet_switchEthereumChain 只接受目标 chainId;钱包应清楚提示请求方与目标链,避免用户在不知情时操作错误账本。
ADD
添加陌生网络
请求可能包含 chainId、RPC URL、区块浏览器 URL、名称和原生货币。钱包应验证 RPC 返回的 chainId 与请求一致。
BRIDGE
真正跨链
桥接需要源链交易、消息传递及目标链结算等额外机制。它不是“切换网络”按钮的隐含效果。
EIP-3085 特别提醒:RPC 端点可能不诚实,也可能暴露 IP 与链上活动;钱包应使用 HTTPS、 校验 chainId,并清楚展示未知端点风险。[13] 状态为 Stagnant(停滞)的 EIP-3326 描述了钱包中广泛实现的切网方法,并强调切网应获得明确确认、 活动链切换时应取消链特定的待处理请求;它是钱包接口提案,不是协议层对所有钱包行为的保证。 [14]
LAB 03 / PARALLEL LEDGERS
切换网络,看见“同址不同账”
所有余额与地址均为虚构教学数据,不连接任何 RPC。
Account / 0x8A2f5c19A07c4D88d22e0e02B5F8c774A8B391C4
你只是改为查看主网状态;没有任何资产被移动。
06 / BLOCK EXPLORER
区块浏览器不是银行回单,而是一台链上数据解码器
先选对链,再从交易原始字段与收据出发;标签、函数名、Token Transfer 和“内部交易”都是建立在原始数据上的解释层。
区块浏览器通过节点与索引系统把十六进制数据整理成人能阅读的页面。它非常有用,但不是协议共识的一部分。 最稳妥的定位单位不是孤立的 tx hash,而是“chainId + tx hash”:先确认自己查的是哪条链, 再看该链上的交易、收据、日志与执行轨迹。
ethereum.org 列出的常见交易字段包括 hash、状态、区块、时间、from、to、Token Transfers、 value、费用、Gas limit / used、nonce 与 input data。 [2] 读这些字段时要注意:
STATUS
Success 只代表没回滚
收据状态为 1 说明顶层执行成功,不代表你拿到好价格、授权对象正确或业务目标达成。Failed 通常回滚状态,却仍消耗 Gas。
TO / VALUE
To 不是最终收款人
与路由合约交互时,To 是第一跳合约;最终代币接收者可能藏在 calldata 与事件中。Value 只表示顶层附带的原生资产。
FEE
实际费用看收据
Gas limit 是上限;实际费用通常由 gasUsed × effectiveGasPrice 决定。未用完的 Gas 上限不是全部被收走。
协议与收据字段
交易字节、区块、from、to、value、nonce、Gas、status、logs。多个节点应能返回一致的已确认数据。
可复算的解码
函数 selector、ABI 参数、事件 topic、代币 decimals。解码质量依赖正确 ABI、合约地址与代理实现。
索引与人工标签
项目名、钓鱼标记、美元价格、“Token Transfer”、内部调用列表。非常有用,但可能滞后、缺失或带假设。
Input / calldata:前 4 字节通常是函数选择器,后面是 ABI 编码参数。已验证源码与正确 ABI
能帮助浏览器显示 approve 等函数名;没有验证时,浏览器可能只能显示十六进制,
而相同 selector 也不等于现实语义必然一致。[1]
Logs / 事件:事件来自执行收据,是应用自己发出的结构化日志。 “Transfer” 字样本身不够;还要核对发出日志的代币合约地址、topics 与 data。 任意合约都可以设计同名事件,标签和代币符号也不是协议级真实性证明。
Internal Transactions:浏览器常用这个名字展示合约执行中的 CALL、CREATE、 SELFDESTRUCT 等轨迹与内部价值移动。它们不是额外由 EOA 签名并广播的顶层交易,而是从父交易执行轨迹 推导的调用。Etherscan 的接口也把它们按父交易哈希、call 类型与 traceId 返回。 [19]
LAB 04 / RECEIPT READER
点一个字段,读懂它能证明什么
虚构交易,不查询真实地址或实时链上数据。
顶层调用没有回滚
Success 表示交易收据状态为 1。它证明 EVM 执行完成,但不证明授权对象可信、报价公平或操作符合你的主观意图。
- 能证明
- 该链上这笔顶层交易执行成功
- 不能证明
- 经济结果正确或网站可信
- 下一步
- 继续核对 input、logs 与状态差异
07 / CHECKING WORKFLOW
确认前读意图,确认后读证据
一套稳定流程,比记住某个钱包版本的按钮位置更可靠。界面会变,检查问题不应变。
识别动作
连接、消息签名、permit、approve、转账还是切网?有没有 Gas 与 tx hash?
核对来源
浏览器域名、钱包显示的 requester、SIWE domain 是否一致?是否来自可信入口?
锁定网络
chainId、网络名称、RPC 与对应区块浏览器是否匹配?当前操作是否本来就该在这条链?
读对象与范围
to、verifyingContract、token、spender / operator、recipient、value、amount、tokenId 分别是谁?
读期限与退出
nonce、deadline、expiration、滑点、可撤销方式和升级权是什么?权限是否超出本次所需?
链后验证
在正确网络查 hash,读 status、input、logs、费用和最终 allowance;必要时再撤销。
BEFORE CONFIRM
不理解就拒绝
拒绝钱包请求是正常控制流,不会因为“网站说必须”而变得危险。无法解释的十六进制、陌生合约、无限额度与异常网络都足以暂停。
AFTER CONFIRM
不要只看余额
余额未变可能只是授权已建立、尚未被使用。对授权类动作,应在正确链上检查 allowance / operator 状态,而不只是交易是否 Success。
08 / INTEGRATED PRACTICE
把四种信息串成一次完整判断
以下是虚构情景。目标不是猜“项目好坏”,而是从钱包与浏览器字段推出可验证的技术结论。
SCENARIO A
“连接领取测试徽章”
页面先请求账户连接,随后弹出 EIP-712 Permit:chainId 1、spender 陌生、value 接近无限、deadline 一年后。
OBSERVATION
文案与请求冲突
测试徽章不应需要主网某 ERC-20 的长期无限额度。没有 Gas 并不代表没有链上可执行权限。
DECISION
拒签并独立核验
记录 domain、verifyingContract、spender 与 chainId,从官方入口重新核对;不要在原页面继续“修复网络”。
SCENARIO B
“授权后兑换 120 USDC”
钱包显示主网 approve,token 合约地址正确,spender 是已核对的 Router,额度 120 USDC。
EXPLORER
交易 Success,Value = 0
Input 解码为 approve(spender, 120e6),日志发出 Approval;余额不变是正常现象。
CONCLUSION
权限已写入,兑换未发生
这只是第一步授权。下一笔 swap 才会尝试转移代币;完成后再检查剩余额度。
SCENARIO C
“切到 L2 后余额消失”
地址未变,但钱包的原生余额、代币列表和 nonce 都不同;主网浏览器里仍可见原资产。
DIAGNOSIS
换了账本,不是资产丢失
切网只更换活动链。若要在 L2 使用资产,需要该链原生资产或经过明确的跨链机制。
CHECK
匹配 chainId 与 explorer
分别在两条链的浏览器按同一地址查询;不要把不同链上同符号代币自动视为同一资产。
09 / RECAP
一张图记住整课
每次钱包弹窗都按同一顺序拆解:类型、域、对象、范围、期限、证据。
connect / sign / approve / tx / switch + 域与网络
domain / chainId / RPC + 对象与范围
to / token / spender / amount + 期限与重放
nonce / deadline / expiration → 链上证据
status / input / logs / allowance
MENTAL MODEL
签名是精确字节的授权证据
风险来自被签内容与它的消费方式,而不是“签名”这个词本身。交易签名、登录签名和 permit 必须分开理解。
FIELD HABIT
永远带着链上下文读数据
地址、合约、余额、nonce、授权、交易 hash 与浏览器都必须绑定到具体 chainId;切网不是跨链。
10 / SELF CHECK
六题检查你是否真正会判断
先作答,再读解释。没有 JavaScript 时,答案解释会直接显示。
1. “连接钱包”本身通常会做什么?
答案:B。连接通常不生成签名或链上授权;风险在于地址隐私和后续请求。
2. 一次 EIP-712 签名不花 Gas,最准确的解释是什么?
答案:C。Permit、订单和元交易等签名可由第三方以后提交,签署时无 Gas 不代表无权限效果。
3. 断开 DApp 连接后,已有 ERC-20 allowance 会怎样?
答案:A。断开影响站点会话;allowance 是代币合约状态,需要链上交易修改。
4. 从主网切到测试网,钱包地址相同但余额不同,原因是什么?
答案:B。切网改变活动账本与 RPC;余额、nonce、合约和授权都是链特定状态。
5. 区块浏览器显示 Status = Success,能推出什么?
答案:C。还需继续核对 input、logs、状态差异与实际业务结果。
6. 一笔 approve 交易显示 Value = 0 ETH,最准确的判断是?
答案:A。顶层 value 只表示附带原生资产;calldata 可以调用代币合约并改变 allowance。
11 / GLOSSARY
本课术语
- Signature
- 私钥对特定消息哈希生成的密码学证明;验证者可确认签名者控制对应账户。
- Domain separator
- EIP-712 中用于把签名绑定到应用、版本、chainId、验证合约等语境的结构。
- Allowance
- ERC-20 中 owner 允许 spender 通过 transferFrom 使用的额度。
- Operator
- 在 ERC-721 / ERC-1155 中,被授权管理某个 collection 下资产的地址。
- Permit
- 以签名表达并可由第三方在 deadline 前提交的代币授权;提交后产生的 allowance 仍持续到耗尽或被重设。
- Chain ID
- 用于区分链的整数标识;进入交易签名与多种结构化签名域。
- RPC
- 钱包或应用向节点读取链状态、模拟调用或广播交易的远程接口。
- Receipt
- 交易被执行后产生的收据,包含 status、gasUsed、logs 等结果字段。
- Calldata
- 交易 input 中传给目标合约的字节;通常编码函数选择器与参数。
- Event log
- 合约执行时写入收据的结构化日志;需要结合发出日志的合约地址解释。
- Internal transaction
- 区块浏览器对合约内部 CALL / CREATE 等执行轨迹的常用称呼,不是新的顶层签名交易。
- Replay
- 把一份有效签名再次使用。chainId、nonce、deadline 与域分离是常见约束手段。
12 / PRIMARY SOURCES
一手资料与核对边界
资料核对日期:2026-07-26。网络、钱包界面与测试网状态会继续变化;概念以标准与协议字段为主,操作前重新核对官方资料。
- 01ethereum.org · Transactions
交易字段、签名、calldata、生命周期、收据状态与类型化交易。
- 02ethereum.org · Block explorers
区块浏览器可展示的交易、账户、合约、代币、Gas 与共识层字段。
- 03ethereum.org · Networks
主网、测试网、Sepolia、Hoodi 与弃用测试网的当前定位。
- 04EIP-155 · Simple replay attack protection
把 chainId 纳入交易签名及主网 chainId = 1 的规范来源。
- 05ERC-191 · Signed Data Standard
已签数据的版本前缀、personal_sign 与 EIP-712 的编码边界。
- 06EIP-712 · Typed structured data
结构化数据哈希、domain separator、chainId 与 verifyingContract。
- 07ERC-4361 · Sign-In with Ethereum
SIWE 的 domain、address、chainId、nonce、时间与来源核验要求。
- 08ERC-20 · Token Standard
approve、allowance、transferFrom 与 Approval 事件的标准接口。
- 09ERC-721 · Non-Fungible Token Standard
单 tokenId approval 与 operator approval 的范围区别。
- 10ERC-1155 · Multi Token Standard
多代币合约与 setApprovalForAll operator 模型。
- 11ERC-2612 · Permit
owner、spender、value、nonce、deadline 与 EIP-712 域;deadline 约束 permit 调用,不是 allowance 自动到期字段。
- 12EIP-1193 · Ethereum Provider API
钱包、Provider、Client 的边界与 chainChanged / accountsChanged。
- 13EIP-3085 · wallet_addEthereumChain
添加链所需元数据、RPC 校验、隐私与未知端点风险。
- 14EIP-3326 · wallet_switchEthereumChain
状态为 Stagnant 的钱包接口提案:活动链切换、用户确认与待处理链特定请求。
- 15ERC-1271 · Contract signature validation
合约账户如何按自己的逻辑验证签名,而不是依赖 EOA 地址恢复。
- 16MetaMask · What is a token approval?
代币授权、spending cap、无限额度与 setApprovalForAll 的用户解释。
- 17MetaMask · Revoke token approvals
断开 DApp 与撤销链上 allowance 的区别及撤销所需 Gas。
- 18Etherscan · Viewing transactions
Pending、Success、Failed、Dropped / Replaced 与确认信息的界面说明。
- 19Etherscan · Internal transactions by tx hash
按父交易哈希返回 call 类型、from、to、value 与错误状态的执行轨迹接口。