It was 2 AM. I had just deployed my first Solidity smart contract—a simple “wave at me” dApp—and was proudly calling wave()
from my frontend. But nothing happened.
No wave.
No confirmation.
Just a pending transaction and a big mystery: what is actually happening when I “call” a smart contract?
If you've ever clicked "Submit" in a Web3 app and wondered what goes on behind the scenes, this post is for you.
🧠 TL;DR First (Then We Dive Deep)
When you call a smart contract:
- You create a transaction from your wallet (like MetaMask).
- That transaction is signed by you, proving it’s legitimate.
- It gets sent to the blockchain network (Ethereum, Polygon, etc).
- Nodes pick it up, run the contract logic, and validate it.
- If all goes well, it’s added to a block, and the change becomes permanent.
But the real magic? It’s what happens between those steps.
Let’s walk through it with a story.
👩💻 The Story: Alice Sends a Transaction
Say Alice wants to buy a sword in a blockchain game by calling a smart contract function:
function buySword(uint swordId) public payable {
require(msg.value >= swordPrice, "Not enough ETH");
ownerOf[swordId] = msg.sender;
}
She clicks “Buy” in the dApp UI. Here’s what happens:
🧰 Step 1: The Frontend Prepares the Payload
The app uses Ethers.js or Web3.js to encode the function and arguments into something the Ethereum Virtual Machine (EVM) understands:
contract.buySword(2, { value: ethers.utils.parseEther("0.05") });
This turns into a raw transaction object like:
{
"to": "0xContractAddress",
"data": "0xa9059cbb000000000000000000...",
"value": "0.05 ETH"
}
🔐 Step 2: Signing the Transaction
Before it can go anywhere, Alice’s wallet (MetaMask, WalletConnect, etc.) pops up and asks her to sign the transaction.
- This doesn’t encrypt it.
- It simply proves: “Yes, I want to do this.”
The private key never leaves her wallet, but the signature is added to the transaction.
🚀 Step 3: Broadcasting to the Network
Once signed, the transaction is sent to the network—usually to a full node like Infura or Alchemy, or directly to an Ethereum node if you're self-hosting.
This step is like saying:
“Hey miners or validators, here’s a new transaction! Please include it in the next block!”
🔄 Step 4: The EVM Executes the Code
When the transaction is picked up by a node (usually by a validator or miner), the Ethereum Virtual Machine (EVM):
- Loads the smart contract's bytecode.
- Locates the function via its function selector (first 4 bytes of the
data
field). - Executes the code line by line.
- Updates blockchain state if successful.
If anything fails (like a failed require
), the whole transaction is reverted — no changes are made.
⛓️ Step 5: It’s Mined & Stored On-Chain
Once the transaction passes validation:
- It's included in the next block.
- That block is appended to the blockchain.
- The transaction becomes immutable history.
Anyone can verify the transaction later on block explorers like Etherscan.
🧼 Behind the Scenes (Gas, Nonces, and State)
A few more things happening under the hood:
- Gas: The fee paid to miners/validators for computation and storage.
- Nonce: A unique number to prevent replay attacks and ensure transaction order.
- State transitions: Events and changes logged to update the ledger.
Smart contracts are deterministic: if the same inputs are given, every node will compute the same result or revert.
🤖 Read vs Write: Calls That Don’t Cost Gas
If Alice just wants to read data (like checking sword ownership), no transaction is created:
const sword = await contract.getSword(2);
- No gas
- No miner
- No blockchain write
- Just a simulated EVM call against the latest state
These are called "view" functions and are free.
🎯 Summary
When you “call” a smart contract, you're not just hitting a function. You’re:
- Encoding the function and its arguments
- Signing the request
- Broadcasting it to the network
- Letting thousands of nodes simulate, verify, and agree on the outcome
- Getting it permanently recorded on the chain
That’s a lot of trustless magic behind one click.
🛠️ Want to See It in Action?
Try this:
- Write a simple contract with a public function
- Deploy it to a testnet (like Sepolia)
- Call it from your dApp with Ethers.js
- Then watch the tx on Etherscan
You’ll see exactly what happens, from pending
to confirmed
.
💬 Over to You
What’s the smartest (or weirdest) smart contract you’ve interacted with?
Ever had a tx fail mysteriously?
Drop your thoughts in the comments 👇
👋 Let’s Connect
- GitHub:https://github.com/amirofekiti/ Thanks for reading! If this helped you, consider hitting ❤️ and saving the post!
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.