ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

EIP-1898 深度解读:为 Ethereum JSON-RPC defaultBlock 方法添加 blockHash 参数

EIP-1898 深度解读:为 Ethereum JSON-RPC defaultBlock 方法添加 blockHash 参数 EIP-1898 深度解读为 Ethereum JSON-RPC defaultBlock 方法添加 blockHash 参数【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs导读EIP-1898AddblockHashto defaultBlock methods是 Ethereum 接口层Interface的标准提案为eth_getBalance、eth_call等状态查询类 JSON-RPC 方法引入了一种新的块标识符Block Identifier对象格式让调用方可以直接用区块哈希block hash无歧义地指定查询目标即使该区块已不在规范链canonical chain上。本文以本仓库中的 EIP-1898 原始提案 为核心结合 EIP-234 与 EIP-1474 中相关的编码规范与错误码定义完整讲解该提案的规范、requireCanonical语义、错误处理、兼容性以及应对链重组的实战方案。读完本文你将掌握如何在钱包、DEX 前端、索引器等客户端中通过区块哈希发起连贯一致的状态查询。一、提案背景为什么需要按哈希查询状态以太坊客户端暴露的 JSON-RPC 接口中有一组状态查询类方法原本只接受默认区块参数defaultBlock来指定查询目标。EIP-1898 指出这组方法没有任何选项可以让调用方无歧义地指定要查询状态的区块这在链重组reorg频繁的真实网络中会给应用带来状态不一致的隐患。提案受 EIP-234为eth_getLogs/eth_newFilter的过滤器选项添加blockHash启发可视为其推广EIP-234 让日志可以按哈希无歧义获取EIP-1898 则让状态查询也能做到同样的事。正如 EIP-1898.md 所述这使客户端即使面对重组也能维持对区块链状态的一致认知coherent picture无需节点维护持久连接或存储任何客户端特定状态。1.1 问题场景两次调用之间发生重组设想一个钱包在用户刚完成转账后需要同时展示发送方与接收方的余额先用eth_getBalance查询发送方余额再用eth_getBalance查询接收方余额。如果两次调用之间发生了重组两次查询可能落在不同的区块上得到的两笔余额彼此无法对账reconcile。类似场景还包括链上订单簿 DEX 前端通过逐个调用eth_call遍历订单链表每个订单的状态必须来自同一区块多状态联合决策例如一个同时持有两个 NFT 才触发支付的应用需要基于多个状态片段做一致性判断。1.2 现有应对策略及其缺陷EIP-1898 的 Rationale 部分系统梳理了当前开发者可用的三种策略并逐一指出其代价策略做法缺陷区块号 回查校验选定区块号每次eth_call后调用eth_getBlockByNumber比对哈希不一致则回滚重试引入O(n)次额外调用的固定开销每次重试再叠加O(n)且无法检测查询前被重组出去、回查前又被重组回来的极端情况依赖日志利用 EIP-234 的blockHash参数无歧义地取日志需要智能合约语义支持必须发出合适的事件否则客户端无法重建所需状态非标准扩展如parity_subscribe通过 IPC/WebSocket 维持客户端与节点的持久连接增加客户端与节点耦合无法处理eth_call调用之间有依赖的场景如遍历链表EIP-1898 的结论是让eth_call及其同类方法能够无歧义指定目标区块是解决上述问题最稳健、最直观的方式——多次连续查询将落到同一状态开发者无需再担心自身视图与链上状态不一致。二、规范受影响的方法与新的块标识符对象2.1 受影响的 JSON-RPC 方法提案明确指定以下 6 个方法受影响与 EIP-1474 中Block Identifier小节列出的方法完全一致eth_getBalance— 查询地址余额weieth_getStorageAt— 查询合约指定存储槽位eth_getTransactionCount— 查询地址的 nonce交易计数eth_getCode— 查询地址处部署的合约代码eth_call— 立即执行一次消息调用不广播交易eth_getProof— 获取账户/存储的默克尔证明2.2 原有 defaultBlock 取值保留不变沿用自 Ethereum JSON-RPC 规范的 defaultBlock 参数目前支持以下取值HEX String— 一个整数区块号earliest— 最早/创世区块latest— 最新规范区块pending— 待处理状态/交易safe— 最近的安全区块finalized— 最近的已敲定finalized区块2.3 新增的 OBJECT 块标识符由于 JSON-RPC 中DATA定长字节串与 QUANTITY数量参数无法从字面上可靠区分例如0x1既可能是区块号也可能是某数据的十六进制前缀EIP-1898 没有直接允许裸哈希字符串而是提出一种新的对象OBJECT方案在原有取值之外额外允许blockNumberQUANTITY— 区块号blockHashDATA— 区块哈希EIP-1474 将该对象正式收录为 RPC 规范中的Block Identifier类型字段约束如下属性类型描述[blockNumber]Quantity规范链中该编号对应的区块或[blockHash]Data该哈希唯一标识的区块。blockNumber与blockHash互斥二者必须恰好设置一个requireCanonicalboolean可选仅在与blockHash搭配时允许。为true时若区块不在规范链中则抛错。默认false关于编码的硬性规则源自 EIP-1474 的 Value encoding 章节Quantity必须是0x前缀的十六进制且每字节使用最少的十六进制位0必须写作0x00x00这类前导零非法Data必须是0x前缀的十六进制且每个字节用两位十六进制数表示0x0非法0x00才是单个零字节。2.4 错误处理语义规范对两种异常情况给出了明确的 JSON-RPC 错误约定区块未找到block not found被调用方节点**应当SHOULD**抛出 JSON-RPC 错误推荐错误码为-32001: Resource not found区块不在规范链block not canonical仅当requireCanonical: true且通过哈希找到的区块不在规范链上时被调用方应当SHOULD额外抛出错误推荐错误码为-32000: Invalid input且必须与未找到错误码不同以便调用方区分两种情况。同时规范明确了一条优先级规则区块未找到检查优先于区块是否规范检查——即当区块不存在时即使requireCanonical为true也应返回未找到错误而不是非规范错误。对照 EIP-1474 的错误码表-32000与-32001均属于非标准non-standard类错误码分别表示 Missing or invalid parameters 与 Requested resource not found与本提案的推荐用法一致。2.5 向后兼容的等价写法为保证向后兼容区块号既可以继续用十六进制字符串也可以使用新的对象方案。以下六种写法对 defaultBlock 参数而言完全等价其中0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3是以太坊主网创世区块的哈希earliest 0x0 { blockNumber: 0x0 } { blockHash: 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3 } { blockHash: 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3, requireCanonical: true } { blockHash: 0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3, requireCanonical: false }三、实战构造按哈希查询的 JSON-RPC 请求3.1 基础请求示例以eth_getBalance为例传统按区块号查询curl -X POST --data { id: 1337, jsonrpc: 2.0, method: eth_getBalance, params: [0xc94770007dda54cF92009BFF0dE90c06F603a09f, latest] } url改用 EIP-1898 的块标识符对象按哈希查询对应 EIP-1474 中 eth_getBalance 的参数表第 2 个参数可为Quantity | string | Block Identifiercurl -X POST --data { id: 1337, jsonrpc: 2.0, method: eth_getBalance, params: [ 0xc94770007dda54cF92009BFF0dE90c06F603a09f, { blockHash: 0xblock-hash } ] } url加上规范校验要求目标区块必须位于规范链curl -X POST --data { id: 1337, jsonrpc: 2.0, method: eth_getBalance, params: [ 0xc94770007dda54cF92009BFF0dE90c06F603a09f, { blockHash: 0xblock-hash, requireCanonical: true } ] } url3.2 一致性查询的完整工作流结合提案 Rationale 中的目标一个无重组干扰的多步状态查询流程可组织为通过eth_getBlockByNumber或订阅获取感兴趣的区块哈希记录该哈希作为本次业务查询的锚点对该区块的多个状态片段连续发起eth_getBalance/eth_call/eth_getStorageAt/eth_getProof一律携带{ blockHash: 0xanchor }若某个调用返回-32001: Resource not found说明该区块已被重组出去此时再取最新区块哈希重试。由于所有查询都以哈希为锚无论链上如何重组只要该区块仍被节点保留返回的状态就永远来自同一个区块多个调用天然一致。3.3 错误响应示例当区块不存在时节点应返回JSON-RPC 响应中的error成员格式遵循 EIP-1474{ id: 1337, jsonrpc: 2.0, error: { code: -32001, message: Resource not found } }四、测试用例规范行为矩阵EIP-1898 的 Test Cases 章节以eth_getStorageAt为对象给出了完整的预期行为矩阵是验证节点实现是否符合规范的直接依据。设0xaddress为查询地址块参数预期行为{ blockNumber: 0x0 }返回创世区块中该地址的存储{ blockHash: 0xd4e5...fa3 }创世区块哈希返回创世区块中该地址的存储{ blockHash: 0xd4e5...fa3, requireCanonical: false }返回创世区块中该地址的存储{ blockHash: 0xd4e5...fa3, requireCanonical: true }返回创世区块中该地址的存储{ blockHash: 0x不存在的哈希 }抛出区块未找到错误{ blockHash: 0x不存在的哈希, requireCanonical: false }抛出区块未找到错误{ blockHash: 0x不存在的哈希, requireCanonical: true }抛出区块未找到错误未找到优先于非规范{ blockHash: 0x非规范区块哈希 }返回指定区块中该地址的存储非规范区块也允许{ blockHash: 0x非规范区块哈希, requireCanonical: false }返回指定区块中该地址的存储{ blockHash: 0x非规范区块哈希, requireCanonical: true }抛出区块非规范错误-32000从该矩阵可以提炼出三条核心语义默认宽松requireCanonical缺省为false只要区块存在即使不在规范链上也能查询错误区分-32001未找到与-32000非规范相互独立客户端可据此决定是重新锚定区块还是终止操作优先级明确未找到检查永远先于规范检查。五、与 EIP-234、EIP-1474 的关系5.1 EIP-234日志侧的 blockHashEIP-234 为eth_newFilter/eth_getLogs的过滤器选项增加了blockHash字段作为fromBlock/toBlock的替代且二者互斥。它解决的是日志流的重组一致性问题按区块号取日志时若查询间隙发生重组返回的可能是被重组进来的区块的日志且空数组结果无法区分该区块确实无日志与结果来自错误区块按哈希取日志则可保证结果一定属于指定区块。EIP-1898 正是把这一思想从日志推广到全部状态查询方法两者共同构成客户端应对重组的完整工具箱——参见 eip-234.md。5.2 EIP-1474块标识符的正式规范收录EIP-1474Remote procedure call specification在定义区块标识符参数时直接引用了 EIP-1898 的对象格式由于无法区分Data与Quantity参数EIP-1898 提供了按哈希或按编号指定区块的格式。这意味着 EIP-1898 定义的块标识符已成为以太坊 RPC 规范中标准参数类型的一部分任何实现 EIP-1474 所述方法的节点都应解析该对象——参见 eip-1474.md。六、向后兼容与安全考量向后兼容提案明确标注 Backwards compatible。新增的对象格式只是对原有 defaultBlock 取值的超集旧的十六进制字符串与earliest/latest等标签的语义完全不变既有客户端无需任何修改即可继续工作。安全考量提案原文声明 None。从设计上看该方案不引入持久连接、不要求节点存储客户端状态、也不扩大节点的攻击面查询非规范区块时节点只需保留对应的历史状态即可属于纯接口语义的扩展。七、总结EIP-1898 以最小侵入的方式补齐了以太坊 JSON-RPC 状态查询接口的一个关键缺口用区块哈希锚定状态查询。它带来的价值可以归纳为三点无歧义区块哈希全局唯一彻底规避了区块号 重组带来的二义性状态连贯多步查询余额对账、订单遍历、多状态联合判定天然一致无需额外的回查校验开销低耦合无需 WebSocket 持久连接或节点侧状态普通 HTTP 轮询即可获得强一致视图。对于钱包、DEX、索引器与任何依赖多步链上状态决策的应用将 defaultBlock 参数升级为{ blockHash: ..., requireCanonical: ... }对象格式是实现重组鲁棒性的标准做法。完整的规范原文见仓库 EIPS/eip-1898.md配套的日志侧方案见 EIPS/eip-234.md参数编码与错误码定义见 EIPS/eip-1474.md。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表