1
From the global context:  msg.gas (uint): remaining gas 

I want to understand when and how this global context variable gets updated. In Remix I ran a fallback function multiple times in a row but it never seemed to change msg.gas ...

Remaining in what sense? Total available for this user? The amount remaining for this particular transaction? What remains after the transaction is completed or before? What if you check it in a function foo() that is just about to call function bar() which also costs gas ? what is its value inside each function? and when exactly does it get changed? Where exactly are these global context variables stored?

6

What msg.gas returns is the available gas remaining for the current transaction from this point on. As each EVM instruction is executed, the EVM itself maintains a record of how much gas has been used so far and how much remains. The rules are in the Yellow Paper appendices G and H.

The EVM implements an instruction, GAS that (from the Yellow Paper),

Get[s] the amount of available gas, including the corresponding reduction for the cost of this instruction.

The Solidity msg.gas construct just accesses the GAS opcode/instruction and evaluates to the result.

When you issue a transaction to the Ethereum blockchain, one of the parameters is the amount of gas you are prepared to pay for. As the transaction gets executed, this gas amount is continually decreased as instructions are executed.

Various things can happen that affect how much gas is consumed by the transaction and how much you might get back:

  1. There is sufficient gas; the transaction completes successfully. You (the sender of the transaction) get refunded any remaining gas.

  2. There is insufficient gas - i.e. it runs out during execution. You get charged for all the gas, but the transaction is reverted - there is no other state change (this is an example of 4. below - running out of gas is an exceptional halting condition).

  3. The transaction reverts (a kind of "soft" error). You get charged for gas used so far and refunded the remainder. There is no other state change (the transaction is rewound).

  4. The transaction throws (a kind of "hard" error/exceptional halt). All the gas gets used up, you don't get a refund, and the transaction is rewound.

To answer some of your questions directly:

  • "Remaining" means available for rest of the execution of the current transaction.

  • It is neither before nor after, but during. The EVM gas counter accessed by msg.gas is continually updated after every EVM instruction executed throughout the transaction.

  • Function calls within a contract are just normal EVM instruction executions. Each instruction uses gas, and the remaining gas counter is just decremented as usual. For function calls to other contracts, there is a rule that a maximum of 63/64 of the remaining gas can be passed to the function called. This is to prevent stack-depth attacks.

  • It gets changed just before the execution every single EVM opcode/instruction.

  • The remaining gas amount is managed by the EVM, and stored internally. It is accessible only via the EVM GAS opcode, similarly to PC, MSIZE etc.

I hope this answers your question sufficiently.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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