一个方法管两件事:EIP-2015 的换链尝试为什么没有成为标准 图 1
一个方法管两件事:EIP-2015 的换链尝试为什么没有成为标准 · 图 1

一个方法,两种动作

钱包里的网络按钮背后其实有两个动作:切到本机已有的网络,和把一条陌生链第一次写进钱包。现成标准把它们拆成了两个方法,而在拆分定型之前,2019 年提交的 EIP-2015 试过另一条路:一个 wallet_updateEthereumChain 同时管”切换”和”添加”。这个提案目前状态是 Stagnant,没有任何主流钱包实装,但它留下的参数结构和两条安全提醒,恰好能当今天换链操作的核对清单。

一个方法管两件事:EIP-2015 的换链尝试为什么没有成为标准 图 2
一个方法管两件事:EIP-2015 的换链尝试为什么没有成为标准 · 图 2

参数表里谁是正主

方法只收一个对象参数。chainId 是唯一必填项,按 EIP-155 的写法带 0x 前缀——链标识是这里唯一的硬事实。其余都是可选的建议项:chainName 给人看的名字、rpcUrls 一组接口地址、nativeCurrencynamesymboldecimals 三个子字段建议原生币怎么显示、blockExplorerUrl 指向区块浏览器。提案明确写着:除 chainId 外全部字段只是”建议”,钱包可以不采信、用自己的显示。对照 钱包弹出的网络配置单怎么逐项核对:chainId、RPC 与小数位 里那份网络配置单,字段家族几乎一一对应——当年这份表,正是后来弹窗里那些项目的雏形,名字与图标都可以是申报项,详见 添加代币弹窗里的名称、符号和小数位:哪一项是链上事实

返回约定与拒绝的样子

若提案落地,你按下的那一下会这样收场:当前活动链与请求一致就返回 true,无论此前它本来就是活动链、还是刚被你批准加进来;用户拒绝则报 4001 错误码。一个方法返回一个布尔,意味着”切到熟链”与”添加陌生 RPC 端点”两种风险完全不同的动作,在接口层面被抹成了同一个形状——这也是它容易被放弃的原因之一:钱包很难对两种语义给出一套差异化的确认界面。

提案里最值钱的两句话

提案的安全部分只讲了两件事。一是 SSRF:钱包在把 rpcUrls 里的地址拿去发请求之前要先验货,至少确认对方对 net_versioneth_chainId 的回答与申报一致——不能网站报什么地址,钱包就直接往里发请求。二是钓鱼:钱包应内置常用链的默认清单,避免用户第一次遇到某条链时,把网站现填的名字、图标、接口全当了真。这两句放到今天的手动添加网络场景里一个字都不用改,具体弹窗怎么逐项核对可以回看 钱包弹出的网络配置单怎么逐项核对:chainId、RPC 与小数位

它为什么停在那里

把两个动作捆在一个方法里,钱包想对”添加陌生链”单独加严就得连”切换”一起动刀,边界不好做。行业最终走的是拆分路线:wallet_addEthereumChain 管添加、wallet_switchEthereumChain 管切换,各管一件事、各弹各的确认框,后者在弹窗前该核对什么单独写过一篇。EIP-2015 则留在提案库里,状态 Stagnant。今天你在钱包里看到的换链请求都走那两个方法,它们都是”请求”而不是”命令”——是否换网络,决定权在人的那一次点击里。

换链那一下,屏幕上该发生什么

把提案放下,回到今天真实存在的换链界面,值得把动作拆成三种情形。第一种,目标链钱包里已经有了:合理的行为是弹一次轻确认,报出链名与链号,你点一下就走。第二种,钱包里没有这条链:任何弹窗都不该”顺手”把 RPC 地址、货币符号、浏览器链接一起静默写入,而应该把每一项列出来让你过目,因为这几项都可以由网站随意填写。第三种最危险:链号相同但参数不同——两条链号写撞了的链在测试环境里并不罕见,此时钱包显示的余额和Gas会用另一条链的规则去算,钱还在,显示和操作全错。三种情形的共同纪律是:链号独立核对,只认你自己向节点或独立资料查到的那一个,弹窗里的名字、图标、符号都只是对方申报。EIP-2015 用布尔值同时回答这三种情形时被指出的老毛病——轻重动作共用一个形状——恰好提醒每个钱包和用户:先分清这是切熟链还是进生链,再决定信多少。

本文为技术说明,不构成投资建议;添加陌生网络前请用独立渠道核对链标识与参数。