资讯动态

web3.js 4.x ABI 迁移指南:AbiInput 类型迁移与 internalType 到 baseType 重命名实战解析

发布时间:2026/9/20 6:07:16 来源:尧图企业网站定制
web3.js 4.x ABI 迁移指南AbiInput 类型迁移与 internalType 到 baseType 重命名实战解析【免费下载链接】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本指南基于 web3.js 官方升级文档 abi_migration_guide.md 展开聚焦web3.eth.abi模块在 1.x → 4.x 升级过程中最重要的两个破坏性变更AbiInput类型的归属迁移以及internalType属性被重命名为baseType。读完本文你将能准确识别旧代码中所有需要修改的类型引用位置理解 4.x 全新的 ABI 参数类型体系AbiParameter/AbiInput联合类型并掌握结合web3-eth-abi源码验证迁移结果的排查方法。迁移概览web3.eth.abi 在 4.x 中的位置在 web3.js 4.x 中ABI 编解码能力被收敛到独立的web3-eth-abi包中其入口文件 packages/web3-eth-abi/src/index.ts 统一导出了api/errors_api.js、api/events_api.js、api/functions_api.js、api/logs_api.js、api/parameters_api.js五个 API 模块utils.js类型映射、结构体扁平化等工具decode_contract_error_data.js合约错误数据解码eip_712.jsEIP-712 消息编码。开发者通过web3.eth.abi调用的encodeParameter、decodeParameters、encodeFunctionSignature等能力均来源于此包例如 parameters_api.ts 与 functions_api.ts。因此本次迁移的核心任务可以概括为两件事改对 import 来源、改对类型字段名。原文档 abi_migration_guide.md 明确列出了以下破坏性变更AbiInputhas moved fromweb3-eth-utilstoweb3-eth-abitypeAbiInputattribute was renamed tobaseTypefrominternalType下文逐一拆解。破坏性变更一AbiInput 的归属迁移1.x 中的情况在 1.x 中AbiInput是一个定义在web3-eth-utils即 1.x 的web3-eth-abi前置工具包中的普通interface结构如下原文档原文export interface AbiInput { name: string; type: string; indexed?: boolean; components?: AbiInput[]; internalType?: string; }也就是说1.x 的AbiInput同时承载了「参数名、参数类型、是否索引、嵌套组件、Solidity 内部类型名」五类信息internalType用于记录 Solidity 源码层面的真实类型如struct ABIV2UserDirectory.User。4.x 中的变化4.x 中AbiInput被彻底重设计为联合类型并且作为规范类型的定义位置迁移到了web3-types包而web3-eth-abi则负责消费它。原文档给出的 4.x 定义如下export type AbiInput string | AbiParameter | { readonly [key: string]: unknown }; // where AbiParameter is ... export type AbiParameter { readonly name: string; readonly type: string; readonly baseType?: string; readonly indexed?: boolean; readonly components?: ReadonlyArrayAbiParameter; readonly arrayLength?: number; readonly arrayChildren?: ReadonlyArrayAbiParameter; };在 packages/web3-types/src/eth_abi_types.ts 中可以找到与文档一致的AbiParameter定义而AbiInput联合类型定义在同文件 L145-L155export type AbiInput | string | AbiParameter | { name: string; type: string; components?: Components; index?: boolean; internalType?: string; } | { readonly [key: string]: unknown };这里需要特别说明三点帮助你在迁移时少踩坑string形式的AbiInput可以直接传uint256、address[]、tuple这样的类型字符串编码器内部会将其解析为标准参数对象见下文toAbiParams分析。兼容形态联合类型中保留了带index、internalType的旧式对象形态以及{ readonly [key: string]: unknown }兜底形态用于兼容来自 Solidity 编译器或第三方工具的 ABI JSON。baseType是可选字段?它只在需要区分「外部 ABI 类型」与「内部完整类型」时才会被填充普通 ABI 可以完全省略。破坏性变更二internalType 到 baseType 的重命名这是本次迁移最容易引发 TypeScript 编译错误的变更。1.x 中字段名为internalType而 4.x 的规范类型AbiParameter中该字段更名为baseType维度1.x旧4.x新字段名internalType?: stringbaseType?: string语义Solidity 内部类型名如struct X.Y参数的 ABI 基础类型所属类型AbiInputinterfaceAbiParametertype 别名可选性可选可选readonly只读定义位置web3-eth-utilsweb3-typesAbiParameter由web3-eth-abi消费源码中的实际状态值得注意的一个细节在 eth_abi_types.ts 中当前仓库的AbiParameter同时保留了baseType?与internalType?两个可选字段export type AbiParameter { readonly name: string; readonly type: string; readonly baseType?: string; readonly indexed?: boolean; readonly components?: ReadonlyArrayAbiParameter; readonly arrayLength?: number; readonly arrayChildren?: ReadonlyArrayAbiParameter; readonly internalType?: string; };也就是说从当前源码结构看internalType并未被完全删除而是以向后兼容的字段形式继续存在于类型定义中AbiInput联合类型中的旧式对象形态也仍带internalType。但从官方迁移语义与规范类型的角度4.x 的规范字段是baseType。迁移时建议新代码一律使用baseType旧代码中的internalType引用如果只是读取在当前版本仍可编译但不应再依赖如果 ABI 来自 Solidity 编译器输出的标准 JSON其中仍包含internalType可以原样传入因为联合类型和兼容字段都能承接。测试数据中的证据在 packages/web3-eth-abi/test/fixtures/data.ts 中可以看到大量仍携带internalType的 ABI 测试数据例如{ indexed: true, internalType: address, name: addr, type: address },以及嵌套结构体场景中典型的internalType: struct ABIV2UserDirectory.User。这些用例同时验证了两点一是 4.x 编码器必须兼容带internalType的外部 ABI JSON二是baseType/internalType这类附加字段不影响name、type、components这些核心字段的正常编解码。迁移实操如何修改你的代码步骤一修正 import 来源1.x 时代如果你从web3-eth-utils或其派生路径导入AbiInput4.x 需要改为从web3-types导入类型、从web3-eth-abi导入运行时能力// 1.x旧写法 import { AbiInput } from web3-eth-utils; // 4.x新写法类型来自 web3-types import { AbiInput, AbiParameter } from web3-types; // 运行时编解码能力来自 web3-eth-abi通常通过 web3.eth.abi 访问 import { encodeParameters, decodeParameters } from web3-eth-abi;如果你使用的是统一的web3包则通常不需要直接 import 包路径而是通过实例访问import Web3 from web3; const web3 new Web3(https://your.provider); // web3.eth.abi.encodeParameters / decodeParameters / encodeFunctionSignature ...步骤二改写自定义的 ABI 类型标注假设旧代码中有这样的接口或使用// 1.x import { AbiInput } from web3-eth-utils; const inputs: AbiInput[] [ { name: myString, type: string, internalType: string }, { name: myNumber, type: uint256, internalType: uint256 }, ];4.x 迁移后import { AbiInput } from web3-types; const inputs: AbiInput[] [ { name: myString, type: string, baseType: string }, { name: myNumber, type: uint256, baseType: uint256 }, ];对于嵌套结构体4.x 的components使用ReadonlyArrayAbiParameter并新增了arrayLength、arrayChildren两个字段来描述定长/嵌套数组const structInput: AbiParameter { name: user, type: tuple, baseType: tuple, components: [ { name: name, type: string, baseType: string }, { name: addr, type: address, baseType: address }, ], };步骤三验证迁移后的编解码行为迁移是否成功最直接的方式是跑一遍web3.eth.abi的编解码。以 parameters_api.ts 中encodeParameter的官方示例为例const res web3.eth.abi.encodeParameter(uint256, 2345675643); // 0x000000000000000000000000000000000000000000000000000000008bd02b7b const res web3.eth.abi.encodeParameter( { ParentStruct: { propertyOne: uint256, propertyTwo: uint256, childStruct: { propertyOne: uint256, propertyTwo: uint256, }, }, }, { propertyOne: 42, propertyTwo: 56, childStruct: { propertyOne: 45, propertyTwo: 78 }, }, );encodeParameter的实现非常薄同文件 L86-L87export const encodeParameter (abi: AbiInput, param: unknown): string encodeParameters([abi], [param]);它把单个参数包装成数组后委托给 coders/encode.ts 中的encodeParameters。解码侧同理decodeParameter委托decodeParameters(..., bytes)[0]取第一个结果见 parameters_api.ts L286-L287。这意味着只要你传入的AbiInput是 4.x 形态编解码行为即可按新版规范工作。源码级纵深4.x 编码器如何消费 AbiInput为了在迁移后对类型行为有底有必要看一下web3-eth-abi内部是如何把三种形态的AbiInput统一成AbiParameter的。关键在 packages/web3-eth-abi/src/coders/utils.ts 的toAbiParamsexport function toAbiParams(abi: ReadonlyArrayAbiInput): ReadonlyArrayAbiParameter { return abi.map(input { if (isAbiParameter(input)) { return input; // 形态一已是标准 AbiParameter直接透传 } if (typeof input string) { return convertExternalAbiParameter(parseAbiParameter(input.replace(/tuple/, ))); // 形态二类型字符串解析 } if (isSimplifiedStructFormat(input)) { const structName Object.keys(input)[0]; const structInfo mapStructNameAndType(structName); structInfo.name structInfo.name ?? ; return { ...structInfo, components: mapStructToCoderFormat( input[structName as keyof typeof input] as unknown as AbiStruct, ), }; // 形态三简化结构体格式 } throw new AbiError(Invalid abi); }); }从中可以提炼出三条对迁移有直接帮助的结论字符串形态uint256这类字符串会在编码时被解析为参数对象tuple前缀会被剥离后再解析因此字符串 ABI 与对象 ABI 可以混用。简化结构体格式{ ParentStruct: { propertyOne: uint256, ... } }这种「以结构体名为 key」的对象会被 utils.ts 中的mapStructNameAndTypemapStructToCoderFormat递归展开为带tuple类型和components的标准格式。非法输入保护既不是标准参数、也不是字符串、也不是简化结构体的输入会直接抛出AbiError(Invalid abi)这有助于迁移期快速定位错误。此外encodeParameterscoders/encode.ts L69-L81还有一道长度校验if (abi?.length ! params.length) { throw new AbiError(Invalid number of values received for given ABI, { expected: abi?.length, received: params.length, }); }迁移时如果遇到Invalid number of values received for given ABI说明 ABI 定义数量与传入参数数量不匹配——这是 4.x 更严格校验的典型表现与类型迁移本身无关但值得留意。如果你不确定参数的确切类型4.x 还提供了inferTypesAndEncodeParameterscoders/encode.ts L102-L114自动推断 ABI 并编码。官方注释明确提醒该方法的类型推断并不完美数组、非 uint256 的 uint、bytes 等场景可能产生意外结果已知类型时仍应优先使用encodeParameters——这也从侧面说明迁移后显式声明baseType的重要性。迁移后的周边适配AbiInput/AbiParameter类型变更的影响会波及web3-eth等上层包。例如合约错误解码路径 packages/web3-eth/src/utils/get_revert_reason.ts 会从web3-eth-abi导入decodeContractErrorData与isAbiErrorFragment依据合约 ABI 中的AbiErrorFragment其inputs同样由ReadonlyArrayAbiParameter组成解析 revert 原因。当你把自定义 ABI 类型从 1.x 形态升级到 4.x 形态后这类上层逻辑才能正确工作。总结与后续阅读本次web3.eth.abi迁移只需抓住两条主线改 importAbiInput以及AbiParameter的规范定义迁移到web3-typesweb3-eth-abi负责运行时编解码旧的web3-eth-utils导入路径不再可用。改字段规范字段由internalType更名为baseType当前源码中internalType仍以兼容字段存在但新代码应统一使用baseType并善用AbiInput联合类型中字符串、标准参数、简化结构体三种形态。升级过程中如果遇到编译错误优先检查上述两处如果遇到运行时AbiError可结合 coders/utils.ts 与 coders/encode.ts 的校验逻辑定位输入格式问题。本次升级是整个 15 系列迁移指南的一部分建议按顺序完成其余模块的迁移迁移指南总览、accounts 迁移、contracts 迁移、providers 迁移、web3-eth 迁移、web3-utils 迁移 等。若需要web3-eth-abi的完整 API 说明可查阅 packages/web3-eth-abi/README.md。【免费下载链接】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),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价