Intermediate level
A wallet prompt is either a transaction, which acts on the chain as soon as it lands and costs a fee, or a message, which is free and does nothing until someone submits or checks it. Both can move your tokens. For any request, find who gets power (the spender or contract), over what (which token, how much), for how long (the deadline) and on which chain. If you cannot read it, and your hardware wallet cannot show it, the answer is no.
Two kinds of request: transactions and messages
Every wallet prompt is one of two things, and the difference decides how you should read it.
| Property | Transaction | Message (offchain signature) |
|---|---|---|
| What it is | An instruction to the chain, sent by you | A signed statement, handed to whoever asked for it |
| Costs a fee | Yes, you pay gas | No, signing is free |
| When it takes effect | When it lands in a block, seconds later | Whenever someone submits or checks it, possibly days later |
| Who submits it | You | The site, a relayer, or anyone holding the signature |
| Can it move tokens | Yes, directly | Yes, if it is a permit, an order or a similar authorization |
The dangerous misconception is that a free signature is a harmless one. Signing is free because nothing happens yet. What happens later depends on what the message says, and a message that says "this spender may take 50,000 USDC before Friday" is as good as a transaction to whoever holds it. The beginner guide to how transactions work covers the transaction side; this guide is mostly about everything else.
Plain messages: personal_sign and EIP-191
The simplest message is readable text. When a site asks you to sign in, prove you own an address or accept its
terms, the wallet uses a method called personal_sign, defined by
EIP-191. Before signing, the
wallet puts \x19Ethereum Signed Message:\n and the message length in front of your text. That
prefix exists so a signed message can never be replayed as a valid transaction.
Sign in with Ethereum (ERC-4361) is the standard form of this. A well formed login message names the website domain, your address, the chain ID, a random nonce and the time it was issued. Check that the domain in the text matches the site in your address bar. A login message for a different domain means the page you are on is relaying someone else’s request.
The old, dangerous cousin is eth_sign, which signs a raw 32 byte hash with no prefix. That hash
could be anything, including the hash of a transaction, and no wallet can show you what it means. MetaMask disabled
it by default in 2023 and later accepted a proposal to remove it entirely. If any wallet ever asks you to sign a
bare hex hash with no explanation, reject it.
Typed data: EIP-712, field by field
Permissions are usually signed as structured data under
EIP-712, through the method
eth_signTypedData_v4. Instead of a blob of text, the wallet receives named fields, so it can show them
to you and you can read them. This is roughly what a token permit request looks like underneath, with placeholder
addresses (the full request also carries a types section defining each field):
{
"domain": {
"name": "Example USD",
"version": "1",
"chainId": 1,
"verifyingContract": "0xTokenContract"
},
"primaryType": "Permit",
"message": {
"owner": "0xYourAddress",
"spender": "0xSpenderAddress",
"value": "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"nonce": 0,
"deadline": 1790812800
}
}Read it in two parts.
The domain: who verifies it, and where
- name and version identify the token or protocol that will check the signature.
- chainId is the network it is valid on. EIP-712 tells wallets to refuse a request whose chain does not match the one you are connected to.
- verifyingContract is the contract that will accept the signature. For a permit it is the token itself. Check that it is the real token address, not a lookalike.
The message: what you are granting
- primaryType names the action.
Permit,PermitSingle,PermitBatch,PermitTransferFromand marketplace order types all grant rights over your assets. - spender is who gets the power. If you cannot match it to the protocol you meant to use, stop.
- value is in the token’s smallest units. A token with 6 decimals, such as USDC, writes 1,000 tokens as
1000000000. The 78 digit number in the example is 2256 − 1, the largest value the field can hold, which means unlimited. - deadline is a Unix timestamp.
1790812800is October 1, 2026 at 00:00 UTC. A deadline years away is a long lived permission. - nonce makes each signature usable once. EIP-712 itself includes no replay protection; the token contract supplies it with this counter.
Approvals, permits and Permit2
Tokens on EVM chains cannot be pulled from your wallet unless you have granted permission. There are several ways to grant it, and the ones that catch people out are those that outlive the moment you signed.
| Mechanism | How you grant it | What it allows | How long it lasts |
|---|---|---|---|
approve | Transaction | A spender may move up to an amount of one token | Until revoked or used up |
increaseAllowance | Transaction | The same, adding to an existing allowance | Until revoked or used up |
setApprovalForAll | Transaction | An operator may move every NFT you hold in a collection, now and later | Until revoked |
ERC-2612 permit | Signature, submitted by someone else | Creates an allowance for one token, like approve | The signature expires at its deadline; the allowance it creates lasts until revoked |
| Permit2 allowance | One approval to the Permit2 contract, then signatures | A spender may move up to an amount through Permit2 | Until its own expiration |
| Permit2 signature transfer | Signature | One specific transfer | Single use, before its deadline |
increaseAllowance deserves a special mention. It was never part of the ERC-20 standard, and
OpenZeppelin removed it from its standard token code in version 5, partly because it widens the room for phishing:
people did not always recognize it as an approval. Many older tokens still have it. Read it exactly as you would
read approve.
ERC-2612 permits and Uniswap’s Permit2, introduced in November 2022, exist for good reasons. They save a transaction, and Permit2 adds expiring allowances and revoking many at once, a real improvement on unlimited approvals that last forever. The cost is that the permission is now an offchain signature, and the ERC-2612 specification itself notes that another party can always submit a permit before the intended one. The site you gave it to, or a drainer pretending to be that site, can use it whenever it likes before the deadline, and the tokens move in a transaction you never see a prompt for.
NFT marketplaces work the same way. A listing is a signed order, and a signature that lists your NFTs at a near zero price lets whoever holds it buy them at that price.
What simulation shows, and what it cannot
Most modern wallets simulate a transaction before you sign it: they run it against the current state of the chain and show the result as balance changes. MetaMask introduced its version, called estimated balance changes, in July 2024, and its documentation notes that the simulation runs on MetaMask servers, which therefore see the transaction and your IP address. Other wallets and security extensions do similar things.
Simulation is excellent at catching a transaction that sends your tokens somewhere unexpected. It has three blind spots:
- Messages have nothing to simulate. A permit changes no balance when you sign it. The loss arrives later, in somebody else’s transaction.
- Permissions are not balance changes. An approval, or a change in who controls an account, moves nothing today. In a case SlowMist published in December 2025, a Solana user signed a transaction that reassigned control of their account. The wallet showed no balance change, and more than $3 million was taken afterward.
- The real block can differ. A simulation is a prediction against the state at that moment. What a contract does can depend on state that changes between the preview and the block your transaction lands in.
Treat a clean simulation as necessary, never as sufficient. Read the permission itself, and take any security warning the wallet raises seriously. The drainers guide shows the lures these requests usually arrive with.
Blind signing and clear signing on a hardware wallet
A hardware wallet protects the key, and its screen is the one display that malware on your computer cannot rewrite. That only helps if the screen shows something you can read.
Blind signing means approving data the device cannot decode, usually shown as a hash or raw bytes. Ledger’s Ethereum app, for example, refuses such requests until you switch on a blind signing setting. Clear signing means the device decodes the request and shows the action in plain terms: the token, the amount, the recipient or spender. ERC-7730, a draft standard first proposed in February 2024, defines a shared format that lets wallets and hardware devices display contract calls and typed data this way.
Clear signing
The device shows what the action does
- Token, amount and recipient or spender in readable form
- A compromised computer cannot change what the device displays
- You can compare it with what you meant to do
Blind signing
The device shows a hash
- You are trusting the computer screen, the one malware can change
- A swapped transaction looks identical to the real one
- Leaving the setting on lets the next request use it too
The Bybit theft of February 2025 is the lesson at full scale. Attackers planted code in the web interface Bybit’s signers used. It showed a routine transfer while the data actually passed for signing replaced the wallet’s contract logic, and the signers approved what their screens showed. When the device cannot show you the real action, the real action is whatever the attacker says it is. The Bybit case study has the full sequence.
Solana: many instructions, one signature
A Solana transaction is a list of instructions that execute together: all of them succeed or none do. A routine swap commonly bundles several, such as setting the compute budget and priority fee, creating a token account for what you receive, the swap itself through one or more pools, and closing a temporary account. That is normal, and it is why you cannot judge a Solana request by its first line.
It also means a malicious instruction can ride along with legitimate ones. The dangerous ones change control rather than balances: approving a delegate on a token account, handing a token account’s authority to another address, or reassigning ownership of an account, as in the SlowMist case above. Solana wallets preview a transaction by simulating it and showing expected balance changes, with warnings when they spot something risky, so read the warnings as carefully as the numbers.
Timing is different too. A normal Solana transaction carries a recent blockhash and expires after about 150 slots, roughly a minute. A transaction built on a durable nonce does not expire that way: it can be signed now and submitted much later. That is useful for legitimate offline signing, and it means a signature you gave today can land long after you closed the tab, the same property that makes EVM permits risky.
A checklist for any signature request
Where did it come from?
You typed the URL or used a bookmark, and the site in the address bar is the one you meant. A request that started from a link in a message, an ad or a token that appeared in your wallet begins with a strike against it.
Is it a transaction or a message?
A transaction acts now. A message may act later, submitted by someone else. Messages that name a spender, an amount or an order deserve more care, not less.
Who gets power?
Find the spender, operator, delegate or recipient, and the verifying contract. If you cannot match them to the protocol you intended, stop.
How much, and for how long?
Convert the amount to human units and check whether it is unlimited. Check the deadline or expiry. Prefer exact amounts and short deadlines.
Which chain?
The chain ID should match the network you are on. A request for a different chain is a reason to pause.
Does the device agree?
On a hardware wallet, the screen should show the same action in readable form. A hash where you expected a transfer is a stop sign.
Can you say it in one sentence?
"This lets the DEX router I chose take up to 500 USDC until tomorrow." If you cannot finish a sentence like that, reject the request. Nothing onchain is so urgent that it cannot wait until you understand it.
Afterward, clean up. Permissions you no longer need should be revoked, which the token approvals guide walks through, and the phishing simulator is a safe place to practice spotting bad requests.
Common questions
Is signing a message free and safe?
Free, yes. Safe depends on the content. A plain login message that names the site you are on and grants nothing is low risk. A typed data message that names a spender, an amount or an order is a permission over your assets, and whoever holds it can use it without asking you again.
Can I cancel a permit I already signed?
Not by deleting it, because the signature exists wherever you sent it. It stops working when its deadline passes or its nonce is used by another permit. Once it has been used, it is an ordinary allowance, which you revoke by setting the approval to zero. Permit2 allowances are revoked through Permit2 itself, which can revoke many at once. A short deadline is the simplest protection, because an expired signature is worthless.
What is the difference between personal_sign and signTypedData?
personal_sign signs readable text with a fixed prefix, and is used for logins and proofs of ownership. eth_signTypedData_v4 signs EIP-712 structured data with named fields and a domain that binds it to one contract and one chain. Typed data is easier to read and is what permits and orders use, so it is also where most signature phishing happens.
Why does my hardware wallet ask me to enable blind signing?
Because it cannot decode the request, so it cannot show you what it does. Some legitimate protocols still need it. If you enable it, do so for one specific action you have verified another way, then switch it off again. Never enable it because a site or a support message tells you to.
Why does a simple Solana swap contain so many instructions?
A Solana transaction bundles every step into one atomic package: compute budget settings, creating token accounts, the swap through one or more pools, and cleanup. Several instructions are normal. What matters is whether any of them change who controls your accounts or tokens, which is what the wallet preview and its warnings help you spot.
Where to go next
Next: Smart accounts, passkeys and gasless transactions
Guide 3 of 16 in the Intermediate level. Your place is kept on this device, so you can pick up exactly here next time.