#ethereum #smartcontracts #cryptocurrency #erc20 #openzeppelin
Вопрос:
Я пишу контракт ERC20, который позволил бы другому ERC20 работать с моим контрактом, и не уверен, как получить конкретный адрес в сценарии, приведенном ниже.
Допустим , таков мой контракт CoinA
, и таков контракт кого-то другого PartnerCoin
. Я проксирован, и они могут быть или не быть (в этом сценарии я уже знаю, проксированы они или нет, однако). И скажите, что я использую OpenZeppelin в качестве своего прокси. Адрес прокси-контракта моей монеты-0x123, а адрес контракта (или прокси-сервера) их монеты-0x456. Мы можем сказать, что если PartnerCoin
они проксированы, то их адрес реализации равен 0x192.
Приходит человек по имени Боб и хочет передать 10 своих PartnerCoin
денег своему другу Джону. Адрес кошелька Боба-0x987, а адрес кошелька Джона-0x654. PartnerCoin
в функции передачи требуется , чтобы она получала конкретный ответ от общедоступной функции, из которой она может вызывать CoinA
, в противном случае она не будет передаваться. Он вызывает функцию, которую мы назовем SuperFunction
, включенной CoinA
и ожидает ответа.
Я только хочу PartnerCoin
иметь возможность позвонить SuperFunction
, по крайней мере сейчас, и я знаю, каков PartnerCoin
его адрес.
В рамках моего контракта на реализацию, скажем, 0x384, я считаю, что это тот случай, когда:
msg.sender
вернет 0x123, мой собственный прокси, потому что мой прокси вызывает мою реализацию, правильно?
_msgSender()
вернет 0x987, потому что они являются фактическим конечным пользователем.
Что вернет адрес PartnerCoin
контракта 0x456, чтобы CoinA
можно было проверить PartnerCoin
, что это действительно звонит SuperFunction
, а не какая-то другая монета?
Спасибо вам за помощь!
Ответ №1:
В настоящее время OpenZeppelin _msgSender()
(источник) (OZ 4.x, Solc 0,8.x) возвращает то же значение, что и глобальная переменная msg.sender
. Функция существует для облегчения обновления, если msg.sender
она когда-либо станет устаревшей (как это уже произошло с ее предшественником tx.origin
).
Когда PartnerCoin
они звонят вам SuperFunction
, не имеет значения, звонят ли они по вашему контракту напрямую или через прокси (это delegatecall
ваш контракт). msg.sender
Это всегда будет тем PartnerCoin
Если бы прокси только call
редактировал (а не delegatecall
редактировал) ваш контракт, то да, msg.sender
это был бы прокси. Но это не относится к прокси-контракту OpenZeppelin (источник).
Комментарии:
1. Итак, в моем примере и msg.sender, и _msgSender() вернут 0x456, тогда? Или они оба вернут 0x987? Спасибо за помощь!
2. @RatherPeachy Оба вернут
PartnerCoin
адрес реализации (не прокси). К сожалению, я не вижу этого адреса в вашем вопросе.3. @RatherPeachy 0x987 (адрес Боба) был бы
msg.sender
в вашем контракте, если бы Бобcall
PartnerCoin
редактировал (не имеет значения, через прокси или напрямую), иPartnerCoin
он редактировал быdelegatecall
ваш контракт. Но тогдаPartnerCoin
он будет действовать как прокси-сервер, поэтому ваш контракт не будет иметь доступа к хранилищу ваших контрактов (в данном случае он будет использовать хранилище проксиPartnerCoin
-сервера ).4. В этом есть большой смысл! В случае, если нам снова понадобится ссылаться на
PartnerCoin
адрес реализации, давайте назовем его 0x192 — я отредактирую исходный вопрос с этой информацией. Это звучит так, как будто , если Боб (0x987)call
PartnerCoin
редактировался , ноPartnerCoin
затем вызывалсяSuperFunction
, то единственным способомSuperFunction
иметь оба адреса, 0x192 и 0x987, былоPartnerCoin
бы передать 0x987 в качестве параметра. Таким образом, дляSuperFunction
_msgSender()
(иmsg.sender
) будет 0x192, а этот новый параметр может быть 0x987. Правильно?5. @RatherPeachy Это правильно.