Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Msg.sender does not work inside a "view" function, why? Is there a workaround?

I want to create a viewable function (needs to return a string to the user) that searches a mapping for msg.sender and if the senders value is x, I want the contract to proceed accordingly. It all does work inside remix but if I upload it to ropsten, it doesn't anymore. Is this a known issue? I have tried tx.origin as well, same result. That's the problematic code I tried:

function getLink() public view returns(string){
    if(tokenBalances[msg.sender]>0){
        return link;
    }else{
        return "You need to purchase a token at first...";
    }
}

EDIT: I think the problem is, that when using a viewable function there is no msg.sender because there is no actual transaction? Is there a way to return a value to the user without using the "view" functions?

like image 224
scoperationX Avatar asked Aug 14 '18 18:08

scoperationX


People also ask

Can MSG sender be spoofed?

For example, a scammer may spoof the text message sender name, turning it into a name that seems like the name of a bank and include a phishing message that tricks users into clicking on a link.

What is the difference between MSG sender and address this?

msg. sender is the address of the contract caller. address(this) is the address of the smart contract itself.

What is MSG sender in Blockchain?

The msg variable (together with tx and block ) is a special global variable that contains properties which allow access to the blockchain. msg. sender is always the address where the current (external) function call came from.

Who is MSG sender in solidity?

What is msg. sender in Solidity? The msg. sender is the address that has called or initiated a function or created a transaction.


1 Answers

Short answer

msg.sender does work in a view function, although it is useless as an authorization scheme. The lookup tool you use should have a mechanism to set the sender.

Call vs Transaction

First, it's important to understand the difference between a call and a transaction.

It appears you're running a call, which runs quickly and does not alter the state of the blockchain. msg.sender is set in both a transaction and a call. In a transaction, it cannot be faked: you must have the private key associated with the given account. But in a call, you are free to set the sender to any value you like.

Setting the Sender

How you set the sender depends on what tool you are using to call. That tool might be web3.js, web3.py, Mist, MyEtherWallet, MyCrypto, etc. They all have (or might not have!) a mechanism to set the sender in a call.

MyEtherWallet

In the comments, you mention MyEtherWallet specifically. In a quick search, I didn't find anything about how to set the sender. There is this unanswered question on ethereum.stackexchange that seems worth following, since it is asking roughly the same question: How to check msg.sender balance with MyEtherWallet contract

Contract Workarounds

is it possible to specify such settings for the contract?

There is no way to help someone set the sender from inside the contract. But you can supply a different method that takes an address as an argument. Then tools like MyEtherWallet will allow you to set the address of interest. For example:

function getLink(address account) public view returns(string){
    if(tokenBalances[account] > 0){
        return link;
    }else{
        return "You need to purchase a token at first...";
    }
}

Hiding Data

It's worth noting that hiding data by checking msg.sender is useless. Anyone can set a fake sender in a call (or directly inspect blockchain state). So, it's trivial to bypass this "protection."

like image 93
carver Avatar answered Oct 15 '22 17:10

carver