Определение адресов в контракте ERC20

#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 Это правильно.