Node.js Keccak-256
Ethereum utilise Keccak-256, et non la variante SHA3 standardisée par le NIST exposée par crypto.createHash('sha3-256') de Node.
Quand l'utiliser
- Calcul de sélecteurs de fonctions ou de sujets d'événements Ethereum
- Construction d'helpers EIP-712, de signatures, de Merkle ou d'emplacements de stockage en JS/TS
- Révision de tout code qui hache des données Ethereum directement avec Node crypto
Comment ça fonctionne
Les deux algorithmes produisent des sorties différentes pour la même entrée, et Node ne vous avertira pas.
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
Exemples
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' },
);
Motifs courants
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]),
);
}
Adresse à partir de la clé publique
import { keccak256 } from 'ethers';
function pubkeyToAddress(pubkeyBytes: Uint8Array): string {
const hash = keccak256(pubkeyBytes.slice(1));
return '0x' + hash.slice(-40);
}
Auditez votre codebase
grep -rn "createHash.*sha3" --include="*.ts" --include="*.js" --exclude-dir=node_modules .
grep -rn "keccak256" --include="*.ts" --include="*.js" . | grep -v node_modules
Règle
Pour les contextes Ethereum, n'utilisez jamais crypto.createHash('sha3-256'). Utilisez des helpers compatibles avec Keccak provenant de ethers, viem, web3, ou toute autre implémentation explicite de Keccak.