You can refund gas cost to the transaction sender. You can do this with a modifier. Here is an example:
pragma solidity^0.4.11;
contract SomeContract {
event SomeEvent(address sender);
// Need to allow depositing ehter to the contract
function() public payable {
}
modifier refundGasCost()
{
uint gasStart = msg.gas;
_;
uint gasEnd = msg.gas;
uint usedGas = gasEnd - gasStart;
// Add intrinsic gas and transfer gas
usedGas = usedGas + 21000 + 9700;
// Possibly need to check gasprice here to limit possibility for abuse.
uint gasCost = usedGas * tx.gasprice;
// Refund gas cost
msg.sender.transfer(gasCost);
}
function doSomething() external refundGasCost {
SomeEvent(msg.sender);
}
}
Refunding in this way implies some overhead: at least 9700 gas has to be payed extra for the transfer function call inside refundGasCost
modifier. Also gas for computations and variables access in refundGasCost
should be added to usedGas
.
Also the above code is potentially vulnerable to reentrancy and other attacks. I provided it only as an example and didn't test it thoroughly.