Msg.sender не работает внутри функции просмотра, почему? Есть ли обходной путь?

Я хочу создать просматриваемую функцию (должна возвращать строку пользователю), которая выполняет поиск сопоставления для 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, потому что нет фактической транзакции? Есть ли способ вернуть значение пользователю без использования функций "просмотра"?


person scoperationX    schedule 14.08.2018    source источник
comment
Вы устанавливаете from в call() для учетной записи, для которой хотите установить msg.sender?   -  person carver    schedule 14.08.2018
comment
@carver, что ты имеешь в виду?   -  person scoperationX    schedule 14.08.2018
comment
@carver Отредактировал сообщение, это код, с которым у меня проблемы ...   -  person scoperationX    schedule 14.08.2018
comment
Вам нужно будет показать, как вы вызываете функцию (или сообщить нам, какой инструмент). При вызове функции просмотра адрес from является необязательным, но если вы его предоставите, msg.sender будет иметь это значение.   -  person user94559    schedule 14.08.2018
comment
@smarx Функцию нужно вызывать прямо из myetherwallet. Но по какой-то причине функции просмотра не могут получить msg.sender, это всегда 0x0000 ...   -  person scoperationX    schedule 14.08.2018
comment
@smarx, пока я пытаюсь сделать ремикс внутри, все в порядке, но когда я пытаюсь использовать его из myetherwallet (сеть ropsten), он не работает ...   -  person scoperationX    schedule 14.08.2018
comment
Я предполагаю, что myetherwallet не указывает адрес from. Я не смотрел их код.   -  person user94559    schedule 15.08.2018
comment
@smarx можно ли в контракте указать такие настройки?   -  person scoperationX    schedule 15.08.2018
comment
Я не уверен, о чем вы спрашиваете. Если вы спрашиваете, есть ли способ заставить MyEtherWallet указывать from адрес, я понятия не имею. (Спросив их, вы, вероятно, добьетесь лучших результатов.)   -  person user94559    schedule 15.08.2018
comment
Что ж, спасибо, проблема действительно в myetherwallet, так что сейчас я мало что могу сделать ...   -  person scoperationX    schedule 15.08.2018


Ответы (1)


Короткий ответ

msg.sender действительно работает в view функции, хотя бесполезен в качестве схемы авторизации. Используемый вами инструмент поиска должен иметь механизм для установки отправителя.

Звонок против транзакции

Во-первых, важно понимать разницу между вызовом и транзакцией.

Похоже, вы используете call, который работает быстро и не меняет состояние цепочки блоков. msg.sender устанавливается как в транзакции, так и в вызове. В транзакции его нельзя подделать: у вас должен быть закрытый ключ, связанный с данной учетной записью. Но в call вы можете указать отправителю любое значение, которое вам нравится.

Настройка отправителя

Как вы установите отправителя, зависит от того, какой инструмент вы используете для звонка. Этим инструментом может быть web3.js, web3.py, Mist, MyEtherWallet, MyCrypto и т. Д. Все они имеют (или могут не иметь!) Механизм для установки отправителя в вызове.

MyEtherWallet

В комментариях вы конкретно упоминаете MyEtherWallet. При быстром поиске ничего не нашел как настроить отправителя. На ethereum.stackexchange есть этот вопрос без ответа, который, кажется, заслуживает внимания, поскольку он задает примерно тот же вопрос: Как проверить msg. баланс отправителя с контрактом MyEtherWallet

Контрактные обходные пути

можно ли указать такие настройки для договора?

Невозможно помочь кому-то установить отправителя изнутри контракта. Но вы можете предоставить другой метод, который принимает адрес в качестве аргумента. Тогда такие инструменты, как 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 бесполезно. Любой может установить поддельного отправителя в вызове (или напрямую проверить состояние цепочки блоков). Так что обойти эту «защиту» просто.

person carver    schedule 14.08.2018
comment
Большое спасибо, я не осознавал разницу между звонком и транзакцией. Я знаю, что прятать что-то за msg.sender бессмысленно из-за видимости всего… Мне просто нужен этот контракт как довольно простой пример. Похоже, Myetherwallet не получает msg.sender в моем звонке. Я тестировал его простым вызовом return msg.sender, и действительно, он просто возвращает 0x000 [...]. Итак, еще раз большое спасибо за развернутый ответ! - person scoperationX; 15.08.2018