Three ways to detect if an address is a smart contract (2024)

This article describes three methods in Solidity for determining if an address is a smart contract:

  • Check if msg.sender == tx.origin. This is not a recommended method, but because many smart contracts use it, we discuss this method for completeness.

  • The second (and recommended way) is to measure the bytecode size of the address using code.length. This approach still has limitations that devs must work around.

  • The third is using codehash and is not recommended because it has the same limitations as code.length with additional complexity.

We discuss each method in this tutorial. Finally, we provide some Solidity puzzles at the end to test your understanding.

Method 1: Using msg.sender == tx.origin to detect if an address is a smart contract

The global variable tx.origin is the wallet that initiated the transaction, while msg.sender is the address that called the smart contract. If a wallet calls a smart contract directly, then tx.origin will be the same as msg.sender.

However, suppose a wallet calls smart contract A which then calls smart contract B.

From contract B’s perspective, msg.sender is contract A and the wallet is tx.origin. Clearly, msg.sender will not equal tx.origin inside of contract B. The diagram below illustrates the relationship:

By checking if msg.sender == tx.origin, the smart contract can detect if the incoming call is from a smart contract or from a wallet.

require(msg.sender == tx.origin) is an antipattern

Using a smart contract as a wallet is becoming increasingly popular with the adoption of account abstraction, such as ERC-4337 and using smart contracts for multisignature wallets (like Gnosis Safe).

Adding require(msg.sender == tx.origin) to a smart contract means that account abstraction wallets and multisignature wallets cannot interact with the smart contract.

This technique can only test if msg.sender is a contract or not. It cannot test an arbitrary address.

Method 2: Detecting if an address is a smart contract with code.length

The recommended way for a smart contract to test if an address is a smart contract is to measure the size of its bytecode.

If an address has bytecode, then it is a smart contract.

Consider the following code:

contractTestAddress{functiontest(addresstarget)publicviewreturns(boolisContract) {if(target.code.length==0) {isContract =false;} else{isContract =true;}}}

Although all smart contracts have bytecode and all wallet addresses do not, there are some “gotchas” to keep in mind:

  • An address which has no bytecode now could have bytecode there in the future if a smart contract gets deployed to that address.

  • Using msg.sender.code.length == 0 is not a reliable way to detect if an incoming call is from a smart contract. If a smart contract makes a call from the constructor then it has not deployed its bytecode yet and msg.sender.code.length will be 0. While the constructor is executing, the bytecode of the smart contract has not yet been deployed. Therefore, code.length will be zero.

  • On EVM chains that support selfdestruct, there might have been a smart contract at target in the past, but the smart contract self destructed.

Testing msg.sender with code.length

If a wallet calls a contract, then msg.sender.code.length is guaranteed to be 0.

If a contract calls a another contract, then msg.sender.code.length will be 0 if called from the constructor and non-zero if called from another smart contract function.

Testing an address (not msg.sender) with code.length

If a smart contract uses the address(target).code.length test on some target, and the target is a smart contract, then address(target).code.length is guaranteed to be non-zero.

The dev should keep in mind the code.length could become 0 later if the contract self destructs (assuming the chain supports selfdestruct and the contract has the ability to selfdestruct).

If a smart contract uses the address(target).code.length test on some target, and the target is a wallet, then address(target.code.length) is guaranteed to be 0.

However, just because address(target).code.length is 0 now does not mean it will always be zero. A smart contract might be deployed there later. Suppose I give you an address. You measure it now with address(target).code.length and it returns 0. That measurement will be accurate at the moment you measured it, but it is possible that I could deploy a contract to that address (target) at a later date and if you measure it again with address(target).code.length it will be non-zero.

Common use case for checking if an address is a smart contract

If a token is transferred to a smart contract that does not have the functionality to send the tokens out, then the tokens will remain stuck, owned by that contract forever.

As such, some token standards take steps to prevent this from happening.

The ERC-721 with the safeTransferFrom function for example will check if the address being transferred to is a smart contract (using the code.length trick).

Three ways to detect if an address is a smart contract (2)

If it is, they attempt to call a special function on the contract to ask if the contract supports ERC-721 tokens. If the function isn’t there, then it knows the tokens will get stuck and it blocks the transfer.

Method 3: Codehash is a bad way to test if an address is a contract

The codehash returns the keccak256 of the bytecode of an address.

It has the following behavior:

  • If the address has no Ethereum balance and no bytecode, there is nothing to hash and returns bytes32(0).

  • If the address has an Ethereum balance but no bytecode, it returns the keccak256 of empty data keccak256("") which equals 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470.

  • If the address has bytecode (regardless of balance) it returns the keccak256 of the bytecode of the contract.

The exact behavior of codehash is described in the Etherum client comments on codehash.

Some contracts have mistakenly used the codehash to test if an address has bytecode or not. This is not a good idea because if we use codehash on a contract that has no bytecode, we will either get back bytes32(0) or keccak256("") and we must check both possibilities.

If an address a has no bytecode and has no ether, then address(a).codehash returns bytes32(0) or 32 bytes of all zero. However, if someone transfers Ether to the address, then the codehash will become keccak256(""), despite not being a wallet and not a smart contract.

You can test the code below in Remix to see the behavior of codehash:

contractTestHash{functiongetHash() external view returns(bytes32) {// random address with no balance or codereturnaddress(101).codehash;// returns 0x000...000}functionhashOfNonEmptyWallet()externalviewreturns(bytes32) {// tx.origin has a non-zero ether balancereturntx.origin.codehash; // returns a non-zero hash}// observe that `keccakNil` and `hashOfNonEmptyWallet`// return the same valuefunctionkeccakNil()externalpurereturns(bytes32) {returnkeccak256("");}// Deploy SomeTestContract and put its address in// codeHashOtherContract to test itfunctioncodeHashOtherContract(address_a)externalviewreturns(bool) {// returns true because the codehash // of another contract// is equal to the `keccak256` of its bytecodereturna.codehash==keccak256(a.code);}}contractSomeTestContract{functionsomeFunction()externalpurereturns(uint256) {return5;}}

Both codehash and code.length can be used to determine if an address is a smart contract by checking for the presence of bytecode; however, codehash introduces unnecessary complexity by hashing the bytecode, resulting in three possible outcomes, whereas we only need to check code.length is zero or not.

It is far simpler to check code.length.

Puzzle to test your knowledge

Puzzle 1

Can you get the following contract to return true when puzzle is called and not revert?

contractPuzzle{functionpuzzle()externalviewreturns(boolsuccess) {require(msg.sender!=tx.origin);require(msg.sender.code.length==0);success =true;}}

Puzzle 2

What should tx.origin.code.length return? Does it always return the same value?

Learn more with RareSkills

See our Solidity course if you are new to Solidity. See our Solidity bootcamp if you already have some experience. Thanks for reading!

Three ways to detect if an address is a smart contract (2024)

FAQs

Three ways to detect if an address is a smart contract? ›

The contract address is determined based on the person's address creating the contract (sender) and the number of transactions the creator has sent (nonce).

How is smart contract address determined? ›

The contract address is determined based on the person's address creating the contract (sender) and the number of transactions the creator has sent (nonce).

How to know if a contract address is legit? ›

Input the address into a block explorer's search bar. Many of these, including Etherscan, will tell you if the code is verified or not, as highlighted below. You can also check to see if the contract has a name — if it doesn't it could be either very new or untrustworthy.

How to verify a smart contract? ›

The simplest way to verify your source code is via the Etherscan UI. This process does not require any programming skills. Navigate to the Contract tab of the smart contract you are viewing on Etherscan and click the Verify and Publish link. Then, you'll need to select the file type, compiler version, and license.

How to test the smart contract? ›

How to Unit Test a Smart Contract
  1. Guide Requirements.
  2. Useful JS + Solidity Testing Resources.
  3. Step 1: Hardhat Project Structure Setup.
  4. Step 2: Add a Faucet. sol Contract File.
  5. Step 3: Add Test File Structure.
  6. Add Withdrawal Amount Test 🔎
  7. Step 5 - Challenge: Add Critical Function Tests ☢️
  8. Learn More About Ethereum Development.

How to tell if an address is a smart contract? ›

The recommended way for a smart contract to test if an address is a smart contract is to measure the size of its bytecode. If an address has bytecode, then it is a smart contract.

How do I find the address of a smart contract? ›

- Block explorers such as Etherscan, BscScan, or Polygonscan hold data about tokens and their equivalents on their respective networks. - To find the token contract address, simply go to the block explorer and search for the token you want. The contract address will be clearly marked on its page.

How do I know if an address is valid? ›

A common way to validate an address is using the USPS Address Verification tool. The free tool is available on USPS.com, can standardize and verify address accuracy, and allows one address entry at a time.

How to check if a contract is legit? ›

What are the five requirements of a valid contract?
  1. The offer (terms of the offer) One party must make an offer to another. ...
  2. Acceptance of an offer. ...
  3. The capacity of the parties involved. ...
  4. Some form of consideration. ...
  5. All parties intend to enter the agreement.

What is a smart contract address? ›

A contract address is a unique identifier for a smart contract deployed on a blockchain. Smart contracts are self-executing agreements that follow predefined rules and automatically enforce actions when specific conditions are met.

How is a smart contract identified? ›

A smart contract is defined as a digital agreement that is signed and stored on a blockchain network, which executes automatically when the contract's terms and conditions (T&C) are met. The T&C is written in blockchain-specific programming languages such as Solidity.

How to know if a smart contract is safe? ›

To determine if a smart contract is safe, look out for these red flags: Lack of Transparency. Scammers often withhold critical information, such as team identities, development plans, or project goals.

What is formal verification of smart contracts? ›

Formal verification proves or disproves the correctness of a system by checking the formal (mathematical) model of the system against a certain formal specification. A specification is a set of properties describing the desired behaviors of a smart contract, usually defined by developers' intention.

How do you analyze a smart contract? ›

Once you have the smart contract address, you can input it into the search bar of the tool to access the smart contract's page. Here, you may find a variety of information such as the creator address, token name, tokens held in the contract, and so on.

Can I see a smart contract? ›

An individual can see the transaction record for a smart contract that occurred on the blockchain by looking at a block explorer. In the figures below, we discuss the information available for smart contracts on the Ethereum Blockchain as shown on numerous websites such as www.etherscan.io.

How do I audit my smart contract? ›

How To Audit a Smart Contract
  1. Collect Documentation. ...
  2. Automated Testing. ...
  3. Manual Review. ...
  4. Classification of Contract Errors. ...
  5. Initial Report. ...
  6. Publish Final Audit Report.
Feb 22, 2024

Do smart contracts have addresses? ›

The standard smart contract EVM address is the address that is compatible with EVM. The EVM contract address is returned by the system once the contract is deployed. This is the address format that is commonly used in the Ethereum ecosystem.

What is the address function in smart contract? ›

Addresses can be stored in Smart Contracts and can be used to transfer Ether from the Smart Contract to to an address stored in a variable. That's where variables of the type address come in. In general, a variable of the type address holds 20 bytes. That's all that happens internally.

How do I change my smart contract address? ›

Smart contracts in Ethereum are immutable by default. Once you create them there is no way to alter them, effectively acting as an unbreakable contract among participants.

What is the difference between a contract address and an eoa? ›

Using code size of the address

Another way you can determine whether a given address is a contract or an externally-owned account (EOA) by checking the code size of the address. If an address is a contract, its code size will be greater than zero, as contracts have bytecode associated with them, whereas EOAs do not.

Top Articles
Wie sicher sind Robo-Advisor? Tipps & Tricks – extraETF
Folder Redirection Policy and Windows Server Backup Feature
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Doby's Funeral Home Obituaries
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Shasta County Most Wanted 2022
Energy Healing Conference Utah
Testberichte zu E-Bikes & Fahrrädern von PROPHETE.
Aaa Saugus Ma Appointment
Geometry Review Quiz 5 Answer Key
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Cvs Sport Physicals
Mercedes W204 Belt Diagram
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Selly Medaline
Latest Posts
Article information

Author: Twana Towne Ret

Last Updated:

Views: 6460

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Twana Towne Ret

Birthday: 1994-03-19

Address: Apt. 990 97439 Corwin Motorway, Port Eliseoburgh, NM 99144-2618

Phone: +5958753152963

Job: National Specialist

Hobby: Kayaking, Photography, Skydiving, Embroidery, Leather crafting, Orienteering, Cooking

Introduction: My name is Twana Towne Ret, I am a famous, talented, joyous, perfect, powerful, inquisitive, lovely person who loves writing and wants to share my knowledge and understanding with you.