☰
fuels-ts 中的 Bytes32 类型全解析:哈希的 256 位字节表示、随机生成与 Hex 互转
2026/10/13 0:26:01 网站建设 项目流程

fuels-ts 中的 Bytes32 类型全解析:哈希的 256 位字节表示、随机生成与 Hex 互转

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

bytes32是 Sway 语言与 FuelVM 中专门用于承载哈希值的 256 位(32 字节)数据类型。本文以 fuels-ts 为主体,结合 TypeScript SDK 中randomBytes、hexlify、arrayify等底层实现与B256、Bytes等相邻类型,完整讲解它的语义、随机生成方法、字节数组与十六进制字符串互转技巧,以及它与 Fuel 原生类型b256的异同,帮助你在签名校验、交易哈希、资产标识等场景中正确处理 32 字节数据。

bytes32 是什么:FuelVM 中的哈希载体

在 Sway 与 FuelVM 的类型体系中,bytes32是表示哈希值的标准类型,它固定承载一个256 位(即 32 字节)的值。无论是区块哈希、交易哈希还是合约状态中散列化后的摘要,只要长度恰为 32 字节的数据,都可以用bytes32来描述。

在 类型总览文档 中,官方明确将这一系列文档定位为"帮助你理解 FuelVM 与 Sway 内部类型及其在 SDK 中的对应物",bytes32正是理解这条对应关系的第一站:Sway 侧是原生类型名bytes32,而在 TypeScript SDK 侧,开发者操作的是它的字节级表示。

需要特别注意它与原始字节数组的区别:bytes32在语义上是定长 32 字节的"值",通常由哈希运算产生,不具备可逆的文本含义;而 SDK 中的Bytes类型(定义为Uint8Array | number[],见 packages/abi-coder/src/utils/types.ts)则是一般意义上的动态原始字节集合。本文讨论的互转工具,正是沟通"定长字节值"与"SDK 运行时表示"的桥梁。

生成随机的 bytes32 值

需要构造一个随机 32 字节数据时(例如生成测试用的随机哈希、随机盐值),SDK 提供了开箱即用的randomBytes函数,它从fuels模块统一导出。

原文档对应的完整代码示例(见 snippets/bytes32/generating-random-bytes32.ts)如下:

import { randomBytes, type Bytes } from 'fuels'; const bytes32: Bytes = randomBytes(32);

关键点拆解:

  • randomBytes(n)会返回一个长度为n字节的Uint8Array;传入32即得到一个完整的bytes32(256 位)随机值。
  • 返回值的类型标注为Bytes,与 abi-coder 中Bytes = Uint8Array | number[]的类型定义保持一致,可直接参与后续的 ABI 编码或哈希计算。

底层实现:浏览器与 Node 双环境适配

randomBytes并不是一个"魔法"函数,在 packages/crypto 包中有针对不同运行环境的两个实现:

  • 浏览器环境(packages/crypto/src/browser/randomBytes.ts):基于 Web Crypto API 的crypto.getRandomValues(new Uint8Array(length))填充随机字节,是浏览器端符合安全要求的 CSPRNG(密码学安全伪随机数生成器)。
  • Node 环境(packages/crypto/src/node/randomBytes.ts):基于 Node 内置crypto模块的crypto.randomBytes(length),随后以Uint8Array.from(...)包装为标准 TypedArray。

也就是说,无论你的应用跑在浏览器还是 Node(含 Bun 等兼容运行时),randomBytes都会自动选择正确的安全随机源,你无需关心环境差异。这一点也可以从 SDK 自身源码中得到印证:getRandomB256正是用hexlify(randomBytes(32))一行组合实现的(见 packages/address/src/utils.ts),说明randomBytes(32)是生成随机 256 位哈希值的基础原语。

字节数组与十六进制字符串互转

在实际与 Fuel 节点、钱包或合约交互时,数据往往需要在这两种形态间切换:一种是机器友好的字节数组(Uint8Array),另一种是人机都可读的0x前缀十六进制字符串。SDK 为此提供了hexlify与arrayify一对互逆函数。

原文档对应的完整代码示例(见 snippets/bytes32/converting-between-byte.ts)如下:

import type { Bytes } from 'fuels'; import { arrayify, hexlify, randomBytes } from 'fuels'; const randomBytes32: Bytes = randomBytes(32); // 字节数组 -> 十六进制字符串 const bytes32String: string = hexlify(randomBytes32); // 十六进制字符串 -> 字节数组(还原) const bytes32: Bytes = arrayify(bytes32String);

这个往返过程可以概括为:randomBytes32(字节)经过hexlify得到带0x前缀的 64 位十六进制字符的字符串(32 字节 × 2 字符/字节),再经arrayify还原为原始的 32 字节数组,过程中数据不丢失。

hexlify:字节 → 0x 十六进制字符串

hexlify的实现位于 packages/utils/src/utils/hexlify.ts。它的处理逻辑很直观:

  1. 首先调用arrayify将入参统一归一化为Uint8Array(因此它不仅能处理字节数组,也能接收已是合法 hex 字符串的输入)。
  2. 以'0x'为前缀,逐字节用查表法(HexCharacters = '0123456789abcdef')将每个字节的高 4 位与低 4 位分别映射成两个十六进制字符并拼接。

由于采用固定小写字母表,生成的字符串是小写0x前缀形式(如0x1234...),长度与输入字节数严格对应——输入 32 字节,输出恰好 66 个字符(含0x)。

arrayify:hex 字符串 → 字节数组

arrayify的实现位于 packages/utils/src/utils/arrayify.ts,它承担着输入校验与转换的双重职责:

  • 输入归一化:若传入的本身就是Uint8Array,默认会拷贝一份新数组返回(copy参数默认为true),避免外部修改影响内部数据;你也可以显式传入copy: false复用原数组。
  • 格式校验:对于字符串输入,必须匹配正则/^0x([0-9a-f][0-9a-f])*$/i,即要求0x前缀 + 偶数个十六进制字符(大小写均可)。32 字节的bytes32对应 64 个十六进制字符。
  • 错误处理:一旦格式不合法,会抛出带INVALID_DATA错误码的FuelError,错误消息还会提示"如果你要转换 hex 值,请确认它以字符串形式传入并带有引号"——这是开发中非常容易踩的坑(例如忘记给 hex 加引号而被当作数值处理),了解这条错误信息有助于快速定位问题。

BytesLike与扩展用法

值得补充的是,hexlify与arrayify操作的对象在 utils 包中被统一定义为BytesLike = Uint8Array | string(见 packages/utils/src/utils/arrayify.ts)。这意味着你甚至可以直接把一份合法的 hex 字符串再次传给hexlify(内部先arrayify再输出规范化格式),用于将大小写混合、缺失前缀等不规范的 hex 统一为 SDK 标准的小写0x形式。这两组工具是 account、abi-coder、transactions 等上层包共用的基础设施,掌握它们的边界行为,能帮助你写出更健壮的字节处理代码。

从 bytes32 到 b256:Fuel 的 256 位原生类型

除了字节层面的bytes32,Fuel 还定义了语义层面的特殊类型b256。二者共享同一物理形态——都承载 256 位(32 字节)的值,常用于表示哈希;差异主要体现在 SDK 的表示策略上:

  • bytes32更多强调"定长 32 字节的原始字节数据"这一存储事实;
  • B256(TS SDK 中的表示)则作为一个语义化类型,SDK 出于可移植性考虑将其表示为hexlified(十六进制化)字符串,需要原始字节时才通过arrayify转换为Uint8Array。

关于B256的完整文档位于 b256.md,其中包括:

  • 使用getRandomB256()直接生成随机的B256十六进制字符串(其内部即hexlify(randomBytes(32)),见 packages/address/src/utils.ts);
  • 借助同一对arrayify/hexlify完成B256字符串与Uint8Array的双向转换;
  • 通过Address类对B256的集成支持,将 256 位值无缝接入地址体系。

因此,本页的bytes32可以视为B256的"字节视角",而B256则是它面向 SDK 业务层的"字符串化视图";当你阅读钱包地址、资产标识或合约哈希相关代码时,会频繁看到两者通过hexlify/arrayify相互桥接。

小结与进一步阅读

围绕bytes32,本文覆盖了三条主线:

  1. 语义定位:bytes32是 Sway/FuelVM 中表示哈希的定长 256 位(32 字节)值,在 SDK 中以 32 字节的Bytes(Uint8Array | number[])形态操作;
  2. 生成:randomBytes(32)一键生成安全的随机 32 字节,浏览器走 Web Crypto、Node 走内置crypto,均由 packages/crypto 统一封装;
  3. 互转:hexlify(字节 →0x小写 hex 字符串)与arrayify(hex 字符串 →Uint8Array,带格式校验与FuelError抛错)构成完整的双向通道,实现代码可分别在 hexlify.ts 与 arrayify.ts 查阅。

若想深入了解与 32 字节值打交道的相邻类型,推荐继续阅读同目录下的 B256 文档、bytes.md(动态字节数组)以及 address.md(基于 256 位值的地址抽象)。将这些文档对照 SDK 源码阅读,即可在编码、序列化与哈希处理的全链条上做到心中有数。

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

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

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

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

立即咨询