| name | keccak256-hash-patterns |
| description | Keccak256 and ethers.js cryptographic utilities for hash-chain integrity. keccak256 of log entries, ABI encoding, hex data manipulation, event topic hashing, and Ethereum-compatible hash structures. Sources: ethers-io/ethers.js. |
/keccak256-hash-patterns
When to Use
- Hash audit log entries with keccak256 for Ethereum-compatible hash-chain
- ABI-encode structured data before hashing (type-safe encoding)
- Compute event topic hashes for on-chain log verification
- Generate deterministic IDs from structured agent action data
Do NOT use for
- Non-Ethereum contexts — prefer SHA-256 (standard, no dependency)
- Large data hashing — keccak256 is designed for 32-byte outputs
keccak256 of log entries
import { ethers } from 'ethers'
function hashLogEntry(entry: object): string {
const json = JSON.stringify(entry, Object.keys(entry).sort())
return ethers.keccak256(ethers.toUtf8Bytes(json))
}
function buildHashChain(entries: object[]): string[] {
const chain: string[] = []
let prev = '0x' + '0'.repeat(64)
for (const entry of entries) {
const current = hashLogEntry(entry)
const linked = ethers.keccak256(
ethers.concat([
ethers.getBytes(prev),
ethers.getBytes(current),
])
)
chain.push(linked)
prev = linked
}
return chain
}
ABI encoding for structured hashing
import { ethers } from 'ethers'
function hashAgentAction(action: {
agentId: string
command: string
timestamp: number
nonce: number
}): string {
const encoded = ethers.AbiCoder.defaultAbiCoder().encode(
['string', 'string', 'uint256', 'uint256'],
[action.agentId, action.command, action.timestamp, action.nonce]
)
return ethers.keccak256(encoded)
}
Event topic hash (EVM-compatible)
const eventSig = 'AgentCommandExecuted(address,string,uint256)'
const topic0 = ethers.id(eventSig)
console.log('topic0:', topic0)
Verify hash chain integrity
function verifyHashChain(entries: object[], storedChain: string[]): boolean {
if (entries.length !== storedChain.length) return false
const recomputed = buildHashChain(entries)
return recomputed.every((h, i) => h === storedChain[i])
}
Hex utilities
const padded = ethers.zeroPadValue(ethers.toBeHex(12345), 32)
const bytes = ethers.getBytes('0xdeadbeef')
const hex = ethers.hexlify(Buffer.from('hello'))
const combined = ethers.concat([bytes1, bytes2])
Anti-Fake-Pass Checklist
❌ JSON.stringify without sorted keys → same object, different hash (non-deterministic)
❌ keccak256 of undefined → ethers throws, crashes hash chain build
❌ ethers.id() vs ethers.keccak256(toUtf8Bytes()) — same result, but id() is cleaner
❌ ABI encode types not matching data — silently pads/truncates numbers
❌ ethers v5 vs v6 API differ significantly — check version (v6: ethers.keccak256, not utils.keccak256)
❌ Chain broken at index N → all subsequent hashes wrong (must restart from last valid checkpoint)