Smart Contracts: When Code Enforces the Agreement
The agreed terms are executed automatically by a program rather than by people or intermediaries. Smart contracts elevated the blockchain from a “record of value” into a “platform for apps that move value.”
What is a smart contract?
A smart contract is a program deployed on a blockchain that runs automatically when predefined conditions are met. Write a rule as code, such as “when A sends funds to B, C issues a token to A,” and it is enforced exactly as written, with no one’s discretion in the loop. Where a paper contract is something you hope will be honored, a smart contract enforces the agreement in a form that cannot be broken.
The concept was proposed in the 1990s by legal scholar Nick Szabo, but it was Ethereum, launched in 2015, that made it real. It was designed as a “world-scale distributed computer” that can run arbitrary programs, not merely record transfers.
How it works: EVM, gas, state transition
Smart contracts run on a virtual machine present in every node (in Ethereum’s case, the EVM: Ethereum Virtual Machine). When a transaction calls a function, every node must run the same code and reach the same result. This deterministic execution is mandatory. That is why operations whose answer varies (randomness, the current time, external network calls) cannot be used directly.
Execution has a cost. Each step is charged a fee measured in units of gas, paid in cryptocurrency. Gas both prices the resources consumed and prevents attacks that would halt the network with infinite loops. If gas runs out, execution is aborted and state changes are rolled back, though the consumed gas is not refunded. Approximate costs are as follows (rough figures).
| Operation | Approximate gas cost | Note |
|---|---|---|
| Simple ETH transfer | 21,000 | Base cost for every transaction |
| New storage write (SSTORE, zero→nonzero) | 20,000 | Establishing new state is especially costly |
| Existing storage update (SSTORE, nonzero→nonzero) | 2,900 | When the slot is already warm |
| Storage read (SLOAD, cold) | 2,100 | First access only; later reads are cheap |
The key point is that operations that rewrite state cost more, since they grow the data every node must keep. A read-only view function, by contrast, is answered locally by a node with no transaction involved, so it consumes no gas.
Running a contract is the blockchain’s state transition itself. State, such as who holds how much of which token, moves deterministically to its next value via a transaction, and its correctness is finalized once all nodes agree (see Distributed Consensus).
From deployment to execution
A few fixed steps take a smart contract from source code to a running program.
- Write: author the logic in Solidity (the most common language) or Vyper.
- Compile: the compiler turns source code into bytecode the EVM can interpret, plus an ABI, the interface definition used to call functions from outside.
- Send the deployment transaction: broadcast a transaction with no recipient address and the bytecode as its data.
- Address assignment: the new address is computed deterministically via
keccak256from the sender’s address and its nonce at the time (with theCREATE2opcode, an address can also be pinned in advance using a salt). - Constructor execution: one-time initialization code runs at deploy time, writing the initial state.
- Accepting calls: from then on, every transaction carrying ABI-encoded calldata to that address triggers the corresponding function.
A Solidity example: a minimal deposit/withdraw contract
Here is a minimal contract anyone can deposit ETH into and withdraw from, up to their own balance.
contract Vault { mapping(address => uint256) public balances; function deposit() external payable { balances[msg.sender] += msg.value; } function withdraw(uint256 amount) external { require(balances[msg.sender] >= amount, "insufficient balance"); balances[msg.sender] -= amount; (bool ok, ) = msg.sender.call{value: amount}(""); require(ok, "transfer failed"); } }
mapping(address => uint256) balances: a state variable holding each address’s balance. The value written here is the blockchain state itself, shared by every node.external payable: a function modifier marking it callable from outside the contract and able to receive ETH at the same time.require(condition, "message"): rolls back the entire call instantly if the condition fails, the basic tool for input validation and access control.- Running
balances[...] -= amountbefore the external call (call) matters: reversing that order opens the reentrancy gap covered next (the Checks-Effects-Interactions pattern).
Representative use cases
- Tokens (ERC-20 / NFT): a contract with nothing more than a “balance table” and a “transfer function” becomes an alternative currency under the ERC-20 standard. NFTs (ERC-721), representing one-of-a-kind assets, are just contracts that record ownership. Shared standards let every wallet and exchange handle them identically.
- DeFi (Decentralized Finance): contracts broker transactions automatically with no central institution. A DEX lets anyone swap tokens via liquidity pools, and lending lets you borrow crypto against collateral. All rules are public and self-executing in code.
- Escrow and automated settlement: combined with multisig or conditional transfers, you can build intermediary-free escrow.
Vulnerabilities, real incidents, and lessons in defense
That “code executes reliably” means, conversely, that bugs execute reliably too. Because contracts are public and irreversible, a vulnerability can lead directly to catastrophic loss.
- Reentrancy: exploiting the window when a contract calls out externally, recursively re-invoking the same function before state is updated to drain funds. In the 2016 DAO incident, about 3.6 million ETH was siphoned, leading to the hard fork that split Ethereum from Ethereum Classic. The standard defenses are the Checks-Effects-Interactions pattern and a
ReentrancyGuardmodifier. - Integer overflow: a classic bug where a value exceeds its maximum and wraps around, breaking balance arithmetic. Solidity 0.8+ checks arithmetic automatically, but earlier versions relied on the
SafeMathlibrary, and missing it caused real losses. - Broken access control: a missing check on “who may call this function.” In the 2021 Poly Network hack, a flaw in permission verification let the attacker gain admin-equivalent privileges and drain over $600 million across several chains (most was later returned). Exhaustively applying modifiers like
onlyOwneris the defense. - Immutability: deployed code cannot, in principle, be rewritten. Proxy patterns enable fixes but introduce new complexity and a concentration of privilege.
- The oracle problem: because execution is deterministic, contracts cannot fetch real-world information on their own. If the oracle bridging that gap feeds wrong data, even correctly written code misbehaves.
The essentials of defense: use audited, battle-tested code, and decentralize privilege with multisig and the like. Contract wallets such as Safe are a prime example.
Auditing and testing in practice
The more value a contract handles, the more verification stages it goes through before deployment as a matter of standard practice.
- Static analysis: tools like Slither and Mythril automatically flag known vulnerability patterns such as reentrancy and overflow, a cheap first screening pass.
- Unit tests and fuzzing: test suites in Foundry or Hardhat check boundary values; invariant testing throws random inputs to see if properties that should always hold get broken.
- Third-party audits: code review from firms such as OpenZeppelin or Trail of Bits. Being audited does not prove zero vulnerabilities, and any change after the audit voids that assurance.
- Formal verification: mathematically proving code matches its specification. Tools such as Certora are used mainly on large DeFi protocols.
- Bug bounties: platforms like Immunefi pay rewards for reported vulnerabilities, creating an economic incentive for white hats to find bugs before attackers do.
- Staged deployment: verify on a testnet before rolling out to mainnet.
Execution on L2 rollups
Ethereum mainnet (L1) has limited throughput, and gas prices spike when demand concentrates. Rollups, which move most execution outside L1 (L2), are the mainstream answer. On EVM-compatible rollups, bytecode runs essentially the same as on L1.
- Optimistic rollups: submitted transactions are treated as correct and reflected immediately; if fraud is suspected, a fraud proof filed within a challenge period (often around a week) can overturn the result. Used by Arbitrum and Optimism.
- ZK rollups: a batch’s state transition is proven correct immediately via a cryptographic validity proof (zk-SNARK, etc.); L1 only needs to verify the proof, with no challenge period to wait out. zkSync, Starknet, and others compete on implementation.
- Shared design: both approaches execute off-chain and post only compressed data or a proof to L1, sharply cutting gas costs. Ultimate security still rests on L1’s Distributed Consensus.
Comparison with traditional contracts
| Aspect | Traditional contract | Smart contract |
|---|---|---|
| Enforcer | The parties themselves, or a court/arbitrator | A program, automatically, the moment conditions are met |
| Amendment/termination | Can be revised or terminated by mutual agreement | Immutable after deployment in principle (proxies etc. needed) |
| Intermediary | Lawyers, escrow agents, financial institutions may be involved | Code alone judges and executes, no intermediary |
| Dispute resolution | Negotiation, litigation, arbitration | Little room for interpretation, but bugs are fatal |
| Transparency | Known only to the parties involved | Code and history are public and verifiable by anyone |
| Cost to enforce | Legal and procedural fees | Gas fees only |
A smart contract is an attempt to separate a contract’s “interpretation” and “enforcement” from human discretion, entrusting them to code as a single source of truth. That rigor is a strength, but it also means code quality sets the ceiling on trustworthiness. The unglamorous work of auditing, testing, and staged deployment is what makes this technology fit for practical use.