DevelopersBeginner

What Is a Smart Contract?

A smart contract is a program stored at an address on a blockchain that runs exactly as written whenever a transaction calls it, with every node executing it and agreeing on the result. It holds its own balance and data, and no single party can edit it after deployment unless the code itself allows upgrades.

By DappAtlas editors · · 6 min read

In this article

Key takeaways

  • A smart contract is code plus storage at a blockchain address, run by every node in the network.
  • NIST defines it as a collection of code and data deployed with cryptographically signed transactions.
  • Deployed Ethereum contract code is capped at 24,576 bytes by EIP-170.
  • Contracts are deterministic and cannot fetch outside data on their own; they need oracles.

A working definition

NIST's glossary defines a smart contract as a collection of code and data, sometimes called functions and state, deployed using cryptographically signed transactions on a blockchain network. All nodes must derive the same result when it runs.[1]

Ethereum.org adds the practical view: a contract is a type of account. It has an address and a balance and can receive transactions, but it is controlled by its code rather than by a private key.[2]

The word contract is loose. Most smart contracts are not legal agreements. They are programs that enforce rules such as who may withdraw funds, at what price a swap happens, or how many tokens exist.

The best-known uses are tokens, exchanges and lending. An ERC-20 token is one contract keeping a table of balances; an exchange is a contract that holds two tokens and prices swaps by formula; a lending market is a contract that tracks deposits, loans and collateral ratios.

How execution works on Ethereum

Contracts on Ethereum are usually written in Solidity or Vyper and compiled before deployment so the Ethereum Virtual Machine can run them. Ethereum.org describes a contract as code (its functions) and data (its state) that reside at a specific address on the chain.[2]

When your transaction calls a function, every validating node runs the same bytecode against the same state. Each operation costs gas, which caps how much work a transaction can do and stops infinite loops from halting the network.[4]

Because every node must reach the same answer, contracts cannot fetch data from offchain sources on their own. Ethereum.org says this is by design, and that price data and other outside facts arrive through oracles.[2]

Contracts can also call other contracts in the same transaction. A single swap may touch a router, two token contracts and a pool. If the transaction runs out of gas partway, the EVM reverts all changes but the gas provided is still consumed.[4]

See also: Chainlink · Pyth Network · Glossary: gas fee

Worked example: a simple storage contract

The Solidity documentation opens with a contract that stores one unsigned integer and exposes set and get functions. Calling get is free when done as a read through a node. Calling set changes state, so it is a transaction that costs gas.[3]

Compare it with the cheapest transaction possible. A plain ETH transfer uses 21,000 gas; at a 10 gwei base fee plus a 2 gwei tip that costs 252,000 gwei, or 0.000252 ETH. A contract call needs more gas, because every storage write and computation step adds to the total.[4]

The Solidity docs note that storage is costly to read and even more costly to initialise and modify, which is why well-written contracts pack values together and avoid writing data they do not need.[3]

Deploying the contract costs far more than calling it; ethereum.org notes that gas costs for deployment are far higher than for a simple transfer. That one-time cost is paid by the deployer, while each set call is paid by whoever sends it.[2]

The same logic explains why many apps keep large data off chain and store only a hash or a pointer in the contract.

Hard limits written into the protocol

Contracts are not unlimited. The protocol sets caps, and they shape how large applications are built.

Protocol limits that apply to Ethereum smart contracts
LimitValueDefined in
Maximum deployed code size24,576 bytesEIP-170
Maximum initcode size at creation49,152 bytesEIP-3860
Gas for a plain ETH transfer21,000 gasethereum.org gas docs

See also: OpenZeppelin

Why the size cap matters

EIP-170, created in 2016, set MAX_CODE_SIZE to 24,576 bytes because a call costs constant gas while loading the code costs nodes work in proportion to its size. Ethereum.org notes that large contracts get around the cap with patterns such as the Diamond pattern that split logic across contracts.[5]

EIP-3860 later limited initcode, the code run once at deployment, to 49,152 bytes, which is twice the runtime cap, and added a charge of 2 gas for each 32-byte chunk of it.[6]

For users, the relevant effect is the proxy pattern. A proxy lets a team swap the logic behind a fixed address, which fixes bugs but also means the code you audited yesterday may not be the code that runs today.

Splitting logic has a cost of its own: every call between contracts adds gas, and more contracts mean more addresses users must verify.

Where smart contracts fail

Code is hard to change once deployed. Ethereum.org notes that contracts are public, work like open APIs that anyone can call, and that interactions with them are irreversible, so a single logic error is visible to every attacker at once.[2]

The common failure types are well known: reentrancy, faulty access control, price manipulation through thin oracle feeds, and unlimited token approvals that outlive the need for them. Audits and formal tests reduce the risk but do not remove it.

Access control is the second classic failure. A function meant only for the owner that lacks the check becomes a function anyone can call.

From source code to a live address

The life cycle has four steps. A developer writes the contract in Solidity, compiles it into EVM bytecode and an ABI, deploys it with a transaction that carries the bytecode, and then publishes the source so explorers can verify it. The Solidity docs call the ABI the standard way to interact with contracts in the Ethereum ecosystem.[7]

The ABI, or application binary interface, is described in JSON as an array of function, event and error descriptions. Wallets and frontends use it to encode your call into the data field of a transaction and to decode the result, because the encoding is not self-describing. Without the ABI, a contract is still callable, but the wallet can only show raw hex.[7]

Deployment is a transaction sent with no recipient. The Solidity docs explain that the new contract's address is derived from the creator's address and nonce, and that the output of the creation code is stored as the contract's code. That stored runtime code is the part bound by the 24,576-byte cap.[3]

Testing happens before any of this touches mainnet. Teams run unit tests on a local chain, then deploy to a public testnet, where test ETH from a faucet pays for gas and mistakes cost nothing.

After launch, the only ways to change behavior are the ones written into the code: parameters an owner may set, a pause function, or a proxy upgrade. Anything else requires deploying a new contract and asking users to move.

See also: Hardhat · Foundry · Remix · Crypto faucets

The bottom line

A smart contract is only as trustworthy as its code and its upgrade keys. Before using one with real money, confirm three things on a block explorer: the source is verified, an audit covers that exact version, and any admin or upgrade role is held by a multisig or timelock rather than one address.

See also: Etherscan · Safe

Educational content, not financial advice. Crypto assets are volatile; do your own research.

How we write our guides

Every guide is written from primary sources: official docs, standards and regulator pages, listed below with the date we read them. No project pays to be mentioned. Editorial standards

Related terms

FAQ

Who invented smart contracts?

The idea predates blockchains: ethereum.org credits Nick Szabo with the vending machine metaphor for it. Ethereum, whose first live release (Frontier) went live on July 30, 2015, made general-purpose smart contracts widely usable by giving them a shared virtual machine.

Can a smart contract be changed?

The bytecode at an address cannot be edited. A contract can be designed as an upgradeable proxy that points to new logic, which is a choice made by its developers.

Are smart contracts legally binding?

Not by default. They are programs. Whether a given arrangement is enforceable depends on the law that applies, not on the code.

Do other blockchains have smart contracts?

Yes. Solana calls them programs, compiled to sBPF bytecode and usually written in Rust, either natively or with Anchor. Hyperledger Fabric calls them chaincode and runs them in general-purpose languages such as Go, Java and Node.js.

Keep reading

Sources (10)
  1. [1] NIST CSRC. “Smart contract: Glossary.” Accessed Sep 26, 2026.
  2. [2] ethereum.org. “Introduction to smart contracts.” Accessed Sep 26, 2026.
  3. [3] Solidity docs. “Introduction to Smart Contracts.” Accessed Sep 26, 2026.
  4. [4] ethereum.org. “Gas and fees.” Accessed Sep 26, 2026.
  5. [5] Ethereum Improvement Proposals. “EIP-170: Contract code size limit.” Accessed Sep 26, 2026.
  6. [6] Ethereum Improvement Proposals. “EIP-3860: Limit and meter initcode.” Accessed Sep 26, 2026.
  7. [7] Solidity docs. “Contract ABI Specification.” Accessed Sep 26, 2026.
  8. [8] ethereum.org. “Ethereum history and forks.” Accessed Sep 26, 2026.
  9. [9] Solana docs. “Programs.” Accessed Sep 26, 2026.
  10. [10] Hyperledger Fabric docs. “Introduction.” Accessed Sep 26, 2026.

How this page works

Sources: NIST CSRC, ethereum.org, Solidity docs. Data as of Sep 26, 2026.

How we review

Not affiliated with any project listed. Educational content, not financial advice.