Msg.sender在“查看”功能中不起作用,为什么?有解决方法吗?

时间:2018-08-14 18:32:53

标签: blockchain ethereum solidity smartcontracts remix

我想创建一个可查看的函数(需要向用户返回一个字符串),该函数在映射中搜索msg.sender,如果发件人的值为x,我希望合同继续进行。在混音中一切正常,但是如果我将其上载到ropsten,它将不再可用。这是一个已知的问题?我也尝试过tx.origin,结果相同。 那是我尝试过的有问题的代码:

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

编辑:我认为问题是,使用可见函数时没有msg.sender,因为没有实际事务?有没有一种方法可以在不使用“视图”功能的情况下向用户返回值?

1 个答案:

答案 0 :(得分:5)

简短回答

msg.sender确实可以在view函数中工作,尽管它不能用作授权方案。您使用的查找工具应具有一种设置发件人的机制。

通话与交易

首先,了解difference between a call and a transaction很重要。

看来您正在运行call,它运行很快并且不会改变区块链的状态。在交易和通话中都设置了msg.sender。在交易中,它不能被伪造:您必须具有与给定帐户关联的私钥。但是在call中,您可以将发件人设置为任意值。

设置发件人

设置发送者的方式取决于您要使用的工具。该工具可能是web3.js,web3.py,Mist,MyEtherWallet,MyCrypto等。它们都具有(或可能不具有!)一种在呼叫中设置发送者的机制。

MyEtherWallet

在评论中,您特别提到MyEtherWallet。在快速搜索中,我没有发现有关如何设置发件人的任何信息。在ethereum.stackexchange上存在一个未解决的问题,似乎值得关注,因为它提出的问题大致相同:How to check msg.sender balance with MyEtherWallet contract

合同解决方法

  

是否可以为合同指定此类设置?

无法帮助某人从合同内部设置发件人。但是您可以提供另一种以地址作为参数的方法。然后,诸如MyEtherWallet之类的工具将允许您设置感兴趣的地址。例如:

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

隐藏数据

值得注意的是,通过检查msg.sender隐藏数据是没有用的。任何人都可以在呼叫中设置伪造的发件人(或直接检查区块链状态)。因此,绕过这种“保护”很简单。