Msg.sender在“view”函数中不起作用,为什么?有解决方法吗?

9

我希望创建一个可查看的函数(需要向用户返回字符串),该函数会搜索一个映射以查找msg.sender,如果发送者的值为x,则希望合约可以相应地进行处理。在remix中,所有这些都能正常工作,但是如果我将其上传到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因为没有实际交易?有没有一种方法可以在不使用“view”函数的情况下向用户返回值?


你在 call() 中设置了 from 为你想要将 msg.sender 设置为的账户吗? - carver
@carver 你是什么意思? - scoperationX
2
您需要展示如何调用该函数(或告诉我们使用的工具)。在调用视图函数时,“from”地址是可选的,但如果您提供它,“msg.sender”将具有该值。 - user94559
1
@smarx 这个函数应该直接从我的以太坊钱包中调用。但由于某些原因,视图函数无法获取 msg.sender,它始终是 0x0000... - scoperationX
只要我在Remix中尝试,一切都很好,但是当我尝试从我的以太钱包(Ropsten网络)使用它时,它就无法工作了... - scoperationX
显示剩余5条评论
1个回答

21

简短回答

msg.senderview 函数中确实起作用,但作为授权方案是无用的。您使用的查询工具应该有机制来设置发送者。

调用与交易

首先,了解 调用和交易之间的区别 很重要。

看起来您正在运行一个 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...";
    }
}

隐藏数据

值得注意的是,通过检查msg.sender来隐藏数据是无用的。 任何人都可以在调用中设置一个虚假的发送者(或直接检查区块链状态)。因此,绕过这种“保护”非常容易。


4
非常感谢,我之前并不了解call和transaction之间的区别。我确实知道在msg.sender后面隐藏一些东西是没有意义的,因为所有信息都是公开可见的……但我只是需要这个合约作为一个相对简单的示例。似乎Myetherwallet在我发起的调用中无法获取到msg.sender。 我使用一个简单的返回msg.sender调用进行测试,结果只返回0x000[...]。再次感谢您详细的回答! - scoperationX

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接