多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

web3.js v4 类型基石 web3-types 的演进全解析:从 CHANGELOG 到源码读懂以太坊 TypeScript 类型系统

web3.js v4 类型基石 web3-types 的演进全解析:从 CHANGELOG 到源码读懂以太坊 TypeScript 类型系统 区块链Web3【免费下载链接】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-types是 web3.js v44.x 系列中承载公共数据结构与接口定义的基础包它被web3、web3-eth、web3-utils、web3-core等所有模块共同引用是整个生态的类型地基。本文以 packages/web3-types/CHANGELOG.md 为主线结合 packages/web3-types/src 下的真实源码系统梳理该包从0.1.1-alpha.1到1.10.0的类型体系演进脉络——包括 EIP-1193 Provider 兼容、JSON-RPC 响应建模、EIP-1559 手续费类型、EIP-712 签名类型、ABI 泛型推导、Buffer 到 Uint8Array 的迁移等关键变化。读完本文你将理解 web3.js v4 类型系统为什么这样设计、每个核心类型定义在源码中的位置以及如何在自己的 TypeScript 项目中正确使用web3-types。一、web3-types 是什么CHANGELOG 背后的包定位web3-types的官方定位是提供 web3 各模块通用的数据结构和接口。在仓库中它的实现集中在 packages/web3-types/src/index.ts该文件通过十余个 re-export 将所有类型域统一导出export * from ./error_types.js; export * from ./apis/eth_execution_api.js; export * from ./apis/web3_eth_execution_api.js; export * from ./apis/web3_net_api.js; export * from ./apis/eth_personal_api.js; export * from ./data_format_types.js; export * from ./eth_types.js; export * from ./eth_abi_types.js; export * from ./eth_contract_types.js; export * from ./json_rpc_types.js; export * from ./primitives_types.js; export * from ./utility_types.js; export * from ./web3_api_types.js; export * from ./web3_base_provider.js; export * from ./web3_base_wallet.js; export * from ./web3_deferred_promise_type.js;类型域大致可划分为六类原始基础类型HexString、Bytes、Numbers、数据格式类型DataFormat、FMT_NUMBER、FMT_BYTES、JSON-RPC 消息类型请求/响应/通知/批量响应、Provider 接口族EIP-1193、Legacy、MetaMask、以太坊执行层 API 描述EthExecutionAPI、Web3EthExecutionAPI、Web3NetAPI、EthPersonalAPI以及ABI/合约类型AbiFragment、ContractMethods等泛型推导工具。从 packages/web3-types/package.json 可以看到它的工程形态当前版本1.10.0以lib/commonjsCJS与lib/esmESM双格式发布engines要求 Node.js 14、npm 6.12.0许可证为 LGPL-3.0。安装方式为npm install web3-types或yarn add web3-types参见 packages/web3-types/README.md。二、原始类型与数据格式一切类型的地基2.1 三个核心原语web3-types的所有以太坊领域类型都建立在三个原语之上见 packages/web3-types/src/primitives_types.tsexport type HexString string; export type Bytes Uint8Array | HexString; export type Numbers number | bigint | string | HexString;HexString当前定义为string源码中有 TODO 注释考虑未来收紧为0x${string}模板字面量类型Bytes同时接受十六进制字符串与Uint8Array这一设计直接服务于 CHANGELOG 中多次出现的Buffer → Uint8Array 迁移Numbers是number | bigint | string的宽松联合配合后续的数据格式类型实现一处定义、多格式返回。文件末尾还导出了TypedArray常量Object.getPrototypeOf(Uint8Array)的原型对象。这正是 CHANGELOG 在1.0.0-rc.0中记录的TypedArray曾在web3-utils与web3-validator中被重复定义现统一收敛到web3-types的落点。2.2 数据格式系统FMT_NUMBER / FMT_BYTES / DataFormatCHANGELOG 的1.0.0-rc.1记录了一批类型从web3-utils迁入FMT_NUMBER、NumberTypes、FMT_BYTES、ByteTypes、DataFormat、DEFAULT_RETURN_FORMAT、ETH_DATA_FORMAT、FormatType。它们全部实现在 packages/web3-types/src/data_format_types.tsexport enum FMT_NUMBER { NUMBER NUMBER_NUMBER, HEX NUMBER_HEX, STR NUMBER_STR, BIGINT NUMBER_BIGINT, } export enum FMT_BYTES { HEX BYTES_HEX, UINT8ARRAY BYTES_UINT8ARRAY, } export type DataFormat { readonly number: FMT_NUMBER; readonly bytes: FMT_BYTES; }; export const DEFAULT_RETURN_FORMAT { number: FMT_NUMBER.BIGINT, bytes: FMT_BYTES.HEX } as const; export const ETH_DATA_FORMAT { number: FMT_NUMBER.HEX, bytes: FMT_BYTES.HEX } as const;要点如下数字四态number、十六进制字符串HEX、十进制字符串STR、bigint字节两态十六进制字符串、Uint8Array两个内置格式常量DEFAULT_RETURN_FORMAT默认返回bigint数字 十六进制字节即 web3.js v4 的默认行为与ETH_DATA_FORMATRPC 线级格式数字一律为 hexFormatTypeT, F是一个递归的条件类型工具它会逐层遍历对象结构把其中所有Numbers兼容的字段映射为F[number]指定的类型、所有Bytes兼容的字段映射为F[bytes]指定的类型。web3.js 各 RPC 方法按需格式化返回的能力正是由它驱动的。三、JSON-RPC 消息类型的建模演进CHANGELOG 中1.7.0是一个标志性节点JsonRpcNotification加入JsonRpcResponse联合类型并新增result与error均为可选never的约束。对应源码见 packages/web3-types/src/json_rpc_types.tsexport interface JsonRpcResponseWithErrorError JsonRpcResult { readonly id: JsonRpcId; readonly jsonrpc: JsonRpcIdentifier; readonly error: JsonRpcErrorError; readonly result?: never; // 有 error 就绝不能有 result } export interface JsonRpcResponseWithResultT JsonRpcResult { readonly id: JsonRpcId; readonly jsonrpc: JsonRpcIdentifier; readonly error?: never; // 有 result 就绝不能有 error readonly result: T; } export interface JsonRpcNotificationT JsonRpcResult { readonly id?: JsonRpcId; readonly jsonrpc: JsonRpcIdentifier; readonly method: string; readonly params: SubscriptionParamsT; readonly result?: never; readonly data?: never; readonly error?: never; } export type JsonRpcResponseResult JsonRpcResult, Error JsonRpcResult | JsonRpcResponseWithErrorError | JsonRpcResponseWithResultResult | JsonRpcBatchResponseResult, Error | JsonRpcNotificationResult;这段类型设计的精妙之处在于通过result?: never/error?: never的互斥标记让 TypeScript 在区分成功响应与错误响应时能自动收窄类型而JsonRpcNotification订阅推送无id、带method与params作为第四种形态进入联合类型使得 provider 的request返回类型与订阅事件回调可以共享同一套模型。1.0.0-rc.2还加入过JsonRpcSubscriptionResultOld与Web3ProviderMessageEventCallback用于兼容旧 provider 的.on(data)事件见 packages/web3-types/src/web3_base_provider.ts 中on方法的重载签名。四、Provider 抽象向 EIP-1193 全面对齐Provider 层是 CHANGELOG 中被反复打磨的主题贯穿0.1.1-alpha.2、1.0.1、1.2.0、1.3.1等多个版本0.1.1-alpha.2EIP1193Provider类的request方法开始兼容 EIP-1193#55911.0.1新增SimpleProvider接口与Eip1193EventName类型#6210EIP1193Provider补齐on/removeListener的全部事件签名1.2.0为Web3BaseProvider增加asEIP1193Provider()#64071.3.1新增MetaMaskProvider接口并纳入SupportedProviders联合类型#6534。源码在 packages/web3-types/src/web3_base_provider.ts 中给出了完整实现几个关键点值得展开1事件名枚举。Eip1193EventName connect | disconnect | message | chainChanged | accountsChanged与 EIP-1193 规范一一对应。2SimpleProvider只要求一个方法export interface SimpleProviderAPI extends Web3APISpec { requestMethod extends Web3APIMethodAPI, ResponseType Web3APIReturnTypeAPI, Method( args: Web3APIPayloadAPI, Method, ): PromiseJsonRpcResponseWithResultResponseType | unknown; }3asEIP1193Provider()的实现思路。它通过Object.create(this)创建一个以当前 provider 为原型的新对象覆写request方法使其直接解包response.result返回并把原对象上的asEIP1193Provider置为undefined防止二次调用同时用注释说明该方法在未来 v5 中将被移除因为届时所有 provider 默认完全兼容 EIP-1193public asEIP1193Provider(): Eip1193CompatibleAPI { const newObj Object.create(this) as Eip1193CompatibleAPI; const originalRequest newObj.request; newObj.request async function request(args) { const response (await originalRequest(args)) as JsonRpcResponseWithResultunknown; return response.result; } as typeof newObj.request; newObj.asEIP1193Provider undefined; return newObj; }4跨版本识别的技巧。Web3BaseProvider定义了一个基于Symbol.for(web3/base-provider)的 getter 属性配合静态方法isWeb3Provider()判断任意对象是否为 web3 provider。源码注释明确解释了原因当项目中出现多个 web3.js 包版本时instanceof会失效而Symbol.for全局注册表可以保证同一字符串在不同包版本中始终映射到同一个 symbol。5SupportedProviders联合类型packages/web3-types/src/web3_base_provider.ts 末尾同时容纳了 EIP-1193、Web3BaseProvider、LegacyRequestProvider、LegacySendProvider、LegacySendAsyncProvider、SimpleProvider与MetaMaskProvider这就是 web3.js v4 既能接入现代钱包MetaMask 等 EIP-1193 实现又能兼容老式回调 provider 的类型基础。五、API 规范类型把 RPC 方法签名变成一等公民CHANGELOG 开篇0.1.1-alpha.1就记录了Web3EthExecutionAPI、Web3NetAPI、EthPersonalAPI三个 API 类型导出#5441随后#5393又让Web3APISpec、Web3APIMethod、Web3APIParams支持unknownAPI——即允许未知的、未被声明的 RPC 方法通过类型检查避免把用户自定义方法与严格类型系统对立起来。5.1 方法签名的组织方式EthExecutionAPI定义在 packages/web3-types/src/apis/eth_execution_api.ts是一张方法名 → 函数签名的映射表每条注释都标注了所依据的 ethereum/execution-apis 规范文件v1.0.0-alpha.9。例如eth_getBlockByNumber: (blockNumber: BlockNumberOrTag, hydrated: boolean) BlockAPI; eth_call: (transaction: TransactionCallAPI, blockNumber: BlockNumberOrTag) HexStringBytes; eth_feeHistory: ( blockCount: Uint, newestBlock: BlockNumberOrTag, rewardPercentiles: number[], ) FeeHistoryResultAPI; eth_getLogs: (filter: Filter) FilterResultsAPI;Web3EthExecutionAPI则通过交叉类型扩展它packages/web3-types/src/apis/web3_eth_execution_api.ts追加了 web3 生态特有的方法每个方法都附 EIP 出处注释export type Web3EthExecutionAPI EthExecutionAPI { eth_pendingTransactions: () TransactionInfo[]; eth_requestAccounts: () Address[]; // EIP-1102 eth_chainId: () Uint; // EIP-695 web3_clientVersion: () string; eth_getProof: (...) AccountObject; // EIP-1186 eth_signTypedData: (...) HexString256Bytes; // EIP-712 eth_signTypedData_v4: (...) HexString256Bytes; // EIP-712 };Web3NetAPI只有三个方法net_version、net_peerCount、net_listening见 packages/web3-types/src/apis/web3_net_api.ts。5.2 泛型工具Web3APISpec 家族配套的泛型工具位于 packages/web3-types/src/web3_api_types.tsexport type Web3APISpec Recordstring, (...params: any) any | unknown; export type Web3APIMethodT extends Web3APISpec string keyof ExcludeT, unknown; export type Web3APIParamsAPI extends Web3APISpec, Method extends Web3APIMethodAPI API extends ExcludeWeb3APISpec, unknown ? ParametersAPI[Method] : unknown; export type Web3APIReturnTypeAPI extends Web3APISpec, Method extends Web3APIMethodAPI API extends Recordstring, (...params: any) any ? ReturnTypeAPI[Method] : any;从Web3APISpec联合了unknown可以看出 #5393 的落地方式当 API 泛型参数退化为unknown时Web3APIParams与Web3APIReturnType分别落到unknown/any从而允许任意参数与返回类型——这正是支持 unknown API的类型机制。六、交易类型Legacy / EIP-2930 / EIP-1559 三态建模交易相关类型是 CHANGELOG 修改最密集的区域之一涉及1.0.0-rc.1TransactionOutput.data改名input#5915signTransaction使用Transaction类型#5993、1.1.0PopulatedUnsignedBaseTransaction的input/data变为可选#6294、1.3.1Transaction1559UnsignedAPI增加gasPrice#6539以及0.1.1-alpha.4三个带本地钱包索引的交易类型#5731。6.1 按 EIP 分类的 RPC 交易类型在 packages/web3-types/src/apis/eth_execution_api.ts 中交易被拆成 Unsigned / Signed 两大族再按类型参数组合LegacyTransactionLegacyUnsignedAPI只有gasPrice签名时带vEIP-2930Transaction2930UnsignedAPIgasPriceaccessListmaxFeePerGas/maxPriorityFeePerGas被约束为neverEIP-1559Transaction1559UnsignedAPImaxFeePerGasmaxPriorityFeePerGasaccessList签名时用yParity且v?: never。export type TransactionUnsignedAPI | Transaction1559UnsignedAPI | Transaction2930UnsignedAPI | TransactionLegacyUnsignedAPI;CHANGELOG 中1.3.1给Transaction1559UnsignedAPI加回gasPrice: Uint正是为了兼容部分客户端如 Ganache在 1559 交易中仍然返回gasPrice字段的现实。6.2 领域层交易类型packages/web3-types/src/eth_types.ts 提供了面向应用层的Transaction系列其中TransactionOutput通过交叉联合强制了互斥约束export type TransactionOutput { readonly to?: HexString; readonly input: string; readonly gas?: Numbers; // ... } ( | { maxPriorityFeePerGas: Numbers; maxFeePerGas: Numbers; gasPrice?: never } | { maxPriorityFeePerGas?: never; maxFeePerGas?: never; gasPrice: Numbers } );即 EIP-1559 字段与gasPrice二者只能取其一。0.1.1-alpha.4加入的三个钱包索引类型则用于本地钱包签名场景export interface TransactionWithFromLocalWalletIndex extends OmitTransaction, from { from: Numbers; // 使用本地钱包索引代替地址 } export interface TransactionWithToLocalWalletIndex extends OmitTransaction, to { to: Numbers; } export interface TransactionWithFromAndToLocalWalletIndex extends OmitTransaction, from | to { from: Numbers; to: Numbers; }6.3 Populated 系列与签名手续费类型PopulatedUnsignedBaseTransaction1.1.0起input/data均可选及其 EIP-2930、EIP-1559 变体gasPrice: never描述了已填充完整的未签名交易而1.5.0新增的FeeData#6795是为await web3.eth.calculateFeeData()准备的 EIP-1559 手续费数据export interface FeeData { readonly gasPrice?: Numbers; // 仅旧网络不支持 EIP-1559 时 readonly baseFeePerGas?: Numbers; // 最近区块的基础费仅信息用途 readonly maxFeePerGas?: Numbers; // 用户愿支付的每 gas 上限 readonly maxPriorityFeePerGas?: Numbers; // 给验证者的小费 }其 JSDoc 注释详细解释了用户实际只需支付未来 baseFeePerGas maxPriorityFeePerGasmaxFeePerGas用于防止 baseFee 过高时超额支付这一 EIP-1559 机制源码注释同时给出 EIP-1559 规范链接。七、区块、日志、收据与过滤器跟随以太坊升级而扩展CHANGELOG 记录了这些类型如何随以太坊协议升级不断加字段1.0.0-rc.0BlockTags/BlockTag增加safe与finalized#58231.8.0BlockTags再增加COMMITTED#7124形成earliest | latest | pending | safe | finalized | committed六值枚举见 packages/web3-types/src/eth_types.ts 的BlockTags定义1.0.2Filter类型包含blockHash#62061.9.0新增FilterParams类型#7353即OmitFilter, blockHash | filter用于不支持blockHash查询的过滤场景1.6.0Withdrawals、Block、BlockHeaderOutput增加 EIP-4844blobGasUsed、excessBlobGas、EIP-4895withdrawals、withdrawalsRoot、EIP-4788parentBeaconBlockRoot相关属性#69331.3.0新增EventLog接口#6410其returnValues字段承载合约事件解码结果、raw字段保留原始data与topics1.8.1修复baseFeePerGas在web3.eth.getFeeHistory中应为number的类型#7291。其中Filter的完整定义见 packages/web3-types/src/eth_types.ts值得单独列出因为它覆盖了fromBlock/toBlock/address/blockHash/topics/filter六类条件且topics使用(null | Topic | Topic[])[]表达通配符 单主题 多主题三种形态export interface Filter { readonly fromBlock?: BlockNumberOrTag; readonly toBlock?: BlockNumberOrTag; readonly address?: Address | Address[]; readonly blockHash?: Address; readonly topics?: (null | Topic | Topic[])[]; readonly filter?: FilterOption; }此外HardforksOrdered枚举1.0.0-rc.2起导出#6102按时间顺序列出了从chainstart到shanghai的全部硬分叉名称源码注释特别强调该列表顺序是有意义的改动时需保持有序packages/web3-types/src/eth_types.ts。八、ABI 类型与泛型推导让合约类型自动生成1.0.0-rc.0记录 ABI 相关类型从web3-eth-abi迁入#57711.0.0-rc.2为AbiParameter增加internalType#61021.4.0重新导出AbiItem以兼容 web3.js v1#66781.6.0为AbiFunctionFragment增加signature#6922。这些类型集中在 packages/web3-types/src/eth_abi_types.ts。8.1 片段类型体系ABI 被拆分为AbiConstructorFragment、AbiFunctionFragment、AbiEventFragment、AbiErrorFragment、AbiFallbackFragment五种片段共用AbiBaseFragment仅要求type字段最终由AbiFragment联合而成AbiItem被定义为AbiFragment的别名以兼容 v1。ContractAbi ReadonlyArrayAbiFragment | ReadonlyArrayAbiItem则是合约 ABI 的顶层类型。8.2 从 Solidity 类型字符串到 TS 类型的映射文件中最有技术含量的是MatchPrimitiveType一族泛型它们用模板字面量类型把 Solidity 类型字符串解析成 TS 类型例如export type PrimitiveAddressTypeType extends string Type extends address[${infer Size}] ? _TypedArrayAddress, Size // address[2] → FixedSizeArrayAddress, 2 : Type extends address ? Address : never;其中FixedSizeArrayT, N借助GrowToSize定义于 packages/web3-types/src/utility_types.ts用元组递归构造固定长度数组类型。ContractMethodInputParameters/ContractMethodOutputParameters则递归地把 ABI 的inputs/outputs映射为方法的参数元组与返回值类型——web3-eth-contract 中根据 ABI 自动推导合约方法签名的体验正是源自这里。九、工程化演进构建、依赖与语言版本CHANGELOG 也记录了三个与类型正确性直接相关的工程化里程碑1.0.0-rc.1混合构建#5904引入 ESM CJS 双格式hybrid build并把源码文件一并发布#5956。在 packages/web3-types/package.json 的exports字段中可以看到types、import、require三路出口分别指向lib/types、lib/esm、lib/commonjs构建脚本分别为build:cjs、build:esm、build:types。1.0.0-rc.2Buffer → Uint8Array#6004FMT_BYTES.BUFFER、Bytes、FormatType以及加密选项中的salt/iv全部从支持Buffer改为支持Uint8Array这是 web3.js v4 全面拥抱现代标准字节表示的一部分。1.0.11.10.0TypeScript 版本适配1.0.1修复了 web3.js 在 TypeScript v5 下的编译问题#61951.10.0正式将 TypeScript 从 4 升级到 5#7272devDependencies中当前锁定的typescript: ^5.5.4与之呼应。十、版本里程碑速览版本核心变化关键 PR0.1.1-alpha.1导出Web3EthExecutionAPI/Web3NetAPI/EthPersonalAPIAPI 类型支持unknown#5441 / #53930.1.1-alpha.2钱包加密类型Cipher/ScryptParams/KeyStore等从web3-eth-accounts迁入#55810.1.1-alpha.3编译产物dist/→lib/新增ProviderRpcError/EthSubscription/ProviderMessage/ProviderConnectInfo#5739 / #56830.1.1-alpha.4三个本地钱包索引交易类型#57311.0.0-rc.0ABI 类型迁入BlockTags增加safe/finalized#5771 / #58231.0.0-rc.1ESMCJS 混合构建TransactionOutput.data→input数据格式类型从web3-utils迁入#5904 / #5915 / #59931.0.0-rc.2Filter.filtersBuffer → Uint8ArrayAbiParameter.internalType导出HardforksOrdered#6010 / #6004 / #61021.0.0正式发布—1.0.1SimpleProvider、Eip1193EventNameTS v5 编译修复#6210 / #61951.0.2Filter包含blockHash#62061.1.0PopulatedUnsignedBaseTransaction的input/data可选EIP-712 类型与eth_signTypedData系列#6294 / #62861.2.0Web3BaseProvider.asEIP1193Provider()#64071.3.0新增EventLog#64101.3.1新增MetaMaskProviderTransaction1559UnsignedAPI.gasPrice#6534 / #65391.4.0重新导出AbiItem兼容 v1#66781.5.0新增FeeData配合calculateFeeData()#67951.6.0AbiFunctionFragment.signature区块类型补充 EIP-4844/4895/4788 字段#6922 / #69331.7.0JsonRpcNotification加入JsonRpcResponse联合类型#70911.8.0BlockTags.COMMITTED#71241.8.1修复baseFeePerGas返回类型为number#72911.9.0新增FilterParams#73531.10.0签名相关类型TypeScript 4 → 5#7374 / #7272当前 CHANGELOG 尾部还有一段[Unreleased]占位后续变更将持续在此累积。十一、在自己的项目中落地使用web3-types的典型使用方式有以下几种类型注解与自定义扩展从web3-types导入Transaction、Block、FeeData、Filter等类型为钱包、交易构建器、事件订阅等业务代码提供类型安全。自定义 RPC 方法与 Provider 类型当需要封装不在标准 API 中的 RPC 时可利用Web3APISpec与SimpleProvider定义自己的方法签名映射配合asEIP1193Provider()获得与 EIP-1193 完全兼容的request返回类型。ABI 泛型驱动合约代码ContractAbi、ContractMethods等类型可让合约封装层直接从 ABI 推导方法参数与返回值类型避免手工维护重复的接口定义。理解 web3.js v4 的返回格式机制DEFAULT_RETURN_FORMATbigint hex与ETH_DATA_FORMAT全 hex的区分决定了web3.eth各方法返回值的形态自定义返回格式则通过DataFormat与FormatType组合表达。安装与构建环境要求可参考 packages/web3-types/README.mdNode.js LTSFermium 起实际engines要求 14、Yarn/Lerna 工作流包自身脚本覆盖build含 CJS/ESM/types 三路、lint、format、testunit/integration 两套 jest 配置等。结语从0.1.1-alpha.1到1.10.0web3-types的 CHANGELOG 完整记录了 web3.js v4 类型系统从搭建骨架到跟随以太坊协议持续演进的整个过程JSON-RPC 消息建模从简单请求/响应走向成功/失败互斥 订阅通知四态Provider 抽象逐步向 EIP-1193 收敛交易类型精确区分 Legacy / EIP-2930 / EIP-1559区块、收据与过滤器类型随 EIP-4844、EIP-4895、EIP-4788 等升级持续扩展ABI 类型则通过模板字面量类型实现了从 Solidity 类型字符串到 TypeScript 类型的自动推导。这份变更日志本质上是一份以太坊类型系统设计笔记——读懂它就理解了 web3.js v4 全库类型体系的骨架也为自行扩展以太坊工具类型提供了可复用的范式。赞分享区块链Web3【免费下载链接】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点击查看免费下载相关推荐Kotatsu内置1200漫画源的开源Android阅读器3步开读Kotatsu内置1200漫画源的开源Android阅读器3步开读 地铁通勤的二十分钟你打开 Kotatsu Android 漫画阅读器从上次停下的那移动开发前端深入解读 Web3.js v4模块化 TypeScript 库如何连接以太坊与 EVM 兼容网络深入解读 Web3.js v4模块化 TypeScript 库如何连接以太坊与 EVM 兼容网络 Web3.js 是一个以 TypeScript/JavaSc区块链Web3Lynx 类型体系演进史从 lynx-js/types CHANGELOG 看跨端框架公共 API 的类型化之路Lynx 类型体系演进史从 lynx js/types CHANGELOG 看跨端框架公共 API 的类型化之路 lynx js/types 是 Lynx跨平台移动开发前端桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表