Solia saysEvery opcode has a gas cost — from PUSH at 3 gas to SSTORE initialization at 20,000 — and the contract is charged before each step, halting if it runs out.
The EVM is a metered VM: every opcode has a published gas cost that the executor charges before running it. PUSH and ADD are 3 gas; MUL is 5; SLOAD is 2100 cold (first time in a tx) or 100 warm; SSTORE is 20000 to initialize a slot to nonzero, 2900 to modify, and yields a refund when zeroing.
If the contract uses more gas than the transaction supplied, it reverts and all state changes roll back — except the gas burned. This metering is what keeps the EVM halting and DoS-resistant. The demo accumulates real gas costs through a small op sequence and shows how quickly SSTORE dominates the bill.
Power-ups you unlock
Every opcode has a fixed (or computed) gas cost
PUSH and arithmetic ops are cheap (3-5 gas)
SLOAD: 2100 cold, 100 warm (within one tx)
SSTORE: 20000 init nonzero, 2900 modify, refunds on zeroing
Out of gas → revert, but the gas spent is still burned
The Reentrancy Reaper attacks — common mistakes
Forgetting cold vs warm SLOAD pricing (EIP-2929)
Treating SSTORE cost as a single number (depends on the slot transition)
Assuming refunds cover full costs (capped at ~20% post-London)
Confusing intrinsic gas (21000 base) with execution gas
Boss battleAccumulate gas across PUSH, ADD, MUL, two SLOADs (cold then warm), SSTORE init, and SSTORE modify.
Example code
<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
const GAS = { PUSH:3, ADD:3, MUL:5, MLOAD:3, MSTORE:3, SLOAD_COLD:2100, SLOAD_WARM:100, SSTORE_INIT:20000, SSTORE_MOD:2900 };
const ops = [
'PUSH', 'PUSH', 'ADD',
'PUSH', 'MUL',
'SLOAD_COLD',
'SLOAD_WARM',
'SSTORE_INIT',
'SSTORE_MOD'
];
let gas = 0;
const rows = ops.map(op => { gas += GAS[op]; return ' ' + op.padEnd(13) + ' +' + String(GAS[op]).padStart(6) + ' running = ' + gas.toLocaleString(); });
document.getElementById('o').textContent = [
'gas accounting (real EVM costs):',
...rows,
'',
'storage dominates: one SSTORE_INIT = ' + GAS.SSTORE_INIT + ' gas (≈ ' + Math.round(GAS.SSTORE_INIT/GAS.PUSH) + ' PUSHes)',
'out of gas → revert, but the gas is burned'
].join('\n');
</script></body></html>