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。它的处理逻辑很直观:
- 首先调用
arrayify将入参统一归一化为Uint8Array(因此它不仅能处理字节数组,也能接收已是合法 hex 字符串的输入)。 - 以
'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,本文覆盖了三条主线:
- 语义定位:
bytes32是 Sway/FuelVM 中表示哈希的定长 256 位(32 字节)值,在 SDK 中以 32 字节的Bytes(Uint8Array | number[])形态操作; - 生成:
randomBytes(32)一键生成安全的随机 32 字节,浏览器走 Web Crypto、Node 走内置crypto,均由 packages/crypto 统一封装; - 互转:
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),仅供参考