Gas and value in a transaction are entirely separate. When you send x
ETH to an address, whether from an account or a contract, the recipient's balance is guaranteed to go up by x
, regardless of how much gas was used (as long as there are no exceptions).
Additionally, gas is always paid by the original sender (tx.origin
in Solidity), not by any intermediate contracts. The gas used in a transaction is always subtracted from the balance of the sendimg account, not of a contract.
tl;dr: you don't need to do anything, just send enough gas in the transaction
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.
Best Answer
Just to add to Jesse's answer.
tx.origin
is supposed to be the account that signed a transaction. This sounds useful in principle, but in practice, it has been shown that the value can be spoofed.That means you can only use
tx.origin
when you're interested in the user identity but security isn't a concern, so ... err .. never. It's possible such a use-case exists, but I've yet to see it.You can successfully design things with the origin in mind, using
msg.sender
as the reliable input. Just pass it into functions in contracts further down the chain.and, in "Other",
Hope it helps.