Node.js Keccak-256
Ethereum utilise Keccak-256, pas la variante SHA3 normalisée par le NIST exposée par crypto.createHash('sha3-256') de Node.
Quand l'utiliser
- Calculer des sélecteurs de fonctions ou des sujets d'événements Ethereum
- Construire des helpers EIP-712, de signature, Merkle ou de slots de stockage en JS/TS
- Relire tout code qui hache des données Ethereum directement avec la crypto de Node
Comment ça marche
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' },
);
Patterns 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);
}
Auditer votre base de code
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 des contextes Ethereum, n'utilisez jamais crypto.createHash('sha3-256'). Utilisez des helpers compatibles Keccak provenant de ethers, viem, web3 ou d'une autre implémentation explicite de Keccak.