1

I am wondering how I could have a function in one contract call another contract and check to see if the calling contract was in fact the one that initiated the call, rather than checking for msg.sender. How could I do this?

I guess an example is that I have a contract that holds tokens and I would like that contract to approve a transferFrom function that allows another contract to transfer token on behalf of the contract. How do I do this while avoiding the role of msg.sender?

4
  • What's the problem with using msg.sender? Is the issue that you want to have another contract in between the owner of the tokens and the token contract? Commented Apr 4, 2017 at 6:15
  • Yes, that is the issue. The owner of the tokens is by another contract. I need to be able to have a user call a function that would transfer tokens from the current contract to another contract. The user however would not actually hold any of the tokens, the contract would.
    – GK1
    Commented Apr 6, 2017 at 19:17
  • I was thinking something like this could work: function approveSelfSpender(address _spender, uint _valuue) returns (bool success) { allowed[this][_spender] = _value; Approval(this, _spender, _value); return true; }
    – GK1
    Commented Apr 6, 2017 at 19:21
  • And then just have a function that allows a user that calls the function to spend the contracts tokens on the contracts behalf, like this approveSelfSpender(msg.sender, balanceOf[this]);
    – GK1
    Commented Apr 6, 2017 at 19:24

1 Answer 1

2

You want to use msg.sender as a reliable means of authenticating the sender. I think what you're getting at is how to cope with the limitations of msg.sender; it reveals only the latest sender in a (possibly) long chain.

Consider another example:

contractFactory produces FundRaiser contracts with "owner" set to the originator who asked contractFactory to deploy a new contract. So, the transaction originator is a step removed from the deployed contract.

The usual approach wouldn't work:

owner = msg.sender;

That would set the new FundRaiser owner to the contractFactory. Not what we want. Since msg.sender isn't giving us the information we need, we'll have to pass it into the FundRaiser constructor, like:

function FundRaiser(address originator) {
    owner = originator;
}

The deploying function in the factory can pass it along, like:

function newCampaign() {
    FundRaiser f = new FundRaiser(msg.sender);
}

That way, the original msg.sender (and any other important information) ends up passed down the chain where it's needed.

Hope it helps.

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.