At a glance
- A smart contract is
- A program deployed to an address on the chain, which runs exactly as written whenever someone calls it
- It has
- Persistent storage (its state) and functions (the things it can do), plus usually a balance
- You use it by
- Sending a transaction whose data selects a function and supplies its arguments
- It is
- Deterministic, public, and effectively immutable once deployed. The code is the contract, and everyone can read it
- The catch
- Because it cannot be quietly patched, a bug is permanent and a public target. This is why the rest of this section exists
A program that lives at an address
A smart contract is a piece of software, but an unusual one. You do not run it on your own machine; you deploy it to the blockchain, where it takes an address of its own and lives as a permanent account. From then on it sits there doing nothing until someone calls it, and when they do, every node in the network runs its code and agrees on the result. "Smart contract" is a grand name for a simple idea: rules written as code that the whole network enforces the same way, with no one able to make an exception.
State and functions
A contract has two halves. Its state is data it stores permanently on-chain, surviving between calls: balances, owners, settings. Its functions are the operations it exposes. Some functions only read the state and cost nothing to call; others change it, and changing shared state requires a transaction and gas. Here is about the smallest useful contract there is.
contract Counter {
uint256 public count; // state: persists on-chain
function increment() external { // changes state: needs a transaction
count += 1;
}
function get() external view returns (uint256) { // only reads: free to call
return count;
}
}
Deploy this and count starts at zero and lives forever at the contract's address. Anyone can call increment to raise it, and anyone can read it. Notice there is no login and no owner here: whatever the code permits, the world can do. Deciding who is allowed to call what is a deliberate design choice, and forgetting to make it is one of the most common bugs, covered in the access-control guide.
How you actually use one
Calling a contract is just sending a transaction to its address with a data field that says which function to run and with what arguments. The first four bytes of that data are a function selector, a fingerprint of the function's name and parameters, and the rest are the encoded arguments. Your wallet builds this for you; you see "Increment", the chain sees a few bytes.
to: 0xThe...Contract // the contract's address
value: 0 // not sending any ether, just calling
data: 0xd09de08a // the 4-byte selector for increment()
Contracts can also call other contracts in the same way, which is how the ecosystem composes: a swap contract calls a token, a lending pool calls a price feed. That composability is powerful and is also why a flaw in one contract can cascade into others that trusted it.
Immutable, deterministic, and fully public
Three properties make contracts different from ordinary software, and each one cuts both ways.
- Immutable. Once deployed, the code cannot be changed. That is what lets people trust it will not rug them tomorrow, but it also means a bug cannot be hot-fixed. Upgradeable designs exist, and they bring their own risks, as the delegatecall guide explains.
- Deterministic. Given the same state and inputs, it always produces the same result on every node. There is no randomness or outside data unless a contract deliberately imports it, which is a subject of its own.
- Public. The deployed bytecode is visible to everyone, and most serious projects publish the source too. Anyone, including an attacker, can study exactly how it works before deciding how to break it.
Immutable and public is why security is not optional. A traditional web bug can be patched the moment it is found. A contract bug is frozen into an address that holds real value, in code an attacker can read at leisure. The upside of code you cannot secretly change is trust; the cost is that it must be right the first time. Everything else in this section follows from that.
The short version. A smart contract is a program deployed at an address, with persistent state and functions, that the whole network runs identically whenever it is called. You use it by sending a transaction that selects a function; contracts call each other the same way, which is what makes the ecosystem composable and fragile. Contracts are deterministic, public, and effectively immutable, so a bug is permanent and openly visible, which is exactly why smart contract security is a discipline of its own.
References & further reading
- Ethereum community, Smart contracts. What they are and how they run.
- Ethereum community, Anatomy of a smart contract. State, functions, and how calls are encoded.
- Ethereum community, Smart contract security. Why immutability raises the stakes.