# Development Update 2 ~ [28/10/2021] The following document is a second development update for the project "Research removal of gas stipend for `CALL` opcodes". It explains the impact of removing the gas stipend from the EVM by replacing its value with 0, or infinity, where all the remaining gas is forwarded. Such changes were observed and documented by running a private blockchain using a modified Geth client. ## Brief Recap As explained in Vitalik's [post](https://hackmd.io/@vbuterin/evm_feature_removing), the gas stipend can be removed by replacing the value 2300 with 0 or a mechanism that forwards all the remaining gas. There are currently three different methods of transferring value between smart contracts, including using `.send()`, `.transfer()`, and `.call()`. These methods function differently, where transactions initiated using `.send()` and `.transfer()` only provide 2300 gas for computation. However, in `.call()`, the computation receives all the remaining gas from the sender contract. ## Impact of 0 Gas Stipend In the source code of geth client, the stipend is stored in `protocol_params.go` as an `uint64` variable named `CallStipend`. It is later used when the functions `opCall` and `opCallCode` are executed. If the `CallStipend` is set to 0, then transactions initiated using `.send()` and `.transfer()` immediately fail: ``` GoError: Error while compiling or running script: Error: execution reverted: Failed to send Ether at web3.js:6357:37(47) at github.com/ethereum/go-ethereum/internal/jsre.MakeCallback.func1 (native) at <eval>:1:12(1) ``` It can be seen that the client displays an error message describing that the execution has been reverted. For a deeper inspection of the error, the condition that fails the transaction was commented out in the `interpreter.go` file: ``` switch { case err != nil: return nil, err //case operation.reverts: //return res, ErrExecutionReverted case operation.halts: return res, nil case !operation.jumps: pc++ } ``` After the transaction was resent, the client no longer shows an error, allowing execution to be debugged. It was then revealed in the trace file that the EVM shows an `out of gas` error after executing the `CALL` opcode: ``` { "depth": 2, "error": "out of gas", "gas": 0, "gasCost": 3, "op": "PUSH1", "pc": 0, "stack": [] } ``` Because the execution was out of gas, no funds were sent to the receiver contract. Transactions initiated using `.call()` were not affected by the stipend's removal because their compuation do not rely completely on it. ## Impact of ∞ Gas Stipend Implementing this change was complex as it involved making modifications to multiple files, including `gas_table.go` and `gas.go`. Firstly, the `gasCall()` function (located in `gas_table.go`) was modified to include the following code: ``` totalGas := contract.Gas + params.ColdAccountAccessCostEIP2929 totalGasUint256 := uint256.Int{} totalGasUint256.SetUint64(totalGas) evm.callGasTemp, err = callGas2(evm.chainRules.IsEIP150, contract.Gas, gas, totalGasUint256) ``` Secondly, in `gas.go`, the `callGas` function was duplicated with a modified name `callGas2`. While the implementation may incorporate poor programming practice or design choices, it is adequate for the current purpose of observing the implications of the infinite gas stipend. With these changes enabled, `.send()` and `.transfer()` receive all the remaining gas from the contract, behaving similarly to `.call()`. Hence, the computation for these transactions no longer rely solely on the gas stipend. When testing, the transactions (created using `.send()` and `.transfer()`) did not fail where the funds were sent successfully to the receiver contract. ## Next Step The next step involves refining and testing the implementation of infinite gas stipend. This process will be documented in a future development update. ## Links 1. https://github.com/holiman/goevmlab/tree/master/cmd/traceview 2. https://github.com/ethereum/go-ethereum ###### tags: `CDAP`