Check a Transaction Before You Sign It
Learn to read a signature request, verify a contract address, and understand approvals and permits before you sign. Essential security steps for crypto users.
Every time you sign a transaction, you are authorizing a change to the blockchain. That change might be exactly what you intend, or it might be something else entirely. The difference is in the details of the request. This page explains what those details mean, how to verify a contract address, and how to spot a malicious request before you sign.
What a Signature Request Actually Is
When you use a wallet like MetaMask, Ledger, or Phantom, you see a popup asking you to confirm a transaction. That popup is a request to sign a piece of data. The data is a set of instructions that the blockchain will execute. Your signature proves you authorized those instructions.
The request typically shows:
- The contract address – the smart contract that will execute the transaction.
- The function – what the contract will do (e.g., transfer, approve, swap).
- The parameters – the inputs to the function (e.g., recipient, amount).
A malicious request might look similar to a legitimate one, but it might be asking the contract to do something different, like approve a large allowance or transfer your tokens to an attacker.
How to Verify a Smart Contract Address
The first step is to check the contract address. This is the unique identifier of the smart contract. You can verify it using a block explorer like Etherscan, BscScan, or Solscan.
- Copy the contract address from the signature request.
- Go to a block explorer for the network you are using.
- Paste the address into the search bar and press Enter.
- Check the contract details:
- Is the contract verified? (Look for a checkmark or “Verified” label.)
- Does the contract name match what you expect?
- Does the contract have a high transaction count? A new contract with few transactions is riskier.
What the Block Explorer Shows
A block explorer shows the contract’s source code, transaction history, and metadata. If the contract is verified, you can read its code and see exactly what functions it has. If it is not verified, you cannot see the code, which is a red flag.
However, even a verified contract can be malicious. Some attackers deploy verified contracts with hidden functions. So, verification is not enough.
Read the Transaction Data
Most wallets allow you to view the raw transaction data. This is the actual data that will be sent to the contract. You can decode it to see what function is being called and with what parameters.
Using a Decoder
Tools like Etherscan’s “Decode Input Data” or dedicated decoders like Tenderly can interpret the data. You can paste the hex data into these tools to see the function name and arguments.
For example, a transaction that calls transfer(address to, uint256 amount) will show the recipient address and the amount. An approve(address spender, uint256 amount) will show the spender and the allowance.
If the data is not decodable, it might be calling a function that is not standard, which is a warning sign.
Simulate the Transaction
Simulation tools let you see the outcome of a transaction without actually sending it. They run the transaction in a sandbox and show you the resulting state changes. This is one of the most powerful ways to check a transaction.
Services like Tenderly, Blowfish, and Pocket Universe offer simulation. Some wallets have built-in simulation.
To simulate:
- Copy the transaction data or the raw transaction.
- Paste it into the simulator.
- Run the simulation.
- Review the result: The simulator will show what balances change, what approvals are set, and what the net effect is.
If the simulation shows that your tokens are being sent to an address you don’t recognize, or that an approval is being set for a suspicious spender, do not sign.
Types of Signatures: Transfer, Approval, and Permit
Transfer
A transfer is a direct movement of tokens from your address to another. The function is usually transfer(address to, uint256 amount). When you sign this, you are authorizing the contract to move your tokens. The recipient and amount are clear.
Approval
An approval is a permission you grant to a contract to spend a certain amount of your tokens. The function is approve(address spender, uint256 amount). This is common when you interact with decentralized exchanges or lending protocols. The spender is the contract that will be allowed to move your tokens.
Risk: If you approve a malicious contract, it can spend your tokens at any time up to the approved amount. Some malicious approvals ask for an unlimited amount (a very large number).
Permit
A permit is a signature that allows someone to approve on your behalf without a separate transaction. It is part of EIP-2612. The signature includes a deadline and a nonce. If you sign a permit, you are authorizing a spender to use your tokens, similar to an approval, but the approval is recorded when the spender submits the permit.
Risk: A permit can be used to approve a malicious spender without you knowing, because the permit is not broadcast until later. Always verify the spender address and the amount.
Comparison Table: How to Check a Transaction
| Method | What It Shows | When to Use | When It Does NOT Apply |
|---|---|---|---|
| Block Explorer | Contract address, verification status, transaction history | To check if the contract is known and verified | When the contract is unverified or newly deployed, you cannot assess its code |
| Transaction Data Decoder | Function name and parameters | To see exactly what the contract will do | When the data is not decodable, you cannot know the function |
| Simulation | Predicted state changes, balances, approvals | To see the outcome before signing | When the transaction involves complex logic that the simulator cannot handle, or when the contract is not supported |
| Wallet UI | Basic details like recipient and amount | For simple transfers | When the wallet does not show the full data, or when the request is for a permit that is not yet on-chain |
What People Get Wrong: The Misdiagnosis
A common mistake is to think that a transaction is safe because the contract address is verified on the block explorer. Verification only means the source code is published, not that it is trustworthy. Attackers can deploy verified contracts with malicious functions hidden in plain sight.
Another mistake is to rely solely on the wallet’s display. Wallets often simplify the data, showing only the recipient and amount. For an approval, the wallet might show “Approve” but not the spender or the amount clearly. The wallet might show a contract name that is misleading.
The natural assumption is that if the wallet shows a familiar interface, the transaction is legitimate. But the wallet is just displaying what the request contains. It does not judge the intent.
This is a natural mistake because the user is not a developer and trusts the tools. But the tools are neutral; they only relay information.
Best Practices for Checking a Transaction
- Always check the contract address on a block explorer, even if the wallet shows a known name.
- Use a simulation tool for any transaction that is not a simple transfer.
- Be wary of approvals that request an unlimited amount. Some protocols need a large allowance, but you can often set a custom amount.
- Check the spender address in an approval. It should match the protocol you intend to use.
- Never sign a transaction that you cannot understand. If the data is not decodable, or the simulation fails, do not sign.
- Be cautious with permits. They can be used without your further action, so verify the spender and amount carefully.
What to Do If You Suspect a Malicious Request
If you see a signature request that looks suspicious:
- Do not sign.
- Revoke any existing approvals to the contract if you have previously approved it. You can use tools like Revoke.cash.
- Report the address to a service like Etherscan or a community watchlist.
Commands and Tools
Some tools are command-line based. For example, using cast from Foundry:
cast call <contract_address> "functionName(uint256)" <args> --rpc-url <rpc>
This command calls a function on the contract and returns the result. It does not send a transaction; it is a read-only call. The output shows what the function would return, which can help you understand what the contract does.
Another useful command is cast code:
cast code <contract_address> --rpc-url <rpc>
This retrieves the bytecode of the contract. If the bytecode is empty, the contract does not exist or is not deployed. If it is long, the contract has complex logic.
These commands are for developers and advanced users. For most users, a block explorer and a simulation tool are sufficient.
Checking a transaction before you sign
Checking a transaction before signing is a multi-step process: verify the contract address, decode the transaction data, and simulate the outcome. Each step has limitations, but together they give you a clear picture of what you are authorizing. The most important rule is to never sign a transaction you do not understand, no matter how legitimate it looks.
Common questions
How do I check if a smart contract is safe?
You can't be 100% sure, but you can check the contract address on a block explorer, see if it's verified, read its source code, and simulate a transaction. A verified contract is not automatically safe, but it's a good first step. Always simulate the transaction to see what it does.
What is a token approval and why is it dangerous?
A token approval is a permission you give a contract to spend your tokens. It's dangerous because if you approve a malicious contract, it can drain your tokens. Always check the spender address and the amount. Avoid approving unlimited amounts unless you trust the protocol.
Can I see what a transaction does before signing?
Yes. Use a block explorer to decode the transaction data, or use a simulation tool like Tenderly or Blowfish. These tools show you the function being called and the predicted outcome, such as balance changes and approvals.
What is a permit signature?
A permit is a signature that allows a contract to approve on your behalf without a separate transaction. It's part of EIP-2612. It can be used to set an approval, so be careful about what you sign. Verify the spender and amount.
What should I do if I already approved a malicious contract?
Revoke the approval immediately. Use a tool like Revoke.cash to remove the allowance. Also, move your funds to a new wallet if you suspect your current one is compromised. Never share your seed phrase or private key with anyone.
Read next
- Blind Signing: What It Is and Why It Matters Blind signing shows a hash instead of a decoded transaction. Learn how it works, why hardware wallets ask for it, and how to avoid approving unknown actions.
- Address Poisoning: The Scam in Your Transaction History An attacker plants a transfer from a lookalike address so a later copy-paste from history sends funds to them. Verify the middle, never the ends.
- SIM Swap Attacks: Why a Phone Number Is Not a Factor The attack is against the carrier, not the phone. Port-out locks, moving off SMS, and the email account that sits behind every recovery flow.
- Smart Contract Wallets: A Wallet That Is a Program Recovery without a seed phrase, spending limits and batched approvals, against deployment cost, per-chain addresses and dependence on the contract's code.
- Stuck Crypto Transactions: Causes and Fixes Learn why crypto transactions get stuck, how nonces work, and how to speed up or cancel a pending transaction. Understand the risks and what not to do.