如何解码从Etherscan获取的Arbitrum L1批量交易数据?
解码Arbitrum L1批量数据的问题与解决方案
我正尝试解码从Etherscan获取的Arbitrum L1批量数据,使用ethers.js将十六进制数据转为Uint8Array后,用Node.js的Brotli库解压时遇到错误。
代码片段
const ethers = require('ethers'); const brotli = require('brotli'); let data = '0x...'; // 从Etherscan获取的十六进制字符串(Input Data下bytes中的`data`) let bytesData = ethers.getBytes(data); let decompressedData = brotli.decompress(bytesData);
错误信息
Error: [ReadHuffmanCodeLengths] space = -1024
1. 正确转换数据用于Brotli解压
- 确认从Etherscan获取的
data字段是否为纯Brotli压缩数据:Arbitrum批量数据的data字段可能包含版本标识、元数据等前缀,直接解压整个字节数组会导致格式错误,需先剥离前缀,仅保留真正的压缩数据段。 - 优先用Buffer传递数据:部分Brotli库对Buffer的兼容性优于Uint8Array,可修改转换逻辑:
const bytesData = ethers.getBytes(data); const decompressedData = brotli.decompress(Buffer.from(bytesData)); - 校验数据完整性:确保十六进制字符串无截断、无多余字符,
0x前缀可由ethers.js自动处理。
2. Arbitrum批量数据格式细节
- Arbitrum的L1批量提交交易(如
submitBatch)输入数据包含多段结构:版本号、批量元数据(链ID、批次号等)、压缩交易数据。 - 压缩交易数据是Brotli流,但需先跳过前面的元数据字段。可通过ethers.js的
AbiCoder解码输入,分离出压缩部分:const abiCoder = new ethers.AbiCoder(); // 按submitBatch的ABI结构解码,提取bytes类型的压缩数据字段 const decodedInput = abiCoder.decode(['bytes'], data); // decodedInput[0]为包含压缩数据的字节数组,可能还需进一步剥离内部前缀 - 不同版本的Arbitrum批量数据前缀长度可能不同,需参考官方规范确认偏移量。
3. 解决Node.js中的解压错误
[ReadHuffmanCodeLengths] space = -1024错误本质是传入的非有效Brotli流,可能是数据包含前缀、截断或格式不匹配。- 更换内置库尝试:Node.js内置的
zlib模块原生支持Brotli,兼容性更稳定:const zlib = require('zlib'); const bytesData = ethers.getBytes(data); // 异步版本 zlib.brotliDecompress(bytesData, (err, result) => { if (err) throw err; console.log(result); }); // 同步版本 const decompressedData = zlib.brotliDecompressSync(bytesData); - 剥离数据前缀:若数据开头有非Brotli标识字节(如版本号),可通过
bytesData.slice(n)跳过前n个字节后再解压。
内容的提问来源于stack exchange,提问作者adrianmcli
相关产品推荐
相关产品推荐

