Skip to content

Latest commit

 

History

History
150 lines (86 loc) · 13.3 KB

gas.asciidoc

File metadata and controls

150 lines (86 loc) · 13.3 KB

Gas

Gas is Ethereum’s unit for measuring the computational and storage resources required to perform actions on the Ethereum blockchain. In contrast to Bitcoin, whose transaction fees only take into account the size of a transaction in kilobytes, Ethereum must account for every computational step performed by transactions and smart contract code execution.

Each operation performed by a transaction or contract costs a fixed amount of gas. Some examples, from the Ethereum yellow paper:

  • Adding two numbers costs 3 gas

  • Calculating a Keccak256 hash costs 30 gas + 6 gas for each 256 bits of data being hashed

  • Sending a transaction costs 21,000 gas

Gas is a crucial component of Ethereum, and serves a dual role: as a buffer between the (volatile) price of Ethereum and the reward to miners for the work they do, and as a defense against denial of service attacks. To prevent accidental or malicious infinite loops or other computational wastage in the network, the initiator of each transaction is required to set a limit to the amount of computation they are willing to pay for. The gas system thereby disincentivizes attackers from sending "spam" transactions, as they must pay proportionately for the computational, bandwidth, and storage resources that they consume.

Halting Problem

The idea of transaction fees and accounting seems practical, though you might wonder why Ethereum requires gas in the first place. Gas is pivotal, as it not only deals with the halting problem but is also critical for safety and liveness. What are the halting problem, safety, and liveness, and why should you care?

Paying for gas

While gas has a price, it cannot be "owned" nor "spent". Gas exists only inside the Ethereum Virtual Machine (EVM) as a count of how much computational work is being performed. The sender is charged a transaction fee in ether, which is then converted to gas and then back to ether as block rewards for the miners. These conversion steps are in place to separate the price of the computation (tied to amount of processing) from the price of ether (tied to market fluctuations).

Gas cost vs. gas price

While the gas cost is a measure of operational steps performed in the EVM, the gas itself also has a price measured in ether. When performing a transaction, the sender specifies the gas price they are willing to pay (in ether) for each unit of gas, allowing the market to decide the relationship between the price of ether and the cost of computing operations (as measured in gas).

total gas used * gas price paid = transaction fee in ether

Miners on the Ethereum network can choose between pending transaction requests by, for example, selecting those which offer to pay a higher gas price. It is currently the case that offering a higher gas price will get your transaction confirmed faster.

It is important to be clear about the distinction between the gas cost and the gas price:

gas cost - the number of units of gas required to perform a particular operation

gas price - the amount of ether you are willing to pay per unit of gas when you send your transaction to the Ethereum network

Rationale Behind Gas Costs

The relative gas costs of the various operations that can be performed by the EVM have been carefully chosen to best protect the Ethereum blockchain from attack. More computationally intensive operations cost more gas. For example, executing the SHA3 function is ten times more expensive (30 gas) than the ADD operation (3 gas). More importantly, some operations such as EXP require an additional payment based on the size of the operand. There is also a gas cost to using EVM memory and for storing data in a contract’s on-chain storage. It is not ideal to conflate the different modalities of resource usage, but making execution cost a vector would have been too much work to allow a timely release of the Ethereum platform.

The initial set of gas costs was close to optimal, but someone found and exploited a mismatch in gas cost and real-world resource cost which made the Ethereum mainnet almost grind to a halt until a hard fork tweaked the relative gas costs and fixed the problem. Since then the blockchain has been running very well in this regard.

Gas cost limit and running out of gas

Before sending a transaction, senders must specify a gas limit - the maximum amount of gas they are willing to use to execute their transaction. They must also specify the gas price - the price in ether they are willing to pay for each unit of gas.

gas limit * gas price in ether is deducted from the sender’s account at the start of transaction execution as a deposit. This is to prevent the sender from going "bankrupt" mid-execution and being unable to pay for gas costs. Any transaction that has set a gas limit such that this "deposit" exceeds the ether account balance will be rejected.

In practice, the sender will set a gas limit that is higher than or equal to the gas expected to be used. If the gas limit is set higher than the amount of gas consumed, the sender will receive a refund of the excess amount, as miners are only compensated for the work they actually perform.

In which case:

(gas limit - excess gas) * gas price ether goes to the miner as a block reward

excess gas * gas price ether is refunded to the sender

However, if the gas used exceeds the specified gas limit at any point, i.e. if the transaction "runs of out gas" during execution, the operation is immediately terminated. Although the transaction was unsuccessful, the sender will not get their transaction fee back as miners have already performed the computational work up to that point, and will be compensated for doing so.

Example

If the transaction is being sent from an Externally Owned Account (EOA), the ether to buy gas limit amount of gas at the offered gas price is deducted from the EOA’s balance. In other words, the originator of the transaction pays for the gas. The originator funds the total gas consumed by the transaction as well as any "sub-executions" that result. This means that if the initiator X pays for gas to call contract A, which spends some of that gas on computation and then sends a message call to contract B, the gas used by A to execute the B is also deducted from X’s gas supply specified and paid for up front.

Let’s look at an example.

An EOA account X initiates a transaction which sends data to a contract account A, paying for a supply of 25,000 gas for the whole transaction.

Firstly, the intrinsic cost of sending a transaction (21,000 gas) is deducted from the gas supply.

Then, Contract A is executed, spends 440 gas on computation and initiates a message call (which costs 700 gas) to Contract B.

Contract B spends 360 gas on computation.

Returning from Contract B completes the transaction.

2,500 gas worth of ether (at the gas price for this transaction) is refunded to X.

Any intermediary contract that executes a portion of the operations in a transaction can therefore theoretically run out of gas if the originator of that transaction did not pay for a big enough supply of gas at the start. In cases where contracts run out of gas mid-execution, all state changes that would have otherwise resulted from that contract’s execution are ignored, except the caller still pays for all the gas used to execute code to get to that point (as execution is the only way to determine that the computation will use up the gas supply).

Estimating Gas

Estimating gas works by pretending the transaction is actually being included in the blockchain, and then returning the exact gas amount that would have been charged if that pretend operation were real. In other words, it uses the exact procedure a miner would use to calculate the actual fee but the transaction is not mined into the blockchain.

Note that the estimate may be significantly different from the amount of gas actually used by the transaction if sent to the Ethereum network, for a variety of reasons, including EVM mechanics and blockchain state.

We can use the web3 interface to get a gas cost estimate:

var result = web3.eth.estimateGas({
    to: "0xc4abd0339eb8d57087278718986382264244252f",
    data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
});
console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015"

Gas price and transaction prioritization

The miner who mines the next block gets to decide which transactions to include. Since gas price is factored into the transaction fee they will receive as a reward, they are more likely to include transactions with the highest gas prices first. If the sender sets the gas price too low, they may have to wait a long time before their transaction gets confirmed. As such, setting a gas price for a transaction is a trade-off between trying to save money and how quickly you want the transaction to be confirmed.

Miners can also decide the order in which transactions are included in a block. Since multiple miners are competing to append their block to the blockchain, the order of transactions within a block is decided by the "winning" miner. Note that while transactions from different accounts can be ordered arbitrarily, transactions from an individual account must be executed in the order of the transaction nonces.

Block gas limit

The block gas limit is the maximum amount of gas that may be consumed by transactions in a block, and constrains how many transactions can fit into a block. For example, let’s say we have 5 transactions whose gas limits have been set to 30,000, 30,000, 40,000, 50,000 and 50,000. If the block gas limit is 180,000, then any four of those transactions can fit in a block, while the fifth will have to wait for a future block. As previously discussed, miners decide which transactions to include in a block. Different miners are likely to select different combinations, mainly due to the different orders that they are likely to receive them in. If a miner tries to include a transaction that requires more gas than the current block gas limit, it will be rejected by the network. Most Ethereum clients will stop you from issuing such a transaction by giving a warning along the lines of “transaction exceeds block gas limit”. The block gas limit was around 8 million gas at the time of writing according to https://etherscan.io, meaning that around 380 basic transactions (each consuming 21,000 gas) could fit into a block.

Who decides what the block gas limit is?

The miners on the network collectively decide the block gas limit. Individuals who want to mine on the Ethereum network use a mining program, such as ethminer, which connects to a Geth or Parity Ethereum client. The Ethereum protocol has a built-in mechanism where miners can vote on the gas limit so capacity can be increased without having to coordinate on a hard fork. The miner of a block can adjust the block gas limit by a factor of 1/1024 (0.0976%) in either direction. The result of this is an adjustable block size based on the needs of the network at the time. This mechanism is coupled with a default mining strategy where miners vote on a gas limit which is at least 4.7 million gas, but which targets a value of 150% of the average of recent total gas usage per block (using a 1024-block exponential moving average). This allows for capacity to organically increase. Miners can choose to change this, but many do not.

Gas refund

Ethereum encourages the deletion of used storage variables and accounts by refunding some of the gas used during contract execution.

There are 2 operations in the EVM with negative gas costs:

  1. Deleting a contract (SELFDESTRUCT) is worth a refund of 24,000 gas

  2. Setting a storage address holding a non-zero value to zero (SSTORE[x] = 0) is worth a refund of 15,000 gas

To avoid exploitation of the refund mechanism, the maximum refund for a transaction is set to half the total amount of gas used (rounded down).

GasToken

GasToken is an ERC20-compliant token that allows anyone to "bank" gas when the gas price is low and use it when gas price is high. By making it a tradable asset, it essentially creates a gas market. It works by taking advantage of the gas refund mechanism described earlier.

You can learn about the maths involved in calculating the profitability and how to use the released gas at https://gastoken.io/

Rent fee

There is currently a proposal in the Ethereum community to charge smart contracts a "rent fee" to be kept alive. If the rent were not paid, the smart contract would be "put to sleep", making it and its data inaccessible even for a simple read. A contract put to sleep would need to be awakened by paying rent and submitting a Merkle proof.