fuels-ts 地址格式转换实战:用 Address 工具类打通 B256、Contract ID、Wallet 与 Asset ID
2026/9/9 20:02:26 网站建设 项目流程

fuels-ts 地址格式转换实战:用 Address 工具类打通 B256、Contract ID、Wallet 与 Asset ID

【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts

本指南聚焦 Fuel TypeScript SDK(fuels-ts)中的地址转换问题。Fuel Network 底层统一使用 B256(64 位十六进制)地址格式,但日常开发中你还会遇到以 Struct 包裹的 Asset ID、EVM Address、Checksum 地址等多种变体。读完本文,你将掌握如何借助Address这个类型安全的工具类,在这些格式与 Sway 标准类型之间自由转换,并理解其底层实现原理。

为什么需要地址转换

任何去中心化应用的开发都离不开地址,而不同网络、不同抽象层往往强制使用不同格式的地址。在 fuels-ts 生态中,主要会遇到以下几种形态:

  • B256 地址:Fuel Network 交互所使用的原生格式,本质是0x前缀加 64 个十六进制字符,总长 66 个字符。这也是 B256 类型(Sway 内建类型)的表示:
const b256 = '0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c';
  • Hex 格式字符串:不带任何业务语义的裸十六进制串,同样常见。
  • Struct 包裹类型:例如 Asset ID 与 EVM Address,它们在 Sway 中是以Struct形式包裹(对应 TypeScript 侧形如{ bits: B256 }的对象),参见 Struct 类型说明。

fuels-ts 通过 Address 工具类 让这些格式之间的转换变得简单——它提供了一系列转换与比较工具方法。下文将逐一演示如何利用该类在地址格式与 Sway 标准类型之间完成互转。

Address 类:一切转换的核心

在 Sway 中,Address是对内建B256原始类型的类型安全封装;而 fuels-ts 的 SDK 另有一套自己的Address抽象。其实现位于 packages/address/src/address.ts,类的核心只有一个只读属性:

readonly b256Address: B256Address;

即所有地址最终都会统一归一化并存储为小写的 B256 地址(见 normalizeB256)。围绕这一个属性,类提供了完整的方法族(源码见 packages/address/src/address.ts):

实例方法返回类型作用
toAddress()B256Address返回b256Address属性(L46-L48)
toB256()B256Address返回 B256 哈希地址字符串(L55-L57)
toBytes()Uint8Array返回 B256 地址的字节数组(L64-L66)
toHexString()B256Address等价于toB256()(L73-L75)
toEvmAddress()EvmAddress转为 SwayEvmAddress的 Struct 形态(L99-L103)
toAssetId()AssetId包装为 SwayAssetId的 Struct 形态(L109-L113)
toChecksum()ChecksumAddress生成 ERC-55 风格的校验和地址(L39-L41)
toString()/valueOf()string均返回校验和地址字符串(L82-L84、L119-L121)
equals(other)boolean比较两个地址是否相等(L128-L130)

构造函数的“万能输入”机制

new Address(address)的构造函数接受多种输入形态并自动判别(L28-L31):传入一个 B256 字符串、一个 512 位公钥字符串、一个 EVM 地址字符串,或一个已有的Address实例均可。其分发逻辑集中在 fromDynamicInputToB256:

  1. 若传入对象实现了toB256(),直接取用;
  2. 否则按长度与正则依次判断是否为B2560x+ 64 位 hex,isB256);
  3. 再判断是否为公钥0x+ 128 位 hex,即 512 bit,isPublicKey),是则对其做 sha256 哈希得到 B256;
  4. 接着判断是否为EVM 地址0x+ 40 位 hex,即 20 字节,isEvmAddress),是则通过 fromEvmAddressToB256 在头部补齐 12 字节零值得到 B256;
  5. 都不匹配则抛出FuelError(错误码PARSE_FAILED)。

需要注意,地址字符串在比较时会被统一转小写(normalizeB256),这意味着大小写差异不会影响相等性判断;而若需要带校验能力的表示,则应使用toChecksum()返回的 ERC-55 校验和地址。

转换 Contract ID

合约的id属性是一个Address实例(文档参见 address-conversion.md)。因此可以直接复用Address类的toAddresstoB256等方法完成转换。下面是从一个已部署合约获取其 B256 地址的完整示例(代码来自 contract.ts):

import type { B256Address } from 'fuels'; import { Address, Provider, Contract } from 'fuels'; import { LOCAL_NETWORK_URL } from '../../../../env'; import { Counter } from '../../../../typegend/contracts'; const provider = new Provider(LOCAL_NETWORK_URL); const contractAbi = Counter.abi; const contractAddress = new Address( '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f' ); const contract = new Contract(contractAddress, contractAbi, provider); const b256: B256Address = contract.id.toAddress(); // 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f

其中contract.id的类型即为Address,所以contract.id.toAddress()contract.id.toB256()均可直接调用,二者等价。这里通过Address的构造函数直接创建合约地址(而非依赖 typegen 生成的常量),充分体现了new Address(...)可接受原始 B256 字符串的能力。

转换 Wallet Address

同理,钱包的address属性同样是Address类型,因此可调用完全相同的方法族。下面的示例先用 B256 构造地址,再创建钱包对象并取出其 B256 地址(代码来自 wallet.ts):

import type { B256Address, WalletLocked } from 'fuels'; import { Address, Provider, Wallet } from 'fuels'; import { LOCAL_NETWORK_URL } from '../../../../env'; const provider = new Provider(LOCAL_NETWORK_URL); const address = new Address( '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f' ); const wallet: WalletLocked = Wallet.fromAddress(address, provider); const b256: B256Address = wallet.address.toAddress(); // 0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f

这里通过Wallet.fromAddress(address, provider)Address实例传入钱包构造器;钱包的address属性保持Address类型,因此wallet.address.toAddress()wallet.address.toB256()wallet.address.toEvmAddress()等方法都能直接使用。当你需要把一个地址作为交易收款方、查询余额等场景前,都可先用这些方法统一转成需要的目标格式。

转换 Asset ID

Asset ID 是包裹了内层 B256 值的 Struct 类型(对应 Sway 标准库定义,TypeScript 表示为{ bits: string },参见 asset-id.md)。下面的例子展示了如何从一个 B256 构造Address,再转成AssetId(代码来自 asset-id.ts):

import type { AssetId, B256Address } from 'fuels'; import { Address } from 'fuels'; const b256: B256Address = '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f'; const address: Address = new Address(b256); const assetId: AssetId = address.toAssetId(); // { // bits: '0x6d309766c0f1c6f103d147b287fabecaedd31beb180d45cf1bf7d88397aecc6f' // }

可以看到toAssetId()只是把内部的b256Address包装进{ bits }结构(实现见 toAssetId),因此这个资产 ID 在链上与原来的 B256 字节完全一致。反过来,当你的合约函数接收一个AssetId参数时,也可以把assetId.bits拿出来直接构造new Address(assetId.bits),进而复用本类全部方法。

转换到 EVM Address 与校验和地址

除上述官方文档演示的场景外,Address还提供了与跨链/校验场景强相关的两个实用方向:

EVM AddresstoEvmAddress()返回 SwayEvmAddressStruct({ bits: ... })。其底层 toB256AddressEvm 会先校验输入为合法 B256,然后裁掉前 12 字节、再在头部补回 12 个零字节,得到低位 20 字节与 EVM 地址对应的 B256。反之,若你手里是标准 20 字节的 EVM 地址字符串,new Address(evmAddress)会自动通过 fromEvmAddressToB256 补齐为 B256,无需手动 pad。

Checksum(校验和)地址toChecksum()遵循 ERC-55 规范——对 B256 十六进制串做 sha256 后,按哈希位逐位决定原字符是否大写(实现见 address.ts 的私有 toChecksum)。toString()valueOf()返回的正是这种校验和形式,equals()在内部也基于校验和比较(L128-L130),因此它同时具备“展示带校验、比较不受大小写干扰”的双重能力。

底层原理小结:一次构造,处处可转

纵观 packages/address/src/address.ts 的实现,fuels-ts 的地址转换设计可以概括为一句话:所有格式在构造Address时被统一折叠为一个小写的 B256,之后任何格式的输出都只由这一个事实源派生

  • 输入归一:构造函数经由 fromDynamicInputToB256 自动识别 B256 / 公钥(512) / EVM 地址 / 已有Address,无法识别时抛错,避免静默产生错误地址。
  • 输出派生toAddress/toB256/toHexString直接返回内部值;toBytes做字节化;toEvmAddress/toAssetId做 Struct 包装;toChecksum/toString做 ERC-55 校验编码。

这种“单一内部表示 + 双向可转换”的设计,使你在处理合约id、钱包address、链上 Asset ID 以及跨链 EVM 地址时,永远只需要一份标准化的转换心智模型。完整入口文档见 address-conversion.md,Address 类型的整体介绍见 address.md,b256.md 与 evm-address.md 则分别给出了各目标类型在 Sway 侧的语义定义,可对照阅读。

【免费下载链接】fuels-tsFuel Network Typescript SDK项目地址: https://gitcode.com/GitHub_Trending/fu/fuels-ts

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询