简体   繁体   English

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

[英]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. 我想创建一个可查看的函数(需要返回一个字符串给用户),搜索msg.sender的映射,如果发件人的值是x,我希望合同继续进行。 It all does work inside remix but if I upload it to ropsten, it doesn't anymore. 这一切都在混音内部工作,但如果我上传到ropsten,它就不再了。 Is this a known issue? 这是一个已知的问题? I have tried tx.origin as well, same result. 我也尝试了tx.origin,结果相同。 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? 编辑:我认为问题是,当使用可查看的函数时,没有msg.sender,因为没有实际的事务? Is there a way to return a value to the user without using the "view" functions? 有没有办法在不使用“视图”功能的情况下将值返回给用户?

Short answer 简短的回答

msg.sender does work in a view function, although it is useless as an authorization scheme. msg.sender确实在view函数中工作,尽管它作为授权方案是无用的。 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. 看起来你正在运行一个快速运行并且不会改变区块链状态的call msg.sender is set in both a transaction and a call. 在事务和调用中都设置了msg.sender 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. 但是在call ,您可以自由地将发件人设置为您喜欢的任何值。

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. 该工具可能是web3.js,web3.py,Mist,MyEtherWallet,MyCrypto等。它们都有(或可能没有!)机制来设置呼叫中的发送方。

MyEtherWallet MyEtherWallet

In the comments, you mention MyEtherWallet specifically. 在评论中,你特别提到了MyEtherWallet。 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 有关ethereum.stackexchange的这个未解决的问题似乎值得关注,因为它提出了大致相同的问题: 如何使用MyEtherWallet合同检查msg.sender余额

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. 然后像MyEtherWallet这样的工具将允许您设置感兴趣的地址。 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. 值得注意的是,通过检查msg.sender来隐藏数据是没用的。 Anyone can set a fake sender in a call (or directly inspect blockchain state). 任何人都可以在通话中设置假发件人(或直接检查区块链状态)。 So, it's trivial to bypass this "protection." 因此,绕过这种“保护”是微不足道的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM