You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算Arweave存储文件的Keccak哈希及本地文件适配问题

计算文件Keccak哈希的正确实现(跨Arweave/本地/IPFS)

原代码的核心问题

  • 流处理不完整:blob.stream().getReader().read()只读取了文件的第一块数据,未遍历读取全部内容,导致哈希基于不完整字节,结果完全错误。
  • Blob转字节的方式冗余,Node.js环境下直接处理ArrayBuffer更高效可靠。

修正后的远程文件(Arweave/IPFS)哈希计算代码

以下代码可正确读取完整文件字节并计算Keccak哈希,保证结果可复现:

import { ethers } from "ethers";

async function calculateRemoteFileKeccak(imageUrl: string): Promise<string> {
    // 获取完整响应流并转换为ArrayBuffer
    const response = await fetch(imageUrl);
    if (!response.ok) throw new Error(`请求失败: ${response.status}`);
    
    // 读取完整的原始字节
    const arrayBuffer = await response.arrayBuffer();
    const rawBytes = new Uint8Array(arrayBuffer);
    
    // 使用ethers计算Solidity兼容的Keccak256哈希,"bytes"类型参数完全正确
    const hash = ethers.utils.solidityKeccak256(["bytes"], [rawBytes]);
    return hash;
}

本地文件哈希计算代码

使用Node.js的fs模块读取本地文件,逻辑与远程保持一致,确保哈希结果相同:

import { ethers } from "ethers";
import { readFile } from "fs/promises";

async function calculateLocalFileKeccak(filePath: string): Promise<string> {
    // 读取本地文件原始字节(默认Buffer类型,可直接转换为Uint8Array)
    const fileBuffer = await readFile(filePath);
    const rawBytes = new Uint8Array(fileBuffer);
    
    // 复用相同的哈希计算逻辑
    const hash = ethers.utils.solidityKeccak256(["bytes"], [rawBytes]);
    return hash;
}

跨存储哈希一致的关键要点

  • 必须读取完整的原始文件字节:无论文件存储在Arweave、IPFS还是本地,都不能对内容做任何修改(如格式转换、压缩、编码调整)。
  • 统一字节处理方式:始终将文件内容转换为Uint8Array(或Node.js的Buffer,两者可互相转换)作为哈希输入,避免编码差异。
  • 固定哈希计算逻辑:坚持使用ethers.utils.solidityKeccak256(["bytes"], [rawBytes]),该方法完全对齐Solidity中keccak256(bytes)的计算逻辑,确保链上链下结果一致。

内容的提问来源于stack exchange,提问作者GGizmos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:00:34