Сделать msg.sender постоянным во вложенных контрактах Solidity

У меня три разных контракта. Один из них — простой контракт (ContractA), второй — мой контракт с токеном, а третий — контракт с токеном ERC20, который наследуется в моем контракте с токеном. Поэтому, когда я делаю запрос из моего интерфейса (reactjs) в мой ContractA, он отправляет этот запрос в мой контракт токена, который отправляет запрос в контракт токена ERC20 для передачи токена на адрес.

Проблема, с которой я сталкиваюсь, заключается в том, что при вызове функций адрес пользователя изменяется на контракт, который вызывает другой контракт. Как я могу сделать контракт постоянным на протяжении всего выполнения. Это означает, что адресом контракта должен быть пользователь, отправивший запрос из внешнего интерфейса.

Примечание. Я не могу изменить свою реализацию в контракте токена, поскольку он уже развернут.

MyContract.sol

function sellTokens(address _from) public {
        require(myToken.balanceOf(_from) >= 1);
        myToken.transfer(_deployerAddress, 1);
}

Вот моя функция sellTokens, которая будет передавать один токен владельцу токена. Это вызывается из файла myContract .

Функция передачи реализована в реализации токена ERC20 от OpenZeppllin. Теперь, когда я вызываю функцию передачи, она получает msg.sender в качестве контракта, который является myContract. И, в свою очередь, это дает мне ошибку о том, что сумма превышает баланс, поскольку myContract не содержит никаких токенов. myToken — это тот, в котором наследуется токен ERC20.

Ответы (2)

Я не совсем уверен, что понимаю ваш вопрос, и что вы можете и что не можете изменить, и в чем разница между snaToken и myToken. Вы проверяете баланс snaToken, но затем отправляете myToken — что именно там происходит?

Но в любом случае, вы знаете о механизме надбавок? (функции .approve и .transferFrom) Вы можете использовать его для этого:

  1. Пользователь вызовет утверждение для MyContract. Это означает, что ваш интерфейс попросит пользователя подписать транзакцию «одобрить» для токена, который вы хотите передать. Итак, если, например, вы хотите, чтобы пользователь отправил свои myTokens, в первую очередь ему нужно позвонить и подписать: myToken.approve(myContract, transferAmount). Это дает контракту myContract разрешение на отправку токенов transferAmount из msg.sender тому, кого выберет myContract.
  2. Тогда пользователь вызовет MyContract sellTokens, но теперь sellTokens не будет вызывать .transfer, а будет вызывать transferFrom: myToken.transferForm(msg.sender, destinationAddress, transferAmount). Это перенесет myTokens пользователя на адрес назначения.

Надеюсь, это поможет, но, как я уже сказал, я не уверен, какова связь между myToken и snaToken и почему вы проверяете баланс одного и отправляете другой.

Большое спасибо за помощь, ваш метод сработал как шарм. Плюс была ошибка, что snaToken совпадает с myToken. Просто забыл изменить имя snaToken на myToken, я исправил.

вы должны использовать tx.originвместо msg.sender, Если есть несколько вызовов функций для нескольких контрактов, tx.origin всегда будет ссылаться на учетную запись, которая запустила транзакцию, независимо от стека вызванных контрактов. Однако msg.sender будет ссылаться на тот, который вызвал контракт, может быть адресом смарт-контракта.

Спасибо за предложение. Не могли бы вы проверить вопрос еще раз и сказать мне, если теперь это имеет смысл. Я добавил еще несколько деталей, чтобы уточнить больше. Я бы использовал tx.origin, если бы у меня был код myToken или другая реализация. Поскольку код myToken развернут, и я не могу его изменить, поэтому мне приходится искать разные имплантации, в которых msg.sender остается постоянным на протяжении всего выполнения.
извините, неправильно понял, в этом случае вы должны использовать approve+ transferFromмеханизм erc20 вместо передаточной функции. передаточные функции могут быть вызваны только напрямую.