ChainFlow SaaS — Referencia de hashing correcto · Web3 / TypeScript
crypto.createHash('sha3-256') produce NIST SHA3-256, no Keccak-256. Ethereum usa Keccak-256. Los selectores de función, topics de eventos y derivaciones de dirección son todos incorrectos sin ningún error en tiempo de ejecución.
import crypto from 'crypto'; // ⚠️ Esto NO es Keccak-256 const nistHash = crypto .createHash('sha3-256') .update('hello') .digest('hex'); // Resultado NIST SHA3: // 3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392
import { keccak256, toUtf8Bytes } from 'ethers'; // ✅ Keccak-256 real const keccakHash = keccak256( toUtf8Bytes('hello') ).slice(2); // Resultado Keccak-256: // 1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
import { keccak256, toUtf8Bytes, solidityPackedKeccak256, id } from 'ethers'; // Hash de bytes crudos const h1 = keccak256( new Uint8Array([0x01, 0x02]) ); // Hash de string UTF-8 const h2 = keccak256(toUtf8Bytes('hello')); // Topic de evento on-chain const topic = id( 'Transfer(address,address,uint256)' ); // 0xddf252ad1be2c89b69c2b068fc378daa9... // ABI-encoded packed hash const packed = solidityPackedKeccak256( ['address', 'uint256'], ['0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c', 100n] );
import { keccak256, toBytes } from 'viem'; // Hash de bytes const hash = keccak256( toBytes('hello') ); // 0x1c8aff950685c2ed4bc3174... // Hash de hex directo const hash2 = keccak256('0x68656c6c6f'); // Resultado idéntico a ethers v6 // para el mismo input
// import Web3 from 'web3'; // const web3 = new Web3(); const hash = web3.utils.keccak256('hello'); const packed = web3.utils.soliditySha3( { type: 'address', value: '0x742d35Cc663...' }, { type: 'uint256', value: '100' } );
import { id, keccak256, AbiCoder } from 'ethers'; // Selector de función (primeros 4 bytes) const selector = id( 'transfer(address,uint256)' ).slice(0, 10); // 0xa9059cbb // TypeHash para EIP-712 const typeHash = keccak256( toUtf8Bytes( 'Transfer(address from,address to,uint256 value)' ) ); // Slot de mapping en storage function getMappingSlot( key: string, slot: number ): string { return keccak256( AbiCoder.defaultAbiCoder().encode( ['address', 'uint256'], [key, slot] ) ); }
import { keccak256 } from 'ethers'; /** * Deriva una dirección Ethereum (EIP-55) desde una clave pública sin comprimir (65 bytes). * La clave pública sin comprimir tiene formato: 0x04 || X (32 bytes) || Y (32 bytes) * Se descarta el prefijo 0x04, se hashea el resto con Keccak-256 * y la dirección son los últimos 20 bytes (40 hex chars). */ function pubkeyToAddress(pubkeyBytes: Uint8Array): string { // Elimina el prefijo de punto no comprimido (0x04) const hash = keccak256(pubkeyBytes.slice(1)); return '0x' + hash.slice(-40); } // Ejemplo con clave pública ficticia de ChainFlow const pubkey = new Uint8Array(65); pubkey[0] = 0x04; // ... (rellena X e Y con los 64 bytes reales) const addr = pubkeyToAddress(pubkey); // → '0x742d35Cc6634C0532925a3b8D4C9B569890FaC1c'
Se encontraron 3 ocurrencias de createHash('sha3-256') en src/utils/crypto.ts, src/contracts/events.ts y src/auth/wallet.ts. Todas deben migrar a keccak256 de ethers v6.
En cualquier contexto de Ethereum, nunca uses crypto.createHash('sha3-256'). Usa siempre los helpers conscientes de Keccak de ethers, viem, web3.js u otra implementación explícita de Keccak-256. El error es silencioso: el código compilará y ejecutará sin excepción pero producirá hashes incorrectos, rompiendo selectores, topics de eventos, EIP-712, Merkle trees y derivación de direcciones.