Skip to main content
3 of 12
added 16 characters in body
medvedev1088
  • 11k
  • 5
  • 36
  • 65

You can refund gas cost to the transaction sender. You can do this with a modifier:

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 remainingGasStart = msg.gas;

        _;
        
        uint remainingGasEnd = msg.gas;
        uint usedGas = remainingGasStart - remainingGasEnd;
        // Add intrinsic gas and transfer gas. Need to account for gas stipend as well.
        usedGas = usedGas + 21000 + 9700;
        // Possibly need to check max gasprice and usedGas here to limit possibility for abuse.
        uint gasCost = usedGas * tx.gasprice;
        // Refund gas cost
        tx.origin.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.

medvedev1088
  • 11k
  • 5
  • 36
  • 65