ethers-kt 没返回区块号:检查 send、链 ID 探测和协程接口
链小知 · 进阶 · 核验 · 依官方文档整理
针对当前 2.0.1 README 的 Kotlin Multiplatform 用法,定位只构造请求、错误展开和 HTTP 订阅失败。
开始前准备
- 准备锁定依赖版本的 Kotlin 工程与脱敏 Provider/RpcRequest 代码;确认目标是 EVM providers 模块。
- iOS/macOS 等共享代码不能直接使用只在 JVM/Android 暴露的 sendAwait/sendAsync;RPC 服务的认证和费用按供应商条件。
1. 先核对模块与运行平台
当前 README 的 BOM 示例为 io.kriptal.ethers:ethers-bom:2.0.1,另有独立 Solana 模块。把项目版本、运行 target 和 imports 列出来;EVM getBlockNumber 不是 Solana 的读取接口,abigen 与 signers-gcp 也不是全平台模块。
检查结果:依赖版本、EVM 模块和 JVM/Android/Apple target 明确。
2. 分清配置 chainId 与探测结果
Provider.builder("<RPC_URL>").build().unwrap() 默认会通过 eth_chainId 判断节点网络;显式 build(chainId = 1L) 则跳过该请求。已有 chainId=1 配置只说明调用者填了 1,不证明 URL 真连到 Ethereum,排查错链时要保留探测路径或独立证据。
检查结果:链身份来自节点返回或可复核配置证据,不把跳过探测的数值当验证。
3. 真正发送区块号请求
val request = provider.getBlockNumber() 只构造 RpcRequest;协程上下文中 request.send() 才发送。把请求构造与结果取得的位置分别检查,避免打印 request 对象或提早返回。共享 KMP 代码使用 suspend send;JVM/Android 的 sendAwait 是另一便利接口。
检查结果:代码有一次明确的发送并等待结果;结果不是请求对象。
4. 保留 RpcResult 的失败信息
用 onFailure 保留错误类型与 message,再决定是否 unwrap;unwrap 会把失败展开为异常,若上层全部捕获成 0,会丢掉认证、方法不可用或节点错误。不要无限重试认证失败;先核对 URL、权限和当前服务状态。
检查结果:失败日志有 RPC 错误信息,零区块号与未成功读取分开。
5. HTTP 不能当 WebSocket 订阅
若区块号单次读取正常而 subscribeNewHeads 报 method not found,核对是否使用 HTTP。官方说明 eth_subscribe 依赖 WebSocket;watch 前缀的过滤器轮询是另一机制。选定机制后记录取消/生命周期处理,不把没有新事件解释为单次读取失败。
检查结果:传输协议、订阅或轮询模式以及实际错误三项一致。
怎样确认完成
- 能区分模块错误、未发送、RPC 失败和订阅传输错误。
- 教程为文档核对,不代表已完成任一平台编译或实网读取。
常见错误与边界
- 指定 chainId 可以省探测请求,也会掩盖 URL 指向错误网络的问题。
- 阻塞式 JVM 便利 API 不能照搬到所有 KMP target。
- 只有 subscribe 才需要事件传输能力;单次读成功不证明节点支持订阅。