f in x
Ethereum for Developers: EVM, Gas, and Smart Contract Deployment — Advanced Hands-On Guide
> cd .. / HUB_EDITORIALE
Analisi dei dati e metriche

Ethereum for Developers: EVM, Gas, and Smart Contract Deployment — Advanced Hands-On Guide

[2026-06-10] Author: Ing. Calogero Bono

You wrote a perfect Solidity smart contract. Compiled, deployed on Goerli... and the transaction fails with "out of gas". Or the estimated gas is twice what you expected. It happens even to experienced devs: the problem isn't your code, it's the lack of understanding of how the EVM works and gas as a resource.

At Meteora Web, we've been working with blockchain for years. Not just theory: we've deployed contracts in production, optimized operations to reduce costs, and seen projects fail because the team didn't grasp gas mechanics. This guide takes you inside the Ethereum Virtual Machine, explains how every operation is priced, and shows you how to deploy efficient contracts. No academic lectures: everything you need to avoid burning ether unnecessarily.

How the EVM works and why gas is its fuel

The Ethereum Virtual Machine (EVM) is a distributed computer that executes bytecode. Every elementary instruction has a gas cost: a unit measuring computational effort. Gas is not the price in ether: it's the amount of work. You set the price (gas price) and multiplying gives the total cost in ETH.

Bytecode structure and opcodes

Your Solidity contract compiles into a sequence of opcodes. Each opcode has a base cost defined by the Ethereum Yellow Paper. For instance:

  • ADD costs 3 gas
  • SLOAD (load from storage) costs 200 gas
  • SSTORE (write to storage) costs 20,000 gas if zero to non-zero, 2,900 if update

The difference is huge. Storage writes are the most expensive because they modify global blockchain state. Storage reads are costly but less. Arithmetic operations are cheap. Understanding this lets you design contracts that cost little.

Gas limit and gas used

When you send a transaction, you set a gas limit — the maximum gas you're willing to consume. If the contract consumes more, the transaction reverts and gas is consumed up to the failure point. If it consumes less, you pay only what was used. Never set the exact gas limit: leave a margin (e.g., +20%) to avoid unexpected failures.

At Meteora Web, we saw a client lose 0.5 ETH in failures because they used a wallet-computed gas limit without margin. Learning to estimate correctly is free.

Gas: operation costs and how to calculate them

Every operation has a fixed cost plus possible dynamic costs. Storage is the worst. Practical Solidity example:

// Expensive: writes to storage on every call
uint256 public counter;
function increment() public {
    counter += 1;  // SSTORE: ~20,000 gas
}

This function costs about 20,000 gas per call due to storage. Call it 100 times and that's 2 million gas. Now compare with a memory variable:

// Cheap: only in-memory operations
function addInMemory(uint256 a, uint256 b) public pure returns (uint256) {
    return a + b;  // ADD: 3 gas
}

The difference is abysmal. Rule of thumb: if you don't need persistence, use memory or calldata. Avoid storage unless strictly necessary.

Estimating gas with Hardhat

Use Hardhat to estimate gas during development. Example:

const { ethers } = require("hardhat");
async function estimate() {
  const Contract = await ethers.getContractFactory("MyContract");
  const contract = await Contract.deploy();
  const tx = await contract.increment();
  const receipt = await tx.wait();
  console.log("Gas used:", receipt.gasUsed.toString());
}

Compare estimates before and after optimizations. We always use gasUsed in tests to avoid surprises in production.

Optimizing a smart contract to reduce gas

Gas optimization is an art. Here are the techniques we apply at Meteora Web on real projects.

Use uint256 instead of smaller uints

The EVM works on 256 bits. Using uint8 does not save gas; it costs more because the EVM must do conversions. Always use uint256 unless you have storage constraints (e.g., arrays of structs).

Packing in storage

If you have multiple small variables, declare them close together so they pack into one slot. Example:

// Bad: occupies 3 slots
uint128 a;
uint128 b;
uint256 c;

// Good: a and b share a slot
uint128 a;
uint128 b;
uint256 c;

Solidity's automatic packing works if variables are declared consecutively and total at most 256 bits. This reduces storage operations.

Use mappings instead of arrays for frequent lookups

Reading an element from a storage array costs SLOAD (200 gas). A mapping has the same cost, but arrays also manage length. For lookups, mappings are more efficient.

Avoid unbounded long loops

A loop that depends on user input can blow up gas. If you must iterate, impose a maximum limit and document it. Better: move logic off-chain and use cryptographic proofs (like Uniswap or ENS).

Deploying on Ethereum: tools and strategies

Deploying a contract also costs gas. Deployment cost is proportional to bytecode size (200 gas per byte) plus creation cost (32,000 gas). A smaller contract costs less.

Hardhat and deployment scripts

We use Hardhat for testnet and mainnet deployment. Minimal script:

async function main() {
  const MyContract = await ethers.getContractFactory("MyContract");
  const contract = await MyContract.deploy();
  await contract.deployed();
  console.log("Deployed at:", contract.address);
}

Before deploying on mainnet, simulate the cost on Hardhat local or testnet. Use ethers.provider.getFeeData() to get current gas price.

Estimating deployment gas

Hardhat estimates automatically, but you can force a limit. We recommend using 20% above estimate as a safety margin. If the market is congested, consider waiting or using a higher gas price.

Verifying the contract on Etherscan

After deployment, verify the source code. Use the hardhat-etherscan plugin:

npx hardhat verify --network mainnet DEPLOYED_ADDRESS

Verification increases user trust and enables interaction directly from Etherscan. We always do it.

Common errors and debugging

We've seen many errors: here are the most frequent and how to avoid them.

Out of gas during deployment

Happens if the bytecode is huge (e.g., contracts with many libraries). Solution: remove unnecessary libraries, use pragma experimental ABIEncoderV2 only if needed, and compile with optimizer enabled (optimizer in Hardhat).

Revert without message

Use require with a message to know where it fails. Or use Hardhat's console.log in tests. Don't leave contracts silent.

Gas price too low

In congested periods, a transaction with low gas price can stay pending for hours. Use ethers.provider.getFeeData() dynamically.

In summary — what to do now

  1. Study the EVM every time you write a smart contract. Don't assume operation costs. Keep the official EVM documentation open.
  2. Always measure gas in your tests with Hardhat. Compare optimized and unoptimized versions.
  3. Apply optimizations: packing, uint256, mappings instead of arrays, bounded loops.
  4. Deploy with margin: gas limit +20% and dynamic gas price.
  5. Verify the contract on Etherscan for transparency and interoperability.

The difference between a good contract and a great one lies in the gas details. At Meteora Web, we build contracts that don't make your wallet cry. If you want to dig deeper, check our guide to open source licenses — even for contracts you need to choose the right license.

Sponsored Protocol

Ing. Calogero Bono

> AUTHOR_EXTRACTED

Ing. Calogero Bono

Co-founder di Meteora Web. Ingegnere informatico, sviluppo ecosistemi digitali ad alte prestazioni. AI, automazione, SEO tecnica e infrastrutture web. Scrivo di tecnologia per rendere complesso… semplice.

[ Read Full Dossier ]

Hai bisogno di applicare questa strategia?

Esegui il protocollo di contatto per iniziare un progetto con noi.

> INIZIA_PROGETTO

Sponsored

> MW_JOURNAL

> READ_ALL()