# 0x0 vs. msg.sender

By [doug](https://paragraph.com/@pfeffunit) · 2022-02-21

---

> UPDATE: [It turns out](https://twitter.com/0xkarmacoma/status/1493380279309717505?s=21) `msg.sender` can be `0x0` in read operations. I didn’t try that in my tests below, since the mystery check that drove me bananas (below) was in a mint operation and you cannot execute that by Read. But it’s food for thought, anyway.

Is it [Nerd Sniping](https://xkcd.com/356/) if you snipe yourself? It happened to me. I saw a weird thing in a Solidity contract and I couldn’t get it out of my mind: The [Pepsi Mic Drop contract](https://etherscan.io/address/0xa67d63e68715dcf9b65e45e5118b5fcd1e554b5f#code) has this check in its `mint` method:

`require(msg.sender != address(0x0), "Public address is not correct");`

I can’t understand what it’s doing, or how `msg.sender` could ever be `0x0`. It doesn’t make any sense. The author of [this Solidity tutorial](https://betterprogramming.pub/nft-beginner-tutorial-pepsi-nft-smart-contract-explained-962721b7361a) notices it and doesn’t understand, too. There’s a bunch of comments on [an old Stack Overflow question](https://ethereum.stackexchange.com/questions/50596/what-s-the-point-of-checking-msg-sender%E2%89%A00-are-there-cases-where-msg-sender-can), and the general consensus is that it’s not possible. But some Googling (and Discord chat, shout out **Def Discord**) suggest that a contract’s `msg.sender` might be 0x0 if an outbound request is made a contract’s constructor. Could that be? Let’s find out!

I set up [a contract](https://rinkeby.etherscan.io/address/0x6C519d1eBB07537fDEE89B23Ba6344090E498873#code) (let’s call it **Target)** that has two methods: one to return the caller’s `msg.sender`, the other to return its `tx.origin`. (BTW, skip way down for some additional details on these two values!)

I then deployed [another contract](https://rinkeby.etherscan.io/address/0x6c4b4ca1287570eb988ae81b83f51d9d590d9a97#code) that itself will deploy an intermediary contract, **CallerByConstructor**. Its job is to call **Target’s** methods to see what that **Target** sees for **CallerByConstructor’s** `tx.origin` and `msg.sender`. **CallerByConstructor** will emit events to log those responses.

Sure enough, **Target** sees **CallerByConstructor’s** address for the `msg.sender`, and my wallet’s address for the `tx.origin`.

So I guess that means the Pepsi check is just cargo cult copy and pasted in? Maybe Solidity used to allow for `0x0 msg.senders` long ago, the code has been passed down to us today? Do you know? Let me know [on Twitter](http://twitter.com/pfeffunit), it’s driving me crazy.

* * *

Quick reminder about `msg.sender` and `tx.origin`:

`msg.sender` will be the address of the immediate caller to a contract. That could be you and your wallet, or it could be a contract calling another contract.

`tx.origin` remains consistent even across multiple contract calls. It will generally always be the wallet address that initially triggered a transaction. For example, say I call Contract A, and A calls B, and B calls C. C is going to report the `tx.origin` as my wallet address (since it originated the whole thing), and `msg.sender` as B’s address.

Additionally, this is why a common anti-bot trick is to `require(msg.sender == tx.origin`): that’ll generally catch any funny business, like contracts deploying other contracts to interact with your contract, as happened to Adidas. Montana Wong touches on it here:

[https://twitter.com/Montana\_Wong/status/1472302221026942977](https://twitter.com/Montana_Wong/status/1472302221026942977)

---

*Originally published on [doug](https://paragraph.com/@pfeffunit/0x0-vs-msg-sender)*
