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

sco*_*onX 4 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...";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

car*_*ver 8

简短答案

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

通话与交易

首先,了解通话和交易之间区别很重要。

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

设置发件人

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

MyEtherWallet

在评论中,您特别提到MyEtherWallet。在快速搜索中,我没有发现有关如何设置发件人的任何信息。关于ethereum.stackexchange,有一个未解决的问题似乎值得关注,因为它询问的问题大致相同:如何使用MyEtherWallet合同检查msg.sender余额

合同解决方法

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

无法帮助某人从合同内部设置发件人。但是,您可以提供采用地址作为参数的其他方法。然后,诸如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...";
    }
}
Run Code Online (Sandbox Code Playgroud)

隐藏数据

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

  • 非常感谢,我并没有真正意识到通话和交易之间的区别。我确实知道,将msg.sender背后的内容隐藏起来是没有意义的,因为所有内容的可见性……我只是需要这份合同作为一个简单的示例。看来Myetherwallet在我拨打的电话中没有收到msg.sender。我用一个简单的return msg.sender调用进行了测试,实际上它只返回0x000 [...]。再次感谢您的广泛答复! (3认同)