我想创建一个可查看的函数(需要向用户返回一个字符串),该函数在映射中搜索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,因为没有实际事务?有没有一种方法可以在不使用“视图”功能的情况下向用户返回值?
答案 0 :(得分:5)
msg.sender
确实可以在view
函数中工作,尽管它不能用作授权方案。您使用的查找工具应具有一种设置发件人的机制。
首先,了解difference between a call and a transaction很重要。
看来您正在运行call
,它运行很快并且不会改变区块链的状态。在交易和通话中都设置了msg.sender
。在交易中,它不能被伪造:您必须具有与给定帐户关联的私钥。但是在call
中,您可以将发件人设置为任意值。
设置发送者的方式取决于您要使用的工具。该工具可能是web3.js,web3.py,Mist,MyEtherWallet,MyCrypto等。它们都具有(或可能不具有!)一种在呼叫中设置发送者的机制。
在评论中,您特别提到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
隐藏数据是没有用的。任何人都可以在呼叫中设置伪造的发件人(或直接检查区块链状态)。因此,绕过这种“保护”很简单。