
web3-validator 深度解析从 Changelog 看 web3.js 数据校验模块的演进与实现原理【免费下载链接】web3.jsCollection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.项目地址: https://gitcode.com/gh_mirrors/we/web3.jsweb3-validator 是 web3.js 生态中负责对象与数据校验的核心子包它为整个 web3.js 提供以太坊类型 JSON-Schema双层校验能力。本文以 web3-validator/CHANGELOG.md 的版本演进为主线结合 web3-validator 源码 与 README系统讲解该模块的安装用法、核心架构、类型体系、校验流程与错误处理帮助你理解 web3.js 内部参数校验的底层原理并能在自己的 TypeScript 项目中独立使用它。一、模块定位web3.js 的参数校验中枢web3-validator 是 web3.js 的一个子包其 README 中的定位是 contains functions for validating objects。它对外暴露两个层面的能力以太坊 ABI 类型校验直接传入类似[uint8, string]的简短 schema校验对应数组形式的参数值JSON-SchemaDraft-07校验将校验器实现为 JSON-Schema-Draft07 的扩展额外支持自定义关键字eth因此也能校验任意对象型数据。整个 web3.js 的 RPC 参数校验如getBalance、sendTransaction等方法的入参检查都依赖该模块可以把它理解为 web3.js 的参数守门员。二、安装与快速上手2.1 安装根据 package.json当前版本为2.0.6要求 Node.js14、npm6.12.0通过 NPM 或 Yarn 安装npm install web3-validator # 或 yarn add web3-validator包采用混合构建hybrid buildmain指向./lib/commonjs/index.jsCJSmodule指向./lib/esm/index.jsESM同时提供 TypeScript 类型声明./lib/types/index.d.tsCJS 与 ESM 两种模块系统下均可直接使用。2.2 基本用法import { validator } from web3-validator; // 校验通过则无副作用校验失败默认抛出异常 validator.validate([uint8, string], [val1, val2]); // 传入 { silent: true } 时不抛异常而是返回错误数组 const errors validator.validate([uint8, string], [val1, val2], { silent: true });其中validator是一个模块级单例见 default_validator.ts由Web3Validator类实例化。对于以太坊兼容数据值必须按 schema 顺序以数组形式传入例如 schema 为[uint, string]时值应传[2, my-string]。2.3 支持的以太坊基础类型README 中列出了可校验的 eth 类型类型输入形式说明uintnumber、string、HexString无符号整数支持全部以太坊变体如uint8、uint256可用数组描述符uint[]、uint[2]intnumber、string、HexString有符号整数支持int8、int256等变体与数组描述符bytesHexString、Uint8Array原始字节支持定长字节如bytes32stringstring字符串addressstring、HexString以太坊网络兼容地址bloomstring、HexString校验是否为合法的 Eth Bloom 值tuplearray以嵌套数组指定任意元组如[uint, string]自定义/数组元组可用[tuple[3], [uint, string]]语法除简短 schema 外还可以直接传完整 ABI 参数对象数组[{ name: owner, type: address }]更多 schema 示例可参考 web3-validator/test/fixtures 目录下的测试夹具文件。三、核心架构与校验调用链3.1 三层结构从源码结构看web3-validator 的校验能力由三层组成validator单例default_validator.ts模块级导出的Web3Validator实例供外部直接使用Web3Validatorweb3_validator.ts面向 ABI schema 的入口内部持有Validator.factory()返回的单例负责把 ABI 转换为 JSON-Schema 后再交给底层Validatorvalidator.ts底层 JSON-Schema 校验器采用factory()单例模式负责将 JSON-Schema 转换为 zod schema 并执行校验。Validator.factory()使用静态字段缓存实例validator.ts保证整个应用内只存在一个底层校验器避免重复构建 schema 的开销。3.2 完整调用链validator.validate([uint8, string], [2, hi])的实际执行路径为Web3Validator.validate调用ethAbiToJsonSchema(schema)utils.ts把 ABI 简短类型转换为{ type: array, items: [...] }形式的 JSON-Schema对空 schema 做特判items为空且数据为空时直接通过items为空但传了数据时抛出Web3ValidatorErrorempty schema against data can not be validated见 web3_validator.ts调用Validator.validate内部经convertToZod(schema)validator.ts把 JSON-Schema 递归转换为 zod schema再用zod.safeParse(data)执行校验校验失败时把 zod 的ZodIssue[]通过convertErrors转换为Web3ValidationErrorObject[]silent: true时原样返回错误数组否则抛出Web3ValidatorErrorvalidator.ts。3.3 convertToZod 的转换规则convertToZod是底层校验的关键其转换逻辑validator.ts依次处理object遍历schema.properties递归转换每个字段并按schema.required列表生成.required(...)约束array当items为多元素数组且带maxItems、各元素$id唯一时转为z.tuple定长元组否则转为z.array(...)并应用minItems/maxItemsoneOf递归映射为z.unionformat查找内置格式表找不到对应格式时抛出SchemaFormatError找到则生成z.any().refine(formats[format])的 refine 校验基础类型string、number、boolean等直接映射到对应的 zod 构造器。由于 2.0.0 起底层从is-my-json-valid全面切换到zodCHANGELOG #6264所有上述转换都是纯函数式地构建 zod 对象这让 schema 既可以预构建缓存也天然支持safeParse的无异常校验模式。四、类型体系与内置格式formats4.1 基础类型常量constants.ts 定义了校验器认可的基础以太坊类型export const VALID_ETH_BASE_TYPES [bool, int, uint, bytes, string, address, tuple];4.2 内置格式表formats.ts 维护了一张format - 校验函数的映射表是convertToZod中refine回调的数据来源包含address、bloom、blockNumber、blockTag、blockNumberOrTag、bool、bytes、filter、hex、uint、int、number、string通过循环程序化生成的全部定宽数值类型int8、int16……int256与uint8、uint16……uint256每 8 位递增见 formats.ts定长字节类型bytes1……bytes32并额外把bytes256别名为通用的bytesformats.ts。这些定宽类型正是 CHANGELOG 2.0.3 中 Validator will now properly handle all valid numeric type sizes: intN / uintN where 8 N 256 and N % 8 0#6434的实现载体isInt/isUInt校验函数接受{ bitSize }参数只有 8 的整数倍位宽才会在formats表中生成对应条目。4.3 类型解析parseBaseTypeutils.ts 的parseBaseType负责把 ABI 类型字符串拆解为三要素baseType剥离位宽与数组后缀后的基础类型名如uint256-uintbaseTypeSize位宽数值如bytes32- 32int128- 128arraySizes/isArray通过正则/(?:\[(\d*)\])/g提取所有维度的大小无固定大小的维度记为-1。例如uint256[2][3]会被解析为baseTypeuint、baseTypeSize256、arraySizes[2,3]、isArraytrue。abiSchemaToJsonSchemautils.ts随后按这些维度逐层构建嵌套的{ type: array, minItems, maxItems }结构正是 CHANGELOG 2.0.3#6435与 2.0.5#6798中多维数组正确处理的实现基础当维度大小为负动态数组时会删除minItems/maxItems约束。4.4 辅助转换工具utils.ts 还提供一批可在外部复用的转换函数hexToNumber/numberToHex十六进制与数字含负数互转超过Number.MAX_SAFE_INTEGER时返回bigintpadLeft对数值或十六进制字符串左侧补零uint8ArrayToHexString/hexToUint8ArrayUint8Array与 hex 字符串互转这是 1.0.0-rc.2 中 Replaced Buffer for Uint8Array#6004的产物——模块全面放弃 Node 的 Buffer改用标准Uint8Array从而获得更好的跨平台浏览器/Node一致性。五、从 Changelog 看版本演进每个条目背后的技术故事CHANGELOG.md 按 Keep a Changelog 与 Semantic Versioning 规范维护。下面把各版本的关键条目与源码对应关系展开。5.1 0.1.1-alpha 系列从雏形到基建0.1.1-alpha.1从Web3ValidatorError类中移除直接声明的toJSON()方法#5435因为该能力已由基类BaseWeb3Error提供删除冗余代码0.1.1-alpha.2修复 hex 校验的边界问题#5373——isHex对-123误判为false、isHexStrict对-0x误判为true、isHex对空字符串误判为true。这三处修复直接塑造了今天 string.ts 中isHex/isHexStrict的严格判定逻辑十六进制前缀、负号与空串处理0.1.1-alpha.3修复浏览器环境webpack 打包下引入web3-validator的报错#5710压缩产物文件名从index.min.js改为web3-validator.min.js避免与其他包的index产物冲突0.1.1-alpha.4 / 0.1.1-alpha.5tsc编译产物目录从dist/调整为lib/#5739并从 package.json 移除build入口#5755确立后续统一的构建产物布局。5.2 1.0.0-rc 系列为 1.0 正式版铺路1.0.0-rc.0TypedArray类型移入web3-types包统一管理#5771isBlockTag新增对safe、finalized两个新区块标签的支持#5823——对应 block.ts 中区块标签白名单的扩展1.0.0-rc.1首次随包发布源码#5956引入 ESM CJS 混合构建#5904这正是现代 package.json 中exports字段同时暴露import与require入口的由来新增isHexString、isHexPrefixed、validateNoLeadingZeroes三个校验函数#59631.0.0-rc.2用Uint8Array全面替换Buffer#6004Web3ValidationErrorObject类型改由web3-types包导出#6102web3-validator不再重复定义该类型1.0.0正式发布此前的 1.x alpha 与 RC 变更全部合入。5.3 2.0.x 系列zod 重写与精细化修复2.0.0最重大的一次架构变更——用zod替换is-my-json-valid#6264。随之调整了ValidationError、JsonSchema类型定义删除RawValidationError类型并将json-schema作为主 JSON-Schema 类型引入。这就是 validator.ts 中convertToZod全部逻辑的诞生背景2.0.1修复 ESM 导入 bug#6359确保在纯 ESM 环境下能正确解析包入口2.0.2依赖整体更新2.0.3三处关键修复——解析 ABI 时多维数组正确处理#6435修复 babel/React 默认配置下的TypeError: Cannot convert a BigInt value to a number#6506解决BigInt在转译链中被误转为 number 的兼容问题校验器完整支持 8 到 256 位且为 8 的倍数位宽的全部intN/uintN类型#6434并在向convertToZod传入不支持的format时抛出SchemaFormatError该错误类由web3-errors定义在 validator.ts 中触发2.0.4修复Uint8Array的跨 realm 检测问题#6486不再仅靠instanceof判断而是同时检查构造函数名见 utils.ts 的ensureIfUint8Array2.0.5定长多维数组如uint[2][3]在 ABI 解析中被正确处理#67982.0.6JSON-Schema 转换在abi.name缺失时如 public mappings正确分配$id#6981对应 utils.ts 中abiName abi.name || \${level}/${index}的兜底逻辑同时从 [package.json](https://link.gitcode.com/i/bc7ad190ee12e78b8a2e2f5afc92cba2) 移除指向不存在 bundle 文件的browser 入口#7015Unreleased为 React Native 构建增加web3-validator的 dist 路径#7416方便移动端打包工具直接引用浏览器产物。六、错误处理体系校验失败时错误信息由 errors.ts 中的Web3ValidatorError统一承载继承web3-errors包的BaseWeb3Errorcode固定为ERR_VALIDATION构造函数接收Web3ValidationErrorObject[]在super.message中汇总为 Web3 validator found N error[s]: ... 的多行消息每个Web3ValidationErrorObject包含keyword、instancePath、schemaPath、params、message等字段由 validator.ts 的convertErrors从 zod issue 转换而来其中数组超长/不足会被映射为maxItems/minItems关键字format 校验失败会被映射为带value、format参数的 custom issue。对于开发自定义校验场景可以配合silent: true拿到结构化错误数组自行处理而不是捕获异常。七、校验函数族validation 目录一览validation/index.ts 统一导出了全部独立校验函数可脱离整体校验器单独使用address.tsisAddressblock.tsisBlockNumber、isBlockNumberOrTag、isBlockTagbloom.tsisBloomboolean.tsisBooleanbytes.tsisBytesnumbers.tsisNumber、isInt、isUInt支持bitSizestring.tsisString、isHex、isHexStrict、isHexPrefixed等filter.ts、topic.ts、object.ts、eth.ts这些函数即 formats.ts 中各个 format 校验回调的底层实现也是 CHANGELOG 中多次 hex 校验修复#5373、位宽支持#6434等条目的直接落点。若需在项目里只做单项判断如这个字符串是不是合法地址直接 import 对应函数即可无需走完整 schema 流程。八、在 web3.js 工程中的位置作为 monorepo 子包web3-validator 被web3-eth、web3-eth-contract、web3-core等上层包依赖其运行时依赖仅包括zod、ethereum-cryptography、web3-errors、web3-types与util见 package.json依赖面很小、便于被各层复用。包内测试划分为test/unit与test/integration两套 Jest 配置对应 package.json 中test:unit/test:integration脚本单元测试覆盖 test/unit 下的校验函数与转换逻辑集成测试覆盖 test/integration 下的完整链路README 还建议通过test/fixtures下的abi_to_json_schema夹具查看更多 schema 示例。九、小结从 CHANGELOG.md 的演进记录可以清晰看到 web3-validator 的成长脉络早期解决 hex 边界与打包问题1.0 时代完成 ESM/CJS 混合构建与Uint8Array标准化2.0 时代则是一次彻底的zod底层重写并在此后持续精修多维数组、数值位宽、BigInt兼容与 React Native 等边界场景。对使用者而言掌握validator.validate的两层 schema 写法、理解convertToZod的转换规则、熟悉Web3ValidatorError的结构化错误字段就能在以太坊相关项目中高效完成参数校验并读懂 web3.js 上层 API 校验报错的真正含义。【免费下载链接】web3.jsCollection of comprehensive TypeScript libraries for Interaction with the Ethereum JSON RPC API and utility functions.项目地址: https://gitcode.com/gh_mirrors/we/web3.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考