1

I have three different contracts. One is a simple contract (ContractA), second is my token contract and the third one is ERC20 Token contract which is inherited in my token contract. So when I make a request from my frontend (reactjs) to my ContractA it sends that request to my Token contract which sends the request to ERC20 token contract in order to transfer token to an address.

The problem that I am facing is that while calling the functions the address of the user is changed to the contract that is calling the other contract. How can I make the contract to be constant throughout the execution. Which means that the address of the contract should be the user that originated the request from the frontend.

Note: I can not change my implementation in my token contract as it is already deployed.

MyContract.sol

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

Here is my sellTokens function that will transfer one token to the owner of the token. This is called from myContract file.

The transfer function is implemented in ERC20 token implementation from OpenZeppllin. Now when I call the transfer function it gets the msg.sender as the contract which is myContract. And in return it is giving me error for amount exceeds balance since myContract does not hold any tokens. myToken is the one in which ERC20 token is inherited.

2 Answers 2

1

I am not totally sure I understand your question, and what you can and can not change, and what is the difference between snaToken and myToken. You are checking the balance of snaToken but then sending myToken - what exactly is happening there?

But anyway, do you know of the allowance mechanism? (functions .approve and .transferFrom) You can use it to do this:

  1. The user will call approve for MyContract. Meaning - your front end will ask the user to sign an "approve" transaction for the token you want to transfer. So if for example you want the user to send his myTokens, first of all he needs to call and sign: myToken.approve(myContract, transferAmount). This gives permission for myContract contract to send transferAmount tokens from msg.sender to whoever myContract chooses.
  2. Then the user will call MyContract sellTokens, but now sellTokens won't call .transfer, but will call transferFrom: myToken.transferForm(msg.sender, destinationAddress, transferAmount). This will transfer the user's myTokens to destinationAddress.

Hopefully this helps but as I said I'm not sure what is the relation between myToken and snaToken and why you are checking balance of one and sending the other.

1
  • 1
    Thank you very much for the help you method worked like a charm. Plus there was a mistake snaToken is same as myToken. Just forgot to change name of snaToken to myToken, I have corrected it.
    – Usama
    Commented Oct 17, 2021 at 17:07
1

you should use tx.origin instead ofmsg.sender, If there are multiple function invocations on multiple contracts, tx.origin will always refer to the account that started the transaction irrespective of the stack of contracts invoked. However, msg.sender will refer to the one that called the contract, could be a smart contract address.

2
  • Thank you for the suggestion. Can you please check the question again and tell me if now it makes sense. I have added few more details in order to clarify more. I would have used tx.origin if I had myToken code with me or done other implementation. Since myToken code is deployed and I can not change it that why I have to look for different implantations in which the msg.sender remains constant through out the execution.
    – Usama
    Commented Oct 17, 2021 at 11:29
  • 1
    sorry misuderstood, in that case you should use approve + transferFrom mechanism of erc20 instead of transfer function. transfer functions can only be called directly.
    – leycun
    Commented Oct 17, 2021 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.