Lessons 1/4 · 20 min
What a contract is: code, state, determinism, gas
A concrete case
A cocoa cooperative in Bafoussam wants a register of lots whose rules cannot be secretly modified by a single person: who may register a lot, and a lot number can never be used twice. A smart contract is a program, with its data, stored at an address on a chain with a programmable virtual machine (Ethereum-style chains, for example). Users call it by sending transactions; every node executes the call and must arrive at the same new state.
A clarification up front: the most widespread language for these chains is Solidity, but this course does not teach its syntax. The examples below are in pseudo-code, readable without knowing any language.
contract LotRegistry:
storage owner // set at creation
storage lots: map lotId -> (holder, weightKg)
function register(lotId, weightKg):
require caller == owner // access control
require lots[lotId] does not exist
lots[lotId] = (caller, weightKg)
emit Registered(lotId)require means: if the condition is false, the whole call is undone and the state stays as before. caller is the address that signed the transaction (or the contract calling it). You saw in the transactions topic that this signature is checked by the protocol; the contract decides what it allows.
Four properties that define the craft
1. Determinism. All nodes must get the same result from the same state and the same transaction. So a contract cannot draw a "truly random" number, nor call a web page (two nodes would ask at different moments and get different answers). A block timestamp exists, but it is a value set by the block producer within bounds, not a trusted clock.
2. Gas. Each operation costs a number of units of gas, and execution is metered: the sender sets a gas limit and a price per unit, and the fee paid is gas consumed × price (as in the fees workshop). If the limit is reached before the end, execution is undone, but the work performed is still paid for. This keeps infinite loops from blocking the network.
Example with a fictitious schedule: writing a new storage slot costs 20,000 units, reading a slot 200, and each transaction has a base cost of 21,000. The register call reads two slots (owner and the lot's existence) and writes one: 21,000 + 200 + 200 + 20,000 = 41,400 units (in this fictitious schedule the pair (holder, weightKg) fits in a single slot and the emit event is ignored; with two separate writes the total would be 61,400). With a limit of 40,000, the call runs out of gas: everything is undone, and the 40,000 units are paid anyway. With a limit of 45,000 it passes and only the gas actually consumed (41,400) is billed. Real schedules differ; the idea stays.
Design consequence: a function that loops over a list that grows with users eventually exceeds a block's gas limit and becomes unusable. Avoid unbounded loops.
3. Publicity. A contract's state is readable by everyone. A language's "private" keywords only stop other contracts from accessing it simply; anyone reading the storage sees the values. No secret in a contract.
4. Immutability. Once deployed, a contract's code cannot be modified in the current scheme. A bug there is permanent. One can plan a "proxy" contract that redirects to a new version, but then whoever holds the right to switch version holds an enormous power, and your users must trust them. Immutable is an advantage (the rules do not move) and a risk (neither do the errors).
What this does NOT guarantee
- The contract guarantees that its rules are applied, not that the facts are true: if the owner records "500 kg" for a lot that weighs 50, the chain faithfully preserves a lie.
- A contract never runs by itself: a transaction must call it. It cannot "act at midnight".
- Deployed does not mean correct.
Recap: code and state at an address, deterministic result, execution metered in gas, public state, frozen code.
