Safe 交易哈希计算器
在 Ledger 或 Trezor 上签署 Safe 交易时,设备显示的是哈希,而不是交易本身。输入交易(逐个字段填写,或使用 Safe Transaction Service 的 JSON),然后将这里计算出的哈希与屏幕上的哈希比对。如果两者不同,你签署的就不是你看到的那笔交易。
哈希计算、解码和风险检查都在当前浏览器中运行。只有当你点击“在链上检查”时,Safe 的地址和交易的每个字段(包括 calldata)才会发送到你所选链的公共 RPC 节点(列在按钮旁边)。
Owners sign a hash, not a transaction
A Safe (formerly Gnosis Safe) is a smart-contract account that executes a transaction once enough owners have signed it. Owners do not sign the transaction itself: they sign its EIP-712 hash, the safeTxHash, computed from
- a domain: the Safe's own address and, since version 1.3.0, the chain id;
- a message: the
SafeTxstruct —to,value,data,operation(CALL or DELEGATECALL), the gas fieldssafeTxGas,baseGasandgasPrice,gasToken,refundReceiverand the Safe'snonce.
safeTxHash = keccak256(0x19 0x01 ‖ domain hash ‖ message hash), exactly as in the Safe contracts' getTransactionHash (Safe documentation).
When the owner signs with a Ledger or a Trezor, the device cannot display a whole transaction: it shows the domain hash and the message hash (or the safeTxHash). That is the moment to check. A compromised web interface can show you one transaction and ask your device to sign another — the signing interface of a large exchange's Safe was manipulated this way in February 2025, and the owners approved a transaction that handed control of the Safe to the attacker. The only defence is to compute the hashes independently and compare them with the device, character for character.
Why the version matters
The hashed types changed twice, so the same fields give different hashes on different Safes:
- 0.1.0 names the gas field
dataGasand has no chain id in the domain; - 1.0.0 – 1.2.0 call it
baseGas, still without the chain id — a signature for such a Safe is valid on every chain where a Safe with the same address exists; - 1.3.0 and later (including the L2 builds) add the chain id to the domain.
Pick the version shown in your Safe's settings. When you paste a hash to compare and it does not match, the calculator tries every version and every listed chain and tells you which one would reproduce it — usually a wrong version or chain, sometimes a different transaction.
Transactions that need a second look
The calculator decodes what the transaction does and flags what can cost the Safe its funds:
- DELEGATECALL to anything but an official Safe library: the target's code runs with the Safe's storage, so it can replace the owners or move every asset. Batches use DELEGATECALL to the official MultiSend contracts, and their content is decoded transaction by transaction.
- Configuration changes: adding, removing or swapping owners, a threshold of one, enabling a module (which can then move funds without any signature), setting a guard or a fallback handler that is not an official one, changing the implementation contract.
- Gas refunds: with a non-zero
gasPrice, the Safe pays the executor; a high value drains the Safe through refunds. - Signatures: owner signatures are decoded the way the Safe reads them — ECDSA,
eth_sign, approved hashes and contract signatures — and the recovered owners are listed.
Everything else in the calldata is shown but not interpreted: decode a call to an unknown contract with its ABI before signing. The EIP-712 inspector explains typed-data signatures in general.
Asking the Safe itself
"Check on chain" reads the Safe's version, nonce, owners, threshold and domain separator from the chain you picked, recomputes the hashes with the version the contract reports and calls getTransactionHash — the hash execTransaction will verify. It also tells you whether the nonce was already used, is next, or waits behind other transactions, and whether each signer is a current owner.
What stays in your browser
Hashing, decoding, the risk checks and signature recovery run in this page. Seed phrases and private keys are refused before anything is computed. The only request the page can make is the on-chain check, when you press its button: it sends the Safe's address and every field of the transaction, calldata included, as read-only calls to a public RPC node of the chain you picked, named next to the button.