什么是 Keccak-256?
Keccak-256 是以太坊随处使用的 256 位海绵结构哈希函数:地址是公钥 Keccak-256 哈希的最后 20 字节,函数选择器是规范签名 Keccak-256 哈希的前 4 字节,事件主题、EIP-55 校验和以及存储槽也都由它派生。它是最初提交的 Keccak 版本,与 NIST 最终定稿的 SHA3-256 仅在填充字节上不同,因此同一输入会得到不同的摘要。
典型用途
- 函数选择器:将
transfer(address,uint256)作为文本哈希并取前 4 字节:0xa9059cbb。选择器工具可一次处理多条签名,并自动规范化 Solidity 声明。 - 事件主题:
Transfer(address,address,uint256)的完整 Keccak-256 哈希就是每条 ERC-20 转账日志的 topic[0]。 - 由公钥推导地址:将 64 字节的非压缩公钥(去掉 0x04 前缀)按十六进制哈希,取最后 20 字节。
- mapping 存储槽:将
abi.encode(key, slot)按十六进制字节哈希,即可找到mapping(address => uint)条目所在的位置。 - 承诺-揭示与内容哈希:对任意文本或以十六进制表示的文件进行哈希。
测试向量
| 输入 | Keccak-256 |
|---|---|
| (空) | 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 |
abc | 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45 |
Transfer(address,address,uint256) | 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef |
在依赖本实现之前,可以粘贴以上任意一条来验证结果。
Keccak-256、SHA3-256 与 SHA-256 的区别
| 函数 | 家族 | 填充 / 结构 | 使用方 |
|---|---|---|---|
| Keccak-256 | Keccak 海绵结构,速率 1088 位 | pad10*1,域分隔字节 0x01 | 以太坊、Tron(TVM)、所有 EVM 链 |
| SHA3-256 | Keccak 海绵结构,速率 1088 位 | pad10*1,域分隔字节 0x06(FIPS 202) | NIST 应用、部分非 EVM 链 |
| SHA-256 | Merkle–Damgård(SHA-2) | 长度填充,512 位分组 | 比特币、Tron txID、TLS、Base58Check |
举例:在 FIPS 202 库中对 abc 计算 SHA3-256 得到 0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532,而同样三个字节的 Keccak-256 则是上表中的 0x4e03657a…。如果合约或区块浏览器中的值与你的库不一致,首先应检查填充字节。