affaan-m/ecc1 file

Nodejs Keccak256

JavaScriptとTypeScriptにおけるEthereumハッシュバグを防ぐ。NodeのSHA3-256はNIST SHA3であり、Ethereum Keccak-256ではなく、セレクター、署名、ストレージスロット、アドレス導出を静かに破壊する。

Specification
Skill ID
affaan-m/ecc/nodejs-keccak256
Publisher
affaan-m
Repository
ecc
Installs
0
Files
1
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

affaan-m/ecc/nodejs-keccak256Installs these files
  • SKILL.md

What this skill tells the agent

Node.js Keccak-256

EthereumはKeccak-256を使用し、Nodeのcrypto.createHash('sha3-256')が公開するNIST標準化SHA3バリアントではない。

使用するタイミング

  • Ethereum関数セレクターやイベントトピックの計算
  • JS/TSでEIP-712、署名、Merkle、またはストレージスロットヘルパーの構築
  • Nodeのcryptoを直接使用してEthereumデータをハッシュするコードのレビュー

仕組み

2つのアルゴリズムは同じ入力に対して異なる出力を生成し、Nodeは警告しない。

import crypto from 'crypto';
import { keccak256, toUtf8Bytes } from 'ethers';

const data = 'hello';
const nistSha3 = crypto.createHash('sha3-256').update(data).digest('hex');
const keccak = keccak256(toUtf8Bytes(data)).slice(2);

console.log(nistSha3 === keccak); // false

例

ethers v6

import { keccak256, toUtf8Bytes, solidityPackedKeccak256, id } from 'ethers';

const hash = keccak256(new Uint8Array([0x01, 0x02]));
const hash2 = keccak256(toUtf8Bytes('hello'));
const topic = id('Transfer(address,address,uint256)');
const packed = solidityPackedKeccak256(
  ['address', 'uint256'],
  ['0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c', 100n],
);

viem

import { keccak256, toBytes } from 'viem';

const hash = keccak256(toBytes('hello'));

web3.js

const hash = web3.utils.keccak256('hello');
const packed = web3.utils.soliditySha3(
  { type: 'address', value: '0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c' },
  { type: 'uint256', value: '100' },
);

一般的なパターン

import { id, keccak256, AbiCoder } from 'ethers';

const selector = id('transfer(address,uint256)').slice(0, 10);
const typeHash = keccak256(toUtf8Bytes('Transfer(address from,address to,uint256 value)'));

function getMappingSlot(key: string, mappingSlot: number): string {
  return keccak256(
    AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [key, mappingSlot]),
  );
}

公開鍵からアドレス

import { keccak256 } from 'ethers';

function pubkeyToAddress(pubkeyBytes: Uint8Array): string {
  const hash = keccak256(pubkeyBytes.slice(1));
  return '0x' + hash.slice(-40);
}

コードベースの監査

grep -rn "createHash.*sha3" --include="*.ts" --include="*.js" --exclude-dir=node_modules .
grep -rn "keccak256" --include="*.ts" --include="*.js" . | grep -v node_modules

ルール

Ethereumコンテキストでは、crypto.createHash('sha3-256')を絶対に使用しない。ethers、viem、web3、または別の明示的なKeccak実装のKeccak対応ヘルパーを使用すること。

Use this skill in a project

Open any RiverX project, search the Skills panel for affaan-m/ecc/nodejs-keccak256, and install it in one click.

Use this skill