Node.js Keccak-256은(는) 무엇을 하나요?
이더리움은 NIST 표준 SHA3가 아닌 Keccak-256을 사용합니다. Node의 crypto.createHash('sha3-256')으로는 올바른 해시를 얻을 수 없습니다.
사용 시기
- 이더리움 함수 셀렉터 또는 이벤트 토픽 계산
- JS/TS에서 EIP-712, 서명, Merkle, 스토리지 슬롯 헬퍼 구축
- Node crypto를 사용하여 이더리움 데이터를 직접 해싱하는 코드 검토
작동 방식
두 알고리즘은 동일한 입력에 대해 다른 출력을 생성하며, 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
규칙
이더리움 컨텍스트에서는 crypto.createHash('sha3-256')을 절대 사용하지 마십시오. ethers, viem, web3 또는 다른 명시적인 Keccak 구현체의 Keccak 인식 헬퍼를 사용하세요.